summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtyom Tarasenko <atar4qemu@gmail.com>2012-04-03 17:49:05 +0200
committerBlue Swirl <blauwirbel@gmail.com>2012-04-04 19:20:44 +0000
commita7be9bad33d81d4bab2a51935b5443d258e7d082 (patch)
tree864306d02649b6811ab5f3b37f69083a33a2601f
parent23cf96e1971f04f21ec4bb048df4d9e2e9933018 (diff)
Improve interrupt handling priority
The vector interrupt has higher priority than interrupt_level_n. Also check only interrupt_level_n concurency when TL > 0, the traps of other types may be nested. Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
-rw-r--r--hw/sun4u.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 50bc0d2e57..fe3313890d 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -248,6 +248,10 @@ void cpu_check_irqs(CPUSPARCState *env)
uint32_t pil = env->pil_in |
(env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
+ /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
+ if (env->ivec_status & 0x20) {
+ return;
+ }
/* check if TM or SM in SOFTINT are set
setting these also causes interrupt 14 */
if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
@@ -275,7 +279,8 @@ void cpu_check_irqs(CPUSPARCState *env)
int old_interrupt = env->interrupt_index;
int new_interrupt = TT_EXTINT | i;
- if (env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt) {
+ if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
+ && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
"current %x >= pending %x\n",
env->tl, cpu_tsptr(env)->tt, new_interrupt);