Revision 36388314
b/hw/mips_int.c | ||
---|---|---|
24 | 24 |
#include "mips_cpudevs.h" |
25 | 25 |
#include "cpu.h" |
26 | 26 |
|
27 |
/* Raise IRQ to CPU if necessary. It must be called every time the active |
|
28 |
IRQ may change */ |
|
29 |
void cpu_mips_update_irq(CPUState *env) |
|
30 |
{ |
|
31 |
if ((env->CP0_Status & (1 << CP0St_IE)) && |
|
32 |
!(env->CP0_Status & (1 << CP0St_EXL)) && |
|
33 |
!(env->CP0_Status & (1 << CP0St_ERL)) && |
|
34 |
!(env->hflags & MIPS_HFLAG_DM)) { |
|
35 |
if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && |
|
36 |
!(env->interrupt_request & CPU_INTERRUPT_HARD)) { |
|
37 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
38 |
} |
|
39 |
} else |
|
40 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
41 |
} |
|
42 |
|
|
43 | 27 |
static void cpu_mips_irq_request(void *opaque, int irq, int level) |
44 | 28 |
{ |
45 | 29 |
CPUState *env = (CPUState *)opaque; |
... | ... | |
52 | 36 |
} else { |
53 | 37 |
env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP)); |
54 | 38 |
} |
55 |
cpu_mips_update_irq(env); |
|
39 |
|
|
40 |
if (env->CP0_Cause & CP0Ca_IP_mask) { |
|
41 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
42 |
} else { |
|
43 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
44 |
} |
|
56 | 45 |
} |
57 | 46 |
|
58 | 47 |
void cpu_mips_irq_init_cpu(CPUState *env) |
b/target-mips/cpu.h | ||
---|---|---|
597 | 597 |
void cpu_mips_start_count(CPUState *env); |
598 | 598 |
void cpu_mips_stop_count(CPUState *env); |
599 | 599 |
|
600 |
/* mips_int.c */ |
|
601 |
void cpu_mips_update_irq (CPUState *env); |
|
602 |
|
|
603 | 600 |
/* helper.c */ |
604 | 601 |
int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
605 | 602 |
int mmu_idx, int is_softmmu); |
b/target-mips/op_helper.c | ||
---|---|---|
1313 | 1313 |
default: cpu_abort(env, "Invalid MMU mode!\n"); break; |
1314 | 1314 |
} |
1315 | 1315 |
} |
1316 |
cpu_mips_update_irq(env); |
|
1317 | 1316 |
} |
1318 | 1317 |
|
1319 | 1318 |
void helper_mttc0_status(target_ulong arg1) |
... | ... | |
1359 | 1358 |
else |
1360 | 1359 |
cpu_mips_start_count(env); |
1361 | 1360 |
} |
1362 |
|
|
1363 |
/* Handle the software interrupt as an hardware one, as they |
|
1364 |
are very similar */ |
|
1365 |
if (arg1 & CP0Ca_IP_mask) { |
|
1366 |
cpu_mips_update_irq(env); |
|
1367 |
} |
|
1368 | 1361 |
} |
1369 | 1362 |
|
1370 | 1363 |
void helper_mtc0_ebase (target_ulong arg1) |
... | ... | |
1793 | 1786 |
target_ulong t0 = env->CP0_Status; |
1794 | 1787 |
|
1795 | 1788 |
env->CP0_Status = t0 & ~(1 << CP0St_IE); |
1796 |
cpu_mips_update_irq(env); |
|
1797 |
|
|
1798 | 1789 |
return t0; |
1799 | 1790 |
} |
1800 | 1791 |
|
... | ... | |
1803 | 1794 |
target_ulong t0 = env->CP0_Status; |
1804 | 1795 |
|
1805 | 1796 |
env->CP0_Status = t0 | (1 << CP0St_IE); |
1806 |
cpu_mips_update_irq(env); |
|
1807 |
|
|
1808 | 1797 |
return t0; |
1809 | 1798 |
} |
1810 | 1799 |
|
Also available in: Unified diff