pci: add MemoryRegion based BAR management API
Allow registering a BAR using a MemoryRegion. Once all users are converted, pci_register_bar() and pci_register_bar_simple() will be removed. Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									1e39101c64
								
							
						
					
					
						commit
						79ff8cb0df
					
				
							
								
								
									
										47
									
								
								hw/pci.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								hw/pci.c
									
									
									
									
									
								
							@ -844,10 +844,15 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
 | 
				
			|||||||
        if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
 | 
					        if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
 | 
				
			||||||
            isa_unassign_ioport(r->addr, r->filtered_size);
 | 
					            isa_unassign_ioport(r->addr, r->filtered_size);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
 | 
					            if (r->memory) {
 | 
				
			||||||
                                                         r->addr),
 | 
					                memory_region_del_subregion(pci_dev->bus->address_space,
 | 
				
			||||||
                                         r->filtered_size,
 | 
					                                            r->memory);
 | 
				
			||||||
                                         IO_MEM_UNASSIGNED);
 | 
					            } else {
 | 
				
			||||||
 | 
					                cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
 | 
				
			||||||
 | 
					                                                             r->addr),
 | 
				
			||||||
 | 
					                                             r->filtered_size,
 | 
				
			||||||
 | 
					                                             IO_MEM_UNASSIGNED);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -893,6 +898,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
 | 
				
			|||||||
    r->type = type;
 | 
					    r->type = type;
 | 
				
			||||||
    r->map_func = map_func;
 | 
					    r->map_func = map_func;
 | 
				
			||||||
    r->ram_addr = IO_MEM_UNASSIGNED;
 | 
					    r->ram_addr = IO_MEM_UNASSIGNED;
 | 
				
			||||||
 | 
					    r->memory = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    wmask = ~(size - 1);
 | 
					    wmask = ~(size - 1);
 | 
				
			||||||
    addr = pci_bar(pci_dev, region_num);
 | 
					    addr = pci_bar(pci_dev, region_num);
 | 
				
			||||||
@ -918,6 +924,16 @@ static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num,
 | 
				
			|||||||
                                 pci_dev->io_regions[region_num].ram_addr);
 | 
					                                 pci_dev->io_regions[region_num].ram_addr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
 | 
				
			||||||
 | 
					                                          pcibus_t addr, pcibus_t size,
 | 
				
			||||||
 | 
					                                          int type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memory_region_add_subregion_overlap(pci_dev->bus->address_space,
 | 
				
			||||||
 | 
					                                        addr,
 | 
				
			||||||
 | 
					                                        pci_dev->io_regions[region_num].memory,
 | 
				
			||||||
 | 
					                                        1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
 | 
					void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
 | 
				
			||||||
                             pcibus_t size,  uint8_t attr, ram_addr_t ram_addr)
 | 
					                             pcibus_t size,  uint8_t attr, ram_addr_t ram_addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -927,6 +943,15 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
 | 
				
			|||||||
    pci_dev->io_regions[region_num].ram_addr = ram_addr;
 | 
					    pci_dev->io_regions[region_num].ram_addr = ram_addr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
 | 
				
			||||||
 | 
					                             uint8_t attr, MemoryRegion *memory)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    pci_register_bar(pci_dev, region_num, memory_region_size(memory),
 | 
				
			||||||
 | 
					                     PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
 | 
				
			||||||
 | 
					                     pci_simple_bar_mapfunc_region);
 | 
				
			||||||
 | 
					    pci_dev->io_regions[region_num].memory = memory;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
 | 
					static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
 | 
				
			||||||
                              uint8_t type)
 | 
					                              uint8_t type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1065,10 +1090,16 @@ static void pci_update_mappings(PCIDevice *d)
 | 
				
			|||||||
                    isa_unassign_ioport(r->addr, r->filtered_size);
 | 
					                    isa_unassign_ioport(r->addr, r->filtered_size);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr),
 | 
					                if (r->memory) {
 | 
				
			||||||
                                             r->filtered_size,
 | 
					                    memory_region_del_subregion(d->bus->address_space,
 | 
				
			||||||
                                             IO_MEM_UNASSIGNED);
 | 
					                                                r->memory);
 | 
				
			||||||
                qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
 | 
					                } else {
 | 
				
			||||||
 | 
					                    cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
 | 
				
			||||||
 | 
					                                                                 r->addr),
 | 
				
			||||||
 | 
					                                                 r->filtered_size,
 | 
				
			||||||
 | 
					                                                 IO_MEM_UNASSIGNED);
 | 
				
			||||||
 | 
					                    qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        r->addr = new_addr;
 | 
					        r->addr = new_addr;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								hw/pci.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								hw/pci.h
									
									
									
									
									
								
							@ -94,6 +94,7 @@ typedef struct PCIIORegion {
 | 
				
			|||||||
    uint8_t type;
 | 
					    uint8_t type;
 | 
				
			||||||
    PCIMapIORegionFunc *map_func;
 | 
					    PCIMapIORegionFunc *map_func;
 | 
				
			||||||
    ram_addr_t ram_addr;
 | 
					    ram_addr_t ram_addr;
 | 
				
			||||||
 | 
					    MemoryRegion *memory;
 | 
				
			||||||
} PCIIORegion;
 | 
					} PCIIORegion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PCI_ROM_SLOT 6
 | 
					#define PCI_ROM_SLOT 6
 | 
				
			||||||
@ -204,6 +205,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
 | 
				
			|||||||
                            PCIMapIORegionFunc *map_func);
 | 
					                            PCIMapIORegionFunc *map_func);
 | 
				
			||||||
void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
 | 
					void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
 | 
				
			||||||
                             pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
 | 
					                             pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
 | 
				
			||||||
 | 
					void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
 | 
				
			||||||
 | 
					                             uint8_t attr, MemoryRegion *memory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
 | 
					int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
 | 
				
			||||||
                       uint8_t offset, uint8_t size);
 | 
					                       uint8_t offset, uint8_t size);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user