@samitouri / QOSamiQemu / commits / 58cbdc780b

target/riscv: Support Smpmpmt extension

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 <jay.chang@sifive.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260305034429.74739-1-jay.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Jay Chang committed Mar 5, 2026 at 11:44 UTC 58cbdc780b11e6c6811c03dd12b94a4f7f5b65e2
4 files changed +20
target/riscv/cpu.c
+2
@@ -223,6 +223,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
223 ISA_EXT_DATA_ENTRY(smcsrind, PRIV_VERSION_1_13_0, ext_smcsrind),
224 ISA_EXT_DATA_ENTRY(smdbltrp, PRIV_VERSION_1_13_0, ext_smdbltrp),
225 ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
226 + ISA_EXT_DATA_ENTRY(smpmpmt, PRIV_VERSION_1_12_0, ext_smpmpmt),
227 ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
228 ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
229 ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
@@ -1276,6 +1277,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
1277 MULTI_EXT_CFG_BOOL("smaia", ext_smaia, false),
1278 MULTI_EXT_CFG_BOOL("smdbltrp", ext_smdbltrp, false),
1279 MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
1280 + MULTI_EXT_CFG_BOOL("smpmpmt", ext_smpmpmt, false),
1281 MULTI_EXT_CFG_BOOL("smrnmi", ext_smrnmi, false),
1282 MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false),
1283 MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false),
target/riscv/cpu_cfg_fields.h.inc
+1
@@ -59,6 +59,7 @@ BOOL_FIELD(ext_svadu)
59 BOOL_FIELD(ext_svinval)
60 BOOL_FIELD(ext_svnapot)
61 BOOL_FIELD(ext_svpbmt)
62 +BOOL_FIELD(ext_smpmpmt)
63 BOOL_FIELD(ext_svrsw60t59b)
64 BOOL_FIELD(ext_svvptc)
65 BOOL_FIELD(ext_svukte)
target/riscv/pmp.c
+16
@@ -165,6 +165,18 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
165 "ignoring pmpcfg write - invalid\n");
166 } else {
167 uint8_t a_field = pmp_get_a_field(val);
168 +
169 + if (!riscv_cpu_cfg(env)->ext_smpmpmt) {
170 + /* If smpmpmt not supported, clear the MTMATCH bit */
171 + val &= ~PMP_MTMATCH;
172 + } else if ((val & PMP_MTMATCH) == PMP_MTMATCH) {
173 + /*
174 + * If trying to set reserved value (0x3) for MT field,
175 + * preserve the original MT field from current config.
176 + */
177 + val = (val & ~PMP_MTMATCH) |
178 + (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_MTMATCH);
179 + }
180 /*
181 * When granularity g >= 1 (i.e., granularity > 4 bytes),
182 * 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,
367 * Check if the address has required RWX privs to complete desired operation
368 * Return true if a pmp rule match or default match
369 * Return false if no match
370 + *
371 + * Note: The MT (Memory Type) field from Smpmpmt extension is stored in
372 + * pmpcfg but is not acted upon during access checks. Cache attributes
373 + * have no functional impact in QEMU emulation.
374 */
375 bool pmp_hart_has_privs(CPURISCVState *env, hwaddr addr,
376 target_ulong size, pmp_priv_t privs,
target/riscv/pmp.h
+1
@@ -29,6 +29,7 @@ typedef enum {
29 PMP_WRITE = 1 << 1,
30 PMP_EXEC = 1 << 2,
31 PMP_AMATCH = (3 << 3),
32 + PMP_MTMATCH = (3 << 5),
33 PMP_LOCK = 1 << 7
34 } pmp_priv_t;
35