diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 05dcd84465380..f1a1a5b89ce6b 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -432,6 +432,30 @@ config PMP_STACK_GUARD_MIN_SIZE wiggle room to accommodate the eventual overflow exception stack usage. +config ROM_REGION_START + string "Start address or linker symbol of the ROM region" + depends on RISCV_PMP + default "__rom_region_start" + help + The linker symbol or hexadecimal address that defines the start of the + ROM region. + This configuration is used to calculate the physical memory + protection (PMP) region entry. The value is resolved at compile time. + To override the linker's default, set this to a hexadecimal string, + such as "0x80000000". + +config ROM_REGION_SIZE + string "Size or linker symbol of the ROM region" + depends on RISCV_PMP + default "__rom_region_size" + help + The linker symbol or hexadecimal size that defines the overall byte + length of the ROM region. + This configuration is used to calculate the physical memory + protection (PMP) region size. The value is resolved at compile time. + To manually override the linker's default size, set this to a + hexadecimal string, such as "0x100000". + # Implement the null pointer detection using the Physical Memory Protection # (PMP) Unit. config NULL_POINTER_EXCEPTION_DETECTION_PMP diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index ca5e5a49d5a74..6d589a6fcc168 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -32,6 +32,8 @@ #include #include +#include + #define LOG_LEVEL CONFIG_MPU_LOG_LEVEL #include LOG_MODULE_REGISTER(mpu); @@ -56,6 +58,14 @@ LOG_MODULE_REGISTER(mpu); #define PMP_NONE 0 +#define ADDRESS_RESOLVER(config_value) \ + (strcmp(config_value, "__rom_region_start") == 0) ? (uintptr_t)__rom_region_start \ + : (strcmp(config_value, "__rom_region_size") == 0) \ + ? (uintptr_t)__rom_region_size \ + : ((config_value[0] == '0' && (config_value[1] == 'x' || config_value[1] == 'X')) \ + ? (uintptr_t)strtoul(config_value, NULL, 16) \ + : 0) + static void print_pmp_entries(unsigned int pmp_start, unsigned int pmp_end, unsigned long *pmp_addr, unsigned long *pmp_cfg, const char *banner) @@ -355,10 +365,9 @@ void z_riscv_pmp_init(void) unsigned int index = 0; /* The read-only area is always there for every mode */ - set_pmp_entry(&index, PMP_R | PMP_X | PMP_L, - (uintptr_t)__rom_region_start, - (size_t)__rom_region_size, - pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr)); + set_pmp_entry(&index, PMP_R | PMP_X | PMP_L, ADDRESS_RESOLVER(CONFIG_ROM_REGION_START), + ADDRESS_RESOLVER(CONFIG_ROM_REGION_SIZE), pmp_addr, pmp_cfg, + ARRAY_SIZE(pmp_addr)); #ifdef CONFIG_NULL_POINTER_EXCEPTION_DETECTION_PMP /*