On Thu, Mar 5, 2026 at 1:45 PM Jay Chang <[email protected]> wrote:
>
> The Smpmpmt extension provides a mechanism to control memory attributes
> at the granularity of PMP (Physical Memory Protection) registers, similar
> to how Svpbmt controls memory attributes at the page level.
>
> Version 0.6
> https://github.com/riscv/riscv-isa-manual/blob/smpmpmt/src/smpmpmt.adoc#svpbmt
>
> Signed-off-by: Jay Chang <[email protected]>
> Reviewed-by: Daniel Henrique Barboza <[email protected]>
> Reviewed-by: Frank Chang <[email protected]>

Thanks!

Applied to riscv-to-apply.next

Alistair

>
> ---
> v2:
>     Place smpmpmt in the correct riscv,isa order.
> v3:
>     Add note comment in pmp_hart_has_privs() explaining that MT field
>     is stored but not acted upon during access checks.
>
> Signed-off-by: Jay Chang <[email protected]>
> ---
>  target/riscv/cpu.c                |  2 ++
>  target/riscv/cpu_cfg_fields.h.inc |  1 +
>  target/riscv/pmp.c                | 16 ++++++++++++++++
>  target/riscv/pmp.h                |  1 +
>  4 files changed, 20 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9be79622f4..8ac935ac06 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -223,6 +223,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
>      ISA_EXT_DATA_ENTRY(smcsrind, PRIV_VERSION_1_13_0, ext_smcsrind),
>      ISA_EXT_DATA_ENTRY(smdbltrp, PRIV_VERSION_1_13_0, ext_smdbltrp),
>      ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
> +    ISA_EXT_DATA_ENTRY(smpmpmt, PRIV_VERSION_1_12_0, ext_smpmpmt),
>      ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
>      ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
>      ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
> @@ -1276,6 +1277,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
>      MULTI_EXT_CFG_BOOL("smaia", ext_smaia, false),
>      MULTI_EXT_CFG_BOOL("smdbltrp", ext_smdbltrp, false),
>      MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
> +    MULTI_EXT_CFG_BOOL("smpmpmt", ext_smpmpmt, false),
>      MULTI_EXT_CFG_BOOL("smrnmi", ext_smrnmi, false),
>      MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false),
>      MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false),
> diff --git a/target/riscv/cpu_cfg_fields.h.inc 
> b/target/riscv/cpu_cfg_fields.h.inc
> index 70ec650abf..cd1a5ec56b 100644
> --- a/target/riscv/cpu_cfg_fields.h.inc
> +++ b/target/riscv/cpu_cfg_fields.h.inc
> @@ -59,6 +59,7 @@ BOOL_FIELD(ext_svadu)
>  BOOL_FIELD(ext_svinval)
>  BOOL_FIELD(ext_svnapot)
>  BOOL_FIELD(ext_svpbmt)
> +BOOL_FIELD(ext_smpmpmt)
>  BOOL_FIELD(ext_svrsw60t59b)
>  BOOL_FIELD(ext_svvptc)
>  BOOL_FIELD(ext_svukte)
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 3ef62d26ad..5391caa59c 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -165,6 +165,18 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t 
> pmp_index, uint8_t val)
>                            "ignoring pmpcfg write - invalid\n");
>          } else {
>              uint8_t a_field = pmp_get_a_field(val);
> +
> +            if (!riscv_cpu_cfg(env)->ext_smpmpmt) {
> +                /* If smpmpmt not supported, clear the MTMATCH bit */
> +                val &= ~PMP_MTMATCH;
> +            } else if ((val & PMP_MTMATCH) == PMP_MTMATCH) {
> +                /*
> +                 * If trying to set reserved value (0x3) for MT field,
> +                 * preserve the original MT field from current config.
> +                 */
> +                val = (val & ~PMP_MTMATCH) |
> +                    (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_MTMATCH);
> +            }
>              /*
>               * When granularity g >= 1 (i.e., granularity > 4 bytes),
>               * the NA4 (Naturally Aligned 4-byte) mode is not selectable
> @@ -355,6 +367,10 @@ static bool pmp_hart_has_privs_default(CPURISCVState 
> *env, pmp_priv_t privs,
>   * Check if the address has required RWX privs to complete desired operation
>   * Return true if a pmp rule match or default match
>   * Return false if no match
> + *
> + * Note: The MT (Memory Type) field from Smpmpmt extension is stored in
> + * pmpcfg but is not acted upon during access checks. Cache attributes
> + * have no functional impact in QEMU emulation.
>   */
>  bool pmp_hart_has_privs(CPURISCVState *env, hwaddr addr,
>                          target_ulong size, pmp_priv_t privs,
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index 271cf24169..467fb6b4b1 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -29,6 +29,7 @@ typedef enum {
>      PMP_WRITE = 1 << 1,
>      PMP_EXEC  = 1 << 2,
>      PMP_AMATCH = (3 << 3),
> +    PMP_MTMATCH = (3 << 5),
>      PMP_LOCK  = 1 << 7
>  } pmp_priv_t;
>
> --
> 2.48.1
>
>

Reply via email to