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,7 +26,7 @@
26 Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is 26 Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
27 the secondary PCI bridge. */ 27 the secondary PCI bridge. */
28 28
29 -#include "hw.h" 29 +#include "sysbus.h"
30 #include "pci.h" 30 #include "pci.h"
31 31
32 /* debug APB */ 32 /* debug APB */
@@ -42,7 +42,10 @@ do { printf(&quot;APB: &quot; fmt , ## __VA_ARGS__); } while (0) @@ -42,7 +42,10 @@ do { printf(&quot;APB: &quot; fmt , ## __VA_ARGS__); } while (0)
42 typedef target_phys_addr_t pci_addr_t; 42 typedef target_phys_addr_t pci_addr_t;
43 #include "pci_host.h" 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 static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr, 50 static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
48 uint32_t val) 51 uint32_t val)
@@ -54,7 +57,7 @@ static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr, @@ -54,7 +57,7 @@ static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
54 #endif 57 #endif
55 APB_DPRINTF("config_writel addr " TARGET_FMT_plx " val %x\n", addr, 58 APB_DPRINTF("config_writel addr " TARGET_FMT_plx " val %x\n", addr,
56 val); 59 val);
57 - s->config_reg = val; 60 + s->host_state.config_reg = val;
58 } 61 }
59 62
60 static uint32_t pci_apb_config_readl (void *opaque, 63 static uint32_t pci_apb_config_readl (void *opaque,
@@ -63,7 +66,7 @@ static uint32_t pci_apb_config_readl (void *opaque, @@ -63,7 +66,7 @@ static uint32_t pci_apb_config_readl (void *opaque,
63 APBState *s = opaque; 66 APBState *s = opaque;
64 uint32_t val; 67 uint32_t val;
65 68
66 - val = s->config_reg; 69 + val = s->host_state.config_reg;
67 #ifdef TARGET_WORDS_BIGENDIAN 70 #ifdef TARGET_WORDS_BIGENDIAN
68 val = bswap32(val); 71 val = bswap32(val);
69 #endif 72 #endif
@@ -225,34 +228,65 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, @@ -225,34 +228,65 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
225 target_phys_addr_t mem_base, 228 target_phys_addr_t mem_base,
226 qemu_irq *pic, PCIBus **bus2, PCIBus **bus3) 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 /* Ultrasparc PBM main bus */ 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 apb_config = cpu_register_io_memory(apb_config_read, 271 apb_config = cpu_register_io_memory(apb_config_read,
240 apb_config_write, s); 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 pci_ioport = cpu_register_io_memory(pci_apb_ioread, 275 pci_ioport = cpu_register_io_memory(pci_apb_ioread,
244 pci_apb_iowrite, s); 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 pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN); 290 pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
257 pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE); 291 pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
258 d->config[0x04] = 0x06; // command = bus master, pci mem 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,13 +298,18 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
264 pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); 298 pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
265 d->config[0x0D] = 0x10; // latency_timer 299 d->config[0x0D] = 0x10; // latency_timer
266 d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type 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,11 +145,13 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
145 return bus; 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 PCIBus *bus; 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 bus->map_irq = map_irq; 155 bus->map_irq = map_irq;
154 bus->parent_dev = dev; 156 bus->parent_dev = dev;
155 bus->next = dev->bus->next; 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,7 +893,7 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
891 PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type 893 PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
892 s->dev.config[0x1E] = 0xa0; // secondary status 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 return s->bus; 897 return s->bus;
896 } 898 }
897 899