[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 12/25] q35: Re-base q35 to 1.2
From: |
Blue Swirl |
Subject: |
Re: [Qemu-devel] [PATCH 12/25] q35: Re-base q35 to 1.2 |
Date: |
Fri, 14 Sep 2012 19:07:21 +0000 |
On Thu, Sep 13, 2012 at 8:12 PM, Jason Baron <address@hidden> wrote:
> Rebase q35 to 1.2 - memory api updates, acpi updates, qom...
>
> Signed-off-by: Jason Baron <address@hidden>
> ---
> hw/acpi_ich9.c | 65 ++++----
> hw/acpi_ich9.h | 9 +-
> hw/pc.h | 2 +
> hw/pc_piix.c | 4 +-
> hw/pc_q35.c | 189 +++++++++++++++-------
> hw/q35.c | 477
> +++++++++++++++++++++++++++++++-------------------------
> hw/q35.h | 97 +++++++++++-
> hw/q35_smbus.c | 78 +++++----
> 8 files changed, 568 insertions(+), 353 deletions(-)
>
> diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
> index 59c0807..0d66109 100644
> --- a/hw/acpi_ich9.c
> +++ b/hw/acpi_ich9.c
> @@ -18,6 +18,7 @@
> /*
> * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
> * VA Linux Systems Japan K.K.
> + * Copyright (C) 2012 Jason Baron <address@hidden>
> *
> * This is based on acpi.c.
> */
> @@ -47,9 +48,9 @@ static void pm_update_sci(ICH9_LPCPmRegs *pm)
> {
> int sci_level, pm1a_sts;
>
> - pm1a_sts = acpi_pm1_evt_get_sts(&pm->pm1a, pm->tmr.overflow_time);
> + pm1a_sts = acpi_pm1_evt_get_sts(&pm->acpi_regs);
>
> - sci_level = (((pm1a_sts & pm->pm1a.en) &
> + sci_level = (((pm1a_sts & pm->acpi_regs.pm1.evt.en) &
> (ACPI_BITMASK_RT_CLOCK_ENABLE |
> ACPI_BITMASK_POWER_BUTTON_ENABLE |
> ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
> @@ -57,14 +58,14 @@ static void pm_update_sci(ICH9_LPCPmRegs *pm)
> qemu_set_irq(pm->irq, sci_level);
>
> /* schedule a timer interruption if needed */
> - acpi_pm_tmr_update(&pm->tmr,
> - (pm->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) &&
> + acpi_pm_tmr_update(&pm->acpi_regs,
> + (pm->acpi_regs.pm1.evt.en &
> ACPI_BITMASK_TIMER_ENABLE) &&
> !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
> }
>
> -static void ich9_pm_update_sci_fn(ACPIPMTimer *tmr)
> +static void ich9_pm_update_sci_fn(ACPIREGS *regs)
> {
> - ICH9_LPCPmRegs *pm = container_of(tmr, ICH9_LPCPmRegs, tmr);
> + ICH9_LPCPmRegs *pm = container_of(regs, ICH9_LPCPmRegs, acpi_regs);
> pm_update_sci(pm);
> }
>
> @@ -74,7 +75,7 @@ static void pm_ioport_writeb(void *opaque, uint32_t addr,
> uint32_t val)
>
> switch (addr & ICH9_PMIO_MASK) {
> case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN -
> 1):
> - acpi_gpe_ioport_writeb(&pm->gpe0, addr, val);
> + acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
> break;
> default:
> break;
> @@ -90,7 +91,7 @@ static uint32_t pm_ioport_readb(void *opaque, uint32_t addr)
>
> switch (addr & ICH9_PMIO_MASK) {
> case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN -
> 1):
> - val = acpi_gpe_ioport_readb(&pm->gpe0, addr);
> + val = acpi_gpe_ioport_readb(&pm->acpi_regs, addr);
> break;
> default:
> val = 0;
> @@ -106,15 +107,15 @@ static void pm_ioport_writew(void *opaque, uint32_t
> addr, uint32_t val)
>
> switch (addr & ICH9_PMIO_MASK) {
> case ICH9_PMIO_PM1_STS:
> - acpi_pm1_evt_write_sts(&pm->pm1a, &pm->tmr, val);
> + acpi_pm1_evt_write_sts(&pm->acpi_regs, val);
> pm_update_sci(pm);
> break;
> case ICH9_PMIO_PM1_EN:
> - pm->pm1a.en = val;
> + pm->acpi_regs.pm1.evt.en = val;
> pm_update_sci(pm);
> break;
> case ICH9_PMIO_PM1_CNT:
> - acpi_pm1_cnt_write(&pm->pm1a, &pm->pm1_cnt, val);
> + acpi_pm1_cnt_write(&pm->acpi_regs, val, 0);
> break;
> default:
> pm_ioport_write_fallback(opaque, addr, 2, val);
> @@ -130,13 +131,13 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t
> addr)
>
> switch (addr & ICH9_PMIO_MASK) {
> case ICH9_PMIO_PM1_STS:
> - val = acpi_pm1_evt_get_sts(&pm->pm1a, pm->tmr.overflow_time);
> + val = acpi_pm1_evt_get_sts(&pm->acpi_regs);
> break;
> case ICH9_PMIO_PM1_EN:
> - val = pm->pm1a.en;
> + val = pm->acpi_regs.pm1.evt.en;
> break;
> case ICH9_PMIO_PM1_CNT:
> - val = pm->pm1_cnt.cnt;
> + val = pm->acpi_regs.pm1.cnt.cnt;
> break;
> default:
> val = pm_ioport_read_fallback(opaque, addr, 2);
> @@ -168,7 +169,7 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t
> addr)
>
> switch (addr & ICH9_PMIO_MASK) {
> case ICH9_PMIO_PM1_TMR:
> - val = acpi_pm_tmr_get(&pm->tmr);
> + val = acpi_pm_tmr_get(&pm->acpi_regs);
> break;
> case ICH9_PMIO_SMI_EN:
> val = pm->smi_en;
> @@ -238,7 +239,7 @@ void ich9_pm_iospace_update(ICH9_LPCPmRegs *pm, uint32_t
> pm_io_base)
> register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 4, pm_ioport_readl, pm);
>
> pm->pm_io_base = pm_io_base;
> - acpi_gpe_blk(&pm->gpe0, pm_io_base + ICH9_PMIO_GPE0_STS);
> + acpi_gpe_blk(&pm->acpi_regs, pm_io_base + ICH9_PMIO_GPE0_STS);
> }
>
> static int ich9_pm_post_load(void *opaque, int version_id)
> @@ -268,13 +269,13 @@ const VMStateDescription vmstate_ich9_pm = {
> .minimum_version_id_old = 1,
> .post_load = ich9_pm_post_load,
> .fields = (VMStateField[]) {
> - VMSTATE_UINT16(pm1a.sts, ICH9_LPCPmRegs),
> - VMSTATE_UINT16(pm1a.en, ICH9_LPCPmRegs),
> - VMSTATE_UINT16(pm1_cnt.cnt, ICH9_LPCPmRegs),
> - VMSTATE_TIMER(tmr.timer, ICH9_LPCPmRegs),
> - VMSTATE_INT64(tmr.overflow_time, ICH9_LPCPmRegs),
> - VMSTATE_GPE_ARRAY(gpe0.sts, ICH9_LPCPmRegs),
> - VMSTATE_GPE_ARRAY(gpe0.en, ICH9_LPCPmRegs),
> + VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9_LPCPmRegs),
> + VMSTATE_UINT16(acpi_regs.pm1.evt.en, ICH9_LPCPmRegs),
> + VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, ICH9_LPCPmRegs),
> + VMSTATE_TIMER(acpi_regs.tmr.timer, ICH9_LPCPmRegs),
> + VMSTATE_INT64(acpi_regs.tmr.overflow_time, ICH9_LPCPmRegs),
> + VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, ICH9_LPCPmRegs),
> + VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9_LPCPmRegs),
> VMSTATE_UINT32(smi_en, ICH9_LPCPmRegs),
> VMSTATE_UINT32(smi_sts, ICH9_LPCPmRegs),
> VMSTATE_END_OF_LIST()
> @@ -286,10 +287,10 @@ static void pm_reset(void *opaque)
> ICH9_LPCPmRegs *pm = opaque;
> ich9_pm_iospace_update(pm, 0);
>
> - acpi_pm1_evt_reset(&pm->pm1a);
> - acpi_pm1_cnt_reset(&pm->pm1_cnt);
> - acpi_pm_tmr_reset(&pm->tmr);
> - acpi_gpe_reset(&pm->gpe0);
> + acpi_pm1_evt_reset(&pm->acpi_regs);
> + acpi_pm1_cnt_reset(&pm->acpi_regs);
> + acpi_pm_tmr_reset(&pm->acpi_regs);
> + acpi_gpe_reset(&pm->acpi_regs);
>
> pm_update_sci(pm);
> }
> @@ -297,17 +298,15 @@ static void pm_reset(void *opaque)
> static void pm_powerdown(void *opaque, int irq, int power_failing)
> {
> ICH9_LPCPmRegs *pm = opaque;
> - ACPIPM1EVT *pm1a = pm ? &pm->pm1a : NULL;
> - ACPIPMTimer *tmr = pm ? &pm->tmr : NULL;
>
> - acpi_pm1_evt_power_down(pm1a, tmr);
> + acpi_pm1_evt_power_down(&pm->acpi_regs);
> }
>
> void ich9_pm_init(ICH9_LPCPmRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
> {
> - acpi_pm_tmr_init(&pm->tmr, ich9_pm_update_sci_fn);
> - acpi_pm1_cnt_init(&pm->pm1_cnt, cmos_s3);
> - acpi_gpe_init(&pm->gpe0, ICH9_PMIO_GPE0_LEN);
> + acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn);
> + acpi_pm1_cnt_init(&pm->acpi_regs);
> + acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
>
> pm->irq = sci_irq;
> qemu_register_reset(pm_reset, pm);
> diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h
> index f55c0e9..9ff4c42 100644
> --- a/hw/acpi_ich9.h
> +++ b/hw/acpi_ich9.h
> @@ -24,19 +24,12 @@
> #include "acpi.h"
>
> typedef struct ICH9_LPCPmRegs {
> - ACPIPM1EVT pm1a;
> -
> /*
> * In ich9 spec says that pm1_cnt register is 32bit width and
> * that the upper 16bits are reserved and unused.
> * PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t.
> */
> - ACPIPM1CNT pm1_cnt;
> -
> - ACPIPMTimer tmr;
> -
> - ACPIGPE gpe0;
> -
> + ACPIREGS acpi_regs;
> uint32_t smi_en;
> uint32_t smi_sts;
>
> diff --git a/hw/pc.h b/hw/pc.h
> index c78923c..125c1fd 100644
> --- a/hw/pc.h
> +++ b/hw/pc.h
> @@ -69,6 +69,8 @@ int pic_read_irq(DeviceState *d);
> int pic_get_output(DeviceState *d);
> void pic_info(Monitor *mon);
> void irq_info(Monitor *mon);
> +void kvm_piix3_gsi_handler(void *opaque, int n, int level);
> +void kvm_piix3_setup_irq_routing(bool pci_enabled);
>
> /* Global System Interrupts */
>
> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> index 60c7166..57830ec 100644
> --- a/hw/pc_piix.c
> +++ b/hw/pc_piix.c
> @@ -53,7 +53,7 @@ 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 };
>
> -static void kvm_piix3_setup_irq_routing(bool pci_enabled)
> +void kvm_piix3_setup_irq_routing(bool pci_enabled)
> {
> #ifdef CONFIG_KVM
> KVMState *s = kvm_state;
> @@ -82,7 +82,7 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
> #endif /* CONFIG_KVM */
> }
>
> -static void kvm_piix3_gsi_handler(void *opaque, int n, int level)
> +void kvm_piix3_gsi_handler(void *opaque, int n, int level)
> {
> GSIState *s = opaque;
>
> diff --git a/hw/pc_q35.c b/hw/pc_q35.c
> index 4f75d97..9d58519 100644
> --- a/hw/pc_q35.c
> +++ b/hw/pc_q35.c
> @@ -27,6 +27,7 @@
> * Copyright (c) 2009, 2010
> * Isaku Yamahata <yamahata at valinux co jp>
> * VA Linux Systems Japan K.K.
> + * Copyright (C) 2012 Jason Baron <address@hidden>
> *
> * This is based on pc.c, but heavily modified.
> *
> @@ -49,7 +50,6 @@
> #include "fdc.h"
> #include "pci.h"
> #include "pci_bridge.h"
> -#include "pci_p2pbr.h"
> #include "ioh3420.h"
> #include "xio3130_upstream.h"
> #include "xio3130_downstream.h"
> @@ -66,36 +66,16 @@
> #include "watchdog.h"
> #include "smbios.h"
> #include "ide.h"
> -#include "usb-uhci.h"
> +#include "mc146818rtc.h"
> +#include "xen.h"
> +#include "kvm.h"
>
> #include "q35.h"
> +#include "exec-memory.h"
>
> /* ICH9 AHCI has 6 ports */
> #define MAX_SATA_PORTS 6
>
> -#define I21154_REV 0x05
> -#define I21154_PI 0x00
> -
> -static PCIBridge *i21154_init(PCIBus *bus, int devfn, const char *bus_name,
> - bool multifunction)
> -{
> - const PCIP2PBridgeInit init = {
> - .bus = bus,
> - .devfn = devfn,
> - .multifunction = multifunction,
> -
> - .bus_name = bus_name,
> - .map_irq = pci_swizzle_map_irq_fn,
> - };
> - const PCIP2PBridgeProp prop = {
> - .vendor_id = PCI_VENDOR_ID_DEC,
> - .device_id = PCI_DEVICE_ID_DEC_21154,
> - .revision_id = I21154_REV,
> - .prog_interface = I21154_PI,
> - };
> - return pci_p2pbr_create_simple(&init, &prop);
> -}
> -
> static void pc_q35_bridge_init(PCIBus *host_bus, PCIBus *pci_bus)
> {
> uint8_t dev;
> @@ -104,7 +84,6 @@ static void pc_q35_bridge_init(PCIBus *host_bus, PCIBus
> *pci_bus)
> uint8_t chassis = 0;
> uint16_t slot = 0;
> uint8_t upstream_port;
> - PCIESlot *s;
> uint8_t fn;
> PCIESlot *root_port;
> PCIBus *root_port_bus;
> @@ -116,11 +95,10 @@ static void pc_q35_bridge_init(PCIBus *host_bus, PCIBus
> *pci_bus)
> #define Q35_P2P_BRDIGE_DEV_MAX 32
> #define Q35_P2P_BRDIGE_SUBBUS_BASE (ICH9_D2P_SECONDARY_DEFAULT + 1)
> for (dev = Q35_P2P_BRDIGE_DEV_BASE; dev < Q35_P2P_BRDIGE_DEV_MAX; dev++)
> {
> - PCIBridge *br;
> sec_bus = Q35_P2P_BRDIGE_SUBBUS_BASE + dev - Q35_P2P_BRDIGE_DEV_BASE;
>
> snprintf(buf, sizeof(buf), "pci.%d", sec_bus);
> - br = i21154_init(pci_bus, PCI_DEVFN(dev, 0), buf, true);
> + i21154_init(pci_bus, PCI_DEVFN(dev, 0), buf, true);
> }
>
> /* PCIe root port b0:d1:f0 in GMCH.
> @@ -128,8 +106,8 @@ static void pc_q35_bridge_init(PCIBus *host_bus, PCIBus
> *pci_bus)
> */
> sec_bus = 32;
> snprintf(buf, sizeof(buf), "pcie.%d", sec_bus);
> - s = ioh3420_init(host_bus, PCI_DEVFN(GMCH_PCIE_DEV, GMCH_PCIE_FUNC),
> true,
> - buf, pci_swizzle_map_irq_fn, port, chassis, slot);
> + ioh3420_init(host_bus, PCI_DEVFN(GMCH_PCIE_DEV, GMCH_PCIE_FUNC), true,
> + buf, pci_swizzle_map_irq_fn, port, chassis, slot);
>
>
> /* more slots. ICH9 doesn't have those, but many slots are wanted. */
> @@ -153,8 +131,8 @@ static void pc_q35_bridge_init(PCIBus *host_bus, PCIBus
> *pci_bus)
> slot++;
>
> snprintf(buf, sizeof(buf), "pcie.%d", sec_bus);
> - s = ioh3420_init(host_bus, PCI_DEVFN(23, fn), true,
> - buf, pci_swizzle_map_irq_fn, port, chassis, slot);
> + ioh3420_init(host_bus, PCI_DEVFN(23, fn), true,
> + buf, pci_swizzle_map_irq_fn, port, chassis, slot);
> }
>
> /* PCIe root port b0:d24:f0 */
> @@ -219,27 +197,38 @@ static void pc_q35_bridge_init(PCIBus *host_bus, PCIBus
> *pci_bus)
> slot++;
>
> snprintf(buf, sizeof(buf), "pcie.%d", sec_bus);
> - s = ioh3420_init(host_bus, PCI_DEVFN(ICH9_PCIE_DEV, fn), true,
> - buf, pci_swizzle_map_irq_fn,
> - port, chassis, slot);
> + ioh3420_init(host_bus, PCI_DEVFN(ICH9_PCIE_DEV, fn), true,
> + buf, pci_swizzle_map_irq_fn,
> + port, chassis, slot);
> }
> }
>
> -static void pc_q35_init_early(qemu_irq *isa_irq, IsaIrqState *isa_irq_state,
> +static void pc_q35_init_early(qemu_irq *gsi, GSIState *gsi_state,
> DeviceState **gmch_host_p,
> PCIBus **host_bus_p, PCIBus **pci_bus_p,
> - PCIDevice **lpc_p)
> + PCIDevice **lpc_p, ISABus **isa_bus,
> + MemoryRegion *system_memory,
> + MemoryRegion *pci_address_space,
> + MemoryRegion *address_space_io,
> + MemoryRegion *ram_memory,
> + ram_addr_t below_4g_mem_size,
> + ram_addr_t above_4g_mem_size)
> {
> + target_phys_addr_t pci_hole64_size;
> DeviceState *gmch_host;
> PCIBus *host_bus;
> PCIBus *pci_bus;
>
> PCIDevice *gmch_state;
> PCIDevice *lpc;
> + GMCH_PCIState *gmps;
> + ICH9_LPCState *ich9_lpc;
>
> /* create pci host bus */
> - host_bus = gmch_host_init(&gmch_host, isa_irq, isa_irq_state->ioapic);
> + host_bus = gmch_host_init(&gmch_host, gsi, gsi_state->ioapic_irq,
> + pci_address_space, address_space_io);
> gmch_state = gmch_init(gmch_host, host_bus);
> + gmps = GMCH_PCI_DEVICE(gmch_state);
>
> /* create conventional pci bus: pcie2pci bridge */
> pci_bus = ich9_d2pbr_init(host_bus, PCI_DEVFN(ICH9_D2P_BRIDGE_DEV,
> @@ -252,10 +241,53 @@ static void pc_q35_init_early(qemu_irq *isa_irq,
> IsaIrqState *isa_irq_state,
> /* create ISA bus */
> lpc = gmch_lpc_init(gmch_host, host_bus);
>
> + gmps->ram_memory = ram_memory;
> + gmps->pci_address_space = pci_address_space;
> + gmps->system_memory = system_memory;
> + /* pci */
> + memory_region_init_alias(&gmps->pci_hole, "pci-hole",
> + gmps->pci_address_space,
> + below_4g_mem_size,
> + 0x100000000ULL - below_4g_mem_size);
> + memory_region_add_subregion(gmps->system_memory, below_4g_mem_size,
> + &gmps->pci_hole);
> + pci_hole64_size = (sizeof(target_phys_addr_t) == 4 ? 0 :
> + ((uint64_t)1 << 62));
> + memory_region_init_alias(&gmps->pci_hole_64bit, "pci-hole64",
> + gmps->pci_address_space,
> + 0x100000000ULL + above_4g_mem_size,
> + pci_hole64_size);
> + if (pci_hole64_size) {
> + memory_region_add_subregion(gmps->system_memory,
> + 0x100000000ULL + above_4g_mem_size,
> + &gmps->pci_hole_64bit);
> + }
> +
> + /* smram */
> + memory_region_init_alias(&gmps->smram_region, "smram-region",
> + pci_address_space, 0xa0000, 0x20000);
> + memory_region_add_subregion_overlap(system_memory, 0xa0000,
> + &gmps->smram_region, 1);
> + memory_region_set_enabled(&gmps->smram_region, false);
> +
> *gmch_host_p = gmch_host;
> *host_bus_p = host_bus;
> *pci_bus_p = pci_bus;
> *lpc_p = lpc;
> + ich9_lpc = ICH9_LPC_DEVICE(lpc);
> + *isa_bus = ich9_lpc->isa_bus;
> +}
> +
> +
> +/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
> + * BIOS will read it and start S3 resume at POST Entry */
> +static void pc_cmos_set_s3_resume(void *opaque, int irq, int level)
> +{
> + ISADevice *s = opaque;
> +
> + if (level) {
> + rtc_set_memory(s, 0xF, 0xFE);
> + }
> }
>
> static void pc_q35_init_late(BusState **idebus, ISADevice *rtc_state,
> @@ -309,18 +341,22 @@ static void pc_q35_init(ram_addr_t ram_size,
> PCIBus *host_bus;
> PCIBus *pci_bus;
> PCIDevice *lpc;
> - qemu_irq *isa_irq;
> - IsaIrqState *isa_irq_state;
> BusState *idebus[MAX_SATA_PORTS];
> ISADevice *rtc_state;
> + ISADevice *floppy;
> MemoryRegion *pci_memory;
> MemoryRegion *rom_memory;
> MemoryRegion *ram_memory;
> + GSIState *gsi_state;
> + ISABus *isa_bus;
> + int pci_enabled = 1;
> + qemu_irq *cpu_irq;
> + qemu_irq *gsi;
> + qemu_irq *i8259;
> + int i;
>
> pc_cpus_init(cpu_model);
>
> - /* FIXME: add kvm clock ? */
> -
> if (ram_size >= 0xe0000000) {
> above_4g_mem_size = ram_size - 0xe0000000;
> below_4g_mem_size = 0xe0000000;
> @@ -330,37 +366,70 @@ static void pc_q35_init(ram_addr_t ram_size,
> }
>
> /* pci enabled */
> - pci_memory = g_new(MemoryRegion, 1);
> - memory_region_init(pci_memory, "pci", INT64_MAX);
> - rom_memory = pci_memory;
> + if (pci_enabled) {
> + pci_memory = g_new(MemoryRegion, 1);
> + memory_region_init(pci_memory, "pci", INT64_MAX);
> + rom_memory = pci_memory;
> + } else {
> + pci_memory = NULL;
> + rom_memory = get_system_memory();
> + }
>
> /* allocate ram and load rom/bios */
> - pc_memory_init(get_system_memory(), kernel_filename, kernel_cmdline,
> - initrd_filename, below_4g_mem_size, above_4g_mem_size,
> - rom_memory, &ram_memory);
> + if (!xen_enabled()) {
> + pc_memory_init(get_system_memory(), kernel_filename, kernel_cmdline,
> + initrd_filename, below_4g_mem_size, above_4g_mem_size,
> + rom_memory, &ram_memory);
> + }
>
> /* irq lines */
> - isa_irq = pc_isa_irq(&isa_irq_state);
> - ioapic_init(isa_irq_state);
> + gsi_state = g_malloc0(sizeof(*gsi_state));
> + if (kvm_irqchip_in_kernel()) {
> + kvm_piix3_setup_irq_routing(pci_enabled);
> + gsi = qemu_allocate_irqs(kvm_piix3_gsi_handler, gsi_state,
> + GSI_NUM_PINS);
> + } else {
> + gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
> + }
> +
> + pc_q35_init_early(gsi, gsi_state,
> + &gmch_host, &host_bus, &pci_bus, &lpc, &isa_bus,
> + get_system_memory(), pci_memory, get_system_io(),
> + ram_memory, below_4g_mem_size, above_4g_mem_size);
> + isa_bus_irqs(isa_bus, gsi);
> +
> + if (kvm_irqchip_in_kernel()) {
> + i8259 = kvm_i8259_init(isa_bus);
> + } else if (xen_enabled()) {
> + i8259 = xen_interrupt_controller_init();
> + } else {
> + cpu_irq = pc_allocate_cpu_irq();
> + i8259 = i8259_init(isa_bus, cpu_irq[0]);
> + }
> +
> + for (i = 0; i < ISA_NUM_IRQS; i++) {
> + gsi_state->i8259_irq[i] = i8259[i];
> + }
> + if (pci_enabled) {
> + ioapic_init_gsi(gsi_state, NULL);
> + }
>
> - pc_q35_init_early(isa_irq, isa_irq_state,
> - &gmch_host, &host_bus, &pci_bus, &lpc);
> - isa_bus_irqs(isa_irq);
> - pc_register_ferr_irq(isa_get_irq(13));
> + pc_register_ferr_irq(gsi[13]);
>
> /* init basic PC hardware */
> - pc_basic_device_init(isa_irq, &rtc_state, false);
> + pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, false);
>
> pc_q35_init_late(idebus, rtc_state, gmch_host, host_bus, pci_bus, lpc);
>
> pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
> - idebus[0], idebus[1], rtc_state);
> + floppy, idebus[0], idebus[1], rtc_state);
>
> /* the rest devices to which pci devfn is automatically assigned */
> - pc_vga_init(host_bus);
> - audio_init(isa_irq, pci_bus);
> - pc_nic_init(pci_bus);
> - pc_pci_device_init(pci_bus);
> + pc_vga_init(isa_bus, host_bus);
> + audio_init(isa_bus, pci_bus);
> + pc_nic_init(isa_bus, pci_bus);
> + if (pci_enabled)
> + pc_pci_device_init(pci_bus);
Missing braces, please read CODING_STYLE.
> }
>
> static QEMUMachine pc_q35_machine = {
> diff --git a/hw/q35.c b/hw/q35.c
> index 1776ac3..09e8bd7 100644
> --- a/hw/q35.c
> +++ b/hw/q35.c
> @@ -25,6 +25,7 @@
> * Copyright (c) 2009, 2010, 2011
> * Isaku Yamahata <yamahata at valinux co jp>
> * VA Linux Systems Japan K.K.
> + * Copyright (C) 2012 Jason Baron <address@hidden>
> *
> * This is based on piix_pci.c, but heavily modified.
> *
> @@ -52,62 +53,16 @@
> #include "pci.h"
> #include "pcie_host.h"
> #include "pci_bridge.h"
> -#include "pci_p2pbr.h"
> #include "q35.h"
> #include "acpi.h"
> #include "acpi_ich9.h"
> #include "pam.h"
> +#include "pci_internals.h"
> +#include "exec-memory.h"
> +#include "isa.h"
> +#include "qemu-common.h"
>
>
> -struct ICH9_LPCState;
> -
> -typedef struct ICH9_LPCIrqState {
> - struct ICH9_LPCState *lpc;
> - qemu_irq *pic;
> - qemu_irq *ioapic;
> -} ICH9_LPCIrqState;
> -
> -typedef struct GMCH_PCIHost {
> - PCIExpressHost host;
> -
> - PCIDevice *dev;
> - ICH9_LPCIrqState irq_state;
> -} GMCH_PCIHost;
> -
> -typedef struct GMCH_PCIState {
> - PCIDevice d;
> - /*
> - * GMCH_PCIHost *gmch_host;
> - * In order to get GMCH_PCIHost
> - * PCIDevice -> qdev -> parent_bus -> qdev -upcast-> GMCH_PCIHost
> - */
> -
> - PAM pam;
> -} GMCH_PCIState;
> -
> -typedef struct ICH9_LPCState {
> - /* ICH9 LPC PCI to ISA bridge */
> - PCIDevice d;
> -
> - /* (pci device, intx) -> pirq
> - * In real chipset case, the unused slots are never used
> - * as ICH9 supports only D25-D32 irq routing.
> - * On the other hand in qemu case, any slot/function can be populated
> - * via command line option.
> - * So fallback interrupt routing for any devices in any slots is
> necessary.
> - */
> - uint8_t irr[PCI_SLOT_MAX][PCI_NUM_PINS];
> -
> - APMState apm;
> - ICH9_LPCPmRegs pm;
> - uint32_t sci_level; /* track sci level */
> -
> - /* 10.1 Chipset Configuration registers(Memory Space)
> - which is pointed by RCBA */
> - uint8_t chip_config[ICH9_CC_SIZE];
> - int rbca_index;
> -} ICH9_LPCState;
> -
>
> /****************************************************************************
> * GMCH PCI host
> @@ -117,20 +72,20 @@ static int ich9_lpc_map_irq(void *opaque, PCIDevice
> *pci_dev, int intx);
> static void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
> static int ich9_lpc_sci_irq(ICH9_LPCState *lpc);
>
> -static GMCH_PCIHost *gmch_pcihost_from_qdev(DeviceState *gmch_host_qdev)
> -{
> - SysBusDevice *sysdev = sysbus_from_qdev(gmch_host_qdev);
> - PCIHostState *pci = FROM_SYSBUS(PCIHostState, sysdev);
> - PCIExpressHost *pcie = DO_UPCAST(PCIExpressHost, pci, pci);
> - return DO_UPCAST(GMCH_PCIHost, host, pcie);
> -}
> -
> static int gmch_pcihost_initfn(SysBusDevice *dev)
> {
> - GMCH_PCIHost *s = gmch_pcihost_from_qdev(&dev->qdev);
> + PCIHostState *pci = FROM_SYSBUS(PCIHostState, dev);
> + GMCH_PCIHost *s = GMCH_HOST_DEVICE(&dev->qdev);
>
> - pci_host_conf_register_ioport(GMCH_HOST_BRIDGE_CONFIG_ADDR,
> &s->host.pci);
> - pci_host_data_register_ioport(GMCH_HOST_BRIDGE_CONFIG_DATA,
> &s->host.pci);
> + memory_region_init_io(&pci->conf_mem, &pci_host_conf_le_ops, pci,
> + "pci-conf-idx", 4);
> + sysbus_add_io(dev, GMCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
> + sysbus_init_ioports(&pci->busdev, GMCH_HOST_BRIDGE_CONFIG_ADDR, 4);
> +
> + memory_region_init_io(&pci->data_mem, &pci_host_data_le_ops, pci,
> + "pci-conf-data", 4);
> + sysbus_add_io(dev, GMCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
> + sysbus_init_ioports(&pci->busdev, GMCH_HOST_BRIDGE_CONFIG_DATA, 4);
>
> if (pcie_host_init(&s->host) < 0) {
> abort();
> @@ -139,36 +94,46 @@ static int gmch_pcihost_initfn(SysBusDevice *dev)
> return 0;
> }
>
> -static SysBusDeviceInfo gmch_pcihost_info = {
> - .init = gmch_pcihost_initfn,
> - .qdev.name = "gmch-pcihost",
> - .qdev.size = sizeof(GMCH_PCIHost),
> - .qdev.no_user = 1,
> - .qdev.props = (Property[]) {
> - {
> - .name = "MCFG",
> - .info = &qdev_prop_uint64,
> - .offset = offsetof(GMCH_PCIHost, host.base_addr),
> - .defval = (uint64_t[]){ GMCH_HOST_BRIDGE_PCIEXBAR_DEFAULT },
> - },
> - DEFINE_PROP_END_OF_LIST(),
> - },
> +static Property gmch_props[] = {
> + DEFINE_PROP_UINT64("MCFG", GMCH_PCIHost, host.base_addr,
> + GMCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void gmch_pcihost_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
> +
> + k->init = gmch_pcihost_initfn;
> + dc->props = gmch_props;
> + dc->no_user = 1;
> +}
> +
> +static TypeInfo gmch_pcihost_info = {
> + .name = TYPE_GMCH_HOST_DEVICE,
> + .parent = TYPE_PCIE_HOST_BRIDGE,
> + .instance_size = sizeof(GMCH_PCIHost),
> + .class_init = gmch_pcihost_class_init,
> };
>
> /* host bridge */
> PCIBus *gmch_host_init(DeviceState **gmch_hostp,
> - qemu_irq *pic, qemu_irq *ioapic)
> + qemu_irq *pic, qemu_irq *ioapic,
> + MemoryRegion *pci_address_space,
> + MemoryRegion *address_space_io)
> {
> DeviceState *dev;
> GMCH_PCIHost *s;
> PCIBus *b;
>
> - dev = qdev_create(NULL, "gmch-pcihost");
> - s = gmch_pcihost_from_qdev(dev);
> + dev = qdev_create(NULL, TYPE_GMCH_HOST_DEVICE);
> + s = GMCH_HOST_DEVICE(dev);
> s->irq_state.pic = pic;
> s->irq_state.ioapic = ioapic;
>
> - b = pci_bus_new(dev, "pcie.0", 0);
> + b = pci_bus_new(&s->host.pci.busdev.qdev, "pcie.0", pci_address_space,
> + address_space_io, 0);
> pci_bus_irqs(b, ich9_lpc_set_irq, ich9_lpc_map_irq, &s->irq_state,
> ICH9_LPC_NB_PIRQS);
> s->host.pci.bus = b;
> @@ -180,12 +145,8 @@ PCIBus *gmch_host_init(DeviceState **gmch_hostp,
>
>
> /****************************************************************************
> - * GMCH
> + * GMCH D0:F0
> */
> -static GMCH_PCIState *gmch_from_pci(PCIDevice *gmch_pci)
> -{
> - return DO_UPCAST(GMCH_PCIState, d, gmch_pci);
> -}
>
> /* PCIE MMCFG */
> static void gmch_update_pciexbar(GMCH_PCIState *gs)
> @@ -193,7 +154,7 @@ static void gmch_update_pciexbar(GMCH_PCIState *gs)
> PCIDevice *pci_dev = &gs->d;
> BusState *bus = qdev_get_parent_bus(&pci_dev->qdev);
> DeviceState *qdev = bus->parent;
> - GMCH_PCIHost *s = gmch_pcihost_from_qdev(qdev);
> + GMCH_PCIHost *s = GMCH_HOST_DEVICE(qdev);
>
> uint64_t pciexbar;
> int enable;
> @@ -234,27 +195,39 @@ static void gmch_update_pciexbar(GMCH_PCIState *gs)
> static void gmch_update_pam(GMCH_PCIState *gs)
> {
> int i;
> +
> + memory_region_transaction_begin();
> for (i = 0; i <= PAM_IDX_MAX; i++) {
> - pam_update(&gs->pam, i, gs->d.config[GMCH_HOST_BRIDGE_PAM0 + i]);
> + pam_update(&gs->pam_regions[0], i,
> + gs->d.config[GMCH_HOST_BRIDGE_PAM0 + i],
> + gs->ram_memory, gs->pci_address_space, gs->system_memory);
> }
> + memory_region_transaction_commit();
> }
>
> /* SMRAM */
> static void gmch_update_smram(GMCH_PCIState *gs)
> {
> - smram_update(&gs->pam, gs->d.config[GMCH_HOST_BRDIGE_SMRAM]);
> + memory_region_transaction_begin();
> + smram_update(&gs->smram_region, gs->d.config[GMCH_HOST_BRDIGE_SMRAM],
> + gs->smm_enabled);
> + memory_region_transaction_commit();
> }
>
> static void gmch_set_smm(int smm, void *arg)
> {
> GMCH_PCIState *gs = arg;
> - smram_set_smm(&gs->pam, smm, gs->d.config[GMCH_HOST_BRDIGE_SMRAM]);
> +
> + memory_region_transaction_begin();
> + smram_set_smm(&gs->smm_enabled, smm,
> gs->d.config[GMCH_HOST_BRDIGE_SMRAM],
> + &gs->smram_region);
> + memory_region_transaction_commit();
> }
>
> static void gmch_write_config(PCIDevice *d,
> uint32_t address, uint32_t val, int len)
> {
> - GMCH_PCIState *gs = gmch_from_pci(d);
> + GMCH_PCIState *gs = GMCH_PCI_DEVICE(d);
>
> /* XXX: implement SMRAM.D_LOCK */
> pci_default_write_config(d, address, val, len);
> @@ -297,15 +270,15 @@ static const VMStateDescription vmstate_gmch = {
> .post_load = gmch_post_load,
> .fields = (VMStateField []) {
> VMSTATE_PCI_DEVICE(d, GMCH_PCIState),
> - VMSTATE_UINT8(pam.smm_enabled, GMCH_PCIState),
> + VMSTATE_UINT8(smm_enabled, GMCH_PCIState),
> VMSTATE_END_OF_LIST()
> }
> };
>
> static void gmch_reset(DeviceState *qdev)
> {
> - PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
> - GMCH_PCIState *gs = gmch_from_pci(d);
> + PCIDevice *d = PCI_DEVICE(qdev);
> + GMCH_PCIState *gs = GMCH_PCI_DEVICE(d);
>
> pci_set_quad(d->config + GMCH_HOST_BRIDGE_PCIEXBAR,
> GMCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
> @@ -315,39 +288,46 @@ static void gmch_reset(DeviceState *qdev)
> gmch_update(gs);
> }
>
> -static int gmch_initfn(PCIDevice *d)
> +static int pci_gmch_initfn(PCIDevice *d)
> {
> - GMCH_PCIState *gs = gmch_from_pci(d);
> -
> - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL);
> - pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_Q35_MCH);
> - pci_config_set_revision(d->config, GMCH_HOST_BRIDGE_REVISION_DEFUALT);
> - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
> + GMCH_PCIState *gs = GMCH_PCI_DEVICE(d);
>
> cpu_smm_register(&gmch_set_smm, gs);
> - pam_init_memory_mappings(&gs->pam);
>
> return 0;
> }
>
> -static PCIDeviceInfo gmch_info = {
> - .qdev.name = "gmch",
> - .qdev.desc = "Host bridge",
> - .qdev.size = sizeof(GMCH_PCIState),
> - .qdev.vmsd = &vmstate_gmch,
> - .qdev.no_user = 1,
> - .init = gmch_initfn,
> - .config_write = gmch_write_config,
> - .qdev.reset = gmch_reset,
> +static void pci_gmch_class_init(ObjectClass *klass, void *data)
> +{
> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + k->init = pci_gmch_initfn;
> + k->config_write = gmch_write_config;
> + dc->reset = gmch_reset;
> + dc->desc = "Host bridge";
> + dc->vmsd = &vmstate_gmch;
> + dc->no_user = 1;
> + k->vendor_id = PCI_VENDOR_ID_INTEL;
> + k->device_id = PCI_DEVICE_ID_INTEL_Q35_MCH;
> + k->revision = GMCH_HOST_BRIDGE_REVISION_DEFUALT;
> + k->class_id = PCI_CLASS_BRIDGE_HOST;
> +}
> +
> +struct TypeInfo pci_gmch_info = {
'static const'
> + .name = TYPE_GMCH_PCI_DEVICE,
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(GMCH_PCIState),
> + .class_init = pci_gmch_class_init,
> };
>
> /* host bridge */
> PCIDevice *gmch_init(DeviceState *gmch_host, PCIBus *b)
> {
> - GMCH_PCIHost *s = gmch_pcihost_from_qdev(gmch_host);
> + GMCH_PCIHost *s = GMCH_HOST_DEVICE(gmch_host);
> PCIDevice *d;
>
> - d = pci_create_simple_multifunction(b, 0, false, "gmch");
> + d = pci_create_simple_multifunction(b, 0, false, TYPE_GMCH_PCI_DEVICE);
> s->dev = d;
>
> return d;
> @@ -359,54 +339,135 @@ PCIDevice *gmch_init(DeviceState *gmch_host, PCIBus *b)
> #define I82801ba_SSVID_SVID 0
> #define I82801ba_SSVID_SSID 0
>
> -static PCIBridge *i82801ba11_init(PCIBus *bus, int devfn, const char
> *bus_name,
> - bool multifunction)
> +struct i82801b11_bridge {
> + PCIBridge br;
> +};
> +
> +static int i82801b11_bridge_initfn(PCIDevice *d)
> {
> - const PCIP2PBridgeInit init = {
> - .bus = bus,
> - .devfn = devfn,
> - .multifunction = multifunction,
> + int rc;
> +
> + rc = pci_bridge_initfn(d);
> + if (rc < 0) {
> + return rc;
> + }
> +
> + rc = pci_bridge_ssvid_init(d, I82801ba_SSVID_OFFSET,
> + I82801ba_SSVID_SVID, I82801ba_SSVID_SSID);
> + if (rc < 0) {
> + goto err_bridge;
> + }
> + return 0;
>
> - .bus_name = bus_name,
> - .map_irq = pci_swizzle_map_irq_fn,
> - };
> - const PCIP2PBridgeProp prop = {
> - .vendor_id = PCI_VENDOR_ID_INTEL,
> - .device_id = PCI_DEVICE_ID_INTEL_82801BA_11,
> - .revision_id = ICH9_D2P_A2_REVISION,
> - .prog_interface = PCI_CLASS_BRDIGE_PCI_INF_SUB,
> +err_bridge:
> + pci_bridge_exitfn(d);
>
> - .ssvid_cap = I82801ba_SSVID_OFFSET,
> - .svid = I82801ba_SSVID_SVID,
> - .ssid = I82801ba_SSVID_SSID,
> - };
> - return pci_p2pbr_create_simple(&init, &prop);
> + return rc;
> }
>
> +static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
> +{
> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> + k->is_bridge = 1;
> + k->vendor_id = PCI_VENDOR_ID_INTEL;
> + k->device_id = PCI_DEVICE_ID_INTEL_82801BA_11;
> + k->revision = ICH9_D2P_A2_REVISION;
> + k->init = i82801b11_bridge_initfn;
> +}
> +
> +static TypeInfo i82801b11_bridge_info = {
'const'
> + .name = "i82801b11-bridge",
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(struct i82801b11_bridge),
> + .class_init = i82801b11_bridge_class_init,
> +};
> +
> PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus)
> {
> + PCIDevice *d;
> PCIBridge *br;
> char buf[16];
> + DeviceState *qdev;
>
> - snprintf(buf, sizeof(buf), "pci.%d", sec_bus);
> - br = i82801ba11_init(bus, devfn, buf, true);
> - if (br == NULL) {
> + d = pci_create_multifunction(bus, devfn, true, "i82801b11-bridge");
> + if (!d) {
> return NULL;
> }
> + br = DO_UPCAST(PCIBridge, dev, d);
> + qdev = &br->dev.qdev;
> +
> + snprintf(buf, sizeof(buf), "pci.%d", sec_bus);
> + pci_bridge_map_irq(br, buf, pci_swizzle_map_irq_fn);
> + qdev_init_nofail(qdev);
> +
> return pci_bridge_get_sec_bus(br);
> }
> +/*****************************************************************************/
> +/* i21154 pci bridge*/
>
> +struct i21154_bridge {
I21154Bridge. If the device has a non-numeric name too that would be better.
> + PCIBridge br;
> +};
>
> -/*****************************************************************************/
> -/* ICH9 LPC PCI to ISA bridge */
> +static int i21154_bridge_initfn(PCIDevice *d)
> +{
> + int rc;
>
> -static void ich9_lpc_reset(DeviceState *qdev);
> + rc = pci_bridge_initfn(d);
> + if (rc < 0) {
> + return rc;
> + }
> +
> + return 0;
> +}
> +
> +#define I21154_REV 0x05
> +#define I21154_PI 0x00
> +
> +static void i21154_bridge_class_init(ObjectClass *klass, void *data)
> +{
> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> + k->is_bridge = 1;
> + k->vendor_id = PCI_VENDOR_ID_DEC;
> + k->device_id = PCI_DEVICE_ID_DEC_21154;
> + k->revision = I21154_REV;
> + k->init = i21154_bridge_initfn;
> +}
> +
> +static TypeInfo i21154_bridge_info = {
'const'
> + .name = "i21154-bridge",
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(struct i21154_bridge),
> + .class_init = i21154_bridge_class_init,
> +};
>
> -static ICH9_LPCState *ich9_lpc_from_pci(PCIDevice *lpc_pci)
> +PCIBridge *i21154_init(PCIBus *bus, int devfn, const char *bus_name,
> + bool multifunction)
> {
> - return DO_UPCAST(ICH9_LPCState, d, lpc_pci);
> + PCIDevice *d;
> + PCIBridge *br;
> + DeviceState *qdev;
> +
> + d = pci_create_multifunction(bus, devfn, multifunction, "i21154-bridge");
> + if (!d) {
> + return NULL;
> + }
> + br = DO_UPCAST(PCIBridge, dev, d);
> + qdev = &br->dev.qdev;
> +
> + pci_bridge_map_irq(br, bus_name, pci_swizzle_map_irq_fn);
> + qdev_init_nofail(qdev);
> +
> + return br;
> }
>
> +/*****************************************************************************/
> +/* ICH9 LPC PCI to ISA bridge */
> +
> +static void ich9_lpc_reset(DeviceState *qdev);
> +
> /* chipset configuration register
> * to access chipset configuration registers, pci_[sg]et_{byte, word, long}
> * are used.
> @@ -485,7 +546,7 @@ static void ich9_cc_reset(ICH9_LPCState *lpc)
> ich9_cc_update(lpc);
> }
>
> -static void ich9_cc_addr_len(uint32_t *addr, int *len)
> +static void ich9_cc_addr_len(uint64_t *addr, unsigned *len)
> {
> *addr &= ICH9_CC_ADDR_MASK;
> if (*addr + *len >= ICH9_CC_SIZE) {
> @@ -494,56 +555,27 @@ static void ich9_cc_addr_len(uint32_t *addr, int *len)
> }
>
> /* val: little endian */
> -static void ich9_cc_write(ICH9_LPCState *lpc, uint32_t addr,
> - uint32_t val, int len)
> +static void ich9_cc_write(void *opaque, target_phys_addr_t addr,
> + uint64_t val, unsigned len)
> {
> + ICH9_LPCState *lpc = (ICH9_LPCState *)opaque;
> +
> ich9_cc_addr_len(&addr, &len);
> memcpy(lpc->chip_config + addr, &val, len);
> }
>
> /* return value: little endian */
> -static uint32_t ich9_cc_read(ICH9_LPCState *lpc, uint32_t addr, int len)
> +static uint64_t ich9_cc_read(void *opaque, target_phys_addr_t addr,
> + unsigned len)
> {
> + ICH9_LPCState *lpc = (ICH9_LPCState *)opaque;
> +
> uint32_t val = 0;
> ich9_cc_addr_len(&addr, &len);
> memcpy(&val, lpc->chip_config + addr, len);
> return val;
> }
>
> -#define ICH9_CC_MMIO_WRITE(type, len) \
> - static void ich9_cc_mmio_write ## type \
> - (void *opaque, target_phys_addr_t addr, uint32_t val) \
> - { \
> - ich9_cc_write(opaque, addr, val, len); \
> - }
> -
> -#define ICH9_CC_MMIO_READ(type, len) \
> - static uint32_t ich9_cc_mmio_read ## type \
> - (void *opaque, target_phys_addr_t addr) \
> - { \
> - return ich9_cc_read(opaque, addr, len); \
> - }
> -
> -ICH9_CC_MMIO_WRITE(b, 1)
> -ICH9_CC_MMIO_WRITE(w, 2)
> -ICH9_CC_MMIO_WRITE(l, 4)
> -
> -ICH9_CC_MMIO_READ(b, 1)
> -ICH9_CC_MMIO_READ(w, 2)
> -ICH9_CC_MMIO_READ(l, 4)
> -
> -static CPUWriteMemoryFunc * const ich9_cc_mmio_write[] = {
> - ich9_cc_mmio_writeb,
> - ich9_cc_mmio_writew,
> - ich9_cc_mmio_writel,
> -};
> -
> -static CPUReadMemoryFunc * const ich9_cc_mmio_read[] = {
> - ich9_cc_mmio_readb,
> - ich9_cc_mmio_readw,
> - ich9_cc_mmio_readl,
> -};
> -
> /* IRQ routing */
> /* */
> static void ich9_lpc_rout(uint8_t pirq_rout, int *pic_irq, int *pic_dis)
> @@ -702,8 +734,8 @@ static void ich9_set_sci(void *opaque, int irq_num, int
> level)
> void ich9_lpc_pm_init(DeviceState *gmch_host, PCIDevice *lpc_pci,
> qemu_irq cmos_s3)
> {
> - GMCH_PCIHost *s = gmch_pcihost_from_qdev(gmch_host);
> - ICH9_LPCState *lpc = ich9_lpc_from_pci(lpc_pci);
> + GMCH_PCIHost *s = GMCH_HOST_DEVICE(gmch_host);
> + ICH9_LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci);
> qemu_irq *sci_irq;
>
> sci_irq = qemu_allocate_irqs(ich9_set_sci, &s->irq_state, 1);
> @@ -713,12 +745,14 @@ void ich9_lpc_pm_init(DeviceState *gmch_host, PCIDevice
> *lpc_pci,
> }
>
> /* APM */
> +
> +
> static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
> {
> ICH9_LPCState *lpc = arg;
>
> /* ACPI specs 3.0, 4.7.2.5 */
> - acpi_pm1_cnt_update(&lpc->pm.pm1_cnt,
> + acpi_pm1_cnt_update(&lpc->pm.acpi_regs,
> val == ICH9_APM_ACPI_ENABLE,
> val == ICH9_APM_ACPI_DISABLE);
>
> @@ -744,12 +778,12 @@ static void ich9_lpc_rcba_update(ICH9_LPCState *lpc,
> uint32_t rbca_old)
> uint32_t rbca = pci_get_long(lpc->d.config + ICH9_LPC_RCBA);
>
> if (rbca_old & ICH9_LPC_RCBA_EN) {
> - cpu_register_physical_memory(rbca_old & ICH9_LPC_RCBA_BA_MASK,
> - ICH9_CC_SIZE, IO_MEM_UNASSIGNED);
> + memory_region_del_subregion(get_system_memory(), &lpc->rbca_mem);
> }
> if (rbca & ICH9_LPC_RCBA_EN) {
> - cpu_register_physical_memory(rbca & ICH9_LPC_RCBA_BA_MASK,
> - ICH9_CC_SIZE, lpc->rbca_index);
> + memory_region_add_subregion_overlap(get_system_memory(),
> + rbca & ICH9_LPC_RCBA_BA_MASK,
> + &lpc->rbca_mem, 1);
> }
> }
>
> @@ -765,7 +799,7 @@ static int ich9_lpc_post_load(void *opaque, int
> version_id)
> static void ich9_lpc_config_write(PCIDevice *d,
> uint32_t addr, uint32_t val, int len)
> {
> - ICH9_LPCState *lpc = ich9_lpc_from_pci(d);
> + ICH9_LPCState *lpc = ICH9_LPC_DEVICE(d);
> uint32_t rbca_old = pci_get_long(d->config + ICH9_LPC_RCBA);
>
> pci_default_write_config(d, addr, val, len);
> @@ -779,8 +813,8 @@ static void ich9_lpc_config_write(PCIDevice *d,
>
> static void ich9_lpc_reset(DeviceState *qdev)
> {
> - PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
> - ICH9_LPCState *lpc = ich9_lpc_from_pci(d);
> + PCIDevice *d = PCI_DEVICE(qdev);
> + ICH9_LPCState *lpc = ICH9_LPC_DEVICE(d);
> uint32_t rbca_old = pci_get_long(d->config + ICH9_LPC_RCBA);
> int i;
>
> @@ -805,22 +839,26 @@ static void ich9_lpc_reset(DeviceState *qdev)
> lpc->sci_level = 0;
> }
>
> +static const MemoryRegionOps rbca_mmio_ops = {
> + .read = ich9_cc_read,
> + .write = ich9_cc_write,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> static int ich9_lpc_initfn(PCIDevice *d)
> {
> - ICH9_LPCState *lpc = ich9_lpc_from_pci(d);
> + ICH9_LPCState *lpc = ICH9_LPC_DEVICE(d);
> + ISABus *isa_bus;
>
> - isa_bus_new(&d->qdev);
> - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL);
> - pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_ICH9_8); /* ICH9
> LPC */
> - pci_config_set_revision(d->config, ICH9_A2_LPC_REVISION);
> - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_ISA);
> + isa_bus = isa_bus_new(&d->qdev, get_system_io());
>
> pci_set_long(d->wmask + ICH9_LPC_PMBASE,
> ICH9_LPC_PMBASE_BASE_ADDRESS_MASK);
>
> - lpc->rbca_index = cpu_register_io_memory(ich9_cc_mmio_read,
> - ich9_cc_mmio_write,
> - lpc, DEVICE_LITTLE_ENDIAN);
> + memory_region_init_io(&lpc->rbca_mem, &rbca_mmio_ops, lpc,
> + "lpc-rbca-mmio", ICH9_CC_SIZE);
> +
> + lpc->isa_bus = isa_bus;
>
> ich9_cc_init(lpc);
> apm_init(&lpc->apm, ich9_apm_ctrl_changed, lpc);
> @@ -845,33 +883,50 @@ static const VMStateDescription vmstate_ich9_lpc = {
>
> PCIDevice *gmch_lpc_init(DeviceState *gmch_host, PCIBus *bus)
> {
> - GMCH_PCIHost *s = gmch_pcihost_from_qdev(gmch_host);
> + GMCH_PCIHost *s = GMCH_HOST_DEVICE(gmch_host);
> PCIDevice *d;
> ICH9_LPCState *lpc;
>
> d = pci_create_simple_multifunction(bus, PCI_DEVFN(ICH9_LPC_DEV,
> ICH9_LPC_FUNC),
> - true, "ICH9 LPC");
> - lpc = ich9_lpc_from_pci(d);
> + true, TYPE_ICH9_LPC_DEVICE);
> + lpc = ICH9_LPC_DEVICE(d);
> s->irq_state.lpc = lpc;
> return &lpc->d;
> }
>
> -static PCIDeviceInfo ich9_lpc_info = {
> - .qdev.name = "ICH9 LPC",
> - .qdev.desc = "ICH9 LPC bridge",
> - .qdev.size = sizeof(ICH9_LPCState),
> - .qdev.vmsd = &vmstate_ich9_lpc,
> - .qdev.no_user = 1,
> - .init = ich9_lpc_initfn,
> - .config_write = ich9_lpc_config_write,
> - .qdev.reset = ich9_lpc_reset,
> +static void ich9_lpc_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> + dc->reset = ich9_lpc_reset;
> + k->init = ich9_lpc_initfn;
> + dc->vmsd = &vmstate_ich9_lpc;
> + dc->no_user = 1;
> + k->config_write = ich9_lpc_config_write;
> + dc->desc = "ICH9 LPC bridge";
> + k->vendor_id = PCI_VENDOR_ID_INTEL;
> + k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8;
> + k->revision = ICH9_A2_LPC_REVISION;
> + k->class_id = PCI_CLASS_BRIDGE_ISA;
> +
> +}
> +
> +static TypeInfo ich9_lpc_info = {
'const'
> + .name = TYPE_ICH9_LPC_DEVICE,
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(struct ICH9_LPCState),
> + .class_init = ich9_lpc_class_init,
> };
>
> static void q35_register(void)
> {
> - sysbus_register_withprop(&gmch_pcihost_info);
> - pci_qdev_register(&gmch_info);
> - pci_qdev_register(&ich9_lpc_info);
> + type_register_static(&pci_gmch_info);
> + type_register_static(&gmch_pcihost_info);
> + type_register_static(&i82801b11_bridge_info);
> + type_register_static(&i21154_bridge_info);
> + type_register_static(&ich9_lpc_info);
> }
> -device_init(q35_register);
> +
> +type_init(q35_register);
> diff --git a/hw/q35.h b/hw/q35.h
> index be2e96b..030386e 100644
> --- a/hw/q35.h
> +++ b/hw/q35.h
> @@ -21,19 +21,109 @@
> #ifndef HW_Q35_H
> #define HW_Q35_H
>
> +#include "hw.h"
> +#include "range.h"
> +#include "isa.h"
> #include "sysbus.h"
> +#include "pc.h"
> +#include "apm.h"
> +#include "apic.h"
> +#include "pci.h"
> +#include "pcie_host.h"
> +#include "pci_bridge.h"
> +#include "q35.h"
> +#include "acpi.h"
> #include "acpi_ich9.h"
> +#include "pam.h"
> +#include "pci_internals.h"
> +
> +
> +#define ICH9_CC_SIZE (16 * 1024) /* 16KB */
> +
> +#define TYPE_GMCH_HOST_DEVICE "gmch-pcihost"
> +#define GMCH_HOST_DEVICE(obj) \
> + OBJECT_CHECK(GMCH_PCIHost, (obj), TYPE_GMCH_HOST_DEVICE)
> +
> +#define TYPE_GMCH_PCI_DEVICE "gmch"
> +#define GMCH_PCI_DEVICE(obj) \
> + OBJECT_CHECK(GMCH_PCIState, (obj), TYPE_GMCH_PCI_DEVICE)
> +
> +#define TYPE_ICH9_LPC_DEVICE "ICH9 LPC"
> +#define ICH9_LPC_DEVICE(obj) \
> + OBJECT_CHECK(ICH9_LPCState, (obj), TYPE_ICH9_LPC_DEVICE)
> +
> +struct ICH9_LPCState;
ICH9LPCState, typedef missing.
> +
> +typedef struct ICH9_LPCIrqState {
ICH9LPCIRQState
> + struct ICH9_LPCState *lpc;
> + qemu_irq *pic;
> + qemu_irq *ioapic;
> +} ICH9_LPCIrqState;
> +
> +typedef struct GMCH_PCIHost {
GMCHPCIHost, or does GMCH stand for something that is more suitable
for CamelCasing?
> + PCIExpressHost host;
> +
> + PCIDevice *dev;
> + ICH9_LPCIrqState irq_state;
> +} GMCH_PCIHost;
> +
> +typedef struct GMCH_PCIState {
> + PCIDevice d;
> + /*
> + * GMCH_PCIHost *gmch_host;
> + * In order to get GMCH_PCIHost
> + * PCIDevice -> qdev -> parent_bus -> qdev -upcast-> GMCH_PCIHost
> + */
> + MemoryRegion *ram_memory;
> + MemoryRegion *pci_address_space;
> + MemoryRegion *system_memory;
> + PAMMemoryRegion pam_regions[13];
> + MemoryRegion smram_region;
> + MemoryRegion pci_hole;
> + MemoryRegion pci_hole_64bit;
> + uint8_t smm_enabled;
> +} GMCH_PCIState;
> +
> +typedef struct ICH9_LPCState {
The typedef part should be declared earlier so that other structures
can use the typedef.
> + /* ICH9 LPC PCI to ISA bridge */
> + PCIDevice d;
> +
> + /* (pci device, intx) -> pirq
> + * In real chipset case, the unused slots are never used
> + * as ICH9 supports only D25-D32 irq routing.
> + * On the other hand in qemu case, any slot/function can be populated
> + * via command line option.
> + * So fallback interrupt routing for any devices in any slots is
> necessary.
> + */
> + uint8_t irr[PCI_SLOT_MAX][PCI_NUM_PINS];
> +
> + APMState apm;
> + ICH9_LPCPmRegs pm;
> + uint32_t sci_level; /* track sci level */
> +
> + /* 10.1 Chipset Configuration registers(Memory Space)
> + which is pointed by RCBA */
> + uint8_t chip_config[ICH9_CC_SIZE];
> + /* isa bus */
> + ISABus *isa_bus;
> + MemoryRegion rbca_mem;
> +} ICH9_LPCState;
>
> -PCIBus *gmch_host_init(DeviceState **gmch_hostp,
> - qemu_irq *pic, qemu_irq *ioapic);
>
> +
> +
> +PCIBus *gmch_host_init(DeviceState **gmch_hostp,
> + qemu_irq *pic, qemu_irq *ioapic,
> + MemoryRegion *pci_address_space,
> + MemoryRegion *address_space_io);
> PCIDevice *gmch_init(DeviceState *gmch_host, PCIBus *b);
> PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus);
> PCIDevice *gmch_lpc_init(DeviceState *gmch_host, PCIBus *bus);
> void ich9_lpc_pm_init(DeviceState *gmch_host, PCIDevice *pci_lpc,
> qemu_irq cmos_s3);
> -
> i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
> +PCIBridge *i21154_init(PCIBus *bus, int devfn, const char *bus_name,
> + bool multifunction);
>
> #define Q35_MASK(bit, ms_bit, ls_bit) \
> ((uint##bit##_t)(((1ULL << ((ms_bit) + 1)) - 1) & ~((1ULL << ls_bit) - 1)))
> @@ -124,7 +214,6 @@ i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t
> smb_io_base);
> */
>
> /* ICH9: Chipset Configuration Registers */
> -#define ICH9_CC_SIZE (16 * 1024) /* 16KB */
> #define ICH9_CC_ADDR_MASK (ICH9_CC_SIZE - 1)
>
> #define ICH9_CC
> diff --git a/hw/q35_smbus.c b/hw/q35_smbus.c
> index fe445ac..0ee404e 100644
> --- a/hw/q35_smbus.c
> +++ b/hw/q35_smbus.c
> @@ -18,6 +18,7 @@
> /*
> * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
> * VA Linux Systems Japan K.K.
> + * Copyright (C) 2012 Jason Baron <address@hidden>
> *
> * This is based on acpi.c, but heavily rewritten.
> */
> @@ -35,6 +36,7 @@ typedef struct ICH9_SMBState {
> PCIDevice dev;
>
> PMSMBus smb;
> + MemoryRegion mem_bar;
> } ICH9_SMBState;
>
> static ICH9_SMBState *ich9_pci_to_smb(PCIDevice* pci_dev)
> @@ -53,7 +55,8 @@ static const VMStateDescription vmstate_ich9_smbus = {
> }
> };
>
> -static void ich9_smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
> +static void ich9_smb_ioport_writeb(void *opaque, target_phys_addr_t addr,
> + uint64_t val, unsigned size)
> {
> ICH9_SMBState *s = opaque;
> uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC];
> @@ -64,7 +67,8 @@ static void ich9_smb_ioport_writeb(void *opaque, uint32_t
> addr, uint32_t val)
> }
> }
>
> -static uint32_t ich9_smb_ioport_readb(void *opaque, uint32_t addr)
> +static uint64_t ich9_smb_ioport_readb(void *opaque, target_phys_addr_t addr,
> + unsigned size)
> {
> ICH9_SMBState *s = opaque;
> uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC];
> @@ -77,32 +81,22 @@ static uint32_t ich9_smb_ioport_readb(void *opaque,
> uint32_t addr)
> return 0xff;
> }
>
> -static void ich9_smb_map_ioport(PCIDevice *dev, int region_num,
> - uint64_t addr, uint64_t size, int type)
> -{
> - ICH9_SMBState *s = ich9_pci_to_smb(dev);
> -
> - assert(size == ICH9_SMB_SMB_BASE_SIZE);
> - assert(type == PCI_BASE_ADDRESS_SPACE_IO);
> -
> - register_ioport_write(addr, 64, 1, ich9_smb_ioport_writeb, s);
> - register_ioport_read(addr, 64, 1, ich9_smb_ioport_readb, s);
> -}
> +static const MemoryRegionOps lpc_smb_mmio_ops = {
> + .read = ich9_smb_ioport_readb,
> + .write = ich9_smb_ioport_writeb,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> + .impl = {
> + .min_access_size = 1,
> + .max_access_size = 1,
> + },
> +};
>
> -static int ich9_smb_initfn(PCIDevice *d)
> +static int ich9_smbus_initfn(PCIDevice *d)
> {
> ICH9_SMBState *s = ich9_pci_to_smb(d);
>
> - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL);
> - pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_ICH9_6);
> -
> pci_set_word(d->wmask + PCI_STATUS,
> - PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY);
> -
> - pci_config_set_revision(d->config, ICH9_A2_SMB_REVISION);
> - pci_config_set_prog_interface(d->config, ICH9_SMB_PI);
> - pci_config_set_class(d->config, PCI_CLASS_SERIAL_SMBUS);
> -
> + PCI_STATUS_SIG_SYSTEM_ERROR |
> PCI_STATUS_DETECTED_PARITY);
> /* TODO? D31IP.SMIP in chipset configuration space */
> pci_config_set_interrupt_pin(d->config, 0x01); /* interrupt pin 1 */
>
> @@ -121,14 +115,30 @@ static int ich9_smb_initfn(PCIDevice *d)
> /* TODO smb_io_base */
> pci_set_byte(d->config + ICH9_SMB_HOSTC, 0);
> /* TODO bar0, bar1: 64bit BAR support*/
> - pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR,
> - ICH9_SMB_SMB_BASE_SIZE, PCI_BASE_ADDRESS_SPACE_IO,
> - &ich9_smb_map_ioport);
>
> + memory_region_init_io(&s->mem_bar, &lpc_smb_mmio_ops, s,
> "ich9-smbus-bar",
> + ICH9_SMB_SMB_BASE_SIZE);
> + pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
> + &s->mem_bar);
> pm_smbus_init(&d->qdev, &s->smb);
> return 0;
> }
>
> +static void ich9_smb_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> + k->vendor_id = PCI_VENDOR_ID_INTEL;
> + k->device_id = PCI_DEVICE_ID_INTEL_ICH9_6;
> + k->revision = ICH9_A2_SMB_REVISION;
> + k->class_id = PCI_CLASS_SERIAL_SMBUS;
> + dc->no_user = 1;
> + dc->vmsd = &vmstate_ich9_smbus;
> + dc->desc = "ICH9 SMBUS Bridge";
> + k->init = ich9_smbus_initfn;
> +}
> +
> i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
> {
> PCIDevice *d =
> @@ -137,18 +147,16 @@ i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t
> smb_io_base)
> return s->smb.smbus;
> }
>
> -static PCIDeviceInfo ich9_smb_info = {
> - .qdev.name = "ICH9 SMB",
> - .qdev.desc = "ICH9 SMBUS Bridge",
> - .qdev.size = sizeof(ICH9_SMBState),
> - .qdev.vmsd = &vmstate_ich9_smbus,
> - .qdev.no_user = 1,
> - .init = ich9_smb_initfn,
> +static TypeInfo ich9_smb_info = {
'const'
> + .name = "ICH9 SMB",
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(ICH9_SMBState),
> + .class_init = ich9_smb_class_init,
> };
>
> static void ich9_smb_register(void)
> {
> - pci_qdev_register(&ich9_smb_info);
> + type_register_static(&ich9_smb_info);
> }
>
> -device_init(ich9_smb_register);
> +type_init(ich9_smb_register);
> --
> 1.7.1
>
>
- Re: [Qemu-devel] [PATCH 24/25] Add a fallback bios file search, if -L fails., (continued)
- [Qemu-devel] [PATCH 16/25] pci: Add class 0xc05 as 'SMBus', Jason Baron, 2012/09/13
- [Qemu-devel] [PATCH 18/25] q35: Fix irr initialization for slots 25..31, Jason Baron, 2012/09/13
- [Qemu-devel] [PATCH 23/25] q35: add acpi-based pci hotplug., Jason Baron, 2012/09/13
- [Qemu-devel] [PATCH 12/25] q35: Re-base q35 to 1.2, Jason Baron, 2012/09/13
- Re: [Qemu-devel] [PATCH 12/25] q35: Re-base q35 to 1.2,
Blue Swirl <=
- Re: [Qemu-devel] [PATCH 00/25] q35 series take #1, Alexander Graf, 2012/09/13
Re: [Qemu-devel] [PATCH 00/25] q35 series take #1, Isaku Yamahata, 2012/09/14