diff options
author | jmallett <jmallett@FreeBSD.org> | 2011-03-16 08:22:29 +0000 |
---|---|---|
committer | jmallett <jmallett@FreeBSD.org> | 2011-03-16 08:22:29 +0000 |
commit | 8be04896763b0d272e2265ecb2b955ff5f7a2543 (patch) | |
tree | 30d2381fed0de2d844518b2db4abda106688e917 | |
parent | 8e0b0a22844d3d1383011c024b1eb1a3b2ee51a8 (diff) | |
download | FreeBSD-src-8be04896763b0d272e2265ecb2b955ff5f7a2543.zip FreeBSD-src-8be04896763b0d272e2265ecb2b955ff5f7a2543.tar.gz |
o) Properly size caches and TLB on Octeon.
o) Make COP0_SYNC do nothing on Octeon, which is fully interlocked.
Submitted by: Bhanu Prakash (with modifications)
-rw-r--r-- | sys/mips/include/cpuregs.h | 13 | ||||
-rw-r--r-- | sys/mips/mips/cpu.c | 49 |
2 files changed, 50 insertions, 12 deletions
diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h index 456c545..01d710d 100644 --- a/sys/mips/include/cpuregs.h +++ b/sys/mips/include/cpuregs.h @@ -198,12 +198,10 @@ #endif /* CPU dependent mtc0 hazard hook */ -#ifdef CPU_CNMIPS -#define COP0_SYNC nop; nop; nop; nop; nop; +#if defined(CPU_CNMIPS) || defined(CPU_RMI) +#define COP0_SYNC #elif defined(CPU_SB1) #define COP0_SYNC ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop -#elif defined(CPU_RMI) -#define COP0_SYNC #else /* * Pick a reasonable default based on the "typical" spacing described in the @@ -571,6 +569,7 @@ * 16/1 MIPS_COP_0_CONFIG1 ..33 Configuration register 1. * 16/2 MIPS_COP_0_CONFIG2 ..33 Configuration register 2. * 16/3 MIPS_COP_0_CONFIG3 ..33 Configuration register 3. + * 16/4 MIPS_COP_0_CONFIG4 ..33 Configuration register 4. * 17 MIPS_COP_0_LLADDR .336 Load Linked Address. * 18 MIPS_COP_0_WATCH_LO .336 WatchLo register. * 19 MIPS_COP_0_WATCH_HI .333 WatchHi register. @@ -656,7 +655,7 @@ #define MIPS_CONFIG1_TLBSZ_MASK 0x7E000000 /* bits 30..25 # tlb entries minus one */ #define MIPS_CONFIG1_TLBSZ_SHIFT 25 -#define MIPS_MAX_TLB_ENTRIES 64 +#define MIPS_MAX_TLB_ENTRIES 128 #define MIPS_CONFIG1_IS_MASK 0x01C00000 /* bits 24..22 icache sets per way */ #define MIPS_CONFIG1_IS_SHIFT 22 @@ -679,6 +678,10 @@ #define MIPS_CONFIG1_EP 0x00000002 /* EJTAG implemented */ #define MIPS_CONFIG1_FP 0x00000001 /* FPU implemented */ +#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 */ + /* * Values for the code field in a break instruction. */ diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index 68615b9..cfb5ddb 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -52,6 +52,11 @@ __FBSDID("$FreeBSD$"); #include <machine/tlb.h> #include <machine/hwfunc.h> +#if defined(CPU_CNMIPS) +#include <contrib/octeon-sdk/cvmx.h> +#include <contrib/octeon-sdk/octeon-model.h> +#endif + static void cpu_identify(void); struct mips_cpuinfo cpuinfo; @@ -70,6 +75,9 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) u_int32_t prid; u_int32_t cfg0; u_int32_t cfg1; +#if defined(CPU_CNMIPS) + u_int32_t cfg4; +#endif u_int32_t tmp; memset(cpuinfo, 0, sizeof(struct mips_cpuinfo)); @@ -96,6 +104,13 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) cpuinfo->tlb_nentries = ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1; + /* Add extended TLB size information from config4. */ +#if defined(CPU_CNMIPS) + cfg4 = mips_rd_config4(); + if ((cfg4 & MIPS_CONFIG4_MMUEXTDEF) == MIPS_CONFIG4_MMUEXTDEF_MMUSIZEEXT) + cpuinfo->tlb_nentries += (cfg4 & MIPS_CONFIG4_MMUSIZEEXT) * 0x40; +#endif + /* L1 instruction cache. */ tmp = (cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT; if (tmp != 0) { @@ -103,10 +118,9 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) cpuinfo->l1.ic_nways = (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONFIG1_IA_SHIFT)) + 1; cpuinfo->l1.ic_nsets = 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + 6); - cpuinfo->l1.ic_size = - cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nways; } +#ifndef CPU_CNMIPS /* L1 data cache. */ tmp = (cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT; if (tmp != 0) { @@ -116,15 +130,36 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) cpuinfo->l1.dc_nsets = 1 << (((cfg1 & MIPS_CONFIG1_DS_MASK) >> MIPS_CONFIG1_DS_SHIFT) + 6); } -#ifdef CPU_CNMIPS +#else /* - * Octeon does 128 byte line-size. But Config-Sel1 doesn't show - * 128 line-size, 1 Set, 64 ways. + * Some Octeon cache configuration parameters are by model family, not + * config1. */ + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) { + /* Octeon and Octeon XL. */ + cpuinfo->l1.dc_nsets = 1; + cpuinfo->l1.dc_nways = 64; + } else if (OCTEON_IS_MODEL(OCTEON_CN5XXX)) { + /* Octeon Plus. */ + cpuinfo->l1.dc_nsets = 2; + cpuinfo->l1.dc_nways = 64; + } else if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { + /* Octeon II. */ + cpuinfo->l1.dc_nsets = 8; + cpuinfo->l1.dc_nways = 32; + + cpuinfo->l1.ic_nsets = 8; + cpuinfo->l1.ic_nways = 37; + } else { + panic("%s: unsupported Cavium Networks CPU.", __func__); + } + + /* All Octeon models use 128 byte line size. */ cpuinfo->l1.dc_linesize = 128; - cpuinfo->l1.dc_nsets = 1; - cpuinfo->l1.dc_nways = 64; #endif + + cpuinfo->l1.ic_size = cpuinfo->l1.ic_linesize + * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nways; cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; } |