Module Name: src Committed By: matt Date: Thu Feb 20 23:24:55 UTC 2014
Modified Files: src/sys/arch/arm/arm: cpufunc.c src/sys/arch/arm/arm32: cpu.c src/sys/arch/arm/include: cpufunc.h Log Message: Keep track of what each cache is (VIVT/VIPT/PIPT). cpu0: 32KB/32B 2-way L1 VIPT Instruction cache cpu0: 32KB/64B 4-way write-back-locking-C L1 PIPT Data cache cpu0: 256KB/64B 8-way write-through L2 PIPT Unified cache To generate a diff of this commit: cvs rdiff -u -r1.138 -r1.139 src/sys/arch/arm/arm/cpufunc.c cvs rdiff -u -r1.99 -r1.100 src/sys/arch/arm/arm32/cpu.c cvs rdiff -u -r1.66 -r1.67 src/sys/arch/arm/include/cpufunc.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.138 src/sys/arch/arm/arm/cpufunc.c:1.139 --- src/sys/arch/arm/arm/cpufunc.c:1.138 Thu Feb 20 17:38:42 2014 +++ src/sys/arch/arm/arm/cpufunc.c Thu Feb 20 23:24:55 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.c,v 1.138 2014/02/20 17:38:42 matt Exp $ */ +/* $NetBSD: cpufunc.c,v 1.139 2014/02/20 23:24:55 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.138 2014/02/20 17:38:42 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.139 2014/02/20 23:24:55 matt Exp $"); #include "opt_compat_netbsd.h" #include "opt_cpuoptions.h" @@ -1509,7 +1509,7 @@ get_cacheinfo_clidr(struct arm_cache_inf u_int nsets; if (clidr & 6) { - csid = get_cachesize_cp15(level << 1); /* select L1 dcache values */ + csid = get_cachesize_cp15(level << 1); /* select 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); @@ -1518,22 +1518,32 @@ get_cacheinfo_clidr(struct arm_cache_inf 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); + arm_dcache_log2_nsets = 31 - __builtin_clz(nsets*2-1); } } info->cache_unified = (clidr == 4); - if (clidr & 1) { - csid = get_cachesize_cp15((level << 1)|CPU_CSSR_InD); /* select L1 icache values */ + if (level > 0) { + info->dcache_type = CACHE_TYPE_PIPT; + info->icache_type = CACHE_TYPE_PIPT; + } + + 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 { + csid = get_cachesize_cp15((level << 1)|CPU_CSSR_InD); /* select 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; + } + if (level == 0 + && info->dcache_size / info->dcache_ways <= PAGE_SIZE + && info->icache_size / info->icache_ways <= PAGE_SIZE) { + arm_cache_prefer_mask = 0; } } #endif /* (ARM_MMU_V6 + ARM_MMU_V7) > 0 */ @@ -1561,9 +1571,20 @@ get_cachetype_cp15(void) if (CPU_CT_FORMAT(ctype) == 4) { u_int clidr = armreg_clidr_read(); - if (CPU_CT4_L1IPOLICY(ctype) != CPU_CT4_L1_PIPT) { + if (CPU_CT4_L1IPOLICY(ctype) == CPU_CT4_L1_PIPT) { + arm_pcache.icache_type = CACHE_TYPE_PIPT; + } else { + arm_pcache.icache_type = CACHE_TYPE_VIPT; arm_cache_prefer_mask = PAGE_SIZE; } +#ifdef CPU_CORTEX + if (CPU_ID_CORTEX_P(cpu_id())) { + arm_pcache.dcache_type = CACHE_TYPE_PIPT; + } else +#endif + { + arm_pcache.dcache_type = CACHE_TYPE_VIPT; + } arm_pcache.cache_type = CPU_CT_CTYPE_WB14; get_cacheinfo_clidr(&arm_pcache, 0, clidr & 7); @@ -1574,6 +1595,9 @@ get_cachetype_cp15(void) if (arm_scache.dcache_line_size < arm_dcache_align) arm_dcache_align = arm_scache.dcache_line_size; } + if (arm_pcache.dcache_type == CACHE_TYPE_PIPT) { + arm_cache_prefer_mask = 0; + } goto out; } #endif /* ARM_MMU_V6 + ARM_MMU_V7 > 0 */ @@ -1600,6 +1624,7 @@ get_cachetype_cp15(void) arm_pcache.icache_ways = multiplier << (CPU_CT_xSIZE_ASSOC(isize) - 1); #if (ARM_MMU_V6 + ARM_MMU_V7) > 0 + arm_pcache.icache_type = CACHE_TYPE_VIPT; if (CPU_CT_xSIZE_P & isize) arm_cache_prefer_mask |= __BIT(9 + CPU_CT_xSIZE_SIZE(isize) @@ -1621,11 +1646,14 @@ get_cachetype_cp15(void) } else { 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) +#if (ARM_MMU_V6) > 0 + arm_pcache.dcache_type = CACHE_TYPE_VIPT; + if ((CPU_CT_xSIZE_P & dsize) + && CPU_ID_ARM11_P(curcpu()->ci_arm_cpuid)) { arm_cache_prefer_mask |= __BIT(9 + CPU_CT_xSIZE_SIZE(dsize) - CPU_CT_xSIZE_ASSOC(dsize)) - PAGE_SIZE; + } #endif } arm_pcache.dcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); @@ -1638,6 +1666,9 @@ get_cachetype_cp15(void) CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); out: + KASSERTMSG(arm_dcache_align <= CACHE_LINE_SIZE, + "arm_dcache_align=%u CACHE_LINE_SIZE=%u", + arm_dcache_align, CACHE_LINE_SIZE); arm_dcache_align_mask = arm_dcache_align - 1; } #endif /* ARM7TDMI || ARM8 || ARM9 || XSCALE */ Index: src/sys/arch/arm/arm32/cpu.c diff -u src/sys/arch/arm/arm32/cpu.c:1.99 src/sys/arch/arm/arm32/cpu.c:1.100 --- src/sys/arch/arm/arm32/cpu.c:1.99 Sat Sep 7 23:10:02 2013 +++ src/sys/arch/arm/arm32/cpu.c Thu Feb 20 23:24:55 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.99 2013/09/07 23:10:02 matt Exp $ */ +/* $NetBSD: cpu.c,v 1.100 2014/02/20 23:24:55 matt Exp $ */ /* * Copyright (c) 1995 Mark Brinicombe. @@ -46,7 +46,7 @@ #include <sys/param.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.99 2013/09/07 23:10:02 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.100 2014/02/20 23:24:55 matt Exp $"); #include <sys/systm.h> #include <sys/conf.h> @@ -565,18 +565,24 @@ 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", + aprint_normal_dev(dv, "%dKB/%dB %d-way %s L%u %cI%cT Unified cache\n", info->dcache_size / 1024, info->dcache_line_size, info->dcache_ways, - wtnames[info->cache_type], level + 1); + wtnames[info->cache_type], level + 1, + info->dcache_type & CACHE_TYPE_PIxx ? 'P' : 'V', + info->dcache_type & CACHE_TYPE_xxPT ? 'P' : 'V'); } else { - aprint_normal_dev(dv, "%dKB/%dB %d-way L%u Instruction cache\n", + aprint_normal_dev(dv, "%dKB/%dB %d-way L%u %cI%cT 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->icache_line_size, info->icache_ways, level + 1, + info->icache_type & CACHE_TYPE_PIxx ? 'P' : 'V', + info->icache_type & CACHE_TYPE_xxPT ? 'P' : 'V'); + aprint_normal_dev(dv, "%dKB/%dB %d-way %s L%u %cI%cT Data cache\n", info->dcache_size / 1024, info->dcache_line_size, info->dcache_ways, - wtnames[info->cache_type], level + 1); + wtnames[info->cache_type], level + 1, + info->dcache_type & CACHE_TYPE_PIxx ? 'P' : 'V', + info->dcache_type & CACHE_TYPE_xxPT ? 'P' : 'V'); } } Index: src/sys/arch/arm/include/cpufunc.h diff -u src/sys/arch/arm/include/cpufunc.h:1.66 src/sys/arch/arm/include/cpufunc.h:1.67 --- src/sys/arch/arm/include/cpufunc.h:1.66 Thu Feb 20 17:19:55 2014 +++ src/sys/arch/arm/include/cpufunc.h Thu Feb 20 23:24:54 2014 @@ -744,6 +744,11 @@ void cpu_reset (void) __dead; /* * Cache info variables. */ +#define CACHE_TYPE_VIVT 0 +#define CACHE_TYPE_xxPT 1 +#define CACHE_TYPE_VIPT 1 +#define CACHE_TYPE_PIxx 2 +#define CACHE_TYPE_PIPT 3 /* PRIMARY CACHE VARIABLES */ struct arm_cache_info { @@ -759,6 +764,8 @@ struct arm_cache_info { u_int cache_type; bool cache_unified; + uint8_t icache_type; + uint8_t dcache_type; }; extern u_int arm_cache_prefer_mask;