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);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to