diff options
author | Palmer Dabbelt <palmer@rivosinc.com> | 2023-03-01 17:28:21 -0800 |
---|---|---|
committer | Palmer Dabbelt <palmer@rivosinc.com> | 2023-03-01 17:30:34 -0800 |
commit | 8e5aded3de88e9403bd95b152e2a5597b5d92895 (patch) | |
tree | a5c2033c47d2c44e5bd86c912ec1397ad9f90f05 | |
parent | fc9ec3625f6dee52811c8150af994abe3c1668a3 (diff) | |
parent | 62108f05e74ce6d2a07d79e9de8801f685d60453 (diff) | |
download | qemu-8e5aded3de88e9403bd95b152e2a5597b5d92895.zip qemu-8e5aded3de88e9403bd95b152e2a5597b5d92895.tar.gz qemu-8e5aded3de88e9403bd95b152e2a5597b5d92895.tar.bz2 |
Merge patch series "target/riscv: Add support for Svadu extension"
Weiwei Li <liweiwei@iscas.ac.cn> says:
This patchset adds support svadu extension. It also fixes some
relationship between *envcfg fields and Svpbmt/Sstc extensions.
Specification for Svadu extension can be found in:
https://github.com/riscv/riscv-svadu
* b4-shazam-merge:
target/riscv: Export Svadu property
target/riscv: Add *envcfg.HADE related check in address translation
target/riscv: Add *envcfg.PBMTE related check in address translation
target/riscv: Add csr support for svadu
target/riscv: Fix the relationship of PBMTE/STCE fields between menvcfg and henvcfg
target/riscv: Fix the relationship between menvcfg.PBMTE/STCE and Svpbmt/Sstc extensions
Message-ID: <20230224040852.37109-1-liweiwei@iscas.ac.cn>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-rw-r--r-- | target/riscv/cpu.c | 8 | ||||
-rw-r--r-- | target/riscv/cpu.h | 1 | ||||
-rw-r--r-- | target/riscv/cpu_bits.h | 4 | ||||
-rw-r--r-- | target/riscv/cpu_helper.c | 16 | ||||
-rw-r--r-- | target/riscv/csr.c | 26 |
5 files changed, 47 insertions, 8 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 3d41016..cac9f1d 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -111,6 +111,7 @@ static const struct isa_ext_data isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia), ISA_EXT_DATA_ENTRY(sscofpmf, true, PRIV_VERSION_1_12_0, ext_sscofpmf), ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc), + ISA_EXT_DATA_ENTRY(svadu, true, PRIV_VERSION_1_12_0, ext_svadu), ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt), @@ -617,6 +618,11 @@ static void riscv_cpu_reset_hold(Object *obj) env->bins = 0; env->two_stage_lookup = false; + env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) | + (cpu->cfg.ext_svadu ? MENVCFG_HADE : 0); + env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) | + (cpu->cfg.ext_svadu ? HENVCFG_HADE : 0); + /* Initialized default priorities of local interrupts. */ for (i = 0; i < ARRAY_SIZE(env->miprio); i++) { iprio = riscv_cpu_default_priority(i); @@ -1129,6 +1135,8 @@ static Property riscv_cpu_extensions[] = { DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), + DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true), + DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false), DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false), DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 30c75bf..665b4c6 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -438,6 +438,7 @@ struct RISCVCPUConfig { bool ext_zihintpause; bool ext_smstateen; bool ext_sstc; + bool ext_svadu; bool ext_svinval; bool ext_svnapot; bool ext_svpbmt; diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 8b0d7e2..fca7ef0 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -747,10 +747,12 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_HADE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) /* For RV32 */ +#define MENVCFGH_HADE BIT(29) #define MENVCFGH_PBMTE BIT(30) #define MENVCFGH_STCE BIT(31) @@ -763,10 +765,12 @@ typedef enum RISCVException { #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_HADE MENVCFG_HADE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE /* For RV32 */ +#define HENVCFGH_HADE MENVCFGH_HADE #define HENVCFGH_PBMTE MENVCFGH_PBMTE #define HENVCFGH_STCE MENVCFGH_STCE diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 16667a3..f88c503 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -936,9 +936,17 @@ restart: return TRANSLATE_FAIL; } + bool pbmte = env->menvcfg & MENVCFG_PBMTE; + bool hade = env->menvcfg & MENVCFG_HADE; + + if (first_stage && two_stage && riscv_cpu_virt_enabled(env)) { + pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE); + hade = hade && (env->henvcfg & HENVCFG_HADE); + } + if (riscv_cpu_sxl(env) == MXL_RV32) { ppn = pte >> PTE_PPN_SHIFT; - } else if (cpu->cfg.ext_svpbmt || cpu->cfg.ext_svnapot) { + } else if (pbmte || cpu->cfg.ext_svnapot) { ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT; } else { ppn = pte >> PTE_PPN_SHIFT; @@ -950,7 +958,7 @@ restart: if (!(pte & PTE_V)) { /* Invalid PTE */ return TRANSLATE_FAIL; - } else if (!cpu->cfg.ext_svpbmt && (pte & PTE_PBMT)) { + } else if (!pbmte && (pte & PTE_PBMT)) { return TRANSLATE_FAIL; } else if (!(pte & (PTE_R | PTE_W | PTE_X))) { /* Inner PTE, continue walking */ @@ -992,6 +1000,10 @@ restart: /* Page table updates need to be atomic with MTTCG enabled */ if (updated_pte != pte) { + if (!hade) { + return TRANSLATE_FAIL; + } + /* * - if accessed or dirty bits need updating, and the PTE is * in RAM, then we do so atomically with a compare and swap. diff --git a/target/riscv/csr.c b/target/riscv/csr.c index a2cf353..ee49b63 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1879,10 +1879,13 @@ static RISCVException read_menvcfg(CPURISCVState *env, int csrno, static RISCVException write_menvcfg(CPURISCVState *env, int csrno, target_ulong val) { + RISCVCPUConfig *cfg = &env_archcpu(env)->cfg; uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE; if (riscv_cpu_mxl(env) == MXL_RV64) { - mask |= MENVCFG_PBMTE | MENVCFG_STCE; + mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) | + (cfg->ext_sstc ? MENVCFG_STCE : 0) | + (cfg->ext_svadu ? MENVCFG_HADE : 0); } env->menvcfg = (env->menvcfg & ~mask) | (val & mask); @@ -1899,7 +1902,10 @@ static RISCVException read_menvcfgh(CPURISCVState *env, int csrno, static RISCVException write_menvcfgh(CPURISCVState *env, int csrno, target_ulong val) { - uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE; + RISCVCPUConfig *cfg = &env_archcpu(env)->cfg; + uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) | + (cfg->ext_sstc ? MENVCFG_STCE : 0) | + (cfg->ext_svadu ? MENVCFG_HADE : 0); uint64_t valh = (uint64_t)val << 32; env->menvcfg = (env->menvcfg & ~mask) | (valh & mask); @@ -1979,7 +1985,13 @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno, return ret; } - *val = env->henvcfg; + /* + * henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0 + * henvcfg.stce is read_only 0 when menvcfg.stce = 0 + * henvcfg.hade is read_only 0 when menvcfg.hade = 0 + */ + *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) | + env->menvcfg); return RISCV_EXCP_NONE; } @@ -1995,7 +2007,7 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno, } if (riscv_cpu_mxl(env) == MXL_RV64) { - mask |= HENVCFG_PBMTE | HENVCFG_STCE; + mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE); } env->henvcfg = (env->henvcfg & ~mask) | (val & mask); @@ -2013,14 +2025,16 @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno, return ret; } - *val = env->henvcfg >> 32; + *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) | + env->menvcfg)) >> 32; return RISCV_EXCP_NONE; } static RISCVException write_henvcfgh(CPURISCVState *env, int csrno, target_ulong val) { - uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE; + uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | + HENVCFG_HADE); uint64_t valh = (uint64_t)val << 32; RISCVException ret; |