Skip to content

Commit 98d5b9d

Browse files
committed
Declare memory pools from linker symbols
Defines static memory pools for boot-time PMP initialization using linker symbols to identify kernel memory regions. Linker symbol declarations are updated to include text segment boundaries and match actual linker script definitions for stack regions. Five kernel memory pools protect text as read-execute, data and bss as read-write, heap and stack as read-write without execute to prevent code injection. Macro helpers reduce initialization boilerplate while maintaining debuggability through struct arrays. Priority-based management handles the 16-region hardware constraint.
1 parent 76a82b5 commit 98d5b9d

File tree

3 files changed

+115
-3
lines changed

3 files changed

+115
-3
lines changed

arch/riscv/hal.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
#include <types.h>
44

55
/* Symbols from the linker script, defining memory boundaries */
6-
extern uint32_t _stack_start, _stack_end; /* Start/end of the STACK memory */
7-
extern uint32_t _heap_start, _heap_end; /* Start/end of the HEAP memory */
8-
extern uint32_t _heap_size; /* Size of HEAP memory */
6+
extern uint32_t _stext, _etext; /* Start/end of the .text section */
97
extern uint32_t _sidata; /* Start address for .data initialization */
108
extern uint32_t _sdata, _edata; /* Start/end address for .data section */
119
extern uint32_t _sbss, _ebss; /* Start/end address for .bss section */
1210
extern uint32_t _end; /* End of kernel image */
11+
extern uint32_t _heap_start, _heap_end; /* Start/end of the HEAP memory */
12+
extern uint32_t _heap_size; /* Size of HEAP memory */
13+
extern uint32_t _stack_bottom, _stack_top; /* Bottom/top of the STACK memory */
1314

1415
/* Read a RISC-V Control and Status Register (CSR).
1516
* @reg : The symbolic name of the CSR (e.g., mstatus).

arch/riscv/pmp.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/* RISC-V Physical Memory Protection (PMP) Implementation
2+
*
3+
* Provides hardware-enforced memory isolation using PMP in TOR mode.
4+
*/
5+
6+
#include <hal.h>
7+
#include <sys/memprot.h>
8+
#include "csr.h"
9+
#include "pmp.h"
10+
11+
/* Static Memory Pools for Boot-time PMP Initialization
12+
*
13+
* Defines kernel memory regions protected at boot. Each pool specifies
14+
* a memory range and access permissions.
15+
*/
16+
static const mempool_t kernel_mempools[] = {
17+
DECLARE_MEMPOOL("kernel_text", &_stext, &_etext, PMPCFG_PERM_RX,
18+
PMP_PRIORITY_KERNEL),
19+
DECLARE_MEMPOOL("kernel_data", &_sdata, &_edata, PMPCFG_PERM_RW,
20+
PMP_PRIORITY_KERNEL),
21+
DECLARE_MEMPOOL("kernel_bss", &_sbss, &_ebss, PMPCFG_PERM_RW,
22+
PMP_PRIORITY_KERNEL),
23+
DECLARE_MEMPOOL("kernel_heap", &_heap_start, &_heap_end, PMPCFG_PERM_RW,
24+
PMP_PRIORITY_KERNEL),
25+
DECLARE_MEMPOOL("kernel_stack", &_stack_bottom, &_stack_top, PMPCFG_PERM_RW,
26+
PMP_PRIORITY_KERNEL),
27+
};
28+
29+
#define KERNEL_MEMPOOL_COUNT \
30+
(sizeof(kernel_mempools) / sizeof(kernel_mempools[0]))
31+
32+
/* Initialize PMP from Memory Pools
33+
*
34+
* Configures PMP regions based on static memory pool definitions.
35+
* Should be called during early boot before task scheduling begins.
36+
*
37+
* @config : Pointer to PMP configuration state
38+
* @pools : Array of memory pool descriptors
39+
* @count : Number of pools in the array
40+
* Returns 0 on success, or negative error code on failure.
41+
*/
42+
int32_t pmp_init_pools(pmp_config_t *config, const mempool_t *pools,
43+
size_t count)
44+
{
45+
if (!config || !pools || count == 0)
46+
return ERR_PMP_INVALID_REGION;
47+
48+
/* Initialize PMP hardware and state */
49+
int32_t ret = pmp_init(config);
50+
if (ret < 0)
51+
return ret;
52+
53+
/* Configure each memory pool as a PMP region */
54+
for (size_t i = 0; i < count; i++) {
55+
const mempool_t *pool = &pools[i];
56+
57+
/* Validate pool boundaries */
58+
if (pool->start >= pool->end)
59+
return ERR_PMP_ADDR_RANGE;
60+
61+
/* Prepare PMP region configuration */
62+
pmp_region_t region = {
63+
.addr_start = pool->start,
64+
.addr_end = pool->end,
65+
.permissions = pool->flags & (PMPCFG_R | PMPCFG_W | PMPCFG_X),
66+
.priority = pool->tag,
67+
.region_id = i,
68+
.locked = 0,
69+
};
70+
71+
/* Configure the PMP region */
72+
ret = pmp_set_region(config, &region);
73+
if (ret < 0)
74+
return ret;
75+
}
76+
77+
return ERR_OK;
78+
}
79+
80+
/* Initialize Kernel Memory Protection
81+
*
82+
* Convenience function that initializes PMP with default kernel memory
83+
* pools. Should be called during kernel initialization.
84+
*
85+
* @config : Pointer to PMP configuration state
86+
* Returns 0 on success, or negative error code on failure.
87+
*/
88+
int32_t pmp_init_kernel(pmp_config_t *config)
89+
{
90+
return pmp_init_pools(config, kernel_mempools, KERNEL_MEMPOOL_COUNT);
91+
}

arch/riscv/pmp.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
#include <types.h>
1010

11+
/* Forward declaration */
12+
typedef struct mempool mempool_t;
13+
1114
/* PMP Region Priority Levels (lower value = higher priority)
1215
*
1316
* Used for eviction decisions when hardware PMP regions are exhausted.
@@ -86,3 +89,20 @@ int32_t pmp_lock_region(pmp_config_t *config, uint8_t region_idx);
8689
*/
8790
int32_t pmp_check_access(const pmp_config_t *config, uint32_t addr,
8891
uint32_t size, uint8_t is_write, uint8_t is_execute);
92+
93+
/* Memory Pool Management Functions */
94+
95+
/* Initializes PMP regions from an array of memory pool descriptors.
96+
* @config : Pointer to PMP configuration state
97+
* @pools : Array of memory pool descriptors
98+
* @count : Number of pools in the array
99+
* Returns 0 on success, or negative error code on failure.
100+
*/
101+
int32_t pmp_init_pools(pmp_config_t *config, const mempool_t *pools,
102+
size_t count);
103+
104+
/* Initializes PMP with default kernel memory pools.
105+
* @config : Pointer to PMP configuration state
106+
* Returns 0 on success, or negative error code on failure.
107+
*/
108+
int32_t pmp_init_kernel(pmp_config_t *config);

0 commit comments

Comments
 (0)