Implement workaround for:

arm11 Errata 364296:Possible Cache Data Corruption with Hit-Under-Miss

Remove hack in userret which is redundant with workaround.

workaround code from <imre.deak@teleca.com>
This commit is contained in:
matt 2008-07-22 07:07:23 +00:00
parent eb096a3c19
commit 4886aa3da7
3 changed files with 44 additions and 21 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ast.c,v 1.14 2008/04/27 18:58:43 matt Exp $ */
/* $NetBSD: ast.c,v 1.15 2008/07/22 07:07:23 matt Exp $ */
/*
* Copyright (c) 1994,1995 Mark Brinicombe
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ast.c,v 1.14 2008/04/27 18:58:43 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: ast.c,v 1.15 2008/07/22 07:07:23 matt Exp $");
#include "opt_ddb.h"
@ -74,23 +74,8 @@ void ast(struct trapframe *);
void
userret(struct lwp *l)
{
#ifdef CPU_ARM11
struct cpu_info * const ci = curcpu();
#endif
/* Invoke MI userret code */
mi_userret(l);
#ifdef CPU_ARM11
/*
* This is a hack to work around an unknown cache bug on the ARM11
* Before returning we clean the data cache.
*/
if (ci->ci_arm_cputype == CPU_ID_ARM1136JS
|| ci->ci_arm_cputype == CPU_ID_ARM1136JSR1) {
__asm("mcr\tp15, 0, %0, c7, c10, 0" :: "r"(0));
}
#endif
}
@ -120,7 +105,7 @@ ast(struct trapframe *tf)
#ifdef DEBUG
if (l == NULL)
panic("ast: no curlwp!");
if (&l->l_addr->u_pcb == 0)
if (&l->l_addr->u_pcb == NULL)
panic("ast: no pcb!");
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpufunc.c,v 1.85 2008/07/13 09:12:14 chris Exp $ */
/* $NetBSD: cpufunc.c,v 1.86 2008/07/22 07:07:23 matt Exp $ */
/*
* arm7tdmi support code Copyright (c) 2001 John Fremlin
@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.85 2008/07/13 09:12:14 chris Exp $");
__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.86 2008/07/22 07:07:23 matt Exp $");
#include "opt_compat_netbsd.h"
#include "opt_cpuoptions.h"
@ -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, %1, c1, c0, 1\n\t"
: "=r"(tmp), "=r"(tmp2) :
"r"(~auxctrl_wax), "r"(auxctrl));
/* And again. */
cpu_idcache_wbinv_all();
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: armreg.h,v 1.38 2008/04/27 18:58:44 matt Exp $ */
/* $NetBSD: armreg.h,v 1.39 2008/07/22 07:07:23 matt Exp $ */
/*
* Copyright (c) 1998, 2001 Ben Harris
@ -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 */