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 spmbase;
|
||||||
target_ulong upmmask;
|
target_ulong upmmask;
|
||||||
target_ulong upmbase;
|
target_ulong upmbase;
|
||||||
|
|
||||||
|
/* CSRs for execution enviornment configuration */
|
||||||
|
uint64_t menvcfg;
|
||||||
|
target_ulong senvcfg;
|
||||||
|
uint64_t henvcfg;
|
||||||
#endif
|
#endif
|
||||||
target_ulong cur_pmmask;
|
target_ulong cur_pmmask;
|
||||||
target_ulong cur_pmbase;
|
target_ulong cur_pmbase;
|
||||||
|
@ -202,6 +202,9 @@
|
|||||||
#define CSR_STVEC 0x105
|
#define CSR_STVEC 0x105
|
||||||
#define CSR_SCOUNTEREN 0x106
|
#define CSR_SCOUNTEREN 0x106
|
||||||
|
|
||||||
|
/* Supervisor Configuration CSRs */
|
||||||
|
#define CSR_SENVCFG 0x10A
|
||||||
|
|
||||||
/* Supervisor Trap Handling */
|
/* Supervisor Trap Handling */
|
||||||
#define CSR_SSCRATCH 0x140
|
#define CSR_SSCRATCH 0x140
|
||||||
#define CSR_SEPC 0x141
|
#define CSR_SEPC 0x141
|
||||||
@ -247,6 +250,10 @@
|
|||||||
#define CSR_HTIMEDELTA 0x605
|
#define CSR_HTIMEDELTA 0x605
|
||||||
#define CSR_HTIMEDELTAH 0x615
|
#define CSR_HTIMEDELTAH 0x615
|
||||||
|
|
||||||
|
/* Hypervisor Configuration CSRs */
|
||||||
|
#define CSR_HENVCFG 0x60A
|
||||||
|
#define CSR_HENVCFGH 0x61A
|
||||||
|
|
||||||
/* Virtual CSRs */
|
/* Virtual CSRs */
|
||||||
#define CSR_VSSTATUS 0x200
|
#define CSR_VSSTATUS 0x200
|
||||||
#define CSR_VSIE 0x204
|
#define CSR_VSIE 0x204
|
||||||
@ -290,6 +297,10 @@
|
|||||||
#define CSR_VSIEH 0x214
|
#define CSR_VSIEH 0x214
|
||||||
#define CSR_VSIPH 0x254
|
#define CSR_VSIPH 0x254
|
||||||
|
|
||||||
|
/* Machine Configuration CSRs */
|
||||||
|
#define CSR_MENVCFG 0x30A
|
||||||
|
#define CSR_MENVCFGH 0x31A
|
||||||
|
|
||||||
/* Enhanced Physical Memory Protection (ePMP) */
|
/* Enhanced Physical Memory Protection (ePMP) */
|
||||||
#define CSR_MSECCFG 0x747
|
#define CSR_MSECCFG 0x747
|
||||||
#define CSR_MSECCFGH 0x757
|
#define CSR_MSECCFGH 0x757
|
||||||
@ -663,6 +674,34 @@ typedef enum RISCVException {
|
|||||||
#define PM_EXT_CLEAN 0x00000002ULL
|
#define PM_EXT_CLEAN 0x00000002ULL
|
||||||
#define PM_EXT_DIRTY 0x00000003ULL
|
#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 */
|
/* Offsets for every pair of control bits per each priv level */
|
||||||
#define XS_OFFSET 0ULL
|
#define XS_OFFSET 0ULL
|
||||||
#define U_OFFSET 2ULL
|
#define U_OFFSET 2ULL
|
||||||
|
@ -1398,6 +1398,101 @@ static RISCVException write_mtval(CPURISCVState *env, int csrno,
|
|||||||
return RISCV_EXCP_NONE;
|
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,
|
static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
|
||||||
uint64_t *ret_val,
|
uint64_t *ret_val,
|
||||||
uint64_t new_val, uint64_t wr_mask)
|
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_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore },
|
||||||
[CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
|
[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 */
|
/* Supervisor Trap Setup */
|
||||||
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
|
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
|
||||||
read_sstatus_i128 },
|
read_sstatus_i128 },
|
||||||
|
@ -231,6 +231,28 @@ static int riscv_cpu_post_load(void *opaque, int version_id)
|
|||||||
return 0;
|
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 = {
|
const VMStateDescription vmstate_riscv_cpu = {
|
||||||
.name = "cpu",
|
.name = "cpu",
|
||||||
.version_id = 3,
|
.version_id = 3,
|
||||||
@ -292,6 +314,7 @@ const VMStateDescription vmstate_riscv_cpu = {
|
|||||||
&vmstate_pointermasking,
|
&vmstate_pointermasking,
|
||||||
&vmstate_rv128,
|
&vmstate_rv128,
|
||||||
&vmstate_kvmtimer,
|
&vmstate_kvmtimer,
|
||||||
|
&vmstate_envcfg,
|
||||||
NULL
|
NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user