[sw,tests] SRAM execution test DV integration
Checks whether code can be executed from the SRAM depending on the values
of LC_STATE, OTP HW_CFG[IFETCH] and SRAM_CTRL EXEC CSR.
Signed-off-by: Dave Williams <dave.williams@ensilica.com>
diff --git a/hw/dv/sv/mem_bkdr_util/mem_bkdr_util__otp.sv b/hw/dv/sv/mem_bkdr_util/mem_bkdr_util__otp.sv
index 1ac0c98..d26b8b6 100644
--- a/hw/dv/sv/mem_bkdr_util/mem_bkdr_util__otp.sv
+++ b/hw/dv/sv/mem_bkdr_util/mem_bkdr_util__otp.sv
@@ -6,13 +6,13 @@
// This file is included in `mem_bkdr_util.sv` as a continuation of `mem_bkdr_util` class.
virtual function void otp_write_lc_partition_state(lc_ctrl_state_pkg::lc_state_e lc_state);
- for (int i = 0; i < LcStateSize; i+=4) begin
+ for (int i = 0; i < LcStateSize; i += 4) begin
write32(i + LcStateOffset, lc_state[i*8+:32]);
end
endfunction
virtual function void otp_write_lc_partition_cnt(lc_ctrl_state_pkg::lc_cnt_e lc_cnt);
- for (int i = 0; i < LcTransitionCntSize; i+=4) begin
+ for (int i = 0; i < LcTransitionCntSize; i += 4) begin
write32(i + LcTransitionCntOffset, lc_cnt[i*8+:32]);
end
endfunction : otp_write_lc_partition_cnt
@@ -22,32 +22,59 @@
otp_write_lc_partition_cnt(lc_cnt);
otp_write_lc_partition_state(lc_state);
-endfunction: otp_write_lc_partition
+endfunction : otp_write_lc_partition
// The following steps are needed to backdoor write a secret partition:
// 1). Scramble the RAW input data.
// 2). Backdoor write the scrambled input data to OTP memory.
// 3). Calculate the correct digest for the secret partition.
// 4). Backdoor write digest data to OTP memory.
-virtual function void otp_write_secret0_partition(bit [TestUnlockTokenSize*8-1:0] unlock_token,
- bit [TestExitTokenSize*8-1:0] exit_token);
+virtual function void otp_write_secret0_partition(
+ bit [TestUnlockTokenSize*8-1:0] unlock_token,
+ bit [TestExitTokenSize*8-1:0] exit_token);
bit [Secret0DigestSize*8-1:0] digest;
bit [TestUnlockTokenSize*8-1:0] scrambled_unlock_token;
bit [TestExitTokenSize*8-1:0] scrambled_exit_token;
bit [bus_params_pkg::BUS_DW-1:0] secret_data[$];
- for (int i = 0; i < TestUnlockTokenSize; i+=8) begin
+ for (int i = 0; i < TestUnlockTokenSize; i += 8) begin
scrambled_unlock_token[i*8+:64] = scramble_data(unlock_token[i*8+:64], Secret0Idx);
write64(i + TestUnlockTokenOffset, scrambled_unlock_token[i*8+:64]);
end
- for (int i = 0; i < TestExitTokenSize; i+=8) begin
+ for (int i = 0; i < TestExitTokenSize; i += 8) begin
scrambled_exit_token[i*8+:64] = scramble_data(exit_token[i*8+:64], Secret0Idx);
write64(i + TestExitTokenOffset, scrambled_exit_token[i*8+:64]);
end
- secret_data = {<<32 {scrambled_exit_token, scrambled_unlock_token}};
+ secret_data = {<<32{scrambled_exit_token, scrambled_unlock_token}};
digest = cal_digest(Secret0Idx, secret_data);
write64(Secret0DigestOffset, digest);
endfunction
+
+virtual function void otp_write_hw_cfg_partition(
+ bit [DeviceIdSize*8-1:0] device_id, bit [ManufStateSize*8-1:0] manuf_state,
+ bit [EnSramIfetchSize*8-1:0] en_sram_ifetch,
+ bit [EnCsrngSwAppReadSize*8-1:0] en_csrng_sw_app_read,
+ bit [EnEntropySrcFwReadSize*8-1:0] en_entropy_src_fw_read,
+ bit [EnEntropySrcFwOverSize*8-1:0] en_entropy_src_fw_over);
+ bit [HwCfgDigestSize*8-1:0] digest;
+
+ bit [bus_params_pkg::BUS_DW-1:0] hw_cfg_data[$];
+
+ for (int i = 0; i < DeviceIdSize; i += 4) begin
+ write32(i + DeviceIdOffset, device_id[i*8+:32]);
+ end
+ for (int i = 0; i < ManufStateSize; i += 4) begin
+ write32(i + ManufStateOffset, manuf_state[i*8+:32]);
+ end
+ write32(EnSramIfetchOffset,
+ {en_entropy_src_fw_over, en_entropy_src_fw_read, en_csrng_sw_app_read, en_sram_ifetch});
+
+ hw_cfg_data = {<<32 {32'h0, en_entropy_src_fw_over, en_entropy_src_fw_read,
+ en_csrng_sw_app_read, en_sram_ifetch, manuf_state, device_id}};
+ digest = cal_digest(HwCfgIdx, hw_cfg_data);
+
+ write64(HwCfgDigestOffset, digest);
+endfunction
diff --git a/hw/top_earlgrey/data/chip_testplan.hjson b/hw/top_earlgrey/data/chip_testplan.hjson
index f5e6faa..595bf58 100644
--- a/hw/top_earlgrey/data/chip_testplan.hjson
+++ b/hw/top_earlgrey/data/chip_testplan.hjson
@@ -2090,7 +2090,7 @@
For the retention SRAM, instruction fetch is completely disabled via design parameter.
'''
milestone: V2
- tests: []
+ tests: ["chip_sw_sram_ctrl_execution_main"]
}
{
name: chip_sw_sram_lc_escalation
diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
index a36e98c..e0e62f9 100644
--- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson
+++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
@@ -353,6 +353,12 @@
uvm_test_seq: chip_sw_rom_ctrl_integrity_check_vseq
sw_images: ["sw/device/tests/rom_ctrl_integrity_check_test:1"]
en_run_modes: ["sw_test_mode"]
+ }
+ {
+ name: chip_sw_sram_ctrl_execution_main
+ uvm_test_seq: chip_sw_sram_ctrl_execution_main_vseq
+ sw_images: ["sw/device/tests/sram_ctrl_execution_test_main:1"]
+ en_run_modes: ["sw_test_mode"]
}
{
name: chip_sw_coremark
diff --git a/hw/top_earlgrey/dv/env/chip_env.core b/hw/top_earlgrey/dv/env/chip_env.core
index c531224..cfc2232 100644
--- a/hw/top_earlgrey/dv/env/chip_env.core
+++ b/hw/top_earlgrey/dv/env/chip_env.core
@@ -45,6 +45,7 @@
- seq_lib/chip_sw_lc_ctrl_transition_vseq.sv: {is_include_file: true}
- seq_lib/chip_sw_spi_tx_rx_vseq.sv: {is_include_file: true}
- seq_lib/chip_sw_rom_ctrl_integrity_check_vseq.sv: {is_include_file: true}
+ - seq_lib/chip_sw_sram_ctrl_execution_main_vseq.sv: {is_include_file: true}
- autogen/chip_env_pkg__params.sv: {is_include_file: true}
- ast_supply_if.sv
file_type: systemVerilogSource
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_sram_ctrl_execution_main_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_sram_ctrl_execution_main_vseq.sv
new file mode 100644
index 0000000..8d89b4d
--- /dev/null
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_sram_ctrl_execution_main_vseq.sv
@@ -0,0 +1,55 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class chip_sw_sram_ctrl_execution_main_vseq extends chip_sw_base_vseq;
+ `uvm_object_utils(chip_sw_sram_ctrl_execution_main_vseq)
+
+ `uvm_object_new
+
+ localparam logic [255:0] DEVICE_ID =
+ 256'hFA53B8058E157CB69F1F413E87242971B6B52A656A1CAB7FEBF21E5BF1F45EDD;
+ localparam logic [255:0] MANUF_STATE =
+ 256'h41389646B3968A3B128F4AF0AFFC1AAC77ADEFF42376E09D523D5C06786AAC34;
+ localparam logic [7:0] EN_CSRNG_SW_APP_READ = 8'hA5;
+ localparam logic [7:0] EN_ENTROPY_SRC_FW_READ = 8'hA5;
+ localparam logic [7:0] EN_ENTROPY_SRC_FW_OVER = 8'hA5;
+ localparam logic [7:0] MUBI8TRUE = 8'h5A;
+ localparam logic [7:0] MUBI8FALSE = 8'hA5;
+
+ virtual task do_test(logic [7:0] en_sram_ifetch, bit set_prod_lc);
+
+ apply_reset();
+
+ if (set_prod_lc) begin
+ cfg.mem_bkdr_util_h[Otp].otp_write_lc_partition_state(LcStProd);
+ end
+ cfg.mem_bkdr_util_h[Otp].otp_write_hw_cfg_partition(
+ .device_id(DEVICE_ID), .manuf_state(MANUF_STATE), .en_sram_ifetch(en_sram_ifetch),
+ .en_csrng_sw_app_read(EN_CSRNG_SW_APP_READ),
+ .en_entropy_src_fw_read(EN_ENTROPY_SRC_FW_READ),
+ .en_entropy_src_fw_over(EN_ENTROPY_SRC_FW_OVER));
+
+ wait(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest);
+ wait(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInWfi);
+ endtask
+
+ virtual task body();
+
+ super.body();
+
+ // State 0 - SRAM_IFETCH = False, LC_STATE = LcStRma (default).
+ do_test(MUBI8FALSE, 0);
+ // State 1 - SRAM_IFETCH = True, LC_STATE = LcStRma (default).
+ do_test(MUBI8TRUE, 0);
+ // State 2 - SRAM_IFETCH = False, LC_STATE = LcStProd.
+ do_test(MUBI8FALSE, 1);
+ // State 3 - SRAM_IFETCH = True, LC_STATE = LcStProd.
+ do_test(MUBI8TRUE, 1);
+
+ cfg.sw_test_status_vif.sw_test_status = SwTestStatusPassed;
+ cfg.sw_test_status_vif.sw_test_done = 1'b1;
+
+ endtask
+
+endclass
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv
index 0e9402d..2aa310f 100644
--- a/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv
@@ -17,3 +17,4 @@
`include "chip_sw_lc_ctrl_transition_vseq.sv"
`include "chip_sw_spi_tx_rx_vseq.sv"
`include "chip_sw_rom_ctrl_integrity_check_vseq.sv"
+`include "chip_sw_sram_ctrl_execution_main_vseq.sv"
diff --git a/sw/device/tests/meson.build b/sw/device/tests/meson.build
index fe68d7e..ba4c545 100644
--- a/sw/device/tests/meson.build
+++ b/sw/device/tests/meson.build
@@ -705,29 +705,6 @@
}
}
-# SRAM Controller execution from Main SRAM test.
-sram_ctrl_execution_test_main_lib = declare_dependency(
- link_with: static_library(
- 'sram_ctrl_execution_test_main_lib',
- sources: ['sram_ctrl_execution_test_main.c'],
- dependencies: [
- sw_lib_bitfield,
- sw_lib_dif_sram_ctrl,
- sw_lib_runtime_ibex,
- sw_lib_runtime_log,
- sw_lib_testing_lc_ctrl_testutils,
- sw_lib_testing_otp_ctrl_testutils,
- sw_lib_testing_sram_ctrl_testutils,
- top_earlgrey,
- ],
- ),
-)
-sw_tests += {
- 'sram_ctrl_execution_test_main': {
- 'library': sram_ctrl_execution_test_main_lib,
- }
-}
-
# SRAM Controller execution from Ret SRAM test.
sram_ctrl_execution_test_ret_lib = declare_dependency(
link_with: static_library(
diff --git a/sw/device/tests/sim_dv/meson.build b/sw/device/tests/sim_dv/meson.build
index 3c40442..463d762 100644
--- a/sw/device/tests/sim_dv/meson.build
+++ b/sw/device/tests/sim_dv/meson.build
@@ -161,3 +161,29 @@
'library': rom_ctrl_integrity_check_test_lib,
}
}
+
+# SRAM Controller execution from Main SRAM test.
+sram_ctrl_execution_test_main_lib = declare_dependency(
+ link_with: static_library(
+ 'sram_ctrl_execution_test_main_lib',
+ sources: [
+ hw_ip_otp_ctrl_reg_h,
+ 'sram_ctrl_execution_test_main.c',
+ ],
+ dependencies: [
+ sw_lib_bitfield,
+ sw_lib_dif_sram_ctrl,
+ sw_lib_runtime_ibex,
+ sw_lib_runtime_log,
+ sw_lib_testing_lc_ctrl_testutils,
+ sw_lib_testing_otp_ctrl_testutils,
+ sw_lib_testing_sram_ctrl_testutils,
+ top_earlgrey,
+ ],
+ ),
+)
+sw_tests += {
+ 'sram_ctrl_execution_test_main': {
+ 'library': sram_ctrl_execution_test_main_lib,
+ }
+}
diff --git a/sw/device/tests/sram_ctrl_execution_test_main.c b/sw/device/tests/sim_dv/sram_ctrl_execution_test_main.c
similarity index 71%
rename from sw/device/tests/sram_ctrl_execution_test_main.c
rename to sw/device/tests/sim_dv/sram_ctrl_execution_test_main.c
index f334679..d73b9c4 100644
--- a/sw/device/tests/sram_ctrl_execution_test_main.c
+++ b/sw/device/tests/sim_dv/sram_ctrl_execution_test_main.c
@@ -7,6 +7,7 @@
#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/macros.h"
+#include "sw/device/lib/base/multibits.h"
#include "sw/device/lib/dif/dif_sram_ctrl.h"
#include "sw/device/lib/runtime/ibex.h"
#include "sw/device/lib/runtime/log.h"
@@ -20,6 +21,7 @@
#include "sw/device/lib/testing/test_framework/test_status.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
+#include "otp_ctrl_regs.h" // Generated
const test_config_t kTestConfig;
@@ -45,9 +47,10 @@
*
* x = OTP_CTRL_PARAM_EN_SRAM_IFETCH_OFFSET (1728)
* y = OTP_CTRL_PARAM_HW_CFG_OFFSET (1664)
- * IFETCH_OFFSET = (x - y) / 8 = 8
+ * IFETCH_OFFSET = (x - y) = 64
*/
-static const uint32_t kOtpIfetchHwRelativeOffset = 8;
+static const uint32_t kOtpIfetchHwRelativeOffset =
+ OTP_CTRL_PARAM_EN_SRAM_IFETCH_OFFSET - OTP_CTRL_PARAM_HW_CFG_OFFSET;
/**
* Executes the return instruction from MAIN SRAM.
@@ -79,8 +82,9 @@
uint32_t value;
CHECK_DIF_OK(dif_otp_ctrl_dai_read32_end(&otp, &value));
- // OTP stores IFETCH state in a single bit (enabled/disabled).
- return bitfield_bit32_read(value, 0);
+ return bitfield_field32_read(
+ value, (bitfield_field32_t){.mask = 0xff, .index = 0}) ==
+ kMultiBitBool8True;
}
/**
@@ -103,7 +107,7 @@
* stack by the OTTF exception handler entry subroutine, which means that the
* return address can be loaded from there. See comments below for more details.
*/
-void ottf_exeception_handler(void) {
+void ottf_exception_handler(void) {
// The frame address is the address of the stack location that holds the
// `mepc`, since the OTTF exception handler entry code saves the `mepc` to
// the top of the stack before transferring control flow to the exception
@@ -144,6 +148,42 @@
}
/**
+ * Sets the sram_ctrl exec CSR to both states and attempts to execute
+ * the code in SRAM. Checks whether an exception was observed for each
+ * case in line with the expected result based on LC_STATE and
+ * OTP IFETCH.
+ */
+void do_execute_test(bool debug_func, bool ifetch_en) {
+ bool csr_enabled_exception_expected;
+ bool csr_disabled_exception_expected;
+
+ if (debug_func && !ifetch_en) {
+ csr_enabled_exception_expected = false;
+ csr_disabled_exception_expected = false;
+ } else if (debug_func && ifetch_en) {
+ csr_enabled_exception_expected = false;
+ csr_disabled_exception_expected = true;
+ } else if (!debug_func && !ifetch_en) {
+ csr_enabled_exception_expected = true;
+ csr_disabled_exception_expected = true;
+ } else {
+ csr_enabled_exception_expected = false;
+ csr_disabled_exception_expected = true;
+ }
+
+ CHECK_DIF_OK(dif_sram_ctrl_exec_set_enabled(&sram_ctrl, kDifToggleEnabled));
+ exception_observed = false;
+ execute_code_in_sram();
+ CHECK(exception_observed == csr_enabled_exception_expected,
+ "Expected exception not observed whilst executing from SRAM!");
+ CHECK_DIF_OK(dif_sram_ctrl_exec_set_enabled(&sram_ctrl, kDifToggleDisabled));
+ exception_observed = false;
+ execute_code_in_sram();
+ CHECK(exception_observed == csr_disabled_exception_expected,
+ "Expected exception not observed whilst executing from SRAM!");
+}
+
+/**
* Performs the tests.
*
* When chip is in one of the lifecycle states where debug functions are
@@ -161,35 +201,25 @@
mmio_region_from_addr(TOP_EARLGREY_SRAM_CTRL_MAIN_REGS_BASE_ADDR),
&sram_ctrl));
+ bool locked;
+ CHECK_DIF_OK(
+ dif_sram_ctrl_is_locked(&sram_ctrl, kDifSramCtrlLockExec, &locked));
+ CHECK(!locked, "Execution is disabled and locked, cannot perform the test");
+
dif_lc_ctrl_t lc;
CHECK_DIF_OK(dif_lc_ctrl_init(
mmio_region_from_addr(TOP_EARLGREY_LC_CTRL_BASE_ADDR), &lc));
- if (otp_ifetch_enabled()) {
- dif_toggle_t state;
- CHECK_DIF_OK(dif_sram_ctrl_exec_get_enabled(&sram_ctrl, &state));
- if (state == kDifToggleDisabled) {
- bool locked;
- CHECK_DIF_OK(
- dif_sram_ctrl_is_locked(&sram_ctrl, kDifSramCtrlLockExec, &locked));
- CHECK(!locked,
- "Execution is disabled and locked, cannot perform the test");
- CHECK_DIF_OK(
- dif_sram_ctrl_exec_set_enabled(&sram_ctrl, kDifToggleEnabled));
+ // For the current configuration (set by the testbench)
+ // check that execution exceptions are as expected.
+ do_execute_test(lc_ctrl_testutils_debug_func_enabled(&lc),
+ otp_ifetch_enabled());
- exception_observed = false;
- execute_code_in_sram();
- CHECK(!exception_observed,
- "Exception observed whilst executing from SRAM!");
- }
- } else if (lc_ctrl_testutils_debug_func_enabled(&lc)) {
- exception_observed = false;
- execute_code_in_sram();
- CHECK(!exception_observed,
- "Exception observed whilst executing from SRAM!");
- } else {
- LOG_FATAL("Execution from SRAM cannot be enabled, cannot run the test");
- }
+ // When the test is complete flag WFI status so
+ // the testbench can reset and progress to the next
+ // combination of LC_STATE and OTP IFETCH.
+ test_status_set(kTestStatusInWfi);
+ wait_for_interrupt();
return true;
}