Skip to content

Commit 54a4836

Browse files
committed
riscv: pmp: Extract region address calculation to helper function
The logic to decode PMP addressing modes (**TOR**, **NA4**, **NAPOT**) into physical start and end addresses was previously embedded in `print_pmp_entries()`. Extract this calculation into a new static helper function, `pmp_decode_region()`, to significantly improve the readability and modularity of the PMP debug printing code. The new helper function is fully self-contained and exposes a defined API for the PMP address decoding logic. This enables **direct reuse** in **unit tests** (e.g., using **Ztest**) to verify the core address calculation accuracy for all PMP modes and boundary conditions, independent of the main PMP initialization or logging path. Signed-off-by: Firas Sammoura <[email protected]>
1 parent 2ae93aa commit 54a4836

File tree

1 file changed

+43
-20
lines changed

1 file changed

+43
-20
lines changed

arch/riscv/core/pmp.c

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,47 @@ LOG_MODULE_REGISTER(mpu);
5757

5858
#define PMP_NONE 0
5959

60+
/**
61+
* @brief Decodes PMP configuration and address registers into a memory region's
62+
* start/end addresses.
63+
*
64+
* @param cfg_byte The PMP configuration byte (pmpcfg_n).
65+
* @param pmp_addr A pointer to the full array of PMP address registers (pmpaddr_n).
66+
* @param index The current PMP entry index.
67+
* @param start Pointer to where the calculated start address should be stored.
68+
* @param end Pointer to where the calculated end address should be stored.
69+
*/
70+
static void pmp_decode_region(uint8_t cfg_byte,
71+
unsigned long *pmp_addr,
72+
unsigned int index,
73+
unsigned long *start,
74+
unsigned long *end)
75+
{
76+
unsigned long tmp;
77+
unsigned long pmp_addr_val = pmp_addr[index];
78+
unsigned long pmp_prev_addr_val = (index == 0) ? 0 : pmp_addr[index - 1];
79+
80+
switch (cfg_byte & PMP_A) {
81+
case PMP_TOR:
82+
*start = (index == 0) ? 0 : (pmp_prev_addr_val << 2);
83+
*end = (pmp_addr_val << 2) - 1;
84+
break;
85+
case PMP_NA4:
86+
*start = pmp_addr_val << 2;
87+
*end = *start + 3;
88+
break;
89+
case PMP_NAPOT:
90+
tmp = (pmp_addr_val << 2) | 0x3;
91+
*start = tmp & (tmp + 1);
92+
*end = tmp | (tmp + 1);
93+
break;
94+
default:
95+
*start = 0;
96+
*end = 0;
97+
break;
98+
}
99+
}
100+
60101
static void print_pmp_entries(unsigned int pmp_start, unsigned int pmp_end,
61102
unsigned long *pmp_addr, unsigned long *pmp_cfg,
62103
const char *banner)
@@ -66,27 +107,9 @@ static void print_pmp_entries(unsigned int pmp_start, unsigned int pmp_end,
66107

67108
LOG_DBG("PMP %s:", banner);
68109
for (index = pmp_start; index < pmp_end; index++) {
69-
unsigned long start, end, tmp;
110+
unsigned long start, end;
70111

71-
switch (pmp_n_cfg[index] & PMP_A) {
72-
case PMP_TOR:
73-
start = (index == 0) ? 0 : (pmp_addr[index - 1] << 2);
74-
end = (pmp_addr[index] << 2) - 1;
75-
break;
76-
case PMP_NA4:
77-
start = pmp_addr[index] << 2;
78-
end = start + 3;
79-
break;
80-
case PMP_NAPOT:
81-
tmp = (pmp_addr[index] << 2) | 0x3;
82-
start = tmp & (tmp + 1);
83-
end = tmp | (tmp + 1);
84-
break;
85-
default:
86-
start = 0;
87-
end = 0;
88-
break;
89-
}
112+
pmp_decode_region(pmp_n_cfg[index], pmp_addr, index, &start, &end);
90113

91114
if (end == 0) {
92115
LOG_DBG("%3d: "PR_ADDR" 0x%02x", index,

0 commit comments

Comments
 (0)