From 7575851fff83197e67a6882626d17c59f1e29ba4 Mon Sep 17 00:00:00 2001 From: Michael Schaffner Date: Tue, 13 Feb 2024 14:52:59 -0800 Subject: [PATCH] [top/dv] Make volatile RAW unlock test parameteric 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 --- hw/top_earlgrey/dv/chip_sim_cfg.hjson | 11 ++- .../dv/env/seq_lib/chip_sw_base_vseq.sv | 36 +++++++-- .../chip_sw_lc_volatile_raw_unlock_vseq.sv | 75 ++++++++++--------- 3 files changed, 79 insertions(+), 43 deletions(-) diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson index 379e254e6a68ea..c59592377ac821 100644 --- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson +++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson @@ -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 } { @@ -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 } { diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv index e73670285f2253..c441605cf7e6bd 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv @@ -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; @@ -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(); @@ -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 diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_volatile_raw_unlock_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_volatile_raw_unlock_vseq.sv index dec13dd8f1cad8..c671e8de4ac986 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_volatile_raw_unlock_vseq.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_volatile_raw_unlock_vseq.sv @@ -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 @@ -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