mirror of https://github.com/xemu-project/xemu.git
target/riscv: Introduce elp state and enabling controls for zicfilp
zicfilp introduces a new state elp ("expected landing pad") in cpu. During normal execution, elp is idle (NO_LP_EXPECTED) i.e not expecting landing pad. On an indirect call, elp moves LP_EXPECTED. When elp is LP_EXPECTED, only a subsquent landing pad instruction can set state back to NO_LP_EXPECTED. On reset, elp is set to NO_LP_EXPECTED. zicfilp is enabled via bit2 in *envcfg CSRs. Enabling control for M-mode is in mseccfg CSR at bit position 10. On trap, elp state is saved away in *status. Adds elp to the migration state as well. Signed-off-by: Deepak Gupta <debug@rivosinc.com> Co-developed-by: Jim Shu <jim.shu@sifive.com> Co-developed-by: Andy Chiu <andy.chiu@sifive.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20241008225010.1861630-4-debug@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
bd08b22e56
commit
4923f672e3
|
@ -1011,6 +1011,9 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
|
||||||
env->menvcfg = 0;
|
env->menvcfg = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* on reset elp is clear */
|
||||||
|
env->elp = false;
|
||||||
|
|
||||||
env->xl = riscv_cpu_mxl(env);
|
env->xl = riscv_cpu_mxl(env);
|
||||||
riscv_cpu_update_mask(env);
|
riscv_cpu_update_mask(env);
|
||||||
cs->exception_index = RISCV_EXCP_NONE;
|
cs->exception_index = RISCV_EXCP_NONE;
|
||||||
|
|
|
@ -230,6 +230,8 @@ struct CPUArchState {
|
||||||
|
|
||||||
target_ulong jvt;
|
target_ulong jvt;
|
||||||
|
|
||||||
|
/* elp state for zicfilp extension */
|
||||||
|
bool elp;
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
uint32_t elf_flags;
|
uint32_t elf_flags;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -552,6 +552,8 @@
|
||||||
#define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */
|
#define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */
|
||||||
#define MSTATUS_TW 0x00200000 /* since: priv-1.10 */
|
#define MSTATUS_TW 0x00200000 /* since: priv-1.10 */
|
||||||
#define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */
|
#define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */
|
||||||
|
#define MSTATUS_SPELP 0x00800000 /* zicfilp */
|
||||||
|
#define MSTATUS_MPELP 0x020000000000 /* zicfilp */
|
||||||
#define MSTATUS_GVA 0x4000000000ULL
|
#define MSTATUS_GVA 0x4000000000ULL
|
||||||
#define MSTATUS_MPV 0x8000000000ULL
|
#define MSTATUS_MPV 0x8000000000ULL
|
||||||
|
|
||||||
|
@ -582,6 +584,7 @@ typedef enum {
|
||||||
#define SSTATUS_XS 0x00018000
|
#define SSTATUS_XS 0x00018000
|
||||||
#define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */
|
#define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */
|
||||||
#define SSTATUS_MXR 0x00080000
|
#define SSTATUS_MXR 0x00080000
|
||||||
|
#define SSTATUS_SPELP MSTATUS_SPELP /* zicfilp */
|
||||||
|
|
||||||
#define SSTATUS64_UXL 0x0000000300000000ULL
|
#define SSTATUS64_UXL 0x0000000300000000ULL
|
||||||
|
|
||||||
|
@ -754,6 +757,7 @@ typedef enum RISCVException {
|
||||||
|
|
||||||
/* Execution environment configuration bits */
|
/* Execution environment configuration bits */
|
||||||
#define MENVCFG_FIOM BIT(0)
|
#define MENVCFG_FIOM BIT(0)
|
||||||
|
#define MENVCFG_LPE BIT(2) /* zicfilp */
|
||||||
#define MENVCFG_CBIE (3UL << 4)
|
#define MENVCFG_CBIE (3UL << 4)
|
||||||
#define MENVCFG_CBCFE BIT(6)
|
#define MENVCFG_CBCFE BIT(6)
|
||||||
#define MENVCFG_CBZE BIT(7)
|
#define MENVCFG_CBZE BIT(7)
|
||||||
|
@ -767,11 +771,13 @@ typedef enum RISCVException {
|
||||||
#define MENVCFGH_STCE BIT(31)
|
#define MENVCFGH_STCE BIT(31)
|
||||||
|
|
||||||
#define SENVCFG_FIOM MENVCFG_FIOM
|
#define SENVCFG_FIOM MENVCFG_FIOM
|
||||||
|
#define SENVCFG_LPE MENVCFG_LPE
|
||||||
#define SENVCFG_CBIE MENVCFG_CBIE
|
#define SENVCFG_CBIE MENVCFG_CBIE
|
||||||
#define SENVCFG_CBCFE MENVCFG_CBCFE
|
#define SENVCFG_CBCFE MENVCFG_CBCFE
|
||||||
#define SENVCFG_CBZE MENVCFG_CBZE
|
#define SENVCFG_CBZE MENVCFG_CBZE
|
||||||
|
|
||||||
#define HENVCFG_FIOM MENVCFG_FIOM
|
#define HENVCFG_FIOM MENVCFG_FIOM
|
||||||
|
#define HENVCFG_LPE MENVCFG_LPE
|
||||||
#define HENVCFG_CBIE MENVCFG_CBIE
|
#define HENVCFG_CBIE MENVCFG_CBIE
|
||||||
#define HENVCFG_CBCFE MENVCFG_CBCFE
|
#define HENVCFG_CBCFE MENVCFG_CBCFE
|
||||||
#define HENVCFG_CBZE MENVCFG_CBZE
|
#define HENVCFG_CBZE MENVCFG_CBZE
|
||||||
|
|
|
@ -1598,6 +1598,11 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If cfi lp extension is available, then apply cfi lp mask */
|
||||||
|
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||||
|
mask |= (MSTATUS_MPELP | MSTATUS_SPELP);
|
||||||
|
}
|
||||||
|
|
||||||
mstatus = (mstatus & ~mask) | (val & mask);
|
mstatus = (mstatus & ~mask) | (val & mask);
|
||||||
|
|
||||||
env->mstatus = mstatus;
|
env->mstatus = mstatus;
|
||||||
|
@ -2344,6 +2349,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
|
||||||
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
|
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
|
||||||
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
|
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
|
||||||
(cfg->ext_svadu ? MENVCFG_ADUE : 0);
|
(cfg->ext_svadu ? MENVCFG_ADUE : 0);
|
||||||
|
|
||||||
|
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||||
|
mask |= MENVCFG_LPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
|
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
|
||||||
|
|
||||||
|
@ -2396,6 +2405,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||||
|
mask |= SENVCFG_LPE;
|
||||||
|
}
|
||||||
|
|
||||||
env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
|
env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
|
||||||
return RISCV_EXCP_NONE;
|
return RISCV_EXCP_NONE;
|
||||||
}
|
}
|
||||||
|
@ -2433,6 +2446,10 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
||||||
|
|
||||||
if (riscv_cpu_mxl(env) == MXL_RV64) {
|
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);
|
||||||
|
|
||||||
|
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||||
|
mask |= HENVCFG_LPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
|
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
|
||||||
|
@ -2897,6 +2914,10 @@ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
|
||||||
mask |= SSTATUS64_UXL;
|
mask |= SSTATUS64_UXL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||||
|
mask |= SSTATUS_SPELP;
|
||||||
|
}
|
||||||
|
|
||||||
*val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
|
*val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
|
||||||
return RISCV_EXCP_NONE;
|
return RISCV_EXCP_NONE;
|
||||||
}
|
}
|
||||||
|
@ -2908,6 +2929,11 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
|
||||||
if (env->xl != MXL_RV32 || env->debugger) {
|
if (env->xl != MXL_RV32 || env->debugger) {
|
||||||
mask |= SSTATUS64_UXL;
|
mask |= SSTATUS64_UXL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||||
|
mask |= SSTATUS_SPELP;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Use SXL not MXL. */
|
/* TODO: Use SXL not MXL. */
|
||||||
*val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
|
*val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
|
||||||
return RISCV_EXCP_NONE;
|
return RISCV_EXCP_NONE;
|
||||||
|
@ -2923,6 +2949,11 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
|
||||||
mask |= SSTATUS64_UXL;
|
mask |= SSTATUS64_UXL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||||
|
mask |= SSTATUS_SPELP;
|
||||||
|
}
|
||||||
|
|
||||||
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
|
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
|
||||||
return write_mstatus(env, CSR_MSTATUS, newval);
|
return write_mstatus(env, CSR_MSTATUS, newval);
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,6 +350,24 @@ static const VMStateDescription vmstate_jvt = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool elp_needed(void *opaque)
|
||||||
|
{
|
||||||
|
RISCVCPU *cpu = opaque;
|
||||||
|
|
||||||
|
return cpu->cfg.ext_zicfilp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_elp = {
|
||||||
|
.name = "cpu/elp",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.needed = elp_needed,
|
||||||
|
.fields = (const VMStateField[]) {
|
||||||
|
VMSTATE_BOOL(env.elp, RISCVCPU),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const VMStateDescription vmstate_riscv_cpu = {
|
const VMStateDescription vmstate_riscv_cpu = {
|
||||||
.name = "cpu",
|
.name = "cpu",
|
||||||
.version_id = 10,
|
.version_id = 10,
|
||||||
|
@ -422,6 +440,7 @@ const VMStateDescription vmstate_riscv_cpu = {
|
||||||
&vmstate_debug,
|
&vmstate_debug,
|
||||||
&vmstate_smstateen,
|
&vmstate_smstateen,
|
||||||
&vmstate_jvt,
|
&vmstate_jvt,
|
||||||
|
&vmstate_elp,
|
||||||
NULL
|
NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -598,6 +598,11 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
|
||||||
val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB);
|
val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* M-mode forward cfi to be enabled if cfi extension is implemented */
|
||||||
|
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||||
|
val |= (val & MSECCFG_MLPE);
|
||||||
|
}
|
||||||
|
|
||||||
env->mseccfg = val;
|
env->mseccfg = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ typedef enum {
|
||||||
MSECCFG_MMWP = 1 << 1,
|
MSECCFG_MMWP = 1 << 1,
|
||||||
MSECCFG_RLB = 1 << 2,
|
MSECCFG_RLB = 1 << 2,
|
||||||
MSECCFG_USEED = 1 << 8,
|
MSECCFG_USEED = 1 << 8,
|
||||||
MSECCFG_SSEED = 1 << 9
|
MSECCFG_SSEED = 1 << 9,
|
||||||
|
MSECCFG_MLPE = 1 << 10,
|
||||||
} mseccfg_field_t;
|
} mseccfg_field_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Reference in New Issue