Rev 2071 | Rev 3584 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2071 | Rev 3193 | ||
---|---|---|---|
Line 50... | Line 50... | ||
50 | * @param as Address space. |
50 | * @param as Address space. |
51 | * @param lock Lock/unlock the address space. |
51 | * @param lock Lock/unlock the address space. |
52 | * @param badvaddr Faulting virtual address. |
52 | * @param badvaddr Faulting virtual address. |
53 | * @param access Access mode that caused the fault. |
53 | * @param access Access mode that caused the fault. |
54 | * @param istate Pointer to interrupted state. |
54 | * @param istate Pointer to interrupted state. |
55 | * @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
55 | * @param pfrc Pointer to variable where as_page_fault() return code |
- | 56 | * will be stored. |
|
56 | * @return PTE on success, NULL otherwise. |
57 | * @return PTE on success, NULL otherwise. |
57 | * |
58 | * |
58 | */ |
59 | */ |
- | 60 | static pte_t * |
|
59 | static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, istate_t *istate, int *pfrc) |
61 | find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, |
- | 62 | istate_t *istate, int *pfrc) |
|
60 | { |
63 | { |
61 | /* |
64 | /* |
62 | * Check if the mapping exists in page tables. |
65 | * Check if the mapping exists in page tables. |
63 | */ |
66 | */ |
64 | pte_t *pte = page_mapping_find(as, badvaddr); |
67 | pte_t *pte = page_mapping_find(as, badvaddr); |
Line 112... | Line 115... | ||
112 | if (s) |
115 | if (s) |
113 | symbol = s; |
116 | symbol = s; |
114 | s = get_symtab_entry(istate->lr); |
117 | s = get_symtab_entry(istate->lr); |
115 | if (s) |
118 | if (s) |
116 | sym2 = s; |
119 | sym2 = s; |
117 | panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); |
120 | panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, |
- | 121 | istate->pc, symbol, sym2); |
|
118 | } |
122 | } |
119 | 123 | ||
120 | 124 | ||
121 | static void pht_insert(const uintptr_t vaddr, const pfn_t pfn) |
125 | static void pht_insert(const uintptr_t vaddr, const pfn_t pfn) |
122 | { |
126 | { |
Line 145... | Line 149... | ||
145 | bool found = false; |
149 | bool found = false; |
146 | 150 | ||
147 | /* Find unused or colliding |
151 | /* Find unused or colliding |
148 | PTE in PTEG */ |
152 | PTE in PTEG */ |
149 | for (i = 0; i < 8; i++) { |
153 | for (i = 0; i < 8; i++) { |
150 | if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) { |
154 | if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && |
- | 155 | (phte[base + i].api == api))) { |
|
151 | found = true; |
156 | found = true; |
152 | break; |
157 | break; |
153 | } |
158 | } |
154 | } |
159 | } |
155 | 160 | ||
Line 158... | Line 163... | ||
158 | uint32_t base2 = (~hash & 0x3ff) << 3; |
163 | uint32_t base2 = (~hash & 0x3ff) << 3; |
159 | 164 | ||
160 | /* Find unused or colliding |
165 | /* Find unused or colliding |
161 | PTE in PTEG */ |
166 | PTE in PTEG */ |
162 | for (i = 0; i < 8; i++) { |
167 | for (i = 0; i < 8; i++) { |
- | 168 | if ((!phte[base2 + i].v) || |
|
163 | if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) { |
169 | ((phte[base2 + i].vsid == vsid) && |
- | 170 | (phte[base2 + i].api == api))) { |
|
164 | found = true; |
171 | found = true; |
165 | base = base2; |
172 | base = base2; |
166 | h = 1; |
173 | h = 1; |
167 | break; |
174 | break; |
168 | } |
175 | } |
Line 212... | Line 219... | ||
212 | bool found = false; |
219 | bool found = false; |
213 | 220 | ||
214 | /* Find unused or colliding |
221 | /* Find unused or colliding |
215 | PTE in PTEG */ |
222 | PTE in PTEG */ |
216 | for (i = 0; i < 8; i++) { |
223 | for (i = 0; i < 8; i++) { |
- | 224 | if ((!phte_physical[base + i].v) || |
|
217 | if ((!phte_physical[base + i].v) || ((phte_physical[base + i].vsid == vsid) && (phte_physical[base + i].api == api))) { |
225 | ((phte_physical[base + i].vsid == vsid) && |
- | 226 | (phte_physical[base + i].api == api))) { |
|
218 | found = true; |
227 | found = true; |
219 | break; |
228 | break; |
220 | } |
229 | } |
221 | } |
230 | } |
222 | 231 | ||
Line 225... | Line 234... | ||
225 | uint32_t base2 = (~hash & 0x3ff) << 3; |
234 | uint32_t base2 = (~hash & 0x3ff) << 3; |
226 | 235 | ||
227 | /* Find unused or colliding |
236 | /* Find unused or colliding |
228 | PTE in PTEG */ |
237 | PTE in PTEG */ |
229 | for (i = 0; i < 8; i++) { |
238 | for (i = 0; i < 8; i++) { |
- | 239 | if ((!phte_physical[base2 + i].v) || |
|
230 | if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) { |
240 | ((phte_physical[base2 + i].vsid == vsid) && |
- | 241 | (phte_physical[base2 + i].api == api))) { |
|
231 | found = true; |
242 | found = true; |
232 | base = base2; |
243 | base = base2; |
233 | h = 1; |
244 | h = 1; |
234 | break; |
245 | break; |
235 | } |
246 | } |
Line 282... | Line 293... | ||
282 | } else |
293 | } else |
283 | badvaddr = istate->pc; |
294 | badvaddr = istate->pc; |
284 | 295 | ||
285 | page_table_lock(as, lock); |
296 | page_table_lock(as, lock); |
286 | 297 | ||
287 | pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
298 | pte = find_mapping_and_check(as, lock, badvaddr, |
- | 299 | PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
|
288 | if (!pte) { |
300 | if (!pte) { |
289 | switch (pfrc) { |
301 | switch (pfrc) { |
290 | case AS_PF_FAULT: |
302 | case AS_PF_FAULT: |
291 | goto fail; |
303 | goto fail; |
292 | break; |
304 | break; |
Line 371... | Line 383... | ||
371 | ); |
383 | ); |
372 | phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); |
384 | phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); |
373 | 385 | ||
374 | uint32_t i; |
386 | uint32_t i; |
375 | for (i = 0; i < 8192; i++) { |
387 | for (i = 0; i < 8192; i++) { |
376 | if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && (phte[i].vsid < ((asid << 4) + 16))) |
388 | if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && |
- | 389 | (phte[i].vsid < ((asid << 4) + 16))) |
|
377 | phte[i].v = 0; |
390 | phte[i].v = 0; |
378 | } |
391 | } |
379 | tlb_invalidate_all(); |
392 | tlb_invalidate_all(); |
380 | } |
393 | } |
381 | 394 | ||
Line 405... | Line 418... | ||
405 | length <<= 1; \ |
418 | length <<= 1; \ |
406 | tmp >>= 1; \ |
419 | tmp >>= 1; \ |
407 | } \ |
420 | } \ |
408 | } else \ |
421 | } else \ |
409 | length = 0; \ |
422 | length = 0; \ |
410 | printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, lower & 0xffff0000, length, mask, ((upper >> 1) & 1) ? " supervisor" : "", (upper & 1) ? " user" : ""); |
423 | printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \ |
- | 424 | sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \ |
|
- | 425 | lower & 0xffff0000, length, mask, \ |
|
- | 426 | ((upper >> 1) & 1) ? " supervisor" : "", \ |
|
- | 427 | (upper & 1) ? " user" : ""); |
|
411 | 428 | ||
412 | 429 | ||
413 | void tlb_print(void) |
430 | void tlb_print(void) |
414 | { |
431 | { |
415 | uint32_t sr; |
432 | uint32_t sr; |
Line 419... | Line 436... | ||
419 | asm volatile ( |
436 | asm volatile ( |
420 | "mfsrin %0, %1\n" |
437 | "mfsrin %0, %1\n" |
421 | : "=r" (vsid) |
438 | : "=r" (vsid) |
422 | : "r" (sr << 28) |
439 | : "r" (sr << 28) |
423 | ); |
440 | ); |
- | 441 | printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, |
|
424 | printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, ((vsid >> 30) & 1) ? " supervisor" : "", ((vsid >> 29) & 1) ? " user" : ""); |
442 | sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, |
- | 443 | ((vsid >> 30) & 1) ? " supervisor" : "", |
|
- | 444 | ((vsid >> 29) & 1) ? " user" : ""); |
|
425 | } |
445 | } |
426 | 446 | ||
427 | uint32_t upper; |
447 | uint32_t upper; |
428 | uint32_t lower; |
448 | uint32_t lower; |
429 | uint32_t mask; |
449 | uint32_t mask; |