tests/libqos: pci-spapr driver and interface nodes
Add pci-bus-spapr node, that produces pci-bus. Move QPCIBusSPAPR struct declaration in its header (since it will be needed by other drivers) and introduce a setter method for drivers that do not need to allocate but have to initialize QPCIBusSPAPR. Signed-off-by: Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
db1f266838
commit
b8782d2a47
@ -748,7 +748,7 @@ libqos-virtio-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) tests/libqos/virt
|
||||
|
||||
# Devices
|
||||
qos-test-obj-y = tests/qos-test.o $(libqgraph-obj-y)
|
||||
qos-test-obj-y += $(libqos-pc-obj-y)
|
||||
qos-test-obj-y += $(libqos-pc-obj-y) $(libqos-spapr-obj-y)
|
||||
qos-test-obj-y += tests/libqos/sdhci.o
|
||||
|
||||
# Machines
|
||||
|
@ -9,33 +9,13 @@
|
||||
#include "libqtest.h"
|
||||
#include "libqos/pci-spapr.h"
|
||||
#include "libqos/rtas.h"
|
||||
#include "libqos/qgraph.h"
|
||||
|
||||
#include "hw/pci/pci_regs.h"
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/host-utils.h"
|
||||
|
||||
|
||||
/* From include/hw/pci-host/spapr.h */
|
||||
|
||||
typedef struct QPCIWindow {
|
||||
uint64_t pci_base; /* window address in PCI space */
|
||||
uint64_t size; /* window size */
|
||||
} QPCIWindow;
|
||||
|
||||
typedef struct QPCIBusSPAPR {
|
||||
QPCIBus bus;
|
||||
QGuestAllocator *alloc;
|
||||
|
||||
uint64_t buid;
|
||||
|
||||
uint64_t pio_cpu_base;
|
||||
QPCIWindow pio;
|
||||
|
||||
uint64_t mmio32_cpu_base;
|
||||
QPCIWindow mmio32;
|
||||
} QPCIBusSPAPR;
|
||||
|
||||
/*
|
||||
* PCI devices are always little-endian
|
||||
* SPAPR by default is big-endian
|
||||
@ -160,60 +140,90 @@ static void qpci_spapr_config_writel(QPCIBus *bus, int devfn, uint8_t offset,
|
||||
#define SPAPR_PCI_MMIO32_WIN_SIZE 0x80000000 /* 2 GiB */
|
||||
#define SPAPR_PCI_IO_WIN_SIZE 0x10000
|
||||
|
||||
QPCIBus *qpci_new_spapr(QTestState *qts, QGuestAllocator *alloc)
|
||||
static void *qpci_spapr_get_driver(void *obj, const char *interface)
|
||||
{
|
||||
QPCIBusSPAPR *ret = g_new0(QPCIBusSPAPR, 1);
|
||||
QPCIBusSPAPR *qpci = obj;
|
||||
if (!g_strcmp0(interface, "pci-bus")) {
|
||||
return &qpci->bus;
|
||||
}
|
||||
fprintf(stderr, "%s not present in pci-bus-spapr", interface);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
void qpci_init_spapr(QPCIBusSPAPR *qpci, QTestState *qts,
|
||||
QGuestAllocator *alloc)
|
||||
{
|
||||
assert(qts);
|
||||
|
||||
ret->alloc = alloc;
|
||||
qpci->alloc = alloc;
|
||||
|
||||
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;
|
||||
qpci->bus.pio_readb = qpci_spapr_pio_readb;
|
||||
qpci->bus.pio_readw = qpci_spapr_pio_readw;
|
||||
qpci->bus.pio_readl = qpci_spapr_pio_readl;
|
||||
qpci->bus.pio_readq = qpci_spapr_pio_readq;
|
||||
|
||||
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;
|
||||
qpci->bus.pio_writeb = qpci_spapr_pio_writeb;
|
||||
qpci->bus.pio_writew = qpci_spapr_pio_writew;
|
||||
qpci->bus.pio_writel = qpci_spapr_pio_writel;
|
||||
qpci->bus.pio_writeq = qpci_spapr_pio_writeq;
|
||||
|
||||
ret->bus.memread = qpci_spapr_memread;
|
||||
ret->bus.memwrite = qpci_spapr_memwrite;
|
||||
qpci->bus.memread = qpci_spapr_memread;
|
||||
qpci->bus.memwrite = qpci_spapr_memwrite;
|
||||
|
||||
ret->bus.config_readb = qpci_spapr_config_readb;
|
||||
ret->bus.config_readw = qpci_spapr_config_readw;
|
||||
ret->bus.config_readl = qpci_spapr_config_readl;
|
||||
qpci->bus.config_readb = qpci_spapr_config_readb;
|
||||
qpci->bus.config_readw = qpci_spapr_config_readw;
|
||||
qpci->bus.config_readl = qpci_spapr_config_readl;
|
||||
|
||||
ret->bus.config_writeb = qpci_spapr_config_writeb;
|
||||
ret->bus.config_writew = qpci_spapr_config_writew;
|
||||
ret->bus.config_writel = qpci_spapr_config_writel;
|
||||
qpci->bus.config_writeb = qpci_spapr_config_writeb;
|
||||
qpci->bus.config_writew = qpci_spapr_config_writew;
|
||||
qpci->bus.config_writel = qpci_spapr_config_writel;
|
||||
|
||||
/* 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 */
|
||||
ret->buid = 0x800000020000000ULL;
|
||||
qpci->buid = 0x800000020000000ULL;
|
||||
|
||||
ret->pio_cpu_base = SPAPR_PCI_BASE;
|
||||
ret->pio.pci_base = 0;
|
||||
ret->pio.size = SPAPR_PCI_IO_WIN_SIZE;
|
||||
qpci->pio_cpu_base = SPAPR_PCI_BASE;
|
||||
qpci->pio.pci_base = 0;
|
||||
qpci->pio.size = SPAPR_PCI_IO_WIN_SIZE;
|
||||
|
||||
/* 32-bit portion of the MMIO window is at PCI address 2..4 GiB */
|
||||
ret->mmio32_cpu_base = SPAPR_PCI_BASE;
|
||||
ret->mmio32.pci_base = SPAPR_PCI_MMIO32_WIN_SIZE;
|
||||
ret->mmio32.size = SPAPR_PCI_MMIO32_WIN_SIZE;
|
||||
qpci->mmio32_cpu_base = SPAPR_PCI_BASE;
|
||||
qpci->mmio32.pci_base = SPAPR_PCI_MMIO32_WIN_SIZE;
|
||||
qpci->mmio32.size = SPAPR_PCI_MMIO32_WIN_SIZE;
|
||||
|
||||
ret->bus.qts = qts;
|
||||
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;
|
||||
qpci->bus.qts = qts;
|
||||
qpci->bus.pio_alloc_ptr = 0xc000;
|
||||
qpci->bus.mmio_alloc_ptr = qpci->mmio32.pci_base;
|
||||
qpci->bus.mmio_limit = qpci->mmio32.pci_base + qpci->mmio32.size;
|
||||
|
||||
return &ret->bus;
|
||||
qpci->obj.get_driver = qpci_spapr_get_driver;
|
||||
}
|
||||
|
||||
QPCIBus *qpci_new_spapr(QTestState *qts, QGuestAllocator *alloc)
|
||||
{
|
||||
QPCIBusSPAPR *qpci = g_new0(QPCIBusSPAPR, 1);
|
||||
qpci_init_spapr(qpci, qts, alloc);
|
||||
|
||||
return &qpci->bus;
|
||||
}
|
||||
|
||||
void qpci_free_spapr(QPCIBus *bus)
|
||||
{
|
||||
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
|
||||
QPCIBusSPAPR *s;
|
||||
|
||||
if (!bus) {
|
||||
return;
|
||||
}
|
||||
s = container_of(bus, QPCIBusSPAPR, bus);
|
||||
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
static void qpci_spapr_register_nodes(void)
|
||||
{
|
||||
qos_node_create_driver("pci-bus-spapr", NULL);
|
||||
qos_node_produces("pci-bus-spapr", "pci-bus");
|
||||
}
|
||||
|
||||
libqos_init(qpci_spapr_register_nodes);
|
||||
|
@ -10,7 +10,31 @@
|
||||
|
||||
#include "libqos/malloc.h"
|
||||
#include "libqos/pci.h"
|
||||
#include "libqos/qgraph.h"
|
||||
|
||||
/* From include/hw/pci-host/spapr.h */
|
||||
|
||||
typedef struct QPCIWindow {
|
||||
uint64_t pci_base; /* window address in PCI space */
|
||||
uint64_t size; /* window size */
|
||||
} QPCIWindow;
|
||||
|
||||
typedef struct QPCIBusSPAPR {
|
||||
QOSGraphObject obj;
|
||||
QPCIBus bus;
|
||||
QGuestAllocator *alloc;
|
||||
|
||||
uint64_t buid;
|
||||
|
||||
uint64_t pio_cpu_base;
|
||||
QPCIWindow pio;
|
||||
|
||||
uint64_t mmio32_cpu_base;
|
||||
QPCIWindow mmio32;
|
||||
} QPCIBusSPAPR;
|
||||
|
||||
void qpci_init_spapr(QPCIBusSPAPR *ret, QTestState *qts,
|
||||
QGuestAllocator *alloc);
|
||||
QPCIBus *qpci_new_spapr(QTestState *qts, QGuestAllocator *alloc);
|
||||
void qpci_free_spapr(QPCIBus *bus);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user