This patch lays the groundwork for the SMMPT (Supervisor Domains Access
Protection) extension by introducing its fundamental components.
It adds:
- New CPU configuration flags, `ext_smmpt` and `ext_smsdid`, to enable
the extension.
- Bit-field definitions for the `mmpt` CSR in `cpu_bits.h`.
- The `mmpt` and `msdcfg` CSR numbers and their read/write handlers in
`csr.c`.
- New fields in `CPUArchState` to store the state of these new CSRs.
- A new translation failure reason `TRANSLATE_MPT_FAIL`.
This provides the necessary infrastructure for the core MPT logic and
MMU integration that will follow.
Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com>
Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
target/riscv/cpu.h | 9 +++-
target/riscv/cpu_bits.h | 27 ++++++++++
target/riscv/cpu_cfg_fields.h.inc | 2 +
target/riscv/csr.c | 83 +++++++++++++++++++++++++++++++
4 files changed, 120 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4a862da615..fa7b804cb3 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -130,7 +130,8 @@ enum {
TRANSLATE_SUCCESS,
TRANSLATE_FAIL,
TRANSLATE_PMP_FAIL,
- TRANSLATE_G_STAGE_FAIL
+ TRANSLATE_G_STAGE_FAIL,
+ TRANSLATE_MPT_FAIL
};
/* Extension context status */
@@ -180,6 +181,7 @@ extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[];
#if !defined(CONFIG_USER_ONLY)
#include "pmp.h"
#include "debug.h"
+#include "riscv_smmpt.h"
#endif
#define RV_VLEN_MAX 1024
@@ -486,6 +488,11 @@ struct CPUArchState {
uint64_t hstateen[SMSTATEEN_MAX_COUNT];
uint64_t sstateen[SMSTATEEN_MAX_COUNT];
uint64_t henvcfg;
+ /* Smsdid */
+ uint32_t mptmode;
+ uint32_t sdid;
+ uint64_t mptppn;
+ uint32_t msdcfg;
#endif
/* Fields from here on are preserved across CPU reset. */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index b62dd82fe7..c6a34863d1 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -1164,4 +1164,31 @@ typedef enum CTRType {
#define MCONTEXT64 0x0000000000001FFFULL
#define MCONTEXT32_HCONTEXT 0x0000007F
#define MCONTEXT64_HCONTEXT 0x0000000000003FFFULL
+
+/* Smsdid */
+#define CSR_MMPT 0xbc0
+#define CSR_MSDCFG 0xbd1
+
+#define MMPT_MODE_MASK_32 0xC0000000
+#define MMPT_SDID_MASK_32 0x3F000000
+#define MMPT_PPN_MASK_32 0x003FFFFF
+
+#define MMPT_MODE_SHIFT_32 30
+#define MMPT_SDID_SHIFT_32 24
+
+#define MMPT_MODE_MASK_64 0xF000000000000000ULL
+#define MMPT_SDID_MASK_64 0x0FC0000000000000ULL
+#define MMPT_PPN_MASK_64 0x000FFFFFFFFFFFFFULL
+
+#define MPTE_L3_VALID 0x0000100000000000ULL
+#define MPTE_L3_RESERVED 0xFFFFE00000000000ULL
+
+#define MPTE_L2_RESERVED_64 0xFFFF800000000000ULL
+#define MPTE_L2_RESERVED_32 0xFE000000
+
+#define MPTE_L1_RESERVED_64 0xFFFFFFFF00000000ULL
+#define MPTE_L1_RESERVED_32 0xFFFF0000
+
+#define MMPT_MODE_SHIFT_64 60
+#define MMPT_SDID_SHIFT_64 54
#endif
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index e2d116f0df..8c8a4ac236 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -60,6 +60,8 @@ BOOL_FIELD(ext_svpbmt)
BOOL_FIELD(ext_svrsw60t59b)
BOOL_FIELD(ext_svvptc)
BOOL_FIELD(ext_svukte)
+BOOL_FIELD(ext_smmpt)
+BOOL_FIELD(ext_smsdid)
BOOL_FIELD(ext_zdinx)
BOOL_FIELD(ext_zaamo)
BOOL_FIELD(ext_zacas)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8842e07a73..77bc596ed3 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -793,6 +793,15 @@ static RISCVException rnmi(CPURISCVState *env, int csrno)
return RISCV_EXCP_ILLEGAL_INST;
}
+
+static RISCVException smsdid(CPURISCVState *env, int csrno)
+{
+ if (riscv_cpu_cfg(env)->ext_smsdid) {
+ return RISCV_EXCP_NONE;
+ }
+
+ return RISCV_EXCP_ILLEGAL_INST;
+}
#endif
static RISCVException seed(CPURISCVState *env, int csrno)
@@ -5470,6 +5479,77 @@ static RISCVException write_mnstatus(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
+static RISCVException read_mmpt(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ if (riscv_cpu_xlen(env) == 32) {
+ uint32_t value = 0;
+ value |= env->mptmode << MMPT_MODE_SHIFT_32;
+ value |= (env->sdid << MMPT_SDID_SHIFT_32) & MMPT_SDID_MASK_32;
+ value |= env->mptppn & MMPT_PPN_MASK_32;
+ *val = value;
+ } else if (riscv_cpu_xlen(env) == 64) {
+ uint64_t value_64 = 0;
+ uint32_t mode_value = env->mptmode;
+ /* mpt_mode_t convert to mmpt.mode value */
+ if (mode_value) {
+ mode_value -= SMMTT43 - SMMTT34;
+ }
+ value_64 |= (uint64_t)mode_value << MMPT_MODE_SHIFT_64;
+ value_64 |= ((uint64_t)env->sdid << MMPT_SDID_SHIFT_64)
+ & MMPT_SDID_MASK_64;
+ value_64 |= (uint64_t)env->mptppn & MMPT_PPN_MASK_64;
+ *val = value_64;
+ } else {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mmpt(CPURISCVState *env, int csrno,
+ target_ulong val, uintptr_t ra)
+{
+ /* Fixme: if mode is bare, the remaining fields in mmpt must be zero */
+ if (riscv_cpu_xlen(env) == 32) {
+ /* Only write the legal value */
+ uint32_t mode_value = (val & MMPT_MODE_MASK_32) >> MMPT_MODE_SHIFT_32;
+ if (mode_value <= SMMTT34) {
+ env->mptmode = mode_value;
+ }
+ env->sdid = (val & MMPT_SDID_MASK_32) >> MMPT_SDID_SHIFT_32;
+ env->mptppn = val & MMPT_PPN_MASK_32;
+ } else if (riscv_cpu_xlen(env) == 64) {
+ uint32_t mode_value = (val & MMPT_MODE_MASK_64) >> MMPT_MODE_SHIFT_64;
+ /* check legal value */
+ if (mode_value < SMMTTMAX) {
+ /* convert to mpt_mode_t */
+ if (mode_value) {
+ mode_value += SMMTT43 - SMMTT34;
+ }
+ env->mptmode = mode_value;
+ }
+ env->sdid = (val & MMPT_SDID_MASK_64) >> MMPT_SDID_SHIFT_64;
+ env->mptppn = val & MMPT_PPN_MASK_64;
+ } else {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_msdcfg(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = env->msdcfg;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_msdcfg(CPURISCVState *env, int csrno,
+ target_ulong val, uintptr_t ra)
+{
+ env->msdcfg = val;
+ return RISCV_EXCP_NONE;
+}
+
#endif
/* Crypto Extension */
@@ -6666,6 +6746,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
write_mhpmcounterh },
[CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf,
.min_priv_ver = PRIV_VERSION_1_12_0 },
+ /* Supervisor Domain Identifier and Protection Registers */
+ [CSR_MMPT] = { "mmpt", smsdid, read_mmpt, write_mmpt },
+ [CSR_MSDCFG] = { "msdcfg", smsdid, read_msdcfg, write_msdcfg },
#endif /* !CONFIG_USER_ONLY */
};
--
2.25.1
On 9/9/25 10:25 AM, LIU Zhiwei wrote: > This patch lays the groundwork for the SMMPT (Supervisor Domains Access > Protection) extension by introducing its fundamental components. > > It adds: > - New CPU configuration flags, `ext_smmpt` and `ext_smsdid`, to enable > the extension. > - Bit-field definitions for the `mmpt` CSR in `cpu_bits.h`. > - The `mmpt` and `msdcfg` CSR numbers and their read/write handlers in > `csr.c`. > - New fields in `CPUArchState` to store the state of these new CSRs. > - A new translation failure reason `TRANSLATE_MPT_FAIL`. > > This provides the necessary infrastructure for the core MPT logic and > MMU integration that will follow. > > Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com> > Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com> > Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> > --- > target/riscv/cpu.h | 9 +++- > target/riscv/cpu_bits.h | 27 ++++++++++ > target/riscv/cpu_cfg_fields.h.inc | 2 + > target/riscv/csr.c | 83 +++++++++++++++++++++++++++++++ > 4 files changed, 120 insertions(+), 1 deletion(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 4a862da615..fa7b804cb3 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -130,7 +130,8 @@ enum { > TRANSLATE_SUCCESS, > TRANSLATE_FAIL, > TRANSLATE_PMP_FAIL, > - TRANSLATE_G_STAGE_FAIL > + TRANSLATE_G_STAGE_FAIL, > + TRANSLATE_MPT_FAIL > }; > > /* Extension context status */ > @@ -180,6 +181,7 @@ extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[]; > #if !defined(CONFIG_USER_ONLY) > #include "pmp.h" > #include "debug.h" > +#include "riscv_smmpt.h" > #endif > > #define RV_VLEN_MAX 1024 > @@ -486,6 +488,11 @@ struct CPUArchState { > uint64_t hstateen[SMSTATEEN_MAX_COUNT]; > uint64_t sstateen[SMSTATEEN_MAX_COUNT]; > uint64_t henvcfg; > + /* Smsdid */ > + uint32_t mptmode; > + uint32_t sdid; > + uint64_t mptppn; > + uint32_t msdcfg; > #endif > > /* Fields from here on are preserved across CPU reset. */ > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h > index b62dd82fe7..c6a34863d1 100644 > --- a/target/riscv/cpu_bits.h > +++ b/target/riscv/cpu_bits.h > @@ -1164,4 +1164,31 @@ typedef enum CTRType { > #define MCONTEXT64 0x0000000000001FFFULL > #define MCONTEXT32_HCONTEXT 0x0000007F > #define MCONTEXT64_HCONTEXT 0x0000000000003FFFULL > + > +/* Smsdid */ > +#define CSR_MMPT 0xbc0 > +#define CSR_MSDCFG 0xbd1 > + > +#define MMPT_MODE_MASK_32 0xC0000000 > +#define MMPT_SDID_MASK_32 0x3F000000 > +#define MMPT_PPN_MASK_32 0x003FFFFF > + > +#define MMPT_MODE_SHIFT_32 30 > +#define MMPT_SDID_SHIFT_32 24 > + > +#define MMPT_MODE_MASK_64 0xF000000000000000ULL > +#define MMPT_SDID_MASK_64 0x0FC0000000000000ULL > +#define MMPT_PPN_MASK_64 0x000FFFFFFFFFFFFFULL > + > +#define MPTE_L3_VALID 0x0000100000000000ULL > +#define MPTE_L3_RESERVED 0xFFFFE00000000000ULL > + > +#define MPTE_L2_RESERVED_64 0xFFFF800000000000ULL > +#define MPTE_L2_RESERVED_32 0xFE000000 > + > +#define MPTE_L1_RESERVED_64 0xFFFFFFFF00000000ULL > +#define MPTE_L1_RESERVED_32 0xFFFF0000 > + > +#define MMPT_MODE_SHIFT_64 60 > +#define MMPT_SDID_SHIFT_64 54 > #endif > diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc > index e2d116f0df..8c8a4ac236 100644 > --- a/target/riscv/cpu_cfg_fields.h.inc > +++ b/target/riscv/cpu_cfg_fields.h.inc > @@ -60,6 +60,8 @@ BOOL_FIELD(ext_svpbmt) > BOOL_FIELD(ext_svrsw60t59b) > BOOL_FIELD(ext_svvptc) > BOOL_FIELD(ext_svukte) > +BOOL_FIELD(ext_smmpt) > +BOOL_FIELD(ext_smsdid) > BOOL_FIELD(ext_zdinx) > BOOL_FIELD(ext_zaamo) > BOOL_FIELD(ext_zacas) > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 8842e07a73..77bc596ed3 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -793,6 +793,15 @@ static RISCVException rnmi(CPURISCVState *env, int csrno) > > return RISCV_EXCP_ILLEGAL_INST; > } > + > +static RISCVException smsdid(CPURISCVState *env, int csrno) > +{ > + if (riscv_cpu_cfg(env)->ext_smsdid) { > + return RISCV_EXCP_NONE; > + } > + > + return RISCV_EXCP_ILLEGAL_INST; > +} > #endif > > static RISCVException seed(CPURISCVState *env, int csrno) > @@ -5470,6 +5479,77 @@ static RISCVException write_mnstatus(CPURISCVState *env, int csrno, > return RISCV_EXCP_NONE; > } > > +static RISCVException read_mmpt(CPURISCVState *env, int csrno, > + target_ulong *val) > +{ > + if (riscv_cpu_xlen(env) == 32) { > + uint32_t value = 0; > + value |= env->mptmode << MMPT_MODE_SHIFT_32; > + value |= (env->sdid << MMPT_SDID_SHIFT_32) & MMPT_SDID_MASK_32; > + value |= env->mptppn & MMPT_PPN_MASK_32; > + *val = value; > + } else if (riscv_cpu_xlen(env) == 64) { > + uint64_t value_64 = 0; > + uint32_t mode_value = env->mptmode; > + /* mpt_mode_t convert to mmpt.mode value */ > + if (mode_value) { > + mode_value -= SMMTT43 - SMMTT34; > + } > + value_64 |= (uint64_t)mode_value << MMPT_MODE_SHIFT_64; > + value_64 |= ((uint64_t)env->sdid << MMPT_SDID_SHIFT_64) > + & MMPT_SDID_MASK_64; > + value_64 |= (uint64_t)env->mptppn & MMPT_PPN_MASK_64; > + *val = value_64; > + } else { > + return RISCV_EXCP_ILLEGAL_INST; > + } > + return RISCV_EXCP_NONE; > +} > + > +static RISCVException write_mmpt(CPURISCVState *env, int csrno, > + target_ulong val, uintptr_t ra) > +{ > + /* Fixme: if mode is bare, the remaining fields in mmpt must be zero */ > + if (riscv_cpu_xlen(env) == 32) { > + /* Only write the legal value */ > + uint32_t mode_value = (val & MMPT_MODE_MASK_32) >> MMPT_MODE_SHIFT_32; > + if (mode_value <= SMMTT34) { > + env->mptmode = mode_value; > + } > + env->sdid = (val & MMPT_SDID_MASK_32) >> MMPT_SDID_SHIFT_32; > + env->mptppn = val & MMPT_PPN_MASK_32; > + } else if (riscv_cpu_xlen(env) == 64) { > + uint32_t mode_value = (val & MMPT_MODE_MASK_64) >> MMPT_MODE_SHIFT_64; > + /* check legal value */ > + if (mode_value < SMMTTMAX) { > + /* convert to mpt_mode_t */ > + if (mode_value) { > + mode_value += SMMTT43 - SMMTT34; > + } > + env->mptmode = mode_value; > + } > + env->sdid = (val & MMPT_SDID_MASK_64) >> MMPT_SDID_SHIFT_64; > + env->mptppn = val & MMPT_PPN_MASK_64; > + } else { > + return RISCV_EXCP_ILLEGAL_INST; > + } > + return RISCV_EXCP_NONE; > +} > + > +static RISCVException read_msdcfg(CPURISCVState *env, int csrno, > + target_ulong *val) > +{ > + *val = env->msdcfg; > + return RISCV_EXCP_NONE; > +} > + > +static RISCVException write_msdcfg(CPURISCVState *env, int csrno, > + target_ulong val, uintptr_t ra) > +{ > + env->msdcfg = val; > + return RISCV_EXCP_NONE; > +} > + > #endif > > /* Crypto Extension */ > @@ -6666,6 +6746,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { > write_mhpmcounterh }, > [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf, > .min_priv_ver = PRIV_VERSION_1_12_0 }, > + /* Supervisor Domain Identifier and Protection Registers */ > + [CSR_MMPT] = { "mmpt", smsdid, read_mmpt, write_mmpt }, > + [CSR_MSDCFG] = { "msdcfg", smsdid, read_msdcfg, write_msdcfg }, I see that you added ext_smmpt but ended up not using in this patch. Shouldn't read_mmpt and write_mmpt dependent on ext_smmpt? Thanks, Daniel > > #endif /* !CONFIG_USER_ONLY */ > };
On 9/17/25 7:16 PM, Daniel Henrique Barboza wrote: > > > On 9/9/25 10:25 AM, LIU Zhiwei wrote: >> This patch lays the groundwork for the SMMPT (Supervisor Domains Access >> Protection) extension by introducing its fundamental components. >> >> It adds: >> - New CPU configuration flags, `ext_smmpt` and `ext_smsdid`, to enable >> the extension. >> - Bit-field definitions for the `mmpt` CSR in `cpu_bits.h`. >> - The `mmpt` and `msdcfg` CSR numbers and their read/write handlers in >> `csr.c`. >> - New fields in `CPUArchState` to store the state of these new CSRs. >> - A new translation failure reason `TRANSLATE_MPT_FAIL`. >> >> This provides the necessary infrastructure for the core MPT logic and >> MMU integration that will follow. >> >> Co-authored-by: Huang Tao <eric.huang@linux.alibaba.com> >> Co-authored-by: TANG Tiancheng <lyndra@linux.alibaba.com> >> Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> >> --- >> target/riscv/cpu.h | 9 +++- >> target/riscv/cpu_bits.h | 27 ++++++++++ >> target/riscv/cpu_cfg_fields.h.inc | 2 + >> target/riscv/csr.c | 83 +++++++++++++++++++++++++++++++ >> 4 files changed, 120 insertions(+), 1 deletion(-) >> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h >> index 4a862da615..fa7b804cb3 100644 >> --- a/target/riscv/cpu.h >> +++ b/target/riscv/cpu.h >> @@ -130,7 +130,8 @@ enum { >> TRANSLATE_SUCCESS, >> TRANSLATE_FAIL, >> TRANSLATE_PMP_FAIL, >> - TRANSLATE_G_STAGE_FAIL >> + TRANSLATE_G_STAGE_FAIL, >> + TRANSLATE_MPT_FAIL >> }; >> /* Extension context status */ >> @@ -180,6 +181,7 @@ extern RISCVCPUImpliedExtsRule >> *riscv_multi_ext_implied_rules[]; >> #if !defined(CONFIG_USER_ONLY) >> #include "pmp.h" >> #include "debug.h" >> +#include "riscv_smmpt.h" >> #endif >> #define RV_VLEN_MAX 1024 >> @@ -486,6 +488,11 @@ struct CPUArchState { >> uint64_t hstateen[SMSTATEEN_MAX_COUNT]; >> uint64_t sstateen[SMSTATEEN_MAX_COUNT]; >> uint64_t henvcfg; >> + /* Smsdid */ >> + uint32_t mptmode; >> + uint32_t sdid; >> + uint64_t mptppn; >> + uint32_t msdcfg; >> #endif >> /* Fields from here on are preserved across CPU reset. */ >> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h >> index b62dd82fe7..c6a34863d1 100644 >> --- a/target/riscv/cpu_bits.h >> +++ b/target/riscv/cpu_bits.h >> @@ -1164,4 +1164,31 @@ typedef enum CTRType { >> #define MCONTEXT64 0x0000000000001FFFULL >> #define MCONTEXT32_HCONTEXT 0x0000007F >> #define MCONTEXT64_HCONTEXT 0x0000000000003FFFULL >> + >> +/* Smsdid */ >> +#define CSR_MMPT 0xbc0 >> +#define CSR_MSDCFG 0xbd1 >> + >> +#define MMPT_MODE_MASK_32 0xC0000000 >> +#define MMPT_SDID_MASK_32 0x3F000000 >> +#define MMPT_PPN_MASK_32 0x003FFFFF >> + >> +#define MMPT_MODE_SHIFT_32 30 >> +#define MMPT_SDID_SHIFT_32 24 >> + >> +#define MMPT_MODE_MASK_64 0xF000000000000000ULL >> +#define MMPT_SDID_MASK_64 0x0FC0000000000000ULL >> +#define MMPT_PPN_MASK_64 0x000FFFFFFFFFFFFFULL >> + >> +#define MPTE_L3_VALID 0x0000100000000000ULL >> +#define MPTE_L3_RESERVED 0xFFFFE00000000000ULL >> + >> +#define MPTE_L2_RESERVED_64 0xFFFF800000000000ULL >> +#define MPTE_L2_RESERVED_32 0xFE000000 >> + >> +#define MPTE_L1_RESERVED_64 0xFFFFFFFF00000000ULL >> +#define MPTE_L1_RESERVED_32 0xFFFF0000 >> + >> +#define MMPT_MODE_SHIFT_64 60 >> +#define MMPT_SDID_SHIFT_64 54 >> #endif >> diff --git a/target/riscv/cpu_cfg_fields.h.inc >> b/target/riscv/cpu_cfg_fields.h.inc >> index e2d116f0df..8c8a4ac236 100644 >> --- a/target/riscv/cpu_cfg_fields.h.inc >> +++ b/target/riscv/cpu_cfg_fields.h.inc >> @@ -60,6 +60,8 @@ BOOL_FIELD(ext_svpbmt) >> BOOL_FIELD(ext_svrsw60t59b) >> BOOL_FIELD(ext_svvptc) >> BOOL_FIELD(ext_svukte) >> +BOOL_FIELD(ext_smmpt) >> +BOOL_FIELD(ext_smsdid) >> BOOL_FIELD(ext_zdinx) >> BOOL_FIELD(ext_zaamo) >> BOOL_FIELD(ext_zacas) >> diff --git a/target/riscv/csr.c b/target/riscv/csr.c >> index 8842e07a73..77bc596ed3 100644 >> --- a/target/riscv/csr.c >> +++ b/target/riscv/csr.c >> @@ -793,6 +793,15 @@ static RISCVException rnmi(CPURISCVState *env, >> int csrno) >> return RISCV_EXCP_ILLEGAL_INST; >> } >> + >> +static RISCVException smsdid(CPURISCVState *env, int csrno) >> +{ >> + if (riscv_cpu_cfg(env)->ext_smsdid) { >> + return RISCV_EXCP_NONE; >> + } >> + >> + return RISCV_EXCP_ILLEGAL_INST; >> +} >> #endif >> static RISCVException seed(CPURISCVState *env, int csrno) >> @@ -5470,6 +5479,77 @@ static RISCVException >> write_mnstatus(CPURISCVState *env, int csrno, >> return RISCV_EXCP_NONE; >> } >> +static RISCVException read_mmpt(CPURISCVState *env, int csrno, >> + target_ulong *val) >> +{ >> + if (riscv_cpu_xlen(env) == 32) { >> + uint32_t value = 0; >> + value |= env->mptmode << MMPT_MODE_SHIFT_32; >> + value |= (env->sdid << MMPT_SDID_SHIFT_32) & MMPT_SDID_MASK_32; >> + value |= env->mptppn & MMPT_PPN_MASK_32; >> + *val = value; >> + } else if (riscv_cpu_xlen(env) == 64) { >> + uint64_t value_64 = 0; >> + uint32_t mode_value = env->mptmode; >> + /* mpt_mode_t convert to mmpt.mode value */ >> + if (mode_value) { >> + mode_value -= SMMTT43 - SMMTT34; >> + } >> + value_64 |= (uint64_t)mode_value << MMPT_MODE_SHIFT_64; >> + value_64 |= ((uint64_t)env->sdid << MMPT_SDID_SHIFT_64) >> + & MMPT_SDID_MASK_64; >> + value_64 |= (uint64_t)env->mptppn & MMPT_PPN_MASK_64; >> + *val = value_64; >> + } else { >> + return RISCV_EXCP_ILLEGAL_INST; >> + } >> + return RISCV_EXCP_NONE; >> +} >> + >> +static RISCVException write_mmpt(CPURISCVState *env, int csrno, >> + target_ulong val, uintptr_t ra) >> +{ >> + /* Fixme: if mode is bare, the remaining fields in mmpt must be >> zero */ >> + if (riscv_cpu_xlen(env) == 32) { >> + /* Only write the legal value */ >> + uint32_t mode_value = (val & MMPT_MODE_MASK_32) >> >> MMPT_MODE_SHIFT_32; >> + if (mode_value <= SMMTT34) { >> + env->mptmode = mode_value; >> + } >> + env->sdid = (val & MMPT_SDID_MASK_32) >> MMPT_SDID_SHIFT_32; >> + env->mptppn = val & MMPT_PPN_MASK_32; >> + } else if (riscv_cpu_xlen(env) == 64) { >> + uint32_t mode_value = (val & MMPT_MODE_MASK_64) >> >> MMPT_MODE_SHIFT_64; >> + /* check legal value */ >> + if (mode_value < SMMTTMAX) { >> + /* convert to mpt_mode_t */ >> + if (mode_value) { >> + mode_value += SMMTT43 - SMMTT34; >> + } >> + env->mptmode = mode_value; >> + } >> + env->sdid = (val & MMPT_SDID_MASK_64) >> MMPT_SDID_SHIFT_64; >> + env->mptppn = val & MMPT_PPN_MASK_64; >> + } else { >> + return RISCV_EXCP_ILLEGAL_INST; >> + } >> + return RISCV_EXCP_NONE; >> +} >> + >> +static RISCVException read_msdcfg(CPURISCVState *env, int csrno, >> + target_ulong *val) >> +{ >> + *val = env->msdcfg; >> + return RISCV_EXCP_NONE; >> +} >> + >> +static RISCVException write_msdcfg(CPURISCVState *env, int csrno, >> + target_ulong val, uintptr_t ra) >> +{ >> + env->msdcfg = val; >> + return RISCV_EXCP_NONE; >> +} >> + >> #endif >> /* Crypto Extension */ >> @@ -6666,6 +6746,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { >> write_mhpmcounterh }, >> [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf, >> .min_priv_ver = PRIV_VERSION_1_12_0 }, >> + /* Supervisor Domain Identifier and Protection Registers */ >> + [CSR_MMPT] = { "mmpt", smsdid, read_mmpt, write_mmpt }, >> + [CSR_MSDCFG] = { "msdcfg", smsdid, read_msdcfg, write_msdcfg }, > > I see that you added ext_smmpt but ended up not using in this patch. > Shouldn't > read_mmpt and write_mmpt dependent on ext_smmpt? Hi Daniel, Great question—thanks for raising it. From the straightforward reading of the spec, mmpt is part of the M-mode programming interface defined by Smsdid, not Smmpt. Quoting the spec: “Smsdid defines an interface to program the configuration for supervisor-domain-related extensions. The interface consists of M-mode CSRs msdcfg and mmpt.” From another angle, we can mirror how satp relates to the MMU to get a cleaner design. As the privileged spec says, “When SXLEN=64, all satp encodings corresponding to MODE=Bare are reserved for future standard use.” Based on that analogy, a better approach is to let ext_smmpt constrain the legal mmpt settings: * Keep mmpt under ext_smsdid (CSR presence/decoding). * Make mmpt WARL: when ext_smmpt is absent, only MODE=Bare is legal and SDID remains readable/writable; writes to other fields are masked to zero and reads return zero. * When ext_smmpt is present, enable the full mmpt mode set and fields. Concretely, I can: * Keep read_mmpt/write_mmpt gated by ext_smsdid, and * Add an access mask that depends on ext_smmpt as above (non-Bare modes are WARL-masked when ext_smmpt=0), with a comment referencing the spec. If that sounds good, I’ll update this patch accordingly. Thanks, Zhiwei > > > Thanks, > > Daniel > >> #endif /* !CONFIG_USER_ONLY */ >> }; >
© 2016 - 2025 Red Hat, Inc.