From 324273c8ddca22604f812f9d8aa7b0a4c7e87144 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 3 Dec 2024 18:49:13 +0100 Subject: [PATCH] [sw,silicon_creator,rom] Convert the OpenTitan ROM to the ROM state API Signed-off-by: Samuel Ortiz --- sw/device/silicon_creator/rom/BUILD | 3 + sw/device/silicon_creator/rom/rom.c | 96 +++++++++++++++++++++++++---- sw/device/silicon_creator/rom/rom.h | 14 +++++ 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/sw/device/silicon_creator/rom/BUILD b/sw/device/silicon_creator/rom/BUILD index ecbffd07dc54c..67b7b103f2319 100644 --- a/sw/device/silicon_creator/rom/BUILD +++ b/sw/device/silicon_creator/rom/BUILD @@ -90,6 +90,7 @@ cc_library( "//sw/device/lib/base:csr", "//sw/device/lib/base:macros", "//sw/device/silicon_creator/lib:error", + "//sw/device/silicon_creator/lib:shutdown", ], ) @@ -135,6 +136,7 @@ cc_library( ":boot_policy_ptrs", ":bootstrap", ":rom_epmp", + ":rom_state", ":sigverify_keys_ecdsa_p256", ":sigverify_keys_spx", ":sigverify_otp_keys", @@ -177,6 +179,7 @@ cc_library( "//sw/device/silicon_creator/lib/drivers:uart", "//sw/device/silicon_creator/lib/drivers:watchdog", "//sw/device/silicon_creator/lib/sigverify", + "@rom_hooks", ], ) diff --git a/sw/device/silicon_creator/rom/rom.c b/sw/device/silicon_creator/rom/rom.c index 38bd13b1f4a9c..f5d0c9ddf62c7 100644 --- a/sw/device/silicon_creator/rom/rom.c +++ b/sw/device/silicon_creator/rom/rom.c @@ -47,6 +47,7 @@ #include "sw/device/silicon_creator/rom/boot_policy_ptrs.h" #include "sw/device/silicon_creator/rom/bootstrap.h" #include "sw/device/silicon_creator/rom/rom_epmp.h" +#include "sw/device/silicon_creator/rom/rom_state.h" #include "sw/device/silicon_creator/rom/sigverify_keys_ecdsa_p256.h" #include "sw/device/silicon_creator/rom/sigverify_keys_spx.h" #include "sw/device/silicon_creator/rom/sigverify_otp_keys.h" @@ -757,26 +758,95 @@ static rom_error_t rom_try_boot(void) { return kErrorRomBootFailed; } -void rom_main(void) { +/* + * The bootstrap request is the kRomStateBootstrapCheck and kRomStateBootstrap + * ROM states argument. It must be undefined before entering the + * kRomStateBootstrapCheck state as only the kRomStateBootstrapCheck run + * callback or hooks should set it to either kHardenedBoolFalse or + * kHardenedBoolTrue. + */ +static hardened_bool_t bootstrap_request = 0; + +enum { + kRomStateCnt_ = 4, +}; +static const size_t kRomStateCnt = kRomStateCnt_; + +/** + * Table of ROM states. + * + * Encoding generated with: + * $ ./util/design/sparse-fsm-encode.py -d 6 -m 4 -n 32 \ + * -s 519644925 --language=c + */ +// clang-format off +#define ROM_STATES(X) \ + X(kRomStateInit, 0x5616ae08, rom_state_init, NULL) \ + X(kRomStateBootstrapCheck, 0x0a9243ab, rom_state_bootstrap_check, &bootstrap_request) \ + X(kRomStateBootstrap, 0xd0a0ff08, rom_state_bootstrap, &bootstrap_request) \ + X(kRomStateBootRomExt, 0xed14f55f, rom_state_boot_rom_ext, NULL) +// clang-format on + +ROM_STATE_INIT_TABLE(rom_states, kRomStateCnt_, ROM_STATES); + +static OT_WARN_UNUSED_RESULT rom_error_t rom_state_init(void *arg, + uint32_t *next_state) { CFI_FUNC_COUNTER_INIT(rom_counters, kCfiRomMain); CFI_FUNC_COUNTER_PREPCALL(rom_counters, kCfiRomMain, 1, kCfiRomInit); - SHUTDOWN_IF_ERROR(rom_init()); + HARDENED_RETURN_IF_ERROR(rom_init()); CFI_FUNC_COUNTER_INCREMENT(rom_counters, kCfiRomMain, 3); - CFI_FUNC_COUNTER_CHECK(rom_counters, kCfiRomInit, 3); - if (launder32(waking_from_low_power) != kHardenedBoolTrue) { - HARDENED_CHECK_EQ(waking_from_low_power, kHardenedBoolFalse); - hardened_bool_t bootstrap_req = bootstrap_requested(); - if (launder32(bootstrap_req) == kHardenedBoolTrue) { - HARDENED_CHECK_EQ(bootstrap_req, kHardenedBoolTrue); - rom_bootstrap_message(); - watchdog_disable(); - shutdown_finalize(bootstrap()); - } + *next_state = kRomStateBootstrapCheck; + + return kErrorOk; +} + +static OT_WARN_UNUSED_RESULT rom_error_t +rom_state_bootstrap_check(void *arg, uint32_t *next_state) { + if (launder32(waking_from_low_power) == kHardenedBoolTrue) { + HARDENED_CHECK_EQ(waking_from_low_power, kHardenedBoolTrue); + *next_state = kRomStateBootRomExt; + + return kErrorOk; + } + + HARDENED_CHECK_EQ(waking_from_low_power, kHardenedBoolFalse); + + hardened_bool_t *bootstrap_req = (hardened_bool_t *)arg; + + // The pre_ hook may have set the bootstrap request flag. + if (launder32(*bootstrap_req) != kHardenedBoolTrue) { + *bootstrap_req = bootstrap_requested(); + } + + *next_state = kRomStateBootRomExt; + return kErrorOk; +} + +static OT_WARN_UNUSED_RESULT rom_error_t +rom_state_bootstrap(void *arg, uint32_t *next_state) { + hardened_bool_t *bootstrap_req = (hardened_bool_t *)arg; + + if (launder32(*bootstrap_req) == kHardenedBoolTrue) { + HARDENED_CHECK_EQ(bootstrap_req, kHardenedBoolTrue); + rom_bootstrap_message(); + watchdog_disable(); + // `bootstrap` will not return unless there is an error. + HARDENED_RETURN_IF_ERROR(bootstrap()); } + return kErrorRomBootFailed; +} + +static OT_WARN_UNUSED_RESULT rom_error_t +rom_state_boot_rom_ext(void *arg, uint32_t *next_state) { // `rom_try_boot` will not return unless there is an error. CFI_FUNC_COUNTER_PREPCALL(rom_counters, kCfiRomMain, 4, kCfiRomTryBoot); - shutdown_finalize(rom_try_boot()); + return rom_try_boot(); +} + +void rom_main(void) { + CFI_FUNC_COUNTER_INIT(rom_counters, kCfiRomMain); + shutdown_finalize(rom_state_fsm(rom_states, kRomStateCnt, kRomStateInit)); } diff --git a/sw/device/silicon_creator/rom/rom.h b/sw/device/silicon_creator/rom/rom.h index 6dd8e6bbaf2e2..64723c71ec1b9 100644 --- a/sw/device/silicon_creator/rom/rom.h +++ b/sw/device/silicon_creator/rom/rom.h @@ -7,10 +7,24 @@ #include +#include "sw/device/silicon_creator/lib/error.h" + #ifdef __cplusplus extern "C" { #endif // __cplusplus +/** + * ROM states run callbacks. + */ +static OT_WARN_UNUSED_RESULT rom_error_t rom_state_init(void *arg, + uint32_t *next_state); +static OT_WARN_UNUSED_RESULT rom_error_t +rom_state_bootstrap_check(void *arg, uint32_t *next_state); +static OT_WARN_UNUSED_RESULT rom_error_t +rom_state_bootstrap(void *arg, uint32_t *next_state); +static OT_WARN_UNUSED_RESULT rom_error_t +rom_state_boot_rom_ext(void *arg, uint32_t *next_state); + /** * The first C function executed by the ROM (defined in `rom.c`) */