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:
Atish Patra 2022-03-03 10:54:39 -08:00 committed by Alistair Francis
parent 3e6a417c8a
commit 29a9ec9bd8
4 changed files with 174 additions and 0 deletions

View file

@ -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 },