Commit 72f44c8cc73deec56a04156384a2d76b7a3ab82d

Authored by Blue Swirl
1 parent 0bf9e31a

Sparc64: convert APB to qdev

Thanks to Igor Kovalenko for a bugfix.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Showing 2 changed files with 76 additions and 35 deletions
hw/apb_pci.c
... ... @@ -26,7 +26,7 @@
26 26 Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
27 27 the secondary PCI bridge. */
28 28  
29   -#include "hw.h"
  29 +#include "sysbus.h"
30 30 #include "pci.h"
31 31  
32 32 /* debug APB */
... ... @@ -42,7 +42,10 @@ do { printf(&quot;APB: &quot; fmt , ## __VA_ARGS__); } while (0)
42 42 typedef target_phys_addr_t pci_addr_t;
43 43 #include "pci_host.h"
44 44  
45   -typedef PCIHostState APBState;
  45 +typedef struct APBState {
  46 + SysBusDevice busdev;
  47 + PCIHostState host_state;
  48 +} APBState;
46 49  
47 50 static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
48 51 uint32_t val)
... ... @@ -54,7 +57,7 @@ static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
54 57 #endif
55 58 APB_DPRINTF("config_writel addr " TARGET_FMT_plx " val %x\n", addr,
56 59 val);
57   - s->config_reg = val;
  60 + s->host_state.config_reg = val;
58 61 }
59 62  
60 63 static uint32_t pci_apb_config_readl (void *opaque,
... ... @@ -63,7 +66,7 @@ static uint32_t pci_apb_config_readl (void *opaque,
63 66 APBState *s = opaque;
64 67 uint32_t val;
65 68  
66   - val = s->config_reg;
  69 + val = s->host_state.config_reg;
67 70 #ifdef TARGET_WORDS_BIGENDIAN
68 71 val = bswap32(val);
69 72 #endif
... ... @@ -225,34 +228,65 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
225 228 target_phys_addr_t mem_base,
226 229 qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
227 230 {
228   - APBState *s;
229   - PCIDevice *d;
230   - int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
  231 + DeviceState *dev;
  232 + SysBusDevice *s;
  233 + APBState *d;
231 234  
232   - s = qemu_mallocz(sizeof(APBState));
233 235 /* Ultrasparc PBM main bus */
234   - s->bus = pci_register_bus(NULL, "pci",
235   - pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32);
  236 + dev = qdev_create(NULL, "pbm");
  237 + qdev_init(dev);
  238 + s = sysbus_from_qdev(dev);
  239 + /* apb_config */
  240 + sysbus_mmio_map(s, 0, special_base + 0x2000ULL);
  241 + /* pci_ioport */
  242 + sysbus_mmio_map(s, 1, special_base + 0x2000000ULL);
  243 + /* mem_config: XXX size should be 4G-prom */
  244 + sysbus_mmio_map(s, 2, special_base + 0x1000000ULL);
  245 + /* mem_data */
  246 + sysbus_mmio_map(s, 3, mem_base);
  247 + d = FROM_SYSBUS(APBState, s);
  248 + d->host_state.bus = pci_register_bus(NULL, "pci",
  249 + pci_apb_set_irq, pci_pbm_map_irq, pic,
  250 + 0, 32);
  251 + pci_create_simple(d->host_state.bus, 0, "pbm");
  252 + /* APB secondary busses */
  253 + *bus2 = pci_bridge_init(d->host_state.bus, 8, PCI_VENDOR_ID_SUN,
  254 + PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
  255 + "Advanced PCI Bus secondary bridge 1");
  256 + *bus3 = pci_bridge_init(d->host_state.bus, 9, PCI_VENDOR_ID_SUN,
  257 + PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
  258 + "Advanced PCI Bus secondary bridge 2");
236 259  
237   - pci_mem_config = cpu_register_io_memory(pci_apb_config_read,
238   - pci_apb_config_write, s);
  260 + return d->host_state.bus;
  261 +}
  262 +
  263 +static void pci_pbm_init_device(SysBusDevice *dev)
  264 +{
  265 +
  266 + APBState *s;
  267 + int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
  268 +
  269 + s = FROM_SYSBUS(APBState, dev);
  270 + /* apb_config */
239 271 apb_config = cpu_register_io_memory(apb_config_read,
240 272 apb_config_write, s);
241   - pci_mem_data = cpu_register_io_memory(pci_apb_read,
242   - pci_apb_write, s);
  273 + sysbus_init_mmio(dev, 0x40ULL, apb_config);
  274 + /* pci_ioport */
243 275 pci_ioport = cpu_register_io_memory(pci_apb_ioread,
244 276 pci_apb_iowrite, s);
  277 + sysbus_init_mmio(dev, 0x10000ULL, pci_ioport);
  278 + /* mem_config */
  279 + pci_mem_config = cpu_register_io_memory(pci_apb_config_read,
  280 + pci_apb_config_write, s);
  281 + sysbus_init_mmio(dev, 0x10ULL, pci_mem_config);
  282 + /* mem_data */
  283 + pci_mem_data = cpu_register_io_memory(pci_apb_read,
  284 + pci_apb_write, &s->host_state);
  285 + sysbus_init_mmio(dev, 0x10000000ULL, pci_mem_data);
  286 +}
245 287  
246   - cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
247   - cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10,
248   - pci_mem_config);
249   - cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000,
250   - pci_ioport);
251   - cpu_register_physical_memory(mem_base, 0x10000000,
252   - pci_mem_data); // XXX size should be 4G-prom
253   -
254   - d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
255   - 0, NULL, NULL);
  288 +static void pbm_pci_host_init(PCIDevice *d)
  289 +{
256 290 pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
257 291 pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
258 292 d->config[0x04] = 0x06; // command = bus master, pci mem
... ... @@ -264,13 +298,18 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
264 298 pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
265 299 d->config[0x0D] = 0x10; // latency_timer
266 300 d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
  301 +}
267 302  
268   - /* APB secondary busses */
269   - *bus2 = pci_bridge_init(s->bus, 8, PCI_VENDOR_ID_SUN,
270   - PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
271   - "Advanced PCI Bus secondary bridge 1");
272   - *bus3 = pci_bridge_init(s->bus, 9, PCI_VENDOR_ID_SUN,
273   - PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
274   - "Advanced PCI Bus secondary bridge 2");
275   - return s->bus;
  303 +static PCIDeviceInfo pbm_pci_host_info = {
  304 + .qdev.name = "pbm",
  305 + .qdev.size = sizeof(PCIDevice),
  306 + .init = pbm_pci_host_init,
  307 +};
  308 +
  309 +static void pbm_register_devices(void)
  310 +{
  311 + sysbus_register_dev("pbm", sizeof(APBState), pci_pbm_init_device);
  312 + pci_qdev_register(&pbm_pci_host_info);
276 313 }
  314 +
  315 +device_init(pbm_register_devices)
... ...
hw/pci.c
... ... @@ -145,11 +145,13 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
145 145 return bus;
146 146 }
147 147  
148   -static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
  148 +static PCIBus *pci_register_secondary_bus(PCIDevice *dev,
  149 + pci_map_irq_fn map_irq,
  150 + const char *name)
149 151 {
150 152 PCIBus *bus;
151 153  
152   - bus = qemu_mallocz(sizeof(PCIBus));
  154 + bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, name));
153 155 bus->map_irq = map_irq;
154 156 bus->parent_dev = dev;
155 157 bus->next = dev->bus->next;
... ... @@ -891,7 +893,7 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
891 893 PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
892 894 s->dev.config[0x1E] = 0xa0; // secondary status
893 895  
894   - s->bus = pci_register_secondary_bus(&s->dev, map_irq);
  896 + s->bus = pci_register_secondary_bus(&s->dev, map_irq, name);
895 897 return s->bus;
896 898 }
897 899  
... ...