target/riscv: Align pmp size to pmp-granularity
When configuring pmpcfg (TOR, NA4, or NAPOT) and pmpaddr, if the value is smaller than the PMP granularity, it needs to be aligned to the PMP granularity. Signed-off-by: Jay Chang <jay.chang@sifive.com> Reviewed-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com> Message-ID: <20260520063606.36600-2-jay.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Jay Chang committed
May 20, 2026 at 14:36 UTC
9afee2bde03539568bae5cfcad2bd5e330f42652
1 file changed
+8
-2
target/riscv/pmp.c
+8
-2
@@ -179,11 +179,12 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
179
}
180
/*
181
* When granularity g >= 1 (i.e., granularity > 4 bytes),
182
- * the NA4 (Naturally Aligned 4-byte) mode is not selectable
182
+ * the NA4 (Naturally Aligned 4-byte) mode is not selectable.
183
+ * In this case, an NA4 setting is reinterpreted as a NAPOT mode.
184
*/
185
if ((riscv_cpu_cfg(env)->pmp_granularity >
186
MIN_RISCV_PMP_GRANULARITY) && (a_field == PMP_AMATCH_NA4)) {
186
- return false;
187
+ val |= PMP_AMATCH;
188
}
189
env->pmp_state.pmp[pmp_index].cfg_reg = val;
190
pmp_update_rule_addr(env, pmp_index);
@@ -263,6 +264,11 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
264
break;
265
266
case PMP_AMATCH_NAPOT:
267
+ /* Bits [g-2:0] need to be all one to align pmp granularity */
268
+ if (g >= 2) {
269
+ this_addr = deposit64(this_addr, 0, g - 1, -1ULL);
270
+ }
271
+
272
pmp_decode_napot(this_addr, &sa, &ea);
273
break;
274