Module Name: src
Committed By: matt
Date: Fri Sep 7 11:49:00 UTC 2012
Modified Files:
src/sys/arch/arm/arm: cpufunc.c cpufunc_asm_arm9.S cpufunc_asm_armv5.S
cpufunc_asm_armv5_ec.S cpufunc_asm_sheeva.S
src/sys/arch/arm/arm32: cpu.c fault.c genassym.cf
src/sys/arch/arm/cortex: pl310.c pl310_reg.h
src/sys/arch/arm/include: armreg.h cpu.h cpufunc.h
src/sys/arch/arm/include/arm32: pmap.h
Added Files:
src/sys/arch/arm/cortex: pl310_var.h
Log Message:
Switch cortex_a9 back to need_ptesync = 1
Add code to disable the L2 cache on cortex-a9 (for now).
Add evcnt for all the fault types.
Move cache info in a structure and have one for the pcache and one for scache.
Probe L1/L2 caches properly for ARMv7
To generate a diff of this commit:
cvs rdiff -u -r1.114 -r1.115 src/sys/arch/arm/arm/cpufunc.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/arm/cpufunc_asm_arm9.S
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/arm/cpufunc_asm_armv5.S
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/arm/cpufunc_asm_armv5_ec.S
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/arm/cpufunc_asm_sheeva.S
cvs rdiff -u -r1.85 -r1.86 src/sys/arch/arm/arm32/cpu.c
cvs rdiff -u -r1.84 -r1.85 src/sys/arch/arm/arm32/fault.c
cvs rdiff -u -r1.53 -r1.54 src/sys/arch/arm/arm32/genassym.cf
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/cortex/pl310.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/cortex/pl310_reg.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/cortex/pl310_var.h
cvs rdiff -u -r1.63 -r1.64 src/sys/arch/arm/include/armreg.h
cvs rdiff -u -r1.72 -r1.73 src/sys/arch/arm/include/cpu.h
cvs rdiff -u -r1.57 -r1.58 src/sys/arch/arm/include/cpufunc.h
cvs rdiff -u -r1.109 -r1.110 src/sys/arch/arm/include/arm32/pmap.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/arm/cpufunc.c
diff -u src/sys/arch/arm/arm/cpufunc.c:1.114 src/sys/arch/arm/arm/cpufunc.c:1.115
--- src/sys/arch/arm/arm/cpufunc.c:1.114 Fri Sep 7 04:39:14 2012
+++ src/sys/arch/arm/arm/cpufunc.c Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.c,v 1.114 2012/09/07 04:39:14 matt Exp $ */
+/* $NetBSD: cpufunc.c,v 1.115 2012/09/07 11:48:59 matt Exp $ */
/*
* arm7tdmi support code Copyright (c) 2001 John Fremlin
@@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.114 2012/09/07 04:39:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.115 2012/09/07 11:48:59 matt Exp $");
#include "opt_compat_netbsd.h"
#include "opt_cpuoptions.h"
@@ -92,23 +92,14 @@ struct arm_pmc_funcs *arm_pmc;
#endif
/* PRIMARY CACHE VARIABLES */
-int arm_picache_size;
-int arm_picache_line_size;
-int arm_picache_ways;
-
-int arm_pdcache_size; /* and unified */
-int arm_pdcache_line_size;
-int arm_pdcache_ways;
#if (ARM_MMU_V6 + ARM_MMU_V7) != 0
-int arm_cache_prefer_mask;
+u_int arm_cache_prefer_mask;
#endif
+struct arm_cache_info arm_pcache;
+struct arm_cache_info arm_scache;
-
-int arm_pcache_type;
-int arm_pcache_unified;
-
-int arm_dcache_align;
-int arm_dcache_align_mask;
+u_int arm_dcache_align;
+u_int arm_dcache_align_mask;
/* 1 == use cpu_sleep(), 0 == don't */
int cpu_do_powersave;
@@ -1355,6 +1346,43 @@ get_cachesize_cp15(int cssr)
}
#endif
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
+static void
+get_cacheinfo_clidr(struct arm_cache_info *info, u_int level, u_int clidr)
+{
+ u_int csid;
+ u_int nsets;
+
+ if (clidr & 6) {
+ csid = get_cachesize_cp15(level << 1); /* select L1 dcache values */
+ nsets = CPU_CSID_NUMSETS(csid) + 1;
+ info->dcache_ways = CPU_CSID_ASSOC(csid) + 1;
+ info->dcache_line_size = 1U << (CPU_CSID_LEN(csid) + 4);
+ info->dcache_size = info->dcache_line_size * info->dcache_ways * nsets;
+
+ if (level == 0) {
+ arm_dcache_log2_assoc = CPU_CSID_ASSOC(csid) + 1;
+ arm_dcache_log2_linesize = CPU_CSID_LEN(csid) + 4;
+ arm_dcache_log2_nsets = 31 - __builtin_clz(nsets);
+ }
+ }
+
+ info->cache_unified = (clidr == 4);
+
+ if (clidr & 1) {
+ csid = get_cachesize_cp15((level << 1)|CPU_CSSR_InD); /* select L1 icache values */
+ nsets = CPU_CSID_NUMSETS(csid) + 1;
+ info->icache_ways = CPU_CSID_ASSOC(csid) + 1;
+ info->icache_line_size = 1U << (CPU_CSID_LEN(csid) + 4);
+ info->icache_size = info->icache_line_size * info->icache_ways * nsets;
+ } else {
+ info->icache_ways = info->dcache_ways;
+ info->icache_line_size = info->dcache_line_size;
+ info->icache_size = info->dcache_size;
+ }
+}
+#endif /* (ARM_MMU_V6 + ARM_MMU_V7) > 0 */
+
static void
get_cachetype_cp15(void)
{
@@ -1376,57 +1404,43 @@ get_cachetype_cp15(void)
#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
if (CPU_CT_FORMAT(ctype) == 4) {
- u_int csid0, csid1;
-
- isize = 1U << (CPU_CT4_ILINE(ctype) + 2);
- dsize = 1U << (CPU_CT4_DLINE(ctype) + 2);
+ u_int clidr = armreg_clidr_read();
- csid0 = get_cachesize_cp15(CPU_CSSR_L1); /* select L1 dcache values */
- arm_pdcache_ways = CPU_CSID_ASSOC(csid0) + 1;
- arm_pdcache_line_size = dsize;
- arm_pdcache_size = arm_pdcache_line_size * arm_pdcache_ways;
- arm_pdcache_size *= (CPU_CSID_NUMSETS(csid0) + 1);
arm_cache_prefer_mask = PAGE_SIZE;
+ arm_pcache.cache_type = CPU_CT_CTYPE_WB14;
- arm_dcache_align = arm_pdcache_line_size;
-
- csid1 = get_cachesize_cp15(CPU_CSSR_L1|CPU_CSSR_InD); /* select L1 icache values */
- arm_picache_ways = CPU_CSID_ASSOC(csid1) + 1;
- arm_picache_line_size = isize;
- arm_picache_size = arm_picache_line_size * arm_picache_ways;
- arm_picache_size *= (CPU_CSID_NUMSETS(csid1) + 1);
- arm_cache_prefer_mask = PAGE_SIZE;
-
- arm_dcache_align = arm_pdcache_line_size;
-
- arm_dcache_log2_assoc = CPU_CSID_ASSOC(csid1) + 1;
- arm_dcache_log2_linesize = CPU_CSID_LEN(csid1) + 2;
- arm_dcache_log2_nsets = CPU_CSID_NUMSETS(csid1) + 1;
- arm_pcache_type = CPU_CT_CTYPE_WB14;
+ get_cacheinfo_clidr(&arm_pcache, 0, clidr & 7);
+ arm_dcache_align = arm_pcache.dcache_line_size;
+ clidr >>= 3;
+ if (clidr & 7) {
+ get_cacheinfo_clidr(&arm_scache, 1, clidr & 7);
+ if (arm_scache.dcache_line_size < arm_dcache_align)
+ arm_dcache_align = arm_scache.dcache_line_size;
+ }
goto out;
}
#endif /* ARM_MMU_V6 + ARM_MMU_V7 > 0 */
if ((ctype & CPU_CT_S) == 0)
- arm_pcache_unified = 1;
+ arm_pcache.cache_unified = 1;
/*
* If you want to know how this code works, go read the ARM ARM.
*/
- arm_pcache_type = CPU_CT_CTYPE(ctype);
+ arm_pcache.cache_type = CPU_CT_CTYPE(ctype);
- if (arm_pcache_unified == 0) {
+ if (arm_pcache.cache_unified == 0) {
isize = CPU_CT_ISIZE(ctype);
multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
- arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
+ arm_pcache.icache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
if (isize & CPU_CT_xSIZE_M)
- arm_picache_line_size = 0; /* not present */
+ arm_pcache.icache_line_size = 0; /* not present */
else
- arm_picache_ways = 1;
+ arm_pcache.icache_ways = 1;
} else {
- arm_picache_ways = multiplier <<
+ arm_pcache.icache_ways = multiplier <<
(CPU_CT_xSIZE_ASSOC(isize) - 1);
#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
if (CPU_CT_xSIZE_P & isize)
@@ -1436,19 +1450,19 @@ get_cachetype_cp15(void)
- PAGE_SIZE;
#endif
}
- arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
+ arm_pcache.icache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
}
dsize = CPU_CT_DSIZE(ctype);
multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
- arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
+ arm_pcache.dcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
if (dsize & CPU_CT_xSIZE_M)
- arm_pdcache_line_size = 0; /* not present */
+ arm_pcache.dcache_line_size = 0; /* not present */
else
- arm_pdcache_ways = 1;
+ arm_pcache.dcache_ways = 1;
} else {
- arm_pdcache_ways = multiplier <<
+ arm_pcache.dcache_ways = multiplier <<
(CPU_CT_xSIZE_ASSOC(dsize) - 1);
#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
if (CPU_CT_xSIZE_P & dsize)
@@ -1457,9 +1471,9 @@ get_cachetype_cp15(void)
- CPU_CT_xSIZE_ASSOC(dsize)) - PAGE_SIZE;
#endif
}
- arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
+ arm_pcache.dcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
- arm_dcache_align = arm_pdcache_line_size;
+ arm_dcache_align = arm_pcache.dcache_line_size;
arm_dcache_log2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
arm_dcache_log2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
@@ -1515,20 +1529,20 @@ get_cachetype_table(void)
for (i = 0; cachetab[i].ct_cpuid != 0; i++) {
if (cachetab[i].ct_cpuid == (cpuid & CPU_ID_CPU_MASK)) {
- arm_pcache_type = cachetab[i].ct_pcache_type;
- arm_pcache_unified = cachetab[i].ct_pcache_unified;
- arm_pdcache_size = cachetab[i].ct_pdcache_size;
- arm_pdcache_line_size =
+ arm_pcache.cache_type = cachetab[i].ct_pcache_type;
+ arm_pcache.cache_unified = cachetab[i].ct_pcache_unified;
+ arm_pcache.dcache_size = cachetab[i].ct_pdcache_size;
+ arm_pcache.dcache_line_size =
cachetab[i].ct_pdcache_line_size;
- arm_pdcache_ways = cachetab[i].ct_pdcache_ways;
- arm_picache_size = cachetab[i].ct_picache_size;
- arm_picache_line_size =
+ arm_pcache.dcache_ways = cachetab[i].ct_pdcache_ways;
+ arm_pcache.icache_size = cachetab[i].ct_picache_size;
+ arm_pcache.icache_line_size =
cachetab[i].ct_picache_line_size;
- arm_picache_ways = cachetab[i].ct_picache_ways;
+ arm_pcache.icache_ways = cachetab[i].ct_picache_ways;
}
}
- arm_dcache_align = arm_pdcache_line_size;
+ arm_dcache_align = arm_pcache.dcache_line_size;
arm_dcache_align_mask = arm_dcache_align - 1;
}
Index: src/sys/arch/arm/arm/cpufunc_asm_arm9.S
diff -u src/sys/arch/arm/arm/cpufunc_asm_arm9.S:1.7 src/sys/arch/arm/arm/cpufunc_asm_arm9.S:1.8
--- src/sys/arch/arm/arm/cpufunc_asm_arm9.S:1.7 Sun Jan 3 04:25:16 2010
+++ src/sys/arch/arm/arm/cpufunc_asm_arm9.S Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc_asm_arm9.S,v 1.7 2010/01/03 04:25:16 uebayasi Exp $ */
+/* $NetBSD: cpufunc_asm_arm9.S,v 1.8 2012/09/07 11:48:59 matt Exp $ */
/*
* Copyright (c) 2001, 2004 ARM Limited
@@ -34,6 +34,8 @@
#include <machine/cpu.h>
#include <machine/asm.h>
+#include "assym.h"
+
/*
* Functions to set the MMU Translation Table Base register
*
@@ -110,7 +112,7 @@ ENTRY_NP(arm9_icache_sync_all)
mov pc, lr
.Larm9_line_size:
- .word _C_LABEL(arm_pdcache_line_size)
+ .word _C_LABEL(arm_pcache) + DCACHE_LINE_SIZE
ENTRY(arm9_dcache_wb_range)
ldr ip, .Larm9_line_size
Index: src/sys/arch/arm/arm/cpufunc_asm_armv5.S
diff -u src/sys/arch/arm/arm/cpufunc_asm_armv5.S:1.3 src/sys/arch/arm/arm/cpufunc_asm_armv5.S:1.4
--- src/sys/arch/arm/arm/cpufunc_asm_armv5.S:1.3 Sat Jan 6 00:50:54 2007
+++ src/sys/arch/arm/arm/cpufunc_asm_armv5.S Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc_asm_armv5.S,v 1.3 2007/01/06 00:50:54 christos Exp $ */
+/* $NetBSD: cpufunc_asm_armv5.S,v 1.4 2012/09/07 11:48:59 matt Exp $ */
/*
* Copyright (c) 2002, 2005 ARM Limited
@@ -36,6 +36,8 @@
#include <machine/cpu.h>
#include <machine/asm.h>
+#include "assym.h"
+
/*
* Functions to set the MMU Translation Table Base register
*
@@ -107,7 +109,7 @@ ENTRY_NP(armv5_icache_sync_all)
RET
.Larmv5_line_size:
- .word _C_LABEL(arm_pdcache_line_size)
+ .word _C_LABEL(arm_pcache) + DCACHE_LINE_SIZE
ENTRY(armv5_dcache_wb_range)
ldr ip, .Larmv5_line_size
Index: src/sys/arch/arm/arm/cpufunc_asm_armv5_ec.S
diff -u src/sys/arch/arm/arm/cpufunc_asm_armv5_ec.S:1.1 src/sys/arch/arm/arm/cpufunc_asm_armv5_ec.S:1.2
--- src/sys/arch/arm/arm/cpufunc_asm_armv5_ec.S:1.1 Sat Jan 6 00:50:54 2007
+++ src/sys/arch/arm/arm/cpufunc_asm_armv5_ec.S Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc_asm_armv5_ec.S,v 1.1 2007/01/06 00:50:54 christos Exp $ */
+/* $NetBSD: cpufunc_asm_armv5_ec.S,v 1.2 2012/09/07 11:48:59 matt Exp $ */
/*
* Copyright (c) 2002, 2005 ARM Limited
@@ -39,6 +39,8 @@
#include <machine/cpu.h>
#include <machine/asm.h>
+#include "assym.h"
+
/*
* Functions to set the MMU Translation Table Base register
*
@@ -109,7 +111,7 @@ ENTRY_NP(armv5_ec_icache_sync_all)
RET
.Larmv5_ec_line_size:
- .word _C_LABEL(arm_pdcache_line_size)
+ .word _C_LABEL(arm_pcache) + DCACHE_LINE_SIZE
ENTRY(armv5_ec_dcache_wb_range)
ldr ip, .Larmv5_ec_line_size
Index: src/sys/arch/arm/arm/cpufunc_asm_sheeva.S
diff -u src/sys/arch/arm/arm/cpufunc_asm_sheeva.S:1.2 src/sys/arch/arm/arm/cpufunc_asm_sheeva.S:1.3
--- src/sys/arch/arm/arm/cpufunc_asm_sheeva.S:1.2 Sat Jul 14 12:59:55 2012
+++ src/sys/arch/arm/arm/cpufunc_asm_sheeva.S Fri Sep 7 11:48:59 2012
@@ -31,10 +31,11 @@
#include <machine/cpu.h>
#include <machine/asm.h>
-#include <arm/arm32/vmparam.h>
+
+#include "assym.h"
.Lsheeva_cache_line_size:
- .word _C_LABEL(arm_pdcache_line_size)
+ .word _C_LABEL(arm_pcache) + DCACHE_LINE_SIZE
.Lsheeva_asm_page_mask:
.word _C_LABEL(PAGE_MASK)
Index: src/sys/arch/arm/arm32/cpu.c
diff -u src/sys/arch/arm/arm32/cpu.c:1.85 src/sys/arch/arm/arm32/cpu.c:1.86
--- src/sys/arch/arm/arm32/cpu.c:1.85 Wed Aug 29 17:44:25 2012
+++ src/sys/arch/arm/arm32/cpu.c Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.85 2012/08/29 17:44:25 matt Exp $ */
+/* $NetBSD: cpu.c,v 1.86 2012/09/07 11:48:59 matt Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
@@ -46,7 +46,7 @@
#include <sys/param.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.85 2012/08/29 17:44:25 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.86 2012/09/07 11:48:59 matt Exp $");
#include <sys/systm.h>
#include <sys/conf.h>
@@ -86,6 +86,7 @@ void identify_features(device_t dv);
void
cpu_attach(device_t dv, cpuid_t id)
{
+ const char * const xname = device_xname(dv);
struct cpu_info *ci;
if (id == 0) {
@@ -127,7 +128,40 @@ cpu_attach(device_t dv, cpuid_t id)
dv->dv_private = ci;
evcnt_attach_dynamic(&ci->ci_arm700bugcount, EVCNT_TYPE_MISC,
- NULL, device_xname(dv), "arm700swibug");
+ NULL, xname, "arm700swibug");
+
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_WRTBUF_0], EVCNT_TYPE_TRAP,
+ NULL, xname, "vector abort");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_WRTBUF_1], EVCNT_TYPE_TRAP,
+ NULL, xname, "terminal abort");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_0], EVCNT_TYPE_TRAP,
+ NULL, xname, "external linefetch abort (S)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_1], EVCNT_TYPE_TRAP,
+ NULL, xname, "external linefetch abort (P)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_2], EVCNT_TYPE_TRAP,
+ NULL, xname, "external non-linefetch abort (S)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_3], EVCNT_TYPE_TRAP,
+ NULL, xname, "external non-linefetch abort (P)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSTRNL1], EVCNT_TYPE_TRAP,
+ NULL, xname, "external translation abort (L1)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSTRNL2], EVCNT_TYPE_TRAP,
+ NULL, xname, "external translation abort (L2)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_ALIGN_0], EVCNT_TYPE_TRAP,
+ NULL, xname, "alignment abort (0)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_ALIGN_1], EVCNT_TYPE_TRAP,
+ NULL, xname, "alignment abort (1)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_TRANS_S], EVCNT_TYPE_TRAP,
+ NULL, xname, "translation abort (S)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_TRANS_P], EVCNT_TYPE_TRAP,
+ NULL, xname, "translation abort (P)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_DOMAIN_S], EVCNT_TYPE_TRAP,
+ NULL, xname, "domain abort (S)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_DOMAIN_P], EVCNT_TYPE_TRAP,
+ NULL, xname, "domain abort (P)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_PERM_S], EVCNT_TYPE_TRAP,
+ NULL, xname, "permission abort (S)");
+ evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_PERM_P], EVCNT_TYPE_TRAP,
+ NULL, xname, "permission abort (P)");
#ifdef MULTIPROCESSOR
/*
@@ -538,9 +572,28 @@ static const char * const wtnames[] = {
"**unknown 12**",
"**unknown 13**",
"write-back-locking-C",
- "**unknown 15**",
+ "write-back-locking-D",
};
+static void
+print_cache_info(device_t dv, struct arm_cache_info *info, u_int level)
+{
+ if (info->cache_unified) {
+ aprint_normal_dev(dv, "%dKB/%dB %d-way %s L%u Unified cache\n",
+ info->dcache_size / 1024,
+ info->dcache_line_size, info->dcache_ways,
+ wtnames[info->cache_type], level + 1);
+ } else {
+ aprint_normal_dev(dv, "%dKB/%dB %d-way L%u Instruction cache\n",
+ info->icache_size / 1024,
+ info->icache_line_size, info->icache_ways, level + 1);
+ aprint_normal_dev(dv, "%dKB/%dB %d-way %s L%u Data cache\n",
+ info->dcache_size / 1024,
+ info->dcache_line_size, info->dcache_ways,
+ wtnames[info->cache_type], level + 1);
+ }
+}
+
void
identify_arm_cpu(device_t dv, struct cpu_info *ci)
{
@@ -632,7 +685,7 @@ identify_arm_cpu(device_t dv, struct cpu
aprint_normal("\n");
-#ifdef CPU_CORTEX
+#if defined(CPU_CORTEX) && 0
if (CPU_ID_CORTEX_P(cpuid)) {
identify_cortex_caches(dv);
if (0)
@@ -640,23 +693,11 @@ identify_arm_cpu(device_t dv, struct cpu
} else
#endif
/* Print cache info. */
- if (arm_picache_line_size != 0 || arm_pdcache_line_size != 0) {
-
- if (arm_pcache_unified) {
- aprint_normal_dev(dv, "%dKB/%dB %d-way %s unified cache\n",
- arm_pdcache_size / 1024,
- arm_pdcache_line_size, arm_pdcache_ways,
- wtnames[arm_pcache_type]);
- } else {
- aprint_normal_dev(dv, "%dKB/%dB %d-way Instruction cache\n",
- arm_picache_size / 1024,
- arm_picache_line_size, arm_picache_ways);
- aprint_normal_dev(dv, "%dKB/%dB %d-way %s Data cache\n",
- arm_pdcache_size / 1024,
- arm_pdcache_line_size, arm_pdcache_ways,
- wtnames[arm_pcache_type]);
- }
-
+ if (arm_pcache.icache_line_size != 0 || arm_pcache.dcache_line_size != 0) {
+ print_cache_info(dv, &arm_pcache, 0);
+ }
+ if (arm_scache.icache_line_size != 0 || arm_scache.dcache_line_size != 0) {
+ print_cache_info(dv, &arm_scache, 1);
}
@@ -725,7 +766,7 @@ identify_arm_cpu(device_t dv, struct cpu
}
}
-#ifdef CPU_CORTEX
+#if defined(CPU_CORTEX) && 0
static void
print_cortex_cache(device_t dv, u_int level, const char *desc)
{
Index: src/sys/arch/arm/arm32/fault.c
diff -u src/sys/arch/arm/arm32/fault.c:1.84 src/sys/arch/arm/arm32/fault.c:1.85
--- src/sys/arch/arm/arm32/fault.c:1.84 Wed Aug 29 16:48:11 2012
+++ src/sys/arch/arm/arm32/fault.c Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: fault.c,v 1.84 2012/08/29 16:48:11 matt Exp $ */
+/* $NetBSD: fault.c,v 1.85 2012/09/07 11:48:59 matt Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@@ -81,7 +81,7 @@
#include "opt_kgdb.h"
#include <sys/types.h>
-__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.84 2012/08/29 16:48:11 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.85 2012/09/07 11:48:59 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -255,6 +255,8 @@ data_abort_handler(trapframe_t *tf)
/* Grab the current pcb */
struct pcb * const pcb = lwp_getpcb(l);
+ curcpu()->ci_abt_evs[fsr & FAULT_TYPE_MASK].ev_count++;
+
/* Invoke the appropriate handler, if necessary */
if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) {
#ifdef DIAGNOSTIC
Index: src/sys/arch/arm/arm32/genassym.cf
diff -u src/sys/arch/arm/arm32/genassym.cf:1.53 src/sys/arch/arm/arm32/genassym.cf:1.54
--- src/sys/arch/arm/arm32/genassym.cf:1.53 Sat Sep 1 14:46:25 2012
+++ src/sys/arch/arm/arm32/genassym.cf Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.53 2012/09/01 14:46:25 matt Exp $
+# $NetBSD: genassym.cf,v 1.54 2012/09/07 11:48:59 matt Exp $
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@@ -78,6 +78,8 @@ define KERNEL_BASE KERNEL_BASE
define VM_MIN_ADDRESS VM_MIN_ADDRESS
define VM_MAXUSER_ADDRESS VM_MAXUSER_ADDRESS
+define DCACHE_LINE_SIZE offsetof(struct arm_cache_info, dcache_line_size)
+
define PV_PA offsetof(pv_addr_t, pv_pa)
define PMAP_DOMAIN_KERNEL PMAP_DOMAIN_KERNEL
define DOMAIN_CLIENT DOMAIN_CLIENT
@@ -103,6 +105,7 @@ ifdef PMAP_INCLUDE_PTE_SYNC
define PMAP_INCLUDE_PTE_SYNC 1
endif
+define PAGE_MASK PAGE_MASK
define PAGE_SIZE PAGE_SIZE
define UPAGES UPAGES
define PGSHIFT PGSHIFT
Index: src/sys/arch/arm/cortex/pl310.c
diff -u src/sys/arch/arm/cortex/pl310.c:1.2 src/sys/arch/arm/cortex/pl310.c:1.3
--- src/sys/arch/arm/cortex/pl310.c:1.2 Sun Sep 2 16:56:41 2012
+++ src/sys/arch/arm/cortex/pl310.c Fri Sep 7 11:49:00 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pl310.c,v 1.2 2012/09/02 16:56:41 matt Exp $ */
+/* $NetBSD: pl310.c,v 1.3 2012/09/07 11:49:00 matt Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pl310.c,v 1.2 2012/09/02 16:56:41 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pl310.c,v 1.3 2012/09/07 11:49:00 matt Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: pl310.c,v 1.
#include <arm/cortex/mpcore_var.h>
#include <arm/cortex/pl310_reg.h>
+#include <arm/cortex/pl310_var.h>
static int arml2cc_match(device_t, cfdata_t, void *);
static void arml2cc_attach(device_t, device_t, void *);
@@ -55,6 +56,8 @@ struct arml2cc_softc {
CFATTACH_DECL_NEW(arml2cc, sizeof(struct arml2cc_softc),
arml2cc_match, arml2cc_attach, NULL, NULL);
+static void arml2cc_disable(struct arml2cc_softc *);
+
static bool attached;
static inline uint32_t
@@ -132,29 +135,59 @@ arml2cc_attach(device_t parent, device_t
}
aprint_naive("\n");
- aprint_normal(": ARM PL310 L2%s Cache Controller\n", revstr);
+ aprint_normal(": ARM PL310%s L2 Cache Controller%s\n",
+ revstr, arml2cc_read_4(sc, L2C_CTL) ? "" : " (disabled)");
+
+ arml2cc_disable(sc);
+ aprint_normal_dev(self, "cache %s\n",
+ arml2cc_read_4(sc, L2C_CTL) ? "enabled" : "disabled");
+}
+
+void
+arml2cc_disable(struct arml2cc_softc *sc)
+{
+ uint32_t way_mask = __BIT(arm_scache.dcache_ways) - 1;
+ register_t psw = cpsid(I32_bit);
+
+ arml2cc_write_4(sc, L2C_CLEAN_INV_WAY, way_mask);
+ while (arml2cc_read_4(sc, L2C_CLEAN_INV_WAY) != 0) {
+ /* spin */
+ }
+
+ arml2cc_write_4(sc, L2C_CACHE_SYNC, 0);
+ while (arml2cc_read_4(sc, L2C_CACHE_SYNC) & 1) {
+ /* spin */
+ }
- uint32_t cfg = arml2cc_read_4(sc, L2C_CACHE_TYPE);
- //u_int cfg_ctype = __SHIFTOUT(cfg, CACHE_TYPE_CTYPE);
- bool cfg_harvard_p = __SHIFTOUT(cfg, CACHE_TYPE_HARVARD) != 0;
+ arml2cc_write_4(sc, L2C_CTL, 0); // turn it off */
+ cpsie(psw);
+}
+
+void
+arml2cc_init(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t o)
+{
+ struct arm_cache_info * const info = &arm_scache;
+
+ uint32_t cfg = bus_space_read_4(bst, bsh, o + L2C_CACHE_TYPE);
+
+ info->cache_type = __SHIFTOUT(cfg, CACHE_TYPE_CTYPE);
+ info->cache_unified = __SHIFTOUT(cfg, CACHE_TYPE_HARVARD) == 0;
u_int cfg_dsize = __SHIFTOUT(cfg, CACHE_TYPE_DSIZE);
- u_int d_waysize = 8192 << __SHIFTOUT(cfg_dsize, CACHE_TYPE_xWAYSIZE);
- u_int d_assoc = 8 << __SHIFTOUT(cfg_dsize, CACHE_TYPE_xASSOC);
- u_int d_linesize = 32 << __SHIFTOUT(cfg_dsize, CACHE_TYPE_xLINESIZE);
- u_int d_size = d_waysize * d_assoc;
- if (cfg_harvard_p) {
+ u_int d_waysize = 8192 << __SHIFTOUT(cfg_dsize, CACHE_TYPE_xWAYSIZE);
+ info->dcache_ways = 8 << __SHIFTOUT(cfg_dsize, CACHE_TYPE_xASSOC);
+ info->dcache_line_size = 32 << __SHIFTOUT(cfg_dsize, CACHE_TYPE_xLINESIZE);
+ info->dcache_size = info->dcache_ways * d_waysize;
+
+ if (info->cache_unified) {
+ info->icache_ways = info->dcache_ways;
+ info->icache_line_size = info->dcache_line_size;
+ info->icache_size = info->dcache_size;
+ } else {
u_int cfg_isize = __SHIFTOUT(cfg, CACHE_TYPE_ISIZE);
u_int i_waysize = 8192 << __SHIFTOUT(cfg_isize, CACHE_TYPE_xWAYSIZE);
- u_int i_assoc = 8 << __SHIFTOUT(cfg_isize, CACHE_TYPE_xASSOC);
- u_int i_linesize = 32 << __SHIFTOUT(cfg_isize, CACHE_TYPE_xLINESIZE);
- u_int i_size = i_waysize * i_assoc;
-
- aprint_normal_dev(self, "%uKB/%uB %u-way L2 Instruction cache\n",
- i_size / 1024, i_linesize, i_assoc);
+ info->icache_ways = 8 << __SHIFTOUT(cfg_isize, CACHE_TYPE_xASSOC);
+ info->icache_line_size = 32 << __SHIFTOUT(cfg_isize, CACHE_TYPE_xLINESIZE);
+ info->icache_size = i_waysize * info->icache_ways;
}
-
- aprint_normal_dev(self, "%uKB/%uB %u-way write-back L2 %s cache\n",
- d_size / 1024, d_linesize, d_assoc,
- (cfg_harvard_p ? "Data" : "Unified"));
}
Index: src/sys/arch/arm/cortex/pl310_reg.h
diff -u src/sys/arch/arm/cortex/pl310_reg.h:1.1 src/sys/arch/arm/cortex/pl310_reg.h:1.2
--- src/sys/arch/arm/cortex/pl310_reg.h:1.1 Sun Sep 2 16:55:10 2012
+++ src/sys/arch/arm/cortex/pl310_reg.h Fri Sep 7 11:49:00 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pl310_reg.h,v 1.1 2012/09/02 16:55:10 matt Exp $ */
+/* $NetBSD: pl310_reg.h,v 1.2 2012/09/07 11:49:00 matt Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -37,25 +37,56 @@
*/
#define L2C_CACHE_ID 0x000
-#define CACHE_ID_IMPL __BITS(31,24)
-#define CACHE_ID_ID __BITS(15,10)
-#define CACHE_ID_PART __BITS(9,6)
-#define CACHE_ID_PART_PL310 3
-#define CACHE_ID_REV __BITS(5,0)
-#define CACHE_ID_REV_R3P3 9
-#define CACHE_ID_REV_R3P2 8
+#define CACHE_ID_IMPL __BITS(31,24)
+#define CACHE_ID_ID __BITS(15,10)
+#define CACHE_ID_PART __BITS(9,6)
+#define CACHE_ID_PART_PL310 3
+#define CACHE_ID_REV __BITS(5,0)
+#define CACHE_ID_REV_R3P3 9
+#define CACHE_ID_REV_R3P2 8
+
#define L2C_CACHE_TYPE 0x004
-#define CACHE_TYPE_DATA_BANKING __BIT(31)
-#define CACHE_TYPE_CTYPE __BITS(28,25)
-#define CACHE_TYPE_HARVARD __BIT(24)
-#define CACHE_TYPE_DSIZE __BITS(23,12)
-#define CACHE_TYPE_ISIZE __BITS(11,0)
-#define CACHE_TYPE_xWAYSIZE __BITS(10,8)
-#define CACHE_TYPE_xASSOC __BIT(6)
-#define CACHE_TYPE_xLINESIZE __BITS(5,0)
+#define CACHE_TYPE_DATA_BANKING __BIT(31)
+#define CACHE_TYPE_CTYPE __BITS(28,25)
+#define CACHE_TYPE_HARVARD __BIT(24)
+#define CACHE_TYPE_DSIZE __BITS(23,12)
+#define CACHE_TYPE_ISIZE __BITS(11,0)
+#define CACHE_TYPE_xWAYSIZE __BITS(10,8)
+#define CACHE_TYPE_xASSOC __BIT(6)
+#define CACHE_TYPE_xLINESIZE __BITS(5,0)
#define L2C_CTL 0x100
+#define CTL_ENABLE __BIT(1)
#define L2C_AUXCTL 0x104
+#define AUXCTL_EARLY_BRESP_EN __BIT(30)
+#define AUXCTL_I_PREFETCH __BIT(29)
+#define AUXCTL_D_PREFETCH __BIT(28)
+#define AUXCTL_NS_INT_ACC_CTL __BIT(27)
+#define AUXCTL_NS_INT_LOCK_EN __BIT(26)
+#define AUXCTL_CACHE_REPL_RR __BIT(25)
+#define AUXCTL_FORCE_WA __BITS(24,23)
+#define AUXCTL_FORCE_WA_AWCACHE 0
+#define AUXCTL_FORCE_WA_NEVER 1
+#define AUXCTL_FORCE_WA_ALWAYS 2
+#define AUXCTL_FORCE_WA_0 3
+#define AUXCTL_SHARED_ATT_OVR __BIT(22)
+#define AUXCTL_PARITY_EN __BIT(21)
+#define AUXCTL_EVT_MON_BUS_EN __BIT(20)
+#define AUXCTL_WAY_SIZE __BITS(19,17)
+#define AUXCTL_WAY_SIZE_RSVD0 0
+#define AUXCTL_WAY_SIZE_16KB 1
+#define AUXCTL_WAY_SIZE_32KB 2
+#define AUXCTL_WAY_SIZE_64KB 3
+#define AUXCTL_WAY_SIZE_128KB 4
+#define AUXCTL_WAY_SIZE_256KB 5
+#define AUXCTL_WAY_SIZE_512KB 6
+#define AUXCTL_WAY_SIZE_RSVD7 7
+#define AUXCTL_ASSOCIATIVITY __BIT(16)
+#define AUXCTL_SH_ATTR_INV_ENA __BIT(13)
+#define AUXCTL_EXCL_CACHE_CFG __BIT(12)
+#define AUXCTL_ST_BUF_DEV_LIM_EN __BIT(11)
+#define AUXCTL_HIPRO_SO_DEV_EN __BIT(10)
+#define AUXCTL_FULL_LINE_WR0 __BIT(0)
#define L2C_TAGRAM_CTL 0x108
#define L2C_DATARAM_CTL 0x10c
Index: src/sys/arch/arm/include/armreg.h
diff -u src/sys/arch/arm/include/armreg.h:1.63 src/sys/arch/arm/include/armreg.h:1.64
--- src/sys/arch/arm/include/armreg.h:1.63 Thu Sep 6 02:05:46 2012
+++ src/sys/arch/arm/include/armreg.h Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: armreg.h,v 1.63 2012/09/06 02:05:46 matt Exp $ */
+/* $NetBSD: armreg.h,v 1.64 2012/09/07 11:48:59 matt Exp $ */
/*
* Copyright (c) 1998, 2001 Ben Harris
@@ -425,7 +425,7 @@
#define CPU_CSID_CTYPE_WA 0x10000000 /* write-allocation avail */
#define CPU_CSID_NUMSETS(x) (((x) >> 13) & 0x7fff)
#define CPU_CSID_ASSOC(x) (((x) >> 3) & 0x1ff)
-#define CPU_CSID_LEN(x) ((x) & 0x03)
+#define CPU_CSID_LEN(x) ((x) & 0x07)
/* Cache size selection register definitions 2, Rd, c0, c0, 0 */
#define CPU_CSSR_L2 0x00000002
Index: src/sys/arch/arm/include/cpu.h
diff -u src/sys/arch/arm/include/cpu.h:1.72 src/sys/arch/arm/include/cpu.h:1.73
--- src/sys/arch/arm/include/cpu.h:1.72 Wed Aug 29 23:10:31 2012
+++ src/sys/arch/arm/include/cpu.h Fri Sep 7 11:48:59 2012
@@ -251,6 +251,7 @@ struct cpu_info {
#if defined(_ARM_ARCH_7)
uint64_t ci_lastintr;
#endif
+ struct evcnt ci_abt_evs[FAULT_TYPE_MASK+1];
#if defined(MP_CPU_INFO_MEMBERS)
MP_CPU_INFO_MEMBERS
#endif
Index: src/sys/arch/arm/include/cpufunc.h
diff -u src/sys/arch/arm/include/cpufunc.h:1.57 src/sys/arch/arm/include/cpufunc.h:1.58
--- src/sys/arch/arm/include/cpufunc.h:1.57 Sat Jul 21 12:19:15 2012
+++ src/sys/arch/arm/include/cpufunc.h Fri Sep 7 11:48:59 2012
@@ -698,28 +698,34 @@ u_int get_r15(void);
* CPU functions from locore.S
*/
-void cpu_reset (void) __attribute__((__noreturn__));
+void cpu_reset (void) __dead;
/*
* Cache info variables.
*/
/* PRIMARY CACHE VARIABLES */
-extern int arm_picache_size;
-extern int arm_picache_line_size;
-extern int arm_picache_ways;
-
-extern int arm_pdcache_size; /* and unified */
-extern int arm_pdcache_line_size;
-extern int arm_pdcache_ways;
-extern int arm_cache_prefer_mask;
-
-extern int arm_pcache_type;
-extern int arm_pcache_unified;
-
-extern int arm_dcache_align;
-extern int arm_dcache_align_mask;
+struct arm_cache_info {
+ u_int icache_size;
+ u_int icache_line_size;
+ u_int icache_ways;
+ u_int icache_sets;
+
+ u_int dcache_size;
+ u_int dcache_line_size;
+ u_int dcache_ways;
+ u_int dcache_sets;
+
+ u_int cache_type;
+ bool cache_unified;
+};
+
+extern u_int arm_cache_prefer_mask;
+extern u_int arm_dcache_align;
+extern u_int arm_dcache_align_mask;
+extern struct arm_cache_info arm_pcache;
+extern struct arm_cache_info arm_scache;
#endif /* _KERNEL */
#if defined(_KERNEL) || defined(_KMEMUSER)
Index: src/sys/arch/arm/include/arm32/pmap.h
diff -u src/sys/arch/arm/include/arm32/pmap.h:1.109 src/sys/arch/arm/include/arm32/pmap.h:1.110
--- src/sys/arch/arm/include/arm32/pmap.h:1.109 Thu Sep 6 04:42:39 2012
+++ src/sys/arch/arm/include/arm32/pmap.h Fri Sep 7 11:48:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.109 2012/09/06 04:42:39 matt Exp $ */
+/* $NetBSD: pmap.h,v 1.110 2012/09/07 11:48:59 matt Exp $ */
/*
* Copyright (c) 2002, 2003 Wasabi Systems, Inc.
@@ -413,7 +413,7 @@ extern int pmap_needs_pte_sync;
#define PMAP_NEEDS_PTE_SYNC 1
#endif
#else
-#define PMAP_NEEDS_PTE_SYNC 0
+#define PMAP_NEEDS_PTE_SYNC 1
#endif
#else
#define PMAP_NEEDS_PTE_SYNC 1
Added files:
Index: src/sys/arch/arm/cortex/pl310_var.h
diff -u /dev/null src/sys/arch/arm/cortex/pl310_var.h:1.1
--- /dev/null Fri Sep 7 11:49:00 2012
+++ src/sys/arch/arm/cortex/pl310_var.h Fri Sep 7 11:49:00 2012
@@ -0,0 +1,37 @@
+/* $NetBSD: pl310_var.h,v 1.1 2012/09/07 11:49:00 matt Exp $ */
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ARM_CORTEX_PL310_VAR_H_
+#define _ARM_CORTEX_PL310_VAR_H_
+
+#include <sys/bus.h>
+
+void arml2cc_init(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+#endif /* !_ARM_CORTEX_PL310_VAR_H_ */