Skip to content

Commit

Permalink
[opentitanlib] set EXEC CSR in sram_ctrl when SRAM program is loaded
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
timothytrippel committed Dec 16, 2024
1 parent 18d5f43 commit 43a1fe5
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 3 deletions.
25 changes: 23 additions & 2 deletions sw/device/silicon_creator/manuf/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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
Expand All @@ -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",
Expand Down
3 changes: 2 additions & 1 deletion sw/host/opentitanlib/bindgen/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand All @@ -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",
]

Expand Down
1 change: 1 addition & 0 deletions sw/host/opentitanlib/bindgen/difs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "lc_ctrl_regs.h" // Generated.
#include "otp_ctrl_regs.h" // Generated.
#include "rstmgr_regs.h" // Generated.
#include "sram_ctrl_regs.h" // Generated.
#include "uart_regs.h" // Generated.

#else
Expand Down
16 changes: 16 additions & 0 deletions sw/host/opentitanlib/src/test_utils/load_sram_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -385,13 +386,28 @@ 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,
prog_info: &SramProgramInfo,
exec_mode: ExecutionMode,
) -> Result<ExecutionResult> {
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;
Expand Down

0 comments on commit 43a1fe5

Please sign in to comment.