From patchwork Wed May 22 05:33:14 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hu Tao X-Patchwork-Id: 245518 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C60332C00A2 for ; Wed, 22 May 2013 15:38:42 +1000 (EST) Received: from localhost ([::1]:43218 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uf1l2-0008LA-Lf for incoming@patchwork.ozlabs.org; Wed, 22 May 2013 01:38:40 -0400 Received: from eggs.gnu.org ([208.118.235.92]:58510) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uf1gy-0002Rp-LF for qemu-devel@nongnu.org; Wed, 22 May 2013 01:34:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uf1gr-0008VJ-8r for qemu-devel@nongnu.org; Wed, 22 May 2013 01:34:28 -0400 Received: from [222.73.24.84] (port=23659 helo=song.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uf1gq-0008Rl-BR for qemu-devel@nongnu.org; Wed, 22 May 2013 01:34:21 -0400 X-IronPort-AV: E=Sophos;i="4.87,719,1363104000"; d="scan'208";a="7330825" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 22 May 2013 13:31:12 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id r4M5Y0we022008; Wed, 22 May 2013 13:34:01 +0800 Received: from G08FNSTD100614.fnst.cn.fujitsu.com ([10.167.233.156]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2013052213324252-1422188 ; Wed, 22 May 2013 13:32:42 +0800 From: Hu Tao To: qemu-devel@nongnu.org Date: Wed, 22 May 2013 13:33:14 +0800 Message-Id: <6b5230f6f9cab8ae01f7f99ed4011c6177d9823d.1369193012.git.hutao@cn.fujitsu.com> X-Mailer: git-send-email 1.8.2.3 In-Reply-To: References: X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/05/22 13:32:42, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/05/22 13:32:44, Serialize complete at 2013/05/22 13:32:44 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 222.73.24.84 Cc: Vasilis Liaskovitis , Jan Kiszka , Anthony Liguori , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Wanpeng Li Subject: [Qemu-devel] [RFC PATCH v1 10/20] piix3, ich9: create the HPET through composition 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 Signed-off-by: Hu Tao --- hw/i386/pc.c | 22 +--------------------- hw/i386/pc_q35.c | 9 ++++++--- hw/isa/lpc_ich9.c | 28 ++++++++++++++++++++++++++++ hw/pci-host/piix.c | 30 ++++++++++++++++++++++++++++++ hw/timer/hpet.c | 2 +- include/hw/i386/ich9.h | 2 ++ include/hw/timer/hpet.h | 3 +++ 7 files changed, 71 insertions(+), 25 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 197d218..d0e7a41 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1130,8 +1130,6 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, int i; DriveInfo *fd[MAX_FD]; DeviceState *hpet = NULL; - int pit_isa_irq = 0; - qemu_irq pit_alt_irq = NULL; qemu_irq rtc_irq = NULL; qemu_irq *a20_line; ISADevice *i8042, *port92, *vmmouse, *pit = NULL; @@ -1145,24 +1143,6 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, memory_region_init_io(ioportF0_io, &ioportF0_io_ops, NULL, "ioportF0", 1); memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io); - /* - * Check if an HPET shall be created. - * - * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT - * when the HPET wants to take over. Thus we have to disable the latter. - */ - if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { - hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL); - - if (hpet) { - for (i = 0; i < GSI_NUM_PINS; i++) { - sysbus_connect_irq(SYS_BUS_DEVICE(hpet), i, gsi[i]); - } - pit_isa_irq = -1; - pit_alt_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_PIT_INT); - rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT); - } - } *rtc_state = rtc_init(isa_bus, 2000, rtc_irq); qemu_register_boot_set(pc_boot_set, *rtc_state); @@ -1171,7 +1151,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, if (kvm_irqchip_in_kernel()) { pit = kvm_pit_init(isa_bus, 0x40); } else { - pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq); + pit = pit_init(isa_bus, 0x40, 0, NULL); } if (hpet) { /* connect PIT to output control line of the HPET */ diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 7888dfe..4797118 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -135,12 +135,15 @@ static void pc_q35_init(QEMUMachineInitArgs *args) qdev_init_nofail(DEVICE(q35_host)); host_bus = q35_host->host.pci.bus; /* create ISA bus */ - lpc = pci_create_simple_multifunction(host_bus, PCI_DEVFN(ICH9_LPC_DEV, - ICH9_LPC_FUNC), true, - TYPE_ICH9_LPC_DEVICE); + lpc = PCI_DEVICE(object_new(TYPE_ICH9_LPC_DEVICE)); ich9_lpc = ICH9_LPC_DEVICE(lpc); ich9_lpc->pic = gsi; + qdev_prop_set_int32(DEVICE(ich9_lpc), "addr", + PCI_DEVFN(ICH9_LPC_DEV, ICH9_LPC_FUNC)); + qdev_prop_set_bit(DEVICE(ich9_lpc), "multifunction", true); + qdev_set_parent_bus(DEVICE(ich9_lpc), BUS(host_bus)); ich9_lpc->ioapic = gsi_state->ioapic_irq; + qdev_init_nofail(DEVICE(ich9_lpc)); pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc, ICH9_LPC_NB_PIRQS); pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 9e44758..8d6da8d 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -44,6 +44,7 @@ #include "hw/pci/pci_bus.h" #include "exec/address-spaces.h" #include "sysemu/sysemu.h" +#include "hw/timer/hpet.h" static int ich9_lpc_sci_irq(ICH9LPCState *lpc); @@ -551,6 +552,21 @@ static int ich9_lpc_realize(PCIDevice *d) ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem, 1); + /* Realize HPET */ + if (lpc->hpet) { + int i; + + /* We need to introduce a proper IRQ and Memory QOM infrastructure + * so that the HPET isn't a sysbus device */ + qdev_set_parent_bus(lpc->hpet, sysbus_get_default()); + qdev_init_nofail(lpc->hpet); + + sysbus_mmio_map(SYS_BUS_DEVICE(lpc->hpet), 0, HPET_BASE); + for (i = 0; i < GSI_NUM_PINS; i++) { + sysbus_connect_irq(SYS_BUS_DEVICE(lpc->hpet), i, lpc->pic[i]); + } + } + return 0; } @@ -596,6 +612,18 @@ static const VMStateDescription vmstate_ich9_lpc = { static void ich9_lpc_initfn(Object *obj) { + ICH9LPCState *s = ICH9_LPC_DEVICE(obj); + + /* + * Check if an HPET shall be created. + * + * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT + * when the HPET wants to take over. Thus we have to disable the latter. + */ + if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { + s->hpet = DEVICE(object_new(TYPE_HPET)); + object_property_add_child(obj, "hpet", OBJECT(s->hpet), NULL); + } } static void ich9_lpc_class_init(ObjectClass *klass, void *data) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 6796cb5..b6bfdf0 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -32,6 +32,7 @@ #include "hw/xen/xen.h" #include "hw/pci-host/pam.h" #include "sysemu/sysemu.h" +#include "hw/timer/hpet.h" /* * I440FX chipset data sheet. @@ -70,6 +71,7 @@ typedef struct PIIX3State { uint64_t pic_levels; ISABus *bus; + DeviceState *hpet; qemu_irq *pic; @@ -580,6 +582,21 @@ static int piix3_realize(PCIDevice *dev) s->bus = isa_bus_new(DEVICE(s), pci_address_space_io(dev)); + /* Realize HPET */ + if (s->hpet) { + int i; + + /* We need to introduce a proper IRQ and Memory QOM infrastructure + * so that the HPET isn't a sysbus device */ + qdev_set_parent_bus(s->hpet, sysbus_get_default()); + qdev_init_nofail(s->hpet); + + sysbus_mmio_map(SYS_BUS_DEVICE(s->hpet), 0, HPET_BASE); + for (i = 0; i < GSI_NUM_PINS; i++) { + sysbus_connect_irq(SYS_BUS_DEVICE(s->hpet), i, s->pic[i]); + } + } + memory_region_init_io(&s->rcr_mem, &rcr_ops, s, "piix3-reset-control", 1); memory_region_add_subregion_overlap(pci_address_space_io(dev), RCR_IOPORT, &s->rcr_mem, 1); @@ -589,6 +606,19 @@ static int piix3_realize(PCIDevice *dev) static void piix3_initfn(Object *obj) { + PIIX3State *s = PIIX3(obj); + + /* + * Check if an HPET shall be created. + * + * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT + * when the HPET wants to take over. Thus we have to disable the latter. + */ + if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { + s->hpet = DEVICE(object_new(TYPE_HPET)); + object_property_add_child(obj, "hpet", OBJECT(s->hpet), NULL); + } + } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 95dd01d..8fbbf9e 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -278,7 +278,7 @@ static const VMStateDescription vmstate_hpet_timer = { }; static const VMStateDescription vmstate_hpet = { - .name = "hpet", + .name = TYPE_HPET, .version_id = 2, .minimum_version_id = 1, .minimum_version_id_old = 1, diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index c5f637b..8dc7d51 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -62,6 +62,8 @@ typedef struct ICH9LPCState { MemoryRegion rbca_mem; Notifier machine_ready; + DeviceState *hpet; + qemu_irq *pic; qemu_irq *ioapic; } ICH9LPCState; diff --git a/include/hw/timer/hpet.h b/include/hw/timer/hpet.h index 757f79f..ab17ed9 100644 --- a/include/hw/timer/hpet.h +++ b/include/hw/timer/hpet.h @@ -71,4 +71,7 @@ struct hpet_fw_config } QEMU_PACKED; extern struct hpet_fw_config hpet_cfg; + +#define TYPE_HPET "hpet" + #endif