Skip to content

Commit 0aadf81

Browse files
clementlegeralistair23
authored andcommitted
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 <[email protected]> Reviewed-by: Daniel Henrique Barboza <[email protected]> Reviewed-by: Alistair Francis <[email protected]> Message-ID: <[email protected]> Signed-off-by: Alistair Francis <[email protected]>
1 parent 507957e commit 0aadf81

File tree

5 files changed

+84
-12
lines changed

5 files changed

+84
-12
lines changed

target/riscv/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
564564
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch);
565565
bool cpu_get_fcfien(CPURISCVState *env);
566566
bool cpu_get_bcfien(CPURISCVState *env);
567+
bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt);
567568
G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
568569
MMUAccessType access_type,
569570
int mmu_idx, uintptr_t retaddr);

target/riscv/cpu_bits.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@
555555
#define MSTATUS_TW 0x00200000 /* since: priv-1.10 */
556556
#define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */
557557
#define MSTATUS_SPELP 0x00800000 /* zicfilp */
558+
#define MSTATUS_SDT 0x01000000
558559
#define MSTATUS_MPELP 0x020000000000 /* zicfilp */
559560
#define MSTATUS_GVA 0x4000000000ULL
560561
#define MSTATUS_MPV 0x8000000000ULL
@@ -587,6 +588,7 @@ typedef enum {
587588
#define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */
588589
#define SSTATUS_MXR 0x00080000
589590
#define SSTATUS_SPELP MSTATUS_SPELP /* zicfilp */
591+
#define SSTATUS_SDT MSTATUS_SDT
590592

591593
#define SSTATUS64_UXL 0x0000000300000000ULL
592594

@@ -782,12 +784,14 @@ typedef enum RISCVException {
782784
#define MENVCFG_CBCFE BIT(6)
783785
#define MENVCFG_CBZE BIT(7)
784786
#define MENVCFG_PMM (3ULL << 32)
787+
#define MENVCFG_DTE (1ULL << 59)
785788
#define MENVCFG_CDE (1ULL << 60)
786789
#define MENVCFG_ADUE (1ULL << 61)
787790
#define MENVCFG_PBMTE (1ULL << 62)
788791
#define MENVCFG_STCE (1ULL << 63)
789792

790793
/* For RV32 */
794+
#define MENVCFGH_DTE BIT(27)
791795
#define MENVCFGH_ADUE BIT(29)
792796
#define MENVCFGH_PBMTE BIT(30)
793797
#define MENVCFGH_STCE BIT(31)
@@ -808,11 +812,13 @@ typedef enum RISCVException {
808812
#define HENVCFG_CBCFE MENVCFG_CBCFE
809813
#define HENVCFG_CBZE MENVCFG_CBZE
810814
#define HENVCFG_PMM MENVCFG_PMM
815+
#define HENVCFG_DTE MENVCFG_DTE
811816
#define HENVCFG_ADUE MENVCFG_ADUE
812817
#define HENVCFG_PBMTE MENVCFG_PBMTE
813818
#define HENVCFG_STCE MENVCFG_STCE
814819

815820
/* For RV32 */
821+
#define HENVCFGH_DTE MENVCFGH_DTE
816822
#define HENVCFGH_ADUE MENVCFGH_ADUE
817823
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
818824
#define HENVCFGH_STCE MENVCFGH_STCE

target/riscv/cpu_cfg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct RISCVCPUConfig {
8383
bool ext_smcntrpmf;
8484
bool ext_smcsrind;
8585
bool ext_sscsrind;
86+
bool ext_ssdbltrp;
8687
bool ext_svadu;
8788
bool ext_svinval;
8889
bool ext_svnapot;

target/riscv/cpu_helper.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ bool cpu_get_bcfien(CPURISCVState *env)
120120
}
121121
}
122122

123+
bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt)
124+
{
125+
#ifdef CONFIG_USER_ONLY
126+
return false;
127+
#else
128+
if (virt) {
129+
return (env->henvcfg & HENVCFG_DTE) != 0;
130+
} else {
131+
return (env->menvcfg & MENVCFG_DTE) != 0;
132+
}
133+
#endif
134+
}
135+
123136
void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
124137
uint64_t *cs_base, uint32_t *pflags)
125138
{
@@ -691,6 +704,10 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
691704

692705
g_assert(riscv_has_ext(env, RVH));
693706

707+
if (riscv_env_smode_dbltrp_enabled(env, current_virt)) {
708+
mstatus_mask |= MSTATUS_SDT;
709+
}
710+
694711
if (current_virt) {
695712
/* Current V=1 and we are about to change to V=0 */
696713
env->vsstatus = env->mstatus & mstatus_mask;

target/riscv/csr.c

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,15 @@ static RISCVException aia_hmode32(CPURISCVState *env, int csrno)
680680
return hmode32(env, csrno);
681681
}
682682

683+
static RISCVException dbltrp_hmode(CPURISCVState *env, int csrno)
684+
{
685+
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
686+
return RISCV_EXCP_NONE;
687+
}
688+
689+
return hmode(env, csrno);
690+
}
691+
683692
static RISCVException pmp(CPURISCVState *env, int csrno)
684693
{
685694
if (riscv_cpu_cfg(env)->pmp) {
@@ -1938,6 +1947,13 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
19381947
mask |= MSTATUS_VS;
19391948
}
19401949

1950+
if (riscv_env_smode_dbltrp_enabled(env, env->virt_enabled)) {
1951+
mask |= MSTATUS_SDT;
1952+
if ((val & MSTATUS_SDT) != 0) {
1953+
val &= ~MSTATUS_SIE;
1954+
}
1955+
}
1956+
19411957
if (xl != MXL_RV32 || env->debugger) {
19421958
if (riscv_has_ext(env, RVH)) {
19431959
mask |= MSTATUS_MPV | MSTATUS_GVA;
@@ -2959,7 +2975,8 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
29592975
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
29602976
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
29612977
(cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
2962-
(cfg->ext_svadu ? MENVCFG_ADUE : 0);
2978+
(cfg->ext_svadu ? MENVCFG_ADUE : 0) |
2979+
(cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
29632980

29642981
if (env_archcpu(env)->cfg.ext_zicfilp) {
29652982
mask |= MENVCFG_LPE;
@@ -2973,6 +2990,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
29732990
if (env_archcpu(env)->cfg.ext_smnpm &&
29742991
get_field(val, MENVCFG_PMM) != PMM_FIELD_RESERVED) {
29752992
mask |= MENVCFG_PMM;
2993+
}
2994+
2995+
if ((val & MENVCFG_DTE) == 0) {
2996+
env->mstatus &= ~MSTATUS_SDT;
29762997
}
29772998
}
29782999
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
@@ -2997,9 +3018,14 @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
29973018
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
29983019
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
29993020
(cfg->ext_svadu ? MENVCFG_ADUE : 0) |
3000-
(cfg->ext_smcdeleg ? MENVCFG_CDE : 0);
3021+
(cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
3022+
(cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
30013023
uint64_t valh = (uint64_t)val << 32;
30023024

3025+
if ((valh & MENVCFG_DTE) == 0) {
3026+
env->mstatus &= ~MSTATUS_SDT;
3027+
}
3028+
30033029
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
30043030
write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32);
30053031

@@ -3070,9 +3096,10 @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
30703096
* henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
30713097
* henvcfg.stce is read_only 0 when menvcfg.stce = 0
30723098
* henvcfg.adue is read_only 0 when menvcfg.adue = 0
3099+
* henvcfg.dte is read_only 0 when menvcfg.dte = 0
30733100
*/
3074-
*val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
3075-
env->menvcfg);
3101+
*val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
3102+
HENVCFG_DTE) | env->menvcfg);
30763103
return RISCV_EXCP_NONE;
30773104
}
30783105

@@ -3088,7 +3115,8 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
30883115
}
30893116

30903117
if (riscv_cpu_mxl(env) == MXL_RV64) {
3091-
mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
3118+
mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
3119+
HENVCFG_DTE);
30923120

30933121
if (env_archcpu(env)->cfg.ext_zicfilp) {
30943122
mask |= HENVCFG_LPE;
@@ -3108,6 +3136,9 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
31083136
}
31093137

31103138
env->henvcfg = val & mask;
3139+
if ((env->henvcfg & HENVCFG_DTE) == 0) {
3140+
env->vsstatus &= ~MSTATUS_SDT;
3141+
}
31113142

31123143
return RISCV_EXCP_NONE;
31133144
}
@@ -3122,25 +3153,27 @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
31223153
return ret;
31233154
}
31243155

3125-
*val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
3126-
env->menvcfg)) >> 32;
3156+
*val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
3157+
HENVCFG_DTE) | env->menvcfg)) >> 32;
31273158
return RISCV_EXCP_NONE;
31283159
}
31293160

31303161
static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
31313162
target_ulong val)
31323163
{
31333164
uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
3134-
HENVCFG_ADUE);
3165+
HENVCFG_ADUE | HENVCFG_DTE);
31353166
uint64_t valh = (uint64_t)val << 32;
31363167
RISCVException ret;
31373168

31383169
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
31393170
if (ret != RISCV_EXCP_NONE) {
31403171
return ret;
31413172
}
3142-
31433173
env->henvcfg = (env->henvcfg & 0xFFFFFFFF) | (valh & mask);
3174+
if ((env->henvcfg & HENVCFG_DTE) == 0) {
3175+
env->vsstatus &= ~MSTATUS_SDT;
3176+
}
31443177
return RISCV_EXCP_NONE;
31453178
}
31463179

@@ -3594,6 +3627,9 @@ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
35943627
if (env->xl != MXL_RV32 || env->debugger) {
35953628
mask |= SSTATUS64_UXL;
35963629
}
3630+
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
3631+
mask |= SSTATUS_SDT;
3632+
}
35973633

35983634
if (env_archcpu(env)->cfg.ext_zicfilp) {
35993635
mask |= SSTATUS_SPELP;
@@ -3614,7 +3650,9 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
36143650
if (env_archcpu(env)->cfg.ext_zicfilp) {
36153651
mask |= SSTATUS_SPELP;
36163652
}
3617-
3653+
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
3654+
mask |= SSTATUS_SDT;
3655+
}
36183656
/* TODO: Use SXL not MXL. */
36193657
*val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
36203658
return RISCV_EXCP_NONE;
@@ -3634,7 +3672,9 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
36343672
if (env_archcpu(env)->cfg.ext_zicfilp) {
36353673
mask |= SSTATUS_SPELP;
36363674
}
3637-
3675+
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
3676+
mask |= SSTATUS_SDT;
3677+
}
36383678
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
36393679
return write_mstatus(env, CSR_MSTATUS, newval);
36403680
}
@@ -4751,6 +4791,13 @@ static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
47514791
if ((val & VSSTATUS64_UXL) == 0) {
47524792
mask &= ~VSSTATUS64_UXL;
47534793
}
4794+
if ((env->henvcfg & HENVCFG_DTE)) {
4795+
if ((val & SSTATUS_SDT) != 0) {
4796+
val &= ~SSTATUS_SIE;
4797+
}
4798+
} else {
4799+
val &= ~SSTATUS_SDT;
4800+
}
47544801
env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
47554802
return RISCV_EXCP_NONE;
47564803
}
@@ -5698,7 +5745,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
56985745
[CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
56995746
.min_priv_ver = PRIV_VERSION_1_12_0 },
57005747

5701-
[CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
5748+
[CSR_MTVAL2] = { "mtval2", dbltrp_hmode, read_mtval2, write_mtval2,
57025749
.min_priv_ver = PRIV_VERSION_1_12_0 },
57035750
[CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
57045751
.min_priv_ver = PRIV_VERSION_1_12_0 },

0 commit comments

Comments
 (0)