From patchwork Fri Jan 13 17:35:06 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 135959 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 89E53B6EF7 for ; Sat, 14 Jan 2012 05:33:39 +1100 (EST) Received: from localhost ([::1]:43554 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rll46-0005Hu-8P for incoming@patchwork.ozlabs.org; Fri, 13 Jan 2012 12:37:22 -0500 Received: from eggs.gnu.org ([140.186.70.92]:58312) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rll2K-00012x-8K for qemu-devel@nongnu.org; Fri, 13 Jan 2012 12:35:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Rll2D-0007kB-B0 for qemu-devel@nongnu.org; Fri, 13 Jan 2012 12:35:32 -0500 Received: from david.siemens.de ([192.35.17.14]:23925) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rll2C-0007gr-SS for qemu-devel@nongnu.org; Fri, 13 Jan 2012 12:35:25 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by david.siemens.de (8.13.6/8.13.6) with ESMTP id q0DHZGjf008783; Fri, 13 Jan 2012 18:35:16 +0100 Received: from mchn199C.mchp.siemens.de ([139.25.109.49]) by mail1.siemens.de (8.13.6/8.13.6) with ESMTP id q0DHZDOn006138; Fri, 13 Jan 2012 18:35:16 +0100 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Date: Fri, 13 Jan 2012 18:35:06 +0100 Message-Id: <4f8138bd38c070b71b1d8a891fe172de2d5b019d.1326476111.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 192.35.17.14 Cc: Blue Swirl , Anthony Liguori , qemu-devel , kvm@vger.kernel.org, "Michael S. Tsirkin" Subject: [Qemu-devel] [PATCH v6 11/18] ioapic: Factor out base class for KVM reuse X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Split up the IOAPIC analogously to APIC and i8259. KVM will share the IOAPICCommonState, the vmstate, reset logic and certain init parts with the user space model. Signed-off-by: Jan Kiszka --- Makefile.target | 2 +- hw/ioapic.c | 140 ++++++++++++------------------------------------- hw/ioapic_common.c | 70 +++++++++++++++++++++++++ hw/ioapic_internal.h | 99 +++++++++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+), 106 deletions(-) create mode 100644 hw/ioapic_common.c create mode 100644 hw/ioapic_internal.h diff --git a/Makefile.target b/Makefile.target index a8acece..4fa91d3 100644 --- a/Makefile.target +++ b/Makefile.target @@ -223,7 +223,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 0743af6..a61aeba 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,65 +35,15 @@ #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]; + IOAPICCommonState ioapic; }; -static IOAPICState *ioapics[MAX_IOAPICS]; +static IOAPICCommonState *ioapics[MAX_IOAPICS]; -static void ioapic_service(IOAPICState *s) +static void ioapic_service(IOAPICCommonState *s) { uint8_t i; uint8_t trig_mode; @@ -135,7 +83,7 @@ static void ioapic_service(IOAPICState *s) static void ioapic_set_irq(void *opaque, int vector, int level) { - IOAPICState *s = opaque; + IOAPICCommonState *s = opaque; /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps * to GSI 2. GSI maps to ioapic 1-1. This is not @@ -174,7 +122,7 @@ static void ioapic_set_irq(void *opaque, int vector, int level) void ioapic_eoi_broadcast(int vector) { - IOAPICState *s; + IOAPICCommonState *s; uint64_t entry; int i, n; @@ -199,7 +147,7 @@ void ioapic_eoi_broadcast(int vector) static uint64_t ioapic_mem_read(void *opaque, target_phys_addr_t addr, unsigned int size) { - IOAPICState *s = opaque; + IOAPICCommonState *s = opaque; int index; uint32_t val = 0; @@ -242,7 +190,7 @@ static void ioapic_mem_write(void *opaque, target_phys_addr_t addr, uint64_t val, unsigned int size) { - IOAPICState *s = opaque; + IOAPICCommonState *s = opaque; int index; switch (addr & 0xff) { @@ -278,32 +226,11 @@ ioapic_mem_write(void *opaque, target_phys_addr_t addr, uint64_t val, } } -static const VMStateDescription vmstate_ioapic = { - .name = "ioapic", - .version_id = 3, - .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) +static void ioapic_reset(DeviceState *dev) { - IOAPICState *s = DO_UPCAST(IOAPICState, busdev.qdev, d); - int i; + IOAPICState *s = DO_UPCAST(IOAPICState, ioapic.busdev.qdev, dev); - 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; - } + ioapic_reset_common(&s->ioapic); } static const MemoryRegionOps ioapic_io_ops = { @@ -312,37 +239,40 @@ static const MemoryRegionOps ioapic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int ioapic_init1(SysBusDevice *dev) +static void ioapic_init(IOAPICCommonState *s, int instance_no) { - 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); + qdev_init_gpio_in(&s->busdev.qdev, ioapic_set_irq, IOAPIC_NUM_PINS); - ioapics[ioapic_no++] = s; - - return 0; + ioapics[instance_no] = 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 const VMStateDescription vmstate_ioapic = { + .name = "ioapic", + .version_id = IOAPIC_VMSTATE_VERSION, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(ioapic, IOAPICState, 0, vmstate_ioapic_common, + IOAPICCommonState), + VMSTATE_END_OF_LIST() + } +}; + +static IOAPICCommonInfo ioapic_info = { + .busdev.init = ioapic_init_common, + .busdev.qdev.name = "ioapic", + .busdev.qdev.size = sizeof(IOAPICState), + .busdev.qdev.vmsd = &vmstate_ioapic, + .busdev.qdev.reset = ioapic_reset, + .busdev.qdev.no_user = 1, + .init = ioapic_init, }; static void ioapic_register_devices(void) { - sysbus_register_withprop(&ioapic_info); + sysbus_register_withprop(&ioapic_info.busdev); } device_init(ioapic_register_devices) diff --git a/hw/ioapic_common.c b/hw/ioapic_common.c new file mode 100644 index 0000000..8535ce2 --- /dev/null +++ b/hw/ioapic_common.c @@ -0,0 +1,70 @@ +/* + * 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 . + */ + +#include "ioapic.h" +#include "ioapic_internal.h" +#include "sysbus.h" + +void ioapic_reset_common(IOAPICCommonState *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; + } +} + +const VMStateDescription vmstate_ioapic_common = { + .name = "ioapic", + .version_id = 3, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(id, IOAPICCommonState), + VMSTATE_UINT8(ioregsel, IOAPICCommonState), + VMSTATE_UNUSED_V(2, 8), /* to account for qemu-kvm's v2 format */ + VMSTATE_UINT32_V(irr, IOAPICCommonState, 2), + VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICCommonState, IOAPIC_NUM_PINS), + VMSTATE_END_OF_LIST() + } +}; + +int ioapic_init_common(SysBusDevice *dev) +{ + IOAPICCommonState *s = FROM_SYSBUS(IOAPICCommonState, dev); + IOAPICCommonInfo *info; + static int ioapic_no; + + if (ioapic_no >= MAX_IOAPICS) { + return -1; + } + + info = DO_UPCAST(IOAPICCommonInfo, busdev.qdev, s->busdev.qdev.info); + info->init(s, ioapic_no); + + sysbus_init_mmio(&s->busdev, &s->io_memory); + ioapic_no++; + + return 0; +} diff --git a/hw/ioapic_internal.h b/hw/ioapic_internal.h new file mode 100644 index 0000000..44d5294 --- /dev/null +++ b/hw/ioapic_internal.h @@ -0,0 +1,99 @@ +/* + * 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 . + */ + +#ifndef QEMU_IOAPIC_INTERNAL_H +#define QEMU_IOAPIC_INTERNAL_H + +#include "hw.h" +#include "memory.h" +#include "sysbus.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 IOAPICCommonState IOAPICCommonState; + +struct IOAPICCommonState { + SysBusDevice busdev; + MemoryRegion io_memory; + uint8_t id; + uint8_t ioregsel; + uint32_t irr; + uint64_t ioredtbl[IOAPIC_NUM_PINS]; +}; + +typedef struct IOAPICCommonInfo IOAPICCommonInfo; + +struct IOAPICCommonInfo { + SysBusDeviceInfo busdev; + void (*init)(IOAPICCommonState *s, int instance_no); +}; + +#define IOAPIC_VMSTATE_VERSION 3 + +extern const VMStateDescription vmstate_ioapic_common; + +int ioapic_init_common(SysBusDevice *dev); +void ioapic_reset_common(IOAPICCommonState *s); + +#endif /* !QEMU_IOAPIC_INTERNAL_H */