From 429ca6c744dd87f33ee4e3e09b32d981dab57115 Mon Sep 17 00:00:00 2001 From: Tim Trippel Date: Fri, 13 Dec 2024 16:25:32 -0800 Subject: [PATCH] [opentitanlib] set EXEC CSR in sram_ctrl when SRAM program is loaded Previously, we were relying on HW_CFG1 partition not being programmed yet for SRAM execution to be enabled in TEST_UNLOCKED* states. However, this limits the re-entrancy of the FT individualize program, where HW_CFG1 is programmed but the individualize program needs to be re-tried again. Signed-off-by: Tim Trippel --- sw/device/silicon_creator/manuf/tests/BUILD | 25 +++++++++++++++++-- sw/host/opentitanlib/bindgen/BUILD | 3 ++- .../src/test_utils/load_sram_program.rs | 16 ++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/sw/device/silicon_creator/manuf/tests/BUILD b/sw/device/silicon_creator/manuf/tests/BUILD index 9a6e883ecaf08b..398fa4088df4c4 100644 --- a/sw/device/silicon_creator/manuf/tests/BUILD +++ b/sw/device/silicon_creator/manuf/tests/BUILD @@ -157,7 +157,6 @@ opentitan_test( ) # This is the same as rom_with_fake_keys_otp_test_unlocked* but with ROM execution disabled. -# TODO(#21204): Enable configuration of ROT AUTH partitions in CP stage. [ otp_image( name = "otp_img_rom_exec_disabled_test_unlocked{}".format(i), @@ -216,6 +215,28 @@ cc_library( ], ) +# Execution from SRAM is always enabled by default in TEST_UNLOCKED* LC states +# unless HW_CFG1 OTP partition has the EN_SRAM_IFETCH field set to True. In that +# case, the EXEC CSR in the sram_ctrl controls SRAM execution enablement. +# Therefore, we want to test with the HW_CFG1 partition programmed with +# EN_SRAM_IFETCH set to True. +[ + otp_image( + name = "otp_img_sram_exec_en_test_unlocked{}".format(i), + src = "//hw/ip/otp_ctrl/data:otp_json_test_unlocked{}".format(i), + overlays = [ + "//hw/ip/otp_ctrl/data:otp_json_fixed_secret0", + "//hw/ip/otp_ctrl/data:otp_json_creator_sw_cfg", + "//hw/ip/otp_ctrl/data:otp_json_owner_sw_cfg", + "//hw/ip/otp_ctrl/data:otp_json_alert_digest_cfg", + "//hw/ip/otp_ctrl/data:otp_json_hw_cfg1", + "//hw/ip/otp_ctrl/data:otp_json_exec_disabled", + ], + visibility = ["//visibility:private"], + ) + for i in range(0, 8) +] + # We are using a bitstream with ROM execution disabled so the contents of flash # does not matter but opentitan_test() is unhappy if we don't provide one. # Additionally, ROM execution is disabled in the OTP image we use so we do not @@ -230,7 +251,7 @@ cc_library( }, fpga = fpga_params( needs_jtag = True, - otp = ":otp_img_rom_exec_disabled_{}".format(lc_state.lower()), + otp = ":otp_img_sram_exec_en_{}".format(lc_state.lower()), tags = ["manuf"], test_cmd = "--elf={firmware}", test_harness = "//sw/host/tests/manuf/manuf_sram_program_crc_check", diff --git a/sw/host/opentitanlib/bindgen/BUILD b/sw/host/opentitanlib/bindgen/BUILD index ef4809174dc376..e8f3e4d9a98288 100644 --- a/sw/host/opentitanlib/bindgen/BUILD +++ b/sw/host/opentitanlib/bindgen/BUILD @@ -2,7 +2,7 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 -load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") +load("@rules_rust//rust:defs.bzl", "rust_library") load("@rules_rust//bindgen:bindgen.bzl", "rust_bindgen", "rust_bindgen_library") package(default_visibility = ["//visibility:public"]) @@ -16,6 +16,7 @@ _ENGLISH_BREAKFAST_DEPS = [ "//sw/device/lib/dif:lc_ctrl", "//sw/device/lib/dif:otp_ctrl", "//sw/device/lib/dif:rstmgr", + "//sw/device/lib/dif:sram_ctrl", "//sw/device/lib/dif:uart", ] diff --git a/sw/host/opentitanlib/src/test_utils/load_sram_program.rs b/sw/host/opentitanlib/src/test_utils/load_sram_program.rs index 0f82c7dfe45d1c..a453ac44a5c279 100644 --- a/sw/host/opentitanlib/src/test_utils/load_sram_program.rs +++ b/sw/host/opentitanlib/src/test_utils/load_sram_program.rs @@ -16,6 +16,7 @@ use object::{Object, ObjectSection, ObjectSegment, SectionKind}; use serde::{Deserialize, Serialize}; use thiserror::Error; +use crate::chip::boolean::MultiBitBool4; use crate::impl_serializable_error; use crate::io::jtag::{Jtag, RiscvCsr, RiscvGpr, RiscvReg}; use crate::util::parse_int::ParseInt; @@ -385,6 +386,20 @@ pub fn prepare_epmp(jtag: &mut dyn Jtag) -> Result<()> { Ok(()) } +/// Set up the sram_ctrl to execute code. +pub fn prepare_sram_ctrl(jtag: &mut dyn Jtag) -> Result<()> { + const SRAM_CTRL_EXEC_REG_OFFSET: u32 = (top_earlgrey::SRAM_CTRL_MAIN_REGS_BASE_ADDR as u32) + + bindgen::dif::SRAM_CTRL_EXEC_REG_OFFSET; + log::info!("Enabling execution from SRAM."); + let mut sram_ctrl_exec = [0]; + jtag.read_memory32(SRAM_CTRL_EXEC_REG_OFFSET, &mut sram_ctrl_exec)?; + log::info!("Old value of sram_exec_en: {:x}", sram_ctrl_exec[0]); + sram_ctrl_exec[0] = u8::from(MultiBitBool4::True) as u32; + jtag.write_memory32(SRAM_CTRL_EXEC_REG_OFFSET, &sram_ctrl_exec)?; + log::info!("New value of sram_exec_en: {:x}", sram_ctrl_exec[0]); + Ok(()) +} + /// Execute an already loaded SRAM program. It takes care of setting up the ePMP. pub fn execute_sram_program( jtag: &mut dyn Jtag, @@ -392,6 +407,7 @@ pub fn execute_sram_program( exec_mode: ExecutionMode, ) -> Result { prepare_epmp(jtag)?; + prepare_sram_ctrl(jtag)?; // To avoid unexpected behaviors, we always make sure that the return address // points to an invalid address. let ret_addr = 0xdeadbeefu32;