Skip to content

Commit 483a878

Browse files
committed
riscv: pmp: Add macro to convert DT memory attributes to PMP permissions
Introduce the DT_MEM_RISCV_TO_PMP_PERM macro to translate Device Tree RISC-V memory attributes (DT_MEM_RISCV_TYPE_IO_R, DT_MEM_RISCV_TYPE_IO_W, DT_MEM_RISCV_TYPE_IO_X) into their corresponding RISC-V PMP permission bits (PMP_R, PMP_W, PMP_X). This allows for a clear and standardized way to define PMP regions based on Device Tree properties. Added a test suite for RISC-V PMP utilities, including a test case to verify the correctness of the DT_MEM_RISCV_TO_PMP_PERM macro across various attribute combinations. Signed-off-by: Firas Sammoura <[email protected]>
1 parent e83d8d9 commit 483a878

File tree

5 files changed

+70
-0
lines changed

5 files changed

+70
-0
lines changed

arch/riscv/include/pmp.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
#ifndef PMP_H_
88
#define PMP_H_
99

10+
#include <zephyr/dt-bindings/memory-attr/memory-attr-riscv.h>
11+
12+
#define DT_MEM_RISCV_TO_PMP_PERM(dt_attr) ( \
13+
(((dt_attr) & DT_MEM_RISCV_TYPE_IO_R) ? PMP_R : 0) | \
14+
(((dt_attr) & DT_MEM_RISCV_TYPE_IO_W) ? PMP_W : 0) | \
15+
(((dt_attr) & DT_MEM_RISCV_TYPE_IO_X) ? PMP_X : 0))
16+
1017
void z_riscv_pmp_init(void);
1118
void z_riscv_pmp_stackguard_prepare(struct k_thread *thread);
1219
void z_riscv_pmp_stackguard_enable(struct k_thread *thread);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(riscv_pmp)
6+
7+
FILE(GLOB app_sources src/*.c)
8+
target_sources(app PRIVATE ${app_sources})
9+
10+
target_include_directories(app PRIVATE
11+
${ZEPHYR_BASE}/kernel/include
12+
${ZEPHYR_BASE}/arch/${ARCH}/include
13+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CONFIG_ZTEST=y
2+
CONFIG_MULTITHREADING=y
3+
CONFIG_RISCV_PMP=y
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2025 Alphabet.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <kernel_internal.h>
7+
#include <zephyr/tc_util.h>
8+
#include <zephyr/ztest.h>
9+
10+
ZTEST(riscv_pmp_general, test_dt_pmp_perm_conversion)
11+
{
12+
uint8_t result;
13+
14+
result = DT_MEM_RISCV_TO_PMP_PERM(0);
15+
zassert_equal(result, 0, "Expected 0, got 0x%x", result);
16+
17+
result = DT_MEM_RISCV_TO_PMP_PERM(DT_MEM_RISCV_TYPE_IO_R);
18+
zassert_equal(result, PMP_R, "Expected PMP_R (0x%x), got 0x%x", PMP_R, result);
19+
20+
result = DT_MEM_RISCV_TO_PMP_PERM(DT_MEM_RISCV_TYPE_IO_W);
21+
zassert_equal(result, PMP_W, "Expected PMP_W (0x%x), got 0x%x", PMP_W, result);
22+
23+
result = DT_MEM_RISCV_TO_PMP_PERM(DT_MEM_RISCV_TYPE_IO_X);
24+
zassert_equal(result, PMP_X, "Expected PMP_X (0x%x), got 0x%x", PMP_X, result);
25+
26+
result = DT_MEM_RISCV_TO_PMP_PERM(DT_MEM_RISCV_TYPE_IO_R | DT_MEM_RISCV_TYPE_IO_W);
27+
zassert_equal(result, PMP_R | PMP_W, "Expected R|W (0x%x), got 0x%x", PMP_R | PMP_W,
28+
result);
29+
30+
result = DT_MEM_RISCV_TO_PMP_PERM(DT_MEM_RISCV_TYPE_IO_R | DT_MEM_RISCV_TYPE_IO_W |
31+
DT_MEM_RISCV_TYPE_IO_X);
32+
zassert_equal(result, PMP_R | PMP_W | PMP_X, "Expected R|W|X (0x%x), got 0x%x",
33+
PMP_R | PMP_W | PMP_X, result);
34+
}
35+
36+
ZTEST_SUITE(riscv_pmp_general, NULL, NULL, NULL, NULL, NULL);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
common:
2+
platform_allow:
3+
- qemu_riscv32
4+
- qemu_riscv32e
5+
- qemu_riscv64
6+
filter: CONFIG_RISCV_PMP
7+
ignore_faults: true
8+
9+
tests:
10+
arch.riscv.pmp.general:
11+
tags: test_framework

0 commit comments

Comments
 (0)