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_ */