Do runtime detection of MP extensions to allow using a MULTIPROCESSOR
kernel on CPUs without the MP extensions feature (like Cortex-A8).
This commit is contained in:
parent
8ae9876451
commit
91a285accd
@ -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;
|
||||
|
@ -64,64 +64,87 @@ ENTRY(armv7_context_switch)
|
||||
END(armv7_context_switch)
|
||||
|
||||
#ifdef ARM_MMU_EXTENDED_XXX
|
||||
ENTRY(armv7_tlb_flushID_ASID)
|
||||
#ifdef MULTIPROCESSOR
|
||||
mcr p15, 0, r0, c8, c3, 2 @ flush I+D tlb all ASID
|
||||
#else
|
||||
ENTRY(armv7up_tlb_flushID_ASID)
|
||||
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)
|
||||
#endif
|
||||
END(armv7up_tlb_flushID_ASID)
|
||||
|
||||
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)
|
||||
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
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
#endif /* !MULTIPROCESSOR */
|
||||
ENTRY(armv7mp_tlb_flushID_ASID)
|
||||
mcr p15, 0, r0, c8, c3, 2 @ flush I+D tlb all ASID
|
||||
dsb @ data synchronization barrier
|
||||
isb
|
||||
bx lr
|
||||
END(armv7_tlb_flushID_SE)
|
||||
END(armv7mp_tlb_flushID_ASID)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ENTRY(armv7_tlb_flushD)
|
||||
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
|
||||
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, 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, c3, 1 @ flush I+D tlb single entry
|
||||
#endif
|
||||
dsb @ data synchronization barrier
|
||||
isb
|
||||
bx lr
|
||||
END(armv7mp_tlb_flushID_SE)
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
@ -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,v 1.10 2016/07/11 16:09:27 matt Exp $");
|
||||
#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_asid_t hi)
|
||||
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_t 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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 armv7up_tlb_flushID(void);
|
||||
void armv7up_tlb_flushI(void);
|
||||
void armv7up_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_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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user