target/riscv: Fix up masking of vsip/vsie accesses
The current logic attempts to shift the VS-level bits into their correct
position in mip while leaving the remaining bits in-tact. This is both
pointless and likely incorrect since one would expect that any new, future
VS-level interrupts will get their own position in mip rather than sharing
with their (H)S-level equivalent. Fix this, and make the logic more
readable, by just making off the VS-level bits and shifting them into
position.
This also fixes reads of vsip, which would only ever report vsip.VSSIP
since the non-writable bits got masked off as well.
Fixes: d028ac7512
("arget/riscv: Implement AIA CSRs for 64 local interrupts on RV32")
Signed-off-by: Andrew Bresticker <abrestic@rivosinc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20221215224541.1423431-1-abrestic@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
9c3ee7e847
commit
06d85c24c2
@ -2305,22 +2305,15 @@ static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
|
||||
uint64_t new_val, uint64_t wr_mask)
|
||||
{
|
||||
RISCVException ret;
|
||||
uint64_t rval, vsbits, mask = env->hideleg & VS_MODE_INTERRUPTS;
|
||||
uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
|
||||
|
||||
/* Bring VS-level bits to correct position */
|
||||
vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
|
||||
new_val &= ~(VS_MODE_INTERRUPTS >> 1);
|
||||
new_val |= vsbits << 1;
|
||||
vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
|
||||
wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
|
||||
wr_mask |= vsbits << 1;
|
||||
new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1;
|
||||
wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1;
|
||||
|
||||
ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
|
||||
if (ret_val) {
|
||||
rval &= mask;
|
||||
vsbits = rval & VS_MODE_INTERRUPTS;
|
||||
rval &= ~VS_MODE_INTERRUPTS;
|
||||
*ret_val = rval | (vsbits >> 1);
|
||||
*ret_val = (rval & mask) >> 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -2521,22 +2514,16 @@ static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
|
||||
uint64_t new_val, uint64_t wr_mask)
|
||||
{
|
||||
RISCVException ret;
|
||||
uint64_t rval, vsbits, mask = env->hideleg & vsip_writable_mask;
|
||||
uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
|
||||
|
||||
/* Bring VS-level bits to correct position */
|
||||
vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
|
||||
new_val &= ~(VS_MODE_INTERRUPTS >> 1);
|
||||
new_val |= vsbits << 1;
|
||||
vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
|
||||
wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
|
||||
wr_mask |= vsbits << 1;
|
||||
new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1;
|
||||
wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1;
|
||||
|
||||
ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask & mask);
|
||||
ret = rmw_mip64(env, csrno, &rval, new_val,
|
||||
wr_mask & mask & vsip_writable_mask);
|
||||
if (ret_val) {
|
||||
rval &= mask;
|
||||
vsbits = rval & VS_MODE_INTERRUPTS;
|
||||
rval &= ~VS_MODE_INTERRUPTS;
|
||||
*ret_val = rval | (vsbits >> 1);
|
||||
*ret_val = (rval & mask) >> 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user