-
Notifications
You must be signed in to change notification settings - Fork 791
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[imm_rom_ext] Add immutable ROM_EXT ePMP reconfiguration
Reconfigure ePMP in immutable ROM_EXT to remove executable permission on the immutable data segment. Now, ePMP will be reconfigured to the following layout before jumping to the mutable ROM_EXT: ``` * 6: MU_EXT ----- ---- * 7: MU_EXT TOR LX-R * 8: IM_EXT ----- ---- * 9: IM_EXT TOR LX-R * 10: VIRTUAL NAPOT L--R * 11: STACK NA4 L--- ``` MU_EXT stands for mutable part of rom_ext, and IM_EXT is the immutable part. Slot 10 will be empty if address translation is not enabled, and stack guard is added back to slot 11. Before jumping to Owner SW, all lock bits will be cleared, so all entries can be recycled by Owner SW. Owner SW will be placed at the same entries as before (2, 3, 4). Change-Id: Id9b6cd68cc24a5816d3e3dc8374b5533a7c6eb75 Signed-off-by: Yi-Hsuan Deng <[email protected]>
- Loading branch information
Showing
9 changed files
with
339 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_epmp.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// 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_epmp.h" | ||
|
||
#include "sw/device/lib/base/csr.h" | ||
#include "sw/device/lib/base/macros.h" | ||
#include "sw/device/silicon_creator/lib/drivers/epmp.h" | ||
#include "sw/device/silicon_creator/lib/drivers/lifecycle.h" | ||
#include "sw/device/silicon_creator/lib/epmp_state.h" | ||
#include "sw/device/silicon_creator/lib/error.h" | ||
#include "sw/device/silicon_creator/lib/manifest.h" | ||
|
||
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" // Generated. | ||
|
||
// Address populated by the linker. | ||
extern char _rom_ext_immutable_start[]; | ||
extern char _rom_ext_immutable_end[]; | ||
extern char _text_end[]; | ||
extern char _stack_start[]; // Lowest stack address. | ||
|
||
static const epmp_region_t kMmioRegion = { | ||
.start = TOP_EARLGREY_MMIO_BASE_ADDR, | ||
.end = TOP_EARLGREY_MMIO_BASE_ADDR + TOP_EARLGREY_MMIO_SIZE_BYTES, | ||
}; | ||
|
||
static const epmp_region_t kFlashRegion = { | ||
.start = TOP_EARLGREY_EFLASH_BASE_ADDR, | ||
.end = TOP_EARLGREY_EFLASH_BASE_ADDR + TOP_EARLGREY_EFLASH_SIZE_BYTES, | ||
}; | ||
|
||
static const epmp_region_t kRvDmRegion = { | ||
.start = TOP_EARLGREY_RV_DM_MEM_BASE_ADDR, | ||
.end = TOP_EARLGREY_RV_DM_MEM_BASE_ADDR + TOP_EARLGREY_RV_DM_MEM_SIZE_BYTES, | ||
}; | ||
|
||
static const epmp_region_t kStackGuard = {.start = (uintptr_t)_stack_start, | ||
.end = (uintptr_t)_stack_start + 4}; | ||
|
||
static const epmp_region_t kImmTextRegion = { | ||
.start = (uintptr_t)_rom_ext_immutable_start, | ||
.end = (uintptr_t)_text_end, | ||
}; | ||
|
||
rom_error_t imm_rom_ext_epmp_reconfigure(void) { | ||
lifecycle_state_t lc_state = lifecycle_state_get(); | ||
|
||
// ePMP region 15 gives read/write access to RAM. | ||
// Leave it unchanged. | ||
|
||
// Reconfigure the ePMP MMIO region to be NAPOT region 14, thus freeing | ||
// up an ePMP entry for use elsewhere. | ||
epmp_set_napot(14, kMmioRegion, kEpmpPermLockedReadWrite); | ||
|
||
// ePMP region 11 protects the stack from overflow. | ||
// This stack guard was in ePMP region 14. | ||
epmp_set_napot(11, kStackGuard, kEpmpPermLockedNoAccess); | ||
|
||
// ePMP region 12 allows RvDM access. | ||
// This RvDM region was in ePMP region 13. | ||
if (lc_state == kLcStateProd || lc_state == kLcStateProdEnd) { | ||
// No RvDM access in Prod states, so we can clear the entry. | ||
epmp_clear(12); | ||
} else { | ||
epmp_set_napot(12, kRvDmRegion, kEpmpPermLockedReadWriteExecute); | ||
} | ||
|
||
// ePMP region 13 gives read access to all of flash for both M and U modes. | ||
// This flash region was in ePMP region 5. | ||
epmp_set_napot(13, kFlashRegion, kEpmpPermLockedReadOnly); | ||
|
||
// Move the ROM_EXT virtual region from entry 6 to 10. | ||
uint32_t virtual_napot; | ||
CSR_READ(CSR_REG_PMPADDR6, &virtual_napot); | ||
epmp_clear(10); | ||
if (virtual_napot) { | ||
epmp_set_napot(10, epmp_decode_napot(virtual_napot), | ||
kEpmpPermLockedReadOnly); | ||
} | ||
|
||
// Clear mutable ROM_EXT entries (8 & 9). | ||
epmp_clear(9); | ||
epmp_clear(8); | ||
|
||
// Immutable ROM_EXT TOR (6 & 7). | ||
epmp_set_tor(6, kImmTextRegion, kEpmpPermLockedReadExecute); | ||
|
||
// Clear entries from 5 ~ 3. | ||
epmp_clear(5); | ||
epmp_clear(4); | ||
epmp_clear(3); | ||
|
||
// 3 ~ 0 are ROM ePMP entries. | ||
// Leave them unchanged. | ||
|
||
HARDENED_RETURN_IF_ERROR(epmp_state_check()); | ||
|
||
return kErrorOk; | ||
} | ||
|
||
rom_error_t imm_rom_ext_epmp_mutable_rx(const manifest_t *manifest) { | ||
// Immutable ROM_EXT TOR (8 & 9). | ||
epmp_region_t mutable_code_region = manifest_code_region_get(manifest); | ||
|
||
// Manifest code_region includes immutable data segment. Move the start | ||
// address to exclude. | ||
mutable_code_region.start = (uintptr_t)_rom_ext_immutable_end; | ||
|
||
epmp_set_tor(8, mutable_code_region, kEpmpPermLockedReadExecute); | ||
|
||
HARDENED_RETURN_IF_ERROR(epmp_state_check()); | ||
|
||
return kErrorOk; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// 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_EPMP_H_ | ||
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_IMM_ROM_EXT_IMM_ROM_EXT_EPMP_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include "sw/device/silicon_creator/lib/error.h" | ||
#include "sw/device/silicon_creator/lib/manifest.h" | ||
|
||
/** | ||
* Reconfigure ePMP entries to lower priority. | ||
* | ||
* ePMP will be reconfigured to: | ||
* 0: ROM ----- ---- | ||
* 1: ROM TOR LX-R | ||
* 2: ROM NAPOT L--R | ||
* 3: ------- ----- ---- | ||
* 4: ------- ----- ---- | ||
* 5: ------- ----- ---- | ||
* 6: IM_EXT ----- ---- | ||
* 7: IM_EXT TOR LX-R | ||
* 8:[MU_EXT ----- ----] | ||
* 9:[MU_EXT TOR LX-R] | ||
* 10: VIRTUAL NAPOT L--R | ||
* 11: STACK NA4 L--- | ||
* 12: RvDM NAPOT LXWR | ||
* 13: FLASH NAPOT L--R | ||
* 14: MMIO NAPOT L-WR | ||
* 15: RAM NAPOT L-WR | ||
* | ||
* Mutable ROM_EXT segment (8 & 9) won't be configured by this function. | ||
* `imm_rom_ext_epmp_mutable_rx` will configure them when we are ready to | ||
* jump back to ROM. | ||
* | ||
* Entries 6~12 can be recycled in Owner SW stage. | ||
* | ||
* @return The result of the operation. | ||
*/ | ||
OT_WARN_UNUSED_RESULT | ||
rom_error_t imm_rom_ext_epmp_reconfigure(void); | ||
|
||
/** | ||
* Configure the Mutable ROM_EXT text segment with read-execute permissions. | ||
* | ||
* 8: MU_EXT ----- ---- | ||
* 9: MU_EXT TOR LX-R | ||
* | ||
* Note: When address translation is enabled, the manifest argument should | ||
* point to the one in the virtual space. | ||
* | ||
* @param manifest Pointer to the rom_ext manifest. | ||
* @return The result of the operation. | ||
*/ | ||
OT_WARN_UNUSED_RESULT | ||
rom_error_t imm_rom_ext_epmp_mutable_rx(const manifest_t *manifest); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif | ||
|
||
#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_IMM_ROM_EXT_IMM_ROM_EXT_EPMP_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.