Port-arm archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: OMAP2/ARM1136 cache aliasing issue
On Fri, Jul 18, 2008 at 10:09:07AM -0700, Matt Thomas wrote:
>
> On Jul 18, 2008, at 8:03 AM, Imre Deak wrote:
>
>> Hi all,
>>
>> I have an H4/OMAP2420/ARM1136r0p2 board. The data cache is 32k/4way
>> cache line size is 32 bytes. I bumped into a memory corruption bug,
>> where
>> a 4 byte location of the kernel code segment got corrupted. This can't
>> be
>> the result of a stray pointer store since pages containing code are
>> read
>> only leading to an exception when a store is attempted to such an
>> address.
>> (I also set a hardware memory write breakpoint at the given address
>> but it
>> never triggered).
>> [...]
>
> Can I suggest changing pmap_map_chunk to not use large pages and see if
> the
> corruption still happens. Just #if 0 the if at ~5578 in pmap.c
>
> Of course that corruption shouldn't have happened and it may very well be
> a silicon bug.
>
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?
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 8514f27..fb8fc27 100644
--- a/sys/arch/arm/arm/cpufunc.c
+++ b/sys/arch/arm/arm/cpufunc.c
@@ -2367,7 +2367,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() */
@@ -2377,6 +2380,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 |
@@ -2412,6 +2417,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();
@@ -2422,6 +2443,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, %0, 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