Rev 819 | Rev 900 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 819 | Rev 899 | ||
---|---|---|---|
Line 31... | Line 31... | ||
31 | */ |
31 | */ |
32 | 32 | ||
33 | #include <mm/tlb.h> |
33 | #include <mm/tlb.h> |
34 | #include <arch/mm/tlb.h> |
34 | #include <arch/mm/tlb.h> |
35 | #include <arch/barrier.h> |
35 | #include <arch/barrier.h> |
36 | - | ||
- | 36 | #include <typedefs.h> |
|
37 | 37 | ||
38 | /** Invalidate all TLB entries. */ |
38 | /** Invalidate all TLB entries. */ |
39 | void tlb_invalidate_all(void) |
39 | void tlb_invalidate_all(void) |
40 | { |
40 | { |
41 | /* TODO */ |
41 | /* TODO */ |
Line 48... | Line 48... | ||
48 | void tlb_invalidate_asid(asid_t asid) |
48 | void tlb_invalidate_asid(asid_t asid) |
49 | { |
49 | { |
50 | /* TODO */ |
50 | /* TODO */ |
51 | } |
51 | } |
52 | 52 | ||
- | 53 | /** Insert data into data translation cache. |
|
- | 54 | * |
|
- | 55 | * @param va Virtual page address. |
|
- | 56 | * @param asid Address space identifier. |
|
- | 57 | * @param entry The rest of TLB entry as required by TLB insertion format. |
|
- | 58 | */ |
|
- | 59 | void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) { |
|
- | 60 | tc_mapping_insert(va, asid, entry, true); |
|
- | 61 | } |
|
53 | 62 | ||
- | 63 | /** Insert data into instruction translation cache. |
|
- | 64 | * |
|
- | 65 | * @param va Virtual page address. |
|
- | 66 | * @param asid Address space identifier. |
|
- | 67 | * @param entry The rest of TLB entry as required by TLB insertion format. |
|
- | 68 | */ |
|
- | 69 | void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) { |
|
- | 70 | tc_mapping_insert(va, asid, entry, false); |
|
- | 71 | } |
|
54 | 72 | ||
- | 73 | /** Insert data into instruction or data translation cache. |
|
- | 74 | * |
|
- | 75 | * @param va Virtual page address. |
|
- | 76 | * @param asid Address space identifier. |
|
- | 77 | * @param entry The rest of TLB entry as required by TLB insertion format. |
|
- | 78 | * @param dtc If true, insert into data translation cache, use instruction translation cache otherwise. |
|
- | 79 | */ |
|
55 | void tlb_fill_data(__address va,asid_t asid,tlb_entry_t entry) |
80 | void tc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtc) |
56 | { |
81 | { |
57 | region_register rr; |
82 | region_register rr; |
- | 83 | bool restore_rr = false; |
|
58 | 84 | ||
- | 85 | if (!(entry.not_present.p)) |
|
- | 86 | return; |
|
59 | 87 | ||
60 | if(!(entry.not_present.p)) return; |
- | |
61 | - | ||
62 | rr.word=rr_read(VA_REGION(va)); |
88 | rr.word = rr_read(VA_REGION(va)); |
63 | - | ||
64 | if(rr.map.rid==ASID2RID(asid,VA_REGION(va))) |
89 | if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) { |
65 | { |
- | |
66 | asm volatile |
- | |
67 | ( |
90 | /* |
68 | "srlz.i;;\n" |
- | |
69 | "srlz.d;;\n" |
- | |
70 | "mov r8=psr;;\n" |
- | |
71 | "and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
- | |
72 | "mov psr.l=r9;;\n" |
- | |
73 | "srlz.d;;\n" |
- | |
74 | "srlz.i;;\n" |
- | |
75 | "mov cr.ifa=%1\n" /*va*/ |
- | |
76 | "mov cr.itir=%2;;\n" /*entry.word[1]*/ |
91 | * The selected region register does not contain required RID. |
77 | "itc.d %3;;\n" /*entry.word[0]*/ |
- | |
78 | "mov psr.l=r8;;\n" |
- | |
79 | "srlz.d;;\n" |
- | |
80 | : |
- | |
81 | :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]) |
92 | * Save the old content of the register and replace the RID. |
82 | :"r8","r9" |
- | |
83 | ); |
93 | */ |
84 | } |
- | |
85 | else |
- | |
86 | { |
- | |
87 | region_register rr0; |
94 | region_register rr0; |
- | 95 | ||
88 | rr0=rr; |
96 | rr0 = rr; |
89 | rr0.map.rid=ASID2RID(asid,VA_REGION(va)); |
97 | rr0.map.rid = ASID2RID(asid, VA_REGION(va)); |
90 | rr_write(VA_REGION(va),rr0.word); |
98 | rr_write(VA_REGION(va), rr0.word); |
91 | srlz_d(); |
99 | srlz_d(); |
92 | asm volatile |
100 | srlz_i(); |
93 | ( |
101 | } |
- | 102 | ||
- | 103 | __asm__ volatile ( |
|
94 | "mov r8=psr;;\n" |
104 | "mov r8=psr;;\n" |
95 | "and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
105 | "and r9=r8,%0;;\n" /* (~PSR_IC_MASK) */ |
96 | "mov psr.l=r9;;\n" |
106 | "mov psr.l=r9;;\n" |
97 | "srlz.d;;\n" |
107 | "srlz.d;;\n" |
- | 108 | "srlz.i;;\n" |
|
98 | "mov cr.ifa=%1\n" /*va*/ |
109 | "mov cr.ifa=%1\n" /* va */ |
99 | "mov cr.itir=%2;;\n" /*entry.word[1]*/ |
110 | "mov cr.itir=%2;;\n" /* entry.word[1] */ |
100 | "itc.d %3;;\n" /*entry.word[0]*/ |
111 | "cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */ |
- | 112 | "(p6) itc.i %3;;\n" |
|
- | 113 | "(p7) itc.d %3;;\n" |
|
101 | "mov psr.l=r8;;\n" |
114 | "mov psr.l=r8;;\n" |
102 | "srlz.d;;\n" |
115 | "srlz.d;;\n" |
103 | : |
116 | : |
104 | :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]) |
117 | : "r" (~PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc) |
105 | :"r8","r9" |
118 | : "p6", "p7", "r8", "r9" |
106 | ); |
119 | ); |
- | 120 | ||
- | 121 | if (restore_rr) { |
|
107 | rr_write(VA_REGION(va),rr.word); |
122 | rr_write(VA_REGION(va),rr.word); |
- | 123 | srlz_d(); |
|
- | 124 | srlz_i(); |
|
108 | } |
125 | } |
109 | - | ||
110 | - | ||
111 | } |
126 | } |
112 | 127 | ||
- | 128 | /** Insert data into instruction translation register. |
|
- | 129 | * |
|
- | 130 | * @param va Virtual page address. |
|
- | 131 | * @param asid Address space identifier. |
|
- | 132 | * @param entry The rest of TLB entry as required by TLB insertion format. |
|
- | 133 | * @param tr Translation register. |
|
- | 134 | */ |
|
113 | void tlb_fill_code(__address va,asid_t asid,tlb_entry_t entry) |
135 | void itr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr) |
114 | { |
136 | { |
115 | region_register rr; |
- | |
116 | - | ||
117 | - | ||
118 | if(!(entry.not_present.p)) return; |
- | |
119 | - | ||
120 | rr.word=rr_read(VA_REGION(va)); |
- | |
121 | - | ||
122 | if(rr.map.rid==ASID2RID(asid,VA_REGION(va))) |
- | |
123 | { |
- | |
124 | asm volatile |
- | |
125 | ( |
- | |
126 | "srlz.i;;\n" |
- | |
127 | "srlz.d;;\n" |
- | |
128 | "mov r8=psr;;\n" |
- | |
129 | "and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
- | |
130 | "mov psr.l=r9;;\n" |
- | |
131 | "srlz.d;;\n" |
- | |
132 | "srlz.i;;\n" |
- | |
133 | "mov cr.ifa=%1\n" /*va*/ |
- | |
134 | "mov cr.itir=%2;;\n" /*entry.word[1]*/ |
- | |
135 | "itc.i %3;;\n" /*entry.word[0]*/ |
- | |
136 | "mov psr.l=r8;;\n" |
- | |
137 | "srlz.d;;\n" |
- | |
138 | : |
- | |
139 | :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]) |
- | |
140 | :"r8","r9" |
- | |
141 | ); |
- | |
142 | } |
- | |
143 | else |
- | |
144 | { |
- | |
145 | region_register rr0; |
- | |
146 | rr0=rr; |
- | |
147 | rr0.map.rid=ASID2RID(asid,VA_REGION(va)); |
137 | tr_mapping_insert(va, asid, entry, false, tr); |
148 | rr_write(VA_REGION(va),rr0.word); |
- | |
149 | srlz_d(); |
- | |
150 | asm volatile |
- | |
151 | ( |
- | |
152 | "mov r8=psr;;\n" |
- | |
153 | "and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
- | |
154 | "mov psr.l=r9;;\n" |
- | |
155 | "srlz.d;;\n" |
- | |
156 | "mov cr.ifa=%1\n" /*va*/ |
- | |
157 | "mov cr.itir=%2;;\n" /*entry.word[1]*/ |
- | |
158 | "itc.i %3;;\n" /*entry.word[0]*/ |
- | |
159 | "mov psr.l=r8;;\n" |
- | |
160 | "srlz.d;;\n" |
- | |
161 | : |
- | |
162 | :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]) |
- | |
163 | :"r8","r9" |
- | |
164 | ); |
- | |
165 | rr_write(VA_REGION(va),rr.word); |
- | |
166 | } |
- | |
167 | - | ||
168 | - | ||
169 | } |
138 | } |
170 | 139 | ||
- | 140 | /** Insert data into data translation register. |
|
- | 141 | * |
|
- | 142 | * @param va Virtual page address. |
|
- | 143 | * @param asid Address space identifier. |
|
- | 144 | * @param entry The rest of TLB entry as required by TLB insertion format. |
|
- | 145 | * @param tr Translation register. |
|
- | 146 | */ |
|
- | 147 | void dtr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr) |
|
- | 148 | { |
|
- | 149 | tr_mapping_insert(va, asid, entry, true, tr); |
|
- | 150 | } |
|
171 | 151 | ||
- | 152 | /** Insert data into instruction or data translation register. |
|
- | 153 | * |
|
- | 154 | * @param va Virtual page address. |
|
- | 155 | * @param asid Address space identifier. |
|
- | 156 | * @param entry The rest of TLB entry as required by TLB insertion format. |
|
- | 157 | * @param dtc If true, insert into data translation register, use instruction translation register otherwise. |
|
- | 158 | * @param tr Translation register. |
|
- | 159 | */ |
|
172 | void tlb_fill_data_tr(__u64 tr,__address va,asid_t asid,tlb_entry_t entry) |
160 | void tr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr) |
173 | { |
161 | { |
174 | region_register rr; |
162 | region_register rr; |
- | 163 | bool restore_rr = false; |
|
175 | 164 | ||
- | 165 | if (!(entry.not_present.p)) |
|
- | 166 | return; |
|
176 | 167 | ||
177 | if(!(entry.not_present.p)) return; |
- | |
178 | - | ||
179 | rr.word=rr_read(VA_REGION(va)); |
168 | rr.word = rr_read(VA_REGION(va)); |
180 | - | ||
181 | if(rr.map.rid==ASID2RID(asid,VA_REGION(va))) |
169 | if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) { |
182 | { |
- | |
183 | asm volatile |
- | |
184 | ( |
170 | /* |
185 | "srlz.i;;\n" |
- | |
186 | "srlz.d;;\n" |
- | |
187 | "mov r8=psr;;\n" |
- | |
188 | "and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
- | |
189 | "mov psr.l=r9;;\n" |
- | |
190 | "srlz.d;;\n" |
- | |
191 | "srlz.i;;\n" |
- | |
192 | "mov cr.ifa=%1\n" /*va*/ |
- | |
193 | "mov cr.itir=%2;;\n" /*entry.word[1]*/ |
171 | * The selected region register does not contain required RID. |
194 | "itr.d dtr[%4]=%3;;\n" /*entry.word[0]*/ |
172 | * Save the old content of the register and replace the RID. |
195 | "mov psr.l=r8;;\n" |
- | |
196 | "srlz.d;;\n" |
- | |
197 | : |
- | |
198 | :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr) |
- | |
199 | :"r8","r9" |
- | |
200 | ); |
173 | */ |
201 | } |
- | |
202 | else |
- | |
203 | { |
- | |
204 | region_register rr0; |
174 | region_register rr0; |
- | 175 | ||
205 | rr0=rr; |
176 | rr0 = rr; |
206 | rr0.map.rid=ASID2RID(asid,VA_REGION(va)); |
177 | rr0.map.rid = ASID2RID(asid, VA_REGION(va)); |
207 | rr_write(VA_REGION(va),rr0.word); |
178 | rr_write(VA_REGION(va), rr0.word); |
208 | srlz_d(); |
179 | srlz_d(); |
209 | asm volatile |
- | |
210 | ( |
- | |
211 | "mov r8=psr;;\n" |
- | |
212 | "and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
- | |
213 | "mov psr.l=r9;;\n" |
- | |
214 | "srlz.d;;\n" |
180 | srlz_i(); |
215 | "mov cr.ifa=%1\n" /*va*/ |
- | |
216 | "mov cr.itir=%2;;\n" /*entry.word[1]*/ |
- | |
217 | "itr.d dtr[%4]=%3;;\n" /*entry.word[0]*/ |
- | |
218 | "mov psr.l=r8;;\n" |
- | |
219 | "srlz.d;;\n" |
- | |
220 | : |
- | |
221 | :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr) |
- | |
222 | :"r8","r9" |
- | |
223 | ); |
- | |
224 | rr_write(VA_REGION(va),rr.word); |
- | |
225 | } |
181 | } |
226 | 182 | ||
- | 183 | __asm__ volatile ( |
|
- | 184 | "mov r8=psr;;\n" |
|
- | 185 | "and r9=r8,%0;;\n" /* (~PSR_IC_MASK) */ |
|
- | 186 | "mov psr.l=r9;;\n" |
|
- | 187 | "srlz.d;;\n" |
|
- | 188 | "srlz.i;;\n" |
|
- | 189 | "mov cr.ifa=%1\n" /* va */ |
|
- | 190 | "mov cr.itir=%2;;\n" /* entry.word[1] */ |
|
- | 191 | "cmp.eq p6,p7=%5,r0;;\n" /* decide between itr and dtr */ |
|
- | 192 | "(p6) itr.i itr[%4]=%3;;\n" |
|
- | 193 | "(p7) itr.d dtr[%4]=%3;;\n" |
|
- | 194 | "mov psr.l=r8;;\n" |
|
- | 195 | "srlz.d;;\n" |
|
- | 196 | : |
|
- | 197 | :"r" (~PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr) |
|
- | 198 | : "p6", "p7", "r8", "r9" |
|
- | 199 | ); |
|
227 | 200 | ||
- | 201 | if (restore_rr) { |
|
- | 202 | rr_write(VA_REGION(va),rr.word); |
|
- | 203 | srlz_d(); |
|
- | 204 | srlz_i(); |
|
- | 205 | } |
|
228 | } |
206 | } |
229 | 207 | ||
230 | void tlb_fill_code_tr(__u64 tr,__address va,asid_t asid,tlb_entry_t entry) |
208 | void alternate_instruction_tlb_fault(void) |
231 | { |
209 | { |
232 | region_register rr; |
210 | panic("%s\n", __FUNCTION__); |
233 | 211 | } |
|
234 | 212 | ||
235 | if(!(entry.not_present.p)) return; |
213 | void alternate_data_tlb_fault(void) |
- | 214 | { |
|
- | 215 | panic("%s\n", __FUNCTION__); |
|
- | 216 | } |
|
236 | 217 | ||
- | 218 | void data_nested_tlb_fault(void) |
|
- | 219 | { |
|
237 | rr.word=rr_read(VA_REGION(va)); |
220 | panic("%s\n", __FUNCTION__); |
- | 221 | } |
|
238 | 222 | ||
239 | if(rr.map.rid==ASID2RID(asid,VA_REGION(va))) |
223 | void data_dirty_bit_fault(void) |
240 | { |
224 | { |
241 | asm volatile |
- | |
242 | ( |
- | |
243 | "srlz.i;;\n" |
- | |
244 | "srlz.d;;\n" |
- | |
245 | "mov r8=psr;;\n" |
- | |
246 | "and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
- | |
247 | "mov psr.l=r9;;\n" |
- | |
248 | "srlz.d;;\n" |
- | |
249 | "srlz.i;;\n" |
- | |
250 | "mov cr.ifa=%1\n" /*va*/ |
- | |
251 | "mov cr.itir=%2;;\n" /*entry.word[1]*/ |
- | |
252 | "itr.i itr[%4]=%3;;\n" /*entry.word[0]*/ |
- | |
253 | "mov psr.l=r8;;\n" |
- | |
254 | "srlz.d;;\n" |
- | |
255 | : |
- | |
256 | :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr) |
- | |
257 | :"r8","r9" |
- | |
258 | ); |
- | |
259 | } |
- | |
260 | else |
- | |
261 | { |
- | |
262 | region_register rr0; |
- | |
263 | rr0=rr; |
- | |
264 | rr0.map.rid=ASID2RID(asid,VA_REGION(va)); |
- | |
265 | rr_write(VA_REGION(va),rr0.word); |
- | |
266 | srlz_d(); |
- | |
267 | asm volatile |
- | |
268 | ( |
- | |
269 | "mov r8=psr;;\n" |
- | |
270 | "and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
- | |
271 | "mov psr.l=r9;;\n" |
- | |
272 | "srlz.d;;\n" |
- | |
273 | "mov cr.ifa=%1\n" /*va*/ |
225 | panic("%s\n", __FUNCTION__); |
274 | "mov cr.itir=%2;;\n" /*entry.word[1]*/ |
- | |
275 | "itr.i itr[%4]=%3;;\n" /*entry.word[0]*/ |
- | |
276 | "mov psr.l=r8;;\n" |
- | |
277 | "srlz.d;;\n" |
- | |
278 | : |
- | |
279 | :"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr) |
- | |
280 | :"r8","r9" |
- | |
281 | ); |
- | |
282 | rr_write(VA_REGION(va),rr.word); |
- | |
283 | } |
226 | } |
284 | 227 | ||
- | 228 | void instruction_access_bit_fault(void) |
|
- | 229 | { |
|
- | 230 | panic("%s\n", __FUNCTION__); |
|
- | 231 | } |
|
285 | 232 | ||
- | 233 | void data_access_bit_fault(void) |
|
- | 234 | { |
|
- | 235 | panic("%s\n", __FUNCTION__); |
|
286 | } |
236 | } |
287 | 237 | ||
- | 238 | void page_not_present(void) |
|
- | 239 | { |
|
- | 240 | panic("%s\n", __FUNCTION__); |
|
- | 241 | } |