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;
|
||||
#endif
|
||||
|
||||
/* on reset elp is clear */
|
||||
env->elp = false;
|
||||
|
||||
env->xl = riscv_cpu_mxl(env);
|
||||
riscv_cpu_update_mask(env);
|
||||
cs->exception_index = RISCV_EXCP_NONE;
|
||||
|
@ -230,6 +230,8 @@ struct CPUArchState {
|
||||
|
||||
target_ulong jvt;
|
||||
|
||||
/* elp state for zicfilp extension */
|
||||
bool elp;
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
uint32_t elf_flags;
|
||||
#endif
|
||||
|
@ -552,6 +552,8 @@
|
||||
#define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */
|
||||
#define MSTATUS_TW 0x00200000 /* 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_MPV 0x8000000000ULL
|
||||
|
||||
@ -582,6 +584,7 @@ typedef enum {
|
||||
#define SSTATUS_XS 0x00018000
|
||||
#define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */
|
||||
#define SSTATUS_MXR 0x00080000
|
||||
#define SSTATUS_SPELP MSTATUS_SPELP /* zicfilp */
|
||||
|
||||
#define SSTATUS64_UXL 0x0000000300000000ULL
|
||||
|
||||
@ -754,6 +757,7 @@ typedef enum RISCVException {
|
||||
|
||||
/* Execution environment configuration bits */
|
||||
#define MENVCFG_FIOM BIT(0)
|
||||
#define MENVCFG_LPE BIT(2) /* zicfilp */
|
||||
#define MENVCFG_CBIE (3UL << 4)
|
||||
#define MENVCFG_CBCFE BIT(6)
|
||||
#define MENVCFG_CBZE BIT(7)
|
||||
@ -767,11 +771,13 @@ typedef enum RISCVException {
|
||||
#define MENVCFGH_STCE BIT(31)
|
||||
|
||||
#define SENVCFG_FIOM MENVCFG_FIOM
|
||||
#define SENVCFG_LPE MENVCFG_LPE
|
||||
#define SENVCFG_CBIE MENVCFG_CBIE
|
||||
#define SENVCFG_CBCFE MENVCFG_CBCFE
|
||||
#define SENVCFG_CBZE MENVCFG_CBZE
|
||||
|
||||
#define HENVCFG_FIOM MENVCFG_FIOM
|
||||
#define HENVCFG_LPE MENVCFG_LPE
|
||||
#define HENVCFG_CBIE MENVCFG_CBIE
|
||||
#define HENVCFG_CBCFE MENVCFG_CBCFE
|
||||
#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);
|
||||
|
||||
env->mstatus = mstatus;
|
||||
@ -2344,6 +2349,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
|
||||
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
|
||||
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
|
||||
(cfg->ext_svadu ? MENVCFG_ADUE : 0);
|
||||
|
||||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= MENVCFG_LPE;
|
||||
}
|
||||
}
|
||||
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
|
||||
|
||||
@ -2396,6 +2405,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= SENVCFG_LPE;
|
||||
}
|
||||
|
||||
env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
@ -2433,6 +2446,10 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
||||
|
||||
if (riscv_cpu_mxl(env) == MXL_RV64) {
|
||||
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);
|
||||
@ -2897,6 +2914,10 @@ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
|
||||
mask |= SSTATUS64_UXL;
|
||||
}
|
||||
|
||||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= SSTATUS_SPELP;
|
||||
}
|
||||
|
||||
*val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
@ -2908,6 +2929,11 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
|
||||
if (env->xl != MXL_RV32 || env->debugger) {
|
||||
mask |= SSTATUS64_UXL;
|
||||
}
|
||||
|
||||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= SSTATUS_SPELP;
|
||||
}
|
||||
|
||||
/* TODO: Use SXL not MXL. */
|
||||
*val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
|
||||
return RISCV_EXCP_NONE;
|
||||
@ -2923,6 +2949,11 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
|
||||
mask |= SSTATUS64_UXL;
|
||||
}
|
||||
}
|
||||
|
||||
if (env_archcpu(env)->cfg.ext_zicfilp) {
|
||||
mask |= SSTATUS_SPELP;
|
||||
}
|
||||
|
||||
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
|
||||
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 = {
|
||||
.name = "cpu",
|
||||
.version_id = 10,
|
||||
@ -422,6 +440,7 @@ const VMStateDescription vmstate_riscv_cpu = {
|
||||
&vmstate_debug,
|
||||
&vmstate_smstateen,
|
||||
&vmstate_jvt,
|
||||
&vmstate_elp,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
@ -598,6 +598,11 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,8 @@ typedef enum {
|
||||
MSECCFG_MMWP = 1 << 1,
|
||||
MSECCFG_RLB = 1 << 2,
|
||||
MSECCFG_USEED = 1 << 8,
|
||||
MSECCFG_SSEED = 1 << 9
|
||||
MSECCFG_SSEED = 1 << 9,
|
||||
MSECCFG_MLPE = 1 << 10,
|
||||
} mseccfg_field_t;
|
||||
|
||||
typedef struct {
|
||||
|
Loading…
Reference in New Issue
Block a user