12ec695af7284adbedcdbc08a22d818b6bdd8990cDavid 'Digit' Turner#include "hw/hw.h" 2c7169658d43ef2a0256cea9a3a1251c3c039676eDavid 'Digit' Turner#include "hw/mips/mips.h" 3409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "cpu.h" 4409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 5409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* Raise IRQ to CPU if necessary. It must be called every time the active 6409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli IRQ may change */ 7e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turnervoid cpu_mips_update_irq(CPUOldState *env) 8409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 9bf7a22f3a6c38d359d2e933dec4706d1c7375f0aDavid 'Digit' Turner CPUState *cpu = ENV_GET_CPU(env); 10bf7a22f3a6c38d359d2e933dec4706d1c7375f0aDavid 'Digit' Turner 11409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if ((env->CP0_Status & (1 << CP0St_IE)) && 12409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli !(env->CP0_Status & (1 << CP0St_EXL)) && 13409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli !(env->CP0_Status & (1 << CP0St_ERL)) && 14409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli !(env->hflags & MIPS_HFLAG_DM)) { 15409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && 16bf7a22f3a6c38d359d2e933dec4706d1c7375f0aDavid 'Digit' Turner !(cpu->interrupt_request & CPU_INTERRUPT_HARD)) { 17bf7a22f3a6c38d359d2e933dec4706d1c7375f0aDavid 'Digit' Turner cpu_interrupt(cpu, CPU_INTERRUPT_HARD); 186657678c3d86395084f6a699e73614195f06c445David 'Digit' Turner } 19409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } else 20bf7a22f3a6c38d359d2e933dec4706d1c7375f0aDavid 'Digit' Turner cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD); 21409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 22409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 23409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic void cpu_mips_irq_request(void *opaque, int irq, int level) 24409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 25e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turner CPUOldState *env = (CPUOldState *)opaque; 26409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 27409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (irq < 0 || irq > 7) 28409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli return; 29409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 30409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (level) { 31409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli env->CP0_Cause |= 1 << (irq + CP0Ca_IP); 32409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } else { 33409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP)); 34409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 35409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_mips_update_irq(env); 36409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 37409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 38e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turnervoid cpu_mips_irq_init_cpu(CPUOldState *env) 39409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 40409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli qemu_irq *qi; 41409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli int i; 42409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 43409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli qi = qemu_allocate_irqs(cpu_mips_irq_request, env, 8); 44409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli for (i = 0; i < 8; i++) { 45409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli env->irq[i] = qi[i]; 46409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 47409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 48