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

Cherry-pick to earlgrey_1.0.0: Immutable rom ext related changes #26144

Merged
merged 2 commits into from
Feb 13, 2025
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
11 changes: 11 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright lowRISC contributors (OpenTitan project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

package(default_visibility = ["//visibility:public"])

cc_library(
name = "main_lib",
srcs = ["imm_rom_ext.c"],
hdrs = ["imm_rom_ext.h"],
)
10 changes: 10 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.h"

void imm_rom_ext_main(void) {
// TODO(opentitan#24368): Implement this.
return;
}
18 changes: 18 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_IMM_ROM_EXT_IMM_ROM_EXT_H_
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_IMM_ROM_EXT_IMM_ROM_EXT_H_

#ifdef __cplusplus
extern "C" {
#endif

void imm_rom_ext_main(void);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_IMM_ROM_EXT_IMM_ROM_EXT_H_
13 changes: 13 additions & 0 deletions sw/device/silicon_creator/lib/drivers/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -886,3 +886,16 @@ cc_test(
"@googletest//:gtest_main",
],
)

cc_library(
name = "epmp",
srcs = ["epmp.c"],
hdrs = ["epmp.h"],
deps = [
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:bitfield",
"//sw/device/lib/base:csr",
"//sw/device/lib/base:hardened",
"//sw/device/silicon_creator/lib:epmp_state",
],
)
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

#include "sw/device/silicon_creator/rom_ext/rom_ext_epmp.h"
#include "sw/device/silicon_creator/lib/drivers/epmp.h"

#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/csr.h"
Expand All @@ -16,7 +16,7 @@
CSR_WRITE(CSR_REG_PMPADDR##addr_reg, pmpaddr); \
CSR_SET_BITS(CSR_REG_PMPCFG##cfg_reg, cfg);

static void rom_ext_epmp_set(uint8_t entry, uint32_t pmpcfg, uint32_t pmpaddr) {
static void epmp_set(uint8_t entry, uint32_t pmpcfg, uint32_t pmpaddr) {
uint32_t shift = 8 * (entry % 4);
uint32_t mask = 0xFFu << shift;
uint32_t cfg = (pmpcfg & 0xFFu) << shift;
Expand Down Expand Up @@ -49,12 +49,9 @@ static void rom_ext_epmp_set(uint8_t entry, uint32_t pmpcfg, uint32_t pmpaddr) {
epmp_state.pmpaddr[entry] = pmpaddr;
}

void rom_ext_epmp_clear(uint8_t entry) {
rom_ext_epmp_set(entry, kEpmpModeOff, 0);
}
void epmp_clear(uint8_t entry) { epmp_set(entry, kEpmpModeOff, 0); }

void rom_ext_epmp_set_napot(uint8_t entry, epmp_region_t region,
epmp_perm_t perm) {
void epmp_set_napot(uint8_t entry, epmp_region_t region, epmp_perm_t perm) {
uint32_t length = region.end - region.start;
// The length must be 4 or more.
HARDENED_CHECK_GE(length, 4);
Expand All @@ -64,18 +61,17 @@ void rom_ext_epmp_set_napot(uint8_t entry, epmp_region_t region,
HARDENED_CHECK_EQ(region.start & (length - 1), 0);
epmp_mode_t mode = length == 4 ? kEpmpModeNa4 : kEpmpModeNapot;
uint32_t addr = (region.start >> 2) | ((length - 1) >> 3);
rom_ext_epmp_set(entry, (uint32_t)mode | (uint32_t)perm, addr);
epmp_set(entry, (uint32_t)mode | (uint32_t)perm, addr);
}

void rom_ext_epmp_set_tor(uint8_t entry, epmp_region_t region,
epmp_perm_t perm) {
void epmp_set_tor(uint8_t entry, epmp_region_t region, epmp_perm_t perm) {
uint32_t start = region.start >> 2;
uint32_t end = ((region.end + 3u) & ~3u) >> 2;
rom_ext_epmp_set(entry, kEpmpModeOff, start);
rom_ext_epmp_set(entry + 1, (uint32_t)kEpmpModeTor | (uint32_t)perm, end);
epmp_set(entry, kEpmpModeOff, start);
epmp_set(entry + 1, (uint32_t)kEpmpModeTor | (uint32_t)perm, end);
}

void rom_ext_epmp_clear_rlb(void) {
void epmp_clear_rlb(void) {
const uint32_t kMask = EPMP_MSECCFG_RLB;
epmp_state.mseccfg &= ~kMask;
CSR_CLEAR_BITS(CSR_REG_MSECCFG, kMask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_ROM_EXT_EPMP_H_
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_ROM_EXT_EPMP_H_
#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_EPMP_H_
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_EPMP_H_

#include <stdint.h>

Expand All @@ -14,7 +14,7 @@ extern "C" {
#endif // __cplusplus

/**
* ROM_EXT ROM enhanced Physical Memory Protection (ePMP) library.
* Enhanced Physical Memory Protection (ePMP) library.
*
* The ePMP configuration is managed in two parts:
*
Expand All @@ -33,8 +33,6 @@ extern "C" {
* initialized) with the in-memory copy of the state used to double check the
* configuration as required.
*/
// TODO(lowrisc/opentitan#8800): Implement ePMP initialization for ROM_EXT
// stage.

/**
* Clear an ePMP entry.
Expand All @@ -43,7 +41,7 @@ extern "C" {
*
* @param entry The ePMP entry to clear.
*/
void rom_ext_epmp_clear(uint8_t entry);
void epmp_clear(uint8_t entry);

/**
* Configures an ePMP entry for a NAPOT or NA4 region.
Expand All @@ -59,8 +57,7 @@ void rom_ext_epmp_clear(uint8_t entry);
* @param region The address region to configure.
* @param perm The ePMP permissions for the region.
*/
void rom_ext_epmp_set_napot(uint8_t entry, epmp_region_t region,
epmp_perm_t perm);
void epmp_set_napot(uint8_t entry, epmp_region_t region, epmp_perm_t perm);

/**
* Configures an ePMP entry for a TOR region.
Expand All @@ -73,18 +70,17 @@ void rom_ext_epmp_set_napot(uint8_t entry, epmp_region_t region,
* @param region The address region to configure.
* @param perm The ePMP permissions for the region.
*/
void rom_ext_epmp_set_tor(uint8_t entry, epmp_region_t region,
epmp_perm_t perm);
void epmp_set_tor(uint8_t entry, epmp_region_t region, epmp_perm_t perm);

/**
* Clear the rule-locking-bypass (RLB) bit.
*
* Clearing RLB causes the Lock bit in the ePMP to be enforced.
*/
void rom_ext_epmp_clear_rlb(void);
void epmp_clear_rlb(void);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXT_ROM_EXT_EPMP_H_
#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_EPMP_H_
16 changes: 2 additions & 14 deletions sw/device/silicon_creator/rom_ext/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,6 @@ load(

package(default_visibility = ["//visibility:public"])

cc_library(
name = "rom_ext_epmp",
srcs = ["rom_ext_epmp.c"],
hdrs = ["rom_ext_epmp.h"],
deps = [
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:bitfield",
"//sw/device/lib/base:csr",
"//sw/device/lib/base:hardened",
"//sw/device/silicon_creator/lib:epmp_state",
],
)

cc_library(
name = "rescue",
srcs = ["rescue.c"],
Expand Down Expand Up @@ -170,7 +157,6 @@ cc_test(
":rescue",
":rom_ext_boot_policy",
":rom_ext_boot_policy_ptrs",
":rom_ext_epmp",
":sigverify_keys",
"//hw/ip/sram_ctrl/data:sram_ctrl_c_regs",
"//hw/top_earlgrey/ip_autogen/flash_ctrl:flash_ctrl_c_regs",
Expand All @@ -180,6 +166,7 @@ cc_test(
"//sw/device/lib/base:memory",
"//sw/device/lib/base:stdasm",
"//sw/device/lib/runtime:hart",
"//sw/device/silicon_creator/imm_rom_ext:main_lib",
"//sw/device/silicon_creator/lib:boot_data",
"//sw/device/silicon_creator/lib:boot_log",
"//sw/device/silicon_creator/lib:dbg_print",
Expand All @@ -193,6 +180,7 @@ cc_test(
"//sw/device/silicon_creator/lib/boot_svc:boot_svc_msg",
"//sw/device/silicon_creator/lib/cert:dice_chain",
"//sw/device/silicon_creator/lib/drivers:ast",
"//sw/device/silicon_creator/lib/drivers:epmp",
"//sw/device/silicon_creator/lib/drivers:flash_ctrl",
"//sw/device/silicon_creator/lib/drivers:hmac",
"//sw/device/silicon_creator/lib/drivers:ibex",
Expand Down
46 changes: 28 additions & 18 deletions sw/device/silicon_creator/rom_ext/rom_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/base/stdasm.h"
#include "sw/device/lib/runtime/hart.h"
#include "sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.h"
#include "sw/device/silicon_creator/lib/base/boot_measurements.h"
#include "sw/device/silicon_creator/lib/base/chip.h"
#include "sw/device/silicon_creator/lib/base/sec_mmio.h"
Expand All @@ -22,6 +23,7 @@
#include "sw/device/silicon_creator/lib/cert/dice_chain.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/epmp.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 All @@ -47,7 +49,6 @@
#include "sw/device/silicon_creator/rom_ext/rescue.h"
#include "sw/device/silicon_creator/rom_ext/rom_ext_boot_policy.h"
#include "sw/device/silicon_creator/rom_ext/rom_ext_boot_policy_ptrs.h"
#include "sw/device/silicon_creator/rom_ext/rom_ext_epmp.h"
#include "sw/device/silicon_creator/rom_ext/sigverify_keys.h"

#include "flash_ctrl_regs.h" // Generated.
Expand Down Expand Up @@ -461,25 +462,25 @@ static rom_error_t rom_ext_boot(boot_data_t *boot_data, boot_log_t *boot_log,
kOtpSecMmioCreatorSwCfgLockDown);

// ePMP region 15 gives read/write access to RAM.
rom_ext_epmp_set_napot(15, kRamRegion, kEpmpPermReadWrite);
epmp_set_napot(15, kRamRegion, kEpmpPermReadWrite);

// Reconfigure the ePMP MMIO region to be NAPOT region 14, thus freeing
// up an ePMP entry for use elsewhere.
rom_ext_epmp_set_napot(14, kMmioRegion, kEpmpPermReadWrite);
epmp_set_napot(14, kMmioRegion, kEpmpPermReadWrite);

// ePMP region 13 allows RvDM access.
if (lc_state == kLcStateProd || lc_state == kLcStateProdEnd) {
// No RvDM access in Prod states, so we can clear the entry.
rom_ext_epmp_clear(13);
epmp_clear(13);
} else {
rom_ext_epmp_set_napot(13, kRvDmRegion, kEpmpPermReadWriteExecute);
epmp_set_napot(13, kRvDmRegion, kEpmpPermReadWriteExecute);
}

// ePMP region 12 gives read access to all of flash for both M and U modes.
// The flash access was in ePMP region 5. Clear it so it doesn't take
// priority over 12.
rom_ext_epmp_set_napot(12, kFlashRegion, kEpmpPermReadOnly);
rom_ext_epmp_clear(5);
epmp_set_napot(12, kFlashRegion, kEpmpPermReadOnly);
epmp_clear(5);

// Move the ROM_EXT TOR region from entries 3/4/6 to 9/10/11.
// If the ROM_EXT is located in the virtual window, the ROM will have
Expand All @@ -501,15 +502,13 @@ static rom_error_t rom_ext_boot(boot_data_t *boot_data, boot_log_t *boot_log,
vwindow = (vwindow & ~(size - 1)) << 2;
size <<= 3;

rom_ext_epmp_set_napot(
11, (epmp_region_t){.start = vwindow, .end = vwindow + size},
kEpmpPermReadOnly);
epmp_set_napot(11, (epmp_region_t){.start = vwindow, .end = vwindow + size},
kEpmpPermReadOnly);
}
rom_ext_epmp_set_tor(rxindex,
(epmp_region_t){.start = start << 2, .end = end << 2},
kEpmpPermReadExecute);
epmp_set_tor(rxindex, (epmp_region_t){.start = start << 2, .end = end << 2},
kEpmpPermReadExecute);
for (int8_t i = (int8_t)rxindex - 1; i >= 0; --i) {
rom_ext_epmp_clear((uint8_t)i);
epmp_clear((uint8_t)i);
}
HARDENED_RETURN_IF_ERROR(epmp_state_check());

Expand All @@ -531,7 +530,7 @@ static rom_error_t rom_ext_boot(boot_data_t *boot_data, boot_log_t *boot_log,

// Unlock read-only for the whole rom_ext virtual memory.
HARDENED_RETURN_IF_ERROR(epmp_state_check());
rom_ext_epmp_set_napot(
epmp_set_napot(
4,
(epmp_region_t){.start = (uintptr_t)_owner_virtual_start_address,
.end = (uintptr_t)_owner_virtual_start_address +
Expand All @@ -552,7 +551,7 @@ static rom_error_t rom_ext_boot(boot_data_t *boot_data, boot_log_t *boot_log,
// anymore and since it isn't being used to encode access to the virtual
// window. However, for SiVal, we want to keep low entries locked to
// prevent using low entries to override policy in higher entries.
// rom_ext_epmp_clear_rom_region();
// epmp_clear_rom_region();
break;
default:
HARDENED_TRAP();
Expand All @@ -562,11 +561,11 @@ static rom_error_t rom_ext_boot(boot_data_t *boot_data, boot_log_t *boot_log,
// unlock the ROM_EXT code regions so the next stage can re-use those
// entries and clear RLB to prevent further changes to locked ePMP regions.
HARDENED_RETURN_IF_ERROR(epmp_state_check());
rom_ext_epmp_set_tor(2, text_region, kEpmpPermReadExecute);
epmp_set_tor(2, text_region, kEpmpPermReadExecute);

// Now that we're done reconfiguring the ePMP, we'll clear the RLB bit to
// prevent any modification to locked entries.
rom_ext_epmp_clear_rlb();
epmp_clear_rlb();
HARDENED_RETURN_IF_ERROR(epmp_state_check());

// Lock the address translation windows.
Expand Down Expand Up @@ -878,6 +877,11 @@ static rom_error_t rom_ext_start(boot_data_t *boot_data, boot_log_t *boot_log) {
}

void rom_ext_main(void) {
// TODO(opentitan#24368): Call immutable main in .rom_ext_immutable.
// The immutable rom_ext startup code is not ready yet, so we call it here
// to avoid breaking tests.
imm_rom_ext_main();

rom_ext_check_rom_expectations();
boot_data_t boot_data;
boot_log_t *boot_log = &retention_sram_get()->creator.boot_log;
Expand All @@ -900,3 +904,9 @@ void rom_ext_exception_handler(void);

OT_ALIAS("rom_ext_interrupt_handler")
void rom_ext_nmi_handler(void);

// A no-op immutable rom_ext fallback to avoid breaking tests before the
// proper bazel target is ready.
// TODO(opentitan#24368): Remove this nop fallback.
OT_SECTION(".rom_ext_immutable.fallback")
void imm_rom_ext_placeholder(void) {}
4 changes: 4 additions & 0 deletions sw/device/silicon_creator/rom_ext/rom_ext_common.ld
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ SECTIONS {
_text_start = .;
_rom_ext_immutable_start = .;
KEEP(*(.rom_ext_immutable))

/* TODO: Remove this fallback when rom_ext_immutable section is ready. */
KEEP(*(.rom_ext_immutable.fallback))

/* Ensure section end is word-aligned. */
. = ALIGN(256);
_rom_ext_immutable_end = .;
Expand Down
Loading
Loading