summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorEdgar E. Iglesias <edgar@axis.com>2010-07-24 13:40:05 +0200
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>2010-07-24 13:40:05 +0200
commitfa5f73b1c9730d7ed9c119d1d0ea12df5661cd15 (patch)
tree7becf392376dc244c812b5ccd23fd7c227124a0b /hw
parent1d4865f5407d07d75e9f2134cf62497ded338b9f (diff)
downloadqemu-fa5f73b1c9730d7ed9c119d1d0ea12df5661cd15.tar.gz
qemu-fa5f73b1c9730d7ed9c119d1d0ea12df5661cd15.tar.bz2
qemu-fa5f73b1c9730d7ed9c119d1d0ea12df5661cd15.zip
mips: Correct MIPS interrupt glue logic for icount
When hw interrupt pending bits in CP0_Cause are set, the CPU should see the hw interrupt line as active. The CPU may or may not take the interrupt based on internal state (global irq mask etc) but the glue logic shouldn't care. This fixes MIPS external hw interrupts in combination with -icount. Signed-off-by: Edgar E. Iglesias <edgar@axis.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/mips_int.c23
1 files changed, 6 insertions, 17 deletions
diff --git a/hw/mips_int.c b/hw/mips_int.c
index c30954caaf..80488baeba 100644
--- a/hw/mips_int.c
+++ b/hw/mips_int.c
@@ -24,22 +24,6 @@
#include "mips_cpudevs.h"
#include "cpu.h"
-/* Raise IRQ to CPU if necessary. It must be called every time the active
- IRQ may change */
-void cpu_mips_update_irq(CPUState *env)
-{
- if ((env->CP0_Status & (1 << CP0St_IE)) &&
- !(env->CP0_Status & (1 << CP0St_EXL)) &&
- !(env->CP0_Status & (1 << CP0St_ERL)) &&
- !(env->hflags & MIPS_HFLAG_DM)) {
- if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
- !(env->interrupt_request & CPU_INTERRUPT_HARD)) {
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- }
- } else
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
-}
-
static void cpu_mips_irq_request(void *opaque, int irq, int level)
{
CPUState *env = (CPUState *)opaque;
@@ -52,7 +36,12 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level)
} else {
env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
}
- cpu_mips_update_irq(env);
+
+ if (env->CP0_Cause & CP0Ca_IP_mask) {
+ cpu_interrupt(env, CPU_INTERRUPT_HARD);
+ } else {
+ cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+ }
}
void cpu_mips_irq_init_cpu(CPUState *env)