Sparc64: convert APB to qdev
Thanks to Igor Kovalenko for a bugfix. Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
		
							parent
							
								
									0bf9e31af1
								
							
						
					
					
						commit
						72f44c8cc7
					
				
							
								
								
									
										105
									
								
								hw/apb_pci.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								hw/apb_pci.c
									
									
									
									
									
								
							| @ -26,7 +26,7 @@ | ||||
|    Ultrasparc PCI host is called the PCI Bus Module (PBM).  The APB is | ||||
|    the secondary PCI bridge.  */ | ||||
| 
 | ||||
| #include "hw.h" | ||||
| #include "sysbus.h" | ||||
| #include "pci.h" | ||||
| 
 | ||||
| /* debug APB */ | ||||
| @ -42,7 +42,10 @@ do { printf("APB: " fmt , ## __VA_ARGS__); } while (0) | ||||
| typedef target_phys_addr_t pci_addr_t; | ||||
| #include "pci_host.h" | ||||
| 
 | ||||
| typedef PCIHostState APBState; | ||||
| typedef struct APBState { | ||||
|     SysBusDevice busdev; | ||||
|     PCIHostState host_state; | ||||
| } APBState; | ||||
| 
 | ||||
| static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr, | ||||
|                                          uint32_t val) | ||||
| @ -54,7 +57,7 @@ static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr, | ||||
| #endif | ||||
|     APB_DPRINTF("config_writel addr " TARGET_FMT_plx " val %x\n", addr, | ||||
|                 val); | ||||
|     s->config_reg = val; | ||||
|     s->host_state.config_reg = val; | ||||
| } | ||||
| 
 | ||||
| static uint32_t pci_apb_config_readl (void *opaque, | ||||
| @ -63,7 +66,7 @@ static uint32_t pci_apb_config_readl (void *opaque, | ||||
|     APBState *s = opaque; | ||||
|     uint32_t val; | ||||
| 
 | ||||
|     val = s->config_reg; | ||||
|     val = s->host_state.config_reg; | ||||
| #ifdef TARGET_WORDS_BIGENDIAN | ||||
|     val = bswap32(val); | ||||
| #endif | ||||
| @ -225,34 +228,65 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, | ||||
|                      target_phys_addr_t mem_base, | ||||
|                      qemu_irq *pic, PCIBus **bus2, PCIBus **bus3) | ||||
| { | ||||
|     DeviceState *dev; | ||||
|     SysBusDevice *s; | ||||
|     APBState *d; | ||||
| 
 | ||||
|     /* Ultrasparc PBM main bus */ | ||||
|     dev = qdev_create(NULL, "pbm"); | ||||
|     qdev_init(dev); | ||||
|     s = sysbus_from_qdev(dev); | ||||
|     /* apb_config */ | ||||
|     sysbus_mmio_map(s, 0, special_base + 0x2000ULL); | ||||
|     /* pci_ioport */ | ||||
|     sysbus_mmio_map(s, 1, special_base + 0x2000000ULL); | ||||
|     /* mem_config: XXX size should be 4G-prom */ | ||||
|     sysbus_mmio_map(s, 2, special_base + 0x1000000ULL); | ||||
|     /* mem_data */ | ||||
|     sysbus_mmio_map(s, 3, mem_base); | ||||
|     d = FROM_SYSBUS(APBState, s); | ||||
|     d->host_state.bus = pci_register_bus(NULL, "pci", | ||||
|                                          pci_apb_set_irq, pci_pbm_map_irq, pic, | ||||
|                                          0, 32); | ||||
|     pci_create_simple(d->host_state.bus, 0, "pbm"); | ||||
|     /* APB secondary busses */ | ||||
|     *bus2 = pci_bridge_init(d->host_state.bus, 8, PCI_VENDOR_ID_SUN, | ||||
|                             PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq, | ||||
|                             "Advanced PCI Bus secondary bridge 1"); | ||||
|     *bus3 = pci_bridge_init(d->host_state.bus, 9, PCI_VENDOR_ID_SUN, | ||||
|                             PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq, | ||||
|                             "Advanced PCI Bus secondary bridge 2"); | ||||
| 
 | ||||
|     return d->host_state.bus; | ||||
| } | ||||
| 
 | ||||
| static void pci_pbm_init_device(SysBusDevice *dev) | ||||
| { | ||||
| 
 | ||||
|     APBState *s; | ||||
|     PCIDevice *d; | ||||
|     int pci_mem_config, pci_mem_data, apb_config, pci_ioport; | ||||
| 
 | ||||
|     s = qemu_mallocz(sizeof(APBState)); | ||||
|     /* Ultrasparc PBM main bus */ | ||||
|     s->bus = pci_register_bus(NULL, "pci", | ||||
|                               pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32); | ||||
| 
 | ||||
|     pci_mem_config = cpu_register_io_memory(pci_apb_config_read, | ||||
|                                             pci_apb_config_write, s); | ||||
|     s = FROM_SYSBUS(APBState, dev); | ||||
|     /* apb_config */ | ||||
|     apb_config = cpu_register_io_memory(apb_config_read, | ||||
|                                         apb_config_write, s); | ||||
|     pci_mem_data = cpu_register_io_memory(pci_apb_read, | ||||
|                                           pci_apb_write, s); | ||||
|     sysbus_init_mmio(dev, 0x40ULL, apb_config); | ||||
|     /* pci_ioport */ | ||||
|     pci_ioport = cpu_register_io_memory(pci_apb_ioread, | ||||
|                                           pci_apb_iowrite, s); | ||||
|     sysbus_init_mmio(dev, 0x10000ULL, pci_ioport); | ||||
|     /* mem_config  */ | ||||
|     pci_mem_config = cpu_register_io_memory(pci_apb_config_read, | ||||
|                                             pci_apb_config_write, s); | ||||
|     sysbus_init_mmio(dev, 0x10ULL, pci_mem_config); | ||||
|     /* mem_data */ | ||||
|     pci_mem_data = cpu_register_io_memory(pci_apb_read, | ||||
|                                           pci_apb_write, &s->host_state); | ||||
|     sysbus_init_mmio(dev, 0x10000000ULL, pci_mem_data); | ||||
| } | ||||
| 
 | ||||
|     cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config); | ||||
|     cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, | ||||
|                                  pci_mem_config); | ||||
|     cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, | ||||
|                                  pci_ioport); | ||||
|     cpu_register_physical_memory(mem_base, 0x10000000, | ||||
|                                  pci_mem_data); // XXX size should be 4G-prom
 | ||||
| 
 | ||||
|     d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice), | ||||
|                             0, NULL, NULL); | ||||
| static void pbm_pci_host_init(PCIDevice *d) | ||||
| { | ||||
|     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN); | ||||
|     pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE); | ||||
|     d->config[0x04] = 0x06; // command = bus master, pci mem
 | ||||
| @ -264,13 +298,18 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, | ||||
|     pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); | ||||
|     d->config[0x0D] = 0x10; // latency_timer
 | ||||
|     d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
 | ||||
| 
 | ||||
|     /* APB secondary busses */ | ||||
|     *bus2 = pci_bridge_init(s->bus, 8, PCI_VENDOR_ID_SUN, | ||||
|                             PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq, | ||||
|                             "Advanced PCI Bus secondary bridge 1"); | ||||
|     *bus3 = pci_bridge_init(s->bus, 9, PCI_VENDOR_ID_SUN, | ||||
|                             PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq, | ||||
|                             "Advanced PCI Bus secondary bridge 2"); | ||||
|     return s->bus; | ||||
| } | ||||
| 
 | ||||
| static PCIDeviceInfo pbm_pci_host_info = { | ||||
|     .qdev.name = "pbm", | ||||
|     .qdev.size = sizeof(PCIDevice), | ||||
|     .init      = pbm_pci_host_init, | ||||
| }; | ||||
| 
 | ||||
| static void pbm_register_devices(void) | ||||
| { | ||||
|     sysbus_register_dev("pbm", sizeof(APBState), pci_pbm_init_device); | ||||
|     pci_qdev_register(&pbm_pci_host_info); | ||||
| } | ||||
| 
 | ||||
| device_init(pbm_register_devices) | ||||
|  | ||||
							
								
								
									
										8
									
								
								hw/pci.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								hw/pci.c
									
									
									
									
									
								
							| @ -145,11 +145,13 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name, | ||||
|     return bus; | ||||
| } | ||||
| 
 | ||||
| static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq) | ||||
| static PCIBus *pci_register_secondary_bus(PCIDevice *dev, | ||||
|                                           pci_map_irq_fn map_irq, | ||||
|                                           const char *name) | ||||
| { | ||||
|     PCIBus *bus; | ||||
| 
 | ||||
|     bus = qemu_mallocz(sizeof(PCIBus)); | ||||
|     bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, name)); | ||||
|     bus->map_irq = map_irq; | ||||
|     bus->parent_dev = dev; | ||||
|     bus->next = dev->bus->next; | ||||
| @ -891,7 +893,7 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, | ||||
|         PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
 | ||||
|     s->dev.config[0x1E] = 0xa0; // secondary status
 | ||||
| 
 | ||||
|     s->bus = pci_register_secondary_bus(&s->dev, map_irq); | ||||
|     s->bus = pci_register_secondary_bus(&s->dev, map_irq, name); | ||||
|     return s->bus; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Blue Swirl
						Blue Swirl