sparc64: interrupt trap handling
cpu_check_irqs
- handle SOFTINT register TICK and STICK timer bits
- only check interrupt levels greater than PIL value
- handle preemption by higher level traps
cpu_exec
- handle CPU_INTERRUPT_HARD only if interrupts are enabled
- PIL 15 is not special level on sparcv9
Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
diff --git a/cpu-exec.c b/cpu-exec.c
index af4595b..4635be3 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -449,20 +449,20 @@
next_tb = 0;
}
#elif defined(TARGET_SPARC)
- if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- cpu_interrupts_enabled(env)) {
- int pil = env->interrupt_index & 15;
- int type = env->interrupt_index & 0xf0;
+ if (interrupt_request & CPU_INTERRUPT_HARD) {
+ if (cpu_interrupts_enabled(env) &&
+ env->interrupt_index > 0) {
+ int pil = env->interrupt_index & 0xf;
+ int type = env->interrupt_index & 0xf0;
- if (((type == TT_EXTINT) &&
- (pil == 15 || pil > env->psrpil)) ||
- type != TT_EXTINT) {
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
- env->exception_index = env->interrupt_index;
- do_interrupt(env);
- env->interrupt_index = 0;
- next_tb = 0;
- }
+ if (((type == TT_EXTINT) &&
+ cpu_pil_allowed(env, pil)) ||
+ type != TT_EXTINT) {
+ env->exception_index = env->interrupt_index;
+ do_interrupt(env);
+ next_tb = 0;
+ }
+ }
} else if (interrupt_request & CPU_INTERRUPT_TIMER) {
//do_interrupt(0, 0, 0, 0, 0);
env->interrupt_request &= ~CPU_INTERRUPT_TIMER;