Skip to content

Commit

Permalink
Parameterizes user mode features
Browse files Browse the repository at this point in the history
Signed-off-by: Halfdan Bechmann Dolva <halfdan.bechmann@silabs.com>
  • Loading branch information
halfdan-dolva committed Sep 11, 2023
1 parent 1c32f0e commit e4258ab
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 20 deletions.
19 changes: 16 additions & 3 deletions rtl/cv32e40s_cs_registers.sv
Expand Up @@ -616,7 +616,7 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;

// mscratchcsw: Scratch Swap for Multiple Privilege Modes
CSR_MSCRATCHCSW: begin
if (CLIC) begin
if (CLIC && USER) begin
// CLIC spec 13.2
// Depending on mstatus.MPP, we return either mscratch_rdata or rs1 to rd.
// Safe to use mstatus_rdata here (EX timing), as there is a generic stall of the ID stage
Expand Down Expand Up @@ -1032,7 +1032,7 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;
tinfo_we = 1'b0;

mstatus_n = csr_next_value(mstatus_t'{
tw: csr_wdata_int[MSTATUS_TW_BIT],
tw: mstatus_tw_resolve(mstatus_rdata.tw, csr_wdata_int[MSTATUS_TW_BIT]),
mprv: mstatus_mprv_resolve(mstatus_rdata.mprv, csr_wdata_int[MSTATUS_MPRV_BIT]),
mpp: mstatus_mpp_resolve(mstatus_rdata.mpp, csr_wdata_int[MSTATUS_MPP_BIT_HIGH:MSTATUS_MPP_BIT_LOW]),
mpie: csr_wdata_int[MSTATUS_MPIE_BIT],
Expand Down Expand Up @@ -1322,7 +1322,7 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;
end

CSR_MSCRATCHCSW: begin
if (CLIC) begin
if (CLIC && USER) begin
// mscratchcsw operates on mscratch
// Writing only when mstatus.mpp != PRIV_LVL_M
if (mstatus_rdata.mpp != PRIV_LVL_M) begin
Expand Down Expand Up @@ -2218,6 +2218,7 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;

assign csr_wr_in_wb_flush_o = xsecure_csr_wr_in_wb || pmp_csr_wr_in_wb || jvt_wr_in_wb;

if (USER) begin : privlvl_user
// Privilege level register
cv32e40s_csr
#(
Expand Down Expand Up @@ -2280,6 +2281,18 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;
end
end


end else begin : no_privlvl_user
assign priv_lvl_q = PRIV_LVL_M;
assign priv_lvl_rd_error = 1'b0;

assign priv_lvl_if_ctrl_o.priv_lvl = PRIV_LVL_M;
assign priv_lvl_if_ctrl_o.priv_lvl_set = 1'b0;

assign priv_lvl_lsu_o = PRIV_LVL_M;
end


generate
if (PMP_NUM_REGIONS > 0) begin: csr_pmp

Expand Down
2 changes: 1 addition & 1 deletion rtl/cv32e40s_debug_triggers.sv
Expand Up @@ -78,7 +78,7 @@ import cv32e40s_pkg::*;
);

// Set mask for supported exception codes for exception triggers.
localparam logic [31:0] ETRIGGER_TDATA2_MASK = (1 << EXC_CAUSE_INSTR_BUS_FAULT) | (1 << EXC_CAUSE_INSTR_INTEGRITY_FAULT) | (1 << EXC_CAUSE_ECALL_MMODE) | (1 << EXC_CAUSE_ECALL_UMODE) | (1 << EXC_CAUSE_STORE_FAULT) |
localparam logic [31:0] ETRIGGER_TDATA2_MASK = (1 << EXC_CAUSE_INSTR_BUS_FAULT) | (1 << EXC_CAUSE_INSTR_INTEGRITY_FAULT) | (1 << EXC_CAUSE_ECALL_MMODE) | ((USER) << EXC_CAUSE_ECALL_UMODE) | (1 << EXC_CAUSE_STORE_FAULT) |
(1 << EXC_CAUSE_LOAD_FAULT) | (1 << EXC_CAUSE_BREAKPOINT) | (1 << EXC_CAUSE_ILLEGAL_INSN) | (1 << EXC_CAUSE_INSTR_FAULT);


Expand Down
2 changes: 1 addition & 1 deletion rtl/cv32e40s_i_decoder.sv
Expand Up @@ -412,7 +412,7 @@ module cv32e40s_i_decoder import cv32e40s_pkg::*;

if (CLIC) begin
// The mscratchcsw[l] CSRs are only accessible using CSRRW with neither rd nor rs1 set to x0
if ((instr_rdata_i[31:20] == CSR_MSCRATCHCSW) || (instr_rdata_i[31:20] == CSR_MSCRATCHCSWL)) begin
if (((instr_rdata_i[31:20] == CSR_MSCRATCHCSW) && (USER)) || (instr_rdata_i[31:20] == CSR_MSCRATCHCSWL)) begin
if (instr_rdata_i[14:12] == 3'b001) begin // CSRRW
if ((instr_rdata_i[11:7] == 5'b0) || (instr_rdata_i[19:15] == 5'b0)) begin
// rd or rs1 is zero, flag instruction as illegal
Expand Down
84 changes: 69 additions & 15 deletions rtl/include/cv32e40s_pkg.sv
Expand Up @@ -541,7 +541,7 @@ typedef enum logic[1:0] {
PRIV_LVL_U = 2'b00
} privlvl_t;

parameter privlvl_t PRIV_LVL_LOWEST = PRIV_LVL_U;
parameter privlvl_t PRIV_LVL_LOWEST = (USER) ? PRIV_LVL_U : PRIV_LVL_M;

// Struct used for setting privilege lelve
typedef struct packed {
Expand Down Expand Up @@ -822,6 +822,9 @@ parameter logic [31:0] TDATA1_RST_VAL = {
// Enable Security Features
parameter SECURE = 1;

// Enable User Mode
parameter bit USER = SECURE;

// Register file read/write ports
parameter REGFILE_NUM_WRITE_PORTS = 1;

Expand Down Expand Up @@ -1525,44 +1528,85 @@ typedef struct packed {
privlvl_t current_value,
logic [1:0] next_value
);
// dcsr.prv is WARL(0x0, 0x3)
return ((next_value != PRIV_LVL_M) && (next_value != PRIV_LVL_U)) ? current_value : privlvl_t'(next_value);
if (USER) begin
// dcsr.prv is WARL(0x0, 0x3)
return ((next_value != PRIV_LVL_M) && (next_value != PRIV_LVL_U)) ? current_value : privlvl_t'(next_value);
end else begin
// dcsr.prv is WARL(0x3)
return PRIV_LVL_M;
end
endfunction

function automatic logic dcsr_ebreaku_resolve
(
logic current_value,
logic next_value
);
// dcsr.ebreaku is WARL
return next_value;
if (USER) begin
// dcsr.ebreaku is WARL
return next_value;
end else begin
// dcsr.ebreaku is WARL(0x0)
return 1'b0;
end

endfunction

function automatic logic [1:0] mstatus_mpp_resolve
(
logic [1:0] current_value,
logic [1:0] next_value
);
// mstatus.mpp is WARL(0x0, 0x3)
return ((next_value != PRIV_LVL_M) && (next_value != PRIV_LVL_U)) ? current_value : next_value;
if (USER) begin
// mstatus.mpp is WARL(0x0, 0x3)
return ((next_value != PRIV_LVL_M) && (next_value != PRIV_LVL_U)) ? current_value : next_value;
end else begin
// mstatus.mpp is WARL(0x3)
return PRIV_LVL_M;
end

endfunction

function automatic logic [1:0] mcause_mpp_resolve
(
logic [1:0] current_value,
logic [1:0] next_value
);
// mcause.mpp is WARL(0x0, 0x3)
return ((next_value != PRIV_LVL_M) && (next_value != PRIV_LVL_U)) ? current_value : next_value;
if (USER) begin
// mcause.mpp is WARL(0x0, 0x3)
return ((next_value != PRIV_LVL_M) && (next_value != PRIV_LVL_U)) ? current_value : next_value;
end else begin
// mcause.mpp is WARL(0x3)
return PRIV_LVL_M;
end

endfunction

function automatic logic mstatus_mprv_resolve
(
logic current_value,
logic next_value
);
// mstatus.mprv is is RW
return next_value;
if (USER) begin
// mstatus.mprv is is RW
return next_value;
end else begin
// mstatus.mprv is WARL(0x0)
return 1'b0;
end
endfunction

function automatic logic mstatus_tw_resolve
(
logic current_value,
logic next_value
);
if (USER) begin
// mstatus.tw is is RW
return next_value;
end else begin
return 1'b0;
end
endfunction

function automatic logic [3:0] mcontrol2_6_match_resolve
Expand All @@ -1576,8 +1620,13 @@ typedef struct packed {
(
logic next_value
);
// mcontrol6.u is WARL
return next_value;
if (USER) begin
// mcontrol6.u is WARL
return next_value;
end else begin
// mcontrol2/6.u is WARL(0x0)
return 1'b0;
end
endfunction

function automatic logic mcontrol6_uncertain_resolve
Expand Down Expand Up @@ -1609,8 +1658,13 @@ typedef struct packed {
(
logic next_value
);
// etrigger.u is WARL
return next_value;
if (USER) begin
// etrigger.u is WARL
return next_value;
end else begin
// etrigger.u is WARL(0x0)
return 1'b0;
end
endfunction

function automatic logic[1:0] mtvec_mode_clint_resolve
Expand Down

0 comments on commit e4258ab

Please sign in to comment.