diff mbox

[RFC,v1,15/20] i440fx pmc: create pmc through comosition

Message ID 0be9ec2476a9e5fe5397e0d220e938eeccd89357.1369193012.git.hutao@cn.fujitsu.com
State New
Headers show

Commit Message

Hu Tao May 22, 2013, 5:33 a.m. UTC
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
 hw/pci-host/piix.c | 101 +++++++++++++++++++++++++++++++++--------------------
 1 file changed, 64 insertions(+), 37 deletions(-)
diff mbox

Patch

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 0030cad..1798060 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -105,6 +105,11 @@  struct I440FXPMCState {
     PAMMemoryRegion pam_regions[13];
     MemoryRegion smram_region;
     uint8_t smm_enabled;
+    ram_addr_t ram_size;
+    hwaddr pci_hole_start;
+    hwaddr pci_hole_size;
+    hwaddr pci_hole64_start;
+    hwaddr pci_hole64_size;
 };
 
 #define TYPE_I440FX_DEVICE "i440FX"
@@ -117,6 +122,7 @@  typedef struct I440FXState {
     MemoryRegion *pci_address_space;
 
     PIIX3State piix3;
+    I440FXPMCState pmc;
 } I440FXState;
 
 #define I440FX_PAM      0x59
@@ -247,6 +253,9 @@  static int i440fx_realize(SysBusDevice *dev)
         pci_bus_set_route_irq_fn(s->bus, piix3_route_intx_pin_to_irq);
     }
 
+    qdev_set_parent_bus(DEVICE(&f->pmc), BUS(s->bus));
+    qdev_init_nofail(DEVICE(&f->pmc));
+
     return 0;
 }
 
@@ -266,11 +275,54 @@  static void i440fx_initfn(Object *obj)
     qdev_prop_set_uint32(DEVICE(&f->piix3), "addr", PCI_DEVFN(1, 0));
     qdev_prop_set_bit(DEVICE(&f->piix3), "multifunction", true);
     object_property_add_child(OBJECT(f), "piix3", OBJECT(&f->piix3), NULL);
+
+    object_initialize(&f->pmc, TYPE_I440FX_PMC_DEVICE);
+    object_property_add_child(obj, "pmc", OBJECT(&f->pmc), NULL);
+    qdev_prop_set_uint32(DEVICE(&f->pmc), "addr", PCI_DEVFN(0, 0));
 }
 
 static int i440fx_pmc_initfn(PCIDevice *dev)
 {
     I440FXPMCState *d = I440FX_PMC_DEVICE(dev);
+    ram_addr_t ram_size;
+    int i;
+
+    g_assert(d->system_memory != NULL);
+    g_assert(d->pci_address_space != NULL);
+    g_assert(d->ram_memory != NULL);
+
+    memory_region_init_alias(&d->pci_hole, "pci-hole", d->pci_address_space,
+                             d->pci_hole_start, d->pci_hole_size);
+    memory_region_add_subregion(d->system_memory, d->pci_hole_start,
+                                &d->pci_hole);
+    memory_region_init_alias(&d->pci_hole_64bit, "pci-hole64",
+                             d->pci_address_space,
+                             d->pci_hole64_start, d->pci_hole64_size);
+    if (d->pci_hole64_size) {
+        memory_region_add_subregion(d->system_memory, d->pci_hole64_start,
+                                    &d->pci_hole_64bit);
+    }
+    memory_region_init_alias(&d->smram_region, "smram-region",
+                             d->pci_address_space, 0xa0000, 0x20000);
+    memory_region_add_subregion_overlap(d->system_memory, 0xa0000,
+                                        &d->smram_region, 1);
+    memory_region_set_enabled(&d->smram_region, false);
+
+    init_pam(d->ram_memory, d->system_memory, d->pci_address_space,
+             &d->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
+    for (i = 0; i < 12; ++i) {
+        init_pam(d->ram_memory, d->system_memory, d->pci_address_space,
+                 &d->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE,
+                 PAM_EXPAN_SIZE);
+    }
+
+    ram_size = d->ram_size / 8 / 1024 / 1024;
+    if (ram_size > 255) {
+        ram_size = 255;
+    }
+    d->dev.config[0x57] = ram_size;
+
+    i440fx_pmc_update_memory_mappings(d);
 
     d->dev.config[I440FX_SMRAM] = 0x02;
 
@@ -291,12 +343,10 @@  static PCIBus *i440fx_common_init(const char *device_name,
                                   MemoryRegion *pci_address_space,
                                   MemoryRegion *ram_memory)
 {
-    PCIDevice *d;
     PCIHostState *s;
     PIIX3State *piix3;
     I440FXPMCState *f;
     I440FXState *i440fx;
-    unsigned i;
 
     i440fx = I440FX_DEVICE(object_new(TYPE_I440FX_DEVICE));
     s = PCI_HOST_BRIDGE(i440fx);
@@ -307,49 +357,26 @@  static PCIBus *i440fx_common_init(const char *device_name,
     piix3 = &i440fx->piix3;
     piix3->pic = pic;
 
-    object_property_add_child(qdev_get_machine(), "i440fx",
-                              OBJECT(i440fx), NULL);
-    qdev_set_parent_bus(DEVICE(i440fx), sysbus_get_default());
-    qdev_init_nofail(DEVICE(i440fx));
+    /* FIXME these should be derived */
+    i440fx->pmc.pci_hole_start = pci_hole_start;
+    i440fx->pmc.pci_hole_size = pci_hole_size;
+    i440fx->pmc.pci_hole64_start = pci_hole64_start;
+    i440fx->pmc.pci_hole64_size = pci_hole64_size;
 
-    d = pci_create_simple(s->bus, 0, device_name);
-    f = I440FX_PMC_DEVICE(d);
+    f = &i440fx->pmc;
+    f->ram_size = ram_size;
     f->system_memory = address_space_mem;
     f->pci_address_space = pci_address_space;
     f->ram_memory = ram_memory;
-    memory_region_init_alias(&f->pci_hole, "pci-hole", f->pci_address_space,
-                             pci_hole_start, pci_hole_size);
-    memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
-    memory_region_init_alias(&f->pci_hole_64bit, "pci-hole64",
-                             f->pci_address_space,
-                             pci_hole64_start, pci_hole64_size);
-    if (pci_hole64_size) {
-        memory_region_add_subregion(f->system_memory, pci_hole64_start,
-                                    &f->pci_hole_64bit);
-    }
-    memory_region_init_alias(&f->smram_region, "smram-region",
-                             f->pci_address_space, 0xa0000, 0x20000);
-    memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
-                                        &f->smram_region, 1);
-    memory_region_set_enabled(&f->smram_region, false);
-    init_pam(f->ram_memory, f->system_memory, f->pci_address_space,
-             &f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
-    for (i = 0; i < 12; ++i) {
-        init_pam(f->ram_memory, f->system_memory, f->pci_address_space,
-                 &f->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE,
-                 PAM_EXPAN_SIZE);
-    }
+
+    object_property_add_child(qdev_get_machine(), "i440fx",
+                              OBJECT(i440fx), NULL);
+    qdev_set_parent_bus(DEVICE(i440fx), sysbus_get_default());
+    qdev_init_nofail(DEVICE(i440fx));
 
     *isa_bus = piix3->bus;
     *piix3_devfn = piix3->dev.devfn;
 
-    ram_size = ram_size / 8 / 1024 / 1024;
-    if (ram_size > 255)
-        ram_size = 255;
-    f->dev.config[0x57] = ram_size;
-
-    i440fx_pmc_update_memory_mappings(f);
-
     return s->bus;
 }