On Thu, Sep 13, 2012 at 8:12 PM, Jason Baron <jba...@redhat.com> wrote: > Rebase q35 to 1.2 - memory api updates, acpi updates, qom... > > Signed-off-by: Jason Baron <jba...@redhat.com> > --- > 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 <jba...@redhat.com> > * > * 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 <jba...@redhat.com> > * > * 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 <jba...@redhat.com> > * > * 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 <jba...@redhat.com> > * > * 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 > >