execute1: Fix interrupt delivery during slow instructions
authorPaul Mackerras <paulus@ozlabs.org>
Mon, 4 May 2020 05:17:04 +0000 (15:17 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Wed, 6 May 2020 22:07:01 +0000 (08:07 +1000)
During slow instructions such as multiply or divide, if a decrementer
(or other asynchronous) interrupt becomes pending, it disrupts the
logic that keeps stall asserted until the end of the slow
instruction, and the interrupt logic starts trying to deliver the
interrupt before the slow instruction has finished.

To fix that, make the interrupt logic wait until it sees e_in.valid
set before setting exception to 1.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
execute1.vhdl

index 18464885143e74aceda413e461b2687d2b453c13..8286d30db10a01069b6ae141b1faabe89f5c6902 100644 (file)
@@ -454,12 +454,12 @@ begin
            v.e.valid := e_in.valid;
            report "Writing SRR1: " & to_hstring(ctrl.srr1);
 
-       elsif irq_valid = '1' then
+       elsif irq_valid = '1' and e_in.valid = '1' then
            -- we need two cycles to write srr0 and 1
            -- will need more when we have to write DSISR, DAR and HIER
             -- Don't deliver the interrupt until we have a valid instruction
             -- coming in, so we have a valid NIA to put in SRR0.
-           exception := e_in.valid;
+           exception := '1';
            ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
 
         elsif e_in.valid = '1' and ctrl.msr(MSR_PR) = '1' and