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 14, 2024
1 parent 4c59f99 commit 9c78061
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 48 deletions.
11 changes: 10 additions & 1 deletion hw/top_earlgrey/data/ip/chip_lc_ctrl_testplan.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,21 @@
- Pre-load OTP image with RAW lc_state.
- Initiate the LC transition to test_unlocked0 state using the
VOLATILE_RAW_UNLOCK mode of operation.

If this top-level is expected to support VOLATILE_RAW_UNLOCK:

- As part of the transition to test_unlocked0, switch the TAP interface to rv_dm.
- Enable ROM execution via rv_dm, and perform POR.
- Initiate a second transition to test_unlocked0 using VOLATILE_RAW_UNLOCK.
- Verify that the CPU is able to execute.
- Test ext_clk injection before enabling ROM execution.

If this top-level is NOT expected to support VOLATILE_RAW_UNLOCK:

Test ext_clk injection before enabling ROM execution.
- Check that the VOLATILE_RAW_UNLOCK bit in the transition control register stays 0
when it is programmed to 1.
- Check that the transition results in a token error (the real RAW unlock transition
expects the unhashed token instead of the hashed token supplied for volatile RAW unlock).
'''
features: [
"LC_CTRL.STATE.RAW",
Expand Down
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
36 changes: 29 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 = 1);
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,16 @@ 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);
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
// The hashed token should be invalid if volatile unlock is not supported, since the
// regular transition expects that the unhashed token is provided.
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 All @@ -33,49 +37,63 @@ class chip_sw_lc_volatile_raw_unlock_vseq extends chip_sw_base_vseq;

super.body();

// Since super.body only does backdoor operatoin,
// Since super.body only does backdoor operation,
// add wait for clock task before the test uses jtag polling task.
wait_rom_check_done();
wait_lc_ready(1);

// 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);
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)
// If we're expecting the feature to be enabled, the device should boot.
if (exp_volatile_raw_unlock_en) begin
// 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(.target_strap(JtagTapRvDm), .expect_success(1));
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)
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 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)
// We expect this to fail in this case.
jtag_lc_state_volatile_raw_unlock(.target_strap(JtagTapLc), .expect_success(0));
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

task post_start();
// In case the volatile RAW unlock feature is not supported by HW, the transition is not going
// to succeed and SW will never be able to run.
if (!exp_volatile_raw_unlock_en) begin
override_test_status_and_finish(.passed(1));
end
super.post_start();
endtask : post_start
endclass

0 comments on commit 9c78061

Please sign in to comment.