[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCHv2 1/7] libqos: Isolate knowledge of spapr memory m
From: |
Laurent Vivier |
Subject: |
Re: [Qemu-ppc] [PATCHv2 1/7] libqos: Isolate knowledge of spapr memory map to qpci_init_spapr() |
Date: |
Wed, 12 Oct 2016 10:00:07 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 |
On 12/10/2016 06:44, David Gibson wrote:
> The libqos code for accessing PCI on the spapr machine type uses IOBASE()
> and MMIOBASE() macros to determine the address in the CPU memory map of
> the windows to PCI address space.
>
> This is a detail of the implementation of PCI in the machine type, it's not
> specified by the PAPR standard. Real guests would get the addresses of the
> PCI windows from the device tree.
>
> Finding the device tree in libqos would be awkward, but we can at least
> localize this knowledge of the implementation to the init function, saving
> it in the QPCIBusSPAPR structure for use by the accessors.
>
> That leaves only one place to fix if we alter the location of the PCI
> windows, as we're planning to do.
>
> Signed-off-by: David Gibson <address@hidden>
Reviewed-by: Laurent Vivier <address@hidden>
> ---
> tests/libqos/pci-spapr.c | 113
> +++++++++++++++++++++++++++--------------------
> 1 file changed, 64 insertions(+), 49 deletions(-)
>
> diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
> index 2f73bad..1765a54 100644
> --- a/tests/libqos/pci-spapr.c
> +++ b/tests/libqos/pci-spapr.c
> @@ -18,30 +18,23 @@
>
> /* From include/hw/pci-host/spapr.h */
>
> -#define SPAPR_PCI_BASE_BUID 0x800000020000000ULL
> -
> -#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
> -
> -#define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL
> -#define SPAPR_PCI_WINDOW_SPACING 0x1000000000ULL
> -#define SPAPR_PCI_MMIO_WIN_OFF 0xA0000000
> -#define SPAPR_PCI_MMIO_WIN_SIZE (SPAPR_PCI_WINDOW_SPACING - \
> - SPAPR_PCI_MEM_WIN_BUS_OFFSET)
> -#define SPAPR_PCI_IO_WIN_OFF 0x80000000
> -#define SPAPR_PCI_IO_WIN_SIZE 0x10000
> -
> -/* index is the phb index */
> -
> -#define BUIDBASE(index) (SPAPR_PCI_BASE_BUID + (index))
> -#define PCIBASE(index) (SPAPR_PCI_WINDOW_BASE + \
> - (index) * SPAPR_PCI_WINDOW_SPACING)
> -#define IOBASE(index) (PCIBASE(index) + SPAPR_PCI_IO_WIN_OFF)
> -#define MMIOBASE(index) (PCIBASE(index) +
> SPAPR_PCI_MMIO_WIN_OFF)
> +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 mmio_cpu_base;
> + QPCIWindow mmio;
> +
> uint64_t pci_hole_start;
> uint64_t pci_hole_size;
> uint64_t pci_hole_alloc;
> @@ -59,69 +52,75 @@ typedef struct QPCIBusSPAPR {
>
> static uint8_t qpci_spapr_io_readb(QPCIBus *bus, void *addr)
> {
> + QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint64_t port = (uintptr_t)addr;
> uint8_t v;
> - if (port < SPAPR_PCI_IO_WIN_SIZE) {
> - v = readb(IOBASE(0) + port);
> + if (port < s->pio.size) {
> + v = readb(s->pio_cpu_base + port);
> } else {
> - v = readb(MMIOBASE(0) + port);
> + v = readb(s->mmio_cpu_base + port);
> }
> return v;
> }
>
> static uint16_t qpci_spapr_io_readw(QPCIBus *bus, void *addr)
> {
> + QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint64_t port = (uintptr_t)addr;
> uint16_t v;
> - if (port < SPAPR_PCI_IO_WIN_SIZE) {
> - v = readw(IOBASE(0) + port);
> + if (port < s->pio.size) {
> + v = readw(s->pio_cpu_base + port);
> } else {
> - v = readw(MMIOBASE(0) + port);
> + v = readw(s->mmio_cpu_base + port);
> }
> return bswap16(v);
> }
>
> static uint32_t qpci_spapr_io_readl(QPCIBus *bus, void *addr)
> {
> + QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint64_t port = (uintptr_t)addr;
> uint32_t v;
> - if (port < SPAPR_PCI_IO_WIN_SIZE) {
> - v = readl(IOBASE(0) + port);
> + if (port < s->pio.size) {
> + v = readl(s->pio_cpu_base + port);
> } else {
> - v = readl(MMIOBASE(0) + port);
> + v = readl(s->mmio_cpu_base + port);
> }
> return bswap32(v);
> }
>
> static void qpci_spapr_io_writeb(QPCIBus *bus, void *addr, uint8_t value)
> {
> + QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint64_t port = (uintptr_t)addr;
> - if (port < SPAPR_PCI_IO_WIN_SIZE) {
> - writeb(IOBASE(0) + port, value);
> + if (port < s->pio.size) {
> + writeb(s->pio_cpu_base + port, value);
> } else {
> - writeb(MMIOBASE(0) + port, value);
> + writeb(s->mmio_cpu_base + port, value);
> }
> }
>
> static void qpci_spapr_io_writew(QPCIBus *bus, void *addr, uint16_t value)
> {
> + QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint64_t port = (uintptr_t)addr;
> value = bswap16(value);
> - if (port < SPAPR_PCI_IO_WIN_SIZE) {
> - writew(IOBASE(0) + port, value);
> + if (port < s->pio.size) {
> + writew(s->pio_cpu_base + port, value);
> } else {
> - writew(MMIOBASE(0) + port, value);
> + writew(s->mmio_cpu_base + port, value);
> }
> }
>
> static void qpci_spapr_io_writel(QPCIBus *bus, void *addr, uint32_t value)
> {
> + QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint64_t port = (uintptr_t)addr;
> value = bswap32(value);
> - if (port < SPAPR_PCI_IO_WIN_SIZE) {
> - writel(IOBASE(0) + port, value);
> + if (port < s->pio.size) {
> + writel(s->pio_cpu_base + port, value);
> } else {
> - writel(MMIOBASE(0) + port, value);
> + writel(s->mmio_cpu_base + port, value);
> }
> }
>
> @@ -129,24 +128,21 @@ static uint8_t qpci_spapr_config_readb(QPCIBus *bus,
> int devfn, uint8_t offset)
> {
> QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint32_t config_addr = (devfn << 8) | offset;
> - return qrtas_ibm_read_pci_config(s->alloc, BUIDBASE(0),
> - config_addr, 1);
> + return qrtas_ibm_read_pci_config(s->alloc, s->buid, config_addr, 1);
> }
>
> static uint16_t qpci_spapr_config_readw(QPCIBus *bus, int devfn, uint8_t
> offset)
> {
> QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint32_t config_addr = (devfn << 8) | offset;
> - return qrtas_ibm_read_pci_config(s->alloc, BUIDBASE(0),
> - config_addr, 2);
> + return qrtas_ibm_read_pci_config(s->alloc, s->buid, config_addr, 2);
> }
>
> static uint32_t qpci_spapr_config_readl(QPCIBus *bus, int devfn, uint8_t
> offset)
> {
> QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint32_t config_addr = (devfn << 8) | offset;
> - return qrtas_ibm_read_pci_config(s->alloc, BUIDBASE(0),
> - config_addr, 4);
> + return qrtas_ibm_read_pci_config(s->alloc, s->buid, config_addr, 4);
> }
>
> static void qpci_spapr_config_writeb(QPCIBus *bus, int devfn, uint8_t offset,
> @@ -154,8 +150,7 @@ static void qpci_spapr_config_writeb(QPCIBus *bus, int
> devfn, uint8_t offset,
> {
> QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint32_t config_addr = (devfn << 8) | offset;
> - qrtas_ibm_write_pci_config(s->alloc, BUIDBASE(0),
> - config_addr, 1, value);
> + qrtas_ibm_write_pci_config(s->alloc, s->buid, config_addr, 1, value);
> }
>
> static void qpci_spapr_config_writew(QPCIBus *bus, int devfn, uint8_t offset,
> @@ -163,8 +158,7 @@ static void qpci_spapr_config_writew(QPCIBus *bus, int
> devfn, uint8_t offset,
> {
> QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint32_t config_addr = (devfn << 8) | offset;
> - qrtas_ibm_write_pci_config(s->alloc, BUIDBASE(0),
> - config_addr, 2, value);
> + qrtas_ibm_write_pci_config(s->alloc, s->buid, config_addr, 2, value);
> }
>
> static void qpci_spapr_config_writel(QPCIBus *bus, int devfn, uint8_t offset,
> @@ -172,8 +166,7 @@ static void qpci_spapr_config_writel(QPCIBus *bus, int
> devfn, uint8_t offset,
> {
> QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
> uint32_t config_addr = (devfn << 8) | offset;
> - qrtas_ibm_write_pci_config(s->alloc, BUIDBASE(0),
> - config_addr, 4, value);
> + qrtas_ibm_write_pci_config(s->alloc, s->buid, config_addr, 4, value);
> }
>
> static void *qpci_spapr_iomap(QPCIBus *bus, QPCIDevice *dev, int barno,
> @@ -242,6 +235,15 @@ static void qpci_spapr_iounmap(QPCIBus *bus, void *data)
> /* FIXME */
> }
>
> +#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
> +#define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL
> +#define SPAPR_PCI_WINDOW_SPACING 0x1000000000ULL
> +#define SPAPR_PCI_MMIO_WIN_OFF 0xA0000000
> +#define SPAPR_PCI_MMIO_WIN_SIZE (SPAPR_PCI_WINDOW_SPACING - \
> + SPAPR_PCI_MEM_WIN_BUS_OFFSET)
> +#define SPAPR_PCI_IO_WIN_OFF 0x80000000
> +#define SPAPR_PCI_IO_WIN_SIZE 0x10000
> +
> QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
> {
> QPCIBusSPAPR *ret;
> @@ -269,6 +271,19 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
> 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 */
> + ret->buid = 0x800000020000000ULL;
> +
> + ret->pio_cpu_base = SPAPR_PCI_WINDOW_BASE + SPAPR_PCI_IO_WIN_OFF;
> + ret->pio.pci_base = 0;
> + ret->pio.size = SPAPR_PCI_IO_WIN_SIZE;
> +
> + ret->mmio_cpu_base = SPAPR_PCI_WINDOW_BASE + SPAPR_PCI_MMIO_WIN_OFF;
> + ret->mmio.pci_base = SPAPR_PCI_MEM_WIN_BUS_OFFSET;
> + ret->mmio.size = SPAPR_PCI_MMIO_WIN_SIZE;
> +
> ret->pci_hole_start = 0xC0000000;
> ret->pci_hole_size = SPAPR_PCI_MMIO_WIN_SIZE;
> ret->pci_hole_alloc = 0;
>
- [Qemu-ppc] [PATCHv2 0/7] Improve PCI IO window orgnaization for pseries, David Gibson, 2016/10/12
- [Qemu-ppc] [PATCHv2 2/7] libqos: Correct error in PCI hole sizing for spapr, David Gibson, 2016/10/12
- [Qemu-ppc] [PATCHv2 4/7] spapr_pci: Delegate placement of PCI host bridges to machine type, David Gibson, 2016/10/12
- [Qemu-ppc] [PATCHv2 1/7] libqos: Isolate knowledge of spapr memory map to qpci_init_spapr(), David Gibson, 2016/10/12
- Re: [Qemu-ppc] [PATCHv2 1/7] libqos: Isolate knowledge of spapr memory map to qpci_init_spapr(),
Laurent Vivier <=
- [Qemu-ppc] [PATCHv2 6/7] spapr_pci: Add a 64-bit MMIO window, David Gibson, 2016/10/12
- [Qemu-ppc] [PATCHv2 5/7] spapr: Adjust placement of PCI host bridge to allow > 1TiB RAM, David Gibson, 2016/10/12
[Qemu-ppc] [PATCHv2 3/7] libqos: Limit spapr-pci to 32-bit MMIO for now, David Gibson, 2016/10/12
[Qemu-ppc] [PATCHv2 7/7] spapr: Improved placement of PCI host bridges in guest memory map, David Gibson, 2016/10/12