/* * Generic ARM Programmable Interrupt Controller support. * * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * * This code is licensed under the LGPL */ #include "hw/hw.h" #include "hw/arm-misc.h" #include "sysemu/kvm.h" /* Input 0 is IRQ and input 1 is FIQ. */ static void arm_pic_cpu_handler(void *opaque, int irq, int level) { ARMCPU *cpu = opaque; CPUARMState *env = &cpu->env; switch (irq) { case ARM_PIC_CPU_IRQ: if (level) cpu_interrupt(env, CPU_INTERRUPT_HARD); else cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); break; case ARM_PIC_CPU_FIQ: if (level) cpu_interrupt(env, CPU_INTERRUPT_FIQ); else cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ); break; default: hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq); } } static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level) { #ifdef CONFIG_KVM ARMCPU *cpu = opaque; CPUState *cs = CPU(cpu); int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT; switch (irq) { case ARM_PIC_CPU_IRQ: kvm_irq |= KVM_ARM_IRQ_CPU_IRQ; break; case ARM_PIC_CPU_FIQ: kvm_irq |= KVM_ARM_IRQ_CPU_FIQ; break; default: hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq); } kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT; kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0); #endif } qemu_irq *arm_pic_init_cpu(ARMCPU *cpu) { if (kvm_enabled()) { return qemu_allocate_irqs(kvm_arm_pic_cpu_handler, cpu, 2); } return qemu_allocate_irqs(arm_pic_cpu_handler, cpu, 2); }