Skip to content

Commit

Permalink
csr_regfile: Fix irq/ex delegation in RVH
Browse files Browse the repository at this point in the history
In RVH, interrupts are currently delegated if hxdeleg is set but mxdeleg
is not, violating the spec ("A trap/irq *that has been delegated to
HS-mode (using mxdeleg)* is further delegated to VS-mode if the
corresponding hxdeleg bit is set"). Fix and simplify the corresponding logic.

Signed-off-by: Nils Wistoff <nwistoff@iis.ee.ethz.ch>
  • Loading branch information
niwis committed Jan 8, 2025
1 parent eab8877 commit b43d6eb
Showing 1 changed file with 10 additions and 24 deletions.
34 changes: 10 additions & 24 deletions core/csr_regfile.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1791,38 +1791,24 @@ module csr_regfile
// a m-mode trap might be delegated if we are taking it in S mode
// first figure out if this was an exception or an interrupt e.g.: look at bit (XLEN-1)
// the cause register can only be $clog2(CVA6Cfg.XLEN) bits long (as we only support XLEN exceptions)
if (CVA6Cfg.RVH) begin
if (CVA6Cfg.RVS) begin
if ((ex_i.cause[CVA6Cfg.XLEN-1] && mideleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]] && ~hideleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]]) || (~ex_i.cause[CVA6Cfg.XLEN-1] && medeleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]] && ~hedeleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]])) begin
// traps never transition from a more-privileged mode to a less privileged mode
// so if we are already in M mode, stay there
trap_to_priv_lvl = (priv_lvl_o == riscv::PRIV_LVL_M) ? riscv::PRIV_LVL_M : riscv::PRIV_LVL_S;
end else if ((ex_i.cause[CVA6Cfg.XLEN-1] && hideleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]]) || (~ex_i.cause[CVA6Cfg.XLEN-1] && hedeleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]])) begin
trap_to_priv_lvl = (priv_lvl_o == riscv::PRIV_LVL_M) ? riscv::PRIV_LVL_M : riscv::PRIV_LVL_S;
// trap to VS only if it is the currently active mode
trap_to_v = v_q;
end
end else begin
if (CVA6Cfg.RVS) begin
if ((ex_i.cause[CVA6Cfg.XLEN-1] && mideleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]]) || (~ex_i.cause[CVA6Cfg.XLEN-1] && medeleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]])) begin
// traps never transition from a more-privileged mode to a less privileged mode
// so if we are already in M mode, stay there
trap_to_priv_lvl = (priv_lvl_o == riscv::PRIV_LVL_M) ? riscv::PRIV_LVL_M : riscv::PRIV_LVL_S;
if (CVA6Cfg.RVH) begin
if ((ex_i.cause[CVA6Cfg.XLEN-1] && hideleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]]) || (~ex_i.cause[CVA6Cfg.XLEN-1] && hedeleg_q[ex_i.cause[$clog2(
CVA6Cfg.XLEN
)-1:0]])) begin
// trap to VS only if it is the currently active mode
trap_to_v = v_q;
end
end
end
end
Expand Down

0 comments on commit b43d6eb

Please sign in to comment.