correct bank and size, use in setting up CSR tables
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 5 Nov 2018 08:51:49 +0000 (08:51 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 5 Nov 2018 08:51:49 +0000 (08:51 +0000)
riscv/processor.cc
riscv/processor.h
riscv/sv.h

index ec8326fa1494445031dd096c762fd60d16a7f379..44cedc6e671fdf1a93de1c7c673e15f15057985a 100644 (file)
@@ -138,6 +138,12 @@ void state_t::reset(reg_t max_isa)
   tselect = 0;
   for (unsigned int i = 0; i < num_triggers; i++)
     mcontrol[i].type = 2;
+#ifdef SPIKE_SIMPLEV
+  // set SV CSR banks to default (full) sizes
+  msv.state_size = 1;
+  ssv.state_size = 1;
+  usv.state_size = 3;
+#endif
 }
 
 void sv_shape_t::setup_map()
@@ -397,6 +403,15 @@ int processor_t::paddr_bits()
   return max_xlen == 64 ? 50 : 34;
 }
 
+void state_t::get_csr_start_end(int &start, int &end)
+{
+    start = sv().state_bank * 4;
+    end = start + (1 << (sv().state_size+1));
+    start = std::min(sv_csr_sz(), start);
+    end = std::min(sv_csr_sz(), end);
+    fprintf(stderr, "sv state csr start/end: %d %d\n", start, end);
+}
+
 void state_t::sv_csr_reg_unpack()
 {
     // okaaay and now "unpack" the CAM to make it easier to use.  this
@@ -405,7 +420,10 @@ void state_t::sv_csr_reg_unpack()
     memset(sv().sv_int_tb, 0, sizeof(sv().sv_int_tb));
     memset(sv().sv_fp_tb, 0, sizeof(sv().sv_fp_tb));
     // now walk the CAM and unpack it
-    for (int i = 0; i < sv_csr_sz(); i++)
+    int start = 0;
+    int end = 0;
+    get_csr_start_end(start, end);
+    for (int i = start; i < end; i++)
     {
         union sv_reg_csr_entry *c = &sv().sv_csrs[i];
         uint64_t idx = c->b.regkey;
@@ -436,7 +454,10 @@ void state_t::sv_csr_pred_unpack()
 {
     memset(sv().sv_pred_int_tb, 0, sizeof(sv().sv_pred_int_tb));
     memset(sv().sv_pred_fp_tb, 0, sizeof(sv().sv_pred_fp_tb));
-    for (int i = 0; i < sv_csr_sz(); i++)
+    int start = 0;
+    int end = 0;
+    get_csr_start_end(start, end);
+    for (int i = start; i < end; i++)
     {
         union sv_pred_csr_entry *c = &sv().sv_pred_csrs[i];
         uint64_t idx = c->b.regkey;
@@ -488,8 +509,18 @@ void processor_t::set_csr(int which, reg_t val)
       reg_t destoffs = get_field(val, SV_STATE_DESTOFFS);
       state.sv().srcoffs  = std::min(srcoffs , state.sv().vl-1);
       state.sv().destoffs = std::min(destoffs, state.sv().vl-1);
+      int old_bank = state.sv().state_bank;
+      int old_size = state.sv().state_size;
       state.sv().state_bank = get_field(val, SV_STATE_BANK);
       state.sv().state_size = get_field(val, SV_STATE_SIZE);
+      if (old_bank != state.sv().state_bank ||
+          old_size != state.sv().state_size)
+      {
+        // if the bank or size is changed, the csrs that are enabled
+        // also changes.  easiest thing in software: recalculate them all
+        state.sv_csr_pred_unpack();
+        state.sv_csr_reg_unpack();
+      }
       break;
     }
     case CSR_USVVL:
index 1be234dc293afc8d1cd58fa3514627104792f47a..8b7163ccf3c20c2bef49fb2b84fa85c64a0f2e0b 100644 (file)
@@ -168,8 +168,7 @@ struct state_t
   sv_shape_t *get_shape(reg_t reg);
   void sv_csr_reg_unpack();
   void sv_csr_pred_unpack();
-
-
+  void get_csr_start_end(int &start, int &end);
 #endif
 
   uint32_t fflags;
index b82eeecc03303b1b7dd07c7d936e4273bcfcbcaf..00f274c248ef37aa0113de7fa8c9a856d992db37 100644 (file)
@@ -108,7 +108,7 @@ typedef struct {
 #define SV_STATE_MVL (0x1f<<6)
 #define SV_STATE_SRCOFFS (0x1f<<12)
 #define SV_STATE_DESTOFFS (0x1f<<18)
-#define SV_STATE_BANK (0x1f<<24)
-#define SV_STATE_SIZE (0x1f<<26)
+#define SV_STATE_BANK (0x7<<24)
+#define SV_STATE_SIZE (0x3<<27)
 
 #endif