Skip to content

Commit

Permalink
[rom_ext] Add AST patching to rom_ext.
Browse files Browse the repository at this point in the history
Add a mechanism to patch the AST configuration in the rom_ext stage. The
data is loaded from the `kFlashCtrlInfoPageFactoryId` info page. The
configuration is only applied if the first two words read from flash are
not 00s or UINT32_t.

Signed-off-by: Miguel Osorio <[email protected]>
  • Loading branch information
moidx committed Dec 21, 2023
1 parent a8eef62 commit 91afa31
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 14 deletions.
2 changes: 2 additions & 0 deletions sw/device/silicon_creator/lib/drivers/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,11 @@ cc_library(
srcs = ["ast.c"],
hdrs = ["ast.h"],
deps = [
":flash_ctrl",
":lifecycle",
":otp",
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//hw/top_earlgrey/ip/ast/data:ast_regs",
"//hw/top_earlgrey/ip/sensor_ctrl/data:sensor_ctrl_regs",
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/arch:device",
Expand Down
86 changes: 82 additions & 4 deletions sw/device/silicon_creator/lib/drivers/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,43 @@
#include "sw/device/lib/base/abs_mmio.h"
#include "sw/device/lib/base/csr.h"
#include "sw/device/lib/base/multibits.h"
#include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
#include "sw/device/silicon_creator/lib/drivers/otp.h"

#include "ast_regs.h" // Generated.
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "otp_ctrl_regs.h"
#include "sensor_ctrl_regs.h"
#include "otp_ctrl_regs.h" // Generated.
#include "sensor_ctrl_regs.h" // Generated.

#ifndef OT_PLATFORM_RV32
// Provide a definition for off-target unit tests.
const uint32_t kAstCheckPollCpuCycles = 10000;
#endif

enum {
kBase = TOP_EARLGREY_SENSOR_CTRL_AON_BASE_ADDR,
kBaseSensorCtrl = TOP_EARLGREY_SENSOR_CTRL_AON_BASE_ADDR,
kBaseAst = TOP_EARLGREY_AST_BASE_ADDR,

/**
* AST Calibration Data Size - Bank 0, Page 0
*
* Number of AST calibration words that will be stored in flash / OTP.
*
* Must match `kFlashInfoAstCalibrationDataSizeIn32BitWords` in
* //sw/device/silicon_creator/manuf/lib/flash_info_fields.h.
*/
kAstCalibrationDataSizeIn32BitWords =
(AST_REGAL_REG_OFFSET + sizeof(uint32_t)) / sizeof(uint32_t),

/**
* The starting offset of the AST calibration data within the
* `kFlashCtrlInfoPageFactoryId` info flash page.
*
* Must be compatible to the `kFlashInfoFieldAstCalibrationData` byte offset
* in //sw/device/silicon_creator/manuf/lib/flash_info_fields.c.
*/
kAstCalibrationDataInfoFlashByteOffset =
OTP_CTRL_PARAM_DEVICE_ID_SIZE + OTP_CTRL_PARAM_MANUF_STATE_SIZE,
};

rom_error_t ast_check(lifecycle_state_t lc_state) {
Expand Down Expand Up @@ -76,7 +100,8 @@ rom_error_t ast_check(lifecycle_state_t lc_state) {

OT_WARN_UNUSED_RESULT
static bool done_bit_get(void) {
uint32_t reg = abs_mmio_read32(kBase + SENSOR_CTRL_STATUS_REG_OFFSET);
uint32_t reg =
abs_mmio_read32(kBaseSensorCtrl + SENSOR_CTRL_STATUS_REG_OFFSET);
return bitfield_bit32_read(reg, SENSOR_CTRL_STATUS_AST_INIT_DONE_BIT);
}

Expand All @@ -96,3 +121,56 @@ hardened_bool_t ast_init_done(void) {
}
return res;
}

/**
* Loads AST patch from kFlashCtrlInfoPageFactoryId page.
*
* The `ast_data` offset must be equivalent to the one used in
* //sw/device/silicon_creator/manuf/lib/ast_program.c.
*
* The info flash configuration must also be the same used to program the page,
* otherwise the data read will be garbled.
*
* @param[out] ast_data Pointer to the buffer used to store the data read.
*
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
static rom_error_t load_ast_config_from_flash(uint32_t *ast_data) {
flash_ctrl_info_perms_set(&kFlashCtrlInfoPageFactoryId,
(flash_ctrl_perms_t){
.read = kMultiBitBool4True,
.write = kMultiBitBool4False,
.erase = kMultiBitBool4False,
});
flash_ctrl_info_cfg_set(&kFlashCtrlInfoPageFactoryId,
(flash_ctrl_cfg_t){
.scrambling = kMultiBitBool4False,
.ecc = kMultiBitBool4True,
.he = kMultiBitBool4False,
});
return flash_ctrl_info_read(&kFlashCtrlInfoPageFactoryId,
kAstCalibrationDataInfoFlashByteOffset,
kAstCalibrationDataSizeIn32BitWords, ast_data);
}

rom_error_t ast_patch(lifecycle_state_t lc_state) {
uint32_t ast_data[kAstCalibrationDataSizeIn32BitWords];
HARDENED_RETURN_IF_ERROR(load_ast_config_from_flash(ast_data));

// Skip patching logic if either of the first two words don't seem to be
// configured.
if (ast_data[0] == 0 || ast_data[0] == UINT32_MAX) {
return ast_check(lc_state);
}

if (ast_data[1] == 0 || ast_data[1] == UINT32_MAX) {
return ast_check(lc_state);
}

for (size_t i = 0; i < kAstCalibrationDataSizeIn32BitWords; ++i) {
abs_mmio_write32(kBaseAst + i * sizeof(uint32_t), ast_data[i]);
}

return ast_check(lc_state);
}
18 changes: 18 additions & 0 deletions sw/device/silicon_creator/lib/drivers/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ extern "C" {
/**
* Check that the AST is in the expected state.
*
* @param lc_state The current life cycle state.
*
* @return an error if the AST is not in the expected state.
*/
OT_WARN_UNUSED_RESULT
Expand All @@ -30,6 +32,22 @@ rom_error_t ast_check(lifecycle_state_t lc_state);
OT_WARN_UNUSED_RESULT
hardened_bool_t ast_init_done(void);

/**
* Conditionally patch the AST registers using data stored in an info partition
* used to store manufacturing information.
*
* The patch is skipped if any of the first to AST words stored in the info
* partition are equivalent to 0 or UINT32_MAX.
*
* This function also calls `ast_check()` before returning.
*
* @param lc_state The current life cycle state.
*
* @return an error if the AST is not in the expected state.
*/
OT_WARN_UNUSED_RESULT
rom_error_t ast_patch(lifecycle_state_t lc_state);

#ifdef __cplusplus
}
#endif
Expand Down
7 changes: 4 additions & 3 deletions sw/device/silicon_creator/rom_ext/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ cc_library(
"//sw/device/silicon_creator/lib/base:sec_mmio",
"//sw/device/silicon_creator/lib/base:static_critical",
"//sw/device/silicon_creator/lib/boot_svc:boot_svc_msg",
"//sw/device/silicon_creator/lib/drivers:ast",
"//sw/device/silicon_creator/lib/drivers:flash_ctrl",
"//sw/device/silicon_creator/lib/drivers:hmac",
"//sw/device/silicon_creator/lib/drivers:ibex",
Expand All @@ -234,14 +235,14 @@ cc_library(
],
)

manifest({
manifest(d = {
"name": "manifest_standard",
"address_translation": hex(CONST.HARDENED_FALSE),
"identifier": hex(CONST.ROM_EXT),
"visibility": ["//visibility:public"],
})

manifest({
manifest(d = {
"name": "manifest_virtual",
"address_translation": hex(CONST.HARDENED_TRUE),
"identifier": hex(CONST.ROM_EXT),
Expand Down Expand Up @@ -301,7 +302,7 @@ opentitan_binary(
],
)

manifest({
manifest(d = {
"name": "manifest_bad_address_translation",
"address_translation": "0",
"identifier": hex(CONST.ROM_EXT),
Expand Down
16 changes: 10 additions & 6 deletions sw/device/silicon_creator/rom_ext/rom_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_header.h"
#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_msg.h"
#include "sw/device/silicon_creator/lib/dbg_print.h"
#include "sw/device/silicon_creator/lib/drivers/ast.h"
#include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
#include "sw/device/silicon_creator/lib/drivers/hmac.h"
#include "sw/device/silicon_creator/lib/drivers/ibex.h"
Expand Down Expand Up @@ -106,16 +107,19 @@ void rom_ext_check_rom_expectations(void) {
sec_mmio_check_values(rnd_uint32());
}

void rom_ext_init(void) {
OT_WARN_UNUSED_RESULT
static rom_error_t rom_ext_init(void) {
sec_mmio_next_stage_init();

lc_state = lifecycle_state_get();

// TODO: Verify ePMP expectations from ROM.

pinmux_init();
// Configure UART0 as stdout.
uart_init(kUartNCOValue);

// TODO: Verify ePMP expectations from ROM.

// Conditionally patch AST and check that it is in the expected state.
HARDENED_RETURN_IF_ERROR(ast_patch(lc_state));
return kErrorOk;
}

void rom_ext_sram_exec(hardened_bool_t enable) {
Expand Down Expand Up @@ -530,7 +534,7 @@ static rom_error_t rom_ext_try_boot(void) {

void rom_ext_main(void) {
rom_ext_check_rom_expectations();
rom_ext_init();
SHUTDOWN_IF_ERROR(rom_ext_init());
dbg_printf("Starting ROM_EXT\r\n");
rom_error_t error = rom_ext_try_boot();
// If the boot failed, enter bootstrap if it's enabled.
Expand Down
2 changes: 1 addition & 1 deletion sw/device/silicon_creator/rom_ext/sival/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ LINK_ORDER = [
"$(location //sw/device/lib/crt)",
]

manifest({
manifest(d = {
"name": "manifest_sival",
"address_translation": hex(CONST.HARDENED_FALSE),
"identifier": hex(CONST.ROM_EXT),
Expand Down

0 comments on commit 91afa31

Please sign in to comment.