mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
target/riscv: Add Ssdbltrp CSRs handling
Add ext_ssdbltrp in RISCVCPUConfig and implement MSTATUS.SDT, {H|M}ENVCFG.DTE and modify the availability of MTVAL2 based on the presence of the Ssdbltrp ISA extension. Signed-off-by: Clément Léger <cleger@rivosinc.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20250110125441.3208676-3-cleger@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
507957eb2a
commit
0aadf8162a
5 changed files with 84 additions and 12 deletions
|
@ -564,6 +564,7 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
|
|||
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch);
|
||||
bool cpu_get_fcfien(CPURISCVState *env);
|
||||
bool cpu_get_bcfien(CPURISCVState *env);
|
||||
bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt);
|
||||
G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
|
||||
MMUAccessType access_type,
|
||||
int mmu_idx, uintptr_t retaddr);
|
||||
|
|
|
@ -555,6 +555,7 @@
|
|||
#define MSTATUS_TW 0x00200000 /* since: priv-1.10 */
|
||||
#define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */
|
||||
#define MSTATUS_SPELP 0x00800000 /* zicfilp */
|
||||
#define MSTATUS_SDT 0x01000000
|
||||
#define MSTATUS_MPELP 0x020000000000 /* zicfilp */
|
||||
#define MSTATUS_GVA 0x4000000000ULL
|
||||
#define MSTATUS_MPV 0x8000000000ULL
|
||||
|
@ -587,6 +588,7 @@ typedef enum {
|
|||
#define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */
|
||||
#define SSTATUS_MXR 0x00080000
|
||||
#define SSTATUS_SPELP MSTATUS_SPELP /* zicfilp */
|
||||
#define SSTATUS_SDT MSTATUS_SDT
|
||||
|
||||
#define SSTATUS64_UXL 0x0000000300000000ULL
|
||||
|
||||
|
@ -782,12 +784,14 @@ typedef enum RISCVException {
|
|||
#define MENVCFG_CBCFE BIT(6)
|
||||
#define MENVCFG_CBZE BIT(7)
|
||||
#define MENVCFG_PMM (3ULL << 32)
|
||||
#define MENVCFG_DTE (1ULL << 59)
|
||||
#define MENVCFG_CDE (1ULL << 60)
|
||||
#define MENVCFG_ADUE (1ULL << 61)
|
||||
#define MENVCFG_PBMTE (1ULL << 62)
|
||||
#define MENVCFG_STCE (1ULL << 63)
|
||||
|
||||
/* For RV32 */
|
||||
#define MENVCFGH_DTE BIT(27)
|
||||
#define MENVCFGH_ADUE BIT(29)
|
||||
#define MENVCFGH_PBMTE BIT(30)
|
||||
#define MENVCFGH_STCE BIT(31)
|
||||
|
@ -808,11 +812,13 @@ typedef enum RISCVException {
|
|||
#define HENVCFG_CBCFE MENVCFG_CBCFE
|
||||
#define HENVCFG_CBZE MENVCFG_CBZE
|
||||
#define HENVCFG_PMM MENVCFG_PMM
|
||||
#define HENVCFG_DTE MENVCFG_DTE
|
||||
#define HENVCFG_ADUE MENVCFG_ADUE
|
||||
#define HENVCFG_PBMTE MENVCFG_PBMTE
|
||||
#define HENVCFG_STCE MENVCFG_STCE
|
||||
|
||||
/* For RV32 */
|
||||
#define HENVCFGH_DTE MENVCFGH_DTE
|
||||
#define HENVCFGH_ADUE MENVCFGH_ADUE
|
||||
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
|
||||
#define HENVCFGH_STCE MENVCFGH_STCE
|
||||
|
|
|
@ -83,6 +83,7 @@ struct RISCVCPUConfig {
|
|||
bool ext_smcntrpmf;
|
||||
bool ext_smcsrind;
|
||||
bool ext_sscsrind;
|
||||
bool ext_ssdbltrp;
|
||||
bool ext_svadu;
|
||||
bool ext_svinval;
|
||||
bool ext_svnapot;
|
||||
|
|
|
@ -120,6 +120,19 @@ bool cpu_get_bcfien(CPURISCVState *env)
|
|||
}
|
||||
}
|
||||
|
||||
bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return false;
|
||||
#else
|
||||
if (virt) {
|
||||
return (env->henvcfg & HENVCFG_DTE) != 0;
|
||||
} else {
|
||||
return (env->menvcfg & MENVCFG_DTE) != 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
|
||||
uint64_t *cs_base, uint32_t *pflags)
|
||||
{
|
||||
|
@ -691,6 +704,10 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
|
|||
|
||||
g_assert(riscv_has_ext(env, RVH));
|
||||
|
||||
if (riscv_env_smode_dbltrp_enabled(env, current_virt)) {
|
||||
mstatus_mask |= MSTATUS_SDT;
|
||||
}
|
||||
|
||||
if (current_virt) {
|
||||
/* Current V=1 and we are about to change to V=0 */
|
||||
env->vsstatus = env->mstatus & mstatus_mask;
|
||||
|
|
|
@ -680,6 +680,15 @@ static RISCVException aia_hmode32(CPURISCVState *env, int csrno)
|
|||
return hmode32(env, csrno);
|
||||
}
|
||||
|
||||
static RISCVException dbltrp_hmode(CPURISCVState *env, int csrno)
|
||||
{
|
||||
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
return hmode(env, csrno);
|
||||
}
|
||||
|
||||
static RISCVException pmp(CPURISCVState *env, int csrno)
|
||||
{
|
||||
if (riscv_cpu_cfg(env)->pmp) {
|
||||
|
@ -1938,6 +1947,13 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
|
|||
mask |= MSTATUS_VS;
|
||||
}
|
||||
|
||||
if (riscv_env_smode_dbltrp_enabled(env, env->virt_enabled)) {
|
||||
mask |= MSTATUS_SDT;
|
||||
if ((val & MSTATUS_SDT) != 0) {
|
||||
val &= ~MSTATUS_SIE;
|
||||
}
|
||||
}
|
||||
|
||||
if (xl != MXL_RV32 || env->debugger) {
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
mask |= MSTATUS_MPV | MSTATUS_GVA;
|
||||
|
@ -2959,7 +2975,8 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
|
|||
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
|
||||
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
|
||||
(cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
|
||||
(cfg->ext_svadu ? MENVCFG_ADUE : 0);
|
||||
(cfg->ext_svadu ? MENVCFG_ADUE : 0) |
|
||||
(cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
|
||||
|
||||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= MENVCFG_LPE;
|
||||
|
@ -2974,6 +2991,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
|
|||
get_field(val, MENVCFG_PMM) != PMM_FIELD_RESERVED) {
|
||||
mask |= MENVCFG_PMM;
|
||||
}
|
||||
|
||||
if ((val & MENVCFG_DTE) == 0) {
|
||||
env->mstatus &= ~MSTATUS_SDT;
|
||||
}
|
||||
}
|
||||
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
|
||||
write_henvcfg(env, CSR_HENVCFG, env->henvcfg);
|
||||
|
@ -2997,9 +3018,14 @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
|
|||
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
|
||||
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
|
||||
(cfg->ext_svadu ? MENVCFG_ADUE : 0) |
|
||||
(cfg->ext_smcdeleg ? MENVCFG_CDE : 0);
|
||||
(cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
|
||||
(cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
|
||||
uint64_t valh = (uint64_t)val << 32;
|
||||
|
||||
if ((valh & MENVCFG_DTE) == 0) {
|
||||
env->mstatus &= ~MSTATUS_SDT;
|
||||
}
|
||||
|
||||
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
|
||||
write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32);
|
||||
|
||||
|
@ -3070,9 +3096,10 @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
|
|||
* henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
|
||||
* henvcfg.stce is read_only 0 when menvcfg.stce = 0
|
||||
* henvcfg.adue is read_only 0 when menvcfg.adue = 0
|
||||
* henvcfg.dte is read_only 0 when menvcfg.dte = 0
|
||||
*/
|
||||
*val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
|
||||
env->menvcfg);
|
||||
*val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
|
||||
HENVCFG_DTE) | env->menvcfg);
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
|
@ -3088,7 +3115,8 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
|||
}
|
||||
|
||||
if (riscv_cpu_mxl(env) == MXL_RV64) {
|
||||
mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
|
||||
mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
|
||||
HENVCFG_DTE);
|
||||
|
||||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= HENVCFG_LPE;
|
||||
|
@ -3108,6 +3136,9 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
|||
}
|
||||
|
||||
env->henvcfg = val & mask;
|
||||
if ((env->henvcfg & HENVCFG_DTE) == 0) {
|
||||
env->vsstatus &= ~MSTATUS_SDT;
|
||||
}
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
@ -3122,8 +3153,8 @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
|
|||
return ret;
|
||||
}
|
||||
|
||||
*val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
|
||||
env->menvcfg)) >> 32;
|
||||
*val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
|
||||
HENVCFG_DTE) | env->menvcfg)) >> 32;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
|
@ -3131,7 +3162,7 @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
|
|||
target_ulong val)
|
||||
{
|
||||
uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
|
||||
HENVCFG_ADUE);
|
||||
HENVCFG_ADUE | HENVCFG_DTE);
|
||||
uint64_t valh = (uint64_t)val << 32;
|
||||
RISCVException ret;
|
||||
|
||||
|
@ -3139,8 +3170,10 @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
|
|||
if (ret != RISCV_EXCP_NONE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
env->henvcfg = (env->henvcfg & 0xFFFFFFFF) | (valh & mask);
|
||||
if ((env->henvcfg & HENVCFG_DTE) == 0) {
|
||||
env->vsstatus &= ~MSTATUS_SDT;
|
||||
}
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
|
@ -3594,6 +3627,9 @@ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
|
|||
if (env->xl != MXL_RV32 || env->debugger) {
|
||||
mask |= SSTATUS64_UXL;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
|
||||
mask |= SSTATUS_SDT;
|
||||
}
|
||||
|
||||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= SSTATUS_SPELP;
|
||||
|
@ -3614,7 +3650,9 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
|
|||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= SSTATUS_SPELP;
|
||||
}
|
||||
|
||||
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
|
||||
mask |= SSTATUS_SDT;
|
||||
}
|
||||
/* TODO: Use SXL not MXL. */
|
||||
*val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
|
||||
return RISCV_EXCP_NONE;
|
||||
|
@ -3634,7 +3672,9 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
|
|||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= SSTATUS_SPELP;
|
||||
}
|
||||
|
||||
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
|
||||
mask |= SSTATUS_SDT;
|
||||
}
|
||||
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
|
||||
return write_mstatus(env, CSR_MSTATUS, newval);
|
||||
}
|
||||
|
@ -4751,6 +4791,13 @@ static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
|
|||
if ((val & VSSTATUS64_UXL) == 0) {
|
||||
mask &= ~VSSTATUS64_UXL;
|
||||
}
|
||||
if ((env->henvcfg & HENVCFG_DTE)) {
|
||||
if ((val & SSTATUS_SDT) != 0) {
|
||||
val &= ~SSTATUS_SIE;
|
||||
}
|
||||
} else {
|
||||
val &= ~SSTATUS_SDT;
|
||||
}
|
||||
env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
@ -5698,7 +5745,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
|||
[CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
|
||||
.min_priv_ver = PRIV_VERSION_1_12_0 },
|
||||
|
||||
[CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
|
||||
[CSR_MTVAL2] = { "mtval2", dbltrp_hmode, read_mtval2, write_mtval2,
|
||||
.min_priv_ver = PRIV_VERSION_1_12_0 },
|
||||
[CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
|
||||
.min_priv_ver = PRIV_VERSION_1_12_0 },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue