From: kettenis Date: Sun, 14 Aug 2016 10:36:47 +0000 (+0000) Subject: Fix setting the SMP bit in the Auxiliary Control Register. The old code was X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=5cc932231238260abb3793dbfcb27cfc6173737d;p=openbsd Fix setting the SMP bit in the Auxiliary Control Register. The old code was toggling the bit, clearing it when already set. On Cortex-A7 setting the SMP bit is essential since without it the CPU doesn't actually use its caches. The SMP bit supposed to be set before turning on the caches and the MMU, so move the setting of the Auxiliary Control Register before setting the System Control Register. ok jsg@ --- diff --git a/sys/arch/arm/arm/cpufunc.c b/sys/arch/arm/arm/cpufunc.c index 667a9ca17d0..ee0b0dfeeeb 100644 --- a/sys/arch/arm/arm/cpufunc.c +++ b/sys/arch/arm/arm/cpufunc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpufunc.c,v 1.44 2016/08/10 21:22:43 kettenis Exp $ */ +/* $OpenBSD: cpufunc.c,v 1.45 2016/08/14 10:36:47 kettenis Exp $ */ /* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */ /* @@ -568,6 +568,26 @@ armv7_setup() uint32_t auxctrl, auxctrlmask; uint32_t cpuctrl, cpuctrlmask; + auxctrl = auxctrlmask = 0; + + switch (cputype & CPU_ID_CORTEX_MASK) { + case CPU_ID_CORTEX_A5: + case CPU_ID_CORTEX_A9: + /* Cache and TLB maintenance broadcast */ +#ifdef notyet + auxctrlmask |= CORTEXA9_AUXCTL_FW; + auxctrl |= CORTEXA9_AUXCTL_FW; +#endif + /* FALLTHROUGH */ + case CPU_ID_CORTEX_A7: + case CPU_ID_CORTEX_A15: + case CPU_ID_CORTEX_A17: + /* Set SMP to allow LDREX/STREX */ + auxctrlmask |= CORTEXA9_AUXCTL_SMP; + auxctrl |= CORTEXA9_AUXCTL_SMP; + break; + } + cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_AFLT_ENABLE | CPU_CONTROL_DC_ENABLE @@ -590,30 +610,17 @@ armv7_setup() /* Clear out the cache */ cpu_idcache_wbinv_all(); + /* + * Set the auxilliary control register first, as the SMP bit + * needs to be set to 1 before the caches and the MMU are + * enabled. + */ + cpu_auxcontrol(auxctrlmask, auxctrl); + /* Set the control register */ curcpu()->ci_ctrl = cpuctrl; cpu_control(cpuctrlmask, cpuctrl); - auxctrl = auxctrlmask = 0; - - switch (cputype & CPU_ID_CORTEX_MASK) { - case CPU_ID_CORTEX_A5: - case CPU_ID_CORTEX_A9: - /* Cache and TLB maintenance broadcast */ -#ifdef notyet - auxctrl |= (1 << 0); -#endif - /* FALLTHROUGH */ - case CPU_ID_CORTEX_A7: - case CPU_ID_CORTEX_A15: - case CPU_ID_CORTEX_A17: - /* Set SMP to allow LDREX/STREX */ - auxctrl |= (1 << 6); - break; - } - - cpu_auxcontrol(auxctrlmask, auxctrl); - /* And again. */ cpu_idcache_wbinv_all(); } diff --git a/sys/arch/arm/include/armreg.h b/sys/arch/arm/include/armreg.h index 5a4a193b669..63a746a836b 100644 --- a/sys/arch/arm/include/armreg.h +++ b/sys/arch/arm/include/armreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: armreg.h,v 1.33 2016/08/06 16:46:25 kettenis Exp $ */ +/* $OpenBSD: armreg.h,v 1.34 2016/08/14 10:36:47 kettenis Exp $ */ /* $NetBSD: armreg.h,v 1.27 2003/09/06 08:43:02 rearnsha Exp $ */ /* @@ -269,6 +269,16 @@ #define XSCALE_AUXCTL_MD_WT 0x00000020 /* mini-D$ wt, read-allocate */ #define XSCALE_AUXCTL_MD_MASK 0x00000030 +/* Cortex-A9 Auxiliary Control Register (CP15 register 1, opcode 1) */ +#define CORTEXA9_AUXCTL_FW (1 << 0) /* Cache and TLB updates broadcast */ +#define CORTEXA9_AUXCTL_L2PE (1 << 1) /* Prefetch hint enable */ +#define CORTEXA9_AUXCTL_L1PE (1 << 2) /* Data prefetch hint enable */ +#define CORTEXA9_AUXCTL_WR_ZERO (1 << 3) /* Ena. write full line of 0s mode */ +#define CORTEXA9_AUXCTL_SMP (1 << 6) /* Coherency is active */ +#define CORTEXA9_AUXCTL_EXCL (1 << 7) /* Exclusive cache bit */ +#define CORTEXA9_AUXCTL_ONEWAY (1 << 8) /* Allocate in on cache way only */ +#define CORTEXA9_AUXCTL_PARITY (1 << 9) /* Support parity checking */ + /* Cache type register definitions */ #define CPU_CT_ISIZE(x) ((x) & 0xfff) /* I$ info */ #define CPU_CT_DSIZE(x) (((x) >> 12) & 0xfff) /* D$ info */