diff --git a/sys/powerpc/aim/aim_machdep.c b/sys/powerpc/aim/aim_machdep.c index 0c476227fd7e..4d7ffa7dfd4e 100644 --- a/sys/powerpc/aim/aim_machdep.c +++ b/sys/powerpc/aim/aim_machdep.c @@ -390,6 +390,25 @@ aim_cpu_init(vm_offset_t toc) bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); + } else { + + /* + * Use an IBAT and a DBAT to map the bottom 256M segment. + * + * It is very important to do it *now* to avoid taking a + * fault in .text / .data before the MMU is bootstrapped, + * because until then, the translation data has not been + * copied over from OpenFirmware, so our DSI/ISI will fail + * to find a match. + */ + + battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW); + battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs); + + __asm (".balign 32; \n" + "mtibatu 0,%0; mtibatl 0,%1; isync; \n" + "mtdbatu 0,%0; mtdbatl 0,%1; isync" + :: "r"(battable[0].batu), "r"(battable[0].batl)); } #else trapsize = (size_t)&hypertrapcodeend - (size_t)&hypertrapcode; diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index 43b2c7480ddf..3b2fda4c852c 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -420,6 +420,32 @@ moea_calc_wimg(vm_paddr_t pa, vm_memattr_t ma) return pte_lo; } +/* + * Translate OFW translations into VM attributes. + */ +static __inline vm_memattr_t +moea_bootstrap_convert_wimg(uint32_t mode) +{ + + switch (mode) { + case (PTE_I | PTE_G): + /* PCI device memory */ + return VM_MEMATTR_UNCACHEABLE; + case (PTE_M): + /* Explicitly coherent */ + return VM_MEMATTR_CACHEABLE; + case 0: /* Default claim */ + case 2: /* Alternate PP bits set by OF for the original payload */ + /* "Normal" memory. */ + return VM_MEMATTR_DEFAULT; + + default: + /* Err on the side of caution for unknowns */ + /* XXX should we panic instead? */ + return VM_MEMATTR_UNCACHEABLE; + } +} + static void tlbie(vm_offset_t va) { @@ -670,13 +696,6 @@ moea_bootstrap(vm_offset_t kernelstart, vm_offset_t kernelend) vm_size_t size, physsz, hwphyssz; vm_offset_t pa, va, off; void *dpcpu; - register_t msr; - - /* - * Set up BAT0 to map the lowest 256 MB area - */ - battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW); - battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs); /* * Map PCI memory space. @@ -693,24 +712,7 @@ moea_bootstrap(vm_offset_t kernelstart, vm_offset_t kernelend) battable[0xb].batl = BATL(0xb0000000, BAT_I|BAT_G, BAT_PP_RW); battable[0xb].batu = BATU(0xb0000000, BAT_BL_256M, BAT_Vs); - /* - * Map obio devices. - */ - battable[0xf].batl = BATL(0xf0000000, BAT_I|BAT_G, BAT_PP_RW); - battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs); - - /* - * Use an IBAT and a DBAT to map the bottom segment of memory - * where we are. Turn off instruction relocation temporarily - * to prevent faults while reprogramming the IBAT. - */ - msr = mfmsr(); - mtmsr(msr & ~PSL_IR); - __asm (".balign 32; \n" - "mtibatu 0,%0; mtibatl 0,%1; isync; \n" - "mtdbatu 0,%0; mtdbatl 0,%1; isync" - :: "r"(battable[0].batu), "r"(battable[0].batl)); - mtmsr(msr); + powerpc_sync(); /* map pci space */ __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu)); @@ -910,15 +912,21 @@ moea_bootstrap(vm_offset_t kernelstart, vm_offset_t kernelend) /* * If the mapping is 1:1, let the RAM and device * on-demand BAT tables take care of the translation. + * + * However, always enter mappings for segment 16, + * which is mixed-protection and therefore not + * compatible with a BAT entry. */ - if (translations[i].om_va == translations[i].om_pa) - continue; + if ((translations[i].om_va >> ADDR_SR_SHFT) != 0xf && + translations[i].om_va == translations[i].om_pa) + continue; /* Enter the pages */ for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) - moea_kenter(translations[i].om_va + off, - translations[i].om_pa + off); + moea_kenter_attr(translations[i].om_va + off, + translations[i].om_pa + off, + moea_bootstrap_convert_wimg(translations[i].om_mode)); } }