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]> --- 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; -- 2.48.1
