Commit 8a14daa5a1ae22fcfc317f4727a88d6c15c39aae

Authored by Gerd Hoffmann
Committed by Anthony Liguori
1 parent bd3c948d

qdev/pci: hook up i440fx.

Hook i44fx pcihost into sysbus.
Convert Host bridge and ISA bridge pci devices to qdev.
Tag as no-user.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 2 changed files with 85 additions and 26 deletions
hw/pci_host.h
@@ -28,6 +28,8 @@ @@ -28,6 +28,8 @@
28 /* debug PCI */ 28 /* debug PCI */
29 //#define DEBUG_PCI 29 //#define DEBUG_PCI
30 30
  31 +#include "sysbus.h"
  32 +
31 #ifdef DEBUG_PCI 33 #ifdef DEBUG_PCI
32 #define PCI_DPRINTF(fmt, ...) \ 34 #define PCI_DPRINTF(fmt, ...) \
33 do { printf("pci_host_data: " fmt , ## __VA_ARGS__); } while (0) 35 do { printf("pci_host_data: " fmt , ## __VA_ARGS__); } while (0)
@@ -36,6 +38,7 @@ do { printf(&quot;pci_host_data: &quot; fmt , ## __VA_ARGS__); } while (0) @@ -36,6 +38,7 @@ do { printf(&quot;pci_host_data: &quot; fmt , ## __VA_ARGS__); } while (0)
36 #endif 38 #endif
37 39
38 typedef struct { 40 typedef struct {
  41 + SysBusDevice busdev;
39 uint32_t config_reg; 42 uint32_t config_reg;
40 PCIBus *bus; 43 PCIBus *bus;
41 } PCIHostState; 44 } PCIHostState;
hw/piix_pci.c
@@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
25 #include "hw.h" 25 #include "hw.h"
26 #include "pc.h" 26 #include "pc.h"
27 #include "pci.h" 27 #include "pci.h"
  28 +#include "sysbus.h"
28 29
29 typedef uint32_t pci_addr_t; 30 typedef uint32_t pci_addr_t;
30 #include "pci_host.h" 31 #include "pci_host.h"
@@ -169,16 +170,9 @@ static int i440fx_load(QEMUFile* f, void *opaque, int version_id) @@ -169,16 +170,9 @@ static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
169 return 0; 170 return 0;
170 } 171 }
171 172
172 -PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) 173 +static void i440fx_pcihost_initfn(SysBusDevice *dev)
173 { 174 {
174 - PCIBus *b;  
175 - PCIDevice *d;  
176 - I440FXState *s;  
177 -  
178 - s = qemu_mallocz(sizeof(I440FXState));  
179 - b = pci_register_bus(NULL, "pci",  
180 - piix3_set_irq, pci_slot_get_pirq, pic, 0, 4);  
181 - s->bus = b; 175 + I440FXState *s = FROM_SYSBUS(I440FXState, dev);
182 176
183 register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s); 177 register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
184 register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s); 178 register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
@@ -189,10 +183,10 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) @@ -189,10 +183,10 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic)
189 register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s); 183 register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
190 register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s); 184 register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
191 register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s); 185 register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
  186 +}
192 187
193 - d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,  
194 - NULL, i440fx_write_config);  
195 - 188 +static void i440fx_initfn(PCIDevice *d)
  189 +{
196 pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL); 190 pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL);
197 pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_82441); 191 pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_82441);
198 d->config[0x08] = 0x02; // revision 192 d->config[0x08] = 0x02; // revision
@@ -202,7 +196,25 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) @@ -202,7 +196,25 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic)
202 d->config[0x72] = 0x02; /* SMRAM */ 196 d->config[0x72] = 0x02; /* SMRAM */
203 197
204 register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d); 198 register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d);
  199 +}
  200 +
  201 +PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic)
  202 +{
  203 + DeviceState *dev;
  204 + PCIBus *b;
  205 + PCIDevice *d;
  206 + I440FXState *s;
  207 +
  208 + dev = qdev_create(NULL, "i440FX-pcihost");
  209 + s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
  210 + b = pci_register_bus(&s->busdev.qdev, "pci.0",
  211 + piix3_set_irq, pci_slot_get_pirq, pic, 0, 4);
  212 + s->bus = b;
  213 + qdev_init(dev);
  214 +
  215 + d = pci_create_simple(b, 0, "i440FX");
205 *pi440fx_state = d; 216 *pi440fx_state = d;
  217 +
206 return b; 218 return b;
207 } 219 }
208 220
@@ -326,49 +338,93 @@ static int piix_load(QEMUFile* f, void *opaque, int version_id) @@ -326,49 +338,93 @@ static int piix_load(QEMUFile* f, void *opaque, int version_id)
326 return pci_device_load(d, f); 338 return pci_device_load(d, f);
327 } 339 }
328 340
329 -int piix3_init(PCIBus *bus, int devfn) 341 +static void piix3_initfn(PCIDevice *d)
330 { 342 {
331 - PCIDevice *d;  
332 uint8_t *pci_conf; 343 uint8_t *pci_conf;
333 344
334 - d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice),  
335 - devfn, NULL, NULL);  
336 register_savevm("PIIX3", 0, 2, piix_save, piix_load, d); 345 register_savevm("PIIX3", 0, 2, piix_save, piix_load, d);
337 346
338 - piix3_dev = d;  
339 pci_conf = d->config; 347 pci_conf = d->config;
340 -  
341 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); 348 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
342 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_0); // 82371SB PIIX3 PCI-to-ISA bridge (Step A1) 349 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_0); // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
343 pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); 350 pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
344 pci_conf[PCI_HEADER_TYPE] = 351 pci_conf[PCI_HEADER_TYPE] =
345 PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic 352 PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic
346 353
  354 + piix3_dev = d;
347 piix3_reset(d); 355 piix3_reset(d);
348 qemu_register_reset(piix3_reset, d); 356 qemu_register_reset(piix3_reset, d);
349 - return d->devfn;  
350 } 357 }
351 358
352 -int piix4_init(PCIBus *bus, int devfn) 359 +static void piix4_initfn(PCIDevice *d)
353 { 360 {
354 - PCIDevice *d;  
355 uint8_t *pci_conf; 361 uint8_t *pci_conf;
356 362
357 - d = pci_register_device(bus, "PIIX4", sizeof(PCIDevice),  
358 - devfn, NULL, NULL);  
359 register_savevm("PIIX4", 0, 2, piix_save, piix_load, d); 363 register_savevm("PIIX4", 0, 2, piix_save, piix_load, d);
360 364
361 - piix4_dev = d;  
362 pci_conf = d->config; 365 pci_conf = d->config;
363 -  
364 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); 366 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
365 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge 367 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
366 pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); 368 pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
367 pci_conf[PCI_HEADER_TYPE] = 369 pci_conf[PCI_HEADER_TYPE] =
368 PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic 370 PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic
369 371
370 - 372 + piix4_dev = d;
371 piix4_reset(d); 373 piix4_reset(d);
372 qemu_register_reset(piix4_reset, d); 374 qemu_register_reset(piix4_reset, d);
  375 +}
  376 +
  377 +int piix3_init(PCIBus *bus, int devfn)
  378 +{
  379 + PCIDevice *d;
  380 +
  381 + d = pci_create_simple(bus, devfn, "PIIX3");
373 return d->devfn; 382 return d->devfn;
374 } 383 }
  384 +
  385 +int piix4_init(PCIBus *bus, int devfn)
  386 +{
  387 + PCIDevice *d;
  388 +
  389 + d = pci_create_simple(bus, devfn, "PIIX4");
  390 + return d->devfn;
  391 +}
  392 +
  393 +static PCIDeviceInfo i440fx_info[] = {
  394 + {
  395 + .qdev.name = "i440FX",
  396 + .qdev.desc = "Host bridge",
  397 + .qdev.size = sizeof(PCIDevice),
  398 + .qdev.no_user = 1,
  399 + .init = i440fx_initfn,
  400 + .config_write = i440fx_write_config,
  401 + },{
  402 + .qdev.name = "PIIX3",
  403 + .qdev.desc = "ISA bridge",
  404 + .qdev.size = sizeof(PCIDevice),
  405 + .qdev.no_user = 1,
  406 + .init = piix3_initfn,
  407 + },{
  408 + .qdev.name = "PIIX4",
  409 + .qdev.desc = "ISA bridge",
  410 + .qdev.size = sizeof(PCIDevice),
  411 + .qdev.no_user = 1,
  412 + .init = piix4_initfn,
  413 + },{
  414 + /* end of list */
  415 + }
  416 +};
  417 +
  418 +static SysBusDeviceInfo i440fx_pcihost_info = {
  419 + .init = i440fx_pcihost_initfn,
  420 + .qdev.name = "i440FX-pcihost",
  421 + .qdev.size = sizeof(I440FXState),
  422 + .qdev.no_user = 1,
  423 +};
  424 +
  425 +static void i440fx_register(void)
  426 +{
  427 + sysbus_register_withprop(&i440fx_pcihost_info);
  428 + pci_qdev_register_many(i440fx_info);
  429 +}
  430 +device_init(i440fx_register);