Commit e954ce23 authored by Peter Xu's avatar Peter Xu Committed by Paolo Bonzini
Browse files

pci: provide pci_scan_bars()



Let's provide a more general way to scan PCI bars, rather than read the
config registers every time.

Then let x86/vmexit.c leverage pci_scan_bars()

Reviewed-by: Andrew Jones's avatarAndrew Jones <drjones@redhat.com>
Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 4d6cefa9
...@@ -234,7 +234,7 @@ bool pci_probe(void) ...@@ -234,7 +234,7 @@ bool pci_probe(void)
cmd = PCI_COMMAND_SERR | PCI_COMMAND_PARITY; cmd = PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
for (i = 0; i < 6; i++) { for (i = 0; i < PCI_BAR_NUM; i++) {
u64 addr; u64 addr;
if (pci_alloc_resource(&pci_dev, i, &addr)) { if (pci_alloc_resource(&pci_dev, i, &addr)) {
......
...@@ -211,7 +211,7 @@ static void pci_dev_print(pcidevaddr_t dev) ...@@ -211,7 +211,7 @@ static void pci_dev_print(pcidevaddr_t dev)
if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL) if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL)
return; return;
for (i = 0; i < 6; i++) { for (i = 0; i < PCI_BAR_NUM; i++) {
if (pci_bar_size(&pci_dev, i)) { if (pci_bar_size(&pci_dev, i)) {
printf("\t"); printf("\t");
pci_bar_print(&pci_dev, i); pci_bar_print(&pci_dev, i);
...@@ -231,3 +231,18 @@ void pci_print(void) ...@@ -231,3 +231,18 @@ void pci_print(void)
pci_dev_print(dev); pci_dev_print(dev);
} }
} }
void pci_scan_bars(struct pci_dev *dev)
{
int i;
for (i = 0; i < PCI_BAR_NUM; i++) {
if (!pci_bar_is_valid(dev, i))
continue;
dev->resource[i] = pci_bar_get_addr(dev, i);
if (pci_bar_is64(dev, i)) {
i++;
dev->resource[i] = (phys_addr_t)0;
}
}
}
...@@ -15,13 +15,16 @@ enum { ...@@ -15,13 +15,16 @@ enum {
PCIDEVADDR_INVALID = 0xffff, PCIDEVADDR_INVALID = 0xffff,
}; };
#define PCI_BAR_NUM 6
#define PCI_DEVFN_MAX 256 #define PCI_DEVFN_MAX 256
struct pci_dev { struct pci_dev {
uint16_t bdf; uint16_t bdf;
phys_addr_t resource[PCI_BAR_NUM];
}; };
extern void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf); extern void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf);
extern void pci_scan_bars(struct pci_dev *dev);
extern bool pci_probe(void); extern bool pci_probe(void);
extern void pci_print(void); extern void pci_print(void);
...@@ -65,6 +68,8 @@ extern int pci_testdev(void); ...@@ -65,6 +68,8 @@ extern int pci_testdev(void);
* pci-testdev supports at least three types of tests (via mmio and * pci-testdev supports at least three types of tests (via mmio and
* portio BARs): no-eventfd, wildcard-eventfd and datamatch-eventfd * portio BARs): no-eventfd, wildcard-eventfd and datamatch-eventfd
*/ */
#define PCI_TESTDEV_BAR_MEM 0
#define PCI_TESTDEV_BAR_IO 1
#define PCI_TESTDEV_NUM_BARS 2 #define PCI_TESTDEV_NUM_BARS 2
#define PCI_TESTDEV_NUM_TESTS 3 #define PCI_TESTDEV_NUM_TESTS 3
......
...@@ -519,17 +519,12 @@ int main(int ac, char **av) ...@@ -519,17 +519,12 @@ int main(int ac, char **av)
ret = pci_find_dev(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_TEST); ret = pci_find_dev(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_TEST);
if (ret != PCIDEVADDR_INVALID) { if (ret != PCIDEVADDR_INVALID) {
pci_dev_init(&pcidev, ret); pci_dev_init(&pcidev, ret);
for (i = 0; i < PCI_TESTDEV_NUM_BARS; i++) { pci_scan_bars(&pcidev);
if (!pci_bar_is_valid(&pcidev, i)) { assert(pci_bar_is_memory(&pcidev, PCI_TESTDEV_BAR_MEM));
continue; assert(!pci_bar_is_memory(&pcidev, PCI_TESTDEV_BAR_IO));
} membar = pcidev.resource[PCI_TESTDEV_BAR_MEM];
if (pci_bar_is_memory(&pcidev, i)) { pci_test.memaddr = ioremap(membar, PAGE_SIZE);
membar = pci_bar_get_addr(&pcidev, i); pci_test.iobar = pcidev.resource[PCI_TESTDEV_BAR_IO];
pci_test.memaddr = ioremap(membar, PAGE_SIZE);
} else {
pci_test.iobar = pci_bar_get_addr(&pcidev, i);
}
}
printf("pci-testdev at 0x%x membar %lx iobar %x\n", printf("pci-testdev at 0x%x membar %lx iobar %x\n",
pcidev.bdf, membar, pci_test.iobar); pcidev.bdf, membar, pci_test.iobar);
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment