static int mmu_mapin(vm_offset_t va, vm_size_t len) { vm_offset_t pa, mva; u_long data; if (va + len > curkva) curkva = va + len; pa = (vm_offset_t)-1; len += va & PAGE_MASK_4M; va &= ~PAGE_MASK_4M; while (len) { if (dtlb_va_to_pa(va) == (vm_offset_t)-1 || itlb_va_to_pa(va) == (vm_offset_t)-1) { /* Allocate a physical page, claim the virtual area */ if (pa == (vm_offset_t)-1) { pa = (vm_offset_t)OF_alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M); if (pa == (vm_offset_t)-1) panic("out of memory"); mva = (vm_offset_t)OF_claim_virt(va, PAGE_SIZE_4M, 0); if (mva != va) { panic("can't claim virtual page " "(wanted %#lx, got %#lx)", va, mva); } /* The mappings may have changed, be paranoid. */ continue; } /* * Actually, we can only allocate two pages less at * most (depending on the kernel TSB size). */ if (dtlb_slot >= dtlb_slot_max) panic("mmu_mapin: out of dtlb_slots"); if (itlb_slot >= itlb_slot_max) panic("mmu_mapin: out of itlb_slots"); data = TD_V | TD_4M | TD_PA(pa) | TD_L | TD_CP | TD_CV | TD_P | TD_W; dtlb_store[dtlb_slot].te_pa = pa; dtlb_store[dtlb_slot].te_va = va; itlb_store[itlb_slot].te_pa = pa; itlb_store[itlb_slot].te_va = va; dtlb_slot++; itlb_slot++; dtlb_enter(va, data); itlb_enter(va, data); pa = (vm_offset_t)-1; } len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len; va += PAGE_SIZE_4M; } if (pa != (vm_offset_t)-1) OF_release_phys(pa, PAGE_SIZE_4M); return 0; }
void mp_init(void) { struct tte *tp; int i; mp_tramp = (vm_offset_t)OF_claim(NULL, PAGE_SIZE, PAGE_SIZE); if (mp_tramp == (vm_offset_t)-1) panic("%s", __func__); bcopy(mp_tramp_code, (void *)mp_tramp, mp_tramp_code_len); *(vm_offset_t *)(mp_tramp + mp_tramp_tlb_slots) = kernel_tlb_slots; *(vm_offset_t *)(mp_tramp + mp_tramp_func) = (vm_offset_t)mp_startup; tp = (struct tte *)(mp_tramp + mp_tramp_code_len); for (i = 0; i < kernel_tlb_slots; i++) { tp[i].tte_vpn = TV_VPN(kernel_tlbs[i].te_va, TS_4M); tp[i].tte_data = TD_V | TD_4M | TD_PA(kernel_tlbs[i].te_pa) | TD_L | TD_CP | TD_CV | TD_P | TD_W; } for (i = 0; i < PAGE_SIZE; i += sizeof(vm_offset_t)) flush(mp_tramp + i); }
static void pmap_print_tte(tte_t tag, tte_t tte) { printf("%s %s ", page_sizes[(tte & TD_SIZE_MASK) >> TD_SIZE_SHIFT], tag & TD_G ? "G" : " "); printf(tte & TD_W ? "W " : " "); printf(tte & TD_P ? "\e[33mP\e[0m " : " "); printf(tte & TD_E ? "E " : " "); printf(tte & TD_CV ? "CV " : " "); printf(tte & TD_CP ? "CP " : " "); printf(tte & TD_L ? "\e[32mL\e[0m " : " "); printf(tte & TD_IE ? "IE " : " "); printf(tte & TD_NFO ? "NFO " : " "); printf("tag=0x%lx pa=0x%lx va=0x%lx ctx=%ld\n", tag, TD_PA(tte), TT_VA(tag), TT_CTX(tag)); } void pmap_print_tlb(char which) { int i; tte_t tte, tag; for (i = 0; i < 64*8; i += 8) { if (which == 'i') { __asm__ __volatile__("ldxa [%1] %2, %0\n" : "=r" (tag) : "r" (i), "i" (ASI_ITLB_TAG_READ_REG)); __asm__ __volatile__("ldxa [%1] %2, %0\n" : "=r" (tte) : "r" (i),