Module Name: src Committed By: jmcneill Date: Thu Aug 24 14:19:36 UTC 2017
Modified Files: src/sys/arch/arm/arm: cpufunc.c cpufunc_asm_armv7.S src/sys/arch/arm/arm32: arm32_tlb.c pmap.c src/sys/arch/arm/include: cpufunc_proto.h locore.h Log Message: Do runtime detection of MP extensions to allow using a MULTIPROCESSOR kernel on CPUs without the MP extensions feature (like Cortex-A8). To generate a diff of this commit: cvs rdiff -u -r1.163 -r1.164 src/sys/arch/arm/arm/cpufunc.c cvs rdiff -u -r1.26 -r1.27 src/sys/arch/arm/arm/cpufunc_asm_armv7.S cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/arm32/arm32_tlb.c cvs rdiff -u -r1.352 -r1.353 src/sys/arch/arm/arm32/pmap.c cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/include/cpufunc_proto.h cvs rdiff -u -r1.27 -r1.28 src/sys/arch/arm/include/locore.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/arm/cpufunc.c diff -u src/sys/arch/arm/arm/cpufunc.c:1.163 src/sys/arch/arm/arm/cpufunc.c:1.164 --- src/sys/arch/arm/arm/cpufunc.c:1.163 Sat Jan 28 13:21:11 2017 +++ src/sys/arch/arm/arm/cpufunc.c Thu Aug 24 14:19:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.c,v 1.163 2017/01/28 13:21:11 jakllsch Exp $ */ +/* $NetBSD: cpufunc.c,v 1.164 2017/08/24 14:19:36 jmcneill Exp $ */ /* * arm7tdmi support code Copyright (c) 2001 John Fremlin @@ -49,7 +49,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.163 2017/01/28 13:21:11 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.164 2017/08/24 14:19:36 jmcneill Exp $"); #include "opt_compat_netbsd.h" #include "opt_cpuoptions.h" @@ -1300,12 +1300,12 @@ struct cpu_functions armv7_cpufuncs = { /* TLB functions */ - .cf_tlb_flushID = armv7_tlb_flushID, - .cf_tlb_flushID_SE = armv7_tlb_flushID_SE, - .cf_tlb_flushI = armv7_tlb_flushI, - .cf_tlb_flushI_SE = armv7_tlb_flushI_SE, - .cf_tlb_flushD = armv7_tlb_flushD, - .cf_tlb_flushD_SE = armv7_tlb_flushD_SE, + .cf_tlb_flushID = armv7up_tlb_flushID, + .cf_tlb_flushID_SE = armv7up_tlb_flushID_SE, + .cf_tlb_flushI = armv7up_tlb_flushI, + .cf_tlb_flushI_SE = armv7up_tlb_flushI_SE, + .cf_tlb_flushD = armv7up_tlb_flushD, + .cf_tlb_flushD_SE = armv7up_tlb_flushD_SE, /* Cache operations */ @@ -2134,6 +2134,18 @@ set_cpufuncs(void) #if defined(CPU_CORTEX) if (CPU_ID_CORTEX_P(cputype)) { cpufuncs = armv7_cpufuncs; +#ifdef MULTIPROCESSOR + /* If MP extensions are present, patch in MP TLB ops */ + const uint32_t mpidr = armreg_mpidr_read(); + if ((mpidr & (MPIDR_MP|MPIDR_U)) == MPIDR_MP) { + cpufuncs.cf_tlb_flushID = armv7mp_tlb_flushID; + cpufuncs.cf_tlb_flushID_SE = armv7mp_tlb_flushID_SE; + cpufuncs.cf_tlb_flushI = armv7mp_tlb_flushI; + cpufuncs.cf_tlb_flushI_SE = armv7mp_tlb_flushI_SE; + cpufuncs.cf_tlb_flushD = armv7mp_tlb_flushD; + cpufuncs.cf_tlb_flushD_SE = armv7mp_tlb_flushD_SE; + } +#endif cpu_do_powersave = 1; /* Enable powersave */ #if defined(CPU_ARMV6) || defined(CPU_PRE_ARMV6) cpu_armv7_p = true; Index: src/sys/arch/arm/arm/cpufunc_asm_armv7.S diff -u src/sys/arch/arm/arm/cpufunc_asm_armv7.S:1.26 src/sys/arch/arm/arm/cpufunc_asm_armv7.S:1.27 --- src/sys/arch/arm/arm/cpufunc_asm_armv7.S:1.26 Tue Jun 9 08:08:14 2015 +++ src/sys/arch/arm/arm/cpufunc_asm_armv7.S Thu Aug 24 14:19:36 2017 @@ -64,64 +64,87 @@ ENTRY(armv7_context_switch) END(armv7_context_switch) #ifdef ARM_MMU_EXTENDED_XXX -ENTRY(armv7_tlb_flushID_ASID) +ENTRY(armv7up_tlb_flushID_ASID) + mcr p15, 0, r0, c8, c7, 2 @ flush I+D tlb all ASID + dsb @ data synchronization barrier + isb + bx lr +END(armv7up_tlb_flushID_ASID) + #ifdef MULTIPROCESSOR +ENTRY(armv7mp_tlb_flushID_ASID) mcr p15, 0, r0, c8, c3, 2 @ flush I+D tlb all ASID -#else - mcr p15, 0, r0, c8, c7, 2 @ flush I+D tlb all ASID -#endif dsb @ data synchronization barrier isb bx lr -END(armv7_tlb_flushID_ASID) +END(armv7mp_tlb_flushID_ASID) +#endif #endif -STRONG_ALIAS(armv7_tlb_flushD_SE, armv7_tlb_flushID_SE) -STRONG_ALIAS(armv7_tlb_flushI_SE, armv7_tlb_flushID_SE) -ENTRY(armv7_tlb_flushID_SE) +STRONG_ALIAS(armv7up_tlb_flushD_SE, armv7up_tlb_flushID_SE) +STRONG_ALIAS(armv7up_tlb_flushI_SE, armv7up_tlb_flushID_SE) +ENTRY(armv7up_tlb_flushID_SE) bfc r0, #0, #12 @ Always KERNEL_PID, i.e. 0 -#ifdef MULTIPROCESSOR - mcr p15, 0, r0, c8, c3, 1 @ flush I+D tlb single entry + mcr p15, 0, r0, c8, c7, 1 @ flush I+D tlb single entry #if PAGE_SIZE == 2*L2_S_SIZE add r0, r0, #L2_S_SIZE - mcr p15, 0, r0, c8, c3, 1 @ flush I+D tlb single entry -#endif -#else /* !MULTIPROCESSOR */ mcr p15, 0, r0, c8, c7, 1 @ flush I+D tlb single entry +#endif + dsb @ data synchronization barrier + isb + bx lr +END(armv7up_tlb_flushID_SE) + +#ifdef MULTIPROCESSOR +STRONG_ALIAS(armv7mp_tlb_flushD_SE, armv7mp_tlb_flushID_SE) +STRONG_ALIAS(armv7mp_tlb_flushI_SE, armv7mp_tlb_flushID_SE) +ENTRY(armv7mp_tlb_flushID_SE) + bfc r0, #0, #12 @ Always KERNEL_PID, i.e. 0 + mcr p15, 0, r0, c8, c3, 1 @ flush I+D tlb single entry #if PAGE_SIZE == 2*L2_S_SIZE add r0, r0, #L2_S_SIZE - mcr p15, 0, r0, c8, c7, 1 @ flush I+D tlb single entry + mcr p15, 0, r0, c8, c3, 1 @ flush I+D tlb single entry #endif -#endif /* !MULTIPROCESSOR */ dsb @ data synchronization barrier isb bx lr -END(armv7_tlb_flushID_SE) +END(armv7mp_tlb_flushID_SE) +#endif -ENTRY(armv7_tlb_flushD) +#ifdef MULTIPROCESSOR +STRONG_ALIAS(armv7mp_tlb_flushD, armv7up_tlb_flushD) +#endif +ENTRY(armv7up_tlb_flushD) mov r0, #0 mcr p15, 0, r0, c8, c6, 0 @ flush entire D tlb dsb @ data synchronization barrier isb bx lr -END(armv7_tlb_flushD) +END(armv7up_tlb_flushD) -STRONG_ALIAS(armv7_tlb_flushI, armv7_tlb_flushID) -ENTRY(armv7_tlb_flushID) +STRONG_ALIAS(armv7up_tlb_flushI, armv7up_tlb_flushID) +ENTRY(armv7up_tlb_flushID) dsb mov r0, #0 -#ifdef MULTIPROCESSOR - mcr p15, 0, r0, c8, c3, 0 @ flush entire I+D tlb, IS - mcr p15, 0, r0, c7, c1, 6 @ branch predictor invalidate, IS -#else mcr p15, 0, r0, c8, c7, 0 @ flush entire I+D tlb mcr p15, 0, r0, c7, c5, 6 @ branch predictor invalidate -#endif dsb @ data synchronization barrier isb bx lr -END(armv7_tlb_flushID) +END(armv7up_tlb_flushID) +#ifdef MULTIPROCESSOR +STRONG_ALIAS(armv7mp_tlb_flushI, armv7mp_tlb_flushID) +ENTRY(armv7mp_tlb_flushID) + dsb + mov r0, #0 + mcr p15, 0, r0, c8, c3, 0 @ flush entire I+D tlb, IS + mcr p15, 0, r0, c7, c1, 6 @ branch predictor invalidate, IS + dsb @ data synchronization barrier + isb + bx lr +END(armv7mp_tlb_flushID) +#endif ENTRY_NP(armv7_setttb) mrc p15, 0, ip, c0, c0, 5 @ get MPIDR Index: src/sys/arch/arm/arm32/arm32_tlb.c diff -u src/sys/arch/arm/arm32/arm32_tlb.c:1.10 src/sys/arch/arm/arm32/arm32_tlb.c:1.11 --- src/sys/arch/arm/arm32/arm32_tlb.c:1.10 Mon Jul 11 16:09:27 2016 +++ src/sys/arch/arm/arm32/arm32_tlb.c Thu Aug 24 14:19:36 2017 @@ -30,7 +30,7 @@ #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: arm32_tlb.c,v 1.10 2016/07/11 16:09:27 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: arm32_tlb.c,v 1.11 2017/08/24 14:19:36 jmcneill Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -40,6 +40,7 @@ __KERNEL_RCSID(1, "$NetBSD: arm32_tlb.c, #include <arm/locore.h> bool arm_has_tlbiasid_p; // CPU supports TLBIASID system coprocessor op +bool arm_has_mpext_p; // CPU supports MP extensions tlb_asid_t tlb_get_asid(void) @@ -64,11 +65,11 @@ tlb_invalidate_all(void) { const bool vivt_icache_p = arm_pcache.icache_type == CACHE_TYPE_VIVT; arm_dsb(); -#ifdef MULTIPROCESSOR - armreg_tlbiallis_write(0); -#else - armreg_tlbiall_write(0); -#endif + if (arm_has_mpext_p) { + armreg_tlbiallis_write(0); + } else { + armreg_tlbiall_write(0); + } arm_isb(); if (__predict_false(vivt_icache_p)) { if (arm_has_tlbiasid_p) { @@ -94,20 +95,20 @@ tlb_invalidate_asids(tlb_asid_t lo, tlb_ arm_dsb(); if (arm_has_tlbiasid_p) { for (; lo <= hi; lo++) { -#ifdef MULTIPROCESSOR - armreg_tlbiasidis_write(lo); -#else - armreg_tlbiasid_write(lo); -#endif + if (arm_has_mpext_p) { + armreg_tlbiasidis_write(lo); + } else { + armreg_tlbiasid_write(lo); + } } arm_dsb(); arm_isb(); if (__predict_false(vivt_icache_p)) { -#ifdef MULTIPROCESSOR - armreg_icialluis_write(0); -#else - armreg_iciallu_write(0); -#endif + if (arm_has_mpext_p) { + armreg_icialluis_write(0); + } else { + armreg_iciallu_write(0); + } } } else { armreg_tlbiall_write(0); @@ -125,12 +126,11 @@ tlb_invalidate_addr(vaddr_t va, tlb_asid arm_dsb(); va = trunc_page(va) | asid; for (vaddr_t eva = va + PAGE_SIZE; va < eva; va += L2_S_SIZE) { -#ifdef MULTIPROCESSOR - armreg_tlbimvais_write(va); -#else - armreg_tlbimva_write(va); -#endif - //armreg_tlbiall_write(asid); + if (arm_has_mpext_p) { + armreg_tlbimvais_write(va); + } else { + armreg_tlbimva_write(va); + } } arm_isb(); } Index: src/sys/arch/arm/arm32/pmap.c diff -u src/sys/arch/arm/arm32/pmap.c:1.352 src/sys/arch/arm/arm32/pmap.c:1.353 --- src/sys/arch/arm/arm32/pmap.c:1.352 Thu Jul 27 10:56:42 2017 +++ src/sys/arch/arm/arm32/pmap.c Thu Aug 24 14:19:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.352 2017/07/27 10:56:42 skrll Exp $ */ +/* $NetBSD: pmap.c,v 1.353 2017/08/24 14:19:36 jmcneill Exp $ */ /* * Copyright 2003 Wasabi Systems, Inc. @@ -217,7 +217,7 @@ #include <arm/locore.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.352 2017/07/27 10:56:42 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.353 2017/08/24 14:19:36 jmcneill Exp $"); //#define PMAP_DEBUG #ifdef PMAP_DEBUG @@ -5071,11 +5071,11 @@ pmap_update(pmap_t pm) pmap_md_pdetab_activate(pm, curlwp); } -#if defined(MULTIPROCESSOR) - armreg_bpiallis_write(0); -#else - armreg_bpiall_write(0); -#endif + if (arm_has_mpext_p) + armreg_bpiallis_write(0); + else + armreg_bpiall_write(0); + kpreempt_enable(); KASSERTMSG(pm == pmap_kernel() @@ -7527,6 +7527,15 @@ pmap_pte_init_armv7(void) arm_has_tlbiasid_p = true; } + /* + * Check the MPIDR to see if this CPU supports MP extensions. + */ +#ifdef MULTIPROCESSOR + arm_has_mpext_p = (armreg_mpidr_read() & (MPIDR_MP|MPIDR_U)) == MPIDR_MP; +#else + arm_has_mpext_p = false; +#endif + pte_l1_s_prot_u = L1_S_PROT_U_armv7; pte_l1_s_prot_w = L1_S_PROT_W_armv7; pte_l1_s_prot_ro = L1_S_PROT_RO_armv7; Index: src/sys/arch/arm/include/cpufunc_proto.h diff -u src/sys/arch/arm/include/cpufunc_proto.h:1.5 src/sys/arch/arm/include/cpufunc_proto.h:1.6 --- src/sys/arch/arm/include/cpufunc_proto.h:1.5 Thu May 14 05:39:32 2015 +++ src/sys/arch/arm/include/cpufunc_proto.h Thu Aug 24 14:19:36 2017 @@ -44,6 +44,8 @@ #ifdef _KERNEL +#include "opt_multiprocessor.h" + #include <sys/types.h> #include <arm/armreg.h> #include <arm/cpuconf.h> @@ -309,13 +311,23 @@ void armv7_dcache_wbinv_all(void); void armv7_idcache_wbinv_range(vaddr_t, vsize_t); void armv7_idcache_wbinv_all(void); -void armv7_tlb_flushID(void); -void armv7_tlb_flushI(void); -void armv7_tlb_flushD(void); - -void armv7_tlb_flushID_SE(vaddr_t); -void armv7_tlb_flushI_SE(vaddr_t); -void armv7_tlb_flushD_SE(vaddr_t); +void armv7up_tlb_flushID(void); +void armv7up_tlb_flushI(void); +void armv7up_tlb_flushD(void); + +void armv7up_tlb_flushID_SE(vaddr_t); +void armv7up_tlb_flushI_SE(vaddr_t); +void armv7up_tlb_flushD_SE(vaddr_t); + +#ifdef MULTIPROCESSOR +void armv7mp_tlb_flushID(void); +void armv7mp_tlb_flushI(void); +void armv7mp_tlb_flushD(void); + +void armv7mp_tlb_flushID_SE(vaddr_t); +void armv7mp_tlb_flushI_SE(vaddr_t); +void armv7mp_tlb_flushD_SE(vaddr_t); +#endif void armv7_cpu_sleep(int); void armv7_drain_writebuf(void); Index: src/sys/arch/arm/include/locore.h diff -u src/sys/arch/arm/include/locore.h:1.27 src/sys/arch/arm/include/locore.h:1.28 --- src/sys/arch/arm/include/locore.h:1.27 Thu Mar 16 16:13:20 2017 +++ src/sys/arch/arm/include/locore.h Thu Aug 24 14:19:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.h,v 1.27 2017/03/16 16:13:20 chs Exp $ */ +/* $NetBSD: locore.h,v 1.28 2017/08/24 14:19:36 jmcneill Exp $ */ /* * Copyright (c) 1994-1996 Mark Brinicombe. @@ -181,6 +181,7 @@ extern int cpu_processor_features[2]; extern int cpu_media_and_vfp_features[2]; extern bool arm_has_tlbiasid_p; +extern bool arm_has_mpext_p; #ifdef MULTIPROCESSOR extern u_int arm_cpu_max; extern volatile u_int arm_cpu_hatched;