pci: Allow PCI bus subtypes to support extended config space accesses
Some PHB implementations, eg. PAPR used on pseries machine, act like a regular PCI bus rather than a PCIe bus, but allow access to the PCIe extended config space anyway. Introduce a new PCI bus class method to modelize this behaviour and use it when adjusting the config space size limit during accesses. No behaviour change for existing PCI bus types. Signed-off-by: Greg Kurz <groug@kaod.org> Message-Id: <155414130271.574858.4253514266378127489.stgit@bahia.lan> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
		
							parent
							
								
									5263724b78
								
							
						
					
					
						commit
						1c685a9026
					
				
							
								
								
									
										24
									
								
								hw/pci/pci.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								hw/pci/pci.c
									
									
									
									
									
								
							| @ -147,6 +147,11 @@ static uint16_t pcibus_numa_node(PCIBus *bus) | ||||
|     return NUMA_NODE_UNASSIGNED; | ||||
| } | ||||
| 
 | ||||
| static bool pcibus_allows_extended_config_space(PCIBus *bus) | ||||
| { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| static void pci_bus_class_init(ObjectClass *klass, void *data) | ||||
| { | ||||
|     BusClass *k = BUS_CLASS(klass); | ||||
| @ -162,6 +167,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data) | ||||
|     pbc->is_root = pcibus_is_root; | ||||
|     pbc->bus_num = pcibus_num; | ||||
|     pbc->numa_node = pcibus_numa_node; | ||||
|     pbc->allows_extended_config_space = pcibus_allows_extended_config_space; | ||||
| } | ||||
| 
 | ||||
| static const TypeInfo pci_bus_info = { | ||||
| @ -182,9 +188,22 @@ static const TypeInfo conventional_pci_interface_info = { | ||||
|     .parent        = TYPE_INTERFACE, | ||||
| }; | ||||
| 
 | ||||
| static bool pciebus_allows_extended_config_space(PCIBus *bus) | ||||
| { | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| static void pcie_bus_class_init(ObjectClass *klass, void *data) | ||||
| { | ||||
|     PCIBusClass *pbc = PCI_BUS_CLASS(klass); | ||||
| 
 | ||||
|     pbc->allows_extended_config_space = pciebus_allows_extended_config_space; | ||||
| } | ||||
| 
 | ||||
| static const TypeInfo pcie_bus_info = { | ||||
|     .name = TYPE_PCIE_BUS, | ||||
|     .parent = TYPE_PCI_BUS, | ||||
|     .class_init = pcie_bus_class_init, | ||||
| }; | ||||
| 
 | ||||
| static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num); | ||||
| @ -401,6 +420,11 @@ bool pci_bus_is_root(PCIBus *bus) | ||||
|     return PCI_BUS_GET_CLASS(bus)->is_root(bus); | ||||
| } | ||||
| 
 | ||||
| bool pci_bus_allows_extended_config_space(PCIBus *bus) | ||||
| { | ||||
|     return PCI_BUS_GET_CLASS(bus)->allows_extended_config_space(bus); | ||||
| } | ||||
| 
 | ||||
| void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent, | ||||
|                               const char *name, | ||||
|                               MemoryRegion *address_space_mem, | ||||
|  | ||||
| @ -54,7 +54,7 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, uint32_t addr) | ||||
| static void pci_adjust_config_limit(PCIBus *bus, uint32_t *limit) | ||||
| { | ||||
|     if (*limit > PCI_CONFIG_SPACE_SIZE) { | ||||
|         if (!pci_bus_is_express(bus)) { | ||||
|         if (!pci_bus_allows_extended_config_space(bus)) { | ||||
|             *limit = PCI_CONFIG_SPACE_SIZE; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
| @ -396,6 +396,8 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin); | ||||
| 
 | ||||
| bool pci_bus_is_express(PCIBus *bus); | ||||
| bool pci_bus_is_root(PCIBus *bus); | ||||
| bool pci_bus_allows_extended_config_space(PCIBus *bus); | ||||
| 
 | ||||
| void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent, | ||||
|                               const char *name, | ||||
|                               MemoryRegion *address_space_mem, | ||||
|  | ||||
| @ -18,6 +18,7 @@ typedef struct PCIBusClass { | ||||
|     bool (*is_root)(PCIBus *bus); | ||||
|     int (*bus_num)(PCIBus *bus); | ||||
|     uint16_t (*numa_node)(PCIBus *bus); | ||||
|     bool (*allows_extended_config_space)(PCIBus *bus); | ||||
| } PCIBusClass; | ||||
| 
 | ||||
| struct PCIBus { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Greg Kurz
						Greg Kurz