Remake support for SMP kernel on UP cpu:

- Use new option SMP_ON_UP instead of (mis)using specific CPU type.
   By this, any SMP kernel can be compiled with SMP_ON_UP support.
 - Enable runtime detection of CPU multiprocessor extensions only
   if SMP_ON_UP option is used. In other cases (pure SMP or UP),
   statically compile only required variant.
 - Don't leak multiprocessor instructions to UP kernel.
 - Correctly handle data cache write back to point of unification.
   DCCMVAU is supported on all armv7 cpus.
 - For SMP_ON_UP kernels, detect proper TTB flags on runtime.

Differential Revision: https://reviews.freebsd.org/D9133
This commit is contained in:
Michal Meloun 2017-02-02 06:14:44 +00:00
parent ae0f418aa4
commit 93a065e749
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=313090
28 changed files with 129 additions and 112 deletions

View File

@ -1,7 +1,7 @@
# Allwinner common options
#$FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,7 +1,7 @@
# Allwinner Uniprocessor common options
#$FreeBSD$
cpu CPU_CORTEXA8
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,6 +1,6 @@
# $FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,6 +1,6 @@
# $FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,6 +1,6 @@
# $FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a -DAL_HAVE_TYPES"

View File

@ -429,7 +429,7 @@ struct cpu_functions arm1176_cpufuncs = {
};
#endif /*CPU_ARM1176 */
#if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || defined(CPU_KRAIT)
#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
struct cpu_functions cortexa_cpufuncs = {
/* Cache operations */
@ -450,7 +450,7 @@ struct cpu_functions cortexa_cpufuncs = {
/* Soft functions */
.cf_setup = cortexa_setup
};
#endif /* CPU_CORTEXA8 || CPU_CORTEXA_MP || CPU_KRAIT */
#endif /* CPU_CORTEXA || CPU_KRAIT */
/*
* Global constants also used by locore.s
@ -468,7 +468,7 @@ u_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore-v4.s */
defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
defined(CPU_FA526) || defined(CPU_MV_PJ4B) || \
defined(CPU_XSCALE_81342) || \
defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || defined(CPU_KRAIT)
defined(CPU_CORTEXA) || defined(CPU_KRAIT)
/* Global cache line sizes, use 32 as default */
int arm_dcache_min_line_size = 32;
@ -659,7 +659,7 @@ set_cpufuncs(void)
goto out;
}
#endif /* CPU_ARM1176 */
#if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || defined(CPU_KRAIT)
#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
switch(cputype & CPU_ID_SCHEME_MASK) {
case CPU_ID_CORTEXA5:
case CPU_ID_CORTEXA7:
@ -677,7 +677,7 @@ set_cpufuncs(void)
default:
break;
}
#endif /* CPU_CORTEXA8 || CPU_CORTEXA_MP || CPU_KRAIT */
#endif /* CPU_CORTEXA || CPU_KRAIT */
#if defined(CPU_MV_PJ4B)
if (cputype == CPU_ID_MV88SV581X_V7 ||
@ -830,7 +830,7 @@ arm10_setup(void)
#if defined(CPU_ARM1176) \
|| defined(CPU_MV_PJ4B) \
|| defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || defined(CPU_KRAIT)
|| defined(CPU_CORTEXA) || defined(CPU_KRAIT)
static __inline void
cpu_scc_setup_ccnt(void)
{
@ -900,7 +900,7 @@ pj4bv7_setup(void)
}
#endif /* CPU_MV_PJ4B */
#if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || defined(CPU_KRAIT)
#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
void
cortexa_setup(void)
@ -908,7 +908,7 @@ cortexa_setup(void)
cpu_scc_setup_ccnt();
}
#endif /* CPU_CORTEXA8 || CPU_CORTEXA_MP || CPU_KRAIT */
#endif /* CPU_CORTEXA || CPU_KRAIT */
#if defined(CPU_FA526)
void

View File

@ -140,7 +140,6 @@ __FBSDID("$FreeBSD$");
#ifdef SMP
#include <machine/smp.h>
#endif
#ifndef PMAP_SHPGPERPROC
#define PMAP_SHPGPERPROC 200
#endif
@ -431,7 +430,9 @@ encode_ttb_flags(int idx)
reg |= (inner & 0x1) << 6;
reg |= (inner & 0x2) >> 1;
#ifdef SMP
reg |= 1 << 1;
ARM_SMP_UP(
reg |= 1 << 1,
);
#endif
return reg;
}
@ -485,8 +486,9 @@ pmap_set_tex(void)
/* Add shareable bits for normal memory in SMP case. */
#ifdef SMP
if (ARM_USE_MP_EXTENSIONS)
prrr |= PRRR_NS1;
ARM_SMP_UP(
prrr |= PRRR_NS1,
);
#endif
cp15_prrr_set(prrr);
cp15_nmrr_set(nmrr);

View File

@ -1,7 +1,7 @@
# $FreeBSD$
machine arm armv6
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
options SOC_BCM2836

View File

@ -20,8 +20,8 @@
ident GENERIC
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA8
cpu CPU_CORTEXA
options SMP_ON_UP
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,6 +1,6 @@
# $FreeBSD$
machine arm armv6
cpu CPU_CORTEXA8
cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
options KERNVIRTADDR=0xc0100000

View File

@ -1,6 +1,6 @@
# $FreeBSD$
machine arm armv6
cpu CPU_CORTEXA8
cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
options KERNVIRTADDR=0xc0100000

View File

@ -1,6 +1,6 @@
# $FreeBSD$
machine arm armv6
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
options KERNVIRTADDR = 0xc2000000

View File

@ -1,6 +1,6 @@
# $FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -41,24 +41,47 @@
#if __ARM_ARCH < 6
#error Only include this file for ARMv6
#else
#endif
/*
* Some kernel modules (dtrace all for example) are compiled
* unconditionally with -DSMP. Although it looks like a bug,
* handle this case here and in #elif condition in ARM_SMP_UP macro.
*/
#if __ARM_ARCH <= 6 && defined(SMP) && !defined(KLD_MODULE)
#error SMP option is not supported on ARMv6
#endif
#if __ARM_ARCH <= 6 && defined(SMP_ON_UP)
#error SMP_ON_UP option is only supported on ARMv7+ CPUs
#endif
#if !defined(SMP) && defined(SMP_ON_UP)
#error SMP option must be defined for SMP_ON_UP option
#endif
#define CPU_ASID_KERNEL 0
#if __ARM_ARCH >= 7
#if !defined(SMP)
/* No SMP so no need to use the MP extensions */
#define ARM_USE_MP_EXTENSIONS 0
#elif defined(CPU_CORTEXA8) && \
(defined(CPU_CORTEXA_MP) || defined(CPU_KRAIT) || defined(CPU_MV_PJ4B))
#define ARM_USE_MP_EXTENSIONS (cpuinfo.mp_ext != 0)
#elif defined(CPU_CORTEXA8)
#define ARM_USE_MP_EXTENSIONS 0
#if defined(SMP_ON_UP)
#define ARM_SMP_UP(smp_code, up_code) \
do { \
if (cpuinfo.mp_ext != 0) { \
smp_code; \
} else { \
up_code; \
} \
} while (0)
#elif defined(SMP) && __ARM_ARCH > 6
#define ARM_SMP_UP(smp_code, up_code) \
do { \
smp_code; \
} while (0)
#else
#define ARM_USE_MP_EXTENSIONS 1
#define ARM_SMP_UP(smp_code, up_code) \
do { \
up_code; \
} while (0)
#endif
#endif /* __ARM_ARCH >= 7 */
void dcache_wbinv_poc_all(void); /* !!! NOT SMP coherent function !!! */
vm_offset_t dcache_wb_pou_checked(vm_offset_t, vm_size_t);
@ -126,15 +149,15 @@ fname(uint64_t reg) \
/* TLB */
_WF0(_CP15_TLBIALL, CP15_TLBIALL) /* Invalidate entire unified TLB */
#if __ARM_ARCH >= 7
#if __ARM_ARCH >= 7 && defined(SMP)
_WF0(_CP15_TLBIALLIS, CP15_TLBIALLIS) /* Invalidate entire unified TLB IS */
#endif
_WF1(_CP15_TLBIASID, CP15_TLBIASID(%0)) /* Invalidate unified TLB by ASID */
#if __ARM_ARCH >= 7
#if __ARM_ARCH >= 7 && defined(SMP)
_WF1(_CP15_TLBIASIDIS, CP15_TLBIASIDIS(%0)) /* Invalidate unified TLB by ASID IS */
#endif
_WF1(_CP15_TLBIMVAA, CP15_TLBIMVAA(%0)) /* Invalidate unified TLB by MVA, all ASID */
#if __ARM_ARCH >= 7
#if __ARM_ARCH >= 7 && defined(SMP)
_WF1(_CP15_TLBIMVAAIS, CP15_TLBIMVAAIS(%0)) /* Invalidate unified TLB by MVA, all ASID IS */
#endif
_WF1(_CP15_TLBIMVA, CP15_TLBIMVA(%0)) /* Invalidate unified TLB by MVA */
@ -144,7 +167,7 @@ _WF1(_CP15_TTB_SET, CP15_TTBR0(%0))
/* Cache and Branch predictor */
_WF0(_CP15_BPIALL, CP15_BPIALL) /* Branch predictor invalidate all */
#if __ARM_ARCH >= 7
#if __ARM_ARCH >= 7 && defined(SMP)
_WF0(_CP15_BPIALLIS, CP15_BPIALLIS) /* Branch predictor invalidate all IS */
#endif
_WF1(_CP15_BPIMVA, CP15_BPIMVA(%0)) /* Branch predictor invalidate by MVA */
@ -158,7 +181,7 @@ _WF1(_CP15_DCCSW, CP15_DCCSW(%0)) /* Data cache clean by set/way */
_WF1(_CP15_DCIMVAC, CP15_DCIMVAC(%0)) /* Data cache invalidate by MVA PoC */
_WF1(_CP15_DCISW, CP15_DCISW(%0)) /* Data cache invalidate by set/way */
_WF0(_CP15_ICIALLU, CP15_ICIALLU) /* Instruction cache invalidate all PoU */
#if __ARM_ARCH >= 7
#if __ARM_ARCH >= 7 && defined(SMP)
_WF0(_CP15_ICIALLUIS, CP15_ICIALLUIS) /* Instruction cache invalidate all PoU IS */
#endif
_WF1(_CP15_ICIMVAU, CP15_ICIMVAU(%0)) /* Instruction cache invalidate */
@ -360,17 +383,17 @@ tlb_flush_range_local(vm_offset_t va, vm_size_t size)
}
/* Broadcasting operations. */
#if __ARM_ARCH >= 7
#if __ARM_ARCH >= 7 && defined(SMP)
static __inline void
tlb_flush_all(void)
{
dsb();
if (ARM_USE_MP_EXTENSIONS)
_CP15_TLBIALLIS();
else
_CP15_TLBIALL();
ARM_SMP_UP(
_CP15_TLBIALLIS(),
_CP15_TLBIALL()
);
dsb();
}
@ -379,10 +402,10 @@ tlb_flush_all_ng(void)
{
dsb();
if (ARM_USE_MP_EXTENSIONS)
_CP15_TLBIASIDIS(CPU_ASID_KERNEL);
else
_CP15_TLBIASID(CPU_ASID_KERNEL);
ARM_SMP_UP(
_CP15_TLBIASIDIS(CPU_ASID_KERNEL),
_CP15_TLBIASID(CPU_ASID_KERNEL)
);
dsb();
}
@ -393,10 +416,10 @@ tlb_flush(vm_offset_t va)
KASSERT((va & PAGE_MASK) == 0, ("%s: va %#x not aligned", __func__, va));
dsb();
if (ARM_USE_MP_EXTENSIONS)
_CP15_TLBIMVAAIS(va);
else
_CP15_TLBIMVA(va | CPU_ASID_KERNEL);
ARM_SMP_UP(
_CP15_TLBIMVAAIS(va),
_CP15_TLBIMVA(va | CPU_ASID_KERNEL)
);
dsb();
}
@ -410,13 +433,16 @@ tlb_flush_range(vm_offset_t va, vm_size_t size)
size));
dsb();
if (ARM_USE_MP_EXTENSIONS) {
for (; va < eva; va += PAGE_SIZE)
_CP15_TLBIMVAAIS(va);
} else {
for (; va < eva; va += PAGE_SIZE)
_CP15_TLBIMVA(va | CPU_ASID_KERNEL);
}
ARM_SMP_UP(
{
for (; va < eva; va += PAGE_SIZE)
_CP15_TLBIMVAAIS(va);
},
{
for (; va < eva; va += PAGE_SIZE)
_CP15_TLBIMVA(va | CPU_ASID_KERNEL);
}
);
dsb();
}
#else /* __ARM_ARCH < 7 */
@ -440,23 +466,19 @@ icache_sync(vm_offset_t va, vm_size_t size)
dsb();
va &= ~cpuinfo.dcache_line_mask;
for ( ; va < eva; va += cpuinfo.dcache_line_size) {
#if __ARM_ARCH >= 7
if (ARM_USE_MP_EXTENSIONS) {
for ( ; va < eva; va += cpuinfo.dcache_line_size)
_CP15_DCCMVAU(va);
} else
_CP15_DCCMVAU(va);
#else
_CP15_DCCMVAC(va);
#endif
{
for ( ; va < eva; va += cpuinfo.dcache_line_size)
_CP15_DCCMVAC(va);
}
dsb();
#if __ARM_ARCH >= 7
if (ARM_USE_MP_EXTENSIONS)
_CP15_ICIALLUIS();
else
#endif
_CP15_ICIALLU();
ARM_SMP_UP(
_CP15_ICIALLUIS(),
_CP15_ICIALLU()
);
dsb();
isb();
}
@ -465,12 +487,11 @@ icache_sync(vm_offset_t va, vm_size_t size)
static __inline void
icache_inv_all(void)
{
#if __ARM_ARCH >= 7
if (ARM_USE_MP_EXTENSIONS)
_CP15_ICIALLUIS();
else
#endif
_CP15_ICIALLU();
ARM_SMP_UP(
_CP15_ICIALLUIS(),
_CP15_ICIALLU()
);
dsb();
isb();
}
@ -479,12 +500,11 @@ icache_inv_all(void)
static __inline void
bpb_inv_all(void)
{
#if __ARM_ARCH >= 7
if (ARM_USE_MP_EXTENSIONS)
_CP15_BPIALLIS();
else
#endif
_CP15_BPIALL();
ARM_SMP_UP(
_CP15_BPIALLIS(),
_CP15_BPIALL()
);
dsb();
isb();
}
@ -497,15 +517,12 @@ dcache_wb_pou(vm_offset_t va, vm_size_t size)
dsb();
va &= ~cpuinfo.dcache_line_mask;
for ( ; va < eva; va += cpuinfo.dcache_line_size) {
#if __ARM_ARCH >= 7
if (ARM_USE_MP_EXTENSIONS) {
for ( ; va < eva; va += cpuinfo.dcache_line_size)
_CP15_DCCMVAU(va);
} else
_CP15_DCCMVAU(va);
#else
_CP15_DCCMVAC(va);
#endif
{
for ( ; va < eva; va += cpuinfo.dcache_line_size)
_CP15_DCCMVAC(va);
}
dsb();
}
@ -668,6 +685,5 @@ cp15_ats1cuw_check(vm_offset_t addr)
isb();
return (cp15_par_get() & 0x01 ? EFAULT : 0);
}
#endif /* !__ARM_ARCH < 6 */
#endif /* !MACHINE_CPU_V6_H */

View File

@ -276,8 +276,7 @@ void sheeva_l2cache_wbinv_all (void);
#if defined(CPU_MV_PJ4B)
void armv6_idcache_wbinv_all (void);
#endif
#if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || \
defined(CPU_MV_PJ4B) || defined(CPU_KRAIT)
#if defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) || defined(CPU_KRAIT)
void armv7_idcache_wbinv_all (void);
void armv7_cpu_sleep (int);
void armv7_setup (void);

View File

@ -76,7 +76,7 @@ int intr_pic_ipi_setup(u_int, const char *, intr_ipi_handler_t *, void *);
#elif defined(CPU_ARM9) || defined(SOC_MV_KIRKWOOD) || \
defined(CPU_XSCALE_IXP435)
#define NIRQ 64
#elif defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP)
#elif defined(CPU_CORTEXA)
#define NIRQ 1020
#elif defined(CPU_KRAIT)
#define NIRQ 288

View File

@ -140,7 +140,7 @@
/*
* CP15 C7 registers
*/
#if __ARM_ARCH >= 7
#if __ARM_ARCH >= 7 && defined(SMP)
/* From ARMv7: */
#define CP15_ICIALLUIS p15, 0, r0, c7, c1, 0 /* Instruction cache invalidate all PoU, IS */
#define CP15_BPIALLIS p15, 0, r0, c7, c1, 6 /* Branch predictor invalidate all IS */
@ -205,7 +205,7 @@
/*
* CP15 C8 registers
*/
#if __ARM_ARCH >= 7
#if __ARM_ARCH >= 7 && defined(SMP)
/* From ARMv7: */
#define CP15_TLBIALLIS p15, 0, r0, c8, c3, 0 /* Invalidate entire unified TLB IS */
#define CP15_TLBIMVAIS(rr) p15, 0, rr, c8, c3, 1 /* Invalidate unified TLB by MVA IS */

View File

@ -1,7 +1,7 @@
# $FreeBSD$
files "../mv/armada38x/files.armada38x"
files "../mv/files.mv"
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,5 +1,5 @@
# $FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,6 +1,6 @@
# $FreeBSD$
machine arm armv6
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
options KERNVIRTADDR = 0xc1000000

View File

@ -1,7 +1,7 @@
# Rockchip rk30xx common options
#$FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,6 +1,6 @@
# $FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -1,6 +1,6 @@
# $FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -3,7 +3,7 @@
files "../ti/am335x/files.am335x"
include "../ti/std.ti"
cpu CPU_CORTEXA8
cpu CPU_CORTEXA
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
makeoptions KERNVIRTADDR=0xc0200000

View File

@ -3,7 +3,7 @@
files "../ti/omap4/files.omap4"
include "../ti/std.ti"
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
makeoptions KERNVIRTADDR=0xc0200000

View File

@ -3,7 +3,7 @@
#
# $FreeBSD$
cpu CPU_CORTEXA_MP
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"

View File

@ -36,7 +36,7 @@ arm/arm/cpufunc_asm_arm11x6.S optional cpu_arm1176
arm/arm/cpufunc_asm_armv4.S optional cpu_arm9 | cpu_arm9e | cpu_fa526 | cpu_xscale_pxa2x0 | cpu_xscale_ixp425 | cpu_xscale_81342
arm/arm/cpufunc_asm_armv5_ec.S optional cpu_arm9e
arm/arm/cpufunc_asm_armv6.S optional cpu_arm1176
arm/arm/cpufunc_asm_armv7.S optional cpu_cortexa8 | cpu_cortexa_mp | cpu_krait | cpu_mv_pj4b
arm/arm/cpufunc_asm_armv7.S optional cpu_cortexa | cpu_krait | cpu_mv_pj4b
arm/arm/cpufunc_asm_fa526.S optional cpu_fa526
arm/arm/cpufunc_asm_pj4b.S optional cpu_mv_pj4b
arm/arm/cpufunc_asm_sheeva.S optional cpu_arm9e

View File

@ -11,8 +11,7 @@ CPSW_ETHERSWITCH opt_cpsw.h
CPU_ARM9 opt_global.h
CPU_ARM9E opt_global.h
CPU_ARM1176 opt_global.h
CPU_CORTEXA8 opt_global.h # Support the Cortex-A8 (no MP extensions)
CPU_CORTEXA_MP opt_global.h # Support Cortex-A CPUs with MP extensions
CPU_CORTEXA opt_global.h
CPU_KRAIT opt_global.h
CPU_FA526 opt_global.h
CPU_MV_PJ4B opt_global.h
@ -20,6 +19,7 @@ CPU_XSCALE_81342 opt_global.h
CPU_XSCALE_IXP425 opt_global.h
CPU_XSCALE_IXP435 opt_global.h
CPU_XSCALE_PXA2X0 opt_global.h
SMP_ON_UP opt_global.h # Runtime detection of MP extensions
DEV_GIC opt_global.h
DEV_PMU opt_global.h
EFI opt_platform.h