Skip to content

Commit

Permalink
[sw,silicon_creator,rom] Convert the OpenTitan ROM to the ROM state API
Browse files Browse the repository at this point in the history
Signed-off-by: Samuel Ortiz <[email protected]>
  • Loading branch information
sameo committed Dec 17, 2024
1 parent bd19b19 commit 324273c
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 13 deletions.
3 changes: 3 additions & 0 deletions sw/device/silicon_creator/rom/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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",
],
)

Expand Down Expand Up @@ -135,6 +136,7 @@ cc_library(
":boot_policy_ptrs",
":bootstrap",
":rom_epmp",
":rom_state",
":sigverify_keys_ecdsa_p256",
":sigverify_keys_spx",
":sigverify_otp_keys",
Expand Down Expand Up @@ -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",
],
)

Expand Down
96 changes: 83 additions & 13 deletions sw/device/silicon_creator/rom/rom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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));
}
14 changes: 14 additions & 0 deletions sw/device/silicon_creator/rom/rom.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@

#include <stdnoreturn.h>

#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`)
*/
Expand Down

0 comments on commit 324273c

Please sign in to comment.