[RTL] Only restore from mstack in nmi mode

Fixes #492
This commit is contained in:
Greg Chadwick 2019-12-11 10:46:12 -08:00
parent 0d6ccbf1f6
commit 328aabb548
6 changed files with 25 additions and 8 deletions

View file

@ -46,6 +46,7 @@ module tb_cs_registers #(
logic irq_external_i;
logic [14:0] irq_fast_i;
logic irq_pending_o; // interupt request pending
logic nmi_mode_i; // core is handling an NMI
logic csr_msip_o; // software interrupt pending
logic csr_mtip_o; // timer interrupt pending
logic csr_meip_o; // external interrupt pending

View file

@ -57,4 +57,4 @@ lint_off -msg UNUSED -file "*/rtl/ibex_pmp.sv" -lines 16
// Signal unoptimizable: Feedback to clock or circular logic:
// ibex_core.cs_registers_i.mie_q
// Issue lowrisc/ibex#212
lint_off -msg UNOPTFLAT -file "*/rtl/ibex_cs_registers.sv" -lines 166
lint_off -msg UNOPTFLAT -file "*/rtl/ibex_cs_registers.sv" -lines 167

View file

@ -59,6 +59,7 @@ module ibex_controller (
input logic [14:0] csr_mfip_i, // fast interrupt pending
input logic irq_pending_i, // interrupt request pending
input logic irq_nm_i, // non-maskeable interrupt
output logic nmi_mode_o, // core executing NMI handler
// debug signals
input logic debug_req_i,
@ -592,6 +593,9 @@ module ibex_controller (
// signal to CSR when in debug mode
assign debug_mode_o = debug_mode_q;
// signal to CSR when in an NMI handler (for nested exception handling)
assign nmi_mode_o = nmi_mode_q;
///////////////////
// Stall control //
///////////////////

View file

@ -176,6 +176,7 @@ module ibex_core #(
// Interrupts
logic irq_pending;
logic nmi_mode;
logic csr_msip;
logic csr_mtip;
logic csr_meip;
@ -441,6 +442,7 @@ module ibex_core #(
.csr_mfip_i ( csr_mfip ),
.irq_pending_i ( irq_pending ),
.irq_nm_i ( irq_nm_i ),
.nmi_mode_o ( nmi_mode ),
// Debug Signal
.debug_mode_o ( debug_mode ),
@ -604,6 +606,7 @@ module ibex_core #(
.irq_external_i ( irq_external_i ),
.irq_fast_i ( irq_fast_i ),
.irq_pending_o ( irq_pending ),
.nmi_mode_i ( nmi_mode ),
.csr_msip_o ( csr_msip ),
.csr_mtip_o ( csr_mtip ),
.csr_meip_o ( csr_meip ),

View file

@ -50,6 +50,7 @@ module ibex_cs_registers #(
input logic irq_external_i,
input logic [14:0] irq_fast_i,
output logic irq_pending_o, // interupt request pending
input logic nmi_mode_i,
output logic csr_msip_o, // software interrupt pending
output logic csr_mtip_o, // timer interrupt pending
output logic csr_meip_o, // external interrupt pending
@ -580,13 +581,19 @@ module ibex_cs_registers #(
csr_restore_mret_i: begin // MRET
priv_lvl_d = mstatus_q.mpp;
mstatus_d.mie = mstatus_q.mpie; // re-enable interrupts
// restore previous status for recoverable NMI
mstatus_d.mpie = mstack_q.mpie;
mstatus_d.mpp = mstack_q.mpp;
mepc_d = mstack_epc_q;
mcause_d = mstack_cause_q;
mstack_d.mpie = 1'b1;
mstack_d.mpp = PRIV_LVL_U;
if (nmi_mode_i) begin
// when returning from an NMI restore state from mstack CSR
mstatus_d.mpie = mstack_q.mpie;
mstatus_d.mpp = mstack_q.mpp;
mepc_d = mstack_epc_q;
mcause_d = mstack_cause_q;
end else begin
// otherwise just set mstatus.MPIE/MPP
// See RISC-V Privileged Specification, version 1.11, Section 3.1.6.1
mstatus_d.mpie = 1'b1;
mstatus_d.mpp = PRIV_LVL_U;
end
end // csr_restore_mret_i
default:;

View file

@ -97,6 +97,7 @@ module ibex_id_stage #(
input logic [14:0] csr_mfip_i,
input logic irq_pending_i,
input logic irq_nm_i,
output logic nmi_mode_o,
input logic lsu_load_err_i,
input logic lsu_store_err_i,
@ -434,6 +435,7 @@ module ibex_id_stage #(
.csr_mfip_i ( csr_mfip_i ),
.irq_pending_i ( irq_pending_i ),
.irq_nm_i ( irq_nm_i ),
.nmi_mode_o ( nmi_mode_o ),
// CSR Controller Signals
.csr_save_if_o ( csr_save_if_o ),