Skip to content
Open
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
24 changes: 24 additions & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 13 additions & 4 deletions arch/riscv/core/pmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include <zephyr/arch/arch_interface.h>
#include <zephyr/arch/riscv/csr.h>

#include <stdlib.h>

#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(mpu);
Expand All @@ -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)
Expand Down Expand Up @@ -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
/*
Expand Down