[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Simulavr-devel] [PATCH] FIX: Remove delayed ISR calls when clearing the
From: |
Stan Behrens |
Subject: |
[Simulavr-devel] [PATCH] FIX: Remove delayed ISR calls when clearing the interrupt's flag. |
Date: |
Thu, 12 Jan 2012 11:39:37 +0100 |
If interrupts are globally disabled and a condition occurs where an ISR
would be executed, they will be delayed until interrupts are enabled
again (SEI or RETI).
On a real MCU the interrupt's condition is saved in hardware through the
wiring of the MCU. In the simulator we have a sorted list for delayed
interrupts (irqPartnerList) which has to be kept in sync with the
simulated hardware state.
This patch fixes a situation where the already scheduled execution
of an ISR is not removed from the list while the hardware state changed
through clearing the interrupt's flag.
---
src/hwtimer/timerirq.cpp | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/hwtimer/timerirq.cpp b/src/hwtimer/timerirq.cpp
index 279d4a7..a05e8d7 100644
--- a/src/hwtimer/timerirq.cpp
+++ b/src/hwtimer/timerirq.cpp
@@ -129,9 +129,19 @@ unsigned char TimerIRQRegister::set_from_reg(const
IOSpecialReg* reg, unsigned c
irqsystem->SetIrqFlag(this, lines[idx]->irqvector);
}
irqmask = nv;
- } else
+ } else {
+ // Get all interrupt flags that are actually cleared with this
instruction.
+ unsigned char reset = nv & bitmask & irqflags;
+
// reset flag, if written with 1
- irqflags ^= nv & bitmask & irqflags;
+ irqflags ^= reset;
+
+ // Walk through resetting flags beginning with the LSB ...
+ for(unsigned char idx = 0; idx < lines.size(); ++idx)
+ if(reset & (1<<idx))
+ // ... and remove there pending calls from the irq system.
+ ClearIrqFlag(lines[idx]->irqvector);
+ }
return nv;
}
--
1.7.5.4