Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[manuf] enable toggling external clock on/off during FT individualize #25630

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sw/device/lib/testing/json/provisioning_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ UJSON_SERDE_STRUCT(ManufCpTestData, \
*/
// clang-format off
#define STRUCT_MANUF_FT_INDIVIDUALIZE_DATA(field, string) \
field(use_ext_clk, bool) \
field(device_id, uint32_t, 8)
UJSON_SERDE_STRUCT(ManufFtIndividualizeData, \
manuf_ft_individualize_data_t, \
Expand Down
2 changes: 2 additions & 0 deletions sw/device/silicon_creator/manuf/base/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,12 @@ opentitan_test(
"//sw/device/lib/arch:device",
"//sw/device/lib/base:abs_mmio",
"//sw/device/lib/base:macros",
"//sw/device/lib/dif:clkmgr",
"//sw/device/lib/dif:flash_ctrl",
"//sw/device/lib/dif:otp_ctrl",
"//sw/device/lib/dif:pinmux",
"//sw/device/lib/runtime:hart",
"//sw/device/lib/runtime:ibex",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:flash_ctrl_testutils",
"//sw/device/lib/testing:otp_ctrl_testutils",
Expand Down
35 changes: 35 additions & 0 deletions sw/device/silicon_creator/manuf/base/sram_ft_individualize.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/base/abs_mmio.h"
#include "sw/device/lib/dif/dif_clkmgr.h"
#include "sw/device/lib/dif/dif_flash_ctrl.h"
#include "sw/device/lib/dif/dif_otp_ctrl.h"
#include "sw/device/lib/runtime/hart.h"
#include "sw/device/lib/runtime/ibex.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/runtime/print.h"
#include "sw/device/lib/testing/flash_ctrl_testutils.h"
Expand All @@ -30,6 +32,7 @@ OTTF_DEFINE_TEST_CONFIG(.console.type = kOttfConsoleSpiDevice,
.console.base_addr = TOP_EARLGREY_SPI_DEVICE_BASE_ADDR,
.console.test_may_clobber = false, );

static dif_clkmgr_t clkmgr;
static dif_flash_ctrl_state_t flash_ctrl_state;
static dif_otp_ctrl_t otp_ctrl;
static dif_pinmux_t pinmux;
Expand All @@ -38,10 +41,16 @@ static manuf_ft_individualize_data_t in_data;
static uint32_t cp_device_id[kFlashInfoFieldCpDeviceIdSizeIn32BitWords];
static uint32_t ast_cfg_data[kFlashInfoAstCalibrationDataSizeIn32BitWords];

// Switching to external clocks causes the clocks to be unstable for some time.
// This is used to delay further action when the switch happens.
static const int kSettleDelayMicros = 200;

/**
* Initializes all DIF handles used in this SRAM program.
*/
static status_t peripheral_handles_init(void) {
TRY(dif_clkmgr_init(mmio_region_from_addr(TOP_EARLGREY_CLKMGR_AON_BASE_ADDR),
&clkmgr));
TRY(dif_flash_ctrl_init_state(
&flash_ctrl_state,
mmio_region_from_addr(TOP_EARLGREY_FLASH_CTRL_CORE_BASE_ADDR)));
Expand Down Expand Up @@ -89,6 +98,13 @@ static status_t read_and_print_flash_and_ast_data(void) {
return OK_STATUS();
}

// For passing into `IBEX_SPIN_FOR`.
static bool did_extclk_settle(const dif_clkmgr_t *clkmgr) {
bool status;
CHECK_DIF_OK(dif_clkmgr_external_clock_is_settled(clkmgr, &status));
return status;
}

/**
* Provision OTP {CreatorSw,OwnerSw,Hw}Cfg and RotCreatorAuth{Codesign,State}
* partitions.
Expand All @@ -97,15 +113,32 @@ static status_t read_and_print_flash_and_ast_data(void) {
* all fields can be programmed until the personalization stage.
*/
static status_t provision(ujson_t *uj) {
// Get host data.
LOG_INFO("Waiting for FT SRAM provisioning data ...");
TRY(ujson_deserialize_manuf_ft_individualize_data_t(uj, &in_data));

// Enable external clock on silicon platforms if requested.
if (kDeviceType == kDeviceSilicon && in_data.use_ext_clk) {
CHECK_DIF_OK(dif_clkmgr_external_clock_set_enabled(&clkmgr,
/*is_low_speed=*/true));
IBEX_SPIN_FOR(did_extclk_settle(&clkmgr), kSettleDelayMicros);
LOG_INFO("External clock enabled.");
}

// Perform OTP writes.
LOG_INFO("Writing HW_CFG* OTP partitions ...");
TRY(manuf_individualize_device_hw_cfg(&flash_ctrl_state, &otp_ctrl,
kFlashInfoPage0Permissions,
in_data.device_id));
LOG_INFO("Writing ROT_CREATOR_AUTH_CODESIGN OTP partition ...");
TRY(manuf_individualize_device_rot_creator_auth_codesign(&otp_ctrl));
LOG_INFO("Writing ROT_CREATOR_AUTH_STATE OTP partition ...");
TRY(manuf_individualize_device_rot_creator_auth_state(&otp_ctrl));
LOG_INFO("Writing OWNER_SW_CFG OTP partition ...");
TRY(manuf_individualize_device_owner_sw_cfg(&otp_ctrl));
LOG_INFO("Writing CREATOR_SW_CFG OTP partition ...");
TRY(manuf_individualize_device_creator_sw_cfg(&otp_ctrl, &flash_ctrl_state));

LOG_INFO("FT SRAM provisioning done.");
return OK_STATUS();
}
Expand All @@ -119,6 +152,8 @@ bool test_main(void) {
// Read and log flash and AST data to console (for manual verification
// purposes), and perform provisioning operations.
CHECK_STATUS_OK(read_and_print_flash_and_ast_data());

// Perform provisioning operations.
CHECK_STATUS_OK(provision(&uj));

// Halt the CPU here to enable JTAG to perform an LC transition to mission
Expand Down
8 changes: 7 additions & 1 deletion sw/host/provisioning/ft/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ pub struct ManufFtProvisioningDataInput {
#[arg(long)]
pub device_id: String,

#[arg(long)]
pub use_ext_clk_during_individualize: bool,

/// TestUnlock token; a 128-bit hex string.
#[arg(long)]
pub test_unlock_token: String,
Expand Down Expand Up @@ -152,7 +155,10 @@ fn main() -> Result<()> {
.join("");
// We feed the device ID to the DUT in little endian order.
device_id.reverse();
let ft_individualize_data_in = ManufFtIndividualizeData { device_id };
let ft_individualize_data_in = ManufFtIndividualizeData {
use_ext_clk: opts.provisioning_data.use_ext_clk_during_individualize,
device_id,
};

// Parse and prepare CA key.
let mut ca_cfgs: HashMap<String, CaConfig> = serde_annotate::from_str(
Expand Down
7 changes: 7 additions & 0 deletions sw/host/provisioning/orchestrator/src/orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ def main(args_in):
choices=["hyper310", "cw340"],
help="Run flow on FPGA (instead of silicon).",
)
parser.add_argument(
"--use-ext-clk",
action="store_true",
default=False,
help="Use external clock during FT individualize step.",
)
parser.add_argument(
"--non-interactive",
action="store_true",
Expand Down Expand Up @@ -161,6 +167,7 @@ def main(args_in):
test_unlock_token=args.test_unlock_token,
test_exit_token=args.test_exit_token,
fpga=args.fpga,
use_ext_clk=args.use_ext_clk,
require_confirmation=not args.non_interactive)
dut.run_cp()
if args.cp_only:
Expand Down
5 changes: 5 additions & 0 deletions sw/host/provisioning/orchestrator/src/ot_dut.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class OtDut():
test_unlock_token: str
test_exit_token: str
fpga: str
use_ext_clk: bool
require_confirmation: bool = True

def _make_log_dir(self) -> None:
Expand Down Expand Up @@ -252,6 +253,10 @@ def run_ft(self) -> None:
--token-encrypt-key-der-file={self.sku_config.token_encrypt_key} \
"""

# Enable external clock if requested.
if self.use_ext_clk:
cmd += " --use-ext-clk-during-individualize"

# Get user confirmation before running command.
logging.info(f"Running command: {cmd}")
if self.require_confirmation:
Expand Down
4 changes: 3 additions & 1 deletion sw/host/provisioning/orchestrator/tests/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ PROVISIONING_EXT_RUNFILES=$TEST_TMPDIR/runfiles/provisioning_exts
$TEST_TMPDIR/runfiles/lowrisc_opentitan/external/provisioning_exts

# Run tool. The path to the --sku-config parameter is relative to the
# runfiles-dir.
# runfiles-dir. Note: "use-ext-clk" flag on FPGA does nothing, but this tests
# the flag can be piped through to the test harness.
$PYTHON ${ORCHESTRATOR_PATH} \
--sku-config=sw/host/provisioning/orchestrator/configs/skus/emulation.hjson \
--test-unlock-token="0x11111111_11111111_11111111_11111111" \
--test-exit-token="0x22222222_22222222_22222222_22222222" \
--fpga=hyper310 \
--use-ext-clk \
--non-interactive \
--runfiles-dir=$TEST_TMPDIR/runfiles/lowrisc_opentitan \
--db-path=$TEST_TMPDIR/registry.sqlite
Loading