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]>
Reviewed-by: Alistair Francis <[email protected]> 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 > >
