diff options
Diffstat (limited to 'hw/arm')
-rw-r--r-- | hw/arm/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/arm/pic_cpu.c | 26 |
2 files changed, 28 insertions, 0 deletions
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index aebbc866e2..2d9c69dfce 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -23,6 +23,8 @@ obj-y += bitbang_i2c.o marvell_88w8618_audio.o obj-y += framebuffer.o obj-y += strongarm.o obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o +obj-$(CONFIG_FDT) += ../device_tree.o +obj-$(CONFIG_KVM) += kvm/arm_gic.o obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c index a7ad893cc2..82236006d2 100644 --- a/hw/arm/pic_cpu.c +++ b/hw/arm/pic_cpu.c @@ -9,6 +9,7 @@ #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) @@ -34,7 +35,32 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level) } } +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); } |