Port-arm archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: OMAP2/ARM1136 cache aliasing issue
On Mon, Jul 21, 2008 at 04:21:41PM +0300, Imre Deak wrote:
> [ ... ]
> It turns out to be a silicon bug. The errata suggests a workaround for this,
> which involves switching on partial low interrupt latency mode. How about the
> following patch?
>
Resending it with a typo fixed.
ARM: ARM1136 r0pX cache corruption bug fix
Workaround for ARM1136 r0px errata #364296. The bug causes random
cache corruption. The workaround involves switching on partial
low interrupt latency mode, which is currently undocumented by
TRM.
---
sys/arch/arm/arm/cpufunc.c | 29 +++++++++++++++++++++++++++++
sys/arch/arm/include/armreg.h | 9 +++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/sys/arch/arm/arm/cpufunc.c b/sys/arch/arm/arm/cpufunc.c
index b95c942..ed1ba08 100644
--- a/sys/arch/arm/arm/cpufunc.c
+++ b/sys/arch/arm/arm/cpufunc.c
@@ -2373,7 +2373,10 @@ void
arm1136_setup(char *args)
{
int cpuctrl, cpuctrl_wax;
+ uint32_t auxctrl, auxctrl_wax;
+ uint32_t tmp, tmp2;
uint32_t sbz=0;
+ uint32_t cpuid;
#if defined(PROCESS_ID_IS_CURCPU)
/* set curcpu() */
@@ -2383,6 +2386,8 @@ arm1136_setup(char *args)
__asm("mcr\tp15, 0, %0, c13, c0, 4" : : "r"(&lwp0));
#endif
+ cpuid = cpu_id();
+
cpuctrl =
CPU_CONTROL_MMU_ENABLE |
CPU_CONTROL_DC_ENABLE |
@@ -2418,6 +2423,22 @@ arm1136_setup(char *args)
if (vector_page == ARM_VECTORS_HIGH)
cpuctrl |= CPU_CONTROL_VECRELOC;
+ auxctrl = 0;
+ auxctrl_wax = ~0;
+ /* This options enables the workaround for the 364296 ARM1136
+ * r0pX errata (possible cache data corruption with
+ * hit-under-miss enabled). It sets the undocumented bit 31 in
+ * the auxiliary control register and the FI bit in the control
+ * register, thus disabling hit-under-miss without putting the
+ * processor into full low interrupt latency mode. ARM11MPCore
+ * is not affected.
+ */
+ if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */
+ cpuctrl |= CPU_CONTROL_FI_ENABLE;
+ auxctrl = ARM11R0_AUXCTL_PFI;
+ auxctrl_wax = ~ARM11R0_AUXCTL_PFI;
+ }
+
/* Clear out the cache */
cpu_idcache_wbinv_all();
@@ -2428,6 +2449,14 @@ arm1136_setup(char *args)
curcpu()->ci_ctrl = cpuctrl;
cpu_control(~cpuctrl_wax, cpuctrl);
+ __asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t"
+ "bic %1, %0, %2\n\t"
+ "eor %1, %0, %3\n\t"
+ "teq %0, %1\n\t"
+ "mcrne p15, 0, %1, c1, c0, 1\n\t"
+ : "=r"(tmp), "=r"(tmp2) :
+ "r"(~auxctrl_wax), "r"(auxctrl));
+
/* And again. */
cpu_idcache_wbinv_all();
}
diff --git a/sys/arch/arm/include/armreg.h b/sys/arch/arm/include/armreg.h
index 18170a0..055ebe0 100644
--- a/sys/arch/arm/include/armreg.h
+++ b/sys/arch/arm/include/armreg.h
@@ -292,9 +292,18 @@
#define CPU_CONTROL_V4COMPAT 0x00008000 /* L4: ARMv4 compat LDR R15 etc */
#define CPU_CONTROL_UNAL_ENABLE 0x00040000 /* U: unaligned data access
*/
#define CPU_CONTROL_XP_ENABLE 0x00080000 /* XP: extended page table */
+#define CPU_CONTROL_FI_ENABLE 0x00200000 /* FI: Low interrupt latency */
#define CPU_CONTROL_IDC_ENABLE CPU_CONTROL_DC_ENABLE
+/* ARM11r0 Auxillary Control Register (CP15 register 1, opcode2 1) */
+#define ARM11R0_AUXCTL_PFI 0x80000000 /* PFI: partial FI mode. */
+ /* This is an undocumented flag
+ * used to work around a cache bug
+ * in r0 steppings. See errata
+ * 364296.
+ */
+
/* XScale Auxillary Control Register (CP15 register 1, opcode2 1) */
#define XSCALE_AUXCTL_K 0x00000001 /* dis. write buffer
coalescing */
#define XSCALE_AUXCTL_P 0x00000002 /* ECC protect page table
access */
--
1.5.6.56.g29b0d
Home |
Main Index |
Thread Index |
Old Index