summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2011-03-16 08:22:29 +0000
committerjmallett <jmallett@FreeBSD.org>2011-03-16 08:22:29 +0000
commit8be04896763b0d272e2265ecb2b955ff5f7a2543 (patch)
tree30d2381fed0de2d844518b2db4abda106688e917
parent8e0b0a22844d3d1383011c024b1eb1a3b2ee51a8 (diff)
downloadFreeBSD-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.h13
-rw-r--r--sys/mips/mips/cpu.c49
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;
}
OpenPOWER on IntegriCloud