Bring mtvec vectoring modes in line with spec: all exceptions go to mtvec, IRQs are optionally vectored away from it if mtvec LSB is set
This commit is contained in:
parent
cec5dc4e3b
commit
12851d3742
|
@ -12,8 +12,16 @@ parameter RESET_VECTOR = 32'h0,
|
|||
|
||||
// MTVEC_INIT: Initial value of trap vector base. Bits clear in MTVEC_WMASK
|
||||
// will never change from this initial value. Bits set in MTVEC_WMASK can be
|
||||
// written/set/cleared as normal. Note that, if CSR_M_TRAP is set, MTVEC_INIT
|
||||
// should probably have a different value from RESET_VECTOR.
|
||||
// written/set/cleared as normal.
|
||||
//
|
||||
// Note that, if CSR_M_TRAP is set, MTVEC_INIT should probably have a
|
||||
// different value from RESET_VECTOR.
|
||||
//
|
||||
// Note that mtvec bits 1:0 do not affect the trap base (as per RISC-V spec).
|
||||
// Bit 1 is don't care, bit 0 selects the vectoring mode: unvectored if == 0
|
||||
// (all traps go to mtvec), vectored if == 1 (exceptions go to mtvec, IRQs to
|
||||
// mtvec + mcause * 4). This means MTVEC_INIT also sets the initial vectoring
|
||||
// mode.
|
||||
parameter MTVEC_INIT = 32'h00000000,
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -66,10 +74,13 @@ parameter MULDIV_UNROLL = 1,
|
|||
parameter MUL_FAST = 0,
|
||||
|
||||
// MTVEC_WMASK: Mask of which bits in MTVEC are modifiable. Save gates by
|
||||
// making trap vector base partly fixed (legal, as it's WARL). Note the entire
|
||||
// vector table must always be aligned to its size, rounded up to a power of
|
||||
// two, so careful with the low-order bits.
|
||||
parameter MTVEC_WMASK = 32'hfffff000,
|
||||
// making trap vector base partly fixed (legal, as it's WARL).
|
||||
//
|
||||
// - The vectoring mode can be made fixed by clearing the LSB of MTVEC_WMASK
|
||||
//
|
||||
// - Note the entire vector table must always be aligned to its size, rounded
|
||||
// up to a power of two, so careful with the low-order bits.
|
||||
parameter MTVEC_WMASK = 32'hffffffff,
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Port size parameters (do not modify)
|
||||
|
|
|
@ -273,7 +273,8 @@ end
|
|||
|
||||
// Trap vector base
|
||||
reg [XLEN-1:0] mtvec_reg;
|
||||
wire [XLEN-1:0] mtvec = (mtvec_reg & MTVEC_WMASK) | (MTVEC_INIT & ~MTVEC_WMASK);
|
||||
wire [XLEN-1:0] mtvec = ((mtvec_reg & MTVEC_WMASK) | (MTVEC_INIT & ~MTVEC_WMASK)) & ({XLEN{1'b1}} << 2);
|
||||
wire irq_vector_enable = mtvec_reg[0];
|
||||
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
|
@ -524,7 +525,8 @@ always @ (*) begin
|
|||
decode_match = 1'b1;
|
||||
rdata = {
|
||||
mtvec[XLEN-1:2], // BASE
|
||||
2'h1 // MODE = Vectored (Direct is useless, and we don't have CLIC)
|
||||
1'b0, // Reserved mode bit gets WARL'd to 0
|
||||
irq_vector_enable // MODE is vectored (2'h1) or direct (2'h0)
|
||||
};
|
||||
end
|
||||
|
||||
|
@ -679,7 +681,7 @@ assign mip = {
|
|||
3'h0, // Reserved
|
||||
1'b0, // Timer (FIXME)
|
||||
3'h0, // Reserved
|
||||
1'b0, // Software interrupt
|
||||
1'b0, // Software interrupt (FIXME)
|
||||
3'h0 // Reserved
|
||||
};
|
||||
|
||||
|
@ -695,9 +697,8 @@ hazard3_priority_encode #(
|
|||
.gnt (irq_num)
|
||||
);
|
||||
|
||||
wire [11:0] mtvec_offs = (exception_req_any ?
|
||||
{8'h0, except} :
|
||||
12'h10 + {7'h0, irq_num}
|
||||
wire [11:0] mtvec_offs = (
|
||||
exception_req_any || !irq_vector_enable ? 12'h0 : {7'h0, irq_num}
|
||||
) << 2;
|
||||
|
||||
assign trap_addr = except == EXCEPT_MRET ? mepc : mtvec | {20'h0, mtvec_offs};
|
||||
|
@ -722,7 +723,7 @@ always @ (posedge clk or negedge rst_n)
|
|||
&& !(trap_enter_vld && trap_enter_rdy && except == EXCEPT_MRET);
|
||||
|
||||
always @ (posedge clk) begin
|
||||
// Assume there are no nested exceptions, to stop risc-formal from doing
|
||||
// Assume there are no nested exceptions, to stop riscv-formal from doing
|
||||
// annoying things like stopping instructions from retiring by repeatedly
|
||||
// feeding in invalid instructions
|
||||
|
||||
|
|
|
@ -21,35 +21,19 @@ j \name
|
|||
.endm
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector table
|
||||
// Hazard5 requires 4k alignment of mtvec
|
||||
// Vector table (must be at least aligned to its size rounded up to power of 2)
|
||||
|
||||
.p2align 12
|
||||
.p2align 8
|
||||
.vector_table:
|
||||
|
||||
// Exceptions
|
||||
// Single exception vector, also takes IRQs if vectoring is disabled
|
||||
|
||||
VEC handle_instr_misalign
|
||||
VEC handle_instr_fault
|
||||
VEC handle_instr_illegal
|
||||
VEC handle_breakpoint
|
||||
VEC handle_load_misalign
|
||||
VEC handle_load_fault
|
||||
VEC handle_store_misalign
|
||||
VEC handle_store_fault
|
||||
VEC .halt
|
||||
VEC .halt
|
||||
VEC .halt
|
||||
VEC handle_ecall
|
||||
VEC .halt
|
||||
VEC .halt
|
||||
VEC .halt
|
||||
VEC .halt
|
||||
VEC handle_exception
|
||||
|
||||
// Standard interrupts
|
||||
// Standard interrupts, if vectoring is enabled
|
||||
// Note: global EIRQ does not fire. Instead we have 16 separate vectors
|
||||
|
||||
VEC .halt
|
||||
// handle_exception ^^^ takes the slot where U-mode softirq would be
|
||||
VEC .halt
|
||||
VEC .halt
|
||||
VEC isr_machine_softirq
|
||||
|
@ -66,7 +50,7 @@ j \name
|
|||
VEC .halt
|
||||
VEC .halt
|
||||
|
||||
// External interrupts
|
||||
// External interrupts, if vectoring is enabled
|
||||
|
||||
VEC isr_irq0
|
||||
VEC isr_irq1
|
||||
|
@ -93,6 +77,8 @@ j \name
|
|||
.reset_handler:
|
||||
la sp, __stack_top
|
||||
la t0, .vector_table
|
||||
// Set mtvec LSB to enable vectoring
|
||||
ori t0, t0, 1
|
||||
csrw mtvec, t0
|
||||
|
||||
// newlib _start expects argc, argv on the stack. Leave stack 16-byte aligned.
|
||||
|
@ -209,15 +195,7 @@ _str_\name:
|
|||
.asciz "\name"
|
||||
.endm
|
||||
|
||||
weak_handler handle_instr_misalign
|
||||
weak_handler handle_instr_fault
|
||||
weak_handler handle_instr_illegal
|
||||
weak_handler handle_breakpoint
|
||||
weak_handler handle_load_misalign
|
||||
weak_handler handle_load_fault
|
||||
weak_handler handle_store_misalign
|
||||
weak_handler handle_store_fault
|
||||
weak_handler handle_ecall
|
||||
weak_handler handle_exception
|
||||
weak_handler isr_machine_softirq
|
||||
weak_handler isr_machine_timer
|
||||
weak_handler isr_irq0
|
||||
|
|
Loading…
Reference in New Issue