1
2
3
4
5
6
7
8
9
10
11
12#include <linux/mm.h>
13#include <linux/init.h>
14#include <asm/page.h>
15#include <asm/tlb.h>
16#include <asm/mmu_context.h>
17
18
19
20
21
22
23int __init sh64_tlb_init(void)
24{
25
26 cpu_data->dtlb.entries = 64;
27 cpu_data->dtlb.step = 0x10;
28
29 cpu_data->dtlb.first = DTLB_FIXED | cpu_data->dtlb.step;
30 cpu_data->dtlb.next = cpu_data->dtlb.first;
31
32 cpu_data->dtlb.last = DTLB_FIXED |
33 ((cpu_data->dtlb.entries - 1) *
34 cpu_data->dtlb.step);
35
36
37 cpu_data->itlb.entries = 64;
38 cpu_data->itlb.step = 0x10;
39
40 cpu_data->itlb.first = ITLB_FIXED | cpu_data->itlb.step;
41 cpu_data->itlb.next = cpu_data->itlb.first;
42 cpu_data->itlb.last = ITLB_FIXED |
43 ((cpu_data->itlb.entries - 1) *
44 cpu_data->itlb.step);
45
46 return 0;
47}
48
49
50
51
52
53
54unsigned long long sh64_next_free_dtlb_entry(void)
55{
56 return cpu_data->dtlb.next;
57}
58
59
60
61
62
63
64unsigned long long sh64_get_wired_dtlb_entry(void)
65{
66 unsigned long long entry = sh64_next_free_dtlb_entry();
67
68 cpu_data->dtlb.first += cpu_data->dtlb.step;
69 cpu_data->dtlb.next += cpu_data->dtlb.step;
70
71 return entry;
72}
73
74
75
76
77
78
79
80
81
82
83int sh64_put_wired_dtlb_entry(unsigned long long entry)
84{
85 __flush_tlb_slot(entry);
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 if (entry <= DTLB_FIXED)
102 return -EINVAL;
103
104
105
106
107
108 if (entry < (cpu_data->dtlb.first - cpu_data->dtlb.step))
109 return -EINVAL;
110
111
112 cpu_data->dtlb.first -= cpu_data->dtlb.step;
113 cpu_data->dtlb.next = entry;
114
115 return 0;
116}
117
118
119
120
121
122
123
124
125
126
127
128
129inline void sh64_setup_tlb_slot(unsigned long long config_addr,
130 unsigned long eaddr,
131 unsigned long asid,
132 unsigned long paddr)
133{
134 unsigned long long pteh, ptel;
135
136
137#if (NEFF == 32)
138 pteh = (unsigned long long)(signed long long)(signed long) eaddr;
139#else
140#error "Can't sign extend more than 32 bits yet"
141#endif
142 pteh &= PAGE_MASK;
143 pteh |= (asid << PTEH_ASID_SHIFT) | PTEH_VALID;
144#if (NEFF == 32)
145 ptel = (unsigned long long)(signed long long)(signed long) paddr;
146#else
147#error "Can't sign extend more than 32 bits yet"
148#endif
149 ptel &= PAGE_MASK;
150 ptel |= (_PAGE_CACHABLE | _PAGE_READ | _PAGE_WRITE);
151
152 asm volatile("putcfg %0, 1, %1\n\t"
153 "putcfg %0, 0, %2\n"
154 : : "r" (config_addr), "r" (ptel), "r" (pteh));
155}
156
157
158
159
160
161
162
163
164inline void sh64_teardown_tlb_slot(unsigned long long config_addr)
165 __attribute__ ((alias("__flush_tlb_slot")));
166
167