[csrng/sec] create fields to enable functions

Use a field instead of a single bit to enable functions is considered more secure.

Signed-off-by: Mark Branstad <mark.branstad@wdc.com>
diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson
index 5ead4b8..98a13c3 100644
--- a/hw/ip/csrng/data/csrng.hjson
+++ b/hw/ip/csrng/data/csrng.hjson
@@ -86,9 +86,8 @@
   registers: [
     { name: "REGWEN",
       desc: "Register write enable for all control registers",
-      swaccess: "ro", // lock is managed by HW
-      hwaccess: "hwo",
-      hwext: "true",
+      swaccess: "rw0c",
+      hwaccess: "none",
       fields: [
         {
             bits: "0",
@@ -103,16 +102,27 @@
       desc: "Control register",
       swaccess: "rw",
       hwaccess: "hro",
+      regwen: "REGWEN",
+      tags: [// Exclude from writes to these bits since hardware actions will start.
+             "excl:CsrAllTests:CsrExclWrite"]
       fields: [
         {
-            bits: "0",
+            bits: "3:0",
             name: "ENABLE",
             desc: '''
-                  Setting this bit will enable the CSRNG module. The application interface for software
-                  (register based) will be enabled only if the respective efuse input is enabled.
+                  Setting this field to 0xA will enable the CSRNG module.
                   '''
-            tags: [// Exclude from writes to these bits.
-                   "excl:CsrAllTests:CsrExclWrite"]
+          resval: "0x5"
+        },
+        {
+            bits: "7:4",
+            name: "SW_APP_ENABLE",
+            desc: '''
+                  Setting this field to 0xA will enable reading from the GENBITS register.
+                  This application interface for software (register based) will be enabled
+                  only if the efuse_sw_app_enable input is set.
+                  '''
+          resval: "0x5"
         },
       ]
     },
diff --git a/hw/ip/csrng/dv/env/seq_lib/csrng_cmds_vseq.sv b/hw/ip/csrng/dv/env/seq_lib/csrng_cmds_vseq.sv
index 1ab9b0a..5102da9 100644
--- a/hw/ip/csrng/dv/env/seq_lib/csrng_cmds_vseq.sv
+++ b/hw/ip/csrng/dv/env/seq_lib/csrng_cmds_vseq.sv
@@ -15,7 +15,8 @@
 
 
   task body();
-    ral.ctrl.enable.set(1'b1);
+    ral.ctrl.enable.set(4'hA);
+    ral.ctrl.sw_app_enable.set(4'hA);
     csr_update(.csr(ral.ctrl));
 
     // TODO: Create/start entropy_src device sequence still under development. Will remove/modify
diff --git a/hw/ip/csrng/dv/env/seq_lib/csrng_smoke_vseq.sv b/hw/ip/csrng/dv/env/seq_lib/csrng_smoke_vseq.sv
index e7a9f01..b7cad67 100644
--- a/hw/ip/csrng/dv/env/seq_lib/csrng_smoke_vseq.sv
+++ b/hw/ip/csrng/dv/env/seq_lib/csrng_smoke_vseq.sv
@@ -10,7 +10,8 @@
 
   task body();
     // Enable CSRNG
-    ral.ctrl.enable.set(1'b1);
+    ral.ctrl.enable.set(4'hA);
+    ral.ctrl.sw_app_enable.set(4'hA);
     csr_update(.csr(ral.ctrl));
 
     // Wait for CSRNG cmd_rdy
diff --git a/hw/ip/csrng/rtl/csrng_core.sv b/hw/ip/csrng/rtl/csrng_core.sv
index f23ff51..c2ccb63 100644
--- a/hw/ip/csrng/rtl/csrng_core.sv
+++ b/hw/ip/csrng/rtl/csrng_core.sv
@@ -70,6 +70,7 @@
   logic       event_cs_hw_inst_exc;
   logic       event_cs_fatal_err;
   logic       cs_enable;
+  logic       sw_app_enable;
   logic       acmd_avail;
   logic       acmd_sop;
   logic       acmd_mop;
@@ -648,8 +649,8 @@
   };
 
   // master module enable
-  assign cs_enable = reg2hw.ctrl.q;
-  assign hw2reg.regwen.d = !cs_enable; // hw reg lock implementation
+  assign cs_enable = (cs_enb_e'(reg2hw.ctrl.enable.q) == CS_FIELD_ON);
+  assign sw_app_enable = (cs_enb_e'(reg2hw.ctrl.sw_app_enable.q) == CS_FIELD_ON);
 
   //------------------------------------------
   // application interface
@@ -711,7 +712,7 @@
   // genbits
   assign hw2reg.genbits_vld.genbits_vld.d = genbits_stage_vldo_sw;
   assign hw2reg.genbits_vld.genbits_fips.d = genbits_stage_fips_sw;
-  assign hw2reg.genbits.d = efuse_sw_app_enable_i ? genbits_stage_bus_sw : '0;
+  assign hw2reg.genbits.d = (sw_app_enable && efuse_sw_app_enable_i) ? genbits_stage_bus_sw : '0;
   assign genbits_stage_bus_rd_sw = reg2hw.genbits.re;
 
 
diff --git a/hw/ip/csrng/rtl/csrng_pkg.sv b/hw/ip/csrng/rtl/csrng_pkg.sv
index a66a5d2..b133ac5 100644
--- a/hw/ip/csrng/rtl/csrng_pkg.sv
+++ b/hw/ip/csrng/rtl/csrng_pkg.sv
@@ -47,4 +47,10 @@
   parameter int CsKeymgrDivWidth = 384;
   typedef logic [CsKeymgrDivWidth-1:0] cs_keymgr_div_t;
 
+  // Sparse four-value signal type
+  parameter int CS_MODE_WIDTH = 4;
+  typedef enum logic [CS_MODE_WIDTH-1:0] {
+    CS_FIELD_ON = 4'b1010
+  } cs_enb_e;
+
 endpackage : csrng_pkg
diff --git a/hw/ip/csrng/rtl/csrng_reg_pkg.sv b/hw/ip/csrng/rtl/csrng_reg_pkg.sv
index 490ad75..8e7d798 100644
--- a/hw/ip/csrng/rtl/csrng_reg_pkg.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_pkg.sv
@@ -71,7 +71,12 @@
   } csrng_reg2hw_alert_test_reg_t;
 
   typedef struct packed {
-    logic        q;
+    struct packed {
+      logic [3:0]  q;
+    } enable;
+    struct packed {
+      logic [3:0]  q;
+    } sw_app_enable;
   } csrng_reg2hw_ctrl_reg_t;
 
   typedef struct packed {
@@ -123,10 +128,6 @@
   } csrng_hw2reg_intr_state_reg_t;
 
   typedef struct packed {
-    logic        d;
-  } csrng_hw2reg_regwen_reg_t;
-
-  typedef struct packed {
     struct packed {
       logic        d;
       logic        de;
@@ -283,11 +284,11 @@
 
   // Register -> HW type
   typedef struct packed {
-    csrng_reg2hw_intr_state_reg_t intr_state; // [130:127]
-    csrng_reg2hw_intr_enable_reg_t intr_enable; // [126:123]
-    csrng_reg2hw_intr_test_reg_t intr_test; // [122:115]
-    csrng_reg2hw_alert_test_reg_t alert_test; // [114:113]
-    csrng_reg2hw_ctrl_reg_t ctrl; // [112:112]
+    csrng_reg2hw_intr_state_reg_t intr_state; // [137:134]
+    csrng_reg2hw_intr_enable_reg_t intr_enable; // [133:130]
+    csrng_reg2hw_intr_test_reg_t intr_test; // [129:122]
+    csrng_reg2hw_alert_test_reg_t alert_test; // [121:120]
+    csrng_reg2hw_ctrl_reg_t ctrl; // [119:112]
     csrng_reg2hw_cmd_req_reg_t cmd_req; // [111:79]
     csrng_reg2hw_genbits_reg_t genbits; // [78:46]
     csrng_reg2hw_int_state_num_reg_t int_state_num; // [45:41]
@@ -298,8 +299,7 @@
 
   // HW -> register type
   typedef struct packed {
-    csrng_hw2reg_intr_state_reg_t intr_state; // [180:173]
-    csrng_hw2reg_regwen_reg_t regwen; // [172:172]
+    csrng_hw2reg_intr_state_reg_t intr_state; // [179:172]
     csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [171:168]
     csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [167:166]
     csrng_hw2reg_genbits_reg_t genbits; // [165:134]
@@ -336,8 +336,6 @@
   parameter logic [0:0] CSRNG_INTR_TEST_CS_FATAL_ERR_RESVAL = 1'h 0;
   parameter logic [0:0] CSRNG_ALERT_TEST_RESVAL = 1'h 0;
   parameter logic [0:0] CSRNG_ALERT_TEST_FATAL_ALERT_RESVAL = 1'h 0;
-  parameter logic [0:0] CSRNG_REGWEN_RESVAL = 1'h 1;
-  parameter logic [0:0] CSRNG_REGWEN_REGWEN_RESVAL = 1'h 1;
   parameter logic [1:0] CSRNG_GENBITS_VLD_RESVAL = 2'h 0;
   parameter logic [31:0] CSRNG_GENBITS_RESVAL = 32'h 0;
   parameter logic [31:0] CSRNG_INT_STATE_VAL_RESVAL = 32'h 0;
diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv
index 68ca9b2..65a9798 100644
--- a/hw/ip/csrng/rtl/csrng_reg_top.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_top.sv
@@ -129,11 +129,14 @@
   logic intr_test_cs_fatal_err_wd;
   logic alert_test_we;
   logic alert_test_wd;
-  logic regwen_re;
+  logic regwen_we;
   logic regwen_qs;
+  logic regwen_wd;
   logic ctrl_we;
-  logic ctrl_qs;
-  logic ctrl_wd;
+  logic [3:0] ctrl_enable_qs;
+  logic [3:0] ctrl_enable_wd;
+  logic [3:0] ctrl_sw_app_enable_qs;
+  logic [3:0] ctrl_sw_app_enable_wd;
   logic cmd_req_we;
   logic [31:0] cmd_req_wd;
   logic sw_cmd_sts_cmd_rdy_qs;
@@ -477,35 +480,19 @@
   );
 
 
-  // R[regwen]: V(True)
-
-  prim_subreg_ext #(
-    .DW    (1)
-  ) u_regwen (
-    .re     (regwen_re),
-    .we     (1'b0),
-    .wd     ('0),
-    .d      (hw2reg.regwen.d),
-    .qre    (),
-    .qe     (),
-    .q      (),
-    .qs     (regwen_qs)
-  );
-
-
-  // R[ctrl]: V(False)
+  // R[regwen]: V(False)
 
   prim_subreg #(
     .DW      (1),
-    .SWACCESS("RW"),
-    .RESVAL  (1'h0)
-  ) u_ctrl (
+    .SWACCESS("W0C"),
+    .RESVAL  (1'h1)
+  ) u_regwen (
     .clk_i   (clk_i),
     .rst_ni  (rst_ni),
 
     // from register interface
-    .we     (ctrl_we),
-    .wd     (ctrl_wd),
+    .we     (regwen_we),
+    .wd     (regwen_wd),
 
     // from internal hardware
     .de     (1'b0),
@@ -513,10 +500,64 @@
 
     // to internal hardware
     .qe     (),
-    .q      (reg2hw.ctrl.q),
+    .q      (),
 
     // to register interface (read)
-    .qs     (ctrl_qs)
+    .qs     (regwen_qs)
+  );
+
+
+  // R[ctrl]: V(False)
+
+  //   F[enable]: 3:0
+  prim_subreg #(
+    .DW      (4),
+    .SWACCESS("RW"),
+    .RESVAL  (4'h5)
+  ) u_ctrl_enable (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (ctrl_we & regwen_qs),
+    .wd     (ctrl_enable_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.ctrl.enable.q),
+
+    // to register interface (read)
+    .qs     (ctrl_enable_qs)
+  );
+
+
+  //   F[sw_app_enable]: 7:4
+  prim_subreg #(
+    .DW      (4),
+    .SWACCESS("RW"),
+    .RESVAL  (4'h5)
+  ) u_ctrl_sw_app_enable (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (ctrl_we & regwen_qs),
+    .wd     (ctrl_sw_app_enable_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.ctrl.sw_app_enable.q),
+
+    // to register interface (read)
+    .qs     (ctrl_sw_app_enable_qs)
   );
 
 
@@ -1608,10 +1649,14 @@
   assign alert_test_we = addr_hit[3] & reg_we & !reg_error;
 
   assign alert_test_wd = reg_wdata[0];
-  assign regwen_re = addr_hit[4] & reg_re & !reg_error;
+  assign regwen_we = addr_hit[4] & reg_we & !reg_error;
+
+  assign regwen_wd = reg_wdata[0];
   assign ctrl_we = addr_hit[5] & reg_we & !reg_error;
 
-  assign ctrl_wd = reg_wdata[0];
+  assign ctrl_enable_wd = reg_wdata[3:0];
+
+  assign ctrl_sw_app_enable_wd = reg_wdata[7:4];
   assign cmd_req_we = addr_hit[6] & reg_we & !reg_error;
 
   assign cmd_req_wd = reg_wdata[31:0];
@@ -1665,7 +1710,8 @@
       end
 
       addr_hit[5]: begin
-        reg_rdata_next[0] = ctrl_qs;
+        reg_rdata_next[3:0] = ctrl_enable_qs;
+        reg_rdata_next[7:4] = ctrl_sw_app_enable_qs;
       end
 
       addr_hit[6]: begin
diff --git a/sw/device/boot_rom/rom_crt.S b/sw/device/boot_rom/rom_crt.S
index a15986a..4106b4c 100644
--- a/sw/device/boot_rom/rom_crt.S
+++ b/sw/device/boot_rom/rom_crt.S
@@ -87,7 +87,7 @@
   sw   t0, ENTROPY_SRC_CONF_REG_OFFSET(a0)
 
   li   a0, TOP_EARLGREY_CSRNG_BASE_ADDR
-  li   t0, 0x1
+  li   t0, 0xaa
   sw   t0, CSRNG_CTRL_REG_OFFSET(a0)
 
   li   a0, TOP_EARLGREY_EDN0_BASE_ADDR
diff --git a/sw/device/lib/dif/dif_csrng.c b/sw/device/lib/dif/dif_csrng.c
index c8c404c..66f98ca 100644
--- a/sw/device/lib/dif/dif_csrng.c
+++ b/sw/device/lib/dif/dif_csrng.c
@@ -128,7 +128,7 @@
   if (csrng == NULL) {
     return kDifCsrngBadArg;
   }
-  mmio_region_write32(csrng->params.base_addr, CSRNG_CTRL_REG_OFFSET, 1);
+  mmio_region_write32(csrng->params.base_addr, CSRNG_CTRL_REG_OFFSET, 0xaa);
   return kDifCsrngOk;
 }
 
diff --git a/sw/device/lib/dif/dif_csrng_unittest.cc b/sw/device/lib/dif/dif_csrng_unittest.cc
index b01ce43..5097283 100644
--- a/sw/device/lib/dif/dif_csrng_unittest.cc
+++ b/sw/device/lib/dif/dif_csrng_unittest.cc
@@ -42,7 +42,7 @@
 }
 
 TEST_F(ConfigTest, ConfigOk) {
-  EXPECT_WRITE32(CSRNG_CTRL_REG_OFFSET, 1);
+  EXPECT_WRITE32(CSRNG_CTRL_REG_OFFSET, 0xaa);
   EXPECT_EQ(dif_csrng_configure(&csrng_), kDifCsrngOk);
 }
 
diff --git a/sw/device/silicon_creator/mask_rom/mask_rom_start.S b/sw/device/silicon_creator/mask_rom/mask_rom_start.S
index b777bf8..1f1f369 100644
--- a/sw/device/silicon_creator/mask_rom/mask_rom_start.S
+++ b/sw/device/silicon_creator/mask_rom/mask_rom_start.S
@@ -155,7 +155,7 @@
   sw t0, ENTROPY_SRC_CONF_REG_OFFSET(a0)
 
   li a0, TOP_EARLGREY_CSRNG_BASE_ADDR
-  li t0, (1 << CSRNG_CTRL_ENABLE_BIT)
+  li t0, (0xa << CSRNG_CTRL_ENABLE_OFFSET) | (0xa << CSRNG_CTRL_SW_APP_ENABLE_OFFSET)
   sw t0, CSRNG_CTRL_REG_OFFSET(a0)
 
   li a0, TOP_EARLGREY_EDN0_BASE_ADDR
diff --git a/sw/device/tests/dif/dif_aes_smoketest.c b/sw/device/tests/dif/dif_aes_smoketest.c
index 4daf33b..bb2d70c 100644
--- a/sw/device/tests/dif/dif_aes_smoketest.c
+++ b/sw/device/tests/dif/dif_aes_smoketest.c
@@ -74,7 +74,7 @@
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
                       ENTROPY_SRC_CONF_REG_OFFSET, 0x2);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      CSRNG_CTRL_REG_OFFSET, 0x1);
+                      CSRNG_CTRL_REG_OFFSET, 0xaa);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
                       EDN_CTRL_REG_OFFSET, 0x9);
 
diff --git a/sw/device/tests/dif/dif_otbn_smoketest.c b/sw/device/tests/dif/dif_otbn_smoketest.c
index 083c022..e953415 100644
--- a/sw/device/tests/dif/dif_otbn_smoketest.c
+++ b/sw/device/tests/dif/dif_otbn_smoketest.c
@@ -21,7 +21,7 @@
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
                       kEntropySrcConfRegOffset, 0x2);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      kCsrngCtrlRegOffset, 0x1);
+                      kCsrngCtrlRegOffset, 0xaa);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
                       kEdnCtrlRegOffset, 0x9);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
diff --git a/sw/device/tests/otbn/otbn_ecdsa_p256_test.c b/sw/device/tests/otbn/otbn_ecdsa_p256_test.c
index f212adf..b7baf25 100644
--- a/sw/device/tests/otbn/otbn_ecdsa_p256_test.c
+++ b/sw/device/tests/otbn/otbn_ecdsa_p256_test.c
@@ -21,7 +21,7 @@
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
                       kEntropySrcConfRegOffset, 0x2);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      kCsrngCtrlRegOffset, 0x1);
+                      kCsrngCtrlRegOffset, 0xaa);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
                       kEdnCtrlRegOffset, 0x9);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
diff --git a/sw/device/tests/otbn/otbn_randomness_test.c b/sw/device/tests/otbn/otbn_randomness_test.c
index 3b6c66a..1e858a0 100644
--- a/sw/device/tests/otbn/otbn_randomness_test.c
+++ b/sw/device/tests/otbn/otbn_randomness_test.c
@@ -21,7 +21,7 @@
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
                       kEntropySrcConfRegOffset, 0x2);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      kCsrngCtrlRegOffset, 0x1);
+                      kCsrngCtrlRegOffset, 0xaa);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
                       kEdnCtrlRegOffset, 0x9);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
diff --git a/sw/device/tests/otbn/otbn_rsa_test.c b/sw/device/tests/otbn/otbn_rsa_test.c
index cd5ac45..fd124ed 100644
--- a/sw/device/tests/otbn/otbn_rsa_test.c
+++ b/sw/device/tests/otbn/otbn_rsa_test.c
@@ -21,7 +21,7 @@
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
                       kEntropySrcConfRegOffset, 0x2);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      kCsrngCtrlRegOffset, 0x1);
+                      kCsrngCtrlRegOffset, 0xaa);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
                       kEdnCtrlRegOffset, 0x9);
   mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),