[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH v5 4/4] target/riscv: smstateen check for AIA/IMSIC
From: |
Alistair Francis |
Subject: |
Re: [RFC PATCH v5 4/4] target/riscv: smstateen check for AIA/IMSIC |
Date: |
Thu, 16 Jun 2022 17:18:53 +1000 |
On Sat, Jun 4, 2022 at 2:15 AM Mayuresh Chitale
<mchitale@ventanamicro.com> wrote:
>
> 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 | 253 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 248 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 8bbbed38ff..213b3c17ff 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -39,6 +39,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
> }
>
> /* Predicates */
> +#if !defined(CONFIG_USER_ONLY)
This should just be in the original patch.
> static RISCVException smstateen_acc_ok(CPURISCVState *env, int mode, int bit)
> {
> CPUState *cs = env_cpu(env);
> @@ -49,7 +50,6 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env,
> int mode, int bit)
> return RISCV_EXCP_NONE;
> }
>
> -#if !defined(CONFIG_USER_ONLY)
> if (!(env->mstateen[0] & 1UL << bit)) {
> return RISCV_EXCP_ILLEGAL_INST;
> }
> @@ -65,11 +65,57 @@ static RISCVException smstateen_acc_ok(CPURISCVState
> *env, int mode, int bit)
> return RISCV_EXCP_ILLEGAL_INST;
> }
> }
> -#endif
> -
> return RISCV_EXCP_NONE;
> }
>
> +static RISCVException smstateen_aia_acc_ok(CPURISCVState *env, int csrno)
The spec doesn't mention the effects on AIA, it just says that some
bits are reserved. How do you know what should happen here?
Alistair
> +{
> + 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);
> +}
> +#endif
> +
> static RISCVException fs(CPURISCVState *env, int csrno)
> {
> #if !defined(CONFIG_USER_ONLY)
> @@ -1130,6 +1176,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);
> @@ -1212,7 +1265,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);
> @@ -1241,11 +1296,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);
> @@ -1279,6 +1343,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);
> @@ -1397,6 +1468,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);
> @@ -1708,6 +1786,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;
> @@ -1736,6 +1820,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;
> @@ -1761,6 +1851,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);
> @@ -1789,6 +1885,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;
> @@ -1979,6 +2081,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) {
> @@ -2033,6 +2141,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) {
> @@ -2195,6 +2309,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) {
> @@ -2249,6 +2369,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) {
> @@ -2441,6 +2567,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.");
> @@ -2501,6 +2631,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) {
> @@ -2547,6 +2683,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) {
> @@ -2601,6 +2743,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;
> }
> @@ -2610,6 +2759,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;
> @@ -2649,6 +2805,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;
> }
> @@ -2719,12 +2882,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;
> }
> @@ -2783,41 +2962,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.25.1
>
>