[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/5] irq: implement route method of ioapic
From: |
Liu Ping Fan |
Subject: |
[Qemu-devel] [PATCH 2/5] irq: implement route method of ioapic |
Date: |
Thu, 12 Sep 2013 13:24:50 +0800 |
Implement the routing of PC's interrupt gpio to intc, and
retrieve the gsi.
Signed-off-by: Liu Ping Fan <address@hidden>
---
hw/core/qdev.c | 8 ++++++++
hw/i386/kvm/i8259.c | 8 +++++++-
hw/i386/kvm/ioapic.c | 21 ++++++++++++++++++++-
hw/i386/pc_q35.c | 4 ++--
include/hw/qdev-core.h | 2 ++
include/sysemu/kvm.h | 1 +
6 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 758de9f..63605d1 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -312,6 +312,14 @@ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler
handler, int n)
dev->num_gpio_in += n;
}
+void qdev_init_gpio_in_2(DeviceState *dev, qemu_irq_handler handler,
+ qemu_irq_route route, int n)
+{
+ dev->gpio_in = qemu_extend_irqs_2(dev->gpio_in, dev->num_gpio_in, handler,
+ route, dev, n);
+ dev->num_gpio_in += n;
+}
+
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
{
assert(dev->num_gpio_out == 0);
diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c
index 53e3ca8..1193b54 100644
--- a/hw/i386/kvm/i8259.c
+++ b/hw/i386/kvm/i8259.c
@@ -106,6 +106,11 @@ static void kvm_pic_reset(DeviceState *dev)
kvm_pic_put(s);
}
+static int kvm_pic_route_gsi(void *opaque, int irq)
+{
+ return irq;
+}
+
static void kvm_pic_set_irq(void *opaque, int irq, int level)
{
int delivered;
@@ -130,7 +135,8 @@ qemu_irq *kvm_i8259_init(ISABus *bus)
i8259_init_chip(TYPE_KVM_I8259, bus, true);
i8259_init_chip(TYPE_KVM_I8259, bus, false);
- return qemu_allocate_irqs(kvm_pic_set_irq, NULL, ISA_NUM_IRQS);
+ return qemu_extend_irqs_2(NULL, 0, kvm_pic_set_irq, kvm_pic_route_gsi,
+ NULL, ISA_NUM_IRQS);
}
static void kvm_i8259_class_init(ObjectClass *klass, void *data)
diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
index f11a540..1e6ff0b 100644
--- a/hw/i386/kvm/ioapic.c
+++ b/hw/i386/kvm/ioapic.c
@@ -44,6 +44,19 @@ void kvm_pc_setup_irq_routing(bool pci_enabled)
}
}
+int kvm_pc_route_gsi(void *opaque, int n)
+{
+ GSIState *s = opaque;
+ int gsi;
+
+ if (n < ISA_NUM_IRQS) {
+ gsi = qemu_irq_route_gsi(s->i8259_irq[n]);
+ } else {
+ gsi = qemu_irq_route_gsi(s->ioapic_irq[n]);
+ }
+ return gsi;
+}
+
void kvm_pc_gsi_handler(void *opaque, int n, int level)
{
GSIState *s = opaque;
@@ -127,11 +140,17 @@ static void kvm_ioapic_set_irq(void *opaque, int irq, int
level)
apic_report_irq_delivered(delivered);
}
+static int kvm_ioapic_route_irq(void *opaque, int irq)
+{
+ return irq;
+}
+
static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no)
{
memory_region_init_reservation(&s->io_memory, NULL, "kvm-ioapic", 0x1000);
- qdev_init_gpio_in(DEVICE(s), kvm_ioapic_set_irq, IOAPIC_NUM_PINS);
+ qdev_init_gpio_in_2(DEVICE(s), kvm_ioapic_set_irq, kvm_ioapic_route_irq,
+ IOAPIC_NUM_PINS);
}
static Property kvm_ioapic_properties[] = {
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 198c785..df1deb3 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -120,8 +120,8 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
gsi_state = g_malloc0(sizeof(*gsi_state));
if (kvm_irqchip_in_kernel()) {
kvm_pc_setup_irq_routing(pci_enabled);
- gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state,
- GSI_NUM_PINS);
+ gsi = qemu_extend_irqs_2(NULL, 0, kvm_pc_gsi_handler,
+ kvm_pc_route_gsi, gsi_state, GSI_NUM_PINS);
} else {
gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
}
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 46972f4..4b8eb35 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -252,6 +252,8 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char
*name);
/* Register device properties. */
/* GPIO inputs also double as IRQ sinks. */
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
+void qdev_init_gpio_in_2(DeviceState *dev, qemu_irq_handler handler,
+ qemu_irq_route route, int n);
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
BusState *qdev_get_parent_bus(DeviceState *dev);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 8e76685..47cc012 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -312,6 +312,7 @@ void kvm_irqchip_release_virq(KVMState *s, int virq);
int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
EventNotifier *rn, int virq);
int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
+int kvm_pc_route_gsi(void *opaque, int n);
void kvm_pc_gsi_handler(void *opaque, int n, int level);
void kvm_pc_setup_irq_routing(bool pci_enabled);
void kvm_init_irq_routing(KVMState *s);
--
1.8.1.4