If smstateen is implemented then accesses to AIA
registers CSRS, IMSIC CSRs and other IMSIC registers
is controlled by setting of corresponding bits in
mstateen/hstateen registers. Otherwise an illegal
instruction trap or virtual instruction trap is
generated.
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
---
target/riscv/csr.c | 248 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 246 insertions(+), 2 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5959adc9b3..cfdda8dc2b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -68,6 +68,53 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, int mode, int bit)
return RISCV_EXCP_NONE;
}
+static RISCVException smstateen_aia_acc_ok(CPURISCVState *env, int csrno)
+{
+ int bit, mode;
+
+ switch (csrno) {
+ case CSR_SSETEIPNUM:
+ case CSR_SCLREIPNUM:
+ case CSR_SSETEIENUM:
+ case CSR_SCLREIENUM:
+ case CSR_STOPEI:
+ case CSR_VSSETEIPNUM:
+ case CSR_VSCLREIPNUM:
+ case CSR_VSSETEIENUM:
+ case CSR_VSCLREIENUM:
+ case CSR_VSTOPEI:
+ case CSR_HSTATUS:
+ mode = PRV_S;
+ bit = SMSTATEEN0_IMSIC;
+ break;
+
+ case CSR_SIEH:
+ case CSR_SIPH:
+ case CSR_HVIPH:
+ case CSR_HVICTL:
+ case CSR_HVIPRIO1:
+ case CSR_HVIPRIO2:
+ case CSR_HVIPRIO1H:
+ case CSR_HVIPRIO2H:
+ case CSR_VSIEH:
+ case CSR_VSIPH:
+ mode = PRV_S;
+ bit = SMSTATEEN0_AIA;
+ break;
+
+ case CSR_SISELECT:
+ case CSR_VSISELECT:
+ mode = PRV_S;
+ bit = SMSTATEEN0_SVSLCT;
+ break;
+
+ default:
+ return RISCV_EXCP_NONE;
+ }
+
+ return smstateen_acc_ok(env, mode, bit);
+}
+
static RISCVException fs(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
@@ -1402,6 +1449,13 @@ static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
target_ulong new_val, target_ulong wr_mask)
{
target_ulong *iselect;
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
/* Translate CSR number for VS-mode */
csrno = aia_xlate_vs_csrno(env, csrno);
@@ -1484,7 +1538,9 @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
bool virt;
uint8_t *iprio;
int ret = -EINVAL;
- target_ulong priv, isel, vgein;
+ target_ulong priv, isel, vgein = 0;
+ CPUState *cs = env_cpu(env);
+ RISCVCPU *cpu = RISCV_CPU(cs);
/* Translate CSR number for VS-mode */
csrno = aia_xlate_vs_csrno(env, csrno);
@@ -1513,11 +1569,20 @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
};
/* Find the selected guest interrupt file */
- vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
+ if (virt) {
+ if (!cpu->cfg.ext_smstateen ||
+ (env->hstateen[0] & 1UL << SMSTATEEN0_IMSIC)) {
+ vgein = get_field(env->hstatus, HSTATUS_VGEIN);
+ }
+ }
if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
/* Local interrupt priority registers not available for VS-mode */
if (!virt) {
+ if (priv == PRV_S && cpu->cfg.ext_smstateen &&
+ !(env->hstateen[0] & 1UL << SMSTATEEN0_AIA)) {
+ goto done;
+ }
ret = rmw_iprio(riscv_cpu_mxl_bits(env),
isel, iprio, val, new_val, wr_mask,
(priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
@@ -1551,6 +1616,13 @@ static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong *val,
int ret = -EINVAL;
bool set, pend, virt;
target_ulong priv, isel, vgein, xlen, nval, wmask;
+ RISCVException excp;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ excp = smstateen_aia_acc_ok(env, csrno);
+ if (excp != RISCV_EXCP_NONE) {
+ return excp;
+ }
/* Translate CSR number for VS-mode */
csrno = aia_xlate_vs_csrno(env, csrno);
@@ -1669,6 +1741,13 @@ static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
bool virt;
int ret = -EINVAL;
target_ulong priv, vgein;
+ RISCVException excp;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ excp = smstateen_aia_acc_ok(env, csrno);
+ if (excp != RISCV_EXCP_NONE) {
+ return excp;
+ }
/* Translate CSR number for VS-mode */
csrno = aia_xlate_vs_csrno(env, csrno);
@@ -2014,6 +2093,12 @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
wr_mask |= 1UL << SMSTATEEN0_FCSR;
}
+ if (riscv_feature(env, RISCV_FEATURE_AIA)) {
+ wr_mask |= (1UL << SMSTATEEN0_IMSIC)
+ | (1UL << SMSTATEEN0_AIA)
+ | (1UL << SMSTATEEN0_SVSLCT);
+ }
+
write_smstateen(env, reg, wr_mask, new_val);
return RISCV_EXCP_NONE;
@@ -2042,6 +2127,12 @@ static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
wr_mask |= 1UL << SMSTATEEN0_FCSR;
}
+ if (riscv_feature(env, RISCV_FEATURE_AIA)) {
+ wr_mask |= (1UL << SMSTATEEN0_IMSIC)
+ | (1UL << SMSTATEEN0_AIA)
+ | (1UL << SMSTATEEN0_SVSLCT);
+ }
+
write_smstateen(env, reg, wr_mask, val);
return RISCV_EXCP_NONE;
@@ -2067,6 +2158,12 @@ static RISCVException write_hstateen(CPURISCVState *env, int csrno,
wr_mask |= 1UL << SMSTATEEN0_FCSR;
}
+ if (riscv_feature(env, RISCV_FEATURE_AIA)) {
+ wr_mask |= (1UL << SMSTATEEN0_IMSIC)
+ | (1UL << SMSTATEEN0_AIA)
+ | (1UL << SMSTATEEN0_SVSLCT);
+ }
+
reg = &env->hstateen[index];
wr_mask &= env->mstateen[index];
write_smstateen(env, reg, wr_mask, new_val);
@@ -2095,6 +2192,12 @@ static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
wr_mask |= 1UL << SMSTATEEN0_FCSR;
}
+ if (riscv_feature(env, RISCV_FEATURE_AIA)) {
+ wr_mask |= (1UL << SMSTATEEN0_IMSIC)
+ | (1UL << SMSTATEEN0_AIA)
+ | (1UL << SMSTATEEN0_SVSLCT);
+ }
+
reg = &env->hstateen[index];
val = (uint64_t)new_val << 32;
val |= *reg & 0xFFFFFFFF;
@@ -2288,6 +2391,12 @@ static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
uint64_t rval;
RISCVException ret;
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
ret = rmw_vsie64(env, csrno, &rval,
((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
if (ret_val) {
@@ -2342,6 +2451,12 @@ static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
uint64_t rval;
RISCVException ret;
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
ret = rmw_sie64(env, csrno, &rval,
((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
if (ret_val) {
@@ -2504,6 +2619,12 @@ static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
uint64_t rval;
RISCVException ret;
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
ret = rmw_vsip64(env, csrno, &rval,
((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
if (ret_val) {
@@ -2558,6 +2679,12 @@ static RISCVException rmw_siph(CPURISCVState *env, int csrno,
uint64_t rval;
RISCVException ret;
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
ret = rmw_sip64(env, csrno, &rval,
((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
if (ret_val) {
@@ -2748,6 +2875,10 @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno,
static RISCVException write_hstatus(CPURISCVState *env, int csrno,
target_ulong val)
{
+ if (smstateen_aia_acc_ok(env, csrno) != RISCV_EXCP_NONE) {
+ val &= ~HSTATUS_VGEIN;
+ }
+
env->hstatus = val;
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.");
@@ -2808,6 +2939,12 @@ static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
uint64_t rval;
RISCVException ret;
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
ret = rmw_hideleg64(env, csrno, &rval,
((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
if (ret_val) {
@@ -2854,6 +2991,12 @@ static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
uint64_t rval;
RISCVException ret;
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
ret = rmw_hvip64(env, csrno, &rval,
((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
if (ret_val) {
@@ -2908,6 +3051,13 @@ static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
static RISCVException read_hgeie(CPURISCVState *env, int csrno,
target_ulong *val)
{
+ RISCVException ret;
+
+ ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_IMSIC);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
if (val) {
*val = env->hgeie;
}
@@ -2917,6 +3067,13 @@ static RISCVException read_hgeie(CPURISCVState *env, int csrno,
static RISCVException write_hgeie(CPURISCVState *env, int csrno,
target_ulong val)
{
+ RISCVException ret;
+
+ ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_IMSIC);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
/* Only GEILEN:1 bits implemented and BIT0 is never implemented */
val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
env->hgeie = val;
@@ -2956,6 +3113,13 @@ static RISCVException write_htinst(CPURISCVState *env, int csrno,
static RISCVException read_hgeip(CPURISCVState *env, int csrno,
target_ulong *val)
{
+ RISCVException ret;
+
+ ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_IMSIC);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
if (val) {
*val = env->hgeip;
}
@@ -3026,12 +3190,28 @@ static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
*val = env->hvictl;
return RISCV_EXCP_NONE;
}
static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
{
+ RISCVException ret = RISCV_EXCP_NONE;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
env->hvictl = val & HVICTL_VALID_MASK;
return RISCV_EXCP_NONE;
}
@@ -3090,41 +3270,105 @@ static int write_hvipriox(CPURISCVState *env, int first_index,
static int read_hviprio1(CPURISCVState *env, int csrno, target_ulong *val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
return read_hvipriox(env, 0, env->hviprio, val);
}
static int write_hviprio1(CPURISCVState *env, int csrno, target_ulong val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
return write_hvipriox(env, 0, env->hviprio, val);
}
static int read_hviprio1h(CPURISCVState *env, int csrno, target_ulong *val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
return read_hvipriox(env, 4, env->hviprio, val);
}
static int write_hviprio1h(CPURISCVState *env, int csrno, target_ulong val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
return write_hvipriox(env, 4, env->hviprio, val);
}
static int read_hviprio2(CPURISCVState *env, int csrno, target_ulong *val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
return read_hvipriox(env, 8, env->hviprio, val);
}
static int write_hviprio2(CPURISCVState *env, int csrno, target_ulong val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
return write_hvipriox(env, 8, env->hviprio, val);
}
static int read_hviprio2h(CPURISCVState *env, int csrno, target_ulong *val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
return read_hvipriox(env, 12, env->hviprio, val);
}
static int write_hviprio2h(CPURISCVState *env, int csrno, target_ulong val)
{
+ RISCVException ret;
+
+ /* Check if smstateen is enabled and this access is allowed */
+ ret = smstateen_aia_acc_ok(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
return write_hvipriox(env, 12, env->hviprio, val);
}
--
2.17.1
在 2022/3/23 下午7:13, Mayuresh Chitale 写道:
> If smstateen is implemented then accesses to AIA
> registers CSRS, IMSIC CSRs and other IMSIC registers
> is controlled by setting of corresponding bits in
> mstateen/hstateen registers. Otherwise an illegal
> instruction trap or virtual instruction trap is
> generated.
>
> Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
> ---
> target/riscv/csr.c | 248 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 246 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 5959adc9b3..cfdda8dc2b 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -68,6 +68,53 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, int mode, int bit)
> return RISCV_EXCP_NONE;
> }
>
> +static RISCVException smstateen_aia_acc_ok(CPURISCVState *env, int csrno)
> +{
> + int bit, mode;
> +
> + switch (csrno) {
> + case CSR_SSETEIPNUM:
> + case CSR_SCLREIPNUM:
> + case CSR_SSETEIENUM:
> + case CSR_SCLREIENUM:
> + case CSR_STOPEI:
> + case CSR_VSSETEIPNUM:
> + case CSR_VSCLREIPNUM:
> + case CSR_VSSETEIENUM:
> + case CSR_VSCLREIENUM:
> + case CSR_VSTOPEI:
> + case CSR_HSTATUS:
> + mode = PRV_S;
> + bit = SMSTATEEN0_IMSIC;
> + break;
> +
> + case CSR_SIEH:
> + case CSR_SIPH:
> + case CSR_HVIPH:
> + case CSR_HVICTL:
> + case CSR_HVIPRIO1:
> + case CSR_HVIPRIO2:
> + case CSR_HVIPRIO1H:
> + case CSR_HVIPRIO2H:
> + case CSR_VSIEH:
> + case CSR_VSIPH:
> + mode = PRV_S;
> + bit = SMSTATEEN0_AIA;
> + break;
> +
> + case CSR_SISELECT:
> + case CSR_VSISELECT:
> + mode = PRV_S;
> + bit = SMSTATEEN0_SVSLCT;
> + break;
> +
> + default:
> + return RISCV_EXCP_NONE;
> + }
> +
> + return smstateen_acc_ok(env, mode, bit);
> +}
> +
> static RISCVException fs(CPURISCVState *env, int csrno)
> {
> #if !defined(CONFIG_USER_ONLY)
> @@ -1402,6 +1449,13 @@ static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
> target_ulong new_val, target_ulong wr_mask)
> {
> target_ulong *iselect;
> + RISCVException ret;
> +
> + /* Check if smstateen is enabled and this access is allowed */
> + ret = smstateen_aia_acc_ok(env, csrno);
> + if (ret != RISCV_EXCP_NONE) {
> + return ret;
> + }
>
> /* Translate CSR number for VS-mode */
> csrno = aia_xlate_vs_csrno(env, csrno);
> @@ -1484,7 +1538,9 @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
> bool virt;
> uint8_t *iprio;
> int ret = -EINVAL;
> - target_ulong priv, isel, vgein;
> + target_ulong priv, isel, vgein = 0;
> + CPUState *cs = env_cpu(env);
> + RISCVCPU *cpu = RISCV_CPU(cs);
>
> /* Translate CSR number for VS-mode */
> csrno = aia_xlate_vs_csrno(env, csrno);
> @@ -1513,11 +1569,20 @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
> };
>
> /* Find the selected guest interrupt file */
> - vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
> + if (virt) {
> + if (!cpu->cfg.ext_smstateen ||
> + (env->hstateen[0] & 1UL << SMSTATEEN0_IMSIC)) {
It seems better that '(' aligned with '!'.
> + vgein = get_field(env->hstatus, HSTATUS_VGEIN);
> + }
> + }
>
> if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
> /* Local interrupt priority registers not available for VS-mode */
> if (!virt) {
> + if (priv == PRV_S && cpu->cfg.ext_smstateen &&
> + !(env->hstateen[0] & 1UL << SMSTATEEN0_AIA)) {
> + goto done;
> + }
> ret = rmw_iprio(riscv_cpu_mxl_bits(env),
> isel, iprio, val, new_val, wr_mask,
> (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
> @@ -1551,6 +1616,13 @@ static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong *val,
> int ret = -EINVAL;
> bool set, pend, virt;
> target_ulong priv, isel, vgein, xlen, nval, wmask;
> + RISCVException excp;
> +
> + /* Check if smstateen is enabled and this access is allowed */
> + excp = smstateen_aia_acc_ok(env, csrno);
> + if (excp != RISCV_EXCP_NONE) {
> + return excp;
> + }
>
> /* Translate CSR number for VS-mode */
> csrno = aia_xlate_vs_csrno(env, csrno);
> @@ -1669,6 +1741,13 @@ static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
> bool virt;
> int ret = -EINVAL;
> target_ulong priv, vgein;
> + RISCVException excp;
> +
> + /* Check if smstateen is enabled and this access is allowed */
> + excp = smstateen_aia_acc_ok(env, csrno);
> + if (excp != RISCV_EXCP_NONE) {
> + return excp;
> + }
>
> /* Translate CSR number for VS-mode */
> csrno = aia_xlate_vs_csrno(env, csrno);
> @@ -2014,6 +2093,12 @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
> wr_mask |= 1UL << SMSTATEEN0_FCSR;
> }
>
> + if (riscv_feature(env, RISCV_FEATURE_AIA)) {
> + wr_mask |= (1UL << SMSTATEEN0_IMSIC)
> + | (1UL << SMSTATEEN0_AIA)
> + | (1UL << SMSTATEEN0_SVSLCT);
I think it's better as follows:
+ wr_mask |= (1UL << SMSTATEEN0_IMSIC) |
+ (1UL << SMSTATEEN0_AIA) |
+ (1UL << SMSTATEEN0_SVSLCT);
Regards,
Weiwei Li
On Wed, Mar 23, 2022 at 6:43 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
>
> 在 2022/3/23 下午7:13, Mayuresh Chitale 写道:
> > If smstateen is implemented then accesses to AIA
> > registers CSRS, IMSIC CSRs and other IMSIC registers
> > is controlled by setting of corresponding bits in
> > mstateen/hstateen registers. Otherwise an illegal
> > instruction trap or virtual instruction trap is
> > generated.
> >
> > Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
> > ---
> > target/riscv/csr.c | 248 ++++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 246 insertions(+), 2 deletions(-)
> >
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 5959adc9b3..cfdda8dc2b 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -68,6 +68,53 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, int mode, int bit)
> > return RISCV_EXCP_NONE;
> > }
> >
> > +static RISCVException smstateen_aia_acc_ok(CPURISCVState *env, int csrno)
> > +{
> > + int bit, mode;
> > +
> > + switch (csrno) {
> > + case CSR_SSETEIPNUM:
> > + case CSR_SCLREIPNUM:
> > + case CSR_SSETEIENUM:
> > + case CSR_SCLREIENUM:
> > + case CSR_STOPEI:
> > + case CSR_VSSETEIPNUM:
> > + case CSR_VSCLREIPNUM:
> > + case CSR_VSSETEIENUM:
> > + case CSR_VSCLREIENUM:
> > + case CSR_VSTOPEI:
> > + case CSR_HSTATUS:
> > + mode = PRV_S;
> > + bit = SMSTATEEN0_IMSIC;
> > + break;
> > +
> > + case CSR_SIEH:
> > + case CSR_SIPH:
> > + case CSR_HVIPH:
> > + case CSR_HVICTL:
> > + case CSR_HVIPRIO1:
> > + case CSR_HVIPRIO2:
> > + case CSR_HVIPRIO1H:
> > + case CSR_HVIPRIO2H:
> > + case CSR_VSIEH:
> > + case CSR_VSIPH:
> > + mode = PRV_S;
> > + bit = SMSTATEEN0_AIA;
> > + break;
> > +
> > + case CSR_SISELECT:
> > + case CSR_VSISELECT:
> > + mode = PRV_S;
> > + bit = SMSTATEEN0_SVSLCT;
> > + break;
> > +
> > + default:
> > + return RISCV_EXCP_NONE;
> > + }
> > +
> > + return smstateen_acc_ok(env, mode, bit);
> > +}
> > +
> > static RISCVException fs(CPURISCVState *env, int csrno)
> > {
> > #if !defined(CONFIG_USER_ONLY)
> > @@ -1402,6 +1449,13 @@ static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
> > target_ulong new_val, target_ulong wr_mask)
> > {
> > target_ulong *iselect;
> > + RISCVException ret;
> > +
> > + /* Check if smstateen is enabled and this access is allowed */
> > + ret = smstateen_aia_acc_ok(env, csrno);
> > + if (ret != RISCV_EXCP_NONE) {
> > + return ret;
> > + }
> >
> > /* Translate CSR number for VS-mode */
> > csrno = aia_xlate_vs_csrno(env, csrno);
> > @@ -1484,7 +1538,9 @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
> > bool virt;
> > uint8_t *iprio;
> > int ret = -EINVAL;
> > - target_ulong priv, isel, vgein;
> > + target_ulong priv, isel, vgein = 0;
> > + CPUState *cs = env_cpu(env);
> > + RISCVCPU *cpu = RISCV_CPU(cs);
> >
> > /* Translate CSR number for VS-mode */
> > csrno = aia_xlate_vs_csrno(env, csrno);
> > @@ -1513,11 +1569,20 @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
> > };
> >
> > /* Find the selected guest interrupt file */
> > - vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
> > + if (virt) {
> > + if (!cpu->cfg.ext_smstateen ||
> > + (env->hstateen[0] & 1UL << SMSTATEEN0_IMSIC)) {
> It seems better that '(' aligned with '!'.
> > + vgein = get_field(env->hstatus, HSTATUS_VGEIN);
> > + }
> > + }
> >
> > if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
> > /* Local interrupt priority registers not available for VS-mode */
> > if (!virt) {
> > + if (priv == PRV_S && cpu->cfg.ext_smstateen &&
> > + !(env->hstateen[0] & 1UL << SMSTATEEN0_AIA)) {
> > + goto done;
> > + }
> > ret = rmw_iprio(riscv_cpu_mxl_bits(env),
> > isel, iprio, val, new_val, wr_mask,
> > (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
> > @@ -1551,6 +1616,13 @@ static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong *val,
> > int ret = -EINVAL;
> > bool set, pend, virt;
> > target_ulong priv, isel, vgein, xlen, nval, wmask;
> > + RISCVException excp;
> > +
> > + /* Check if smstateen is enabled and this access is allowed */
> > + excp = smstateen_aia_acc_ok(env, csrno);
> > + if (excp != RISCV_EXCP_NONE) {
> > + return excp;
> > + }
> >
> > /* Translate CSR number for VS-mode */
> > csrno = aia_xlate_vs_csrno(env, csrno);
> > @@ -1669,6 +1741,13 @@ static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
> > bool virt;
> > int ret = -EINVAL;
> > target_ulong priv, vgein;
> > + RISCVException excp;
> > +
> > + /* Check if smstateen is enabled and this access is allowed */
> > + excp = smstateen_aia_acc_ok(env, csrno);
> > + if (excp != RISCV_EXCP_NONE) {
> > + return excp;
> > + }
> >
> > /* Translate CSR number for VS-mode */
> > csrno = aia_xlate_vs_csrno(env, csrno);
> > @@ -2014,6 +2093,12 @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
> > wr_mask |= 1UL << SMSTATEEN0_FCSR;
> > }
> >
> > + if (riscv_feature(env, RISCV_FEATURE_AIA)) {
> > + wr_mask |= (1UL << SMSTATEEN0_IMSIC)
> > + | (1UL << SMSTATEEN0_AIA)
> > + | (1UL << SMSTATEEN0_SVSLCT);
>
> I think it's better as follows:
Ok. Will fix it in the next version.
>
> + wr_mask |= (1UL << SMSTATEEN0_IMSIC) |
> + (1UL << SMSTATEEN0_AIA) |
> + (1UL << SMSTATEEN0_SVSLCT);
>
> Regards,
>
> Weiwei Li
>
© 2016 - 2026 Red Hat, Inc.