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 - 2026 Red Hat, Inc.