diff options
Diffstat (limited to 'hw/pci-host/i440fx.c')
| -rw-r--r-- | hw/pci-host/i440fx.c | 128 |
1 files changed, 69 insertions, 59 deletions
diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c index 61e7b97ff4..62d6287681 100644 --- a/hw/pci-host/i440fx.c +++ b/hw/pci-host/i440fx.c @@ -27,7 +27,6 @@ #include "qemu/range.h" #include "hw/i386/pc.h" #include "hw/pci/pci.h" -#include "hw/pci/pci_bus.h" #include "hw/pci/pci_host.h" #include "hw/pci-host/i440fx.h" #include "hw/qdev-properties.h" @@ -47,10 +46,19 @@ OBJECT_DECLARE_SIMPLE_TYPE(I440FXState, I440FX_PCI_HOST_BRIDGE) struct I440FXState { PCIHostState parent_obj; + + MemoryRegion *system_memory; + MemoryRegion *io_memory; + MemoryRegion *pci_address_space; + MemoryRegion *ram_memory; Range pci_hole; + uint64_t below_4g_mem_size; + uint64_t above_4g_mem_size; uint64_t pci_hole64_size; bool pci_hole64_fix; uint32_t short_root_bus; + + char *pci_type; }; #define I440FX_PAM 0x59 @@ -65,6 +73,15 @@ struct I440FXState { */ #define I440FX_COREBOOT_RAM_SIZE 0x57 +static void i440fx_realize(PCIDevice *dev, Error **errp) +{ + dev->config[I440FX_SMRAM] = 0x02; + + if (object_property_get_bool(qdev_get_machine(), "iommu", NULL)) { + warn_report("i440fx doesn't support emulated iommu"); + } +} + static void i440fx_update_memory_mappings(PCII440FXState *d) { int i; @@ -205,80 +222,69 @@ static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v, static void i440fx_pcihost_initfn(Object *obj) { - PCIHostState *s = PCI_HOST_BRIDGE(obj); + I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj); + PCIHostState *phb = PCI_HOST_BRIDGE(obj); - memory_region_init_io(&s->conf_mem, obj, &pci_host_conf_le_ops, s, + memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb, "pci-conf-idx", 4); - memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s, + memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb, "pci-conf-data", 4); -} -static void i440fx_pcihost_realize(DeviceState *dev, Error **errp) -{ - PCIHostState *s = PCI_HOST_BRIDGE(dev); - SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + object_property_add_link(obj, PCI_HOST_PROP_RAM_MEM, TYPE_MEMORY_REGION, + (Object **) &s->ram_memory, + qdev_prop_allow_set_link_before_realize, 0); - memory_region_add_subregion(s->bus->address_space_io, 0xcf8, &s->conf_mem); - sysbus_init_ioports(sbd, 0xcf8, 4); + object_property_add_link(obj, PCI_HOST_PROP_PCI_MEM, TYPE_MEMORY_REGION, + (Object **) &s->pci_address_space, + qdev_prop_allow_set_link_before_realize, 0); - memory_region_add_subregion(s->bus->address_space_io, 0xcfc, &s->data_mem); - sysbus_init_ioports(sbd, 0xcfc, 4); + object_property_add_link(obj, PCI_HOST_PROP_SYSTEM_MEM, TYPE_MEMORY_REGION, + (Object **) &s->system_memory, + qdev_prop_allow_set_link_before_realize, 0); - /* register i440fx 0xcf8 port as coalesced pio */ - memory_region_set_flush_coalesced(&s->data_mem); - memory_region_add_coalescing(&s->conf_mem, 0, 4); + object_property_add_link(obj, PCI_HOST_PROP_IO_MEM, TYPE_MEMORY_REGION, + (Object **) &s->io_memory, + qdev_prop_allow_set_link_before_realize, 0); } -static void i440fx_realize(PCIDevice *dev, Error **errp) -{ - dev->config[I440FX_SMRAM] = 0x02; - - if (object_property_get_bool(qdev_get_machine(), "iommu", NULL)) { - warn_report("i440fx doesn't support emulated iommu"); - } -} - -PCIBus *i440fx_init(const char *pci_type, - DeviceState *dev, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io, - ram_addr_t ram_size, - ram_addr_t below_4g_mem_size, - ram_addr_t above_4g_mem_size, - MemoryRegion *pci_address_space, - MemoryRegion *ram_memory) +static void i440fx_pcihost_realize(DeviceState *dev, Error **errp) { + ERRP_GUARD(); + I440FXState *s = I440FX_PCI_HOST_BRIDGE(dev); + PCIHostState *phb = PCI_HOST_BRIDGE(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); PCIBus *b; PCIDevice *d; - PCIHostState *s; PCII440FXState *f; unsigned i; - I440FXState *i440fx; - s = PCI_HOST_BRIDGE(dev); - b = pci_root_bus_new(dev, NULL, pci_address_space, - address_space_io, 0, TYPE_PCI_BUS); - s->bus = b; - object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev)); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + memory_region_add_subregion(s->io_memory, 0xcf8, &phb->conf_mem); + sysbus_init_ioports(sbd, 0xcf8, 4); + + memory_region_add_subregion(s->io_memory, 0xcfc, &phb->data_mem); + sysbus_init_ioports(sbd, 0xcfc, 4); - d = pci_create_simple(b, 0, pci_type); + /* register i440fx 0xcf8 port as coalesced pio */ + memory_region_set_flush_coalesced(&phb->data_mem); + memory_region_add_coalescing(&phb->conf_mem, 0, 4); + + b = pci_root_bus_new(dev, NULL, s->pci_address_space, + s->io_memory, 0, TYPE_PCI_BUS); + phb->bus = b; + + d = pci_create_simple(b, 0, s->pci_type); f = I440FX_PCI_DEVICE(d); - f->system_memory = address_space_mem; - f->pci_address_space = pci_address_space; - f->ram_memory = ram_memory; - i440fx = I440FX_PCI_HOST_BRIDGE(dev); - range_set_bounds(&i440fx->pci_hole, below_4g_mem_size, + range_set_bounds(&s->pci_hole, s->below_4g_mem_size, IO_APIC_DEFAULT_ADDRESS - 1); /* setup pci memory mapping */ - pc_pci_as_mapping_init(f->system_memory, f->pci_address_space); + pc_pci_as_mapping_init(s->system_memory, s->pci_address_space); /* if *disabled* show SMRAM to all CPUs */ memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region", - f->pci_address_space, 0xa0000, 0x20000); - memory_region_add_subregion_overlap(f->system_memory, 0xa0000, + s->pci_address_space, SMRAM_C_BASE, SMRAM_C_SIZE); + memory_region_add_subregion_overlap(s->system_memory, SMRAM_C_BASE, &f->smram_region, 1); memory_region_set_enabled(&f->smram_region, true); @@ -286,20 +292,21 @@ PCIBus *i440fx_init(const char *pci_type, memory_region_init(&f->smram, OBJECT(d), "smram", 4 * GiB); memory_region_set_enabled(&f->smram, true); memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low", - f->ram_memory, 0xa0000, 0x20000); + s->ram_memory, SMRAM_C_BASE, SMRAM_C_SIZE); memory_region_set_enabled(&f->low_smram, true); - memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram); + memory_region_add_subregion(&f->smram, SMRAM_C_BASE, &f->low_smram); object_property_add_const_link(qdev_get_machine(), "smram", OBJECT(&f->smram)); - init_pam(&f->pam_regions[0], OBJECT(d), f->ram_memory, f->system_memory, - f->pci_address_space, PAM_BIOS_BASE, PAM_BIOS_SIZE); + init_pam(&f->pam_regions[0], OBJECT(d), s->ram_memory, s->system_memory, + s->pci_address_space, PAM_BIOS_BASE, PAM_BIOS_SIZE); for (i = 0; i < ARRAY_SIZE(f->pam_regions) - 1; ++i) { - init_pam(&f->pam_regions[i + 1], OBJECT(d), f->ram_memory, - f->system_memory, f->pci_address_space, + init_pam(&f->pam_regions[i + 1], OBJECT(d), s->ram_memory, + s->system_memory, s->pci_address_space, PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); } + ram_addr_t ram_size = s->below_4g_mem_size + s->above_4g_mem_size; ram_size = ram_size / 8 / 1024 / 1024; if (ram_size > 255) { ram_size = 255; @@ -307,8 +314,6 @@ PCIBus *i440fx_init(const char *pci_type, d->config[I440FX_COREBOOT_RAM_SIZE] = ram_size; i440fx_update_memory_mappings(f); - - return b; } static void i440fx_class_init(ObjectClass *klass, void *data) @@ -359,7 +364,12 @@ static Property i440fx_props[] = { DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState, pci_hole64_size, I440FX_PCI_HOST_HOLE64_SIZE_DEFAULT), DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 0), + DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, I440FXState, + below_4g_mem_size, 0), + DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, I440FXState, + above_4g_mem_size, 0), DEFINE_PROP_BOOL("x-pci-hole64-fix", I440FXState, pci_hole64_fix, true), + DEFINE_PROP_STRING(I440FX_HOST_PROP_PCI_TYPE, I440FXState, pci_type), DEFINE_PROP_END_OF_LIST(), }; |