Index: sys/powerpc/aim/aim_machdep.c =================================================================== --- sys/powerpc/aim/aim_machdep.c +++ sys/powerpc/aim/aim_machdep.c @@ -476,14 +476,9 @@ * in case the platform module had a better idea of what we * should do. */ - if (cpu_features2 & PPC_FEATURE2_ARCH_3_00) { - radix_mmu = 0; - TUNABLE_INT_FETCH("radix_mmu", &radix_mmu); - if (radix_mmu) - pmap_mmu_install(MMU_TYPE_RADIX, BUS_PROBE_GENERIC); - else - pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); - } else if (cpu_features & PPC_FEATURE_64) + if (radix_mmu) + pmap_mmu_install(MMU_TYPE_RADIX, BUS_PROBE_GENERIC); + else if (cpu_features & PPC_FEATURE_64) pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); else pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); @@ -586,6 +581,25 @@ #endif +void +pmap_early_io_map_init(void) +{ + if ((cpu_features2 & PPC_FEATURE2_ARCH_3_00) == 0) + radix_mmu = 0; + else + TUNABLE_INT_FETCH("radix_mmu", &radix_mmu); + + /* + * When using Radix, set the start and end of kva early, to be able to + * use KVAs on pmap_early_io_map and avoid issues when remapping them + * later. + */ + if (radix_mmu) { + virtual_avail = VM_MIN_KERNEL_ADDRESS; + virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS; + } +} + /* * These functions need to provide addresses that both (a) work in real mode * (or whatever mode/circumstances the kernel is in in early boot (now)) and @@ -601,10 +615,20 @@ * If we have the MMU up in early boot, assume it is 1:1. Otherwise, * try to get the address in a memory region compatible with the * direct map for efficiency later. + * Except for Radix MMU, for which current implementation doesn't + * support mapping arbitrary virtual addresses, such as the ones + * generated by "direct mapping" I/O addresses. In this case, use + * addresses from KVA area. */ if (mfmsr() & PSL_DR) return (pa); - else + else if (radix_mmu) { + vm_offset_t va; + + va = virtual_avail; + virtual_avail += round_page(size + pa - trunc_page(pa)); + return (va); + } else return (DMAP_BASE_ADDRESS + pa); } Index: sys/powerpc/aim/mmu_radix.c =================================================================== --- sys/powerpc/aim/mmu_radix.c +++ sys/powerpc/aim/mmu_radix.c @@ -907,7 +907,7 @@ pt_entry_t *l3e; l3e = pmap_pml3e(kernel_pmap, va); - if ((be64toh(*l3e) & RPTE_VALID) == 0) + if (l3e == NULL || (be64toh(*l3e) & RPTE_VALID) == 0) return (NULL); return (pmap_l3e_to_pte(l3e, va)); } @@ -2071,12 +2071,6 @@ for (i = 0; phys_avail[i + 2] != 0; i += 2) Maxmem = MAX(Maxmem, powerpc_btop(phys_avail[i + 1])); - /* - * Set the start and end of kva. - */ - virtual_avail = VM_MIN_KERNEL_ADDRESS; - virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS; - /* * Remap any early IO mappings (console framebuffer, etc.) */ Index: sys/powerpc/include/pmap.h =================================================================== --- sys/powerpc/include/pmap.h +++ sys/powerpc/include/pmap.h @@ -340,6 +340,9 @@ extern int radix_mmu; extern int superpages_enabled; +#ifdef AIM +void pmap_early_io_map_init(void); +#endif vm_offset_t pmap_early_io_map(vm_paddr_t pa, vm_size_t size); void pmap_early_io_unmap(vm_offset_t va, vm_size_t size); void pmap_track_page(pmap_t pmap, vm_offset_t va); Index: sys/powerpc/powerpc/machdep.c =================================================================== --- sys/powerpc/powerpc/machdep.c +++ sys/powerpc/powerpc/machdep.c @@ -419,6 +419,15 @@ if (ofw_bootargs) ofw_parse_bootargs(); +#ifdef AIM + /* + * Early I/O map needs to be initialized before console, in order to + * map frame buffers properly, and after boot args have been parsed, + * to handle tunables properly. + */ + pmap_early_io_map_init(); +#endif + /* * Initialize the console before printing anything. */