target/riscv: Add *envcfg* CSRs support
The RISC-V privileged specification v1.12 defines few execution environment configuration CSRs that can be used enable/disable extensions per privilege levels. Add the basic support for these CSRs. Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Atish Patra <atishp@rivosinc.com> Message-Id: <20220303185440.512391-6-atishp@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
3e6a417c8a
commit
29a9ec9bd8
@ -304,6 +304,11 @@ struct CPUArchState {
|
||||
target_ulong spmbase;
|
||||
target_ulong upmmask;
|
||||
target_ulong upmbase;
|
||||
|
||||
/* CSRs for execution enviornment configuration */
|
||||
uint64_t menvcfg;
|
||||
target_ulong senvcfg;
|
||||
uint64_t henvcfg;
|
||||
#endif
|
||||
target_ulong cur_pmmask;
|
||||
target_ulong cur_pmbase;
|
||||
|
@ -202,6 +202,9 @@
|
||||
#define CSR_STVEC 0x105
|
||||
#define CSR_SCOUNTEREN 0x106
|
||||
|
||||
/* Supervisor Configuration CSRs */
|
||||
#define CSR_SENVCFG 0x10A
|
||||
|
||||
/* Supervisor Trap Handling */
|
||||
#define CSR_SSCRATCH 0x140
|
||||
#define CSR_SEPC 0x141
|
||||
@ -247,6 +250,10 @@
|
||||
#define CSR_HTIMEDELTA 0x605
|
||||
#define CSR_HTIMEDELTAH 0x615
|
||||
|
||||
/* Hypervisor Configuration CSRs */
|
||||
#define CSR_HENVCFG 0x60A
|
||||
#define CSR_HENVCFGH 0x61A
|
||||
|
||||
/* Virtual CSRs */
|
||||
#define CSR_VSSTATUS 0x200
|
||||
#define CSR_VSIE 0x204
|
||||
@ -290,6 +297,10 @@
|
||||
#define CSR_VSIEH 0x214
|
||||
#define CSR_VSIPH 0x254
|
||||
|
||||
/* Machine Configuration CSRs */
|
||||
#define CSR_MENVCFG 0x30A
|
||||
#define CSR_MENVCFGH 0x31A
|
||||
|
||||
/* Enhanced Physical Memory Protection (ePMP) */
|
||||
#define CSR_MSECCFG 0x747
|
||||
#define CSR_MSECCFGH 0x757
|
||||
@ -663,6 +674,34 @@ typedef enum RISCVException {
|
||||
#define PM_EXT_CLEAN 0x00000002ULL
|
||||
#define PM_EXT_DIRTY 0x00000003ULL
|
||||
|
||||
/* Execution enviornment configuration bits */
|
||||
#define MENVCFG_FIOM BIT(0)
|
||||
#define MENVCFG_CBIE (3UL << 4)
|
||||
#define MENVCFG_CBCFE BIT(6)
|
||||
#define MENVCFG_CBZE BIT(7)
|
||||
#define MENVCFG_PBMTE (1ULL << 62)
|
||||
#define MENVCFG_STCE (1ULL << 63)
|
||||
|
||||
/* For RV32 */
|
||||
#define MENVCFGH_PBMTE BIT(30)
|
||||
#define MENVCFGH_STCE BIT(31)
|
||||
|
||||
#define SENVCFG_FIOM MENVCFG_FIOM
|
||||
#define SENVCFG_CBIE MENVCFG_CBIE
|
||||
#define SENVCFG_CBCFE MENVCFG_CBCFE
|
||||
#define SENVCFG_CBZE MENVCFG_CBZE
|
||||
|
||||
#define HENVCFG_FIOM MENVCFG_FIOM
|
||||
#define HENVCFG_CBIE MENVCFG_CBIE
|
||||
#define HENVCFG_CBCFE MENVCFG_CBCFE
|
||||
#define HENVCFG_CBZE MENVCFG_CBZE
|
||||
#define HENVCFG_PBMTE MENVCFG_PBMTE
|
||||
#define HENVCFG_STCE MENVCFG_STCE
|
||||
|
||||
/* For RV32 */
|
||||
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
|
||||
#define HENVCFGH_STCE MENVCFGH_STCE
|
||||
|
||||
/* Offsets for every pair of control bits per each priv level */
|
||||
#define XS_OFFSET 0ULL
|
||||
#define U_OFFSET 2ULL
|
||||
|
@ -1398,6 +1398,101 @@ static RISCVException write_mtval(CPURISCVState *env, int csrno,
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
/* Execution environment configuration setup */
|
||||
static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
*val = env->menvcfg;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
|
||||
|
||||
if (riscv_cpu_mxl(env) == MXL_RV64) {
|
||||
mask |= MENVCFG_PBMTE | MENVCFG_STCE;
|
||||
}
|
||||
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
*val = env->menvcfg >> 32;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE;
|
||||
uint64_t valh = (uint64_t)val << 32;
|
||||
|
||||
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
*val = env->senvcfg;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
|
||||
|
||||
env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
*val = env->henvcfg;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
|
||||
|
||||
if (riscv_cpu_mxl(env) == MXL_RV64) {
|
||||
mask |= HENVCFG_PBMTE | HENVCFG_STCE;
|
||||
}
|
||||
|
||||
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
*val = env->henvcfg >> 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 valh = (uint64_t)val << 32;
|
||||
|
||||
env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
|
||||
uint64_t *ret_val,
|
||||
uint64_t new_val, uint64_t wr_mask)
|
||||
@ -3158,6 +3253,18 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
||||
[CSR_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore },
|
||||
[CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
|
||||
|
||||
/* Execution environment configuration */
|
||||
[CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg,
|
||||
.min_priv_ver = PRIV_VERSION_1_12_0 },
|
||||
[CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh,
|
||||
.min_priv_ver = PRIV_VERSION_1_12_0 },
|
||||
[CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
|
||||
.min_priv_ver = PRIV_VERSION_1_12_0 },
|
||||
[CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg,
|
||||
.min_priv_ver = PRIV_VERSION_1_12_0 },
|
||||
[CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
|
||||
.min_priv_ver = PRIV_VERSION_1_12_0 },
|
||||
|
||||
/* Supervisor Trap Setup */
|
||||
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
|
||||
read_sstatus_i128 },
|
||||
|
@ -231,6 +231,28 @@ static int riscv_cpu_post_load(void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool envcfg_needed(void *opaque)
|
||||
{
|
||||
RISCVCPU *cpu = opaque;
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
return (env->priv_ver >= PRIV_VERSION_1_12_0 ? 1 : 0);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_envcfg = {
|
||||
.name = "cpu/envcfg",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = envcfg_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(env.menvcfg, RISCVCPU),
|
||||
VMSTATE_UINTTL(env.senvcfg, RISCVCPU),
|
||||
VMSTATE_UINT64(env.henvcfg, RISCVCPU),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
const VMStateDescription vmstate_riscv_cpu = {
|
||||
.name = "cpu",
|
||||
.version_id = 3,
|
||||
@ -292,6 +314,7 @@ const VMStateDescription vmstate_riscv_cpu = {
|
||||
&vmstate_pointermasking,
|
||||
&vmstate_rv128,
|
||||
&vmstate_kvmtimer,
|
||||
&vmstate_envcfg,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user