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…
Reference in a new issue