Skip to content

Commit

Permalink
[entropy_src/rtl] Modify enable registers
Browse files Browse the repository at this point in the history
This PR makes two broad changes to the entropy_src enable registers:

- The conf.enable field has been split into two registers
  - module_enable.module_enable: for overall activation of the IP in
    any context (BOOT_ROM or otherwise)
  - conf.fips_enable: For activation of strict RNG health testing, using
    stricter CC or FIPS grade health-test thresholds (not recommended
    for BOOT_ROM driven operation).
- For better sequencing control, and error handling capabilities, the
  module_enable has been split out into its own register, with a
  separate write enable control (REGWEN_ME vs. REGWEN).

Note on Software guidelines following this commit:

The appropriate use of these registers depends on whether they are
set in the BOOT_ROM or in later (mutable) C-code:

- The enable fields should only differ when set by the BOOT ROM, which
  uses a preliminary set of health test thresholds.  Here, the
  MODULE_ENABLE should be set _without_ setting the FIPS_ENABLE field.
  This indicates that the stronger "FIPS" thresholds have not been set,
  and the IP is not configured for reliable entropy generation.

- For all later, DIF-driven software stages we assume that the
  "Module" enable and the "FIPS" enable are always set together,
  after the final stricter health test thresholds have been set.

Fixes #9637.

Signed-off-by: Mark Branstad <[email protected]>
Co-authored-by: Martin Lueker-Boden <[email protected]>
  • Loading branch information
2 people authored and msfschaffner committed Jan 26, 2022
1 parent 961710a commit 51fde5a
Show file tree
Hide file tree
Showing 14 changed files with 562 additions and 329 deletions.
50 changes: 46 additions & 4 deletions hw/ip/entropy_src/data/entropy_src.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@

regwidth: "32",
registers: [
{ name: "REGWEN_ME",
desc: "Register write enable for module enable control register",
swaccess: "rw0c",
hwaccess: "none",
fields: [
{
bits: "0",
desc: ''' When true, the !!MODULE_ENABLE register can be modified.
When false, it becomes read-only.
'''
resval: 1
}
]
},
{ name: "REGWEN",
desc: "Register write enable for all control registers",
swaccess: "rw0c",
Expand Down Expand Up @@ -149,6 +163,25 @@
}
]
},
{ name: "MODULE_ENABLE",
desc: "Module enable register",
swaccess: "rw",
hwaccess: "hro",
regwen: "REGWEN_ME",
tags: [// Exclude from writes to these field because they cause side affects.
"excl:CsrAllTests:CsrExclAll"]
fields: [
{ bits: "3:0",
mubi: true,
name: "MODULE_ENABLE",
desc: '''
Setting this field to kMuBi4True will enable the ENTROPY_SRC module. Setting
this field to kMuBi4False will effectively reset the module.
'''
resval: false,
},
]
},
{ name: "CONF",
desc: "Configuration register",
swaccess: "rw",
Expand All @@ -158,10 +191,11 @@
"excl:CsrAllTests:CsrExclAll"]
fields: [
{ bits: "3:0",
name: "ENABLE",
name: "FIPS_ENABLE",
mubi: true,
desc: '''
Setting this field to kMuBi4True will enable the ENTROPY_SRC module.
Setting this field to kMuBi4True will enable FIPS qualified entropy to be
generated.
'''
resval: false,
},
Expand Down Expand Up @@ -1153,9 +1187,9 @@
hwaccess: "hwo",
fields: [
{ bits: "0",
name: "ENABLE_FIELD_ALERT",
name: "FIPS_ENABLE_FIELD_ALERT",
desc: '''
This bit is set when the ENABLE field in the !!CONF register is set to
This bit is set when the FIPS_ENABLE field in the !!CONF register is set to
a value other than 0x5 or 0xA.
Writing a zero resets this status bit.
'''
Expand All @@ -1168,6 +1202,14 @@
Writing a zero resets this status bit.
'''
}
{ bits: "2",
name: "MODULE_ENABLE_FIELD_ALERT",
desc: '''
This bit is set when the MODULE_ENABLE field in the !!MODULE_ENABLE register is set to
a value other than 0x5 or 0xA.
Writing a zero resets this status bit.
'''
}
{ bits: "3",
name: "BOOT_BYPASS_DISABLE_FIELD_ALERT",
desc: '''
Expand Down
8 changes: 6 additions & 2 deletions hw/ip/entropy_src/dv/env/entropy_src_scoreboard.sv
Original file line number Diff line number Diff line change
Expand Up @@ -649,9 +649,9 @@ class entropy_src_scoreboard extends cip_base_scoreboard
void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
// Special handling for registers with broader impacts
case (csr.get_name())
"conf": begin
"module_enable": begin
bit do_disable, do_enable;
uvm_reg_field enable_field = csr.get_field_by_name("enable");
uvm_reg_field enable_field = csr.get_field_by_name("module_enable");
prim_mubi_pkg::mubi4_t enable_mubi = enable_field.get_mirrored_value();
// TODO: integrate this with invalid MuBi checks
do_disable = (enable_mubi == prim_mubi_pkg::MuBi4False);
Expand Down Expand Up @@ -697,8 +697,12 @@ class entropy_src_scoreboard extends cip_base_scoreboard
end
"intr_test": begin
end
"regwen_me": begin
end
"regwen": begin
end
"module_enable": begin
end
"conf": begin
end
"rev": begin
Expand Down
14 changes: 9 additions & 5 deletions hw/ip/entropy_src/dv/env/seq_lib/entropy_src_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ class entropy_src_base_vseq extends cip_base_vseq #(
`uvm_info(`gfn, $sformatf("Found %01d seeds", seeds_found), UVM_HIGH)
end while (seeds_found > 0);

`uvm_info(`gfn, "Disabling DUT", UVM_MEDIUM)
ral.module_enable.module_enable.set(prim_mubi_pkg::MuBi4False);
csr_update(.csr(ral.module_enable));

`uvm_info(`gfn, "Checking diagnostics", UVM_MEDIUM)
check_ht_diagnostics();
`uvm_info(`gfn, "Disabling DUT", UVM_MEDIUM)
ral.conf.enable.set(prim_mubi_pkg::MuBi4False);
csr_update(.csr(ral.conf));
`uvm_info(`gfn, "Clearing Alerts", UVM_MEDIUM)
ral.conf.enable.set(prim_mubi_pkg::MuBi4False);
ral.recov_alert_sts.es_main_sm_alert.set(1'b0);
csr_update(.csr(ral.recov_alert_sts));
super.dut_shutdown();
Expand All @@ -108,13 +108,17 @@ class entropy_src_base_vseq extends cip_base_vseq #(
// Thresholds managed in derived vseq classes

// Enables (should be done last)
ral.conf.enable.set(cfg.enable);
ral.conf.fips_enable.set(cfg.enable);

ral.conf.entropy_data_reg_enable.set(cfg.entropy_data_reg_enable);
ral.conf.boot_bypass_disable.set(cfg.boot_bypass_disable);
ral.conf.rng_bit_enable.set(cfg.rng_bit_enable);
ral.conf.rng_bit_sel.set(cfg.rng_bit_sel);
csr_update(.csr(ral.conf));

ral.module_enable.set(cfg.enable); // TODO: Change config here?
csr_update(.csr(ral.module_enable));

if (do_interrupt) begin
ral.intr_enable.set(en_intr);
csr_update(ral.intr_enable);
Expand Down
10 changes: 5 additions & 5 deletions hw/ip/entropy_src/dv/env/seq_lib/entropy_src_rng_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class entropy_src_rng_vseq extends entropy_src_base_vseq;

task enable_dut();
`uvm_info(`gfn, "CSR Thread: Enabling DUT", UVM_MEDIUM)
ral.conf.enable.set(prim_mubi_pkg::MuBi4True);
csr_update(.csr(ral.conf));
ral.module_enable.set(prim_mubi_pkg::MuBi4True);
csr_update(.csr(ral.module_enable));
endtask

virtual task entropy_src_init();
Expand Down Expand Up @@ -155,7 +155,7 @@ class entropy_src_rng_vseq extends entropy_src_base_vseq;
`uvm_info(`gfn, "Identified main_sm alert", UVM_HIGH)
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(dly_to_access_alert_sts)
cfg.clk_rst_vif.wait_clks(dly_to_access_alert_sts);
csr_wr(.ptr(ral.conf.enable), .value(prim_mubi_pkg::MuBi4False));
csr_wr(.ptr(ral.module_enable.module_enable), .value(prim_mubi_pkg::MuBi4False));
csr_wr(.ptr(ral.recov_alert_sts.es_main_sm_alert), .value(1'b1));
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(do_check_ht_diag)
if (do_check_ht_diag) begin
Expand All @@ -164,9 +164,9 @@ class entropy_src_rng_vseq extends entropy_src_base_vseq;
// read all health check values
`uvm_info(`gfn, "Checking_ht_values", UVM_HIGH)
check_ht_diagnostics();
`uvm_info(`gfn, "ht value check complete", UVM_HIGH)
`uvm_info(`gfn, "HT value check complete", UVM_HIGH)
end
csr_wr(.ptr(ral.conf.enable), .value(prim_mubi_pkg::MuBi4True));
csr_wr(.ptr(ral.module_enable.module_enable), .value(prim_mubi_pkg::MuBi4True));
end
endtask

Expand Down
14 changes: 10 additions & 4 deletions hw/ip/entropy_src/rtl/entropy_src.sv
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,13 @@ module entropy_src
es_fips: '1
};
// once enabled, stub entropy is always available
assign stub_es_valid = |reg2hw.conf.enable.q;

import prim_mubi_pkg::mubi4_t;
import prim_mubi_pkg::mubi4_test_true_strict;

mubi4_t mubi_module_en;
assign mubi_module_en = mubi4_t'(reg2hw.module_enable.q);
assign stub_es_valid = mubi4_test_true_strict(mubi_module_en);

if (Stub) begin : gen_stub_entropy_src

Expand All @@ -197,10 +203,10 @@ module entropy_src
if (!rst_ni) begin
lfsr_en <= '0;
end else begin
lfsr_en <= |reg2hw.conf.enable.q;
lfsr_en <= stub_es_valid;
end
end
assign seed_ld = |reg2hw.conf.enable.q & !lfsr_en;
assign seed_ld = stub_es_valid & !lfsr_en;

prim_lfsr #(
.LfsrDw(StubLfsrWidth),
Expand All @@ -226,7 +232,7 @@ module entropy_src
// need to move this to package so that it can be referenced
stub_hw2reg.debug_status.main_sm_state.d = 8'b01110110;

stub_hw2reg.intr_state.es_entropy_valid.de = |reg2hw.conf.enable.q;
stub_hw2reg.intr_state.es_entropy_valid.de = stub_es_valid;
stub_hw2reg.intr_state.es_entropy_valid.d = 1'b1;

end
Expand Down
32 changes: 25 additions & 7 deletions hw/ip/entropy_src/rtl/entropy_src_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ module entropy_src_core import entropy_src_pkg::*; #(
logic es_enable_pfa;
logic es_enable_early;

logic fips_enable_pfe;
logic fips_enable_pfa;

logic es_enable_rng;
logic rng_bit_en;
logic rng_bit_enable_pfe;
Expand Down Expand Up @@ -449,12 +452,19 @@ module entropy_src_core import entropy_src_pkg::*; #(
// check for illegal enable field states, and set alert if detected

// SEC_CM: CONFIG.MUBI
mubi4_t mubi_conf_en;
assign mubi_conf_en = mubi4_t'(reg2hw.conf.enable.q);
assign es_enable_pfe = mubi4_test_true_strict(mubi_conf_en);
assign es_enable_pfa = mubi4_test_invalid(mubi_conf_en);
assign hw2reg.recov_alert_sts.enable_field_alert.de = es_enable_pfa;
assign hw2reg.recov_alert_sts.enable_field_alert.d = es_enable_pfa;
mubi4_t mubi_module_en;
assign mubi_module_en = mubi4_t'(reg2hw.module_enable.q);
assign es_enable_pfe = mubi4_test_true_strict(mubi_module_en);
assign es_enable_pfa = mubi4_test_invalid(mubi_module_en);
assign hw2reg.recov_alert_sts.module_enable_field_alert.de = es_enable_pfa;
assign hw2reg.recov_alert_sts.module_enable_field_alert.d = es_enable_pfa;

mubi4_t mubi_fips_en;
assign mubi_fips_en = mubi4_t'(reg2hw.conf.fips_enable.q);
assign fips_enable_pfe = mubi4_test_true_strict(mubi_fips_en);
assign fips_enable_pfa = mubi4_test_invalid(mubi_fips_en);
assign hw2reg.recov_alert_sts.fips_enable_field_alert.de = fips_enable_pfa;
assign hw2reg.recov_alert_sts.fips_enable_field_alert.d = fips_enable_pfa;

// SEC_CM: CONFIG.MUBI
mubi4_t mubi_entropy_reg_en;
Expand Down Expand Up @@ -2169,7 +2179,15 @@ module entropy_src_core import entropy_src_pkg::*; #(
assign es_hw_if_req = entropy_src_hw_if_i.es_req;
assign entropy_src_hw_if_o.es_ack = es_hw_if_ack;
assign entropy_src_hw_if_o.es_bits = esfinal_data;
assign entropy_src_hw_if_o.es_fips = esfinal_fips_flag;
// TODO: The following is a placeholder for the final implementation
// for blocking non-FIPS data. Please see PR #9949 & Issue 9853
// for details.
//
// For now data is simply masked if fips_enable is not set
// but this does not prevent previously queued seeds from
// exiting once FIPS_ENABLE is asserted.
assign entropy_src_hw_if_o.es_fips = esfinal_fips_flag
&& fips_enable_pfe; // TODO: Fix fips_enable_pfe

entropy_src_ack_sm u_entropy_src_ack_sm (
.clk_i (clk_i),
Expand Down
Loading

0 comments on commit 51fde5a

Please sign in to comment.