diff options
author | Igor V. Kovalenko <igor.v.kovalenko@gmail.com> | 2010-01-07 23:28:31 +0300 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2010-01-08 17:25:13 +0000 |
commit | d532b26c9dee0fb5b2186572f921b1e413963ec2 (patch) | |
tree | 75eef4cbe9034f96b98c176db0e8eeb03923f652 /cpu-exec.c | |
parent | 2df6c2d0de31461f18d97f8a4d122bdb003297db (diff) | |
download | qemu-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.c | 28 |
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; |