17b9cbadbSAurelien Jarno /* 27b9cbadbSAurelien Jarno * QEMU MIPS interrupt support 37b9cbadbSAurelien Jarno * 47b9cbadbSAurelien Jarno * Permission is hereby granted, free of charge, to any person obtaining a copy 57b9cbadbSAurelien Jarno * of this software and associated documentation files (the "Software"), to deal 67b9cbadbSAurelien Jarno * in the Software without restriction, including without limitation the rights 77b9cbadbSAurelien Jarno * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 87b9cbadbSAurelien Jarno * copies of the Software, and to permit persons to whom the Software is 97b9cbadbSAurelien Jarno * furnished to do so, subject to the following conditions: 107b9cbadbSAurelien Jarno * 117b9cbadbSAurelien Jarno * The above copyright notice and this permission notice shall be included in 127b9cbadbSAurelien Jarno * all copies or substantial portions of the Software. 137b9cbadbSAurelien Jarno * 147b9cbadbSAurelien Jarno * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 157b9cbadbSAurelien Jarno * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167b9cbadbSAurelien Jarno * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 177b9cbadbSAurelien Jarno * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 187b9cbadbSAurelien Jarno * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 197b9cbadbSAurelien Jarno * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 207b9cbadbSAurelien Jarno * THE SOFTWARE. 217b9cbadbSAurelien Jarno */ 227b9cbadbSAurelien Jarno 23c684822aSPeter Maydell #include "qemu/osdep.h" 24215581bdSAleksandar Markovic #include "qemu/main-loop.h" 2564552b6bSMarkus Armbruster #include "hw/irq.h" 260d09e41aSPaolo Bonzini #include "hw/mips/cpudevs.h" 274de9b249Sths #include "cpu.h" 28b1bd8b28SSanjay Lal #include "sysemu/kvm.h" 29b1bd8b28SSanjay Lal #include "kvm_mips.h" 304de9b249Sths 31d537cf6cSpbrook static void cpu_mips_irq_request(void *opaque, int irq, int level) 324de9b249Sths { 33d8ed887bSAndreas Färber MIPSCPU *cpu = opaque; 34d8ed887bSAndreas Färber CPUMIPSState *env = &cpu->env; 35d8ed887bSAndreas Färber CPUState *cs = CPU(cpu); 36215581bdSAleksandar Markovic bool locked = false; 374de9b249Sths 386c06ea4cSAleksandar Markovic if (irq < 0 || irq > 7) { 394de9b249Sths return; 406c06ea4cSAleksandar Markovic } 414de9b249Sths 42215581bdSAleksandar Markovic /* Make sure locking works even if BQL is already held by the caller */ 43215581bdSAleksandar Markovic if (!qemu_mutex_iothread_locked()) { 44215581bdSAleksandar Markovic locked = true; 45215581bdSAleksandar Markovic qemu_mutex_lock_iothread(); 46215581bdSAleksandar Markovic } 47215581bdSAleksandar Markovic 484de9b249Sths if (level) { 4939d51eb8Sths env->CP0_Cause |= 1 << (irq + CP0Ca_IP); 504de9b249Sths } else { 5139d51eb8Sths env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP)); 52*56b92eeeSPhilippe Mathieu-Daudé } 53b1bd8b28SSanjay Lal 54b1bd8b28SSanjay Lal if (kvm_enabled() && irq == 2) { 55b1bd8b28SSanjay Lal kvm_mips_set_interrupt(cpu, irq, level); 56b1bd8b28SSanjay Lal } 5736388314SEdgar E. Iglesias 5836388314SEdgar E. Iglesias if (env->CP0_Cause & CP0Ca_IP_mask) { 59c3affe56SAndreas Färber cpu_interrupt(cs, CPU_INTERRUPT_HARD); 6036388314SEdgar E. Iglesias } else { 61d8ed887bSAndreas Färber cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); 6236388314SEdgar E. Iglesias } 63215581bdSAleksandar Markovic 64215581bdSAleksandar Markovic if (locked) { 65215581bdSAleksandar Markovic qemu_mutex_unlock_iothread(); 66215581bdSAleksandar Markovic } 674de9b249Sths } 68d537cf6cSpbrook 695a975d43SPaolo Bonzini void cpu_mips_irq_init_cpu(MIPSCPU *cpu) 70d537cf6cSpbrook { 715a975d43SPaolo Bonzini CPUMIPSState *env = &cpu->env; 72d537cf6cSpbrook qemu_irq *qi; 73d537cf6cSpbrook int i; 74d537cf6cSpbrook 750009b4f3SPhilippe Mathieu-Daudé qi = qemu_allocate_irqs(cpu_mips_irq_request, cpu, 8); 76d537cf6cSpbrook for (i = 0; i < 8; i++) { 77d537cf6cSpbrook env->irq[i] = qi[i]; 78d537cf6cSpbrook } 790287d89fSPaolo Bonzini g_free(qi); 80d537cf6cSpbrook } 815dc5d9f0SAurelien Jarno 8261c56c8cSAndreas Färber void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level) 835dc5d9f0SAurelien Jarno { 845dc5d9f0SAurelien Jarno if (irq < 0 || irq > 2) { 855dc5d9f0SAurelien Jarno return; 865dc5d9f0SAurelien Jarno } 875dc5d9f0SAurelien Jarno 885dc5d9f0SAurelien Jarno qemu_set_irq(env->irq[irq], level); 895dc5d9f0SAurelien Jarno } 90