[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v5 09/16] ioapic: Introduce backend/frontend infrast
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH v5 09/16] ioapic: Introduce backend/frontend infrastructure for KVM reuse |
Date: |
Thu, 15 Dec 2011 13:33:24 +0100 |
Split up the IOAPIC analogously to APIC and i8259. KVM will share the
device description, reset logic and certain init parts with the user
space model.
Signed-off-by: Jan Kiszka <address@hidden>
---
Makefile.target | 2 +-
hw/ioapic.c | 130 ++++-------------------------------------------
hw/ioapic_common.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++
hw/ioapic_internal.h | 105 ++++++++++++++++++++++++++++++++++++++
hw/pc_piix.c | 1 +
5 files changed, 254 insertions(+), 121 deletions(-)
create mode 100644 hw/ioapic_common.c
create mode 100644 hw/ioapic_internal.h
diff --git a/Makefile.target b/Makefile.target
index c46f062..b549988 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -231,7 +231,7 @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o
# Hardware support
obj-i386-y += vga.o
obj-i386-y += mc146818rtc.o pc.o
-obj-i386-y += cirrus_vga.o sga.o apic_common.o apic.o ioapic.o piix_pci.o
+obj-i386-y += cirrus_vga.o sga.o apic_common.o apic.o ioapic_common.o ioapic.o
piix_pci.o
obj-i386-y += vmport.o
obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
obj-i386-y += debugcon.o multiboot.o
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 27b07c6..2db72e0 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -24,9 +24,7 @@
#include "pc.h"
#include "apic.h"
#include "ioapic.h"
-#include "qemu-timer.h"
-#include "host-utils.h"
-#include "sysbus.h"
+#include "ioapic_internal.h"
//#define DEBUG_IOAPIC
@@ -37,62 +35,6 @@
#define DPRINTF(fmt, ...)
#endif
-#define MAX_IOAPICS 1
-
-#define IOAPIC_VERSION 0x11
-
-#define IOAPIC_LVT_DEST_SHIFT 56
-#define IOAPIC_LVT_MASKED_SHIFT 16
-#define IOAPIC_LVT_TRIGGER_MODE_SHIFT 15
-#define IOAPIC_LVT_REMOTE_IRR_SHIFT 14
-#define IOAPIC_LVT_POLARITY_SHIFT 13
-#define IOAPIC_LVT_DELIV_STATUS_SHIFT 12
-#define IOAPIC_LVT_DEST_MODE_SHIFT 11
-#define IOAPIC_LVT_DELIV_MODE_SHIFT 8
-
-#define IOAPIC_LVT_MASKED (1 << IOAPIC_LVT_MASKED_SHIFT)
-#define IOAPIC_LVT_REMOTE_IRR (1 << IOAPIC_LVT_REMOTE_IRR_SHIFT)
-
-#define IOAPIC_TRIGGER_EDGE 0
-#define IOAPIC_TRIGGER_LEVEL 1
-
-/*io{apic,sapic} delivery mode*/
-#define IOAPIC_DM_FIXED 0x0
-#define IOAPIC_DM_LOWEST_PRIORITY 0x1
-#define IOAPIC_DM_PMI 0x2
-#define IOAPIC_DM_NMI 0x4
-#define IOAPIC_DM_INIT 0x5
-#define IOAPIC_DM_SIPI 0x6
-#define IOAPIC_DM_EXTINT 0x7
-#define IOAPIC_DM_MASK 0x7
-
-#define IOAPIC_VECTOR_MASK 0xff
-
-#define IOAPIC_IOREGSEL 0x00
-#define IOAPIC_IOWIN 0x10
-
-#define IOAPIC_REG_ID 0x00
-#define IOAPIC_REG_VER 0x01
-#define IOAPIC_REG_ARB 0x02
-#define IOAPIC_REG_REDTBL_BASE 0x10
-#define IOAPIC_ID 0x00
-
-#define IOAPIC_ID_SHIFT 24
-#define IOAPIC_ID_MASK 0xf
-
-#define IOAPIC_VER_ENTRIES_SHIFT 16
-
-typedef struct IOAPICState IOAPICState;
-
-struct IOAPICState {
- SysBusDevice busdev;
- MemoryRegion io_memory;
- uint8_t id;
- uint8_t ioregsel;
- uint32_t irr;
- uint64_t ioredtbl[IOAPIC_NUM_PINS];
-};
-
static IOAPICState *ioapics[MAX_IOAPICS];
static void ioapic_service(IOAPICState *s)
@@ -278,83 +220,31 @@ ioapic_mem_write(void *opaque, target_phys_addr_t addr,
uint64_t val,
}
}
-static int ioapic_post_load(void *opaque, int version_id)
-{
- IOAPICState *s = opaque;
-
- if (version_id == 1) {
- /* set sane value */
- s->irr = 0;
- }
- return 0;
-}
-
-static const VMStateDescription vmstate_ioapic = {
- .name = "ioapic",
- .version_id = 3,
- .post_load = ioapic_post_load,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(id, IOAPICState),
- VMSTATE_UINT8(ioregsel, IOAPICState),
- VMSTATE_UNUSED_V(2, 8), /* to account for qemu-kvm's v2 format */
- VMSTATE_UINT32_V(irr, IOAPICState, 2),
- VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICState, IOAPIC_NUM_PINS),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void ioapic_reset(DeviceState *d)
-{
- IOAPICState *s = DO_UPCAST(IOAPICState, busdev.qdev, d);
- int i;
-
- s->id = 0;
- s->ioregsel = 0;
- s->irr = 0;
- for (i = 0; i < IOAPIC_NUM_PINS; i++) {
- s->ioredtbl[i] = 1 << IOAPIC_LVT_MASKED_SHIFT;
- }
-}
-
static const MemoryRegionOps ioapic_io_ops = {
.read = ioapic_mem_read,
.write = ioapic_mem_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int ioapic_init1(SysBusDevice *dev)
+static void ioapic_backend_init(IOAPICState *s, int index)
{
- IOAPICState *s = FROM_SYSBUS(IOAPICState, dev);
- static int ioapic_no;
-
- if (ioapic_no >= MAX_IOAPICS) {
- return -1;
- }
-
memory_region_init_io(&s->io_memory, &ioapic_io_ops, s, "ioapic", 0x1000);
- sysbus_init_mmio(dev, &s->io_memory);
-
- qdev_init_gpio_in(&dev->qdev, ioapic_set_irq, IOAPIC_NUM_PINS);
- ioapics[ioapic_no++] = s;
+ qdev_init_gpio_in(&s->busdev.qdev, ioapic_set_irq, IOAPIC_NUM_PINS);
- return 0;
+ ioapics[index] = s;
}
-static SysBusDeviceInfo ioapic_info = {
- .init = ioapic_init1,
- .qdev.name = "ioapic",
- .qdev.size = sizeof(IOAPICState),
- .qdev.vmsd = &vmstate_ioapic,
- .qdev.reset = ioapic_reset,
- .qdev.no_user = 1,
+static IOAPICBackend ioapic_backend = {
+ .name = "QEMU",
+ .init = ioapic_backend_init,
+ .reset = ioapic_reset_internal,
};
static void ioapic_register_devices(void)
{
- sysbus_register_withprop(&ioapic_info);
+ ioapic_register_device();
+ ioapic_register_backend(&ioapic_backend);
}
device_init(ioapic_register_devices)
diff --git a/hw/ioapic_common.c b/hw/ioapic_common.c
new file mode 100644
index 0000000..094551c
--- /dev/null
+++ b/hw/ioapic_common.c
@@ -0,0 +1,137 @@
+/*
+ * IOAPIC emulation logic - common bits of emulated and KVM kernel model
+ *
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ * Copyright (c) 2009 Xiantao Zhang, Intel
+ * Copyright (c) 2011 Jan Kiszka, Siemens AG
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ioapic.h"
+#include "ioapic_internal.h"
+#include "sysbus.h"
+
+static QSIMPLEQ_HEAD(, IOAPICBackend) backends =
+ QSIMPLEQ_HEAD_INITIALIZER(backends);
+
+void ioapic_reset_internal(IOAPICState *s)
+{
+ int i;
+
+ s->id = 0;
+ s->ioregsel = 0;
+ s->irr = 0;
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ s->ioredtbl[i] = 1 << IOAPIC_LVT_MASKED_SHIFT;
+ }
+}
+
+static void ioapic_dispatch_pre_save(void *opaque)
+{
+ IOAPICState *s = opaque;
+
+ if (s->backend->pre_save) {
+ s->backend->pre_save(s);
+ }
+}
+
+static int ioapic_post_load(void *opaque, int version_id)
+{
+ IOAPICState *s = opaque;
+
+ if (version_id == 1) {
+ /* set sane value */
+ s->irr = 0;
+ }
+ if (s->backend->post_load) {
+ s->backend->post_load(s);
+ }
+ return 0;
+}
+
+const VMStateDescription vmstate_ioapic = {
+ .name = "ioapic",
+ .version_id = 3,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .pre_save = ioapic_dispatch_pre_save,
+ .post_load = ioapic_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(id, IOAPICState),
+ VMSTATE_UINT8(ioregsel, IOAPICState),
+ VMSTATE_UNUSED_V(2, 8), /* to account for qemu-kvm's v2 format */
+ VMSTATE_UINT32_V(irr, IOAPICState, 2),
+ VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICState, IOAPIC_NUM_PINS),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static int ioapic_init(SysBusDevice *dev)
+{
+ IOAPICState *s = FROM_SYSBUS(IOAPICState, dev);
+ static int ioapic_no;
+ IOAPICBackend *b;
+
+ if (ioapic_no >= MAX_IOAPICS) {
+ return -1;
+ }
+
+ QSIMPLEQ_FOREACH(b, &backends, entry) {
+ if (strcmp(b->name, s->backend_name) == 0) {
+ s->backend = b;
+ break;
+ }
+ }
+ if (!s->backend) {
+ hw_error("IOAPIC backend '%s' not found!", s->backend_name);
+ exit(1);
+ }
+
+ b->init(s, ioapic_no++);
+
+ sysbus_init_mmio(&s->busdev, &s->io_memory);
+
+ return 0;
+}
+
+static void ioapic_reset(DeviceState *dev)
+{
+ IOAPICState *s = DO_UPCAST(IOAPICState, busdev.qdev, dev);
+
+ s->backend->reset(s);
+}
+
+static SysBusDeviceInfo ioapic_info = {
+ .init = ioapic_init,
+ .qdev.name = "ioapic",
+ .qdev.size = sizeof(IOAPICState),
+ .qdev.vmsd = &vmstate_ioapic,
+ .qdev.reset = ioapic_reset,
+ .qdev.no_user = 1,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_STRING("backend", IOAPICState, backend_name),
+ DEFINE_PROP_END_OF_LIST(),
+ },
+};
+
+void ioapic_register_backend(IOAPICBackend *backend)
+{
+ QSIMPLEQ_INSERT_TAIL(&backends, backend, entry);
+}
+
+void ioapic_register_device(void)
+{
+ sysbus_register_withprop(&ioapic_info);
+}
diff --git a/hw/ioapic_internal.h b/hw/ioapic_internal.h
new file mode 100644
index 0000000..c5fab8b
--- /dev/null
+++ b/hw/ioapic_internal.h
@@ -0,0 +1,105 @@
+/*
+ * IOAPIC emulation logic - internal interfaces
+ *
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ * Copyright (c) 2009 Xiantao Zhang, Intel
+ * Copyright (c) 2011 Jan Kiszka, Siemens AG
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_IOAPIC_INTERNAL_H
+#define QEMU_IOAPIC_INTERNAL_H
+
+#include "hw.h"
+#include "memory.h"
+#include "sysbus.h"
+#include "qemu-queue.h"
+
+#define MAX_IOAPICS 1
+
+#define IOAPIC_VERSION 0x11
+
+#define IOAPIC_LVT_DEST_SHIFT 56
+#define IOAPIC_LVT_MASKED_SHIFT 16
+#define IOAPIC_LVT_TRIGGER_MODE_SHIFT 15
+#define IOAPIC_LVT_REMOTE_IRR_SHIFT 14
+#define IOAPIC_LVT_POLARITY_SHIFT 13
+#define IOAPIC_LVT_DELIV_STATUS_SHIFT 12
+#define IOAPIC_LVT_DEST_MODE_SHIFT 11
+#define IOAPIC_LVT_DELIV_MODE_SHIFT 8
+
+#define IOAPIC_LVT_MASKED (1 << IOAPIC_LVT_MASKED_SHIFT)
+#define IOAPIC_LVT_REMOTE_IRR (1 << IOAPIC_LVT_REMOTE_IRR_SHIFT)
+
+#define IOAPIC_TRIGGER_EDGE 0
+#define IOAPIC_TRIGGER_LEVEL 1
+
+/*io{apic,sapic} delivery mode*/
+#define IOAPIC_DM_FIXED 0x0
+#define IOAPIC_DM_LOWEST_PRIORITY 0x1
+#define IOAPIC_DM_PMI 0x2
+#define IOAPIC_DM_NMI 0x4
+#define IOAPIC_DM_INIT 0x5
+#define IOAPIC_DM_SIPI 0x6
+#define IOAPIC_DM_EXTINT 0x7
+#define IOAPIC_DM_MASK 0x7
+
+#define IOAPIC_VECTOR_MASK 0xff
+
+#define IOAPIC_IOREGSEL 0x00
+#define IOAPIC_IOWIN 0x10
+
+#define IOAPIC_REG_ID 0x00
+#define IOAPIC_REG_VER 0x01
+#define IOAPIC_REG_ARB 0x02
+#define IOAPIC_REG_REDTBL_BASE 0x10
+#define IOAPIC_ID 0x00
+
+#define IOAPIC_ID_SHIFT 24
+#define IOAPIC_ID_MASK 0xf
+
+#define IOAPIC_VER_ENTRIES_SHIFT 16
+
+typedef struct IOAPICBackend IOAPICBackend;
+typedef struct IOAPICState IOAPICState;
+
+struct IOAPICBackend {
+ const char *name;
+ void (*init)(IOAPICState *s, int index);
+ void (*reset)(IOAPICState *s);
+ void (*pre_save)(IOAPICState *s);
+ void (*post_load)(IOAPICState *s);
+
+ QSIMPLEQ_ENTRY(IOAPICBackend) entry;
+};
+
+struct IOAPICState {
+ SysBusDevice busdev;
+ MemoryRegion io_memory;
+ uint8_t id;
+ uint8_t ioregsel;
+ uint32_t irr;
+ uint64_t ioredtbl[IOAPIC_NUM_PINS];
+
+ char *backend_name;
+ IOAPICBackend *backend;
+};
+
+void ioapic_register_device(void);
+void ioapic_register_backend(IOAPICBackend *backend);
+
+void ioapic_reset_internal(IOAPICState *s);
+
+#endif /* !QEMU_IOAPIC_INTERNAL_H */
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 530fe9c..98f2822 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -60,6 +60,7 @@ static void ioapic_init(GSIState *gsi_state)
unsigned int i;
dev = qdev_create(NULL, "ioapic");
+ qdev_prop_set_string(dev, "backend", g_strdup("QEMU"));
qdev_init_nofail(dev);
d = sysbus_from_qdev(dev);
sysbus_mmio_map(d, 0, 0xfec00000);
--
1.7.3.4
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, (continued)
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Jan Kiszka, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Anthony Liguori, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Jan Kiszka, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Anthony Liguori, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Jan Kiszka, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Anthony Liguori, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Jan Kiszka, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Anthony Liguori, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Jan Kiszka, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 06/16] apic: Introduce backend/frontend infrastructure for KVM reuse, Avi Kivity, 2011/12/20
[Qemu-devel] [PATCH v5 09/16] ioapic: Introduce backend/frontend infrastructure for KVM reuse,
Jan Kiszka <=
[Qemu-devel] [PATCH v5 04/16] apic: Inject external NMI events via LINT1, Jan Kiszka, 2011/12/15
[Qemu-devel] [PATCH v5 13/16] kvm: x86: Add user space part for in-kernel APIC, Jan Kiszka, 2011/12/15
Re: [Qemu-devel] [PATCH v5 00/16] uq/master: Introduce basic irqchip support, Marcelo Tosatti, 2011/12/19
- Re: [Qemu-devel] [PATCH v5 00/16] uq/master: Introduce basic irqchip support, Anthony Liguori, 2011/12/19
- Re: [Qemu-devel] [PATCH v5 00/16] uq/master: Introduce basic irqchip support, Jan Kiszka, 2011/12/19
- Re: [Qemu-devel] [PATCH v5 00/16] uq/master: Introduce basic irqchip support, Anthony Liguori, 2011/12/19
- Re: [Qemu-devel] [PATCH v5 00/16] uq/master: Introduce basic irqchip support, Jan Kiszka, 2011/12/19
- Re: [Qemu-devel] [PATCH v5 00/16] uq/master: Introduce basic irqchip support, Anthony Liguori, 2011/12/19
- Re: [Qemu-devel] [PATCH v5 00/16] uq/master: Introduce basic irqchip support, Avi Kivity, 2011/12/20
- Re: [Qemu-devel] [PATCH v5 00/16] uq/master: Introduce basic irqchip support, Anthony Liguori, 2011/12/19