From patchwork Tue Dec 18 12:41:41 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vasilis Liaskovitis X-Patchwork-Id: 207117 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 0256C2C008D for ; Wed, 19 Dec 2012 00:43:13 +1100 (EST) Received: from localhost ([::1]:57808 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkwWJ-00018Z-Sg for incoming@patchwork.ozlabs.org; Tue, 18 Dec 2012 07:43:39 -0500 Received: from eggs.gnu.org ([208.118.235.92]:46173) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkwVH-00085e-60 for qemu-devel@nongnu.org; Tue, 18 Dec 2012 07:42:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TkwVE-0008Tc-Jq for qemu-devel@nongnu.org; Tue, 18 Dec 2012 07:42:34 -0500 Received: from mail-bk0-f52.google.com ([209.85.214.52]:56026) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkwVE-0008TR-8P for qemu-devel@nongnu.org; Tue, 18 Dec 2012 07:42:32 -0500 Received: by mail-bk0-f52.google.com with SMTP id w5so279832bku.25 for ; Tue, 18 Dec 2012 04:42:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=3tECgn3oMp/wEkIiTMv7BkVWVQhSijLQI/ByPOypUuA=; b=Jjs+sb/gHORFzYHHsxczmJSALzHc47r3W4AYxLZ1cAtqFIhw7DxaxTvi8jO5Dt/3CN erOtayBoyOs9Qc5zu9drVr2zyZtzaIc5qwu6qWjq8ME98OC8P7jwX1pd/0/DRkn0Y44a Sh3ufFOBoPO7qHpXWgbUIs9dDGKUEEapNbMvlaDRWbBYl/Ld0oAH4FO2+RfS4N90Ql7t Lff7swXwC1ym2u8Qa7v8uHUHtgpD1KmHl+T0hndbyITA4E8MJzZnqOkfIF7Wm2wzMe0i DcuB7QX2E8ChfBIMo9h7VO/20SogTPo1fTJEn4Yv9HgeFguhbl7SNOrT0E9TsevZ7TwQ b/QA== X-Received: by 10.204.147.217 with SMTP id m25mr682295bkv.17.1355834551014; Tue, 18 Dec 2012 04:42:31 -0800 (PST) Received: from dhcp-192-168-178-175.ri.profitbricks.localdomain ([62.217.45.26]) by mx.google.com with ESMTPS id f24sm1169954bkv.7.2012.12.18.04.42.29 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 18 Dec 2012 04:42:29 -0800 (PST) From: Vasilis Liaskovitis To: qemu-devel@nongnu.org, seabios@seabios.org Date: Tue, 18 Dec 2012 13:41:41 +0100 Message-Id: <1355834518-17989-14-git-send-email-vasilis.liaskovitis@profitbricks.com> X-Mailer: git-send-email 1.7.9 In-Reply-To: <1355834518-17989-1-git-send-email-vasilis.liaskovitis@profitbricks.com> References: <1355834518-17989-1-git-send-email-vasilis.liaskovitis@profitbricks.com> X-Gm-Message-State: ALoCoQn+rMQ0e/PeKGdvJKDVhTJNn5RILwAvVwHlDx8/ozF6a09VJvUaJTtTybJocW0e/8PAZ3/a X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.214.52 Cc: Vasilis Liaskovitis , pingfank@linux.vnet.ibm.com, gleb@redhat.com, stefanha@gmail.com, jbaron@redhat.com, blauwirbel@gmail.com, kevin@koconnor.net, kraxel@redhat.com, anthony@codemonkey.ws Subject: [Qemu-devel] [RFC PATCH v4 13/30] piix_pci and pc_piix: refactor 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 Refactor code so that chipset initialization is similar to q35. This will allow memory map initialization at chipset qdev init time for both machines, as well as more similar code structure overall. Signed-off-by: Vasilis Liaskovitis --- hw/pc_piix.c | 57 ++++++++++++--- hw/piix_pci.c | 225 ++++++++++++++------------------------------------------- 2 files changed, 100 insertions(+), 182 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 19e342a..6a9b508 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -47,6 +47,7 @@ #ifdef CONFIG_XEN # include #endif +#include "piix_pci.h" #define MAX_IDE_BUS 2 @@ -85,6 +86,8 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; + I440FXState *i440fx_host; + PIIX3State *piix3; pc_cpus_init(cpu_model); @@ -127,21 +130,53 @@ static void pc_init1(MemoryRegion *system_memory, } if (pci_enabled) { - pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi, - system_memory, system_io, ram_size, - below_4g_mem_size, - 0x100000000ULL - below_4g_mem_size, - 0x100000000ULL + above_4g_mem_size, - (sizeof(hwaddr) == 4 - ? 0 - : ((uint64_t)1 << 62)), - pci_memory, ram_memory); + i440fx_host = I440FX_HOST_DEVICE(qdev_create(NULL, + TYPE_I440FX_HOST_DEVICE)); + i440fx_host->mch.ram_memory = ram_memory; + i440fx_host->mch.pci_address_space = pci_memory; + i440fx_host->mch.system_memory = get_system_memory(); + i440fx_host->mch.address_space_io = get_system_io();; + i440fx_host->mch.below_4g_mem_size = below_4g_mem_size; + i440fx_host->mch.above_4g_mem_size = above_4g_mem_size; + + qdev_init_nofail(DEVICE(i440fx_host)); + i440fx_state = &i440fx_host->mch; + pci_bus = i440fx_host->parent_obj.bus; + /* Xen supports additional interrupt routes from the PCI devices to + * the IOAPIC: the four pins of each PCI device on the bus are also + * connected to the IOAPIC directly. + * These additional routes can be discovered through ACPI. */ + if (xen_enabled()) { + piix3 = DO_UPCAST(PIIX3State, dev, + pci_create_simple_multifunction(pci_bus, -1, true, + "PIIX3-xen")); + pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq, + piix3, XEN_PIIX_NUM_PIRQS); + } else { + piix3 = DO_UPCAST(PIIX3State, dev, + pci_create_simple_multifunction(pci_bus, -1, true, + "PIIX3")); + pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq, piix3, + PIIX_NUM_PIRQS); + pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq); + } + piix3->pic = gsi; + isa_bus = DO_UPCAST(ISABus, qbus, + qdev_get_child_bus(&piix3->dev.qdev, "isa.0")); + + piix3_devfn = piix3->dev.devfn; + + ram_size = ram_size / 8 / 1024 / 1024; + if (ram_size > 255) { + ram_size = 255; + } + i440fx_state->dev.config[0x57] = ram_size; } else { pci_bus = NULL; - i440fx_state = NULL; isa_bus = isa_bus_new(NULL, system_io); no_hpet = 1; } + isa_bus_irqs(isa_bus, gsi); if (kvm_irqchip_in_kernel()) { @@ -157,7 +192,7 @@ static void pc_init1(MemoryRegion *system_memory, gsi_state->i8259_irq[i] = i8259[i]; } if (pci_enabled) { - ioapic_init_gsi(gsi_state, "i440fx"); + ioapic_init_gsi(gsi_state, NULL); } pc_register_ferr_irq(gsi[13]); diff --git a/hw/piix_pci.c b/hw/piix_pci.c index ba1b3de..7ca3c73 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -31,70 +31,15 @@ #include "range.h" #include "xen.h" #include "pam.h" +#include "piix_pci.h" -/* - * I440FX chipset data sheet. - * http://download.intel.com/design/chipsets/datashts/29054901.pdf - */ - -typedef struct I440FXState { - PCIHostState parent_obj; -} I440FXState; - -#define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ -#define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */ -#define XEN_PIIX_NUM_PIRQS 128ULL -#define PIIX_PIRQC 0x60 - -typedef struct PIIX3State { - PCIDevice dev; - - /* - * bitmap to track pic levels. - * The pic level is the logical OR of all the PCI irqs mapped to it - * So one PIC level is tracked by PIIX_NUM_PIRQS bits. - * - * PIRQ is mapped to PIC pins, we track it by - * PIIX_NUM_PIRQS * PIIX_NUM_PIC_IRQS = 64 bits with - * pic_irq * PIIX_NUM_PIRQS + pirq - */ -#if PIIX_NUM_PIC_IRQS * PIIX_NUM_PIRQS > 64 -#error "unable to encode pic state in 64bit in pic_levels." -#endif - uint64_t pic_levels; - - qemu_irq *pic; - - /* This member isn't used. Just for save/load compatibility */ - int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS]; -} PIIX3State; - -struct PCII440FXState { - PCIDevice dev; - MemoryRegion *system_memory; - MemoryRegion *pci_address_space; - MemoryRegion *ram_memory; - MemoryRegion pci_hole; - MemoryRegion pci_hole_64bit; - PAMMemoryRegion pam_regions[13]; - MemoryRegion smram_region; - uint8_t smm_enabled; -}; - - -#define I440FX_PAM 0x59 -#define I440FX_PAM_SIZE 7 -#define I440FX_SMRAM 0x72 - -static void piix3_set_irq(void *opaque, int pirq, int level); -static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pci_intx); static void piix3_write_config_xen(PCIDevice *dev, uint32_t address, uint32_t val, int len); /* return the global irq number corresponding to a given device irq pin. We could also use the bus number to have a more precise mapping. */ -static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx) +int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx) { int slot_addend; slot_addend = (pci_dev->devfn >> 3) - 1; @@ -180,149 +125,86 @@ static const VMStateDescription vmstate_i440fx = { } }; -static int i440fx_pcihost_initfn(SysBusDevice *dev) +static void i440fx_pcihost_initfn(Object *obj) { - PCIHostState *s = PCI_HOST_BRIDGE(dev); + I440FXState *s = I440FX_HOST_DEVICE(obj); + object_initialize(&s->mch, TYPE_I440FX_PCI_DEVICE); + object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL); +} - memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s, - "pci-conf-idx", 4); - sysbus_add_io(dev, 0xcf8, &s->conf_mem); - sysbus_init_ioports(&s->busdev, 0xcf8, 4); +static int i440fx_pcihost_init(SysBusDevice *dev) +{ + PCIHostState *pci = FROM_SYSBUS(PCIHostState, dev); + I440FXState *s = I440FX_HOST_DEVICE(&dev->qdev); + PCIBus *b; + + memory_region_init_io(&pci->conf_mem, &pci_host_conf_le_ops, pci, + "pci-conf-idx", 4); + sysbus_add_io(dev, 0xcf8, &pci->conf_mem); + sysbus_init_ioports(&pci->busdev, 0xcf8, 4); + memory_region_init_io(&pci->data_mem, &pci_host_data_le_ops, pci, + "pci-conf-data", 4); - memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s, - "pci-conf-data", 4); - sysbus_add_io(dev, 0xcfc, &s->data_mem); - sysbus_init_ioports(&s->busdev, 0xcfc, 4); + sysbus_add_io(dev, 0xcfc, &pci->data_mem); + sysbus_init_ioports(&pci->busdev, 0xcfc, 4); + + b = pci_bus_new(&s->parent_obj.busdev.qdev, NULL, s->mch.pci_address_space, + s->mch.address_space_io, 0); + s->parent_obj.bus = b; + qdev_set_parent_bus(DEVICE(&s->mch), BUS(b)); + qdev_init_nofail(DEVICE(&s->mch)); return 0; } static int i440fx_initfn(PCIDevice *dev) { - PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev); + int i; + PCII440FXState *f = DO_UPCAST(PCII440FXState, dev, dev); + hwaddr pci_hole64_size; - d->dev.config[I440FX_SMRAM] = 0x02; + f->dev.config[I440FX_SMRAM] = 0x02; - cpu_smm_register(&i440fx_set_smm, d); - return 0; -} + cpu_smm_register(&i440fx_set_smm, f); -static PCIBus *i440fx_common_init(const char *device_name, - PCII440FXState **pi440fx_state, - int *piix3_devfn, - ISABus **isa_bus, qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io, - ram_addr_t ram_size, - hwaddr pci_hole_start, - hwaddr pci_hole_size, - hwaddr pci_hole64_start, - hwaddr pci_hole64_size, - MemoryRegion *pci_address_space, - MemoryRegion *ram_memory) -{ - DeviceState *dev; - PCIBus *b; - PCIDevice *d; - PCIHostState *s; - PIIX3State *piix3; - PCII440FXState *f; - unsigned i; - - dev = qdev_create(NULL, "i440FX-pcihost"); - s = PCI_HOST_BRIDGE(dev); - s->address_space = address_space_mem; - b = pci_bus_new(dev, NULL, pci_address_space, - address_space_io, 0); - s->bus = b; - object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL); - qdev_init_nofail(dev); - - d = pci_create_simple(b, 0, device_name); - *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); - f = *pi440fx_state; - f->system_memory = address_space_mem; - f->pci_address_space = pci_address_space; - f->ram_memory = ram_memory; + pci_hole64_size = (sizeof(hwaddr) == 4 ? 0 : + ((uint64_t)1 << 62)); memory_region_init_alias(&f->pci_hole, "pci-hole", f->pci_address_space, - pci_hole_start, pci_hole_size); - memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole); + f->below_4g_mem_size, + 0x100000000LL - f->below_4g_mem_size); + memory_region_add_subregion(f->system_memory, f->below_4g_mem_size, + &f->pci_hole); memory_region_init_alias(&f->pci_hole_64bit, "pci-hole64", f->pci_address_space, - pci_hole64_start, pci_hole64_size); + 0x100000000LL + f->above_4g_mem_size, + pci_hole64_size); if (pci_hole64_size) { - memory_region_add_subregion(f->system_memory, pci_hole64_start, + memory_region_add_subregion(f->system_memory, + 0x100000000LL + f->above_4g_mem_size, &f->pci_hole_64bit); } + memory_region_init_alias(&f->smram_region, "smram-region", f->pci_address_space, 0xa0000, 0x20000); memory_region_add_subregion_overlap(f->system_memory, 0xa0000, &f->smram_region, 1); memory_region_set_enabled(&f->smram_region, false); + init_pam(f->ram_memory, f->system_memory, f->pci_address_space, &f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); for (i = 0; i < 12; ++i) { init_pam(f->ram_memory, f->system_memory, f->pci_address_space, - &f->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, + &f->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); } - - /* Xen supports additional interrupt routes from the PCI devices to - * the IOAPIC: the four pins of each PCI device on the bus are also - * connected to the IOAPIC directly. - * These additional routes can be discovered through ACPI. */ - if (xen_enabled()) { - piix3 = DO_UPCAST(PIIX3State, dev, - pci_create_simple_multifunction(b, -1, true, "PIIX3-xen")); - pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, - piix3, XEN_PIIX_NUM_PIRQS); - } else { - piix3 = DO_UPCAST(PIIX3State, dev, - pci_create_simple_multifunction(b, -1, true, "PIIX3")); - pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, - PIIX_NUM_PIRQS); - pci_bus_set_route_irq_fn(b, piix3_route_intx_pin_to_irq); - } - piix3->pic = pic; - *isa_bus = DO_UPCAST(ISABus, qbus, - qdev_get_child_bus(&piix3->dev.qdev, "isa.0")); - - *piix3_devfn = piix3->dev.devfn; - - ram_size = ram_size / 8 / 1024 / 1024; - if (ram_size > 255) - ram_size = 255; - (*pi440fx_state)->dev.config[0x57]=ram_size; - + f->dev.config[0x57] = f->below_4g_mem_size; i440fx_update_memory_mappings(f); - return b; -} - -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, - ISABus **isa_bus, qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io, - ram_addr_t ram_size, - hwaddr pci_hole_start, - hwaddr pci_hole_size, - hwaddr pci_hole64_start, - hwaddr pci_hole64_size, - MemoryRegion *pci_memory, MemoryRegion *ram_memory) - -{ - PCIBus *b; - - b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, isa_bus, pic, - address_space_mem, address_space_io, ram_size, - pci_hole_start, pci_hole_size, - pci_hole64_start, pci_hole64_size, - pci_memory, ram_memory); - return b; + return 0; } /* PIIX3 PCI to ISA bridge */ -static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq) +void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq) { qemu_set_irq(piix3->pic[pic_irq], !!(piix3->pic_levels & @@ -347,13 +229,13 @@ static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level) piix3_set_irq_pic(piix3, pic_irq); } -static void piix3_set_irq(void *opaque, int pirq, int level) +void piix3_set_irq(void *opaque, int pirq, int level) { PIIX3State *piix3 = opaque; piix3_set_irq_level(piix3, pirq, level); } -static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin) +PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin) { PIIX3State *piix3 = opaque; int irq = piix3->dev.config[PIIX_PIRQC + pin]; @@ -550,7 +432,7 @@ static void i440fx_class_init(ObjectClass *klass, void *data) } static const TypeInfo i440fx_info = { - .name = "i440FX", + .name = TYPE_I440FX_PCI_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCII440FXState), .class_init = i440fx_class_init, @@ -561,15 +443,16 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = i440fx_pcihost_initfn; + k->init = i440fx_pcihost_init; dc->fw_name = "pci"; dc->no_user = 1; } static const TypeInfo i440fx_pcihost_info = { - .name = "i440FX-pcihost", + .name = TYPE_I440FX_HOST_DEVICE, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(I440FXState), + .instance_init = i440fx_pcihost_initfn, .class_init = i440fx_pcihost_class_init, };