mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -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,
|
EXT_STATUS_DIRTY,
|
||||||
} RISCVExtStatus;
|
} 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 {
|
typedef struct riscv_cpu_implied_exts_rule {
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -575,6 +575,7 @@ typedef enum {
|
||||||
#define HSTATUS_VTSR 0x00400000
|
#define HSTATUS_VTSR 0x00400000
|
||||||
#define HSTATUS_HUKTE 0x01000000
|
#define HSTATUS_HUKTE 0x01000000
|
||||||
#define HSTATUS_VSXL 0x300000000
|
#define HSTATUS_VSXL 0x300000000
|
||||||
|
#define HSTATUS_HUPMM 0x3000000000000
|
||||||
|
|
||||||
#define HSTATUS32_WPRI 0xFF8FF87E
|
#define HSTATUS32_WPRI 0xFF8FF87E
|
||||||
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
|
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
|
||||||
|
@ -735,6 +736,7 @@ typedef enum RISCVException {
|
||||||
#define MENVCFG_CBIE (3UL << 4)
|
#define MENVCFG_CBIE (3UL << 4)
|
||||||
#define MENVCFG_CBCFE BIT(6)
|
#define MENVCFG_CBCFE BIT(6)
|
||||||
#define MENVCFG_CBZE BIT(7)
|
#define MENVCFG_CBZE BIT(7)
|
||||||
|
#define MENVCFG_PMM (3ULL << 32)
|
||||||
#define MENVCFG_ADUE (1ULL << 61)
|
#define MENVCFG_ADUE (1ULL << 61)
|
||||||
#define MENVCFG_PBMTE (1ULL << 62)
|
#define MENVCFG_PBMTE (1ULL << 62)
|
||||||
#define MENVCFG_STCE (1ULL << 63)
|
#define MENVCFG_STCE (1ULL << 63)
|
||||||
|
@ -751,6 +753,7 @@ typedef enum RISCVException {
|
||||||
#define SENVCFG_CBCFE MENVCFG_CBCFE
|
#define SENVCFG_CBCFE MENVCFG_CBCFE
|
||||||
#define SENVCFG_CBZE MENVCFG_CBZE
|
#define SENVCFG_CBZE MENVCFG_CBZE
|
||||||
#define SENVCFG_UKTE BIT(8)
|
#define SENVCFG_UKTE BIT(8)
|
||||||
|
#define SENVCFG_PMM MENVCFG_PMM
|
||||||
|
|
||||||
#define HENVCFG_FIOM MENVCFG_FIOM
|
#define HENVCFG_FIOM MENVCFG_FIOM
|
||||||
#define HENVCFG_LPE MENVCFG_LPE
|
#define HENVCFG_LPE MENVCFG_LPE
|
||||||
|
@ -758,6 +761,7 @@ typedef enum RISCVException {
|
||||||
#define HENVCFG_CBIE MENVCFG_CBIE
|
#define HENVCFG_CBIE MENVCFG_CBIE
|
||||||
#define HENVCFG_CBCFE MENVCFG_CBCFE
|
#define HENVCFG_CBCFE MENVCFG_CBCFE
|
||||||
#define HENVCFG_CBZE MENVCFG_CBZE
|
#define HENVCFG_CBZE MENVCFG_CBZE
|
||||||
|
#define HENVCFG_PMM MENVCFG_PMM
|
||||||
#define HENVCFG_ADUE MENVCFG_ADUE
|
#define HENVCFG_ADUE MENVCFG_ADUE
|
||||||
#define HENVCFG_PBMTE MENVCFG_PBMTE
|
#define HENVCFG_PBMTE MENVCFG_PBMTE
|
||||||
#define HENVCFG_STCE MENVCFG_STCE
|
#define HENVCFG_STCE MENVCFG_STCE
|
||||||
|
|
|
@ -129,6 +129,9 @@ struct RISCVCPUConfig {
|
||||||
bool ext_ssaia;
|
bool ext_ssaia;
|
||||||
bool ext_sscofpmf;
|
bool ext_sscofpmf;
|
||||||
bool ext_smepmp;
|
bool ext_smepmp;
|
||||||
|
bool ext_ssnpm;
|
||||||
|
bool ext_smnpm;
|
||||||
|
bool ext_smmpm;
|
||||||
bool rvv_ta_all_1s;
|
bool rvv_ta_all_1s;
|
||||||
bool rvv_ma_all_1s;
|
bool rvv_ma_all_1s;
|
||||||
bool rvv_vl_half_avl;
|
bool rvv_vl_half_avl;
|
||||||
|
|
|
@ -575,6 +575,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno)
|
||||||
if (riscv_cpu_cfg(env)->ext_zkr) {
|
if (riscv_cpu_cfg(env)->ext_zkr) {
|
||||||
return RISCV_EXCP_NONE;
|
return RISCV_EXCP_NONE;
|
||||||
}
|
}
|
||||||
|
if (riscv_cpu_cfg(env)->ext_smmpm) {
|
||||||
|
return RISCV_EXCP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
return RISCV_EXCP_ILLEGAL_INST;
|
return RISCV_EXCP_ILLEGAL_INST;
|
||||||
}
|
}
|
||||||
|
@ -2379,6 +2382,12 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
|
||||||
if (env_archcpu(env)->cfg.ext_zicfiss) {
|
if (env_archcpu(env)->cfg.ext_zicfiss) {
|
||||||
mask |= MENVCFG_SSE;
|
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);
|
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;
|
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
|
||||||
RISCVException ret;
|
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);
|
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
|
||||||
if (ret != RISCV_EXCP_NONE) {
|
if (ret != RISCV_EXCP_NONE) {
|
||||||
|
@ -2493,6 +2508,12 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
||||||
get_field(env->menvcfg, MENVCFG_SSE)) {
|
get_field(env->menvcfg, MENVCFG_SSE)) {
|
||||||
mask |= HENVCFG_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);
|
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,
|
static RISCVException write_hstatus(CPURISCVState *env, int csrno,
|
||||||
target_ulong val)
|
target_ulong val)
|
||||||
{
|
{
|
||||||
|
uint64_t mask = (target_ulong)-1;
|
||||||
if (!env_archcpu(env)->cfg.ext_svukte) {
|
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) {
|
if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
|
||||||
qemu_log_mask(LOG_UNIMP,
|
qemu_log_mask(LOG_UNIMP,
|
||||||
"QEMU does not support mixed HSXLEN options.");
|
"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)
|
void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
|
||||||
{
|
{
|
||||||
int i;
|
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);
|
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) {
|
if (riscv_cpu_cfg(env)->ext_smepmp) {
|
||||||
/* Sticky bits */
|
/* Sticky bits */
|
||||||
val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
|
val |= (env->mseccfg & mask);
|
||||||
if ((val ^ env->mseccfg) & (MSECCFG_MMWP | MSECCFG_MML)) {
|
if ((val ^ env->mseccfg) & mask) {
|
||||||
tlb_flush(env_cpu(env));
|
tlb_flush(env_cpu(env));
|
||||||
}
|
}
|
||||||
} else {
|
} 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 */
|
/* M-mode forward cfi to be enabled if cfi extension is implemented */
|
||||||
|
|
|
@ -46,6 +46,7 @@ typedef enum {
|
||||||
MSECCFG_USEED = 1 << 8,
|
MSECCFG_USEED = 1 << 8,
|
||||||
MSECCFG_SSEED = 1 << 9,
|
MSECCFG_SSEED = 1 << 9,
|
||||||
MSECCFG_MLPE = 1 << 10,
|
MSECCFG_MLPE = 1 << 10,
|
||||||
|
MSECCFG_PMM = 3ULL << 32,
|
||||||
} mseccfg_field_t;
|
} mseccfg_field_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue