target: riscv: Add Svrsw60t59b extension support

The Svrsw60t59b extension allows to free the PTE reserved bits 60 and 59
for software to use.

Reviewed-by: Deepak Gupta <debug@rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Nutty Liu<liujingqi@lanxincomputing.com>
Message-ID: <20250702-dev-alex-svrsw60b59b_v2-v2-1-504ddf0f8530@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Alexandre Ghiti 2025-07-02 07:28:52 +00:00 committed by Alistair Francis
parent 5625817e8b
commit dc8bffc4eb
7 changed files with 18 additions and 3 deletions

View file

@ -79,6 +79,7 @@ struct riscv_iommu_pq_record {
#define RISCV_IOMMU_CAP_SV39 BIT_ULL(9)
#define RISCV_IOMMU_CAP_SV48 BIT_ULL(10)
#define RISCV_IOMMU_CAP_SV57 BIT_ULL(11)
#define RISCV_IOMMU_CAP_SVRSW60T59B BIT_ULL(14)
#define RISCV_IOMMU_CAP_SV32X4 BIT_ULL(16)
#define RISCV_IOMMU_CAP_SV39X4 BIT_ULL(17)
#define RISCV_IOMMU_CAP_SV48X4 BIT_ULL(18)

View file

@ -2351,7 +2351,8 @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp)
}
if (s->enable_g_stage) {
s->cap |= RISCV_IOMMU_CAP_SV32X4 | RISCV_IOMMU_CAP_SV39X4 |
RISCV_IOMMU_CAP_SV48X4 | RISCV_IOMMU_CAP_SV57X4;
RISCV_IOMMU_CAP_SV48X4 | RISCV_IOMMU_CAP_SV57X4 |
RISCV_IOMMU_CAP_SVRSW60T59B;
}
if (s->hpm_cntrs > 0) {

View file

@ -230,6 +230,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
ISA_EXT_DATA_ENTRY(svrsw60t59b, PRIV_VERSION_1_13_0, ext_svrsw60t59b),
ISA_EXT_DATA_ENTRY(svukte, PRIV_VERSION_1_13_0, ext_svukte),
ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
@ -1285,6 +1286,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
MULTI_EXT_CFG_BOOL("svinval", ext_svinval, false),
MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false),
MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false),
MULTI_EXT_CFG_BOOL("svrsw60t59b", ext_svrsw60t59b, false),
MULTI_EXT_CFG_BOOL("svvptc", ext_svvptc, true),
MULTI_EXT_CFG_BOOL("zicntr", ext_zicntr, true),

View file

@ -735,7 +735,8 @@ typedef enum {
#define PTE_SOFT 0x300 /* Reserved for Software */
#define PTE_PBMT 0x6000000000000000ULL /* Page-based memory types */
#define PTE_N 0x8000000000000000ULL /* NAPOT translation */
#define PTE_RESERVED 0x1FC0000000000000ULL /* Reserved bits */
#define PTE_RESERVED(svrsw60t59b) \
(svrsw60t59b ? 0x07C0000000000000ULL : 0x1FC0000000000000ULL) /* Reserved bits */
#define PTE_ATTR (PTE_N | PTE_PBMT) /* All attributes bits */
/* Page table PPN shift amount */

View file

@ -57,6 +57,7 @@ BOOL_FIELD(ext_svadu)
BOOL_FIELD(ext_svinval)
BOOL_FIELD(ext_svnapot)
BOOL_FIELD(ext_svpbmt)
BOOL_FIELD(ext_svrsw60t59b)
BOOL_FIELD(ext_svvptc)
BOOL_FIELD(ext_svukte)
BOOL_FIELD(ext_zdinx)

View file

@ -1309,6 +1309,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
bool svade = riscv_cpu_cfg(env)->ext_svade;
bool svadu = riscv_cpu_cfg(env)->ext_svadu;
bool adue = svadu ? env->menvcfg & MENVCFG_ADUE : !svade;
bool svrsw60t59b = riscv_cpu_cfg(env)->ext_svrsw60t59b;
if (first_stage && two_stage && env->virt_enabled) {
pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
@ -1376,7 +1377,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
if (riscv_cpu_sxl(env) == MXL_RV32) {
ppn = pte >> PTE_PPN_SHIFT;
} else {
if (pte & PTE_RESERVED) {
if (pte & PTE_RESERVED(svrsw60t59b)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: reserved bits set in PTE: "
"addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
__func__, pte_addr, pte);

View file

@ -839,6 +839,12 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
cpu->cfg.ext_ssctr = false;
}
if (cpu->cfg.ext_svrsw60t59b &&
(!cpu->cfg.mmu || mcc->def->misa_mxl_max == MXL_RV32)) {
error_setg(errp, "svrsw60t59b is not supported on RV32 and MMU-less platforms");
return;
}
/*
* Disable isa extensions based on priv spec after we
* validated and set everything we need.
@ -1588,6 +1594,8 @@ static void riscv_init_max_cpu_extensions(Object *obj)
if (env->misa_mxl != MXL_RV32) {
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcf), false);
} else {
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_svrsw60t59b), false);
}
/*