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;