Commit 79ff8cb0 authored by Avi Kivity's avatar Avi Kivity Committed by Anthony Liguori
Browse files

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: default avatarAnthony Liguori <aliguori@us.ibm.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 1e39101c
Loading
Loading
Loading
Loading
+39 −8
Original line number Diff line number Diff line
@@ -843,6 +843,10 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
            continue;
        if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
            isa_unassign_ioport(r->addr, r->filtered_size);
        } else {
            if (r->memory) {
                memory_region_del_subregion(pci_dev->bus->address_space,
                                            r->memory);
            } else {
                cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
                                                             r->addr),
@@ -851,6 +855,7 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
            }
        }
    }
}

static int pci_unregister_device(DeviceState *dev)
{
@@ -893,6 +898,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
    r->type = type;
    r->map_func = map_func;
    r->ram_addr = IO_MEM_UNASSIGNED;
    r->memory = NULL;

    wmask = ~(size - 1);
    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);
}

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,
                             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;
}

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,
                              uint8_t type)
{
@@ -1065,12 +1090,18 @@ static void pci_update_mappings(PCIDevice *d)
                    isa_unassign_ioport(r->addr, r->filtered_size);
                }
            } else {
                cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr),
                if (r->memory) {
                    memory_region_del_subregion(d->bus->address_space,
                                                r->memory);
                } 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->filtered_size = filtered_size;
        if (r->addr != PCI_BAR_UNMAPPED) {
+3 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ typedef struct PCIIORegion {
    uint8_t type;
    PCIMapIORegionFunc *map_func;
    ram_addr_t ram_addr;
    MemoryRegion *memory;
} PCIIORegion;

#define PCI_ROM_SLOT 6
@@ -204,6 +205,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
                            PCIMapIORegionFunc *map_func);
void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
                             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,
                       uint8_t offset, uint8_t size);