From 0abae30906bd682bd16cb94fad16caed31c0775a Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Thu, 25 May 2023 18:31:52 +0200 Subject: [PATCH 01/12] [ADD] Support for Virtual Supervisor mode tracing --- common/local/util/ex_trace_item.svh | 1 + common/local/util/instr_trace_item.svh | 7 +++++-- common/local/util/instr_tracer.sv | 10 +++++----- common/local/util/instr_tracer_if.sv | 3 ++- core/cva6.sv | 1 + 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/common/local/util/ex_trace_item.svh b/common/local/util/ex_trace_item.svh index 91b090c625..46543cc4ed 100644 --- a/common/local/util/ex_trace_item.svh +++ b/common/local/util/ex_trace_item.svh @@ -35,6 +35,7 @@ class ex_trace_item; riscv::ST_ACCESS_FAULT: this.cause_s = "Store Access Fault"; riscv::ENV_CALL_UMODE: this.cause_s = "Environment Call User Mode"; riscv::ENV_CALL_SMODE: this.cause_s = "Environment Call Supervisor Mode"; + riscv::ENV_CALL_VSMODE: this.cause_s = "Environment Call Virtual Supervisor Mode"; riscv::ENV_CALL_MMODE: this.cause_s = "Environment Call Machine Mode"; riscv::INSTR_PAGE_FAULT: this.cause_s = "Instruction Page Fault"; riscv::LOAD_PAGE_FAULT: this.cause_s = "Load Page Fault"; diff --git a/common/local/util/instr_trace_item.svh b/common/local/util/instr_trace_item.svh index b9b1bbbdd3..b95f15d1f6 100644 --- a/common/local/util/instr_trace_item.svh +++ b/common/local/util/instr_trace_item.svh @@ -39,13 +39,14 @@ class instr_trace_item; logic [63:0] result; logic [riscv::PLEN-1:0] paddr; string priv_lvl; + logic v; ariane_pkg::bp_resolve_t bp; logic [4:0] rs1, rs2, rs3, rd; // constructor creating a new instruction trace item, e.g.: a single instruction with all relevant information function new (time simtime, longint unsigned cycle, ariane_pkg::scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] gp_reg_file [32], - logic [63:0] fp_reg_file [32], logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, ariane_pkg::bp_resolve_t bp); + logic [63:0] fp_reg_file [32], logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic v, logic debug_mode, ariane_pkg::bp_resolve_t bp); this.simtime = simtime; this.cycle = cycle; this.pc = sbe.pc; @@ -56,6 +57,7 @@ class instr_trace_item; this.paddr = paddr; this.bp = bp; this.priv_lvl = (debug_mode) ? "D" : getPrivLevel(priv_lvl); + this.v = v; this.rs1 = sbe.rs1[4:0]; this.rs2 = sbe.rs2[4:0]; this.rs3 = instr[31:27]; @@ -361,9 +363,10 @@ class instr_trace_item; default: s = this.printMnemonic("INVALID"); endcase - s = $sformatf("%8dns %8d %s %h %h %h %-36s", simtime, + s = $sformatf("%8dns %8d %s V=%d %h %h %h %-36s", simtime, cycle, priv_lvl, + v, sbe.pc, bp.is_mispredict & bp.valid, instr, diff --git a/common/local/util/instr_tracer.sv b/common/local/util/instr_tracer.sv index 17c11e5f14..32babde9b0 100644 --- a/common/local/util/instr_tracer.sv +++ b/common/local/util/instr_tracer.sv @@ -128,11 +128,11 @@ module instr_tracer ( // check if the write back is valid, if not we need to source the result from the register file // as the most recent version of this register will be there. if (tracer_if.pck.we_gpr[i] || tracer_if.pck.we_fpr[i]) begin - printInstr(issue_sbe, issue_commit_instruction, tracer_if.pck.wdata[i], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction); + printInstr(issue_sbe, issue_commit_instruction, tracer_if.pck.wdata[i], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.v, tracer_if.pck.debug_mode, bp_instruction); end else if (ariane_pkg::is_rd_fpr(commit_instruction.op)) begin - printInstr(issue_sbe, issue_commit_instruction, fp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction); + printInstr(issue_sbe, issue_commit_instruction, fp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.v, tracer_if.pck.debug_mode, bp_instruction); end else begin - printInstr(issue_sbe, issue_commit_instruction, gp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction); + printInstr(issue_sbe, issue_commit_instruction, gp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.v, tracer_if.pck.debug_mode, bp_instruction); end end end @@ -186,8 +186,8 @@ module instr_tracer ( bp = {}; endfunction - function void printInstr(ariane_pkg::scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, ariane_pkg::bp_resolve_t bp); - automatic instr_trace_item iti = new ($time, clk_ticks, sbe, instr, gp_reg_file, fp_reg_file, result, paddr, priv_lvl, debug_mode, bp); + function void printInstr(ariane_pkg::scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic v, logic debug_mode, ariane_pkg::bp_resolve_t bp); + automatic instr_trace_item iti = new ($time, clk_ticks, sbe, instr, gp_reg_file, fp_reg_file, result, paddr, priv_lvl, v, debug_mode, bp); // print instruction to console automatic string print_instr = iti.printInstr(); if (ariane_pkg::ENABLE_SPIKE_COMMIT_LOG && !debug_mode) begin diff --git a/common/local/util/instr_tracer_if.sv b/common/local/util/instr_tracer_if.sv index 5015cfd7d0..f2c5d158e6 100644 --- a/common/local/util/instr_tracer_if.sv +++ b/common/local/util/instr_tracer_if.sv @@ -51,6 +51,7 @@ interface instr_tracer_if ( ariane_pkg::exception_t exception; // current privilege level riscv::priv_lvl_t priv_lvl; + logic v; logic debug_mode; // the tracer just has a passive interface we do not drive anything with it @@ -58,7 +59,7 @@ interface instr_tracer_if ( clocking pck @(posedge clk); input rstn, flush_unissued, flush, instruction, fetch_valid, fetch_ack, issue_ack, issue_sbe, waddr, st_valid, st_paddr, ld_valid, ld_kill, ld_paddr, resolve_branch, - wdata, we_gpr, we_fpr, commit_instr, commit_ack, exception, priv_lvl, debug_mode; + wdata, we_gpr, we_fpr, commit_instr, commit_ack, exception, priv_lvl, v, debug_mode; endclocking //pragma translate_on diff --git a/core/cva6.sv b/core/cva6.sv index 42285e1b02..bd396ee9fb 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -1478,6 +1478,7 @@ module cva6 assign tracer_if.exception = commit_stage_i.exception_o; // assign current privilege level assign tracer_if.priv_lvl = priv_lvl; + assign tracer_if.v = v; assign tracer_if.debug_mode = debug_mode; instr_tracer instr_tracer_i ( From 44a75d6a829a29d578be8d0cdd305f66f1c72830 Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Fri, 26 May 2023 09:06:04 +0200 Subject: [PATCH 02/12] [ADD] S-mode trap delegation when in CLIC mode --- core/csr_regfile.sv | 8 ++++++-- core/cva6.sv | 8 ++++++-- core/cva6_clic_controller.sv | 8 +++++++- core/decoder.sv | 3 +++ core/frontend/instr_queue.sv | 2 ++ core/id_stage.sv | 3 +++ core/include/ariane_pkg.sv | 2 ++ 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 047780d53d..f436a57490 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -1740,6 +1740,8 @@ module csr_regfile 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 else if (ex_i.cause[riscv::XLEN-1] && clic_mode_o) begin + trap_to_priv_lvl = ex_i.priv_lvl; end end else begin if (CVA6Cfg.RVS && (ex_i.cause[riscv::XLEN-1] && mideleg_q[ex_i.cause[$clog2( @@ -1750,6 +1752,8 @@ module csr_regfile // 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[riscv::XLEN-1] && clic_mode_o) begin + trap_to_priv_lvl = ex_i.priv_lvl; end end @@ -2306,12 +2310,12 @@ module csr_regfile // trap_vector_base instead. if (ex_i.cause[riscv::XLEN-1] && ((((CVA6Cfg.RVS || CVA6Cfg.RVU) && trap_to_priv_lvl == riscv::PRIV_LVL_M && mtvec_q[0]) || (!CVA6Cfg.RVS && !CVA6Cfg.RVU && mtvec_q[0])) - || (CVA6Cfg.RVS && trap_to_priv_lvl == riscv::PRIV_LVL_S && !trap_to_v && stvec_q[0]) + || (CVA6Cfg.RVS && trap_to_priv_lvl == riscv::PRIV_LVL_S && !trap_to_v && stvec_q[0] && !clic_mode_o) || (CVA6Cfg.RVSCLIC && clic_mode_o && clic_irq_shv_i))) begin trap_vector_base_o[7:2] = ex_i.cause[5:0]; end if (ex_i.cause[riscv::XLEN-1] && - (CVA6Cfg.RVH && trap_to_priv_lvl == riscv::PRIV_LVL_S && trap_to_v && vstvec_q[0])) begin + (CVA6Cfg.RVH && trap_to_priv_lvl == riscv::PRIV_LVL_S && trap_to_v && vstvec_q[0] && !clic_mode_o)) begin trap_vector_base_o[7:2] = {ex_i.cause[5:2], 2'b01}; end diff --git a/core/cva6.sv b/core/cva6.sv index bd396ee9fb..03b978b8c6 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -527,8 +527,9 @@ module cva6 // ---------------------- // CLIC Controller <-> ID // ---------------------- - logic clic_irq_req_id; - riscv::xlen_t clic_irq_cause_id; + logic clic_irq_req_id; + riscv::priv_lvl_t clic_irq_priv_id; + riscv::xlen_t clic_irq_cause_id; // -------------- // Frontend @@ -591,6 +592,7 @@ module cva6 .irq_ctrl_i (irq_ctrl_csr_id), .clic_mode_i (clic_mode), .clic_irq_req_i (clic_irq_req_id), + .clic_irq_priv_i ( clic_irq_priv_id), .clic_irq_cause_i(clic_irq_cause_id), .debug_mode_i (debug_mode), .tvm_i (tvm_csr_id), @@ -1375,11 +1377,13 @@ module cva6 .clic_kill_ack_o (clic_kill_ack_o), // to ID stage .clic_irq_req_o (clic_irq_req_id), + .clic_irq_priv_o (clic_irq_priv_id), .clic_irq_cause_o(clic_irq_cause_id) ); end else begin : gen_dummy_clic_controller assign clic_kill_ack_o = 1'b0; assign clic_irq_req_id = 1'b0; + assign clic_irq_priv_id = riscv::PRIV_LVL_M; assign clic_irq_cause_id = '0; end diff --git a/core/cva6_clic_controller.sv b/core/cva6_clic_controller.sv index 68c6947cec..1bcc7ea67a 100644 --- a/core/cva6_clic_controller.sv +++ b/core/cva6_clic_controller.sv @@ -25,6 +25,7 @@ module cva6_clic_controller #( output logic clic_kill_ack_o, // kill acknowledge // to ID stage output logic clic_irq_req_o, + output riscv::priv_lvl_t clic_irq_priv_o, output riscv::xlen_t clic_irq_cause_o ); // ------- @@ -60,7 +61,9 @@ module cva6_clic_controller #( end riscv::PRIV_LVL_U: begin // Take all M-mode and S-mode interrupts - clic_irq_req_o = clic_irq_valid_i; + clic_irq_req_o = ((clic_irq_valid_i) && + ((clic_irq_priv_i == riscv::PRIV_LVL_M) || + (clic_irq_priv_i == riscv::PRIV_LVL_S && irq_ctrl_i.sie))); end default: ; endcase @@ -78,6 +81,9 @@ module cva6_clic_controller #( clic_irq_id_i }; // to mcause + // IRQ priv mode + assign clic_irq_priv_o = clic_irq_priv_i; + // ------------ // Kill Control // ------------ diff --git a/core/decoder.sv b/core/decoder.sv index fad81f4d27..60ef52f83f 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -49,6 +49,8 @@ module decoder // TO_BE_COMPLETED - CLIC_CTRL input logic clic_irq_req_i, // TO_BE_COMPLETED - CLIC_CTRL + input riscv::priv_lvl_t clic_irq_priv_i, + // TO_BE_COMPLETED - CLIC_CTRL input riscv::xlen_t clic_irq_cause_i, // Current privilege level - CSR_REGFILE input riscv::priv_lvl_t priv_lvl_i, @@ -1628,6 +1630,7 @@ module decoder end else begin instruction_o.ex.valid = 1'b1; instruction_o.ex.cause = interrupt_cause; + instruction_o.ex.priv_lvl = clic_irq_priv_i; end end end diff --git a/core/frontend/instr_queue.sv b/core/frontend/instr_queue.sv index a6658e7073..6e9a1163e4 100644 --- a/core/frontend/instr_queue.sv +++ b/core/frontend/instr_queue.sv @@ -298,6 +298,7 @@ ariane_pkg::FETCH_FIFO_DEPTH fetch_entry_o.ex.tval2 = '0; fetch_entry_o.ex.gva = 1'b0; fetch_entry_o.ex.tinst = '0; + fetch_entry_o.ex.priv_lvl = riscv::PRIV_LVL_M; // Only meaningful when receiving CLIC interrupts fetch_entry_o.branch_predict.predict_address = address_out; fetch_entry_o.branch_predict.cf = ariane_pkg::NoCF; // output mux select @@ -343,6 +344,7 @@ ariane_pkg::FETCH_FIFO_DEPTH fetch_entry_o.ex.gva = 1'b0; fetch_entry_o.ex.valid = instr_data_out[0].ex != ariane_pkg::FE_NONE; + fetch_entry_o.ex.priv_lvl = riscv::PRIV_LVL_M; // Only meaningful when receiving CLIC interrupts if (instr_data_out[0].ex == ariane_pkg::FE_INSTR_ACCESS_FAULT) begin fetch_entry_o.ex.cause = riscv::INSTR_ACCESS_FAULT; end else begin diff --git a/core/id_stage.sv b/core/id_stage.sv index dcff46d078..530ef2b010 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -63,6 +63,8 @@ module id_stage #( // TO_BE_COMPLETED - CLIC_CTRL input logic clic_irq_req_i, // TO_BE_COMPLETED - CLIC_CTRL + input riscv::priv_lvl_t clic_irq_priv_i, + // TO_BE_COMPLETED - CLIC_CTRL input riscv::xlen_t clic_irq_cause_i, // Is current mode debug ? - CSR_REGFILE input logic debug_mode_i, @@ -123,6 +125,7 @@ module id_stage #( .irq_ctrl_i, .clic_mode_i (clic_mode_i), .clic_irq_req_i (clic_irq_req_i), + .clic_irq_priv_i (clic_irq_priv_i), .clic_irq_cause_i (clic_irq_cause_i), .irq_i, .pc_i (fetch_entry_i.address), diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index b7ae4e2337..08aa356a01 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -199,6 +199,8 @@ package ariane_pkg; riscv::xlen_t tinst; // transformed instruction information logic gva; // signals when a guest virtual address is written to tval logic valid; + riscv::priv_lvl_t priv_lvl; // In CLIC mode, keeps information about + // incoming interrupt target privilege level } exception_t; typedef enum logic [2:0] { From 67f4acc3794284cd097c13d0260c66b4a745250b Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Mon, 5 Jun 2023 18:20:40 +0200 Subject: [PATCH 03/12] [ADD] Support for virtualised CLIC --- core/csr_regfile.sv | 32 +++++++++++++++++++++---- core/cva6.sv | 14 ++++++++++- core/cva6_clic_controller.sv | 46 +++++++++++++++++++++++++++++++----- core/decoder.sv | 3 +++ core/frontend/instr_queue.sv | 2 ++ core/id_stage.sv | 5 +++- core/include/ariane_pkg.sv | 14 +++++++++-- core/include/riscv_pkg.sv | 3 ++- 8 files changed, 104 insertions(+), 15 deletions(-) diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index f436a57490..b5d2700fe1 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -151,6 +151,8 @@ module csr_regfile // TO_BE_COMPLETED - CLIC_CTRL output logic [7:0] sintthresh_o, // TO_BE_COMPLETED - CLIC_CTRL + output logic [7:0] vsintthresh_o, + // TO_BE_COMPLETED - CLIC_CTRL output logic clic_irq_ready_o, // we are in single-step mode - COMMIT_STAGE output logic single_step_o, @@ -258,6 +260,7 @@ module csr_regfile riscv::xlen_t vsepc_q, vsepc_d; riscv::xlen_t vscause_q, vscause_d; riscv::xlen_t vstval_q, vstval_d; + riscv::intthresh_rv_t vsintthresh_q, vsintthresh_d; riscv::xlen_t dcache_q, dcache_d; riscv::xlen_t icache_q, icache_d; @@ -321,12 +324,14 @@ module csr_regfile assign mintstatus_o = mintstatus_q; assign mintthresh_o = mintthresh_q.th; assign sintthresh_o = sintthresh_q.th; + assign vsintthresh_o = vsintthresh_q.th; assign clic_irq_ready_o = clic_mode_o & ex_i.valid & ex_i.cause[riscv::XLEN-1]; end else begin : gen_dummy_clic_csr_signals assign clic_mode_o = 1'b0; assign mintstatus_o = '0; assign mintthresh_o = '0; assign sintthresh_o = '0; + assign vsintthresh_o = '0; assign clic_irq_ready_o = 1'b0; end @@ -513,7 +518,7 @@ module csr_regfile if (CVA6Cfg.RVH) csr_rdata = hideleg_q; else read_access_exception = 1'b1; riscv::CSR_HIE: - if (CVA6Cfg.RVH) csr_rdata = mie_q & HS_DELEG_INTERRUPTS; + if (CVA6Cfg.RVH) csr_rdata = mie_q & HIE_MASK; else read_access_exception = 1'b1; riscv::CSR_HIP: if (CVA6Cfg.RVH) csr_rdata = mip_q & HS_DELEG_INTERRUPTS; @@ -531,7 +536,7 @@ module csr_regfile if (CVA6Cfg.RVH) csr_rdata = htinst_q; else read_access_exception = 1'b1; riscv::CSR_HGEIE: - if (CVA6Cfg.RVH) csr_rdata = '0; + if (CVA6Cfg.RVH) csr_rdata = {hgeie_q[riscv::XLEN-1:1], 1'b0}; else read_access_exception = 1'b1; riscv::CSR_HGEIP: if (CVA6Cfg.RVH) csr_rdata = '0; @@ -948,6 +953,7 @@ module csr_regfile vscause_d = vscause_q; vstval_d = vstval_q; vsatp_d = vsatp_q; + vsintthresh_d = vsintthresh_q; sepc_d = sepc_q; scause_d = scause_q; @@ -1073,6 +1079,16 @@ module csr_regfile update_access_exception = 1'b1; end end + riscv::CSR_VSINTTHRESH: begin + if (CVA6Cfg.RVH && CVA6Cfg.RVSCLIC) begin + // Writes are legal but ignored in CLINT mode + if (clic_mode_o) begin + vsintthresh_d.th = csr_wdata[7:0]; + end + end else begin + update_access_exception = 1'b1; + end + end riscv::CSR_VSTVEC: begin if (CVA6Cfg.RVH) begin vstvec_d = {csr_wdata[riscv::XLEN-1:2], 1'b0, csr_wdata[0]}; @@ -1260,7 +1276,7 @@ module csr_regfile end riscv::CSR_HIE: begin if (CVA6Cfg.RVH) begin - mask = HS_DELEG_INTERRUPTS; + mask = HIE_MASK; mie_d = (mie_q & ~mask) | (csr_wdata & mask); end else begin update_access_exception = 1'b1; @@ -1307,6 +1323,8 @@ module csr_regfile riscv::CSR_HGEIE: begin if (!CVA6Cfg.RVH) begin update_access_exception = 1'b1; + end else begin + hgeie_d = {csr_wdata[riscv::XLEN-1:1], 1'b0}; end end riscv::CSR_HGATP: begin @@ -1742,6 +1760,7 @@ module csr_regfile trap_to_v = v_q; end else if (ex_i.cause[riscv::XLEN-1] && clic_mode_o) begin trap_to_priv_lvl = ex_i.priv_lvl; + trap_to_v = ex_i.trap_to_v; end end else begin if (CVA6Cfg.RVS && (ex_i.cause[riscv::XLEN-1] && mideleg_q[ex_i.cause[$clog2( @@ -1766,7 +1785,7 @@ module csr_regfile // this can either be user or supervisor mode vsstatus_d.spp = priv_lvl_q[0]; // set cause - vscause_d = ex_i.cause[riscv::XLEN-1] ? {ex_i.cause[riscv::XLEN-1:2], 2'b01} : ex_i.cause; + vscause_d = (~clic_mode_o & ex_i.cause[riscv::XLEN-1]) ? {ex_i.cause[riscv::XLEN-1:2], 2'b01} : ex_i.cause; // set epc vsepc_d = {{riscv::XLEN - riscv::VLEN{pc_i[riscv::VLEN-1]}}, pc_i}; // set vstval @@ -2148,6 +2167,9 @@ module csr_regfile assign irq_ctrl_o.mie = mie_q; assign irq_ctrl_o.mip = mip_q; assign irq_ctrl_o.sie = (CVA6Cfg.RVH && v_q) ? vsstatus_q.sie : mstatus_q.sie; + assign irq_ctrl_o.sgeie = CVA6Cfg.RVH ? mie_q[riscv::IRQ_HS_EXT] : '0; + assign irq_ctrl_o.hgeie = CVA6Cfg.RVH ? hgeie_q : '0; + assign irq_ctrl_o.vgein = CVA6Cfg.RVH ? hstatus_q.vgein : '0; assign irq_ctrl_o.mideleg = mideleg_q; assign irq_ctrl_o.hideleg = (CVA6Cfg.RVH) ? hideleg_q : '0; assign irq_ctrl_o.global_enable = (~debug_mode_q) @@ -2481,6 +2503,7 @@ module csr_regfile vsscratch_q <= {riscv::XLEN{1'b0}}; vstval_q <= {riscv::XLEN{1'b0}}; vsatp_q <= {riscv::XLEN{1'b0}}; + vsintthresh_q <= 8'b0; en_ld_st_g_translation_q <= 1'b0; end // timer and counters @@ -2566,6 +2589,7 @@ module csr_regfile vsscratch_q <= vsscratch_d; vstval_q <= vstval_d; vsatp_q <= vsatp_d; + vsintthresh_q <= vsintthresh_d; en_ld_st_g_translation_q <= en_ld_st_g_translation_d; end // timer and counters diff --git a/core/cva6.sv b/core/cva6.sv index 03b978b8c6..9bce82d993 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -136,6 +136,8 @@ module cva6 input logic [$clog2(CVA6Cfg.CLICNumInterruptSrc)-1:0] clic_irq_id_i, // interrupt source ID input logic [7:0] clic_irq_level_i, // interrupt level is 8-bit from CLIC spec input riscv::priv_lvl_t clic_irq_priv_i, // CLIC interrupt privilege level + input logic clic_irq_v_i, // CLIC interrupt virtualization bit + input logic [5:0] clic_irq_vsid_i, // CLIC interrupt Virtual Supervisor ID input logic clic_irq_shv_i, // selective hardware vectoring bit output logic clic_irq_ready_o, // core side interrupt hanshake (ready) input logic clic_kill_req_i, // kill request @@ -427,6 +429,7 @@ module cva6 riscv::intstatus_rv_t mintstatus_csr; logic [7:0] mintthresh_csr; logic [7:0] sintthresh_csr; + logic [7:0] vsintthresh_csr; logic dcache_en_csr_nbdcache; logic csr_write_fflags_commit_cs; logic icache_en_csr; @@ -529,6 +532,7 @@ module cva6 // ---------------------- logic clic_irq_req_id; riscv::priv_lvl_t clic_irq_priv_id; + logic clic_irq_v_id; riscv::xlen_t clic_irq_cause_id; // -------------- @@ -592,7 +596,8 @@ module cva6 .irq_ctrl_i (irq_ctrl_csr_id), .clic_mode_i (clic_mode), .clic_irq_req_i (clic_irq_req_id), - .clic_irq_priv_i ( clic_irq_priv_id), + .clic_irq_priv_i (clic_irq_priv_id), + .clic_irq_v_i (clic_irq_v_id), .clic_irq_cause_i(clic_irq_cause_id), .debug_mode_i (debug_mode), .tvm_i (tvm_csr_id), @@ -956,6 +961,7 @@ module cva6 .mintstatus_o (mintstatus_csr), .mintthresh_o (mintthresh_csr), .sintthresh_o (sintthresh_csr), + .vsintthresh_o (vsintthresh_csr), .clic_irq_shv_i (clic_irq_shv_i), .clic_irq_ready_o (clic_irq_ready_o), .ld_st_priv_lvl_o (ld_st_priv_lvl_csr_ex), @@ -1363,9 +1369,11 @@ module cva6 .rst_ni (rst_ni), // from CSR file .priv_lvl_i (priv_lvl), + .v_i (v), .irq_ctrl_i (irq_ctrl_csr_id), .mintthresh_i (mintthresh_csr), .sintthresh_i (sintthresh_csr), + .vsintthresh_i (vsintthresh_csr), .mintstatus_i (mintstatus_csr), // from/to CLIC .clic_irq_valid_i(clic_irq_valid_i), @@ -1373,17 +1381,21 @@ module cva6 .clic_irq_id_i (clic_irq_id_i), .clic_irq_level_i(clic_irq_level_i), .clic_irq_priv_i (clic_irq_priv_i), + .clic_irq_v_i (clic_irq_v_i), + .clic_irq_vsid_i (clic_irq_vsid_i), .clic_kill_req_i (clic_kill_req_i), .clic_kill_ack_o (clic_kill_ack_o), // to ID stage .clic_irq_req_o (clic_irq_req_id), .clic_irq_priv_o (clic_irq_priv_id), + .clic_irq_v_o (clic_irq_v_id), .clic_irq_cause_o(clic_irq_cause_id) ); end else begin : gen_dummy_clic_controller assign clic_kill_ack_o = 1'b0; assign clic_irq_req_id = 1'b0; assign clic_irq_priv_id = riscv::PRIV_LVL_M; + assign clic_irq_v_id = 1'b0; assign clic_irq_cause_id = '0; end diff --git a/core/cva6_clic_controller.sv b/core/cva6_clic_controller.sv index 1bcc7ea67a..381fd740da 100644 --- a/core/cva6_clic_controller.sv +++ b/core/cva6_clic_controller.sv @@ -11,9 +11,11 @@ module cva6_clic_controller #( input logic rst_ni, // from CSR file input riscv::priv_lvl_t priv_lvl_i, // current privilege level + input logic v_i, // current virtualization bit input ariane_pkg::irq_ctrl_t irq_ctrl_i, input logic [7:0] mintthresh_i, // M-mode interrupt threshold input logic [7:0] sintthresh_i, // S-mode interrupt threshold + input logic [7:0] vsintthresh_i, // VS-mode interrupt threshold input riscv::intstatus_rv_t mintstatus_i, // interrupt status // from/to CLIC input logic clic_irq_valid_i, // interrupt is valid @@ -21,11 +23,14 @@ module cva6_clic_controller #( input logic [$clog2(CVA6Cfg.CLICNumInterruptSrc)-1:0] clic_irq_id_i, // interrupt ID input logic [7:0] clic_irq_level_i, // interrupt level input riscv::priv_lvl_t clic_irq_priv_i, // interrupt privilege level + input logic clic_irq_v_i, // interrupt virtualization flag + input logic [5:0] clic_irq_vsid_i, // interrupt VS-id input logic clic_kill_req_i, // kill request output logic clic_kill_ack_o, // kill acknowledge // to ID stage output logic clic_irq_req_o, output riscv::priv_lvl_t clic_irq_priv_o, + output logic clic_irq_v_o, output riscv::xlen_t clic_irq_cause_o ); // ------- @@ -35,14 +40,17 @@ module cva6_clic_controller #( // irq threshold and global interrupt are enabled (otherwise it won't fire). // The effective interrupt threshold is the maximum of mintstatus.mil and // mintthresh, because interrupts with higher level have priority. - logic [7:0] max_mthresh, max_sthresh; + logic [7:0] max_mthresh, max_sthresh, max_vsthresh; assign max_mthresh = mintthresh_i > mintstatus_i.mil ? mintthresh_i : mintstatus_i.mil; assign max_sthresh = sintthresh_i > mintstatus_i.sil ? sintthresh_i : mintstatus_i.sil; + assign max_vsthresh = vsintthresh_i > mintstatus_i.vsil ? vsintthresh_i : mintstatus_i.vsil; // Determine if CLIC interrupt shall be accepted always_comb begin : clic_irq_accept - clic_irq_req_o = 1'b0; + clic_irq_priv_o = clic_irq_priv_i; + clic_irq_v_o = '0; + clic_irq_req_o = 1'b0; unique case (priv_lvl_i) riscv::PRIV_LVL_M: begin // Take M-mode interrupts with higher level @@ -56,7 +64,36 @@ module cva6_clic_controller #( clic_irq_req_o = clic_irq_valid_i; // Take S-mode interrupts with higher level end else if (clic_irq_priv_i == riscv::PRIV_LVL_S) begin - clic_irq_req_o = (clic_irq_level_i > max_sthresh) && (clic_irq_valid_i) && irq_ctrl_i.sie; + // clic_irq_req_o = (clic_irq_level_i > max_sthresh) && (clic_irq_valid_i) && irq_ctrl_i.sie; + if (v_i) begin + // Hart currently in VS-mode + if (clic_irq_v_i) begin + // Virtual interrrupt + if (clic_irq_vsid_i == irq_ctrl_i.vgein) begin + // VS-mode interrupt is for currently running VS + clic_irq_req_o = (clic_irq_level_i > max_vsthresh) && (clic_irq_valid_i) && irq_ctrl_i.vsie; + clic_irq_v_o = 1'b1; + end else begin + // Received IRQ delegated to a differet VS: trap to hypervisor if SGEIE == 1 (from hie). + // TODO: Should also depend on hgeie[irq_vsid]: should be integrated in CLIC or checked here? + clic_irq_req_o = (clic_irq_valid_i) && irq_ctrl_i.sgeie && irq_ctrl_i.hgeie[clic_irq_vsid_i]; + end + end else begin + // (Host) Supervisor interrupt + clic_irq_req_o = (clic_irq_level_i > max_sthresh) && (clic_irq_valid_i); // HS-mode sie is implicitly enabled in VS-mode + end + end else begin + // Hart currently in (H)S-mode + if (clic_irq_v_i) begin + // Virtual interrrupt + // TODO: Received VS-mode interrupt in Hypervisor mode: just ignore ? + end else begin + // (Host) Supervisor interrupt + clic_irq_req_o = (clic_irq_level_i > max_sthresh) && (clic_irq_valid_i) && irq_ctrl_i.sie; + end + end + end else begin + // TODO: an interrupt should always have mode == M or mode == S. What to do here ? end end riscv::PRIV_LVL_U: begin @@ -81,9 +118,6 @@ module cva6_clic_controller #( clic_irq_id_i }; // to mcause - // IRQ priv mode - assign clic_irq_priv_o = clic_irq_priv_i; - // ------------ // Kill Control // ------------ diff --git a/core/decoder.sv b/core/decoder.sv index 60ef52f83f..e1a633f9cd 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -51,6 +51,8 @@ module decoder // TO_BE_COMPLETED - CLIC_CTRL input riscv::priv_lvl_t clic_irq_priv_i, // TO_BE_COMPLETED - CLIC_CTRL + input logic clic_irq_v_i, + // TO_BE_COMPLETED - CLIC_CTRL input riscv::xlen_t clic_irq_cause_i, // Current privilege level - CSR_REGFILE input riscv::priv_lvl_t priv_lvl_i, @@ -1631,6 +1633,7 @@ module decoder instruction_o.ex.valid = 1'b1; instruction_o.ex.cause = interrupt_cause; instruction_o.ex.priv_lvl = clic_irq_priv_i; + instruction_o.ex.trap_to_v = clic_irq_v_i; end end end diff --git a/core/frontend/instr_queue.sv b/core/frontend/instr_queue.sv index 6e9a1163e4..96065c8909 100644 --- a/core/frontend/instr_queue.sv +++ b/core/frontend/instr_queue.sv @@ -299,6 +299,7 @@ ariane_pkg::FETCH_FIFO_DEPTH fetch_entry_o.ex.gva = 1'b0; fetch_entry_o.ex.tinst = '0; fetch_entry_o.ex.priv_lvl = riscv::PRIV_LVL_M; // Only meaningful when receiving CLIC interrupts + fetch_entry_o.ex.trap_to_v = '0; // Only meaningful when receiving CLIC interrupts fetch_entry_o.branch_predict.predict_address = address_out; fetch_entry_o.branch_predict.cf = ariane_pkg::NoCF; // output mux select @@ -345,6 +346,7 @@ ariane_pkg::FETCH_FIFO_DEPTH fetch_entry_o.ex.valid = instr_data_out[0].ex != ariane_pkg::FE_NONE; fetch_entry_o.ex.priv_lvl = riscv::PRIV_LVL_M; // Only meaningful when receiving CLIC interrupts + fetch_entry_o.ex.trap_to_v = '0; // Only meaningful when receiving CLIC interrupts if (instr_data_out[0].ex == ariane_pkg::FE_INSTR_ACCESS_FAULT) begin fetch_entry_o.ex.cause = riscv::INSTR_ACCESS_FAULT; end else begin diff --git a/core/id_stage.sv b/core/id_stage.sv index 530ef2b010..5cf200fb91 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -63,7 +63,9 @@ module id_stage #( // TO_BE_COMPLETED - CLIC_CTRL input logic clic_irq_req_i, // TO_BE_COMPLETED - CLIC_CTRL - input riscv::priv_lvl_t clic_irq_priv_i, + input riscv::priv_lvl_t clic_irq_priv_i, + // TO_BE_COMPLETED - CLIC_CTRL + input logic clic_irq_v_i, // TO_BE_COMPLETED - CLIC_CTRL input riscv::xlen_t clic_irq_cause_i, // Is current mode debug ? - CSR_REGFILE @@ -126,6 +128,7 @@ module id_stage #( .clic_mode_i (clic_mode_i), .clic_irq_req_i (clic_irq_req_i), .clic_irq_priv_i (clic_irq_priv_i), + .clic_irq_v_i (clic_irq_v_i), .clic_irq_cause_i (clic_irq_cause_i), .irq_i, .pc_i (fetch_entry_i.address), diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index 08aa356a01..3c16ddab4c 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -149,14 +149,19 @@ package ariane_pkg; | riscv::HSTATUS_SPV | riscv::HSTATUS_SPVP | riscv::HSTATUS_HU + | riscv::HSTATUS_VGEIN | riscv::HSTATUS_VTVM | riscv::HSTATUS_VTW | riscv::HSTATUS_VTSR; // hypervisor delegable interrupts - localparam logic [riscv::XLEN-1:0] HS_DELEG_INTERRUPTS = riscv::MIP_VSSIP + localparam logic [riscv::XLEN-1:0] HS_DELEG_INTERRUPTS = riscv::MIP_VSSIP; + + localparam logic [63:0] HIE_MASK = riscv::MIP_VSSIP | riscv::MIP_VSTIP - | riscv::MIP_VSEIP; + | riscv::MIP_VSEIP + | riscv::MIP_SGEIP; + // virtual supervisor delegable interrupts localparam logic [riscv::XLEN-1:0] VS_DELEG_INTERRUPTS = riscv::MIP_VSSIP | riscv::MIP_VSTIP @@ -201,6 +206,7 @@ package ariane_pkg; logic valid; riscv::priv_lvl_t priv_lvl; // In CLIC mode, keeps information about // incoming interrupt target privilege level + logic trap_to_v; } exception_t; typedef enum logic [2:0] { @@ -291,6 +297,10 @@ package ariane_pkg; riscv::xlen_t mideleg; riscv::xlen_t hideleg; logic sie; + logic vsie; // VS global interrupt enable + logic sgeie; + riscv::xlen_t hgeie; + logic [5:0] vgein; // Current VS external interrupt ID logic global_enable; } irq_ctrl_t; diff --git a/core/include/riscv_pkg.sv b/core/include/riscv_pkg.sv index 3e3f70a3ee..52290f15d6 100644 --- a/core/include/riscv_pkg.sv +++ b/core/include/riscv_pkg.sv @@ -165,7 +165,7 @@ package riscv; typedef struct packed { logic [7:0] mil; - logic [7:0] wpri; + logic [7:0] vsil; // wpri; logic [7:0] sil; logic [7:0] uil; } intstatus_rv_t; @@ -468,6 +468,7 @@ package riscv; CSR_VSCAUSE = 12'h242, CSR_VSTVAL = 12'h243, CSR_VSIP = 12'h244, + CSR_VSINTTHRESH = 12'h247, CSR_VSATP = 12'h280, // Supervisor Mode CSRs CSR_SSTATUS = 12'h100, From a502ac94529653600776b745d262001951a92a50 Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Tue, 4 Jul 2023 18:32:41 +0200 Subject: [PATCH 04/12] [FIX] CLIC interrupts when in U-mode --- core/cva6_clic_controller.sv | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/cva6_clic_controller.sv b/core/cva6_clic_controller.sv index 381fd740da..38cd29e6b3 100644 --- a/core/cva6_clic_controller.sv +++ b/core/cva6_clic_controller.sv @@ -98,9 +98,8 @@ module cva6_clic_controller #( end riscv::PRIV_LVL_U: begin // Take all M-mode and S-mode interrupts - clic_irq_req_o = ((clic_irq_valid_i) && - ((clic_irq_priv_i == riscv::PRIV_LVL_M) || - (clic_irq_priv_i == riscv::PRIV_LVL_S && irq_ctrl_i.sie))); + clic_irq_req_o = clic_irq_valid_i; + clic_irq_v_o = clic_irq_v_i; end default: ; endcase From 2c8dad03c10d3b576414a61527944760cb6de0ac Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Tue, 4 Jul 2023 18:40:36 +0200 Subject: [PATCH 05/12] [FIX] Remove unnecessary vsie signal from irq_ctrl_t --- core/cva6_clic_controller.sv | 2 +- core/include/ariane_pkg.sv | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/core/cva6_clic_controller.sv b/core/cva6_clic_controller.sv index 38cd29e6b3..9454b3b5c8 100644 --- a/core/cva6_clic_controller.sv +++ b/core/cva6_clic_controller.sv @@ -71,7 +71,7 @@ module cva6_clic_controller #( // Virtual interrrupt if (clic_irq_vsid_i == irq_ctrl_i.vgein) begin // VS-mode interrupt is for currently running VS - clic_irq_req_o = (clic_irq_level_i > max_vsthresh) && (clic_irq_valid_i) && irq_ctrl_i.vsie; + clic_irq_req_o = (clic_irq_level_i > max_vsthresh) && (clic_irq_valid_i) && irq_ctrl_i.sie; clic_irq_v_o = 1'b1; end else begin // Received IRQ delegated to a differet VS: trap to hypervisor if SGEIE == 1 (from hie). diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index 3c16ddab4c..47618e96ca 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -297,7 +297,6 @@ package ariane_pkg; riscv::xlen_t mideleg; riscv::xlen_t hideleg; logic sie; - logic vsie; // VS global interrupt enable logic sgeie; riscv::xlen_t hgeie; logic [5:0] vgein; // Current VS external interrupt ID From a238d82ec1a2f53c301d5d55bf3d40d0b80b2567 Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Tue, 4 Jul 2023 18:43:04 +0200 Subject: [PATCH 06/12] [FIX] Uninitialized signals in irq_ctrl_t struct --- core/branch_unit.sv | 2 + core/commit_stage.sv | 2 + core/csr_regfile.sv | 2 + core/cvxif_fu.sv | 4 ++ core/load_store_unit.sv | 20 +++++++ core/load_unit.sv | 2 + core/mmu_sv39x4/cva6_mmu_sv39x4.sv | 86 ++++++++++++++++++++++-------- 7 files changed, 96 insertions(+), 22 deletions(-) diff --git a/core/branch_unit.sv b/core/branch_unit.sv index 9a59402105..9bbdf984ac 100644 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -115,6 +115,8 @@ module branch_unit #( branch_exception_o.tval2 = {riscv::GPLEN{1'b0}}; branch_exception_o.tinst = {riscv::XLEN{1'b0}}; branch_exception_o.gva = CVA6Cfg.RVH ? v_i : 1'b0; + branch_exception_o.priv_lvl = riscv::PRIV_LVL_M; + branch_exception_o.trap_to_v = 1'b0; // Only throw instruction address misaligned exception if this is indeed a `taken` conditional branch or // an unconditional jump if (branch_valid_i && (target_address[0] || (!CVA6Cfg.RVC && target_address[1])) && jump_taken) begin diff --git a/core/commit_stage.sv b/core/commit_stage.sv index 8d86eb1946..d10ac6a44a 100644 --- a/core/commit_stage.sv +++ b/core/commit_stage.sv @@ -339,6 +339,8 @@ module commit_stage exception_o.tval2 = '0; exception_o.tinst = '0; exception_o.gva = 1'b0; + exception_o.priv_lvl = riscv::PRIV_LVL_M; + exception_o.trap_to_v = 1'b0; // we need a valid instruction in the commit stage if (commit_instr_i[0].valid) begin diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index b5d2700fe1..3e0531b6da 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -2260,6 +2260,8 @@ module csr_regfile {riscv::GPLEN{1'b0}}, {riscv::XLEN{1'b0}}, 1'b0, + 1'b0, + riscv::PRIV_LVL_M, 1'b0 }; // ---------------------------------- diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv index d417552947..f163361d5d 100644 --- a/core/cvxif_fu.sv +++ b/core/cvxif_fu.sv @@ -96,6 +96,8 @@ module cvxif_fu x_exception_o.tinst = '0; x_exception_o.tval2 = '0; x_exception_o.gva = '0; + x_exception_o.priv_lvl = riscv::PRIV_LVL_M; + x_exception_o.trap_to_v = 1'b0; x_we_o = x_valid_o ? cvxif_resp_i.x_result.we : '0; if (illegal_n) begin if (~x_valid_o) begin @@ -108,6 +110,8 @@ module cvxif_fu x_exception_o.tinst = '0; x_exception_o.tval2 = '0; x_exception_o.gva = '0; + x_exception_o.priv_lvl = riscv::PRIV_LVL_M; + x_exception_o.trap_to_v = 1'b0; x_we_o = '0; illegal_n = '0; // Reset flag for illegal instr. illegal_id and illegal instr values are a don't care, no need to reset it. end diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 04f222981b..cf9976262a 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -544,6 +544,8 @@ module load_store_unit {riscv::GPLEN{1'b0}}, {riscv::XLEN{1'b0}}, 1'b0, + 1'b0, + riscv::PRIV_LVL_M, 1'b0 }; data_misaligned = 1'b0; @@ -591,6 +593,9 @@ module load_store_unit misaligned_exception.tval2 = '0; misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; + misaligned_exception.valid = 1'b1; + misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; + misaligned_exception.trap_to_v = 1'b0; end else if (lsu_ctrl.fu == STORE) begin misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED; @@ -600,6 +605,9 @@ module load_store_unit misaligned_exception.tval2 = '0; misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; + misaligned_exception.valid = 1'b1; + misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; + misaligned_exception.trap_to_v = 1'b0; end end @@ -613,6 +621,9 @@ module load_store_unit misaligned_exception.tval2 = '0; misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; + misaligned_exception.valid = 1'b1; + misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; + misaligned_exception.trap_to_v = 1'b0; end else if (lsu_ctrl.fu == STORE) begin misaligned_exception.cause = riscv::ST_ACCESS_FAULT; @@ -622,6 +633,9 @@ module load_store_unit misaligned_exception.tval2 = '0; misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; + misaligned_exception.valid = 1'b1; + misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; + misaligned_exception.trap_to_v = 1'b0; end end @@ -635,6 +649,9 @@ module load_store_unit misaligned_exception.tval2 = '0; misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; + misaligned_exception.valid = 1'b1; + misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; + misaligned_exception.trap_to_v = 1'b0; end else if (lsu_ctrl.fu == STORE) begin misaligned_exception.cause = riscv::STORE_GUEST_PAGE_FAULT; misaligned_exception.valid = 1'b1; @@ -643,6 +660,9 @@ module load_store_unit misaligned_exception.tval2 = '0; misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; + misaligned_exception.valid = 1'b1; + misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; + misaligned_exception.trap_to_v = 1'b0; end end end diff --git a/core/load_unit.sv b/core/load_unit.sv index b8c0861963..1c35fc2c89 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -208,6 +208,8 @@ module load_unit assign ex_o.tval2 = CVA6Cfg.RVH ? ex_i.tval2 : '0; assign ex_o.tinst = CVA6Cfg.RVH ? ex_i.tinst : '0; assign ex_o.gva = CVA6Cfg.RVH ? ex_i.gva : 1'b0; + assign ex_o.priv_lvl = CVA6Cfg.RVH ? ex_i.priv_lvl : riscv::PRIV_LVL_M; + assign ex_o.trap_to_v = CVA6Cfg.RVH ? ex_i.trap_to_v : 1'b0; // Check that NI operations follow the necessary conditions logic paddr_ni; diff --git a/core/mmu_sv39x4/cva6_mmu_sv39x4.sv b/core/mmu_sv39x4/cva6_mmu_sv39x4.sv index 041bf14fe6..e51c678f72 100644 --- a/core/mmu_sv39x4/cva6_mmu_sv39x4.sv +++ b/core/mmu_sv39x4/cva6_mmu_sv39x4.sv @@ -291,7 +291,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, {{riscv::XLEN{1'b0}}}, v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end @@ -323,7 +325,9 @@ module cva6_mmu_sv39x4 itlb_gpaddr[riscv::GPLEN-1:0], {riscv::XLEN{1'b0}}, v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; // we got an access error end else if (iaccess_err) begin @@ -334,8 +338,10 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, {riscv::XLEN{1'b0}}, v_i, - 1'b1 - }; + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 + }; end else if (!pmp_instr_allow) begin icache_areq_o.fetch_exception = { riscv::INSTR_ACCESS_FAULT, @@ -343,7 +349,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, {riscv::XLEN{1'b0}}, v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end else @@ -361,7 +369,9 @@ module cva6_mmu_sv39x4 ptw_bad_gpaddr, (ptw_err_at_g_int_st ? (riscv::IS_XLEN64 ? riscv::READ_64_PSEUDOINSTRUCTION : riscv::READ_32_PSEUDOINSTRUCTION) : {riscv::XLEN{1'b0}}), v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end else begin icache_areq_o.fetch_exception = { @@ -370,7 +380,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, {riscv::XLEN{1'b0}}, v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end // TODO(moschn,zarubaf): What should the value of tval be in this case? @@ -381,7 +393,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, {riscv::XLEN{1'b0}}, v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end @@ -394,7 +408,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, {riscv::XLEN{1'b0}}, v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end @@ -515,7 +531,9 @@ module cva6_mmu_sv39x4 lsu_gpaddr_q, {riscv::XLEN{1'b0}}, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end else if (en_ld_st_translation_i && (!dtlb_pte_q.w || daccess_err || !dtlb_pte_q.d)) begin lsu_exception_o = { @@ -524,7 +542,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; // Check if any PMPs are violated end else if (!pmp_data_allow) begin @@ -534,7 +554,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end @@ -547,7 +569,9 @@ module cva6_mmu_sv39x4 lsu_gpaddr_q, {riscv::XLEN{1'b0}}, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; // check for sufficient access privileges - throw a page fault if necessary end else if (daccess_err) begin @@ -557,7 +581,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; // Check if any PMPs are violated end else if (!pmp_data_allow) begin @@ -567,7 +593,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end @@ -591,7 +619,9 @@ module cva6_mmu_sv39x4 ptw_bad_gpaddr, (ptw_err_at_g_int_st ? (riscv::IS_XLEN64 ? riscv::READ_64_PSEUDOINSTRUCTION : riscv::READ_32_PSEUDOINSTRUCTION) : {riscv::XLEN{1'b0}}), ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end else begin lsu_exception_o = { @@ -600,7 +630,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end else begin @@ -611,7 +643,9 @@ module cva6_mmu_sv39x4 ptw_bad_gpaddr, (ptw_err_at_g_int_st ? (riscv::IS_XLEN64 ? riscv::READ_64_PSEUDOINSTRUCTION : riscv::READ_32_PSEUDOINSTRUCTION) : {riscv::XLEN{1'b0}}), ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end else begin lsu_exception_o = { @@ -620,7 +654,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end @@ -636,7 +672,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end @@ -649,7 +687,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end else begin lsu_exception_o = { @@ -658,7 +698,9 @@ module cva6_mmu_sv39x4 {riscv::GPLEN{1'b0}}, lsu_tinst_q, ld_st_v_i, - 1'b1 + 1'b1, + riscv::PRIV_LVL_M, + 1'b0 }; end end From 959a034a0a8fb07ca3543840d69c9110e887fd6b Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Wed, 12 Jul 2023 10:55:11 +0200 Subject: [PATCH 07/12] [FIX] CLIC interrupts in U-mode --- core/cva6_clic_controller.sv | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/core/cva6_clic_controller.sv b/core/cva6_clic_controller.sv index 9454b3b5c8..bf47f61942 100644 --- a/core/cva6_clic_controller.sv +++ b/core/cva6_clic_controller.sv @@ -98,8 +98,33 @@ module cva6_clic_controller #( end riscv::PRIV_LVL_U: begin // Take all M-mode and S-mode interrupts - clic_irq_req_o = clic_irq_valid_i; - clic_irq_v_o = clic_irq_v_i; + if(clic_irq_priv_i == riscv::PRIV_LVL_M) begin + clic_irq_req_o = clic_irq_valid_i; + end else if (clic_irq_priv_i == riscv::PRIV_LVL_S) begin + if(v_i) begin // VU-mode + if(clic_irq_v_i) begin // irq is delegated to VM clic_irq_vsid_i + if (clic_irq_vsid_i == irq_ctrl_i.vgein) begin + // VS-mode interrupt is for currently running VS + clic_irq_req_o = clic_irq_valid_i; + clic_irq_v_o = 1'b1; + end else begin + // Received IRQ delegated to a differet VS: trap to hypervisor if SGEIE == 1 (from hie). + clic_irq_req_o = (clic_irq_valid_i) && irq_ctrl_i.sgeie && irq_ctrl_i.hgeie[clic_irq_vsid_i]; + end + end else begin + // (Host) Supervisor interrupt + clic_irq_req_o = clic_irq_valid_i; // HS-mode sie is implicitly enabled in VU-mode + end + end else begin // U-mode + if (clic_irq_v_i) begin + // Virtual interrrupt + // TODO: Received VS-mode interrupt in U-mode: just ignore ? + end else begin + // (Host) Supervisor interrupt + clic_irq_req_o = clic_irq_valid_i; // HS-mode sie is implicitly enabled in U-mode + end + end + end end default: ; endcase From fd1ce4b882d70542d43e811c134757dc3c199749 Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Mon, 4 Mar 2024 19:06:10 +0100 Subject: [PATCH 08/12] Update core/branch_unit.sv Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- core/branch_unit.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/branch_unit.sv b/core/branch_unit.sv index 9bbdf984ac..a2d0b79b19 100644 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -114,8 +114,8 @@ module branch_unit #( else branch_exception_o.tval = '0; branch_exception_o.tval2 = {riscv::GPLEN{1'b0}}; branch_exception_o.tinst = {riscv::XLEN{1'b0}}; - branch_exception_o.gva = CVA6Cfg.RVH ? v_i : 1'b0; - branch_exception_o.priv_lvl = riscv::PRIV_LVL_M; + branch_exception_o.gva = CVA6Cfg.RVH ? v_i : 1'b0; + branch_exception_o.priv_lvl = riscv::PRIV_LVL_M; branch_exception_o.trap_to_v = 1'b0; // Only throw instruction address misaligned exception if this is indeed a `taken` conditional branch or // an unconditional jump From eff9be562c44d1c6f8cf226879f90bbf7f254531 Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Mon, 4 Mar 2024 19:06:21 +0100 Subject: [PATCH 09/12] Update core/commit_stage.sv Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- core/commit_stage.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/commit_stage.sv b/core/commit_stage.sv index d10ac6a44a..8592ed43cb 100644 --- a/core/commit_stage.sv +++ b/core/commit_stage.sv @@ -338,8 +338,8 @@ module commit_stage exception_o.tval = '0; exception_o.tval2 = '0; exception_o.tinst = '0; - exception_o.gva = 1'b0; - exception_o.priv_lvl = riscv::PRIV_LVL_M; + exception_o.gva = 1'b0; + exception_o.priv_lvl = riscv::PRIV_LVL_M; exception_o.trap_to_v = 1'b0; // we need a valid instruction in the commit stage From 40ef35750a64d0db53cc2fd11cd726503570f8f8 Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Tue, 5 Mar 2024 15:16:25 +0100 Subject: [PATCH 10/12] fix lint errors --- core/commit_stage.sv | 2 +- core/csr_regfile.sv | 14 ++++++------ core/cva6_clic_controller.sv | 18 +++++++-------- core/cvxif_fu.sv | 4 ++-- core/decoder.sv | 2 +- core/frontend/instr_queue.sv | 4 ++-- core/include/ariane_pkg.sv | 6 ++--- core/include/riscv_pkg.sv | 2 +- core/load_store_unit.sv | 36 +++++++++++++++--------------- core/mmu_sv39x4/cva6_mmu_sv39x4.sv | 2 +- 10 files changed, 45 insertions(+), 45 deletions(-) diff --git a/core/commit_stage.sv b/core/commit_stage.sv index 8592ed43cb..17d6b1d971 100644 --- a/core/commit_stage.sv +++ b/core/commit_stage.sv @@ -335,7 +335,7 @@ module commit_stage // interrupts are correctly prioritized in the CSR reg file, exceptions are prioritized here exception_o.valid = 1'b0; exception_o.cause = '0; - exception_o.tval = '0; + exception_o.tval = '0; exception_o.tval2 = '0; exception_o.tinst = '0; exception_o.gva = 1'b0; diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 3e0531b6da..319e8ef82d 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -1080,14 +1080,14 @@ module csr_regfile end end riscv::CSR_VSINTTHRESH: begin - if (CVA6Cfg.RVH && CVA6Cfg.RVSCLIC) begin - // Writes are legal but ignored in CLINT mode - if (clic_mode_o) begin - vsintthresh_d.th = csr_wdata[7:0]; - end - end else begin - update_access_exception = 1'b1; + if (CVA6Cfg.RVH && CVA6Cfg.RVSCLIC) begin + // Writes are legal but ignored in CLINT mode + if (clic_mode_o) begin + vsintthresh_d.th = csr_wdata[7:0]; end + end else begin + update_access_exception = 1'b1; + end end riscv::CSR_VSTVEC: begin if (CVA6Cfg.RVH) begin diff --git a/core/cva6_clic_controller.sv b/core/cva6_clic_controller.sv index bf47f61942..929e15d03b 100644 --- a/core/cva6_clic_controller.sv +++ b/core/cva6_clic_controller.sv @@ -15,7 +15,7 @@ module cva6_clic_controller #( input ariane_pkg::irq_ctrl_t irq_ctrl_i, input logic [7:0] mintthresh_i, // M-mode interrupt threshold input logic [7:0] sintthresh_i, // S-mode interrupt threshold - input logic [7:0] vsintthresh_i, // VS-mode interrupt threshold + input logic [7:0] vsintthresh_i, // VS-mode interrupt threshold input riscv::intstatus_rv_t mintstatus_i, // interrupt status // from/to CLIC input logic clic_irq_valid_i, // interrupt is valid @@ -42,8 +42,8 @@ module cva6_clic_controller #( // mintthresh, because interrupts with higher level have priority. logic [7:0] max_mthresh, max_sthresh, max_vsthresh; - assign max_mthresh = mintthresh_i > mintstatus_i.mil ? mintthresh_i : mintstatus_i.mil; - assign max_sthresh = sintthresh_i > mintstatus_i.sil ? sintthresh_i : mintstatus_i.sil; + assign max_mthresh = mintthresh_i > mintstatus_i.mil ? mintthresh_i : mintstatus_i.mil; + assign max_sthresh = sintthresh_i > mintstatus_i.sil ? sintthresh_i : mintstatus_i.sil; assign max_vsthresh = vsintthresh_i > mintstatus_i.vsil ? vsintthresh_i : mintstatus_i.vsil; // Determine if CLIC interrupt shall be accepted @@ -98,22 +98,22 @@ module cva6_clic_controller #( end riscv::PRIV_LVL_U: begin // Take all M-mode and S-mode interrupts - if(clic_irq_priv_i == riscv::PRIV_LVL_M) begin + if (clic_irq_priv_i == riscv::PRIV_LVL_M) begin clic_irq_req_o = clic_irq_valid_i; end else if (clic_irq_priv_i == riscv::PRIV_LVL_S) begin - if(v_i) begin // VU-mode - if(clic_irq_v_i) begin // irq is delegated to VM clic_irq_vsid_i + if (v_i) begin // VU-mode + if (clic_irq_v_i) begin // irq is delegated to VM clic_irq_vsid_i if (clic_irq_vsid_i == irq_ctrl_i.vgein) begin // VS-mode interrupt is for currently running VS clic_irq_req_o = clic_irq_valid_i; - clic_irq_v_o = 1'b1; + clic_irq_v_o = 1'b1; end else begin // Received IRQ delegated to a differet VS: trap to hypervisor if SGEIE == 1 (from hie). clic_irq_req_o = (clic_irq_valid_i) && irq_ctrl_i.sgeie && irq_ctrl_i.hgeie[clic_irq_vsid_i]; end end else begin // (Host) Supervisor interrupt - clic_irq_req_o = clic_irq_valid_i; // HS-mode sie is implicitly enabled in VU-mode + clic_irq_req_o = clic_irq_valid_i; // HS-mode sie is implicitly enabled in VU-mode end end else begin // U-mode if (clic_irq_v_i) begin @@ -121,7 +121,7 @@ module cva6_clic_controller #( // TODO: Received VS-mode interrupt in U-mode: just ignore ? end else begin // (Host) Supervisor interrupt - clic_irq_req_o = clic_irq_valid_i; // HS-mode sie is implicitly enabled in U-mode + clic_irq_req_o = clic_irq_valid_i; // HS-mode sie is implicitly enabled in U-mode end end end diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv index f163361d5d..fe7e05176f 100644 --- a/core/cvxif_fu.sv +++ b/core/cvxif_fu.sv @@ -96,7 +96,7 @@ module cvxif_fu x_exception_o.tinst = '0; x_exception_o.tval2 = '0; x_exception_o.gva = '0; - x_exception_o.priv_lvl = riscv::PRIV_LVL_M; + x_exception_o.priv_lvl = riscv::PRIV_LVL_M; x_exception_o.trap_to_v = 1'b0; x_we_o = x_valid_o ? cvxif_resp_i.x_result.we : '0; if (illegal_n) begin @@ -110,7 +110,7 @@ module cvxif_fu x_exception_o.tinst = '0; x_exception_o.tval2 = '0; x_exception_o.gva = '0; - x_exception_o.priv_lvl = riscv::PRIV_LVL_M; + x_exception_o.priv_lvl = riscv::PRIV_LVL_M; x_exception_o.trap_to_v = 1'b0; x_we_o = '0; illegal_n = '0; // Reset flag for illegal instr. illegal_id and illegal instr values are a don't care, no need to reset it. diff --git a/core/decoder.sv b/core/decoder.sv index e1a633f9cd..eb248a27b3 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -49,7 +49,7 @@ module decoder // TO_BE_COMPLETED - CLIC_CTRL input logic clic_irq_req_i, // TO_BE_COMPLETED - CLIC_CTRL - input riscv::priv_lvl_t clic_irq_priv_i, + input riscv::priv_lvl_t clic_irq_priv_i, // TO_BE_COMPLETED - CLIC_CTRL input logic clic_irq_v_i, // TO_BE_COMPLETED - CLIC_CTRL diff --git a/core/frontend/instr_queue.sv b/core/frontend/instr_queue.sv index 96065c8909..aae988a2ee 100644 --- a/core/frontend/instr_queue.sv +++ b/core/frontend/instr_queue.sv @@ -299,7 +299,7 @@ ariane_pkg::FETCH_FIFO_DEPTH fetch_entry_o.ex.gva = 1'b0; fetch_entry_o.ex.tinst = '0; fetch_entry_o.ex.priv_lvl = riscv::PRIV_LVL_M; // Only meaningful when receiving CLIC interrupts - fetch_entry_o.ex.trap_to_v = '0; // Only meaningful when receiving CLIC interrupts + fetch_entry_o.ex.trap_to_v = '0; // Only meaningful when receiving CLIC interrupts fetch_entry_o.branch_predict.predict_address = address_out; fetch_entry_o.branch_predict.cf = ariane_pkg::NoCF; // output mux select @@ -346,7 +346,7 @@ ariane_pkg::FETCH_FIFO_DEPTH fetch_entry_o.ex.valid = instr_data_out[0].ex != ariane_pkg::FE_NONE; fetch_entry_o.ex.priv_lvl = riscv::PRIV_LVL_M; // Only meaningful when receiving CLIC interrupts - fetch_entry_o.ex.trap_to_v = '0; // Only meaningful when receiving CLIC interrupts + fetch_entry_o.ex.trap_to_v = '0; // Only meaningful when receiving CLIC interrupts if (instr_data_out[0].ex == ariane_pkg::FE_INSTR_ACCESS_FAULT) begin fetch_entry_o.ex.cause = riscv::INSTR_ACCESS_FAULT; end else begin diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index 47618e96ca..50b2e43560 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -204,8 +204,8 @@ package ariane_pkg; riscv::xlen_t tinst; // transformed instruction information logic gva; // signals when a guest virtual address is written to tval logic valid; - riscv::priv_lvl_t priv_lvl; // In CLIC mode, keeps information about - // incoming interrupt target privilege level + riscv::priv_lvl_t priv_lvl; // In CLIC mode, keeps information about + // incoming interrupt target privilege level logic trap_to_v; } exception_t; @@ -299,7 +299,7 @@ package ariane_pkg; logic sie; logic sgeie; riscv::xlen_t hgeie; - logic [5:0] vgein; // Current VS external interrupt ID + logic [5:0] vgein; // Current VS external interrupt ID logic global_enable; } irq_ctrl_t; diff --git a/core/include/riscv_pkg.sv b/core/include/riscv_pkg.sv index 52290f15d6..2e3c3cbbf7 100644 --- a/core/include/riscv_pkg.sv +++ b/core/include/riscv_pkg.sv @@ -165,7 +165,7 @@ package riscv; typedef struct packed { logic [7:0] mil; - logic [7:0] vsil; // wpri; + logic [7:0] vsil; // wpri; logic [7:0] sil; logic [7:0] uil; } intstatus_rv_t; diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index cf9976262a..db7dd70d5b 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -590,9 +590,9 @@ module load_store_unit misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr}; - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; misaligned_exception.valid = 1'b1; misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; misaligned_exception.trap_to_v = 1'b0; @@ -602,9 +602,9 @@ module load_store_unit misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr}; - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; misaligned_exception.valid = 1'b1; misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; misaligned_exception.trap_to_v = 1'b0; @@ -618,9 +618,9 @@ module load_store_unit misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr}; - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; misaligned_exception.valid = 1'b1; misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; misaligned_exception.trap_to_v = 1'b0; @@ -630,9 +630,9 @@ module load_store_unit misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr}; - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; misaligned_exception.valid = 1'b1; misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; misaligned_exception.trap_to_v = 1'b0; @@ -646,9 +646,9 @@ module load_store_unit misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr}; - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; misaligned_exception.valid = 1'b1; misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; misaligned_exception.trap_to_v = 1'b0; @@ -657,9 +657,9 @@ module load_store_unit misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) misaligned_exception.tval = {{riscv::XLEN - riscv::VLEN{1'b0}}, lsu_ctrl.vaddr}; - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; misaligned_exception.valid = 1'b1; misaligned_exception.priv_lvl = riscv::PRIV_LVL_M; misaligned_exception.trap_to_v = 1'b0; diff --git a/core/mmu_sv39x4/cva6_mmu_sv39x4.sv b/core/mmu_sv39x4/cva6_mmu_sv39x4.sv index e51c678f72..805704bb20 100644 --- a/core/mmu_sv39x4/cva6_mmu_sv39x4.sv +++ b/core/mmu_sv39x4/cva6_mmu_sv39x4.sv @@ -341,7 +341,7 @@ module cva6_mmu_sv39x4 1'b1, riscv::PRIV_LVL_M, 1'b0 - }; + }; end else if (!pmp_instr_allow) begin icache_areq_o.fetch_exception = { riscv::INSTR_ACCESS_FAULT, From e5139fbe3d02cdfacdc87c92f9ceba93a9a2129a Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Tue, 5 Mar 2024 15:25:34 +0100 Subject: [PATCH 11/12] add missing assignments in core/acc_dispatcher.sv --- core/acc_dispatcher.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/acc_dispatcher.sv b/core/acc_dispatcher.sv index 95cf93f4bb..f7783936bb 100644 --- a/core/acc_dispatcher.sv +++ b/core/acc_dispatcher.sv @@ -271,7 +271,9 @@ module acc_dispatcher tval2 : '0, tinst : '0, gva : '0, - valid: acc_resp_i.error + valid: acc_resp_i.error, + priv_lvl: riscv::PRIV_LVL_M, + trap_to_v: '0 }; assign acc_fflags_valid_o = acc_resp_i.fflags_valid; assign acc_fflags_o = acc_resp_i.fflags; From 9b56333ed0976633c356db9303e3ecd353ab8dd4 Mon Sep 17 00:00:00 2001 From: Enrico Zelioli Date: Wed, 6 Mar 2024 12:39:34 +0100 Subject: [PATCH 12/12] RVH: fix interrupt delegation --- core/csr_regfile.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 319e8ef82d..6e0304fbaa 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -437,7 +437,7 @@ module csr_regfile else read_access_exception = 1'b1; riscv::CSR_SIP: if (CVA6Cfg.RVS) - csr_rdata = clic_mode_o ? '0 : ((CVA6Cfg.RVH) ? mip_q & mideleg_q & ~HS_DELEG_INTERRUPTS : mip_q & mideleg_q); + csr_rdata = clic_mode_o ? '0 : ((CVA6Cfg.RVH) ? mip_q & mideleg_q & ~HIE_MASK : mip_q & mideleg_q); else read_access_exception = 1'b1; riscv::CSR_STVEC: if (CVA6Cfg.RVS) @@ -521,7 +521,7 @@ module csr_regfile if (CVA6Cfg.RVH) csr_rdata = mie_q & HIE_MASK; else read_access_exception = 1'b1; riscv::CSR_HIP: - if (CVA6Cfg.RVH) csr_rdata = mip_q & HS_DELEG_INTERRUPTS; + if (CVA6Cfg.RVH) csr_rdata = mip_q & HIE_MASK; else read_access_exception = 1'b1; riscv::CSR_HVIP: if (CVA6Cfg.RVH) csr_rdata = mip_q & VS_DELEG_INTERRUPTS; @@ -1284,7 +1284,7 @@ module csr_regfile end riscv::CSR_HIP: begin if (CVA6Cfg.RVH) begin - mask = riscv::MIP_VSSIP; + mask = HIE_MASK; mip_d = (mip_q & ~mask) | (csr_wdata & mask); end else begin update_access_exception = 1'b1;