mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 12:57:13 -04:00
Cause illegal instruction exception for access violations on CSRs
This commit adds checks to CSR accesses. If a CSR is accessed that is not implemented, or if a read-only CSR is written to, an illegal instruction exception is caused.
This commit is contained in:
parent
3ea6744f81
commit
d4b349766e
4 changed files with 46 additions and 10 deletions
|
@ -139,6 +139,8 @@ module ibex_core #(
|
|||
csr_num_e csr_addr;
|
||||
logic [31:0] csr_rdata;
|
||||
logic [31:0] csr_wdata;
|
||||
logic illegal_csr_insn_id; // CSR access to non-existent register,
|
||||
// with wrong priviledge level, or missing write permissions
|
||||
|
||||
// Data Memory Control
|
||||
logic data_we_ex;
|
||||
|
@ -345,6 +347,7 @@ module ibex_core #(
|
|||
.csr_restore_mret_id_o ( csr_restore_mret_id ), // control signal to restore pc
|
||||
.csr_restore_dret_id_o ( csr_restore_dret_id ), // control signal to restore pc
|
||||
.csr_save_cause_o ( csr_save_cause ),
|
||||
.illegal_csr_insn_i ( illegal_csr_insn_id ),
|
||||
|
||||
// LSU
|
||||
.data_req_ex_o ( data_req_ex ), // to load store unit
|
||||
|
@ -520,7 +523,7 @@ module ibex_core #(
|
|||
.csr_restore_dret_i ( csr_restore_dret_id ),
|
||||
.csr_cause_i ( csr_cause ),
|
||||
.csr_save_cause_i ( csr_save_cause ),
|
||||
|
||||
.illegal_csr_insn_o ( illegal_csr_insn_id ),
|
||||
|
||||
// performance counter related signals
|
||||
.insn_ret_i ( insn_ret ),
|
||||
|
|
|
@ -71,6 +71,9 @@ module ibex_cs_registers #(
|
|||
input ibex_defines::exc_cause_e csr_cause_i,
|
||||
input logic csr_save_cause_i,
|
||||
|
||||
output logic illegal_csr_insn_o, // access to non-existent CSR,
|
||||
// with wrong priviledge level, or
|
||||
// missing write permissions
|
||||
// Performance Counters
|
||||
input logic insn_ret_i, // instr retired in ID/EX stage
|
||||
input logic if_valid_i, // IF stage gives a new instr
|
||||
|
@ -79,7 +82,7 @@ module ibex_cs_registers #(
|
|||
input logic is_decoding_i, // controller is in DECODE state
|
||||
|
||||
input logic imiss_i, // instr fetch
|
||||
input logic pc_set_i, // pc was set to a new value
|
||||
input logic pc_set_i, // PC was set to a new value
|
||||
input logic jump_i, // jump instr seen (j, jr, jal, jalr)
|
||||
input logic branch_i, // branch instr seen (bf, bnf)
|
||||
input logic branch_taken_i, // branch was taken
|
||||
|
@ -200,6 +203,11 @@ module ibex_cs_registers #(
|
|||
Status_t mstatus_q, mstatus_n;
|
||||
logic [31:0] exception_pc;
|
||||
|
||||
// Access violation signals
|
||||
logic illegal_csr;
|
||||
logic illegal_csr_priv;
|
||||
logic illegal_csr_write;
|
||||
|
||||
/////////////
|
||||
// CSR reg //
|
||||
/////////////
|
||||
|
@ -208,9 +216,14 @@ module ibex_cs_registers #(
|
|||
assign csr_addr = {csr_addr_i};
|
||||
assign mhpmcounter_idx = csr_addr[4:0];
|
||||
|
||||
assign illegal_csr_priv = 1'b0; // we only support M-mode
|
||||
assign illegal_csr_write = (csr_addr[11:10] == 2'b11) && csr_we_int;
|
||||
assign illegal_csr_insn_o = illegal_csr | illegal_csr_write | illegal_csr_priv;
|
||||
|
||||
// read logic
|
||||
always_comb begin
|
||||
csr_rdata_int = '0;
|
||||
illegal_csr = 1'b0;
|
||||
|
||||
unique case (csr_addr_i)
|
||||
// mstatus: always M-mode, contains IE bit
|
||||
|
@ -256,10 +269,32 @@ module ibex_cs_registers #(
|
|||
default: begin
|
||||
if (csr_addr_i == CSR_MCOUNTER_SETUP_MASK) begin
|
||||
csr_rdata_int = mhpmevent[mhpmcounter_idx];
|
||||
// check access to non-existent or already covered CSRs
|
||||
if ((csr_addr[4:0] == 5'b00000) || // CSR_MCOUNTINHIBIT
|
||||
(csr_addr[4:0] == 5'b00001) ||
|
||||
(csr_addr[4:0] == 5'b00010)) begin
|
||||
illegal_csr = csr_access_i;
|
||||
end
|
||||
|
||||
end else if (csr_addr_i == CSR_MCOUNTER_MASK) begin
|
||||
csr_rdata_int = mhpmcounter_q[mhpmcounter_idx][31: 0];
|
||||
// check access to non-existent or already covered CSRs
|
||||
if ((csr_addr[4:0] == 5'b00000) || // CSR_MCYCLE
|
||||
(csr_addr[4:0] == 5'b00001) ||
|
||||
(csr_addr[4:0] == 5'b00010)) begin // CSR_MINSTRET
|
||||
illegal_csr = csr_access_i;
|
||||
end
|
||||
|
||||
end else if (csr_addr_i == CSR_MCOUNTERH_MASK) begin
|
||||
csr_rdata_int = mhpmcounter_q[mhpmcounter_idx][63:32];
|
||||
// check access to non-existent or already covered CSRs
|
||||
if ((csr_addr[4:0] == 5'b00000) || // CSR_MCYCLEH
|
||||
(csr_addr[4:0] == 5'b00001) ||
|
||||
(csr_addr[4:0] == 5'b00010)) begin // CSR_MINSTRETH
|
||||
illegal_csr = csr_access_i;
|
||||
end
|
||||
end else begin
|
||||
illegal_csr = csr_access_i;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
|
|
@ -96,7 +96,6 @@ module ibex_decoder #(
|
|||
logic branch_in_id;
|
||||
logic jump_in_id;
|
||||
|
||||
csr_op_e csr_op;
|
||||
logic csr_illegal;
|
||||
|
||||
opcode_e opcode;
|
||||
|
@ -125,7 +124,7 @@ module ibex_decoder #(
|
|||
csr_access_o = 1'b0;
|
||||
csr_status_o = 1'b0;
|
||||
csr_illegal = 1'b0;
|
||||
csr_op = CSR_OP_NONE;
|
||||
csr_op_o = CSR_OP_NONE;
|
||||
|
||||
data_we_o = 1'b0;
|
||||
data_type_o = 2'b00;
|
||||
|
@ -496,9 +495,9 @@ module ibex_decoder #(
|
|||
end
|
||||
|
||||
unique case (instr_rdata_i[13:12])
|
||||
2'b01: csr_op = CSR_OP_WRITE;
|
||||
2'b10: csr_op = CSR_OP_SET;
|
||||
2'b11: csr_op = CSR_OP_CLEAR;
|
||||
2'b01: csr_op_o = CSR_OP_WRITE;
|
||||
2'b10: csr_op_o = CSR_OP_SET;
|
||||
2'b11: csr_op_o = CSR_OP_CLEAR;
|
||||
default: csr_illegal = 1'b1;
|
||||
endcase
|
||||
|
||||
|
@ -514,7 +513,6 @@ module ibex_decoder #(
|
|||
end
|
||||
|
||||
illegal_insn_o = csr_illegal;
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -549,7 +547,6 @@ module ibex_decoder #(
|
|||
assign mult_int_en_o = RV32M ? ((deassert_we_i) ? 1'b0 : mult_int_en) : 1'b0;
|
||||
assign div_int_en_o = RV32M ? ((deassert_we_i) ? 1'b0 : div_int_en ) : 1'b0;
|
||||
assign data_req_o = (deassert_we_i) ? 1'b0 : data_req;
|
||||
assign csr_op_o = (deassert_we_i) ? CSR_OP_NONE : csr_op;
|
||||
assign jump_in_id_o = (deassert_we_i) ? 1'b0 : jump_in_id;
|
||||
assign branch_in_id_o = (deassert_we_i) ? 1'b0 : branch_in_id;
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ module ibex_id_stage #(
|
|||
output logic csr_restore_mret_id_o,
|
||||
output logic csr_restore_dret_id_o,
|
||||
output logic csr_save_cause_o,
|
||||
input logic illegal_csr_insn_i,
|
||||
|
||||
// Interface to load store unit
|
||||
output logic data_req_ex_o,
|
||||
|
@ -407,7 +408,7 @@ module ibex_id_stage #(
|
|||
////////////////
|
||||
// Controller //
|
||||
////////////////
|
||||
assign illegal_insn_o = illegal_insn_dec | illegal_reg_rv32e;
|
||||
assign illegal_insn_o = illegal_insn_dec | illegal_reg_rv32e | illegal_csr_insn_i;
|
||||
|
||||
ibex_controller controller_i (
|
||||
.clk_i ( clk_i ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue