Skip to content

Commit

Permalink
[top/dv] Make volatile RAW unlock test parameteric
Browse files Browse the repository at this point in the history
Besides being able to test the volatile RAW unlock mechanism,
we should also be able to test whether the case where that
mechanism has been disabled in HW.

This patch adds a plusarg that allows to parameterize the test with our
expectation.

In production silicon this mechanism should be disabled, for example.

Signed-off-by: Michael Schaffner <[email protected]>
  • Loading branch information
msfschaffner committed Feb 13, 2024
1 parent 82e79b8 commit 5761280
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 43 deletions.
11 changes: 9 additions & 2 deletions hw/top_earlgrey/dv/chip_sim_cfg.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,11 @@
uvm_test_seq: chip_sw_lc_volatile_raw_unlock_vseq
sw_images: ["//sw/device/tests/sim_dv:lc_ctrl_volatile_raw_unlock_test:1:new_rules"]
en_run_modes: ["sw_test_mode_test_rom"]
run_opts: ["+use_otp_image=OtpTypeLcStRaw"]
run_opts: [
"+use_otp_image=OtpTypeLcStRaw",
# We set this to zero if the volatile RAW unlock mechanism is expected
# to be disabled (this should be the case in production silicon).
"+exp_volatile_raw_unlock_en=0"]
run_timeout_mins: 120
}
{
Expand All @@ -935,7 +939,10 @@
en_run_modes: ["sw_test_mode_test_rom"]
run_opts: [
"+use_otp_image=OtpTypeLcStRaw",
"+chip_clock_source=ChipClockSourceExternal48Mhz"]
"+chip_clock_source=ChipClockSourceExternal48Mhz",
# We set this to zero if the volatile RAW unlock mechanism is expected
# to be disabled (this should be the case in production silicon).
"+exp_volatile_raw_unlock_en=0"]
run_timeout_mins: 120
}
{
Expand Down
35 changes: 28 additions & 7 deletions hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -801,9 +801,18 @@ class chip_sw_base_vseq extends chip_base_vseq;
cfg.m_jtag_riscv_agent_cfg.allow_errors = 0;
endtask

virtual task wait_lc_token_error(bit allow_err = 1, int max_attempt = 5000);
cfg.m_jtag_riscv_agent_cfg.allow_errors = allow_err;
wait_lc_status(LcTokenError, max_attempt);
cfg.m_jtag_riscv_agent_cfg.allow_errors = 0;
endtask

// Use JTAG interface to transit LC_CTRL from RAW to TEST_UNLOCKED* states
// using the VOLATILE_RAW_UNLOCK mode of operation.
virtual task jtag_lc_state_volatile_raw_unlock(chip_jtag_tap_e target_strap);
// If this operation is expected to fail due to the absence of the mechanism in HW, set the
// expect_success argument to 0.
virtual task jtag_lc_state_volatile_raw_unlock(chip_jtag_tap_e target_strap,
bit expect_success = 0);
bit [TL_DW-1:0] current_lc_state;
bit [TL_DW-1:0] transition_ctrl;
bit use_ext_clk = 1'b0;
Expand Down Expand Up @@ -840,8 +849,15 @@ class chip_sw_base_vseq extends chip_base_vseq;
ral.lc_ctrl.transition_ctrl.get_offset(),
p_sequencer.jtag_sequencer_h,
transition_ctrl);
`DV_CHECK_FATAL(transition_ctrl & (1 << 1), {"VOLATILE_RAW_UNLOCK is not supported by this ",
"top level. Check the SecVolatileRawUnlockEn parameter configuration."})
// In this case we expect the transition_ctrl bit to stay 0.
if (expect_success) begin
`DV_CHECK_FATAL(transition_ctrl & (1 << 1), {"VOLATILE_RAW_UNLOCK is not supported by this ",
"top level. Check the SecVolatileRawUnlockEn parameter configuration."})
end else begin
`DV_CHECK_FATAL(!(transition_ctrl & (1 << 1)), {"VOLATILE_RAW_UNLOCK is not expected to be ",
"supported by this top-level. Check the SecVolatileRawUnlockEn parameter "
"configuration"})
end

if (use_ext_clk) begin
wait_lc_ext_clk_switched();
Expand Down Expand Up @@ -869,10 +885,15 @@ class chip_sw_base_vseq extends chip_base_vseq;
1);

if (target_strap == JtagTapLc) begin
wait_lc_transition_successful(.max_attempt(max_attempt));
jtag_riscv_agent_pkg::jtag_write_csr(ral.lc_ctrl.claim_transition_if.get_offset(),
p_sequencer.jtag_sequencer_h,
prim_mubi_pkg::MuBi8False);
// The token should be invalid for this transition.
if (expect_success) begin
wait_lc_transition_successful(.max_attempt(max_attempt));
jtag_riscv_agent_pkg::jtag_write_csr(ral.lc_ctrl.claim_transition_if.get_offset(),
p_sequencer.jtag_sequencer_h,
prim_mubi_pkg::MuBi8False);
end else begin
wait_lc_token_error(.max_attempt(max_attempt));
end
end else begin
cfg.clk_rst_vif.wait_clks($urandom_range(10000, 20000));
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ class chip_sw_lc_volatile_raw_unlock_vseq extends chip_sw_base_vseq;
// image.
bit rom_prod_mode = 1'b0;

// Indicates whether we expect the volatile RAW unlock feature to be enabled in HW or not.
bit exp_volatile_raw_unlock_en = 1'b0;

virtual task pre_start();
void'($value$plusargs("rom_prod_mode=%0d", rom_prod_mode));
void'($value$plusargs("exp_volatile_raw_unlock_en=%0d", exp_volatile_raw_unlock_en));
cfg.chip_vif.tap_straps_if.drive(JtagTapLc);
super.pre_start();
endtask
Expand Down Expand Up @@ -40,42 +44,45 @@ class chip_sw_lc_volatile_raw_unlock_vseq extends chip_sw_base_vseq;

// VOLATILE_RAW_UNLOCK does not require a reset after completion.
// Applying a reset will move the device back to RAW state in this case.
jtag_lc_state_volatile_raw_unlock(JtagTapRvDm);
jtag_lc_state_volatile_raw_unlock(.target_strap(JtagTapRvDm),
.expect_success(exp_volatile_raw_unlock_en));
reset_jtag_tap();

if (rom_prod_mode) begin
// The production ROM is not instrumented to report `sw_test_status`, so
// we wait for the PC to advance before continuing with the test. The
// PC was taken from the ROM disassembly.
`DV_WAIT(cfg.chip_vif.probed_cpu_pc.pc_wb >= 8194)
end else begin
// In RAW state the ROM should halt as RomExecEn is not set yet.
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInBootRomHalt)
// If we're expecting the feature to be enabled, the device should boot.
if (exp_volatile_raw_unlock_en) begin
if (rom_prod_mode) begin
// The production ROM is not instrumented to report `sw_test_status`, so
// we wait for the PC to advance before continuing with the test. The
// PC was taken from the ROM disassembly.
`DV_WAIT(cfg.chip_vif.probed_cpu_pc.pc_wb >= 8194)
end else begin
// In RAW state the ROM should halt as RomExecEn is not set yet.
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInBootRomHalt)
end

// Use the frontend interface to configure the RomExecEn OTP value. A
// reset is required to have otp_ctrl sample the new OTP value.
`uvm_info(`gfn, "Configuring RomExecEng", UVM_LOW)
jtag_dm_activation_seq.start(p_sequencer.jtag_sequencer_h);
`uvm_info(`gfn, $sformatf("rv_dm_activated: %0d", cfg.m_jtag_riscv_agent_cfg.rv_dm_activated),
UVM_LOW)
cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 1;
jtag_otp_program32(otp_ctrl_reg_pkg::CreatorSwCfgRomExecEnOffset, 1);

cfg.chip_vif.tap_straps_if.drive(JtagTapLc);
cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 0;
apply_reset();
reset_jtag_tap();

// Wait for `rom_ctrl` to complete the ROM check. This will give the dut
// enough time to configure the TAP interface before any JTAG agents send
// any commands.
wait_rom_check_done();

// Second VOLATILE_RAW_UNLOCK does not change the TAP interface to rv_dm
// so that we can check the completion status through that interface.
// After this, the rest of the test should proceed.
jtag_lc_state_volatile_raw_unlock(JtagTapLc);
end

// Use the frontend interface to configure the RomExecEn OTP value. A
// reset is required to have otp_ctrl sample the new OTP value.
`uvm_info(`gfn, "Configuring RomExecEng", UVM_LOW)
jtag_dm_activation_seq.start(p_sequencer.jtag_sequencer_h);
`uvm_info(`gfn, $sformatf("rv_dm_activated: %0d", cfg.m_jtag_riscv_agent_cfg.rv_dm_activated),
UVM_LOW)
cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 1;
jtag_otp_program32(otp_ctrl_reg_pkg::CreatorSwCfgRomExecEnOffset, 1);

cfg.chip_vif.tap_straps_if.drive(JtagTapLc);
cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 0;
apply_reset();
reset_jtag_tap();

// Wait for `rom_ctrl` to complete the ROM check. This will give the dut
// enough time to configure the TAP interface before any JTAG agents send
// any commands.
wait_rom_check_done();

// Second VOLATILE_RAW_UNLOCK does not change the TAP interface to rv_dm
// so that we can check the completion status through that interface.
// After this, the rest of the test should proceed.
jtag_lc_state_volatile_raw_unlock(JtagTapLc);

endtask
endclass

0 comments on commit 5761280

Please sign in to comment.