svn commit: r274752 - in head/sys/mips: include mips
Ruslan Bukin
br at FreeBSD.org
Thu Nov 20 17:06:43 UTC 2014
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);
}
More information about the svn-src-all
mailing list