diff --git a/sys/conf/options.powerpc b/sys/conf/options.powerpc index 463c2b9da8c7..5d8e91a92e56 100644 --- a/sys/conf/options.powerpc +++ b/sys/conf/options.powerpc @@ -25,7 +25,7 @@ POWERMAC opt_platform.h PS3 opt_platform.h MAMBO POWERNV opt_platform.h -PSERIES +PSERIES opt_platform.h PSIM QEMU opt_platform.h diff --git a/sys/powerpc/aim/mmu_radix.c b/sys/powerpc/aim/mmu_radix.c index 58fca5dec471..8c3f6e2cf37a 100644 --- a/sys/powerpc/aim/mmu_radix.c +++ b/sys/powerpc/aim/mmu_radix.c @@ -25,6 +25,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_platform.h" + #include __FBSDID("$FreeBSD$"); @@ -84,6 +86,9 @@ __FBSDID("$FreeBSD$"); #include #include +/* For pseries bit. */ +#include + #ifdef INVARIANTS #include #endif @@ -93,6 +98,7 @@ __FBSDID("$FreeBSD$"); #define PPC_BITLSHIFT_VAL(val, bit) ((val) << PPC_BITLSHIFT(bit)) #include "opt_ddb.h" + #ifdef DDB static void pmap_pte_walk(pml1_entry_t *l1, vm_offset_t va); #endif @@ -780,8 +786,10 @@ mmu_radix_tlbiel_flush(int scope) static void mmu_radix_tlbie_all() { - /* TODO: LPID invalidate */ - mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL); + if (powernv_enabled) + mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL); + else + mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_LPID); } static void @@ -2024,11 +2032,14 @@ mmu_radix_early_bootstrap(vm_offset_t start, vm_offset_t end) */ if (isa3_pid_bits == 0) isa3_pid_bits = 20; - parttab_phys = moea64_bootstrap_alloc(PARTTAB_SIZE, PARTTAB_SIZE); - validate_addr(parttab_phys, PARTTAB_SIZE); - for (int i = 0; i < PARTTAB_SIZE/PAGE_SIZE; i++) - pagezero(PHYS_TO_DMAP(parttab_phys + i * PAGE_SIZE)); + if (powernv_enabled) { + parttab_phys = + moea64_bootstrap_alloc(PARTTAB_SIZE, PARTTAB_SIZE); + validate_addr(parttab_phys, PARTTAB_SIZE); + for (int i = 0; i < PARTTAB_SIZE/PAGE_SIZE; i++) + pagezero(PHYS_TO_DMAP(parttab_phys + i * PAGE_SIZE)); + } proctab_size = 1UL << PROCTAB_SIZE_SHIFT; proctab0pa = moea64_bootstrap_alloc(proctab_size, proctab_size); validate_addr(proctab0pa, proctab_size); @@ -2181,12 +2192,20 @@ mmu_radix_proctab_init(void) htobe64(RTS_SIZE | DMAP_TO_PHYS((vm_offset_t)kernel_pmap->pm_pml1) | RADIX_PGD_INDEX_SHIFT); - mmu_radix_proctab_register(proctab0pa, PROCTAB_SIZE_SHIFT - 12); + if (powernv_enabled) { + mmu_radix_proctab_register(proctab0pa, PROCTAB_SIZE_SHIFT - 12); + __asm __volatile("ptesync" : : : "memory"); + __asm __volatile(PPC_TLBIE_5(%0,%1,2,1,1) : : + "r" (TLBIEL_INVAL_SET_LPID), "r" (0)); + __asm __volatile("eieio; tlbsync; ptesync" : : : "memory"); +#ifdef PSERIES + } else { + phyp_hcall(H_REGISTER_PROC_TBL, + PROC_TABLE_NEW | PROC_TABLE_RADIX | PROC_TABLE_GTSE, + proctab0pa, 0, PROCTAB_SIZE_SHIFT - 12); +#endif + } - __asm __volatile("ptesync" : : : "memory"); - __asm __volatile(PPC_TLBIE_5(%0,%1,2,1,1) : : - "r" (TLBIEL_INVAL_SET_LPID), "r" (0)); - __asm __volatile("eieio; tlbsync; ptesync" : : : "memory"); if (bootverbose) printf("process table %p and kernel radix PDE: %p\n", isa3_proctab, kernel_pmap->pm_pml1); @@ -2326,6 +2345,7 @@ mmu_radix_bootstrap(vm_offset_t start, vm_offset_t end) if (bootverbose) printf("%s\n", __func__); hw_direct_map = 1; + powernv_enabled = (mfmsr() & PSL_HV) ? 1 : 0; mmu_radix_early_bootstrap(start, end); if (bootverbose) printf("early bootstrap complete\n"); @@ -2340,8 +2360,10 @@ mmu_radix_bootstrap(vm_offset_t start, vm_offset_t end) mmu_radix_init_iamr(); mmu_radix_proctab_init(); mmu_radix_pid_set(kernel_pmap); - /* XXX assume CPU_FTR_HVMODE */ - mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL); + if (powernv_enabled) + mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL); + else + mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_LPID); mmu_radix_late_bootstrap(start, end); numa_mem_regions(&numa_pregions, &numa_pregions_sz); @@ -2368,7 +2390,10 @@ mmu_radix_cpu_bootstrap(int ap) } mmu_radix_init_iamr(); mmu_radix_pid_set(kernel_pmap); - mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL); + if (powernv_enabled) + mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL); + else + mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_LPID); } static SYSCTL_NODE(_vm_pmap, OID_AUTO, l3e, CTLFLAG_RD, 0, diff --git a/sys/powerpc/pseries/phyp-hvcall.h b/sys/powerpc/pseries/phyp-hvcall.h index 90f75807e56a..face804aff08 100644 --- a/sys/powerpc/pseries/phyp-hvcall.h +++ b/sys/powerpc/pseries/phyp-hvcall.h @@ -177,6 +177,16 @@ #define H_SET_MODE_RSRC_ILE 0x4 /* PAPR 2.8 / ISA 2.07 */ #define H_SET_MODE_RSRC_DAWR1 0x5 /* ISA 3.1 Future support */ +/* H_REGISTER_PROC_TBL identifiers. */ +#define PROC_TABLE_OP_MASK 0x18 +#define PROC_TABLE_DEREG 0x10 +#define PROC_TABLE_NEW 0x18 +#define PROC_TABLE_TYPE_MASK 0x06 +#define PROC_TABLE_HPT_SLB 0x00 +#define PROC_TABLE_GTSE 0x01 +#define PROC_TABLE_HPT_PT 0x02 +#define PROC_TABLE_RADIX 0x04 + /* pSeries hypervisor opcodes. */ #define H_REMOVE 0x04 #define H_ENTER 0x08 diff --git a/sys/powerpc/pseries/platform_chrp.c b/sys/powerpc/pseries/platform_chrp.c index 202ee059c528..f095e97edaf1 100644 --- a/sys/powerpc/pseries/platform_chrp.c +++ b/sys/powerpc/pseries/platform_chrp.c @@ -154,7 +154,8 @@ chrp_attach(platform_t plat) realmaxaddr = MAX(off, realmaxaddr); } - pmap_mmu_install("mmu_phyp", BUS_PROBE_SPECIFIC); + if (!radix_mmu) + pmap_mmu_install("mmu_phyp", BUS_PROBE_SPECIFIC); cpu_idle_hook = phyp_cpu_idle; /* Set up important VPA fields */