summaryrefslogtreecommitdiff
path: root/cpu-exec.c
diff options
context:
space:
mode:
authorIgor V. Kovalenko <igor.v.kovalenko@gmail.com>2010-01-07 23:28:31 +0300
committerBlue Swirl <blauwirbel@gmail.com>2010-01-08 17:25:13 +0000
commitd532b26c9dee0fb5b2186572f921b1e413963ec2 (patch)
tree75eef4cbe9034f96b98c176db0e8eeb03923f652 /cpu-exec.c
parent2df6c2d0de31461f18d97f8a4d122bdb003297db (diff)
downloadqemu-d532b26c9dee0fb5b2186572f921b1e413963ec2.tar.gz
qemu-d532b26c9dee0fb5b2186572f921b1e413963ec2.tar.bz2
qemu-d532b26c9dee0fb5b2186572f921b1e413963ec2.zip
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>
Diffstat (limited to 'cpu-exec.c')
-rw-r--r--cpu-exec.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/cpu-exec.c b/cpu-exec.c
index af4595b65a..4635be34f5 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -449,20 +449,20 @@ int cpu_exec(CPUState *env1)
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 (((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 (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) &&
+ 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;