On Wed, May 20, 2026 at 02:36:05PM +0800, Jay Chang wrote:
> 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 <[email protected]>
> Reviewed-by: Frank Chang <[email protected]>
> Reviewed-by: Daniel Henrique Barboza <[email protected]>
Reviewed-by: Chao Liu <[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 a71091a316..8adf7c9719 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -179,11 +179,12 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t
> pmp_index, uint8_t 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);
> @@ -263,6 +264,11 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t
> pmp_index)
> break;
>
> case PMP_AMATCH_NAPOT:
> + /* Bits [g-2:0] need to be all one to align pmp granularity */
> + if (g >= 2) {
> + this_addr = deposit64(this_addr, 0, g - 1, -1ULL);
> + }
> +
> pmp_decode_napot(this_addr, &sa, &ea);
> break;
>
> --
> 2.48.1
>