Date: Thu, 20 Nov 2014 17:06:41 +0000 (UTC) From: Ruslan Bukin <br@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r274752 - in head/sys/mips: include mips Message-ID: <201411201706.sAKH6fVP032621@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: br Date: Thu Nov 20 17:06:41 2014 New Revision: 274752 URL: https://svnweb.freebsd.org/changeset/base/274752 Log: Add L2-cache writeback/flush operations. Supported 32,128-byte line-size, else ignored. Cavium Networks also ignored as it has non-standard config registers. Obtained from: NetBSD Sponsored by: DARPA, AFRL Modified: head/sys/mips/include/cache_mipsNN.h head/sys/mips/include/cpuinfo.h head/sys/mips/include/cpuregs.h head/sys/mips/mips/cache.c head/sys/mips/mips/cache_mipsNN.c head/sys/mips/mips/cpu.c Modified: head/sys/mips/include/cache_mipsNN.h ============================================================================== --- head/sys/mips/include/cache_mipsNN.h Thu Nov 20 17:03:40 2014 (r274751) +++ head/sys/mips/include/cache_mipsNN.h Thu Nov 20 17:06:41 2014 (r274752) @@ -67,5 +67,15 @@ void mipsNN_pdcache_wbinv_range_index_12 void mipsNN_pdcache_inv_range_128(vm_offset_t, vm_size_t); void mipsNN_pdcache_wb_range_128(vm_offset_t, vm_size_t); #endif +void mipsNN_sdcache_wbinv_all_32(void); +void mipsNN_sdcache_wbinv_range_32(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wbinv_range_index_32(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_inv_range_32(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wb_range_32(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wbinv_all_128(void); +void mipsNN_sdcache_wbinv_range_128(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wbinv_range_index_128(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_inv_range_128(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wb_range_128(vm_paddr_t, vm_size_t); #endif /* _MACHINE_CACHE_MIPSNN_H_ */ Modified: head/sys/mips/include/cpuinfo.h ============================================================================== --- head/sys/mips/include/cpuinfo.h Thu Nov 20 17:03:40 2014 (r274751) +++ head/sys/mips/include/cpuinfo.h Thu Nov 20 17:06:41 2014 (r274752) @@ -67,6 +67,12 @@ struct mips_cpuinfo { u_int8_t dc_nways; u_int16_t dc_nsets; } l1; + struct { + u_int32_t dc_size; + u_int8_t dc_linesize; + u_int8_t dc_nways; + u_int16_t dc_nsets; + } l2; }; extern struct mips_cpuinfo cpuinfo; Modified: head/sys/mips/include/cpuregs.h ============================================================================== --- head/sys/mips/include/cpuregs.h Thu Nov 20 17:03:40 2014 (r274751) +++ head/sys/mips/include/cpuregs.h Thu Nov 20 17:06:41 2014 (r274752) @@ -550,6 +550,13 @@ #define MIPS_CONFIG1_EP 0x00000002 /* EJTAG implemented */ #define MIPS_CONFIG1_FP 0x00000001 /* FPU implemented */ +#define MIPS_CONFIG2_SA_SHIFT 0 /* Secondary cache associativity */ +#define MIPS_CONFIG2_SA_MASK 0xf +#define MIPS_CONFIG2_SL_SHIFT 4 /* Secondary cache line size */ +#define MIPS_CONFIG2_SL_MASK 0xf +#define MIPS_CONFIG2_SS_SHIFT 8 /* Secondary cache sets per way */ +#define MIPS_CONFIG2_SS_MASK 0xf + #define MIPS_CONFIG4_MMUSIZEEXT 0x000000FF /* bits 7.. 0 MMU Size Extension */ #define MIPS_CONFIG4_MMUEXTDEF 0x0000C000 /* bits 15.14 MMU Extension Definition */ #define MIPS_CONFIG4_MMUEXTDEF_MMUSIZEEXT 0x00004000 /* This values denotes CONFIG4 bits */ Modified: head/sys/mips/mips/cache.c ============================================================================== --- head/sys/mips/mips/cache.c Thu Nov 20 17:03:40 2014 (r274751) +++ head/sys/mips/mips/cache.c Thu Nov 20 17:06:41 2014 (r274752) @@ -260,19 +260,42 @@ mips_config_cache(struct mips_cpuinfo * panic("no pdcache_wb_range"); } - /* XXXMIPS: No secondary cache handlers yet */ -#ifdef notyet - if (mips_sdcache_size) { - if (!mips_cache_ops.mco_sdcache_wbinv_all) - panic("no sdcache_wbinv_all"); - if (!mips_cache_ops.mco_sdcache_wbinv_range) - panic("no sdcache_wbinv_range"); - if (!mips_cache_ops.mco_sdcache_wbinv_range_index) - panic("no sdcache_wbinv_range_index"); - if (!mips_cache_ops.mco_sdcache_inv_range) - panic("no sdcache_inv_range"); - if (!mips_cache_ops.mco_sdcache_wb_range) - panic("no sdcache_wb_range"); + /* L2 data cache */ + if (!cpuinfo->l2.dc_size) { + /* No L2 found, ignore */ + return; } + + switch (cpuinfo->l2.dc_linesize) { + case 32: + mips_cache_ops.mco_sdcache_wbinv_all = + mipsNN_sdcache_wbinv_all_32; + mips_cache_ops.mco_sdcache_wbinv_range = + mipsNN_sdcache_wbinv_range_32; + mips_cache_ops.mco_sdcache_wbinv_range_index = + mipsNN_sdcache_wbinv_range_index_32; + mips_cache_ops.mco_sdcache_inv_range = + mipsNN_sdcache_inv_range_32; + mips_cache_ops.mco_sdcache_wb_range = + mipsNN_sdcache_wb_range_32; + break; + case 128: + mips_cache_ops.mco_sdcache_wbinv_all = + mipsNN_sdcache_wbinv_all_128; + mips_cache_ops.mco_sdcache_wbinv_range = + mipsNN_sdcache_wbinv_range_128; + mips_cache_ops.mco_sdcache_wbinv_range_index = + mipsNN_sdcache_wbinv_range_index_128; + mips_cache_ops.mco_sdcache_inv_range = + mipsNN_sdcache_inv_range_128; + mips_cache_ops.mco_sdcache_wb_range = + mipsNN_sdcache_wb_range_128; + break; + default: +#ifdef CACHE_DEBUG + printf(" no sdcache ops for %d byte lines", + cpuinfo->l2.dc_linesize); #endif + break; + } } Modified: head/sys/mips/mips/cache_mipsNN.c ============================================================================== --- head/sys/mips/mips/cache_mipsNN.c Thu Nov 20 17:03:40 2014 (r274751) +++ head/sys/mips/mips/cache_mipsNN.c Thu Nov 20 17:06:41 2014 (r274752) @@ -52,6 +52,9 @@ __FBSDID("$FreeBSD$"); #define round_line32(x) (((x) + 31) & ~31) #define trunc_line32(x) ((x) & ~31) +#define round_line128(x) (((x) + 127) & ~127) +#define trunc_line128(x) ((x) & ~127) + #if defined(CPU_NLM) static __inline void xlp_sync(void) @@ -100,6 +103,10 @@ static int pdcache_size; static int pdcache_stride; static int pdcache_loopcount; static int pdcache_way_mask; +static int sdcache_size; +static int sdcache_stride; +static int sdcache_loopcount; +static int sdcache_way_mask; void mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) @@ -142,6 +149,11 @@ mipsNN_cache_init(struct mips_cpuinfo * pdcache_size = cpuinfo->l1.dc_size; pdcache_way_mask = cpuinfo->l1.dc_nways - 1; + sdcache_stride = cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize; + sdcache_loopcount = cpuinfo->l2.dc_nways; + sdcache_size = cpuinfo->l2.dc_size; + sdcache_way_mask = cpuinfo->l2.dc_nways - 1; + #define CACHE_DEBUG #ifdef CACHE_DEBUG printf("Cache info:\n"); @@ -636,3 +648,195 @@ mipsNN_pdcache_wb_range_128(vm_offset_t } #endif + +void +mipsNN_sdcache_wbinv_all_32(void) +{ + vm_offset_t va = MIPS_PHYS_TO_KSEG0(0); + vm_offset_t eva = va + sdcache_size; + + while (va < eva) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += (32 * 32); + } +} + +void +mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line32(va + size); + + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += 32; + } +} + +void +mipsNN_sdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + /* + * Since we're doing Index ops, we expect to not be able + * to access the address we've been given. So, get the + * bits that determine the cache index, and make a KSEG0 + * address out of them. + */ + va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1)); + + eva = round_line32(va + size); + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += 32; + } +} + +void +mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line32(va + size); + + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += 32; + } +} + +void +mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line32(va + size); + + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += 32; + } +} + +void +mipsNN_sdcache_wbinv_all_128(void) +{ + vm_offset_t va = MIPS_PHYS_TO_KSEG0(0); + vm_offset_t eva = va + sdcache_size; + + while (va < eva) { + cache_r4k_op_32lines_128(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += (32 * 128); + } +} + +void +mipsNN_sdcache_wbinv_range_128(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line128(va + size); + + va = trunc_line128(va); + + while ((eva - va) >= (32 * 128)) { + cache_r4k_op_32lines_128(va, + CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += (32 * 128); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += 128; + } +} + +void +mipsNN_sdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + /* + * Since we're doing Index ops, we expect to not be able + * to access the address we've been given. So, get the + * bits that determine the cache index, and make a KSEG0 + * address out of them. + */ + va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1)); + + eva = round_line128(va + size); + va = trunc_line128(va); + + while ((eva - va) >= (32 * 128)) { + cache_r4k_op_32lines_128(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += (32 * 128); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += 128; + } +} + +void +mipsNN_sdcache_inv_range_128(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line128(va + size); + + va = trunc_line128(va); + + while ((eva - va) >= (32 * 128)) { + cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += (32 * 128); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += 128; + } +} + +void +mipsNN_sdcache_wb_range_128(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line128(va + size); + + va = trunc_line128(va); + + while ((eva - va) >= (32 * 128)) { + cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += (32 * 128); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += 128; + } +} Modified: head/sys/mips/mips/cpu.c ============================================================================== --- head/sys/mips/mips/cpu.c Thu Nov 20 17:03:40 2014 (r274751) +++ head/sys/mips/mips/cpu.c Thu Nov 20 17:06:41 2014 (r274752) @@ -73,6 +73,7 @@ mips_get_identity(struct mips_cpuinfo *c u_int32_t prid; u_int32_t cfg0; u_int32_t cfg1; + u_int32_t cfg2; #if defined(CPU_CNMIPS) u_int32_t cfg4; #endif @@ -186,6 +187,31 @@ mips_get_identity(struct mips_cpuinfo *c * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nways; cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; + +#ifndef CPU_CNMIPS + /* L2 cache */ + if (!(cfg1 & MIPS_CONFIG_CM)) { + /* We don't have valid cfg2 register */ + return; + } + + cfg2 = mips_rd_config2(); + + tmp = (cfg2 >> MIPS_CONFIG2_SL_SHIFT) & MIPS_CONFIG2_SL_MASK; + if (0 < tmp && tmp <= 7) + cpuinfo->l2.dc_linesize = 2 << tmp; + + tmp = (cfg2 >> MIPS_CONFIG2_SS_SHIFT) & MIPS_CONFIG2_SS_MASK; + if (0 <= tmp && tmp <= 7) + cpuinfo->l2.dc_nsets = 64 << tmp; + + tmp = (cfg2 >> MIPS_CONFIG2_SA_SHIFT) & MIPS_CONFIG2_SA_MASK; + if (0 <= tmp && tmp <= 7) + cpuinfo->l2.dc_nways = tmp + 1; + + cpuinfo->l2.dc_size = cpuinfo->l2.dc_linesize + * cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_nways; +#endif } void @@ -355,6 +381,7 @@ static driver_t cpu_driver = { static int cpu_probe(device_t dev) { + return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411201706.sAKH6fVP032621>