/*
 * QEMU sPAPR PCI host originated from Uninorth PCI host
 *
 * Copyright (c) 2011 Alexey Kardashevskiy, IBM Corporation.
 * Copyright (C) 2011 David Gibson, IBM Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "hw/pci/pci.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "hw/pci/pci_host.h"
#include "hw/ppc/spapr.h"
#include "hw/pci-host/spapr.h"
#include "exec/address-spaces.h"
#include <libfdt.h>
#include "trace.h"
#include "qemu/error-report.h"
#include "qapi/qmp/qerror.h"

#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h"
#include "hw/ppc/spapr_drc.h"
#include "sysemu/device_tree.h"

/* Copied from the kernel arch/powerpc/platforms/pseries/msi.c */
#define RTAS_QUERY_FN           0
#define RTAS_CHANGE_FN          1
#define RTAS_RESET_FN           2
#define RTAS_CHANGE_MSI_FN      3
#define RTAS_CHANGE_MSIX_FN     4

/* Interrupt types to return on RTAS_CHANGE_* */
#define RTAS_TYPE_MSI           1
#define RTAS_TYPE_MSIX          2

#define FDT_NAME_MAX          128

#define _FDT(exp) \
    do { \
        int ret = (exp);                                           \
        if (ret < 0) {                                             \
            return ret;                                            \
        }                                                          \
    } while (0)

sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid)
{
    sPAPRPHBState *sphb;

    QLIST_FOREACH(sphb, &spapr->phbs, list) {
        if (sphb->buid != buid) {
            continue;
        }
        return sphb;
    }

    return NULL;
}

PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
                              uint32_t config_addr)
{
    sPAPRPHBState *sphb = spapr_pci_find_phb(spapr, buid);
    PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
    int bus_num = (config_addr >> 16) & 0xFF;
    int devfn = (config_addr >> 8) & 0xFF;

    if (!phb) {
        return NULL;
    }

    return pci_find_device(phb->bus, bus_num, devfn);
}

static uint32_t rtas_pci_cfgaddr(uint32_t arg)
{
    /* This handles the encoding of extended config space addresses */
    return ((arg >> 20) & 0xf00) | (arg & 0xff);
}

static void finish_read_pci_config(sPAPRMachineState *spapr, uint64_t buid,
                                   uint32_t addr, uint32_t size,
                                   target_ulong rets)
{
    PCIDevice *pci_dev;
    uint32_t val;

    if ((size != 1) && (size != 2) && (size != 4)) {
        /* access must be 1, 2 or 4 bytes */
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    pci_dev = spapr_pci_find_dev(spapr, buid, addr);
    addr = rtas_pci_cfgaddr(addr);

    if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {
        /* Access must be to a valid device, within bounds and
         * naturally aligned */
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    val = pci_host_config_read_common(pci_dev, addr,
                                      pci_config_size(pci_dev), size);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, val);
}

static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                     uint32_t token, uint32_t nargs,
                                     target_ulong args,
                                     uint32_t nret, target_ulong rets)
{
    uint64_t buid;
    uint32_t size, addr;

    if ((nargs != 4) || (nret != 2)) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    buid = rtas_ldq(args, 1);
    size = rtas_ld(args, 3);
    addr = rtas_ld(args, 0);

    finish_read_pci_config(spapr, buid, addr, size, rets);
}

static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                 uint32_t token, uint32_t nargs,
                                 target_ulong args,
                                 uint32_t nret, target_ulong rets)
{
    uint32_t size, addr;

    if ((nargs != 2) || (nret != 2)) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    size = rtas_ld(args, 1);
    addr = rtas_ld(args, 0);

    finish_read_pci_config(spapr, 0, addr, size, rets);
}

static void finish_write_pci_config(sPAPRMachineState *spapr, uint64_t buid,
                                    uint32_t addr, uint32_t size,
                                    uint32_t val, target_ulong rets)
{
    PCIDevice *pci_dev;

    if ((size != 1) && (size != 2) && (size != 4)) {
        /* access must be 1, 2 or 4 bytes */
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    pci_dev = spapr_pci_find_dev(spapr, buid, addr);
    addr = rtas_pci_cfgaddr(addr);

    if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {
        /* Access must be to a valid device, within bounds and
         * naturally aligned */
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    pci_host_config_write_common(pci_dev, addr, pci_config_size(pci_dev),
                                 val, size);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}

static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                      uint32_t token, uint32_t nargs,
                                      target_ulong args,
                                      uint32_t nret, target_ulong rets)
{
    uint64_t buid;
    uint32_t val, size, addr;

    if ((nargs != 5) || (nret != 1)) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    buid = rtas_ldq(args, 1);
    val = rtas_ld(args, 4);
    size = rtas_ld(args, 3);
    addr = rtas_ld(args, 0);

    finish_write_pci_config(spapr, buid, addr, size, val, rets);
}

static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  uint32_t token, uint32_t nargs,
                                  target_ulong args,
                                  uint32_t nret, target_ulong rets)
{
    uint32_t val, size, addr;

    if ((nargs != 3) || (nret != 1)) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }


    val = rtas_ld(args, 2);
    size = rtas_ld(args, 1);
    addr = rtas_ld(args, 0);

    finish_write_pci_config(spapr, 0, addr, size, val, rets);
}

/*
 * Set MSI/MSIX message data.
 * This is required for msi_notify()/msix_notify() which
 * will write at the addresses via spapr_msi_write().
 *
 * If hwaddr == 0, all entries will have .data == first_irq i.e.
 * table will be reset.
 */
static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, bool msix,
                             unsigned first_irq, unsigned req_num)
{
    unsigned i;
    MSIMessage msg = { .address = addr, .data = first_irq };

    if (!msix) {
        msi_set_message(pdev, msg);
        trace_spapr_pci_msi_setup(pdev->name, 0, msg.address);
        return;
    }

    for (i = 0; i < req_num; ++i) {
        msix_set_message(pdev, i, msg);
        trace_spapr_pci_msi_setup(pdev->name, i, msg.address);
        if (addr) {
            ++msg.data;
        }
    }
}

static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                uint32_t token, uint32_t nargs,
                                target_ulong args, uint32_t nret,
                                target_ulong rets)
{
    uint32_t config_addr = rtas_ld(args, 0);
    uint64_t buid = rtas_ldq(args, 1);
    unsigned int func = rtas_ld(args, 3);
    unsigned int req_num = rtas_ld(args, 4); /* 0 == remove all */
    unsigned int seq_num = rtas_ld(args, 5);
    unsigned int ret_intr_type;
    unsigned int irq, max_irqs = 0, num = 0;
    sPAPRPHBState *phb = NULL;
    PCIDevice *pdev = NULL;
    spapr_pci_msi *msi;
    int *config_addr_key;

    switch (func) {
    case RTAS_CHANGE_MSI_FN:
    case RTAS_CHANGE_FN:
        ret_intr_type = RTAS_TYPE_MSI;
        break;
    case RTAS_CHANGE_MSIX_FN:
        ret_intr_type = RTAS_TYPE_MSIX;
        break;
    default:
        error_report("rtas_ibm_change_msi(%u) is not implemented", func);
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    /* Fins sPAPRPHBState */
    phb = spapr_pci_find_phb(spapr, buid);
    if (phb) {
        pdev = spapr_pci_find_dev(spapr, buid, config_addr);
    }
    if (!phb || !pdev) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    /* Releasing MSIs */
    if (!req_num) {
        msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr);
        if (!msi) {
            trace_spapr_pci_msi("Releasing wrong config", config_addr);
            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
            return;
        }

        xics_free(spapr->icp, msi->first_irq, msi->num);
        if (msi_present(pdev)) {
            spapr_msi_setmsg(pdev, 0, false, 0, num);
        }
        if (msix_present(pdev)) {
            spapr_msi_setmsg(pdev, 0, true, 0, num);
        }
        g_hash_table_remove(phb->msi, &config_addr);

        trace_spapr_pci_msi("Released MSIs", config_addr);
        rtas_st(rets, 0, RTAS_OUT_SUCCESS);
        rtas_st(rets, 1, 0);
        return;
    }

    /* Enabling MSI */

    /* Check if the device supports as many IRQs as requested */
    if (ret_intr_type == RTAS_TYPE_MSI) {
        max_irqs = msi_nr_vectors_allocated(pdev);
    } else if (ret_intr_type == RTAS_TYPE_MSIX) {
        max_irqs = pdev->msix_entries_nr;
    }
    if (!max_irqs) {
        error_report("Requested interrupt type %d is not enabled for device %x",
                     ret_intr_type, config_addr);
        rtas_st(rets, 0, -1); /* Hardware error */
        return;
    }
    /* Correct the number if the guest asked for too many */
    if (req_num > max_irqs) {
        trace_spapr_pci_msi_retry(config_addr, req_num, max_irqs);
        req_num = max_irqs;
        irq = 0; /* to avoid misleading trace */
        goto out;
    }

    /* Allocate MSIs */
    irq = xics_alloc_block(spapr->icp, 0, req_num, false,
                           ret_intr_type == RTAS_TYPE_MSI);
    if (!irq) {
        error_report("Cannot allocate MSIs for device %x", config_addr);
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    /* Setup MSI/MSIX vectors in the device (via cfgspace or MSIX BAR) */
    spapr_msi_setmsg(pdev, SPAPR_PCI_MSI_WINDOW, ret_intr_type == RTAS_TYPE_MSIX,
                     irq, req_num);

    /* Add MSI device to cache */
    msi = g_new(spapr_pci_msi, 1);
    msi->first_irq = irq;
    msi->num = req_num;
    config_addr_key = g_new(int, 1);
    *config_addr_key = config_addr;
    g_hash_table_insert(phb->msi, config_addr_key, msi);

out:
    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, req_num);
    rtas_st(rets, 2, ++seq_num);
    if (nret > 3) {
        rtas_st(rets, 3, ret_intr_type);
    }

    trace_spapr_pci_rtas_ibm_change_msi(config_addr, func, req_num, irq);
}

static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
                                                   sPAPRMachineState *spapr,
                                                   uint32_t token,
                                                   uint32_t nargs,
                                                   target_ulong args,
                                                   uint32_t nret,
                                                   target_ulong rets)
{
    uint32_t config_addr = rtas_ld(args, 0);
    uint64_t buid = rtas_ldq(args, 1);
    unsigned int intr_src_num = -1, ioa_intr_num = rtas_ld(args, 3);
    sPAPRPHBState *phb = NULL;
    PCIDevice *pdev = NULL;
    spapr_pci_msi *msi;

    /* Find sPAPRPHBState */
    phb = spapr_pci_find_phb(spapr, buid);
    if (phb) {
        pdev = spapr_pci_find_dev(spapr, buid, config_addr);
    }
    if (!phb || !pdev) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    /* Find device descriptor and start IRQ */
    msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr);
    if (!msi || !msi->first_irq || !msi->num || (ioa_intr_num >= msi->num)) {
        trace_spapr_pci_msi("Failed to return vector", config_addr);
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }
    intr_src_num = msi->first_irq + ioa_intr_num;
    trace_spapr_pci_rtas_ibm_query_interrupt_source_number(ioa_intr_num,
                                                           intr_src_num);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, intr_src_num);
    rtas_st(rets, 2, 1);/* 0 == level; 1 == edge */
}

static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
                                    sPAPRMachineState *spapr,
                                    uint32_t token, uint32_t nargs,
                                    target_ulong args, uint32_t nret,
                                    target_ulong rets)
{
    sPAPRPHBState *sphb;
    sPAPRPHBClass *spc;
    uint32_t addr, option;
    uint64_t buid;
    int ret;

    if ((nargs != 4) || (nret != 1)) {
        goto param_error_exit;
    }

    buid = rtas_ldq(args, 1);
    addr = rtas_ld(args, 0);
    option = rtas_ld(args, 3);

    sphb = spapr_pci_find_phb(spapr, buid);
    if (!sphb) {
        goto param_error_exit;
    }

    spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
    if (!spc->eeh_set_option) {
        goto param_error_exit;
    }

    ret = spc->eeh_set_option(sphb, addr, option);
    rtas_st(rets, 0, ret);
    return;

param_error_exit:
    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}

static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
                                           sPAPRMachineState *spapr,
                                           uint32_t token, uint32_t nargs,
                                           target_ulong args, uint32_t nret,
                                           target_ulong rets)
{
    sPAPRPHBState *sphb;
    sPAPRPHBClass *spc;
    PCIDevice *pdev;
    uint32_t addr, option;
    uint64_t buid;

    if ((nargs != 4) || (nret != 2)) {
        goto param_error_exit;
    }

    buid = rtas_ldq(args, 1);
    sphb = spapr_pci_find_phb(spapr, buid);
    if (!sphb) {
        goto param_error_exit;
    }

    spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
    if (!spc->eeh_set_option) {
        goto param_error_exit;
    }

    /*
     * We always have PE address of form "00BB0001". "BB"
     * represents the bus number of PE's primary bus.
     */
    option = rtas_ld(args, 3);
    switch (option) {
    case RTAS_GET_PE_ADDR:
        addr = rtas_ld(args, 0);
        pdev = spapr_pci_find_dev(spapr, buid, addr);
        if (!pdev) {
            goto param_error_exit;
        }

        rtas_st(rets, 1, (pci_bus_num(pdev->bus) << 16) + 1);
        break;
    case RTAS_GET_PE_MODE:
        rtas_st(rets, 1, RTAS_PE_MODE_SHARED);
        break;
    default:
        goto param_error_exit;
    }

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    return;

param_error_exit:
    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}

static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
                                            sPAPRMachineState *spapr,
                                            uint32_t token, uint32_t nargs,
                                            target_ulong args, uint32_t nret,
                                            target_ulong rets)
{
    sPAPRPHBState *sphb;
    sPAPRPHBClass *spc;
    uint64_t buid;
    int state, ret;

    if ((nargs != 3) || (nret != 4 && nret != 5)) {
        goto param_error_exit;
    }

    buid = rtas_ldq(args, 1);
    sphb = spapr_pci_find_phb(spapr, buid);
    if (!sphb) {
        goto param_error_exit;
    }

    spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
    if (!spc->eeh_get_state) {
        goto param_error_exit;
    }

    ret = spc->eeh_get_state(sphb, &state);
    rtas_st(rets, 0, ret);
    if (ret != RTAS_OUT_SUCCESS) {
        return;
    }

    rtas_st(rets, 1, state);
    rtas_st(rets, 2, RTAS_EEH_SUPPORT);
    rtas_st(rets, 3, RTAS_EEH_PE_UNAVAIL_INFO);
    if (nret >= 5) {
        rtas_st(rets, 4, RTAS_EEH_PE_RECOVER_INFO);
    }
    return;

param_error_exit:
    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}

static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
                                    sPAPRMachineState *spapr,
                                    uint32_t token, uint32_t nargs,
                                    target_ulong args, uint32_t nret,
                                    target_ulong rets)
{
    sPAPRPHBState *sphb;
    sPAPRPHBClass *spc;
    uint32_t option;
    uint64_t buid;
    int ret;

    if ((nargs != 4) || (nret != 1)) {
        goto param_error_exit;
    }

    buid = rtas_ldq(args, 1);
    option = rtas_ld(args, 3);
    sphb = spapr_pci_find_phb(spapr, buid);
    if (!sphb) {
        goto param_error_exit;
    }

    spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
    if (!spc->eeh_reset) {
        goto param_error_exit;
    }

    ret = spc->eeh_reset(sphb, option);
    rtas_st(rets, 0, ret);
    return;

param_error_exit:
    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}

static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
                                  sPAPRMachineState *spapr,
                                  uint32_t token, uint32_t nargs,
                                  target_ulong args, uint32_t nret,
                                  target_ulong rets)
{
    sPAPRPHBState *sphb;
    sPAPRPHBClass *spc;
    uint64_t buid;
    int ret;

    if ((nargs != 3) || (nret != 1)) {
        goto param_error_exit;
    }

    buid = rtas_ldq(args, 1);
    sphb = spapr_pci_find_phb(spapr, buid);
    if (!sphb) {
        goto param_error_exit;
    }

    spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
    if (!spc->eeh_configure) {
        goto param_error_exit;
    }

    ret = spc->eeh_configure(sphb);
    rtas_st(rets, 0, ret);
    return;

param_error_exit:
    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}

/* To support it later */
static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
                                       sPAPRMachineState *spapr,
                                       uint32_t token, uint32_t nargs,
                                       target_ulong args, uint32_t nret,
                                       target_ulong rets)
{
    sPAPRPHBState *sphb;
    sPAPRPHBClass *spc;
    int option;
    uint64_t buid;

    if ((nargs != 8) || (nret != 1)) {
        goto param_error_exit;
    }

    buid = rtas_ldq(args, 1);
    sphb = spapr_pci_find_phb(spapr, buid);
    if (!sphb) {
        goto param_error_exit;
    }

    spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
    if (!spc->eeh_set_option) {
        goto param_error_exit;
    }

    option = rtas_ld(args, 7);
    switch (option) {
    case RTAS_SLOT_TEMP_ERR_LOG:
    case RTAS_SLOT_PERM_ERR_LOG:
        break;
    default:
        goto param_error_exit;
    }

    /* We don't have error log yet */
    rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
    return;

param_error_exit:
    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}

static int pci_spapr_swizzle(int slot, int pin)
{
    return (slot + pin) % PCI_NUM_PINS;
}

static int pci_spapr_map_irq(PCIDevice *pci_dev, int irq_num)
{
    /*
     * Here we need to convert pci_dev + irq_num to some unique value
     * which is less than number of IRQs on the specific bus (4).  We
     * use standard PCI swizzling, that is (slot number + pin number)
     * % 4.
     */
    return pci_spapr_swizzle(PCI_SLOT(pci_dev->devfn), irq_num);
}

static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
{
    /*
     * Here we use the number returned by pci_spapr_map_irq to find a
     * corresponding qemu_irq.
     */
    sPAPRPHBState *phb = opaque;

    trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, phb->lsi_table[irq_num].irq);
    qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
}

static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
{
    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(opaque);
    PCIINTxRoute route;

    route.mode = PCI_INTX_ENABLED;
    route.irq = sphb->lsi_table[pin].irq;

    return route;
}

/*
 * MSI/MSIX memory region implementation.
 * The handler handles both MSI and MSIX.
 * For MSI-X, the vector number is encoded as a part of the address,
 * data is set to 0.
 * For MSI, the vector number is encoded in least bits in data.
 */
static void spapr_msi_write(void *opaque, hwaddr addr,
                            uint64_t data, unsigned size)
{
    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
    uint32_t irq = data;

    trace_spapr_pci_msi_write(addr, data, irq);

    qemu_irq_pulse(xics_get_qirq(spapr->icp, irq));
}

static const MemoryRegionOps spapr_msi_ops = {
    /* There is no .read as the read result is undefined by PCI spec */
    .read = NULL,
    .write = spapr_msi_write,
    .endianness = DEVICE_LITTLE_ENDIAN
};

/*
 * PHB PCI device
 */
static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
{
    sPAPRPHBState *phb = opaque;

    return &phb->iommu_as;
}

static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb,  PCIDevice *pdev)
{
    char *path = NULL, *buf = NULL, *host = NULL;

    /* Get the PCI VFIO host id */
    host = object_property_get_str(OBJECT(pdev), "host", NULL);
    if (!host) {
        goto err_out;
    }

    /* Construct the path of the file that will give us the DT location */
    path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
    g_free(host);
    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
        goto err_out;
    }
    g_free(path);

    /* Construct and read from host device tree the loc-code */
    path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
    g_free(buf);
    if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) {
        goto err_out;
    }
    return buf;

err_out:
    g_free(path);
    return NULL;
}

static char *spapr_phb_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev)
{
    char *buf;
    const char *devtype = "qemu";
    uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(pdev))));

    if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
        buf = spapr_phb_vfio_get_loc_code(sphb, pdev);
        if (buf) {
            return buf;
        }
        devtype = "vfio";
    }
    /*
     * For emulated devices and VFIO-failure case, make up
     * the loc-code.
     */
    buf = g_strdup_printf("%s_%s:%04x:%02x:%02x.%x",
                          devtype, pdev->name, sphb->index, busnr,
                          PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
    return buf;
}

/* Macros to operate with address in OF binding to PCI */
#define b_x(x, p, l)    (((x) & ((1<<(l))-1)) << (p))
#define b_n(x)          b_x((x), 31, 1) /* 0 if relocatable */
#define b_p(x)          b_x((x), 30, 1) /* 1 if prefetchable */
#define b_t(x)          b_x((x), 29, 1) /* 1 if the address is aliased */
#define b_ss(x)         b_x((x), 24, 2) /* the space code */
#define b_bbbbbbbb(x)   b_x((x), 16, 8) /* bus number */
#define b_ddddd(x)      b_x((x), 11, 5) /* device number */
#define b_fff(x)        b_x((x), 8, 3)  /* function number */
#define b_rrrrrrrr(x)   b_x((x), 0, 8)  /* register number */

/* for 'reg'/'assigned-addresses' OF properties */
#define RESOURCE_CELLS_SIZE 2
#define RESOURCE_CELLS_ADDRESS 3

typedef struct ResourceFields {
    uint32_t phys_hi;
    uint32_t phys_mid;
    uint32_t phys_lo;
    uint32_t size_hi;
    uint32_t size_lo;
} QEMU_PACKED ResourceFields;

typedef struct ResourceProps {
    ResourceFields reg[8];
    ResourceFields assigned[7];
    uint32_t reg_len;
    uint32_t assigned_len;
} ResourceProps;

/* fill in the 'reg'/'assigned-resources' OF properties for
 * a PCI device. 'reg' describes resource requirements for a
 * device's IO/MEM regions, 'assigned-addresses' describes the
 * actual resource assignments.
 *
 * the properties are arrays of ('phys-addr', 'size') pairs describing
 * the addressable regions of the PCI device, where 'phys-addr' is a
 * RESOURCE_CELLS_ADDRESS-tuple of 32-bit integers corresponding to
 * (phys.hi, phys.mid, phys.lo), and 'size' is a
 * RESOURCE_CELLS_SIZE-tuple corresponding to (size.hi, size.lo).
 *
 * phys.hi = 0xYYXXXXZZ, where:
 *   0xYY = npt000ss
 *          |||   |
 *          |||   +-- space code
 *          |||               |
 *          |||               +  00 if configuration space
 *          |||               +  01 if IO region,
 *          |||               +  10 if 32-bit MEM region
 *          |||               +  11 if 64-bit MEM region
 *          |||
 *          ||+------ for non-relocatable IO: 1 if aliased
 *          ||        for relocatable IO: 1 if below 64KB
 *          ||        for MEM: 1 if below 1MB
 *          |+------- 1 if region is prefetchable
 *          +-------- 1 if region is non-relocatable
 *   0xXXXX = bbbbbbbb dddddfff, encoding bus, slot, and function
 *            bits respectively
 *   0xZZ = rrrrrrrr, the register number of the BAR corresponding
 *          to the region
 *
 * phys.mid and phys.lo correspond respectively to the hi/lo portions
 * of the actual address of the region.
 *
 * how the phys-addr/size values are used differ slightly between
 * 'reg' and 'assigned-addresses' properties. namely, 'reg' has
 * an additional description for the config space region of the
 * device, and in the case of QEMU has n=0 and phys.mid=phys.lo=0
 * to describe the region as relocatable, with an address-mapping
 * that corresponds directly to the PHB's address space for the
 * resource. 'assigned-addresses' always has n=1 set with an absolute
 * address assigned for the resource. in general, 'assigned-addresses'
 * won't be populated, since addresses for PCI devices are generally
 * unmapped initially and left to the guest to assign.
 *
 * note also that addresses defined in these properties are, at least
 * for PAPR guests, relative to the PHBs IO/MEM windows, and
 * correspond directly to the addresses in the BARs.
 *
 * in accordance with PCI Bus Binding to Open Firmware,
 * IEEE Std 1275-1994, section 4.1.1, as implemented by PAPR+ v2.7,
 * Appendix C.
 */
static void populate_resource_props(PCIDevice *d, ResourceProps *rp)
{
    int bus_num = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(d))));
    uint32_t dev_id = (b_bbbbbbbb(bus_num) |
                       b_ddddd(PCI_SLOT(d->devfn)) |
                       b_fff(PCI_FUNC(d->devfn)));
    ResourceFields *reg, *assigned;
    int i, reg_idx = 0, assigned_idx = 0;

    /* config space region */
    reg = &rp->reg[reg_idx++];
    reg->phys_hi = cpu_to_be32(dev_id);
    reg->phys_mid = 0;
    reg->phys_lo = 0;
    reg->size_hi = 0;
    reg->size_lo = 0;

    for (i = 0; i < PCI_NUM_REGIONS; i++) {
        if (!d->io_regions[i].size) {
            continue;
        }

        reg = &rp->reg[reg_idx++];

        reg->phys_hi = cpu_to_be32(dev_id | b_rrrrrrrr(pci_bar(d, i)));
        if (d->io_regions[i].type & PCI_BASE_ADDRESS_SPACE_IO) {
            reg->phys_hi |= cpu_to_be32(b_ss(1));
        } else if (d->io_regions[i].type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
            reg->phys_hi |= cpu_to_be32(b_ss(3));
        } else {
            reg->phys_hi |= cpu_to_be32(b_ss(2));
        }
        reg->phys_mid = 0;
        reg->phys_lo = 0;
        reg->size_hi = cpu_to_be32(d->io_regions[i].size >> 32);
        reg->size_lo = cpu_to_be32(d->io_regions[i].size);

        if (d->io_regions[i].addr == PCI_BAR_UNMAPPED) {
            continue;
        }

        assigned = &rp->assigned[assigned_idx++];
        assigned->phys_hi = cpu_to_be32(reg->phys_hi | b_n(1));
        assigned->phys_mid = cpu_to_be32(d->io_regions[i].addr >> 32);
        assigned->phys_lo = cpu_to_be32(d->io_regions[i].addr);
        assigned->size_hi = reg->size_hi;
        assigned->size_lo = reg->size_lo;
    }

    rp->reg_len = reg_idx * sizeof(ResourceFields);
    rp->assigned_len = assigned_idx * sizeof(ResourceFields);
}

static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
                                            PCIDevice *pdev);

static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
                                       sPAPRPHBState *sphb)
{
    ResourceProps rp;
    bool is_bridge = false;
    int pci_status, err;
    char *buf = NULL;
    uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);
    uint32_t max_msi, max_msix;

    if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) ==
        PCI_HEADER_TYPE_BRIDGE) {
        is_bridge = true;
    }

    /* in accordance with PAPR+ v2.7 13.6.3, Table 181 */
    _FDT(fdt_setprop_cell(fdt, offset, "vendor-id",
                          pci_default_read_config(dev, PCI_VENDOR_ID, 2)));
    _FDT(fdt_setprop_cell(fdt, offset, "device-id",
                          pci_default_read_config(dev, PCI_DEVICE_ID, 2)));
    _FDT(fdt_setprop_cell(fdt, offset, "revision-id",
                          pci_default_read_config(dev, PCI_REVISION_ID, 1)));
    _FDT(fdt_setprop_cell(fdt, offset, "class-code",
                          pci_default_read_config(dev, PCI_CLASS_PROG, 3)));
    if (pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)) {
        _FDT(fdt_setprop_cell(fdt, offset, "interrupts",
                 pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)));
    }

    if (!is_bridge) {
        _FDT(fdt_setprop_cell(fdt, offset, "min-grant",
            pci_default_read_config(dev, PCI_MIN_GNT, 1)));
        _FDT(fdt_setprop_cell(fdt, offset, "max-latency",
            pci_default_read_config(dev, PCI_MAX_LAT, 1)));
    }

    if (pci_default_read_config(dev, PCI_SUBSYSTEM_ID, 2)) {
        _FDT(fdt_setprop_cell(fdt, offset, "subsystem-id",
                 pci_default_read_config(dev, PCI_SUBSYSTEM_ID, 2)));
    }

    if (pci_default_read_config(dev, PCI_SUBSYSTEM_VENDOR_ID, 2)) {
        _FDT(fdt_setprop_cell(fdt, offset, "subsystem-vendor-id",
                 pci_default_read_config(dev, PCI_SUBSYSTEM_VENDOR_ID, 2)));
    }

    _FDT(fdt_setprop_cell(fdt, offset, "cache-line-size",
        pci_default_read_config(dev, PCI_CACHE_LINE_SIZE, 1)));

    /* the following fdt cells are masked off the pci status register */
    pci_status = pci_default_read_config(dev, PCI_STATUS, 2);
    _FDT(fdt_setprop_cell(fdt, offset, "devsel-speed",
                          PCI_STATUS_DEVSEL_MASK & pci_status));

    if (pci_status & PCI_STATUS_FAST_BACK) {
        _FDT(fdt_setprop(fdt, offset, "fast-back-to-back", NULL, 0));
    }
    if (pci_status & PCI_STATUS_66MHZ) {
        _FDT(fdt_setprop(fdt, offset, "66mhz-capable", NULL, 0));
    }
    if (pci_status & PCI_STATUS_UDF) {
        _FDT(fdt_setprop(fdt, offset, "udf-supported", NULL, 0));
    }

    /* NOTE: this is normally generated by firmware via path/unit name,
     * but in our case we must set it manually since it does not get
     * processed by OF beforehand
     */
    _FDT(fdt_setprop_string(fdt, offset, "name", "pci"));
    buf = spapr_phb_get_loc_code(sphb, dev);
    if (!buf) {
        error_report("Failed setting the ibm,loc-code");
        return -1;
    }

    err = fdt_setprop_string(fdt, offset, "ibm,loc-code", buf);
    g_free(buf);
    if (err < 0) {
        return err;
    }

    if (drc_index) {
        _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));
    }

    _FDT(fdt_setprop_cell(fdt, offset, "#address-cells",
                          RESOURCE_CELLS_ADDRESS));
    _FDT(fdt_setprop_cell(fdt, offset, "#size-cells",
                          RESOURCE_CELLS_SIZE));

    max_msi = msi_nr_vectors_allocated(dev);
    if (max_msi) {
        _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi", max_msi));
    }
    max_msix = dev->msix_entries_nr;
    if (max_msix) {
        _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi-x", max_msix));
    }

    populate_resource_props(dev, &rp);
    _FDT(fdt_setprop(fdt, offset, "reg", (uint8_t *)rp.reg, rp.reg_len));
    _FDT(fdt_setprop(fdt, offset, "assigned-addresses",
                     (uint8_t *)rp.assigned, rp.assigned_len));

    return 0;
}

/* create OF node for pci device and required OF DT properties */
static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
                                     void *fdt, int node_offset)
{
    int offset, ret;
    int slot = PCI_SLOT(dev->devfn);
    int func = PCI_FUNC(dev->devfn);
    char nodename[FDT_NAME_MAX];

    if (func != 0) {
        snprintf(nodename, FDT_NAME_MAX, "pci@%x,%x", slot, func);
    } else {
        snprintf(nodename, FDT_NAME_MAX, "pci@%x", slot);
    }
    offset = fdt_add_subnode(fdt, node_offset, nodename);
    ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb);

    g_assert(!ret);
    if (ret) {
        return 0;
    }
    return offset;
}

static void spapr_phb_add_pci_device(sPAPRDRConnector *drc,
                                     sPAPRPHBState *phb,
                                     PCIDevice *pdev,
                                     Error **errp)
{
    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
    DeviceState *dev = DEVICE(pdev);
    void *fdt = NULL;
    int fdt_start_offset = 0, fdt_size;

    if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
        sPAPRTCETable *tcet = spapr_tce_find_by_liobn(phb->dma_liobn);

        spapr_tce_set_need_vfio(tcet, true);
    }

    if (dev->hotplugged) {
        fdt = create_device_tree(&fdt_size);
        fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, fdt, 0);
        if (!fdt_start_offset) {
            error_setg(errp, "Failed to create pci child device tree node");
            goto out;
        }
    }

    drck->attach(drc, DEVICE(pdev),
                 fdt, fdt_start_offset, !dev->hotplugged, errp);
out:
    if (*errp) {
        g_free(fdt);
    }
}

static void spapr_phb_remove_pci_device_cb(DeviceState *dev, void *opaque)
{
    /* some version guests do not wait for completion of a device
     * cleanup (generally done asynchronously by the kernel) before
     * signaling to QEMU that the device is safe, but instead sleep
     * for some 'safe' period of time. unfortunately on a busy host
     * this sleep isn't guaranteed to be long enough, resulting in
     * bad things like IRQ lines being left asserted during final
     * device removal. to deal with this we call reset just prior
     * to finalizing the device, which will put the device back into
     * an 'idle' state, as the device cleanup code expects.
     */
    pci_device_reset(PCI_DEVICE(dev));
    object_unparent(OBJECT(dev));
}

static void spapr_phb_remove_pci_device(sPAPRDRConnector *drc,
                                        sPAPRPHBState *phb,
                                        PCIDevice *pdev,
                                        Error **errp)
{
    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    drck->detach(drc, DEVICE(pdev), spapr_phb_remove_pci_device_cb, phb, errp);
}

static sPAPRDRConnector *spapr_phb_get_pci_drc(sPAPRPHBState *phb,
                                               PCIDevice *pdev)
{
    uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(pdev))));
    return spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_PCI,
                                    (phb->index << 16) |
                                    (busnr << 8) |
                                    pdev->devfn);
}

static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
                                            PCIDevice *pdev)
{
    sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
    sPAPRDRConnectorClass *drck;

    if (!drc) {
        return 0;
    }

    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
    return drck->get_index(drc);
}

static void spapr_phb_hot_plug_child(HotplugHandler *plug_handler,
                                     DeviceState *plugged_dev, Error **errp)
{
    sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
    PCIDevice *pdev = PCI_DEVICE(plugged_dev);
    sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
    Error *local_err = NULL;

    /* if DR is disabled we don't need to do anything in the case of
     * hotplug or coldplug callbacks
     */
    if (!phb->dr_enabled) {
        /* if this is a hotplug operation initiated by the user
         * we need to let them know it's not enabled
         */
        if (plugged_dev->hotplugged) {
            error_setg(errp, QERR_BUS_NO_HOTPLUG,
                       object_get_typename(OBJECT(phb)));
        }
        return;
    }

    g_assert(drc);

    spapr_phb_add_pci_device(drc, phb, pdev, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    if (plugged_dev->hotplugged) {
        spapr_hotplug_req_add_by_index(drc);
    }
}

static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler,
                                       DeviceState *plugged_dev, Error **errp)
{
    sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
    PCIDevice *pdev = PCI_DEVICE(plugged_dev);
    sPAPRDRConnectorClass *drck;
    sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
    Error *local_err = NULL;

    if (!phb->dr_enabled) {
        error_setg(errp, QERR_BUS_NO_HOTPLUG,
                   object_get_typename(OBJECT(phb)));
        return;
    }

    g_assert(drc);

    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
    if (!drck->release_pending(drc)) {
        spapr_phb_remove_pci_device(drc, phb, pdev, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            return;
        }
        spapr_hotplug_req_remove_by_index(drc);
    }
}

static void spapr_phb_realize(DeviceState *dev, Error **errp)
{
    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
    SysBusDevice *s = SYS_BUS_DEVICE(dev);
    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
    PCIHostState *phb = PCI_HOST_BRIDGE(s);
    sPAPRPHBClass *info = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(s);
    char *namebuf;
    int i;
    PCIBus *bus;
    uint64_t msi_window_size = 4096;

    if (sphb->index != (uint32_t)-1) {
        hwaddr windows_base;

        if ((sphb->buid != (uint64_t)-1) || (sphb->dma_liobn != (uint32_t)-1)
            || (sphb->mem_win_addr != (hwaddr)-1)
            || (sphb->io_win_addr != (hwaddr)-1)) {
            error_setg(errp, "Either \"index\" or other parameters must"
                       " be specified for PAPR PHB, not both");
            return;
        }

        if (sphb->index > SPAPR_PCI_MAX_INDEX) {
            error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
                       SPAPR_PCI_MAX_INDEX);
            return;
        }

        sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index;
        sphb->dma_liobn = SPAPR_PCI_LIOBN(sphb->index, 0);

        windows_base = SPAPR_PCI_WINDOW_BASE
            + sphb->index * SPAPR_PCI_WINDOW_SPACING;
        sphb->mem_win_addr = windows_base + SPAPR_PCI_MMIO_WIN_OFF;
        sphb->io_win_addr = windows_base + SPAPR_PCI_IO_WIN_OFF;
    }

    if (sphb->buid == (uint64_t)-1) {
        error_setg(errp, "BUID not specified for PHB");
        return;
    }

    if (sphb->dma_liobn == (uint32_t)-1) {
        error_setg(errp, "LIOBN not specified for PHB");
        return;
    }

    if (sphb->mem_win_addr == (hwaddr)-1) {
        error_setg(errp, "Memory window address not specified for PHB");
        return;
    }

    if (sphb->io_win_addr == (hwaddr)-1) {
        error_setg(errp, "IO window address not specified for PHB");
        return;
    }

    if (spapr_pci_find_phb(spapr, sphb->buid)) {
        error_setg(errp, "PCI host bridges must have unique BUIDs");
        return;
    }

    sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid);

    namebuf = alloca(strlen(sphb->dtbusname) + 32);

    /* Initialize memory regions */
    sprintf(namebuf, "%s.mmio", sphb->dtbusname);
    memory_region_init(&sphb->memspace, OBJECT(sphb), namebuf, UINT64_MAX);

    sprintf(namebuf, "%s.mmio-alias", sphb->dtbusname);
    memory_region_init_alias(&sphb->memwindow, OBJECT(sphb),
                             namebuf, &sphb->memspace,
                             SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size);
    memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,
                                &sphb->memwindow);

    /* Initialize IO regions */
    sprintf(namebuf, "%s.io", sphb->dtbusname);
    memory_region_init(&sphb->iospace, OBJECT(sphb),
                       namebuf, SPAPR_PCI_IO_WIN_SIZE);

    sprintf(namebuf, "%s.io-alias", sphb->dtbusname);
    memory_region_init_alias(&sphb->iowindow, OBJECT(sphb), namebuf,
                             &sphb->iospace, 0, SPAPR_PCI_IO_WIN_SIZE);
    memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
                                &sphb->iowindow);

    bus = pci_register_bus(dev, NULL,
                           pci_spapr_set_irq, pci_spapr_map_irq, sphb,
                           &sphb->memspace, &sphb->iospace,
                           PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
    phb->bus = bus;
    qbus_set_hotplug_handler(BUS(phb->bus), DEVICE(sphb), NULL);

    /*
     * Initialize PHB address space.
     * By default there will be at least one subregion for default
     * 32bit DMA window.
     * Later the guest might want to create another DMA window
     * which will become another memory subregion.
     */
    sprintf(namebuf, "%s.iommu-root", sphb->dtbusname);

    memory_region_init(&sphb->iommu_root, OBJECT(sphb),
                       namebuf, UINT64_MAX);
    address_space_init(&sphb->iommu_as, &sphb->iommu_root,
                       sphb->dtbusname);

    /*
     * As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
     * we need to allocate some memory to catch those writes coming
     * from msi_notify()/msix_notify().
     * As MSIMessage:addr is going to be the same and MSIMessage:data
     * is going to be a VIRQ number, 4 bytes of the MSI MR will only
     * be used.
     *
     * For KVM we want to ensure that this memory is a full page so that
     * our memory slot is of page size granularity.
     */
#ifdef CONFIG_KVM
    if (kvm_enabled()) {
        msi_window_size = getpagesize();
    }
#endif

    memory_region_init_io(&sphb->msiwindow, NULL, &spapr_msi_ops, spapr,
                          "msi", msi_window_size);
    memory_region_add_subregion(&sphb->iommu_root, SPAPR_PCI_MSI_WINDOW,
                                &sphb->msiwindow);

    pci_setup_iommu(bus, spapr_pci_dma_iommu, sphb);

    pci_bus_set_route_irq_fn(bus, spapr_route_intx_pin_to_irq);

    QLIST_INSERT_HEAD(&spapr->phbs, sphb, list);

    /* Initialize the LSI table */
    for (i = 0; i < PCI_NUM_PINS; i++) {
        uint32_t irq;

        irq = xics_alloc_block(spapr->icp, 0, 1, true, false);
        if (!irq) {
            error_setg(errp, "spapr_allocate_lsi failed");
            return;
        }

        sphb->lsi_table[i].irq = irq;
    }

    /* allocate connectors for child PCI devices */
    if (sphb->dr_enabled) {
        for (i = 0; i < PCI_SLOT_MAX * 8; i++) {
            spapr_dr_connector_new(OBJECT(phb),
                                   SPAPR_DR_CONNECTOR_TYPE_PCI,
                                   (sphb->index << 16) | i);
        }
    }

    if (!info->finish_realize) {
        error_setg(errp, "finish_realize not defined");
        return;
    }

    info->finish_realize(sphb, errp);

    sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
}

static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp)
{
    sPAPRTCETable *tcet;
    uint32_t nb_table;

    nb_table = sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT;
    tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn,
                               0, SPAPR_TCE_PAGE_SHIFT, nb_table, false);
    if (!tcet) {
        error_setg(errp, "Unable to create TCE table for %s",
                   sphb->dtbusname);
        return ;
    }

    /* Register default 32bit DMA window */
    memory_region_add_subregion(&sphb->iommu_root, sphb->dma_win_addr,
                                spapr_tce_get_iommu(tcet));
}

static int spapr_phb_children_reset(Object *child, void *opaque)
{
    DeviceState *dev = (DeviceState *) object_dynamic_cast(child, TYPE_DEVICE);

    if (dev) {
        device_reset(dev);
    }

    return 0;
}

static void spapr_phb_reset(DeviceState *qdev)
{
    /* Reset the IOMMU state */
    object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL);
}

static Property spapr_phb_properties[] = {
    DEFINE_PROP_UINT32("index", sPAPRPHBState, index, -1),
    DEFINE_PROP_UINT64("buid", sPAPRPHBState, buid, -1),
    DEFINE_PROP_UINT32("liobn", sPAPRPHBState, dma_liobn, -1),
    DEFINE_PROP_UINT64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
    DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size,
                       SPAPR_PCI_MMIO_WIN_SIZE),
    DEFINE_PROP_UINT64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
    DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size,
                       SPAPR_PCI_IO_WIN_SIZE),
    DEFINE_PROP_BOOL("dynamic-reconfiguration", sPAPRPHBState, dr_enabled,
                     true),
    /* Default DMA window is 0..1GB */
    DEFINE_PROP_UINT64("dma_win_addr", sPAPRPHBState, dma_win_addr, 0),
    DEFINE_PROP_UINT64("dma_win_size", sPAPRPHBState, dma_win_size, 0x40000000),
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription vmstate_spapr_pci_lsi = {
    .name = "spapr_pci/lsi",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_EQUAL(irq, struct spapr_pci_lsi),

        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_spapr_pci_msi = {
    .name = "spapr_pci/msi",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField []) {
        VMSTATE_UINT32(key, spapr_pci_msi_mig),
        VMSTATE_UINT32(value.first_irq, spapr_pci_msi_mig),
        VMSTATE_UINT32(value.num, spapr_pci_msi_mig),
        VMSTATE_END_OF_LIST()
    },
};

static void spapr_pci_pre_save(void *opaque)
{
    sPAPRPHBState *sphb = opaque;
    GHashTableIter iter;
    gpointer key, value;
    int i;

    g_free(sphb->msi_devs);
    sphb->msi_devs = NULL;
    sphb->msi_devs_num = g_hash_table_size(sphb->msi);
    if (!sphb->msi_devs_num) {
        return;
    }
    sphb->msi_devs = g_malloc(sphb->msi_devs_num * sizeof(spapr_pci_msi_mig));

    g_hash_table_iter_init(&iter, sphb->msi);
    for (i = 0; g_hash_table_iter_next(&iter, &key, &value); ++i) {
        sphb->msi_devs[i].key = *(uint32_t *) key;
        sphb->msi_devs[i].value = *(spapr_pci_msi *) value;
    }
}

static int spapr_pci_post_load(void *opaque, int version_id)
{
    sPAPRPHBState *sphb = opaque;
    gpointer key, value;
    int i;

    for (i = 0; i < sphb->msi_devs_num; ++i) {
        key = g_memdup(&sphb->msi_devs[i].key,
                       sizeof(sphb->msi_devs[i].key));
        value = g_memdup(&sphb->msi_devs[i].value,
                         sizeof(sphb->msi_devs[i].value));
        g_hash_table_insert(sphb->msi, key, value);
    }
    g_free(sphb->msi_devs);
    sphb->msi_devs = NULL;
    sphb->msi_devs_num = 0;

    return 0;
}

static const VMStateDescription vmstate_spapr_pci = {
    .name = "spapr_pci",
    .version_id = 2,
    .minimum_version_id = 2,
    .pre_save = spapr_pci_pre_save,
    .post_load = spapr_pci_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState),
        VMSTATE_UINT32_EQUAL(dma_liobn, sPAPRPHBState),
        VMSTATE_UINT64_EQUAL(mem_win_addr, sPAPRPHBState),
        VMSTATE_UINT64_EQUAL(mem_win_size, sPAPRPHBState),
        VMSTATE_UINT64_EQUAL(io_win_addr, sPAPRPHBState),
        VMSTATE_UINT64_EQUAL(io_win_size, sPAPRPHBState),
        VMSTATE_STRUCT_ARRAY(lsi_table, sPAPRPHBState, PCI_NUM_PINS, 0,
                             vmstate_spapr_pci_lsi, struct spapr_pci_lsi),
        VMSTATE_INT32(msi_devs_num, sPAPRPHBState),
        VMSTATE_STRUCT_VARRAY_ALLOC(msi_devs, sPAPRPHBState, msi_devs_num, 0,
                                    vmstate_spapr_pci_msi, spapr_pci_msi_mig),
        VMSTATE_END_OF_LIST()
    },
};

static const char *spapr_phb_root_bus_path(PCIHostState *host_bridge,
                                           PCIBus *rootbus)
{
    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(host_bridge);

    return sphb->dtbusname;
}

static void spapr_phb_class_init(ObjectClass *klass, void *data)
{
    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);
    sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_CLASS(klass);
    HotplugHandlerClass *hp = HOTPLUG_HANDLER_CLASS(klass);

    hc->root_bus_path = spapr_phb_root_bus_path;
    dc->realize = spapr_phb_realize;
    dc->props = spapr_phb_properties;
    dc->reset = spapr_phb_reset;
    dc->vmsd = &vmstate_spapr_pci;
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    dc->cannot_instantiate_with_device_add_yet = false;
    spc->finish_realize = spapr_phb_finish_realize;
    hp->plug = spapr_phb_hot_plug_child;
    hp->unplug = spapr_phb_hot_unplug_child;
}

static const TypeInfo spapr_phb_info = {
    .name          = TYPE_SPAPR_PCI_HOST_BRIDGE,
    .parent        = TYPE_PCI_HOST_BRIDGE,
    .instance_size = sizeof(sPAPRPHBState),
    .class_init    = spapr_phb_class_init,
    .class_size    = sizeof(sPAPRPHBClass),
    .interfaces    = (InterfaceInfo[]) {
        { TYPE_HOTPLUG_HANDLER },
        { }
    }
};

PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index)
{
    DeviceState *dev;

    dev = qdev_create(NULL, TYPE_SPAPR_PCI_HOST_BRIDGE);
    qdev_prop_set_uint32(dev, "index", index);
    qdev_init_nofail(dev);

    return PCI_HOST_BRIDGE(dev);
}

typedef struct sPAPRFDT {
    void *fdt;
    int node_off;
    sPAPRPHBState *sphb;
} sPAPRFDT;

static void spapr_populate_pci_devices_dt(PCIBus *bus, PCIDevice *pdev,
                                          void *opaque)
{
    PCIBus *sec_bus;
    sPAPRFDT *p = opaque;
    int offset;
    sPAPRFDT s_fdt;

    offset = spapr_create_pci_child_dt(p->sphb, pdev, p->fdt, p->node_off);
    if (!offset) {
        error_report("Failed to create pci child device tree node");
        return;
    }

    if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) !=
         PCI_HEADER_TYPE_BRIDGE)) {
        return;
    }

    sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
    if (!sec_bus) {
        return;
    }

    s_fdt.fdt = p->fdt;
    s_fdt.node_off = offset;
    s_fdt.sphb = p->sphb;
    pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
                        spapr_populate_pci_devices_dt,
                        &s_fdt);
}

static void spapr_phb_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
                                           void *opaque)
{
    unsigned int *bus_no = opaque;
    unsigned int primary = *bus_no;
    unsigned int subordinate = 0xff;
    PCIBus *sec_bus = NULL;

    if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) !=
         PCI_HEADER_TYPE_BRIDGE)) {
        return;
    }

    (*bus_no)++;
    pci_default_write_config(pdev, PCI_PRIMARY_BUS, primary, 1);
    pci_default_write_config(pdev, PCI_SECONDARY_BUS, *bus_no, 1);
    pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, *bus_no, 1);

    sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
    if (!sec_bus) {
        return;
    }

    pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, subordinate, 1);
    pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
                        spapr_phb_pci_enumerate_bridge, bus_no);
    pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, *bus_no, 1);
}

static void spapr_phb_pci_enumerate(sPAPRPHBState *phb)
{
    PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
    unsigned int bus_no = 0;

    pci_for_each_device(bus, pci_bus_num(bus),
                        spapr_phb_pci_enumerate_bridge,
                        &bus_no);

}

int spapr_populate_pci_dt(sPAPRPHBState *phb,
                          uint32_t xics_phandle,
                          void *fdt)
{
    int bus_off, i, j, ret;
    char nodename[FDT_NAME_MAX];
    uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
    const uint64_t mmiosize = memory_region_size(&phb->memwindow);
    const uint64_t w32max = (1ULL << 32) - SPAPR_PCI_MEM_WIN_BUS_OFFSET;
    const uint64_t w32size = MIN(w32max, mmiosize);
    const uint64_t w64size = (mmiosize > w32size) ? (mmiosize - w32size) : 0;
    struct {
        uint32_t hi;
        uint64_t child;
        uint64_t parent;
        uint64_t size;
    } QEMU_PACKED ranges[] = {
        {
            cpu_to_be32(b_ss(1)), cpu_to_be64(0),
            cpu_to_be64(phb->io_win_addr),
            cpu_to_be64(memory_region_size(&phb->iospace)),
        },
        {
            cpu_to_be32(b_ss(2)), cpu_to_be64(SPAPR_PCI_MEM_WIN_BUS_OFFSET),
            cpu_to_be64(phb->mem_win_addr),
            cpu_to_be64(w32size),
        },
        {
            cpu_to_be32(b_ss(3)), cpu_to_be64(1ULL << 32),
            cpu_to_be64(phb->mem_win_addr + w32size),
            cpu_to_be64(w64size)
        },
    };
    const unsigned sizeof_ranges = (w64size ? 3 : 2) * sizeof(ranges[0]);
    uint64_t bus_reg[] = { cpu_to_be64(phb->buid), 0 };
    uint32_t interrupt_map_mask[] = {
        cpu_to_be32(b_ddddd(-1)|b_fff(0)), 0x0, 0x0, cpu_to_be32(-1)};
    uint32_t interrupt_map[PCI_SLOT_MAX * PCI_NUM_PINS][7];
    sPAPRTCETable *tcet;
    PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
    sPAPRFDT s_fdt;

    /* Start populating the FDT */
    snprintf(nodename, FDT_NAME_MAX, "pci@%" PRIx64, phb->buid);
    bus_off = fdt_add_subnode(fdt, 0, nodename);
    if (bus_off < 0) {
        return bus_off;
    }

    /* Write PHB properties */
    _FDT(fdt_setprop_string(fdt, bus_off, "device_type", "pci"));
    _FDT(fdt_setprop_string(fdt, bus_off, "compatible", "IBM,Logical_PHB"));
    _FDT(fdt_setprop_cell(fdt, bus_off, "#address-cells", 0x3));
    _FDT(fdt_setprop_cell(fdt, bus_off, "#size-cells", 0x2));
    _FDT(fdt_setprop_cell(fdt, bus_off, "#interrupt-cells", 0x1));
    _FDT(fdt_setprop(fdt, bus_off, "used-by-rtas", NULL, 0));
    _FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range)));
    _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges));
    _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
    _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1));
    _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", XICS_IRQS));

    /* Build the interrupt-map, this must matches what is done
     * in pci_spapr_map_irq
     */
    _FDT(fdt_setprop(fdt, bus_off, "interrupt-map-mask",
                     &interrupt_map_mask, sizeof(interrupt_map_mask)));
    for (i = 0; i < PCI_SLOT_MAX; i++) {
        for (j = 0; j < PCI_NUM_PINS; j++) {
            uint32_t *irqmap = interrupt_map[i*PCI_NUM_PINS + j];
            int lsi_num = pci_spapr_swizzle(i, j);

            irqmap[0] = cpu_to_be32(b_ddddd(i)|b_fff(0));
            irqmap[1] = 0;
            irqmap[2] = 0;
            irqmap[3] = cpu_to_be32(j+1);
            irqmap[4] = cpu_to_be32(xics_phandle);
            irqmap[5] = cpu_to_be32(phb->lsi_table[lsi_num].irq);
            irqmap[6] = cpu_to_be32(0x8);
        }
    }
    /* Write interrupt map */
    _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map,
                     sizeof(interrupt_map)));

    tcet = spapr_tce_find_by_liobn(SPAPR_PCI_LIOBN(phb->index, 0));
    spapr_dma_dt(fdt, bus_off, "ibm,dma-window",
                 tcet->liobn, tcet->bus_offset,
                 tcet->nb_table << tcet->page_shift);

    /* Walk the bridges and program the bus numbers*/
    spapr_phb_pci_enumerate(phb);
    _FDT(fdt_setprop_cell(fdt, bus_off, "qemu,phb-enumerated", 0x1));

    /* Populate tree nodes with PCI devices attached */
    s_fdt.fdt = fdt;
    s_fdt.node_off = bus_off;
    s_fdt.sphb = phb;
    pci_for_each_device(bus, pci_bus_num(bus),
                        spapr_populate_pci_devices_dt,
                        &s_fdt);

    ret = spapr_drc_populate_dt(fdt, bus_off, OBJECT(phb),
                                SPAPR_DR_CONNECTOR_TYPE_PCI);
    if (ret) {
        return ret;
    }

    return 0;
}

void spapr_pci_rtas_init(void)
{
    spapr_rtas_register(RTAS_READ_PCI_CONFIG, "read-pci-config",
                        rtas_read_pci_config);
    spapr_rtas_register(RTAS_WRITE_PCI_CONFIG, "write-pci-config",
                        rtas_write_pci_config);
    spapr_rtas_register(RTAS_IBM_READ_PCI_CONFIG, "ibm,read-pci-config",
                        rtas_ibm_read_pci_config);
    spapr_rtas_register(RTAS_IBM_WRITE_PCI_CONFIG, "ibm,write-pci-config",
                        rtas_ibm_write_pci_config);
    if (msi_supported) {
        spapr_rtas_register(RTAS_IBM_QUERY_INTERRUPT_SOURCE_NUMBER,
                            "ibm,query-interrupt-source-number",
                            rtas_ibm_query_interrupt_source_number);
        spapr_rtas_register(RTAS_IBM_CHANGE_MSI, "ibm,change-msi",
                            rtas_ibm_change_msi);
    }

    spapr_rtas_register(RTAS_IBM_SET_EEH_OPTION,
                        "ibm,set-eeh-option",
                        rtas_ibm_set_eeh_option);
    spapr_rtas_register(RTAS_IBM_GET_CONFIG_ADDR_INFO2,
                        "ibm,get-config-addr-info2",
                        rtas_ibm_get_config_addr_info2);
    spapr_rtas_register(RTAS_IBM_READ_SLOT_RESET_STATE2,
                        "ibm,read-slot-reset-state2",
                        rtas_ibm_read_slot_reset_state2);
    spapr_rtas_register(RTAS_IBM_SET_SLOT_RESET,
                        "ibm,set-slot-reset",
                        rtas_ibm_set_slot_reset);
    spapr_rtas_register(RTAS_IBM_CONFIGURE_PE,
                        "ibm,configure-pe",
                        rtas_ibm_configure_pe);
    spapr_rtas_register(RTAS_IBM_SLOT_ERROR_DETAIL,
                        "ibm,slot-error-detail",
                        rtas_ibm_slot_error_detail);
}

static void spapr_pci_register_types(void)
{
    type_register_static(&spapr_phb_info);
}

type_init(spapr_pci_register_types)

static int spapr_switch_one_vga(DeviceState *dev, void *opaque)
{
    bool be = *(bool *)opaque;

    if (object_dynamic_cast(OBJECT(dev), "VGA")
        || object_dynamic_cast(OBJECT(dev), "secondary-vga")) {
        object_property_set_bool(OBJECT(dev), be, "big-endian-framebuffer",
                                 &error_abort);
    }
    return 0;
}

void spapr_pci_switch_vga(bool big_endian)
{
    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
    sPAPRPHBState *sphb;

    /*
     * For backward compatibility with existing guests, we switch
     * the endianness of the VGA controller when changing the guest
     * interrupt mode
     */
    QLIST_FOREACH(sphb, &spapr->phbs, list) {
        BusState *bus = &PCI_HOST_BRIDGE(sphb)->bus->qbus;
        qbus_walk_children(bus, spapr_switch_one_vga, NULL, NULL, NULL,
                           &big_endian);
    }
}
