From patchwork Thu Nov 8 05:36:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wanpeng Li X-Patchwork-Id: 197773 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 B69812C00A4 for ; Thu, 8 Nov 2012 16:43:42 +1100 (EST) Received: from localhost ([::1]:47272 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TWKoF-0004zB-QF for incoming@patchwork.ozlabs.org; Thu, 08 Nov 2012 00:37:47 -0500 Received: from eggs.gnu.org ([208.118.235.92]:44051) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TWKnc-0003XE-EI for qemu-devel@nongnu.org; Thu, 08 Nov 2012 00:37:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TWKna-0003vZ-MD for qemu-devel@nongnu.org; Thu, 08 Nov 2012 00:37:08 -0500 Received: from e28smtp02.in.ibm.com ([122.248.162.2]:54530) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TWKnZ-0003vP-MW for qemu-devel@nongnu.org; Thu, 08 Nov 2012 00:37:06 -0500 Received: from /spool/local by e28smtp02.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 8 Nov 2012 11:07:03 +0530 Received: from d28relay03.in.ibm.com (9.184.220.60) by e28smtp02.in.ibm.com (192.168.1.132) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 8 Nov 2012 11:07:00 +0530 Received: from d28av03.in.ibm.com (d28av03.in.ibm.com [9.184.220.65]) by d28relay03.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id qA85b0kf17891442 for ; Thu, 8 Nov 2012 11:07:00 +0530 Received: from d28av03.in.ibm.com (loopback [127.0.0.1]) by d28av03.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id qA85axrS019657 for ; Thu, 8 Nov 2012 16:37:00 +1100 Received: from localhost ([9.123.236.63]) by d28av03.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id qA85axmx019635; Thu, 8 Nov 2012 16:36:59 +1100 From: Wanpeng Li To: Anthony Liguori Date: Thu, 8 Nov 2012 13:36:31 +0800 Message-Id: <1352352999-2561-3-git-send-email-liwanp@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1352352999-2561-1-git-send-email-liwanp@linux.vnet.ibm.com> References: <1352352999-2561-1-git-send-email-liwanp@linux.vnet.ibm.com> x-cbid: 12110805-5816-0000-0000-000005465D70 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 122.248.162.2 Cc: Ram Pai , "Michael S. Tsirkin" , Jan Kiszka , qemu-devel@nongnu.org, Liu Ping Fan , Blue Swirl , Stefan Weil , Avi Kivity , Paolo Bonzini , Wanpeng Li Subject: [Qemu-devel] [PATCH 02/10] convert HPET as piix3 proper QOM child 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 convert HPET as piix3 proper QOM child. HPET creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Anthony Liguori Signed-off-by: Wanpeng Li --- hw/hpet.c | 35 ----------------------------------- hw/hpet_emul.h | 40 ++++++++++++++++++++++++++++++++++++++++ hw/pc.c | 21 --------------------- hw/piix3.c | 28 ++++++++++++++++++++++++++-- hw/piix3.h | 4 ++-- 5 files changed, 68 insertions(+), 60 deletions(-) diff --git a/hw/hpet.c b/hw/hpet.c index 50ac067..b128505 100644 --- a/hw/hpet.c +++ b/hw/hpet.c @@ -42,41 +42,6 @@ #define HPET_MSI_SUPPORT 0 -struct HPETState; -typedef struct HPETTimer { /* timers */ - uint8_t tn; /*timer number*/ - QEMUTimer *qemu_timer; - struct HPETState *state; - /* Memory-mapped, software visible timer registers */ - uint64_t config; /* configuration/cap */ - uint64_t cmp; /* comparator */ - uint64_t fsb; /* FSB route */ - /* Hidden register state */ - uint64_t period; /* Last value written to comparator */ - uint8_t wrap_flag; /* timer pop will indicate wrap for one-shot 32-bit - * mode. Next pop will be actual timer expiration. - */ -} HPETTimer; - -typedef struct HPETState { - SysBusDevice busdev; - MemoryRegion iomem; - uint64_t hpet_offset; - qemu_irq irqs[HPET_NUM_IRQ_ROUTES]; - uint32_t flags; - uint8_t rtc_irq_level; - qemu_irq pit_enabled; - uint8_t num_timers; - HPETTimer timer[HPET_MAX_TIMERS]; - - /* Memory-mapped, software visible registers */ - uint64_t capability; /* capabilities */ - uint64_t config; /* configuration */ - uint64_t isr; /* interrupt status reg */ - uint64_t hpet_counter; /* main counter */ - uint8_t hpet_id; /* instance id */ -} HPETState; - static uint32_t hpet_in_legacy_mode(HPETState *s) { return s->config & HPET_CFG_LEGACY; diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h index 757f79f..46dee92 100644 --- a/hw/hpet_emul.h +++ b/hw/hpet_emul.h @@ -13,6 +13,8 @@ #ifndef QEMU_HPET_EMUL_H #define QEMU_HPET_EMUL_H +#include "sysbus.h" + #define HPET_BASE 0xfed00000 #define HPET_CLK_PERIOD 10000000ULL /* 10000000 femtoseconds == 10ns*/ @@ -71,4 +73,42 @@ struct hpet_fw_config } QEMU_PACKED; extern struct hpet_fw_config hpet_cfg; + +#define TYPE_HPET "hpet" + +struct HPETState; +typedef struct HPETTimer { /* timers */ + uint8_t tn; /*timer number*/ + QEMUTimer *qemu_timer; + struct HPETState *state; + /* Memory-mapped, software visible timer registers */ + uint64_t config; /* configuration/cap */ + uint64_t cmp; /* comparator */ + uint64_t fsb; /* FSB route */ + /* Hidden register state */ + uint64_t period; /* Last value written to comparator */ + uint8_t wrap_flag; /* timer pop will indicate wrap for one-shot 32-bit + * mode. Next pop will be actual timer expiration. + */ +} HPETTimer; + +typedef struct HPETState { + SysBusDevice busdev; + MemoryRegion iomem; + uint64_t hpet_offset; + qemu_irq irqs[HPET_NUM_IRQ_ROUTES]; + uint32_t flags; + uint8_t rtc_irq_level; + qemu_irq pit_enabled; + uint8_t num_timers; + HPETTimer timer[HPET_MAX_TIMERS]; + + /* Memory-mapped, software visible registers */ + uint64_t capability; /* capabilities */ + uint64_t config; /* configuration */ + uint64_t isr; /* interrupt status reg */ + uint64_t hpet_counter; /* main counter */ + uint8_t hpet_id; /* instance id */ +} HPETState; + #endif diff --git a/hw/pc.c b/hw/pc.c index 7fed363..7105f4e 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -90,8 +90,6 @@ struct e820_table { struct e820_entry entry[E820_NR_ENTRIES]; } QEMU_PACKED __attribute((__aligned__(4))); -qemu_irq rtc_irq; - static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; @@ -959,25 +957,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); - /* - * 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(sysbus_from_qdev(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); - } - } - if (!xen_enabled()) { if (kvm_irqchip_in_kernel()) { pit = kvm_pit_init(isa_bus, 0x40); diff --git a/hw/piix3.c b/hw/piix3.c index a40c8cd..5fe41cd 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -193,6 +193,7 @@ static const VMStateDescription vmstate_piix3 = { static int piix3_realize(PCIDevice *dev) { PIIX3State *s = PIIX3(dev); + qemu_irq rtc_irq; /* Initialize ISA Bus */ s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev)); @@ -202,13 +203,33 @@ static int piix3_realize(PCIDevice *dev) qdev_set_parent_bus(DEVICE(&s->rtc), BUS(s->bus)); qdev_init_nofail(DEVICE(&s->rtc)); - /* Setup the RTC IRQ */ + /* + *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->rtc.irq = rtc_irq; + 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(DEVICE(&s->hpet), sysbus_get_default()); + qdev_init_nofail(DEVICE(&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]); + } + + rtc_irq = qdev_get_gpio_in(DEVICE(&s->hpet), HPET_LEGACY_RTC_INT); } else { isa_init_irq(ISA_DEVICE(&s->rtc), &rtc_irq, RTC_ISA_IRQ); } + /* Setup the RTC IRQ */ + s->rtc.irq = rtc_irq; + return 0; } @@ -222,6 +243,9 @@ static void piix3_initfn(Object *obj) object_initialize(&s->rtc, TYPE_RTC); object_property_add_child(obj, "rtc", OBJECT(&s->rtc), NULL); qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000); + + object_initialize(&s->hpet, 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/piix3.h b/hw/piix3.h index 23ee74a..ef22c03 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -31,6 +31,7 @@ #include "pci.h" #include "mc146818rtc.h" +#include "hpet_emul.h" #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ #define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */ @@ -60,6 +61,7 @@ typedef struct PIIX3State { ISABus *bus; RTCState rtc; + HPETState hpet; qemu_irq *pic; @@ -73,6 +75,4 @@ void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level); void piix3_set_irq(void *opaque, int pirq, int level); -extern qemu_irq rtc_irq; - #endif