mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v1.0
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20250106102346.1100149-3-baturo.alexey@gmail.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
37089cb8ad
commit
33ca99a111
6 changed files with 58 additions and 5 deletions
|
@ -128,6 +128,14 @@ typedef enum {
|
|||
EXT_STATUS_DIRTY,
|
||||
} RISCVExtStatus;
|
||||
|
||||
/* Enum holds PMM field values for Zjpm v1.0 extension */
|
||||
typedef enum {
|
||||
PMM_FIELD_DISABLED = 0,
|
||||
PMM_FIELD_RESERVED = 1,
|
||||
PMM_FIELD_PMLEN7 = 2,
|
||||
PMM_FIELD_PMLEN16 = 3,
|
||||
} RISCVPmPmm;
|
||||
|
||||
typedef struct riscv_cpu_implied_exts_rule {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/*
|
||||
|
|
|
@ -575,6 +575,7 @@ typedef enum {
|
|||
#define HSTATUS_VTSR 0x00400000
|
||||
#define HSTATUS_HUKTE 0x01000000
|
||||
#define HSTATUS_VSXL 0x300000000
|
||||
#define HSTATUS_HUPMM 0x3000000000000
|
||||
|
||||
#define HSTATUS32_WPRI 0xFF8FF87E
|
||||
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
|
||||
|
@ -735,6 +736,7 @@ typedef enum RISCVException {
|
|||
#define MENVCFG_CBIE (3UL << 4)
|
||||
#define MENVCFG_CBCFE BIT(6)
|
||||
#define MENVCFG_CBZE BIT(7)
|
||||
#define MENVCFG_PMM (3ULL << 32)
|
||||
#define MENVCFG_ADUE (1ULL << 61)
|
||||
#define MENVCFG_PBMTE (1ULL << 62)
|
||||
#define MENVCFG_STCE (1ULL << 63)
|
||||
|
@ -751,6 +753,7 @@ typedef enum RISCVException {
|
|||
#define SENVCFG_CBCFE MENVCFG_CBCFE
|
||||
#define SENVCFG_CBZE MENVCFG_CBZE
|
||||
#define SENVCFG_UKTE BIT(8)
|
||||
#define SENVCFG_PMM MENVCFG_PMM
|
||||
|
||||
#define HENVCFG_FIOM MENVCFG_FIOM
|
||||
#define HENVCFG_LPE MENVCFG_LPE
|
||||
|
@ -758,6 +761,7 @@ typedef enum RISCVException {
|
|||
#define HENVCFG_CBIE MENVCFG_CBIE
|
||||
#define HENVCFG_CBCFE MENVCFG_CBCFE
|
||||
#define HENVCFG_CBZE MENVCFG_CBZE
|
||||
#define HENVCFG_PMM MENVCFG_PMM
|
||||
#define HENVCFG_ADUE MENVCFG_ADUE
|
||||
#define HENVCFG_PBMTE MENVCFG_PBMTE
|
||||
#define HENVCFG_STCE MENVCFG_STCE
|
||||
|
|
|
@ -129,6 +129,9 @@ struct RISCVCPUConfig {
|
|||
bool ext_ssaia;
|
||||
bool ext_sscofpmf;
|
||||
bool ext_smepmp;
|
||||
bool ext_ssnpm;
|
||||
bool ext_smnpm;
|
||||
bool ext_smmpm;
|
||||
bool rvv_ta_all_1s;
|
||||
bool rvv_ma_all_1s;
|
||||
bool rvv_vl_half_avl;
|
||||
|
|
|
@ -575,6 +575,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno)
|
|||
if (riscv_cpu_cfg(env)->ext_zkr) {
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
if (riscv_cpu_cfg(env)->ext_smmpm) {
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
return RISCV_EXCP_ILLEGAL_INST;
|
||||
}
|
||||
|
@ -2379,6 +2382,12 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
|
|||
if (env_archcpu(env)->cfg.ext_zicfiss) {
|
||||
mask |= MENVCFG_SSE;
|
||||
}
|
||||
|
||||
/* Update PMM field only if the value is valid according to Zjpm v1.0 */
|
||||
if (env_archcpu(env)->cfg.ext_smnpm &&
|
||||
get_field(val, MENVCFG_PMM) != PMM_FIELD_RESERVED) {
|
||||
mask |= MENVCFG_PMM;
|
||||
}
|
||||
}
|
||||
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
|
||||
|
||||
|
@ -2425,6 +2434,12 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
|
|||
{
|
||||
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
|
||||
RISCVException ret;
|
||||
/* Update PMM field only if the value is valid according to Zjpm v1.0 */
|
||||
if (env_archcpu(env)->cfg.ext_ssnpm &&
|
||||
riscv_cpu_mxl(env) == MXL_RV64 &&
|
||||
get_field(val, SENVCFG_PMM) != PMM_FIELD_RESERVED) {
|
||||
mask |= SENVCFG_PMM;
|
||||
}
|
||||
|
||||
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
|
||||
if (ret != RISCV_EXCP_NONE) {
|
||||
|
@ -2493,6 +2508,12 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
|||
get_field(env->menvcfg, MENVCFG_SSE)) {
|
||||
mask |= HENVCFG_SSE;
|
||||
}
|
||||
|
||||
/* Update PMM field only if the value is valid according to Zjpm v1.0 */
|
||||
if (env_archcpu(env)->cfg.ext_ssnpm &&
|
||||
get_field(val, HENVCFG_PMM) != PMM_FIELD_RESERVED) {
|
||||
mask |= HENVCFG_PMM;
|
||||
}
|
||||
}
|
||||
|
||||
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
|
||||
|
@ -3529,10 +3550,18 @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno,
|
|||
static RISCVException write_hstatus(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
uint64_t mask = (target_ulong)-1;
|
||||
if (!env_archcpu(env)->cfg.ext_svukte) {
|
||||
val = val & (~HSTATUS_HUKTE);
|
||||
mask &= ~HSTATUS_HUKTE;
|
||||
}
|
||||
env->hstatus = val;
|
||||
/* Update PMM field only if the value is valid according to Zjpm v1.0 */
|
||||
if (!env_archcpu(env)->cfg.ext_ssnpm ||
|
||||
riscv_cpu_mxl(env) != MXL_RV64 ||
|
||||
get_field(val, HSTATUS_HUPMM) == PMM_FIELD_RESERVED) {
|
||||
mask &= ~HSTATUS_HUPMM;
|
||||
}
|
||||
env->hstatus = (env->hstatus & ~mask) | (val & mask);
|
||||
|
||||
if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"QEMU does not support mixed HSXLEN options.");
|
||||
|
|
|
@ -575,6 +575,13 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
|
|||
void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
|
||||
{
|
||||
int i;
|
||||
uint64_t mask = MSECCFG_MMWP | MSECCFG_MML;
|
||||
/* Update PMM field only if the value is valid according to Zjpm v1.0 */
|
||||
if (riscv_cpu_cfg(env)->ext_smmpm &&
|
||||
riscv_cpu_mxl(env) == MXL_RV64 &&
|
||||
get_field(val, MSECCFG_PMM) != PMM_FIELD_RESERVED) {
|
||||
mask |= MSECCFG_PMM;
|
||||
}
|
||||
|
||||
trace_mseccfg_csr_write(env->mhartid, val);
|
||||
|
||||
|
@ -590,12 +597,13 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
|
|||
|
||||
if (riscv_cpu_cfg(env)->ext_smepmp) {
|
||||
/* Sticky bits */
|
||||
val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
|
||||
if ((val ^ env->mseccfg) & (MSECCFG_MMWP | MSECCFG_MML)) {
|
||||
val |= (env->mseccfg & mask);
|
||||
if ((val ^ env->mseccfg) & mask) {
|
||||
tlb_flush(env_cpu(env));
|
||||
}
|
||||
} else {
|
||||
val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB);
|
||||
mask |= MSECCFG_RLB;
|
||||
val &= ~(mask);
|
||||
}
|
||||
|
||||
/* M-mode forward cfi to be enabled if cfi extension is implemented */
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef enum {
|
|||
MSECCFG_USEED = 1 << 8,
|
||||
MSECCFG_SSEED = 1 << 9,
|
||||
MSECCFG_MLPE = 1 << 10,
|
||||
MSECCFG_PMM = 3ULL << 32,
|
||||
} mseccfg_field_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue