Changeset 46c20c8 in mainline for kernel/arch/ppc32/src/mm
- Timestamp:
- 2010-11-26T20:08:10Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 45df59a
- Parents:
- fb150d78 (diff), ffdd2b9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- kernel/arch/ppc32/src/mm
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ppc32/src/mm/as.c
rfb150d78 r46c20c8 55 55 void as_install_arch(as_t *as) 56 56 { 57 asid_t asid;58 57 uint32_t sr; 59 60 asid = as->asid;61 58 62 59 /* Lower 2 GB, user and supervisor access */ 63 for (sr = 0; sr < 8; sr++) { 64 asm volatile ( 65 "mtsrin %0, %1\n" 66 : 67 : "r" ((0x6000 << 16) + (asid << 4) + sr), "r" (sr << 28) 68 ); 69 } 60 for (sr = 0; sr < 8; sr++) 61 sr_set(0x6000, as->asid, sr); 70 62 71 63 /* Upper 2 GB, only supervisor access */ 72 for (sr = 8; sr < 16; sr++) { 73 asm volatile ( 74 "mtsrin %0, %1\n" 75 : 76 : "r" ((0x4000 << 16) + (asid << 4) + sr), "r" (sr << 28) 77 ); 78 } 64 for (sr = 8; sr < 16; sr++) 65 sr_set(0x4000, as->asid, sr); 79 66 } 80 67 -
kernel/arch/ppc32/src/mm/frame.c
rfb150d78 r46c20c8 27 27 */ 28 28 29 /** @addtogroup ppc32mm 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 41 41 42 42 uintptr_t last_frame = 0; 43 memmap_t memmap; 43 44 44 45 void physmem_print(void) 45 46 { 46 unsigned int i;47 printf("[base ] [size ]\n"); 47 48 48 printf("Base Size\n"); 49 printf("---------- ----------\n"); 50 51 for (i = 0; i < bootinfo.memmap.count; i++) { 52 printf("%#10x %#10x\n", bootinfo.memmap.zones[i].start, 53 bootinfo.memmap.zones[i].size); 49 size_t i; 50 for (i = 0; i < memmap.cnt; i++) { 51 printf("%p %#0zx\n", memmap.zones[i].start, 52 memmap.zones[i].size); 54 53 } 55 54 } … … 59 58 pfn_t minconf = 2; 60 59 size_t i; 61 pfn_t start, conf;62 size_t size;63 60 64 for (i = 0; i < bootinfo.memmap.count; i++) { 65 start = ADDR2PFN(ALIGN_UP(bootinfo.memmap.zones[i].start, FRAME_SIZE)); 66 size = SIZE2FRAMES(ALIGN_DOWN(bootinfo.memmap.zones[i].size, FRAME_SIZE)); 61 for (i = 0; i < memmap.cnt; i++) { 62 /* To be safe, make the available zone possibly smaller */ 63 uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start, 64 FRAME_SIZE); 65 size_t new_size = ALIGN_DOWN(memmap.zones[i].size - 66 (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE); 67 67 68 if ((minconf < start) || (minconf >= start + size)) 69 conf = start; 68 pfn_t pfn = ADDR2PFN(new_start); 69 size_t count = SIZE2FRAMES(new_size); 70 71 pfn_t conf; 72 if ((minconf < pfn) || (minconf >= pfn + count)) 73 conf = pfn; 70 74 else 71 75 conf = minconf; 72 76 73 zone_create(start, size, conf, 0); 74 if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE)) 75 last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE); 77 zone_create(pfn, count, conf, 0); 78 79 if (last_frame < ALIGN_UP(new_start + new_size, FRAME_SIZE)) 80 last_frame = ALIGN_UP(new_start + new_size, FRAME_SIZE); 76 81 } 77 82 … … 81 86 82 87 /* Mark the Page Hash Table frames as unavailable */ 83 uint32_t sdr1; 84 asm volatile ( 85 "mfsdr1 %0\n" 86 : "=r" (sdr1) 87 ); 88 frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); // FIXME 88 uint32_t sdr1 = sdr1_get(); 89 90 // FIXME: compute size of PHT exactly 91 frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); 89 92 } 90 93 -
kernel/arch/ppc32/src/mm/page.c
rfb150d78 r46c20c8 45 45 } 46 46 47 48 47 uintptr_t hw_map(uintptr_t physaddr, size_t size) 49 48 { 50 49 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > 51 50 KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 52 panic("Unable to map physical memory %p (% " PRIs "bytes).",53 physaddr, size);51 panic("Unable to map physical memory %p (%zu bytes).", 52 (void *) physaddr, size); 54 53 55 54 uintptr_t virtaddr = PA2KA(last_frame); 56 55 pfn_t i; 56 page_table_lock(AS_KERNEL, true); 57 57 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) 58 58 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), 59 59 physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); 60 page_table_unlock(AS_KERNEL, true); 60 61 61 62 last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); -
kernel/arch/ppc32/src/mm/tlb.c
rfb150d78 r46c20c8 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) 115 112 { 116 char *symbol; 117 char *sym2; 118 119 symbol = symtab_fmt_name_lookup(istate->pc); 120 sym2 = symtab_fmt_name_lookup(istate->lr); 121 122 fault_if_from_uspace(istate, 123 "PHT Refill Exception on %p.", badvaddr); 124 panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr, 125 istate->pc, symbol, sym2); 126 } 127 113 fault_if_from_uspace(istate, "PHT Refill Exception on %p.", 114 (void *) badvaddr); 115 panic_memtrap(istate, PF_ACCESS_UNKNOWN, badvaddr, 116 "PHT Refill Exception."); 117 } 128 118 129 119 static void pht_insert(const uintptr_t vaddr, const pte_t *pte) … … 132 122 uint32_t api = (vaddr >> 22) & 0x3f; 133 123 134 uint32_t vsid; 135 asm volatile ( 136 "mfsrin %0, %1\n" 137 : "=r" (vsid) 138 : "r" (vaddr) 139 ); 140 141 uint32_t sdr1; 142 asm volatile ( 143 "mfsdr1 %0\n" 144 : "=r" (sdr1) 145 ); 124 uint32_t vsid = sr_get(vaddr); 125 uint32_t sdr1 = sdr1_get(); 126 127 // FIXME: compute size of PHT exactly 146 128 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 147 129 … … 218 200 } 219 201 220 221 202 /** Process Instruction/Data Storage Exception 222 203 * … … 225 206 * 226 207 */ 227 void pht_refill(int n, istate_t *istate) 228 { 208 void pht_refill(unsigned int n, istate_t *istate) 209 { 210 as_t *as = (AS == NULL) ? AS_KERNEL : AS; 229 211 uintptr_t badvaddr; 230 pte_t *pte;231 int pfrc;232 as_t *as;233 bool lock;234 235 if (AS == NULL) {236 as = AS_KERNEL;237 lock = false;238 } else {239 as = AS;240 lock = true;241 }242 212 243 213 if (n == VECTOR_DATA_STORAGE) … … 245 215 else 246 216 badvaddr = istate->pc; 247 248 page_table_lock(as, lock); 249 250 pte = find_mapping_and_check(as, lock, badvaddr, 217 218 page_table_lock(as, true); 219 220 int pfrc; 221 pte_t *pte = find_mapping_and_check(as, badvaddr, 251 222 PF_ACCESS_READ /* FIXME */, istate, &pfrc); 223 252 224 if (!pte) { 253 225 switch (pfrc) { … … 260 232 * or copy_to_uspace(). 261 233 */ 262 page_table_unlock(as, lock);234 page_table_unlock(as, true); 263 235 return; 264 236 default: … … 267 239 } 268 240 269 pte->accessed = 1; /* Record access to PTE */ 241 /* Record access to PTE */ 242 pte->accessed = 1; 270 243 pht_insert(badvaddr, pte); 271 244 272 page_table_unlock(as, lock);245 page_table_unlock(as, true); 273 246 return; 274 247 275 248 fail: 276 page_table_unlock(as, lock);249 page_table_unlock(as, true); 277 250 pht_refill_fail(badvaddr, istate); 278 251 } 279 280 252 281 253 /** Process Instruction/Data Storage Exception in Real Mode … … 285 257 * 286 258 */ 287 bool pht_refill_real( int n, istate_t *istate)259 bool pht_refill_real(unsigned int n, istate_t *istate) 288 260 { 289 261 uintptr_t badvaddr; … … 294 266 badvaddr = istate->pc; 295 267 296 uint32_t physmem; 297 asm volatile ( 298 "mfsprg3 %0\n" 299 : "=r" (physmem) 300 ); 268 uint32_t physmem = physmem_top(); 301 269 302 270 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) … … 306 274 uint32_t api = (badvaddr >> 22) & 0x3f; 307 275 308 uint32_t vsid; 309 asm volatile ( 310 "mfsrin %0, %1\n" 311 : "=r" (vsid) 312 : "r" (badvaddr) 313 ); 314 315 uint32_t sdr1; 316 asm volatile ( 317 "mfsdr1 %0\n" 318 : "=r" (sdr1) 319 ); 276 uint32_t vsid = sr_get(badvaddr); 277 uint32_t sdr1 = sdr1_get(); 278 279 // FIXME: compute size of PHT exactly 320 280 phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); 321 281 … … 399 359 } 400 360 401 402 361 /** Process ITLB/DTLB Miss Exception in Real Mode 403 362 * 404 363 * 405 364 */ 406 void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) 365 void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi, 366 ptelo_t ptelo, istate_t *istate) 407 367 { 408 368 uint32_t badvaddr = tlbmiss & 0xfffffffc; 409 410 uint32_t physmem; 411 asm volatile ( 412 "mfsprg3 %0\n" 413 : "=r" (physmem) 414 ); 369 uint32_t physmem = physmem_top(); 415 370 416 371 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) … … 423 378 uint32_t index = 0; 424 379 asm volatile ( 425 "mtspr 981, % 0\n"426 "mtspr 982, % 1\n"427 "tlbld % 2\n"428 "tlbli % 2\n"429 : "=r" (index)430 : "r" (ptehi),431 "r" (ptelo)380 "mtspr 981, %[ptehi]\n" 381 "mtspr 982, %[ptelo]\n" 382 "tlbld %[index]\n" 383 "tlbli %[index]\n" 384 : [index] "=r" (index) 385 : [ptehi] "r" (ptehi), 386 [ptelo] "r" (ptelo) 432 387 ); 433 388 } 434 389 435 436 390 void tlb_arch_init(void) 437 391 { … … 439 393 } 440 394 441 442 395 void tlb_invalidate_all(void) 443 396 { 444 397 uint32_t index; 398 445 399 asm volatile ( 446 "li % 0, 0\n"400 "li %[index], 0\n" 447 401 "sync\n" 448 402 449 403 ".rept 64\n" 450 " tlbie %0\n"451 " addi %0, %0, 0x1000\n"404 " tlbie %[index]\n" 405 " addi %[index], %[index], 0x1000\n" 452 406 ".endr\n" 453 407 … … 455 409 "tlbsync\n" 456 410 "sync\n" 457 : "=r" (index)411 : [index] "=r" (index) 458 412 ); 459 413 } 460 414 461 462 415 void tlb_invalidate_asid(asid_t asid) 463 416 { 464 uint32_t sdr1; 465 asm volatile ( 466 "mfsdr1 %0\n" 467 : "=r" (sdr1) 468 ); 417 uint32_t sdr1 = sdr1_get(); 418 419 // FIXME: compute size of PHT exactly 469 420 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 470 421 471 uint32_t i;422 size_t i; 472 423 for (i = 0; i < 8192; i++) { 473 424 if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && … … 475 426 phte[i].v = 0; 476 427 } 428 477 429 tlb_invalidate_all(); 478 430 } 479 480 431 481 432 void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) … … 485 436 } 486 437 487 488 438 #define PRINT_BAT(name, ureg, lreg) \ 489 439 asm volatile ( \ 490 "mfspr %0," #ureg "\n" \ 491 "mfspr %1," #lreg "\n" \ 492 : "=r" (upper), "=r" (lower) \ 440 "mfspr %[upper], " #ureg "\n" \ 441 "mfspr %[lower], " #lreg "\n" \ 442 : [upper] "=r" (upper), \ 443 [lower] "=r" (lower) \ 493 444 ); \ 445 \ 494 446 mask = (upper & 0x1ffc) >> 2; \ 495 447 if (upper & 3) { \ 496 448 uint32_t tmp = mask; \ 497 449 length = 128; \ 450 \ 498 451 while (tmp) { \ 499 452 if ((tmp & 1) == 0) { \ … … 506 459 } else \ 507 460 length = 0; \ 508 printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \ 509 sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \ 510 lower & 0xffff0000, length, mask, \ 461 \ 462 printf(name ": page=%#0" PRIx32 " frame=%#0" PRIx32 \ 463 " length=%#0" PRIx32 " KB (mask=%#0" PRIx32 ")%s%s\n", \ 464 upper & UINT32_C(0xffff0000), lower & UINT32_C(0xffff0000), \ 465 length, mask, \ 511 466 ((upper >> 1) & 1) ? " supervisor" : "", \ 512 467 (upper & 1) ? " user" : ""); 513 468 514 515 469 void tlb_print(void) 516 470 { … … 518 472 519 473 for (sr = 0; sr < 16; sr++) { 520 uint32_t vsid; 521 asm volatile ( 522 "mfsrin %0, %1\n" 523 : "=r" (vsid) 524 : "r" (sr << 28) 525 ); 526 printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr, 527 sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, 474 uint32_t vsid = sr_get(sr << 28); 475 476 printf("sr[%02" PRIu32 "]: vsid=%#0" PRIx32 " (asid=%" PRIu32 ")" 477 "%s%s\n", sr, vsid & UINT32_C(0x00ffffff), 478 (vsid & UINT32_C(0x00ffffff)) >> 4, 528 479 ((vsid >> 30) & 1) ? " supervisor" : "", 529 480 ((vsid >> 29) & 1) ? " user" : "");
Note:
See TracChangeset
for help on using the changeset viewer.
