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;

Reply via email to