summary refs log tree commit diff stats
path: root/tests/libqos/pci-spapr.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/libqos/pci-spapr.c')
-rw-r--r--tests/libqos/pci-spapr.c194
1 files changed, 52 insertions, 142 deletions
diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
index 2eaaf9159a..1e5d015bd4 100644
--- a/tests/libqos/pci-spapr.c
+++ b/tests/libqos/pci-spapr.c
@@ -34,14 +34,6 @@ typedef struct QPCIBusSPAPR {
 
     uint64_t mmio32_cpu_base;
     QPCIWindow mmio32;
-
-    uint64_t pci_hole_start;
-    uint64_t pci_hole_size;
-    uint64_t pci_hole_alloc;
-
-    uint32_t pci_iohole_start;
-    uint32_t pci_iohole_size;
-    uint32_t pci_iohole_alloc;
 } QPCIBusSPAPR;
 
 /*
@@ -50,78 +42,66 @@ typedef struct QPCIBusSPAPR {
  * so PCI accessors need to swap data endianness
  */
 
-static uint8_t qpci_spapr_io_readb(QPCIBus *bus, void *addr)
+static uint8_t qpci_spapr_pio_readb(QPCIBus *bus, uint32_t addr)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    return readb(s->pio_cpu_base + addr);
+}
+
+static void qpci_spapr_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    writeb(s->pio_cpu_base + addr, val);
+}
+
+static uint16_t qpci_spapr_pio_readw(QPCIBus *bus, uint32_t addr)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    return bswap16(readw(s->pio_cpu_base + addr));
+}
+
+static void qpci_spapr_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
 {
     QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-    uint64_t port = (uintptr_t)addr;
-    uint8_t v;
-    if (port < s->pio.size) {
-        v = readb(s->pio_cpu_base + port);
-    } else {
-        v = readb(s->mmio32_cpu_base + port);
-    }
-    return v;
+    writew(s->pio_cpu_base + addr, bswap16(val));
 }
 
-static uint16_t qpci_spapr_io_readw(QPCIBus *bus, void *addr)
+static uint32_t qpci_spapr_pio_readl(QPCIBus *bus, uint32_t addr)
 {
     QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-    uint64_t port = (uintptr_t)addr;
-    uint16_t v;
-    if (port < s->pio.size) {
-        v = readw(s->pio_cpu_base + port);
-    } else {
-        v = readw(s->mmio32_cpu_base + port);
-    }
-    return bswap16(v);
+    return bswap32(readl(s->pio_cpu_base + addr));
 }
 
-static uint32_t qpci_spapr_io_readl(QPCIBus *bus, void *addr)
+static void qpci_spapr_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
 {
     QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-    uint64_t port = (uintptr_t)addr;
-    uint32_t v;
-    if (port < s->pio.size) {
-        v = readl(s->pio_cpu_base + port);
-    } else {
-        v = readl(s->mmio32_cpu_base + port);
-    }
-    return bswap32(v);
+    writel(s->pio_cpu_base + addr, bswap32(val));
 }
 
-static void qpci_spapr_io_writeb(QPCIBus *bus, void *addr, uint8_t value)
+static uint64_t qpci_spapr_pio_readq(QPCIBus *bus, uint32_t addr)
 {
     QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-    uint64_t port = (uintptr_t)addr;
-    if (port < s->pio.size) {
-        writeb(s->pio_cpu_base + port, value);
-    } else {
-        writeb(s->mmio32_cpu_base + port, value);
-    }
+    return bswap64(readq(s->pio_cpu_base + addr));
 }
 
-static void qpci_spapr_io_writew(QPCIBus *bus, void *addr, uint16_t value)
+static void qpci_spapr_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
 {
     QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-    uint64_t port = (uintptr_t)addr;
-    value = bswap16(value);
-    if (port < s->pio.size) {
-        writew(s->pio_cpu_base + port, value);
-    } else {
-        writew(s->mmio32_cpu_base + port, value);
-    }
+    writeq(s->pio_cpu_base + addr, bswap64(val));
 }
 
-static void qpci_spapr_io_writel(QPCIBus *bus, void *addr, uint32_t value)
+static void qpci_spapr_memread(QPCIBus *bus, uint32_t addr,
+                               void *buf, size_t len)
 {
     QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-    uint64_t port = (uintptr_t)addr;
-    value = bswap32(value);
-    if (port < s->pio.size) {
-        writel(s->pio_cpu_base + port, value);
-    } else {
-        writel(s->mmio32_cpu_base + port, value);
-    }
+    memread(s->mmio32_cpu_base + addr, buf, len);
+}
+
+static void qpci_spapr_memwrite(QPCIBus *bus, uint32_t addr,
+                                const void *buf, size_t len)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    memwrite(s->mmio32_cpu_base + addr, buf, len);
 }
 
 static uint8_t qpci_spapr_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
@@ -169,72 +149,6 @@ static void qpci_spapr_config_writel(QPCIBus *bus, int devfn, uint8_t offset,
     qrtas_ibm_write_pci_config(s->alloc, s->buid, config_addr, 4, value);
 }
 
-static void *qpci_spapr_iomap(QPCIBus *bus, QPCIDevice *dev, int barno,
-                              uint64_t *sizeptr)
-{
-    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
-    static const int bar_reg_map[] = {
-        PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
-        PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
-    };
-    int bar_reg;
-    uint32_t addr;
-    uint64_t size;
-    uint32_t io_type;
-
-    g_assert(barno >= 0 && barno <= 5);
-    bar_reg = bar_reg_map[barno];
-
-    qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
-    addr = qpci_config_readl(dev, bar_reg);
-
-    io_type = addr & PCI_BASE_ADDRESS_SPACE;
-    if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
-        addr &= PCI_BASE_ADDRESS_IO_MASK;
-    } else {
-        addr &= PCI_BASE_ADDRESS_MEM_MASK;
-    }
-
-    size = (1ULL << ctzl(addr));
-    if (size == 0) {
-        return NULL;
-    }
-    if (sizeptr) {
-        *sizeptr = size;
-    }
-
-    if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
-        uint16_t loc;
-
-        g_assert(QEMU_ALIGN_UP(s->pci_iohole_alloc, size) + size
-                 <= s->pci_iohole_size);
-        s->pci_iohole_alloc = QEMU_ALIGN_UP(s->pci_iohole_alloc, size);
-        loc = s->pci_iohole_start + s->pci_iohole_alloc;
-        s->pci_iohole_alloc += size;
-
-        qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO);
-
-        return (void *)(unsigned long)loc;
-    } else {
-        uint64_t loc;
-
-        g_assert(QEMU_ALIGN_UP(s->pci_hole_alloc, size) + size
-                 <= s->pci_hole_size);
-        s->pci_hole_alloc = QEMU_ALIGN_UP(s->pci_hole_alloc, size);
-        loc = s->pci_hole_start + s->pci_hole_alloc;
-        s->pci_hole_alloc += size;
-
-        qpci_config_writel(dev, bar_reg, loc);
-
-        return (void *)(unsigned long)loc;
-    }
-}
-
-static void qpci_spapr_iounmap(QPCIBus *bus, void *data)
-{
-    /* FIXME */
-}
-
 #define SPAPR_PCI_BASE               (1ULL << 45)
 
 #define SPAPR_PCI_MMIO32_WIN_SIZE    0x80000000 /* 2 GiB */
@@ -248,13 +162,18 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
 
     ret->alloc = alloc;
 
-    ret->bus.io_readb = qpci_spapr_io_readb;
-    ret->bus.io_readw = qpci_spapr_io_readw;
-    ret->bus.io_readl = qpci_spapr_io_readl;
+    ret->bus.pio_readb = qpci_spapr_pio_readb;
+    ret->bus.pio_readw = qpci_spapr_pio_readw;
+    ret->bus.pio_readl = qpci_spapr_pio_readl;
+    ret->bus.pio_readq = qpci_spapr_pio_readq;
 
-    ret->bus.io_writeb = qpci_spapr_io_writeb;
-    ret->bus.io_writew = qpci_spapr_io_writew;
-    ret->bus.io_writel = qpci_spapr_io_writel;
+    ret->bus.pio_writeb = qpci_spapr_pio_writeb;
+    ret->bus.pio_writew = qpci_spapr_pio_writew;
+    ret->bus.pio_writel = qpci_spapr_pio_writel;
+    ret->bus.pio_writeq = qpci_spapr_pio_writeq;
+
+    ret->bus.memread = qpci_spapr_memread;
+    ret->bus.memwrite = qpci_spapr_memwrite;
 
     ret->bus.config_readb = qpci_spapr_config_readb;
     ret->bus.config_readw = qpci_spapr_config_readw;
@@ -264,9 +183,6 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
     ret->bus.config_writew = qpci_spapr_config_writew;
     ret->bus.config_writel = qpci_spapr_config_writel;
 
-    ret->bus.iomap = qpci_spapr_iomap;
-    ret->bus.iounmap = qpci_spapr_iounmap;
-
     /* FIXME: We assume the default location of the PHB for now.
      * Ideally we'd parse the device tree deposited in the guest to
      * get the window locations */
@@ -281,15 +197,9 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
     ret->mmio32.pci_base = 0x80000000; /* 2 GiB */
     ret->mmio32.size = SPAPR_PCI_MMIO32_WIN_SIZE;
 
-    ret->pci_hole_start = 0xC0000000;
-    ret->pci_hole_size =
-        ret->mmio32.pci_base + ret->mmio32.size - ret->pci_hole_start;
-    ret->pci_hole_alloc = 0;
-
-    ret->pci_iohole_start = 0xc000;
-    ret->pci_iohole_size =
-        ret->pio.pci_base + ret->pio.size - ret->pci_iohole_start;
-    ret->pci_iohole_alloc = 0;
+    ret->bus.pio_alloc_ptr = 0xc000;
+    ret->bus.mmio_alloc_ptr = ret->mmio32.pci_base;
+    ret->bus.mmio_limit = ret->mmio32.pci_base + ret->mmio32.size;
 
     return &ret->bus;
 }