Index: sys/powerpc/booke/pmap.c =================================================================== --- sys/powerpc/booke/pmap.c +++ sys/powerpc/booke/pmap.c @@ -958,7 +958,7 @@ pmap->pm_pdir[pdir_idx] = ptbl; } pte = &(pmap->pm_pdir[pdir_idx][ptbl_idx]); - pte->rpn = VM_PAGE_TO_PHYS(m) & ~PTE_PA_MASK; + pte->rpn = PTE_RPN_FROM_PA(VM_PAGE_TO_PHYS(m)); pte->flags |= (PTE_VALID | flags); tlb_miss_unlock(); @@ -1121,7 +1121,7 @@ /* Calculate corresponding physical addresses for the kernel region. */ phys_kernelend = kernload + kernsize; debugf("kernel image and allocated data:\n"); - debugf(" kernload = 0x%08x\n", kernload); + debugf(" kernload = 0x%09llx\n", (uint64_t)kernload); debugf(" kernstart = 0x%08x\n", kernstart); debugf(" kernsize = 0x%08x\n", kernsize); @@ -1307,7 +1307,7 @@ thread0.td_kstack_pages = KSTACK_PAGES; debugf("kstack_sz = 0x%08x\n", kstack0_sz); - debugf("kstack0_phys at 0x%08x - 0x%08x\n", + debugf("kstack0_phys at 0x%09llx - 0x%09llx\n", kstack0_phys, kstack0_phys + kstack0_sz); debugf("kstack0 at 0x%08x - 0x%08x\n", kstack0, kstack0 + kstack0_sz); @@ -1488,7 +1488,7 @@ tlb0_flush_entry(va); } - pte->rpn = pa & ~PTE_PA_MASK; + pte->rpn = PTE_RPN_FROM_PA(pa); pte->flags = flags; //debugf("mmu_booke_kenter: pdir_idx = %d ptbl_idx = %d va=0x%08x " @@ -2553,7 +2553,7 @@ /* Minidumps are based on virtual memory addresses. */ if (do_minidump) { - *va = (void *)pa; + *va = (void *)(vm_offset_t)pa; return; } @@ -2697,7 +2697,7 @@ if (pa >= tlb1[i].phys && (pa + size) <= (tlb1[i].phys + tlb1[i].size)) return (void *)(tlb1[i].virt + - (pa - tlb1[i].phys)); + (vm_offset_t)(pa - tlb1[i].phys)); } } @@ -2725,7 +2725,7 @@ do { sz = 1 << (ilog2(size) & ~1); if (bootverbose) - printf("Wiring VA=%x to PA=%x (size=%x), " + printf("Wiring VA=%x to PA=%llx (size=%x), " "using TLB1[%d]\n", va, pa, sz, tlb1_idx); tlb1_set_entry(va, pa, sz, tlb_calc_wimg(pa, ma)); size -= sz; @@ -2947,13 +2947,10 @@ static void tlb1_write_entry(unsigned int idx) { - uint32_t mas0, mas7; + uint32_t mas0; //debugf("tlb1_write_entry: s\n"); - /* Clear high order RPN bits */ - mas7 = 0; - /* Select entry */ mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(idx); //debugf("tlb1_write_entry: mas0 = 0x%08x\n", mas0); @@ -2966,7 +2963,7 @@ __asm __volatile("isync"); mtspr(SPR_MAS3, tlb1[idx].mas3); __asm __volatile("isync"); - mtspr(SPR_MAS7, mas7); + mtspr(SPR_MAS7, tlb1[idx].mas7); __asm __volatile("isync; tlbwe; isync; msync"); //debugf("tlb1_write_entry: e\n"); @@ -3049,6 +3046,7 @@ /* Set supervisor RWX permission bits */ tlb1[index].mas3 = (pa & MAS3_RPN) | MAS3_SR | MAS3_SW | MAS3_SX; + tlb1[index].mas7 = (pa >> 32); tlb1_write_entry(index); @@ -3112,7 +3110,7 @@ for (idx = 0; idx < nents; idx++) { pgsz = pgs[idx]; - debugf("%u: %x -> %x, size=%x\n", idx, pa, va, pgsz); + debugf("%u: %llx -> %x, size=%x\n", idx, pa, va, pgsz); tlb1_set_entry(va, pa, pgsz, _TLB_ENTRY_MEM); pa += pgsz; va += pgsz; @@ -3131,7 +3129,7 @@ void tlb1_init() { - uint32_t mas0, mas1, mas2, mas3; + uint32_t mas0, mas1, mas2, mas3, mas7; uint32_t tsz; u_int i; @@ -3152,12 +3150,14 @@ mas2 = mfspr(SPR_MAS2); mas3 = mfspr(SPR_MAS3); + mas7 = mfspr(SPR_MAS7); tlb1[i].mas1 = mas1; tlb1[i].mas2 = mfspr(SPR_MAS2); tlb1[i].mas3 = mas3; tlb1[i].virt = mas2 & MAS2_EPN_MASK; - tlb1[i].phys = mas3 & MAS3_RPN; + tlb1[i].phys = ((vm_paddr_t)(mas7 & MAS7_RPN) << 32) | + (mas3 & MAS3_RPN); if (i == 0) kernload = tlb1[i].phys; @@ -3310,7 +3310,8 @@ KASSERT((entry_tsize), ("tlb1_iomapped: invalid entry tsize")); entry_size = tsize2size(entry_tsize); - pa_start = tlb1[i].mas3 & MAS3_RPN; + pa_start = (((vm_paddr_t)tlb1[i].mas7 & MAS7_RPN) << 32) | + (tlb1[i].mas3 & MAS3_RPN); pa_end = pa_start + entry_size - 1; if ((pa < pa_start) || ((pa + size) > pa_end)) Index: sys/powerpc/booke/trap_subr.S =================================================================== --- sys/powerpc/booke/trap_subr.S +++ sys/powerpc/booke/trap_subr.S @@ -697,8 +697,10 @@ /* Setup MAS3 value in r23. */ lwz %r23, PTE_RPN(%r25) /* get pte->rpn */ + rlwinm %r22, %r23, 12, 0, 20 /* extract MAS3 portion of RPN */ - rlwimi %r23, %r21, 24, 26, 31 /* insert protection bits from pte */ + rlwimi %r22, %r21, 24, 26, 31 /* insert protection bits from pte */ + rlwinm %r23, %r23, 12, 28, 31 /* MAS7 portion of RPN */ /* Load MAS registers. */ mtspr SPR_MAS0, %r29 @@ -707,7 +709,9 @@ isync mtspr SPR_MAS2, %r27 isync - mtspr SPR_MAS3, %r23 + mtspr SPR_MAS3, %r22 + isync + mtspr SPR_MAS7, %r23 isync tlbwe Index: sys/powerpc/include/_types.h =================================================================== --- sys/powerpc/include/_types.h +++ sys/powerpc/include/_types.h @@ -128,7 +128,11 @@ #else typedef __uint32_t __u_register_t; typedef __uint32_t __vm_offset_t; +#ifdef BOOKE +typedef __uint64_t __vm_paddr_t; +#else typedef __uint32_t __vm_paddr_t; +#endif typedef __uint32_t __vm_size_t; #endif typedef __int64_t __vm_ooffset_t; Index: sys/powerpc/include/pte.h =================================================================== --- sys/powerpc/include/pte.h +++ sys/powerpc/include/pte.h @@ -207,10 +207,13 @@ /* * Page Table Entry definitions and macros. + * + * RPN need only be 32-bit because Book-E has 36-bit addresses, and the smallest + * page size is 4k (12-bit mask), so RPN can really fit into 24 bits. */ #ifndef LOCORE struct pte { - vm_paddr_t rpn; + vm_offset_t rpn; uint32_t flags; }; typedef struct pte pte_t; @@ -266,7 +269,9 @@ #define PTE_REFERENCED 0x04000000 /* Referenced */ /* Macro argument must of pte_t type. */ -#define PTE_PA(pte) ((pte)->rpn & ~PTE_PA_MASK) +#define PTE_PA_SHIFT 12 +#define PTE_RPN_FROM_PA(pa) ((pa) >> PTE_PA_SHIFT) +#define PTE_PA(pte) ((vm_paddr_t)((pte)->rpn) << PTE_PA_SHIFT) #define PTE_ISVALID(pte) ((pte)->flags & PTE_VALID) #define PTE_ISWIRED(pte) ((pte)->flags & PTE_WIRED) #define PTE_ISMANAGED(pte) ((pte)->flags & PTE_MANAGED) Index: sys/powerpc/include/tlb.h =================================================================== --- sys/powerpc/include/tlb.h +++ sys/powerpc/include/tlb.h @@ -106,6 +106,8 @@ #define MAS6_SPID0_SHIFT 16 #define MAS6_SAS 0x00000001 +#define MAS7_RPN 0x0000000F + #define MAS1_GETTID(mas1) (((mas1) & MAS1_TID_MASK) >> MAS1_TID_SHIFT) #define MAS2_TLB0_ENTRY_IDX_MASK 0x0007f000 @@ -132,6 +134,7 @@ uint32_t mas1; uint32_t mas2; uint32_t mas3; + uint32_t mas7; } tlb_entry_t; void tlb0_print_tlbentries(void); Index: sys/powerpc/powerpc/uma_machdep.c =================================================================== --- sys/powerpc/powerpc/uma_machdep.c +++ sys/powerpc/powerpc/uma_machdep.c @@ -53,6 +53,7 @@ uma_small_alloc(uma_zone_t zone, vm_size_t bytes, u_int8_t *flags, int wait) { void *va; + vm_paddr_t pa; vm_page_t m; int pflags; @@ -69,7 +70,13 @@ break; } - va = (void *) VM_PAGE_TO_PHYS(m); + pa = VM_PAGE_TO_PHYS(m); + + /* On book-e sizeof(void *) < sizeof(vm_paddr_t) */ + if ((vm_offset_t)pa != pa) + return (NULL); + + va = (void *)(vm_offset_t)pa; if (!hw_direct_map) pmap_kenter((vm_offset_t)va, VM_PAGE_TO_PHYS(m));