Changes in kernel/arch/ppc32/src/mm/tlb.c [a000878c:8f80c77] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ppc32/src/mm/tlb.c
ra000878c r8f80c77 45 45 46 46 static unsigned int seed = 10; 47 static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;48 47 static unsigned int seed_real 48 __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42; 49 49 50 50 /** Try to find PTE for faulting address 51 51 * 52 * Try to find PTE for faulting address. 53 * The as->lock must be held on entry to this function 54 * if lock is true. 55 * 56 * @param as Address space. 57 * @param lock Lock/unlock the address space. 58 * @param badvaddr Faulting virtual address. 59 * @param access Access mode that caused the fault. 60 * @param istate Pointer to interrupted state. 61 * @param pfrc Pointer to variable where as_page_fault() return code 62 * will be stored. 63 * @return PTE on success, NULL otherwise. 64 * 65 */ 66 static pte_t * 67 find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, 52 * @param as Address space. 53 * @param lock Lock/unlock the address space. 54 * @param badvaddr Faulting virtual address. 55 * @param access Access mode that caused the fault. 56 * @param istate Pointer to interrupted state. 57 * @param pfrc Pointer to variable where as_page_fault() return code 58 * will be stored. 59 * 60 * @return PTE on success, NULL otherwise. 61 * 62 */ 63 static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access, 68 64 istate_t *istate, int *pfrc) 69 65 { 66 ASSERT(mutex_locked(&as->lock)); 67 70 68 /* 71 69 * Check if the mapping exists in page tables. 72 */ 70 */ 73 71 pte_t *pte = page_mapping_find(as, badvaddr); 74 72 if ((pte) && (pte->present)) { … … 79 77 return pte; 80 78 } else { 81 int rc;82 83 79 /* 84 80 * Mapping not found in page tables. 85 81 * Resort to higher-level page fault handler. 86 82 */ 87 page_table_unlock(as, lock); 88 switch (rc = as_page_fault(badvaddr, access, istate)) { 83 page_table_unlock(as, true); 84 85 int rc = as_page_fault(badvaddr, access, istate); 86 switch (rc) { 89 87 case AS_PF_OK: 90 88 /* … … 92 90 * The mapping ought to be in place. 93 91 */ 94 page_table_lock(as, lock);92 page_table_lock(as, true); 95 93 pte = page_mapping_find(as, badvaddr); 96 94 ASSERT((pte) && (pte->present)); … … 98 96 return pte; 99 97 case AS_PF_DEFER: 100 page_table_lock(as, lock);98 page_table_lock(as, true); 101 99 *pfrc = rc; 102 100 return NULL; 103 101 case AS_PF_FAULT: 104 page_table_lock(as, lock);102 page_table_lock(as, true); 105 103 *pfrc = rc; 106 104 return NULL; 107 105 default: 108 106 panic("Unexpected rc (%d).", rc); 109 } 110 } 111 } 112 107 } 108 } 109 } 113 110 114 111 static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate) … … 123 120 } 124 121 125 126 122 static void pht_insert(const uintptr_t vaddr, const pte_t *pte) 127 123 { … … 129 125 uint32_t api = (vaddr >> 22) & 0x3f; 130 126 131 uint32_t vsid; 132 asm volatile ( 133 "mfsrin %0, %1\n" 134 : "=r" (vsid) 135 : "r" (vaddr) 136 ); 137 138 uint32_t sdr1; 139 asm volatile ( 140 "mfsdr1 %0\n" 141 : "=r" (sdr1) 142 ); 127 uint32_t vsid = sr_get(vaddr); 128 uint32_t sdr1 = sdr1_get(); 129 130 // FIXME: compute size of PHT exactly 143 131 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 144 132 … … 215 203 } 216 204 217 218 205 /** Process Instruction/Data Storage Exception 219 206 * … … 224 211 void pht_refill(int n, istate_t *istate) 225 212 { 213 as_t *as = (AS == NULL) ? AS_KERNEL : AS; 226 214 uintptr_t badvaddr; 227 pte_t *pte;228 int pfrc;229 as_t *as;230 bool lock;231 232 if (AS == NULL) {233 as = AS_KERNEL;234 lock = false;235 } else {236 as = AS;237 lock = true;238 }239 215 240 216 if (n == VECTOR_DATA_STORAGE) … … 242 218 else 243 219 badvaddr = istate->pc; 244 245 page_table_lock(as, lock); 246 247 pte = find_mapping_and_check(as, lock, badvaddr, 220 221 page_table_lock(as, true); 222 223 int pfrc; 224 pte_t *pte = find_mapping_and_check(as, badvaddr, 248 225 PF_ACCESS_READ /* FIXME */, istate, &pfrc); 226 249 227 if (!pte) { 250 228 switch (pfrc) { … … 257 235 * or copy_to_uspace(). 258 236 */ 259 page_table_unlock(as, lock);237 page_table_unlock(as, true); 260 238 return; 261 239 default: … … 264 242 } 265 243 266 pte->accessed = 1; /* Record access to PTE */ 244 /* Record access to PTE */ 245 pte->accessed = 1; 267 246 pht_insert(badvaddr, pte); 268 247 269 page_table_unlock(as, lock);248 page_table_unlock(as, true); 270 249 return; 271 250 272 251 fail: 273 page_table_unlock(as, lock);252 page_table_unlock(as, true); 274 253 pht_refill_fail(badvaddr, istate); 275 254 } 276 277 255 278 256 /** Process Instruction/Data Storage Exception in Real Mode … … 291 269 badvaddr = istate->pc; 292 270 293 uint32_t physmem; 294 asm volatile ( 295 "mfsprg3 %0\n" 296 : "=r" (physmem) 297 ); 271 uint32_t physmem = physmem_top(); 298 272 299 273 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) … … 303 277 uint32_t api = (badvaddr >> 22) & 0x3f; 304 278 305 uint32_t vsid; 306 asm volatile ( 307 "mfsrin %0, %1\n" 308 : "=r" (vsid) 309 : "r" (badvaddr) 310 ); 311 312 uint32_t sdr1; 313 asm volatile ( 314 "mfsdr1 %0\n" 315 : "=r" (sdr1) 316 ); 279 uint32_t vsid = sr_get(badvaddr); 280 uint32_t sdr1 = sdr1_get(); 281 282 // FIXME: compute size of PHT exactly 317 283 phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); 318 284 … … 396 362 } 397 363 398 399 364 /** Process ITLB/DTLB Miss Exception in Real Mode 400 365 * … … 404 369 { 405 370 uint32_t badvaddr = tlbmiss & 0xfffffffc; 406 407 uint32_t physmem; 408 asm volatile ( 409 "mfsprg3 %0\n" 410 : "=r" (physmem) 411 ); 371 uint32_t physmem = physmem_top(); 412 372 413 373 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) … … 420 380 uint32_t index = 0; 421 381 asm volatile ( 422 "mtspr 981, % 0\n"423 "mtspr 982, % 1\n"424 "tlbld % 2\n"425 "tlbli % 2\n"426 : "=r" (index)427 : "r" (ptehi),428 "r" (ptelo)382 "mtspr 981, %[ptehi]\n" 383 "mtspr 982, %[ptelo]\n" 384 "tlbld %[index]\n" 385 "tlbli %[index]\n" 386 : [index] "=r" (index) 387 : [ptehi] "r" (ptehi), 388 [ptelo] "r" (ptelo) 429 389 ); 430 390 } 431 391 432 433 392 void tlb_arch_init(void) 434 393 { … … 436 395 } 437 396 438 439 397 void tlb_invalidate_all(void) 440 398 { 441 399 uint32_t index; 400 442 401 asm volatile ( 443 "li % 0, 0\n"402 "li %[index], 0\n" 444 403 "sync\n" 445 404 446 405 ".rept 64\n" 447 " tlbie %0\n"448 " addi %0, %0, 0x1000\n"406 " tlbie %[index]\n" 407 " addi %[index], %[index], 0x1000\n" 449 408 ".endr\n" 450 409 … … 452 411 "tlbsync\n" 453 412 "sync\n" 454 : "=r" (index)413 : [index] "=r" (index) 455 414 ); 456 415 } 457 416 458 459 417 void tlb_invalidate_asid(asid_t asid) 460 418 { 461 uint32_t sdr1; 462 asm volatile ( 463 "mfsdr1 %0\n" 464 : "=r" (sdr1) 465 ); 419 uint32_t sdr1 = sdr1_get(); 420 421 // FIXME: compute size of PHT exactly 466 422 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 467 423 468 uint32_t i;424 size_t i; 469 425 for (i = 0; i < 8192; i++) { 470 426 if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && … … 472 428 phte[i].v = 0; 473 429 } 430 474 431 tlb_invalidate_all(); 475 432 } 476 477 433 478 434 void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) … … 482 438 } 483 439 484 485 440 #define PRINT_BAT(name, ureg, lreg) \ 486 441 asm volatile ( \ 487 "mfspr %0," #ureg "\n" \ 488 "mfspr %1," #lreg "\n" \ 489 : "=r" (upper), "=r" (lower) \ 442 "mfspr %[upper], " #ureg "\n" \ 443 "mfspr %[lower], " #lreg "\n" \ 444 : [upper] "=r" (upper), \ 445 [lower] "=r" (lower) \ 490 446 ); \ 447 \ 491 448 mask = (upper & 0x1ffc) >> 2; \ 492 449 if (upper & 3) { \ 493 450 uint32_t tmp = mask; \ 494 451 length = 128; \ 452 \ 495 453 while (tmp) { \ 496 454 if ((tmp & 1) == 0) { \ … … 503 461 } else \ 504 462 length = 0; \ 463 \ 505 464 printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \ 506 465 sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \ … … 515 474 516 475 for (sr = 0; sr < 16; sr++) { 517 uint32_t vsid; 518 asm volatile ( 519 "mfsrin %0, %1\n" 520 : "=r" (vsid) 521 : "r" (sr << 28) 522 ); 476 uint32_t vsid = sr_get(sr << 28); 477 523 478 printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr, 524 479 sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
Note:
See TracChangeset
for help on using the changeset viewer.