Plumb privilege state through to the bus ports
This commit is contained in:
parent
cfed35b3da
commit
4878a752d6
|
@ -81,14 +81,12 @@ wire debug_mode;
|
|||
assign dbg_halted = DEBUG_SUPPORT && debug_mode;
|
||||
assign dbg_running = DEBUG_SUPPORT && !debug_mode;
|
||||
|
||||
assign bus_priv_i = 1'b1;
|
||||
always @ (*) bus_priv_d = 1'b1;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Pipe Stage F
|
||||
|
||||
wire f_jump_req;
|
||||
wire [W_ADDR-1:0] f_jump_target;
|
||||
wire f_jump_priv;
|
||||
wire f_jump_rdy;
|
||||
wire f_jump_now = f_jump_req && f_jump_rdy;
|
||||
|
||||
|
@ -118,6 +116,7 @@ hazard3_frontend #(
|
|||
|
||||
.mem_size (f_mem_size),
|
||||
.mem_addr (bus_haddr_i),
|
||||
.mem_priv (bus_priv_i),
|
||||
.mem_addr_vld (bus_aph_req_i),
|
||||
.mem_addr_rdy (bus_aph_ready_i),
|
||||
|
||||
|
@ -126,6 +125,7 @@ hazard3_frontend #(
|
|||
.mem_data_vld (bus_dph_ready_i),
|
||||
|
||||
.jump_target (f_jump_target),
|
||||
.jump_priv (f_jump_priv),
|
||||
.jump_target_vld (f_jump_req),
|
||||
.jump_target_rdy (f_jump_rdy),
|
||||
|
||||
|
@ -257,6 +257,11 @@ wire m_trap_enter_vld;
|
|||
wire m_trap_enter_soon;
|
||||
wire m_trap_enter_rdy = f_jump_rdy;
|
||||
|
||||
// Privilege state outputs from CSR block
|
||||
wire x_mmode_execution;
|
||||
wire x_mmode_loadstore;
|
||||
wire m_mmode_trap_entry;
|
||||
|
||||
reg [W_REGADDR-1:0] xm_rs1;
|
||||
reg [W_REGADDR-1:0] xm_rs2;
|
||||
reg [W_REGADDR-1:0] xm_rd;
|
||||
|
@ -554,6 +559,7 @@ always @ (*) begin
|
|||
// Need to be careful not to use anything hready-sourced to gate htrans!
|
||||
bus_haddr_d = x_addr_sum;
|
||||
bus_hwrite_d = x_memop_write;
|
||||
bus_priv_d = x_mmode_loadstore;
|
||||
case (d_memop)
|
||||
MEMOP_LW: bus_hsize_d = HSIZE_WORD;
|
||||
MEMOP_SW: bus_hsize_d = HSIZE_WORD;
|
||||
|
@ -804,6 +810,10 @@ hazard3_csr #(
|
|||
.mepc_in (m_exception_return_addr),
|
||||
.wfi_stall_clear (m_wfi_stall_clear),
|
||||
|
||||
.m_mode_execution (x_mmode_execution),
|
||||
.m_mode_loadstore (x_mmode_loadstore),
|
||||
.m_mode_trap_entry (m_mmode_trap_entry),
|
||||
|
||||
// IRQ and exception requests
|
||||
.delay_irq_entry (xm_delay_irq_entry),
|
||||
.irq (irq),
|
||||
|
@ -887,6 +897,7 @@ reg [W_DATA-1:0] m_result;
|
|||
|
||||
assign f_jump_req = x_jump_req || m_trap_enter_vld;
|
||||
assign f_jump_target = m_trap_enter_vld ? m_trap_addr : x_jump_target;
|
||||
assign f_jump_priv = m_trap_enter_vld ? m_mmode_trap_entry : x_mmode_execution;
|
||||
assign x_jump_not_except = !m_trap_enter_vld;
|
||||
|
||||
// EXCEPT_NONE clause is needed in the following sequence:
|
||||
|
|
|
@ -81,6 +81,11 @@ module hazard3_csr #(
|
|||
input wire [XLEN-1:0] mepc_in,
|
||||
output wire wfi_stall_clear,
|
||||
|
||||
// Each of these may be performed at a different privilege level from the others:
|
||||
output wire m_mode_execution,
|
||||
output wire m_mode_trap_entry,
|
||||
output wire m_mode_loadstore,
|
||||
|
||||
// Exceptions must *not* be a function of bus stall.
|
||||
input wire [W_EXCEPT-1:0] except,
|
||||
|
||||
|
@ -90,6 +95,7 @@ module hazard3_csr #(
|
|||
input wire irq_software,
|
||||
input wire irq_timer,
|
||||
|
||||
|
||||
// Other CSR-specific signalling
|
||||
input wire instr_ret
|
||||
);
|
||||
|
@ -1027,6 +1033,32 @@ assign trap_enter_soon = trap_enter_vld || (
|
|||
assign mcause_irq_next = !exception_req_any;
|
||||
assign mcause_code_next = exception_req_any ? {2'h0, except} : mcause_irq_num;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Privilege state outputs
|
||||
|
||||
// Effective privilege for execution. Used for:
|
||||
// - Privilege level of branch target fetches (frontend keeps fetch privilege
|
||||
// constant during sequential fetch)
|
||||
// - Checking PC against PMP execute permission
|
||||
|
||||
assign m_mode_execution = !U_MODE || debug_mode || m_mode;
|
||||
|
||||
// Effective privilege for trap entry. Used for:
|
||||
// - Privilege level of trap target fetches (frontend keeps fetch privilege
|
||||
// constant during sequential fetch)
|
||||
|
||||
assign m_mode_trap_entry = !U_MODE || (
|
||||
except == EXCEPT_MRET ? mstatus_mpp : 1'b1
|
||||
);
|
||||
|
||||
// Effective privilege for load/stores. Used for:
|
||||
// - Privilege level of load/stores on the bus
|
||||
// - Checking load/stores against PMP read/write permission
|
||||
|
||||
assign m_mode_loadstore = !U_MODE || debug_mode || ( // FIXME how does this interact with load/store racing against debug entry?
|
||||
mstatus_mprv ? mstatus_mpp : m_mode
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Properties
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ module hazard3_frontend #(
|
|||
// may not be used to compute combinational outputs.
|
||||
output wire mem_size, // 1'b1 -> 32 bit access
|
||||
output wire [W_ADDR-1:0] mem_addr,
|
||||
output wire mem_priv,
|
||||
output wire mem_addr_vld,
|
||||
input wire mem_addr_rdy,
|
||||
input wire [W_DATA-1:0] mem_data,
|
||||
|
@ -32,6 +33,7 @@ module hazard3_frontend #(
|
|||
// unless rdy is high. Processor *may* alter request during this time.
|
||||
// Inputs must not be a function of hready.
|
||||
input wire [W_ADDR-1:0] jump_target,
|
||||
input wire jump_priv,
|
||||
input wire jump_target_vld,
|
||||
output wire jump_target_rdy,
|
||||
|
||||
|
@ -179,14 +181,18 @@ end
|
|||
|
||||
// Fetch addr runs ahead of the PC, in word increments.
|
||||
reg [W_ADDR-1:0] fetch_addr;
|
||||
reg fetch_priv;
|
||||
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
fetch_addr <= RESET_VECTOR;
|
||||
// M-mode at reset:
|
||||
fetch_priv <= 1'b1;
|
||||
end else begin
|
||||
if (jump_now) begin
|
||||
// Post-increment if jump request is going straight through
|
||||
fetch_addr <= {jump_target[W_ADDR-1:2] + (mem_addr_rdy && !mem_addr_hold), 2'b00};
|
||||
fetch_priv <= jump_priv || !U_MODE;
|
||||
end else if (mem_addr_vld && mem_addr_rdy) begin
|
||||
fetch_addr <= fetch_addr + 32'h4;
|
||||
end
|
||||
|
@ -263,19 +269,25 @@ always @ (posedge clk or negedge rst_n)
|
|||
reset_holdoff <= 1'b0;
|
||||
|
||||
reg [W_ADDR-1:0] mem_addr_r;
|
||||
reg mem_addr_vld_r;
|
||||
reg mem_priv_r;
|
||||
reg mem_addr_vld_r;
|
||||
|
||||
// Downstream accesses are always word-sized word-aligned.
|
||||
assign mem_addr = mem_addr_r;
|
||||
assign mem_priv = mem_addr_r;
|
||||
assign mem_addr_vld = mem_addr_vld_r && !reset_holdoff;
|
||||
assign mem_size = 1'b1;
|
||||
|
||||
always @ (*) begin
|
||||
mem_addr_r = {W_ADDR{1'b0}};
|
||||
mem_priv_r = fetch_priv;
|
||||
mem_addr_vld_r = 1'b1;
|
||||
case (1'b1)
|
||||
mem_addr_hold : begin mem_addr_r = fetch_addr; end
|
||||
jump_target_vld : begin mem_addr_r = {jump_target[W_ADDR-1:2], 2'b00}; end
|
||||
jump_target_vld : begin
|
||||
mem_addr_r = {jump_target[W_ADDR-1:2], 2'b00};
|
||||
mem_priv_r = jump_priv || !U_MODE;
|
||||
end
|
||||
DEBUG_SUPPORT && debug_mode : begin mem_addr_vld_r = 1'b0; end
|
||||
!fetch_stall : begin mem_addr_r = fetch_addr; end
|
||||
default : begin mem_addr_vld_r = 1'b0; end
|
||||
|
@ -443,4 +455,6 @@ end
|
|||
|
||||
endmodule
|
||||
|
||||
`ifndef YOSYS
|
||||
`default_nettype wire
|
||||
`endif
|
||||
|
|
Loading…
Reference in New Issue