On 12/23/25 7:25 AM, Jay Chang wrote:
When configuring pmpcfg (TOR, NA4, or NAPOT) and pmpaddr, if the
value is smaller than the PMP granularity, it automatically aligned
to the PMP granularity.

Signed-off-by: Jay Chang <[email protected]>
Reviewed-by: Frank Chang <[email protected]>
---

Reviewed-by: Daniel Henrique Barboza <[email protected]>

  target/riscv/pmp.c | 10 ++++++++--
  1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 3ef62d26ad..01b337f529 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -167,11 +167,12 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t 
pmp_index, uint8_t val)
              uint8_t a_field = pmp_get_a_field(val);
              /*
               * When granularity g >= 1 (i.e., granularity > 4 bytes),
-             * the NA4 (Naturally Aligned 4-byte) mode is not selectable
+             * the NA4 (Naturally Aligned 4-byte) mode is not selectable.
+             * In this case, an NA4 setting is reinterpreted as a NAPOT mode.
               */
              if ((riscv_cpu_cfg(env)->pmp_granularity >
                  MIN_RISCV_PMP_GRANULARITY) && (a_field == PMP_AMATCH_NA4)) {
-                    return false;
+                    val |= PMP_AMATCH;
              }
              env->pmp_state.pmp[pmp_index].cfg_reg = val;
              pmp_update_rule_addr(env, pmp_index);
@@ -251,6 +252,11 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t 
pmp_index)
          break;
case PMP_AMATCH_NAPOT:
+        /* Align to pmp_granularity */
+        if (g >= 2) {
+            this_addr |= ((1ULL << (g - 1ULL)) - 1ULL);
+        }
+
          pmp_decode_napot(this_addr, &sa, &ea);
          break;


Reply via email to