/*
 * 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 "qemu/osdep.h"
#include "qapi/error.h"
#include "cpu.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "migration/vmstate.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 "exec/ram_addr.h"
#include <libfdt.h>
#include "trace.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/qmp/qerror.h"
#include "hw/ppc/fdt.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_ids.h"
#include "hw/ppc/spapr_drc.h"
#include "hw/qdev-properties.h"
#include "sysemu/device_tree.h"
#include "sysemu/kvm.h"
#include "sysemu/hostmem.h"
#include "sysemu/numa.h"
#include "hw/ppc/spapr_numa.h"
#include "qemu/log.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

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)
{
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    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;
    SpaprPhbState *phb = NULL;
    PCIDevice *pdev = NULL;
    SpaprPciMsi *msi;
    int *config_addr_key;
    Error *err = NULL;
    int i;

    /* 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;
    }

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

    msi = (SpaprPciMsi *) g_hash_table_lookup(phb->msi, &config_addr);

    /* Releasing MSIs */
    if (!req_num) {
        if (!msi) {
            trace_spapr_pci_msi("Releasing wrong config", config_addr);
            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
            return;
        }

        if (msi_present(pdev)) {
            spapr_msi_setmsg(pdev, 0, false, 0, 0);
        }
        if (msix_present(pdev)) {
            spapr_msi_setmsg(pdev, 0, true, 0, 0);
        }
        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 */
    if (smc->legacy_irq_allocation) {
        irq = spapr_irq_find(spapr, req_num, ret_intr_type == RTAS_TYPE_MSI,
                             &err);
    } else {
        irq = spapr_irq_msi_alloc(spapr, req_num,
                                  ret_intr_type == RTAS_TYPE_MSI, &err);
    }
    if (err) {
        error_reportf_err(err, "Can't allocate MSIs for device %x: ",
                          config_addr);
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    for (i = 0; i < req_num; i++) {
        spapr_irq_claim(spapr, irq + i, false, &err);
        if (err) {
            if (i) {
                spapr_irq_free(spapr, irq, i);
            }
            if (!smc->legacy_irq_allocation) {
                spapr_irq_msi_free(spapr, irq, req_num);
            }
            error_reportf_err(err, "Can't allocate MSIs for device %x: ",
                              config_addr);
            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
            return;
        }
    }

    /* Release previous MSIs */
    if (msi) {
        g_hash_table_remove(phb->msi, &config_addr);
    }

    /* 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(SpaprPciMsi, 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;
    SpaprPciMsi *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 = (SpaprPciMsi *) 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;
    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;
    }

    if (!spapr_phb_eeh_available(sphb)) {
        goto param_error_exit;
    }

    ret = spapr_phb_vfio_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;
    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;
    }

    if (!spapr_phb_eeh_available(sphb)) {
        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(pci_get_bus(pdev)) << 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;
    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;
    }

    if (!spapr_phb_eeh_available(sphb)) {
        goto param_error_exit;
    }

    ret = spapr_phb_vfio_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;
    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;
    }

    if (!spapr_phb_eeh_available(sphb)) {
        goto param_error_exit;
    }

    ret = spapr_phb_vfio_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;
    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;
    }

    if (!spapr_phb_eeh_available(sphb)) {
        goto param_error_exit;
    }

    ret = spapr_phb_vfio_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;
    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;
    }

    if (!spapr_phb_eeh_available(sphb)) {
        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 void pci_spapr_set_irq(void *opaque, int irq_num, int level)
{
    /*
     * Here we use the number returned by pci_swizzle_map_irq_fn to find a
     * corresponding qemu_irq.
     */
    SpaprPhbState *phb = opaque;
    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());

    trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, phb->lsi_table[irq_num].irq);
    qemu_set_irq(spapr_qirq(spapr, phb->lsi_table[irq_num].irq), 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;
}

static uint64_t spapr_msi_read(void *opaque, hwaddr addr, unsigned size)
{
    qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid access\n", __func__);
    return 0;
}

/*
 * MSI/MSIX memory region implementation.
 * The handler handles both MSI and MSIX.
 * 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 = opaque;
    uint32_t irq = data;

    trace_spapr_pci_msi_write(addr, data, irq);

    qemu_irq_pulse(spapr_qirq(spapr, irq));
}

static const MemoryRegionOps spapr_msi_ops = {
    /*
     * .read result is undefined by PCI spec.
     * define .read method to avoid assert failure in memory_region_init_io
     */
    .read = spapr_msi_read,
    .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 (!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 (!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' 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];
    uint32_t reg_len;
} ResourceProps;

/* fill in the 'reg' OF properties for
 * a PCI device. 'reg' describes resource requirements for a
 * device's IO/MEM regions.
 *
 * the property is an array 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.
 *
 * note also that addresses defined in this property 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;
    int i, reg_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);
    }

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

typedef struct PCIClass PCIClass;
typedef struct PCISubClass PCISubClass;
typedef struct PCIIFace PCIIFace;

struct PCIIFace {
    int iface;
    const char *name;
};

struct PCISubClass {
    int subclass;
    const char *name;
    const PCIIFace *iface;
};

struct PCIClass {
    const char *name;
    const PCISubClass *subc;
};

static const PCISubClass undef_subclass[] = {
    { PCI_CLASS_NOT_DEFINED_VGA, "display", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass mass_subclass[] = {
    { PCI_CLASS_STORAGE_SCSI, "scsi", NULL },
    { PCI_CLASS_STORAGE_IDE, "ide", NULL },
    { PCI_CLASS_STORAGE_FLOPPY, "fdc", NULL },
    { PCI_CLASS_STORAGE_IPI, "ipi", NULL },
    { PCI_CLASS_STORAGE_RAID, "raid", NULL },
    { PCI_CLASS_STORAGE_ATA, "ata", NULL },
    { PCI_CLASS_STORAGE_SATA, "sata", NULL },
    { PCI_CLASS_STORAGE_SAS, "sas", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass net_subclass[] = {
    { PCI_CLASS_NETWORK_ETHERNET, "ethernet", NULL },
    { PCI_CLASS_NETWORK_TOKEN_RING, "token-ring", NULL },
    { PCI_CLASS_NETWORK_FDDI, "fddi", NULL },
    { PCI_CLASS_NETWORK_ATM, "atm", NULL },
    { PCI_CLASS_NETWORK_ISDN, "isdn", NULL },
    { PCI_CLASS_NETWORK_WORLDFIP, "worldfip", NULL },
    { PCI_CLASS_NETWORK_PICMG214, "picmg", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass displ_subclass[] = {
    { PCI_CLASS_DISPLAY_VGA, "vga", NULL },
    { PCI_CLASS_DISPLAY_XGA, "xga", NULL },
    { PCI_CLASS_DISPLAY_3D, "3d-controller", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass media_subclass[] = {
    { PCI_CLASS_MULTIMEDIA_VIDEO, "video", NULL },
    { PCI_CLASS_MULTIMEDIA_AUDIO, "sound", NULL },
    { PCI_CLASS_MULTIMEDIA_PHONE, "telephony", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass mem_subclass[] = {
    { PCI_CLASS_MEMORY_RAM, "memory", NULL },
    { PCI_CLASS_MEMORY_FLASH, "flash", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass bridg_subclass[] = {
    { PCI_CLASS_BRIDGE_HOST, "host", NULL },
    { PCI_CLASS_BRIDGE_ISA, "isa", NULL },
    { PCI_CLASS_BRIDGE_EISA, "eisa", NULL },
    { PCI_CLASS_BRIDGE_MC, "mca", NULL },
    { PCI_CLASS_BRIDGE_PCI, "pci", NULL },
    { PCI_CLASS_BRIDGE_PCMCIA, "pcmcia", NULL },
    { PCI_CLASS_BRIDGE_NUBUS, "nubus", NULL },
    { PCI_CLASS_BRIDGE_CARDBUS, "cardbus", NULL },
    { PCI_CLASS_BRIDGE_RACEWAY, "raceway", NULL },
    { PCI_CLASS_BRIDGE_PCI_SEMITP, "semi-transparent-pci", NULL },
    { PCI_CLASS_BRIDGE_IB_PCI, "infiniband", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass comm_subclass[] = {
    { PCI_CLASS_COMMUNICATION_SERIAL, "serial", NULL },
    { PCI_CLASS_COMMUNICATION_PARALLEL, "parallel", NULL },
    { PCI_CLASS_COMMUNICATION_MULTISERIAL, "multiport-serial", NULL },
    { PCI_CLASS_COMMUNICATION_MODEM, "modem", NULL },
    { PCI_CLASS_COMMUNICATION_GPIB, "gpib", NULL },
    { PCI_CLASS_COMMUNICATION_SC, "smart-card", NULL },
    { 0xFF, NULL, NULL, },
};

static const PCIIFace pic_iface[] = {
    { PCI_CLASS_SYSTEM_PIC_IOAPIC, "io-apic" },
    { PCI_CLASS_SYSTEM_PIC_IOXAPIC, "io-xapic" },
    { 0xFF, NULL },
};

static const PCISubClass sys_subclass[] = {
    { PCI_CLASS_SYSTEM_PIC, "interrupt-controller", pic_iface },
    { PCI_CLASS_SYSTEM_DMA, "dma-controller", NULL },
    { PCI_CLASS_SYSTEM_TIMER, "timer", NULL },
    { PCI_CLASS_SYSTEM_RTC, "rtc", NULL },
    { PCI_CLASS_SYSTEM_PCI_HOTPLUG, "hot-plug-controller", NULL },
    { PCI_CLASS_SYSTEM_SDHCI, "sd-host-controller", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass inp_subclass[] = {
    { PCI_CLASS_INPUT_KEYBOARD, "keyboard", NULL },
    { PCI_CLASS_INPUT_PEN, "pen", NULL },
    { PCI_CLASS_INPUT_MOUSE, "mouse", NULL },
    { PCI_CLASS_INPUT_SCANNER, "scanner", NULL },
    { PCI_CLASS_INPUT_GAMEPORT, "gameport", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass dock_subclass[] = {
    { PCI_CLASS_DOCKING_GENERIC, "dock", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass cpu_subclass[] = {
    { PCI_CLASS_PROCESSOR_PENTIUM, "pentium", NULL },
    { PCI_CLASS_PROCESSOR_POWERPC, "powerpc", NULL },
    { PCI_CLASS_PROCESSOR_MIPS, "mips", NULL },
    { PCI_CLASS_PROCESSOR_CO, "co-processor", NULL },
    { 0xFF, NULL, NULL },
};

static const PCIIFace usb_iface[] = {
    { PCI_CLASS_SERIAL_USB_UHCI, "usb-uhci" },
    { PCI_CLASS_SERIAL_USB_OHCI, "usb-ohci", },
    { PCI_CLASS_SERIAL_USB_EHCI, "usb-ehci" },
    { PCI_CLASS_SERIAL_USB_XHCI, "usb-xhci" },
    { PCI_CLASS_SERIAL_USB_UNKNOWN, "usb-unknown" },
    { PCI_CLASS_SERIAL_USB_DEVICE, "usb-device" },
    { 0xFF, NULL },
};

static const PCISubClass ser_subclass[] = {
    { PCI_CLASS_SERIAL_FIREWIRE, "firewire", NULL },
    { PCI_CLASS_SERIAL_ACCESS, "access-bus", NULL },
    { PCI_CLASS_SERIAL_SSA, "ssa", NULL },
    { PCI_CLASS_SERIAL_USB, "usb", usb_iface },
    { PCI_CLASS_SERIAL_FIBER, "fibre-channel", NULL },
    { PCI_CLASS_SERIAL_SMBUS, "smb", NULL },
    { PCI_CLASS_SERIAL_IB, "infiniband", NULL },
    { PCI_CLASS_SERIAL_IPMI, "ipmi", NULL },
    { PCI_CLASS_SERIAL_SERCOS, "sercos", NULL },
    { PCI_CLASS_SERIAL_CANBUS, "canbus", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass wrl_subclass[] = {
    { PCI_CLASS_WIRELESS_IRDA, "irda", NULL },
    { PCI_CLASS_WIRELESS_CIR, "consumer-ir", NULL },
    { PCI_CLASS_WIRELESS_RF_CONTROLLER, "rf-controller", NULL },
    { PCI_CLASS_WIRELESS_BLUETOOTH, "bluetooth", NULL },
    { PCI_CLASS_WIRELESS_BROADBAND, "broadband", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass sat_subclass[] = {
    { PCI_CLASS_SATELLITE_TV, "satellite-tv", NULL },
    { PCI_CLASS_SATELLITE_AUDIO, "satellite-audio", NULL },
    { PCI_CLASS_SATELLITE_VOICE, "satellite-voice", NULL },
    { PCI_CLASS_SATELLITE_DATA, "satellite-data", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass crypt_subclass[] = {
    { PCI_CLASS_CRYPT_NETWORK, "network-encryption", NULL },
    { PCI_CLASS_CRYPT_ENTERTAINMENT,
      "entertainment-encryption", NULL },
    { 0xFF, NULL, NULL },
};

static const PCISubClass spc_subclass[] = {
    { PCI_CLASS_SP_DPIO, "dpio", NULL },
    { PCI_CLASS_SP_PERF, "counter", NULL },
    { PCI_CLASS_SP_SYNCH, "measurement", NULL },
    { PCI_CLASS_SP_MANAGEMENT, "management-card", NULL },
    { 0xFF, NULL, NULL },
};

static const PCIClass pci_classes[] = {
    { "legacy-device", undef_subclass },
    { "mass-storage",  mass_subclass },
    { "network", net_subclass },
    { "display", displ_subclass, },
    { "multimedia-device", media_subclass },
    { "memory-controller", mem_subclass },
    { "unknown-bridge", bridg_subclass },
    { "communication-controller", comm_subclass},
    { "system-peripheral", sys_subclass },
    { "input-controller", inp_subclass },
    { "docking-station", dock_subclass },
    { "cpu", cpu_subclass },
    { "serial-bus", ser_subclass },
    { "wireless-controller", wrl_subclass },
    { "intelligent-io", NULL },
    { "satellite-device", sat_subclass },
    { "encryption", crypt_subclass },
    { "data-processing-controller", spc_subclass },
};

static const char *dt_name_from_class(uint8_t class, uint8_t subclass,
                                      uint8_t iface)
{
    const PCIClass *pclass;
    const PCISubClass *psubclass;
    const PCIIFace *piface;
    const char *name;

    if (class >= ARRAY_SIZE(pci_classes)) {
        return "pci";
    }

    pclass = pci_classes + class;
    name = pclass->name;

    if (pclass->subc == NULL) {
        return name;
    }

    psubclass = pclass->subc;
    while ((psubclass->subclass & 0xff) != 0xff) {
        if ((psubclass->subclass & 0xff) == subclass) {
            name = psubclass->name;
            break;
        }
        psubclass++;
    }

    piface = psubclass->iface;
    if (piface == NULL) {
        return name;
    }
    while ((piface->iface & 0xff) != 0xff) {
        if ((piface->iface & 0xff) == iface) {
            name = piface->name;
            break;
        }
        piface++;
    }

    return name;
}

/*
 * DRC helper functions
 */

static uint32_t drc_id_from_devfn(SpaprPhbState *phb,
                                  uint8_t chassis, int32_t devfn)
{
    return (phb->index << 16) | (chassis << 8) | devfn;
}

static SpaprDrc *drc_from_devfn(SpaprPhbState *phb,
                                uint8_t chassis, int32_t devfn)
{
    return spapr_drc_by_id(TYPE_SPAPR_DRC_PCI,
                           drc_id_from_devfn(phb, chassis, devfn));
}

static uint8_t chassis_from_bus(PCIBus *bus)
{
    if (pci_bus_is_root(bus)) {
        return 0;
    } else {
        PCIDevice *bridge = pci_bridge_get_device(bus);

        return object_property_get_uint(OBJECT(bridge), "chassis_nr",
                                        &error_abort);
    }
}

static SpaprDrc *drc_from_dev(SpaprPhbState *phb, PCIDevice *dev)
{
    uint8_t chassis = chassis_from_bus(pci_get_bus(dev));

    return drc_from_devfn(phb, chassis, dev->devfn);
}

static void add_drcs(SpaprPhbState *phb, PCIBus *bus)
{
    Object *owner;
    int i;
    uint8_t chassis;

    if (!phb->dr_enabled) {
        return;
    }

    chassis = chassis_from_bus(bus);

    if (pci_bus_is_root(bus)) {
        owner = OBJECT(phb);
    } else {
        owner = OBJECT(pci_bridge_get_device(bus));
    }

    for (i = 0; i < PCI_SLOT_MAX * PCI_FUNC_MAX; i++) {
        spapr_dr_connector_new(owner, TYPE_SPAPR_DRC_PCI,
                               drc_id_from_devfn(phb, chassis, i));
    }
}

static void remove_drcs(SpaprPhbState *phb, PCIBus *bus)
{
    int i;
    uint8_t chassis;

    if (!phb->dr_enabled) {
        return;
    }

    chassis = chassis_from_bus(bus);

    for (i = PCI_SLOT_MAX * PCI_FUNC_MAX - 1; i >= 0; i--) {
        SpaprDrc *drc = drc_from_devfn(phb, chassis, i);

        if (drc) {
            object_unparent(OBJECT(drc));
        }
    }
}

typedef struct PciWalkFdt {
    void *fdt;
    int offset;
    SpaprPhbState *sphb;
    int err;
} PciWalkFdt;

static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
                               void *fdt, int parent_offset);

static void spapr_dt_pci_device_cb(PCIBus *bus, PCIDevice *pdev,
                                   void *opaque)
{
    PciWalkFdt *p = opaque;
    int err;

    if (p->err) {
        /* Something's already broken, don't keep going */
        return;
    }

    err = spapr_dt_pci_device(p->sphb, pdev, p->fdt, p->offset);
    if (err < 0) {
        p->err = err;
    }
}

/* Augment PCI device node with bridge specific information */
static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus *bus,
                               void *fdt, int offset)
{
    Object *owner;
    PciWalkFdt cbinfo = {
        .fdt = fdt,
        .offset = offset,
        .sphb = sphb,
        .err = 0,
    };
    int ret;

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

    assert(bus);
    pci_for_each_device_reverse(bus, pci_bus_num(bus),
                                spapr_dt_pci_device_cb, &cbinfo);
    if (cbinfo.err) {
        return cbinfo.err;
    }

    if (pci_bus_is_root(bus)) {
        owner = OBJECT(sphb);
    } else {
        owner = OBJECT(pci_bridge_get_device(bus));
    }

    ret = spapr_dt_drc(fdt, offset, owner,
                       SPAPR_DR_CONNECTOR_TYPE_PCI);
    if (ret) {
        return ret;
    }

    return offset;
}

char *spapr_pci_fw_dev_name(PCIDevice *dev)
{
    const gchar *basename;
    int slot = PCI_SLOT(dev->devfn);
    int func = PCI_FUNC(dev->devfn);
    uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);

    basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
                                  ccode & 0xff);

    if (func != 0) {
        return g_strdup_printf("%s@%x,%x", basename, slot, func);
    } else {
        return g_strdup_printf("%s@%x", basename, slot);
    }
}

/* create OF node for pci device and required OF DT properties */
static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
                               void *fdt, int parent_offset)
{
    int offset;
    g_autofree gchar *nodename = spapr_pci_fw_dev_name(dev);
    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
    ResourceProps rp;
    SpaprDrc *drc = drc_from_dev(sphb, dev);
    uint32_t vendor_id = pci_default_read_config(dev, PCI_VENDOR_ID, 2);
    uint32_t device_id = pci_default_read_config(dev, PCI_DEVICE_ID, 2);
    uint32_t revision_id = pci_default_read_config(dev, PCI_REVISION_ID, 1);
    uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
    uint32_t irq_pin = pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1);
    uint32_t subsystem_id = pci_default_read_config(dev, PCI_SUBSYSTEM_ID, 2);
    uint32_t subsystem_vendor_id =
        pci_default_read_config(dev, PCI_SUBSYSTEM_VENDOR_ID, 2);
    uint32_t cache_line_size =
        pci_default_read_config(dev, PCI_CACHE_LINE_SIZE, 1);
    uint32_t pci_status = pci_default_read_config(dev, PCI_STATUS, 2);
    gchar *loc_code;

    _FDT(offset = fdt_add_subnode(fdt, parent_offset, nodename));

    /* in accordance with PAPR+ v2.7 13.6.3, Table 181 */
    _FDT(fdt_setprop_cell(fdt, offset, "vendor-id", vendor_id));
    _FDT(fdt_setprop_cell(fdt, offset, "device-id", device_id));
    _FDT(fdt_setprop_cell(fdt, offset, "revision-id", revision_id));

    _FDT(fdt_setprop_cell(fdt, offset, "class-code", ccode));
    if (irq_pin) {
        _FDT(fdt_setprop_cell(fdt, offset, "interrupts", irq_pin));
    }

    if (subsystem_id) {
        _FDT(fdt_setprop_cell(fdt, offset, "subsystem-id", subsystem_id));
    }

    if (subsystem_vendor_id) {
        _FDT(fdt_setprop_cell(fdt, offset, "subsystem-vendor-id",
                              subsystem_vendor_id));
    }

    _FDT(fdt_setprop_cell(fdt, offset, "cache-line-size", cache_line_size));


    /* the following fdt cells are masked off the pci status register */
    _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));
    }

    loc_code = spapr_phb_get_loc_code(sphb, dev);
    _FDT(fdt_setprop_string(fdt, offset, "ibm,loc-code", loc_code));
    g_free(loc_code);

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

    if (msi_present(dev)) {
        uint32_t max_msi = msi_nr_vectors_allocated(dev);
        if (max_msi) {
            _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi", max_msi));
        }
    }
    if (msix_present(dev)) {
        uint32_t 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));

    if (sphb->pcie_ecs && pci_is_express(dev)) {
        _FDT(fdt_setprop_cell(fdt, offset, "ibm,pci-config-space-type", 0x1));
    }

    spapr_phb_nvgpu_populate_pcidev_dt(dev, fdt, offset, sphb);

    if (!pc->is_bridge) {
        /* Properties only for non-bridges */
        uint32_t min_grant = pci_default_read_config(dev, PCI_MIN_GNT, 1);
        uint32_t max_latency = pci_default_read_config(dev, PCI_MAX_LAT, 1);
        _FDT(fdt_setprop_cell(fdt, offset, "min-grant", min_grant));
        _FDT(fdt_setprop_cell(fdt, offset, "max-latency", max_latency));
        return offset;
    } else {
        PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(dev));

        return spapr_dt_pci_bus(sphb, sec_bus, fdt, offset);
    }
}

/* Callback to be called during DRC release. */
void spapr_phb_remove_pci_device_cb(DeviceState *dev)
{
    HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);

    hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
    object_unparent(OBJECT(dev));
}

int spapr_pci_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
                          void *fdt, int *fdt_start_offset, Error **errp)
{
    HotplugHandler *plug_handler = qdev_get_hotplug_handler(drc->dev);
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(plug_handler);
    PCIDevice *pdev = PCI_DEVICE(drc->dev);

    *fdt_start_offset = spapr_dt_pci_device(sphb, pdev, fdt, 0);
    return 0;
}

static void spapr_pci_bridge_plug(SpaprPhbState *phb,
                                  PCIBridge *bridge)
{
    PCIBus *bus = pci_bridge_get_sec_bus(bridge);

    add_drcs(phb, bus);
}

/* Returns non-zero if the value of "chassis_nr" is already in use */
static int check_chassis_nr(Object *obj, void *opaque)
{
    int new_chassis_nr =
        object_property_get_uint(opaque, "chassis_nr", &error_abort);
    int chassis_nr =
        object_property_get_uint(obj, "chassis_nr", NULL);

    if (!object_dynamic_cast(obj, TYPE_PCI_BRIDGE)) {
        return 0;
    }

    /* Skip unsupported bridge types */
    if (!chassis_nr) {
        return 0;
    }

    /* Skip self */
    if (obj == opaque) {
        return 0;
    }

    return chassis_nr == new_chassis_nr;
}

static bool bridge_has_valid_chassis_nr(Object *bridge, Error **errp)
{
    int chassis_nr =
        object_property_get_uint(bridge, "chassis_nr", NULL);

    /*
     * slotid_cap_init() already ensures that "chassis_nr" isn't null for
     * standard PCI bridges, so this really tells if "chassis_nr" is present
     * or not.
     */
    if (!chassis_nr) {
        error_setg(errp, "PCI Bridge lacks a \"chassis_nr\" property");
        error_append_hint(errp, "Try -device pci-bridge instead.\n");
        return false;
    }

    /* We want unique values for "chassis_nr" */
    if (object_child_foreach_recursive(object_get_root(), check_chassis_nr,
                                       bridge)) {
        error_setg(errp, "Bridge chassis %d already in use", chassis_nr);
        return false;
    }

    return true;
}

static void spapr_pci_pre_plug(HotplugHandler *plug_handler,
                               DeviceState *plugged_dev, Error **errp)
{
    SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
    PCIDevice *pdev = PCI_DEVICE(plugged_dev);
    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(plugged_dev);
    SpaprDrc *drc = drc_from_dev(phb, pdev);
    PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
    uint32_t slotnr = PCI_SLOT(pdev->devfn);

    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;
        }
    }

    if (pc->is_bridge) {
        if (!bridge_has_valid_chassis_nr(OBJECT(plugged_dev), errp)) {
            return;
        }
    }

    /* Following the QEMU convention used for PCIe multifunction
     * hotplug, we do not allow functions to be hotplugged to a
     * slot that already has function 0 present
     */
    if (plugged_dev->hotplugged && bus->devices[PCI_DEVFN(slotnr, 0)] &&
        PCI_FUNC(pdev->devfn) != 0) {
        error_setg(errp, "PCI: slot %d function 0 already occupied by %s,"
                   " additional functions can no longer be exposed to guest.",
                   slotnr, bus->devices[PCI_DEVFN(slotnr, 0)]->name);
    }

    if (drc && drc->dev) {
        error_setg(errp, "PCI: slot %d already occupied by %s", slotnr,
                   pci_get_function_0(PCI_DEVICE(drc->dev))->name);
        return;
    }
}

static void spapr_pci_plug(HotplugHandler *plug_handler,
                           DeviceState *plugged_dev, Error **errp)
{
    SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
    PCIDevice *pdev = PCI_DEVICE(plugged_dev);
    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(plugged_dev);
    SpaprDrc *drc = drc_from_dev(phb, pdev);
    uint32_t slotnr = PCI_SLOT(pdev->devfn);

    /*
     * If DR is disabled we don't need to do anything in the case of
     * hotplug or coldplug callbacks.
     */
    if (!phb->dr_enabled) {
        return;
    }

    g_assert(drc);

    if (pc->is_bridge) {
        spapr_pci_bridge_plug(phb, PCI_BRIDGE(plugged_dev));
    }

    /* spapr_pci_pre_plug() already checked the DRC is attachable */
    spapr_drc_attach(drc, DEVICE(pdev));

    /* If this is function 0, signal hotplug for all the device functions.
     * Otherwise defer sending the hotplug event.
     */
    if (!spapr_drc_hotplugged(plugged_dev)) {
        spapr_drc_reset(drc);
    } else if (PCI_FUNC(pdev->devfn) == 0) {
        int i;
        uint8_t chassis = chassis_from_bus(pci_get_bus(pdev));

        for (i = 0; i < 8; i++) {
            SpaprDrc *func_drc;
            SpaprDrcClass *func_drck;
            SpaprDREntitySense state;

            func_drc = drc_from_devfn(phb, chassis, PCI_DEVFN(slotnr, i));
            func_drck = SPAPR_DR_CONNECTOR_GET_CLASS(func_drc);
            state = func_drck->dr_entity_sense(func_drc);

            if (state == SPAPR_DR_ENTITY_SENSE_PRESENT) {
                spapr_hotplug_req_add_by_index(func_drc);
            }
        }
    }
}

static void spapr_pci_bridge_unplug(SpaprPhbState *phb,
                                    PCIBridge *bridge)
{
    PCIBus *bus = pci_bridge_get_sec_bus(bridge);

    remove_drcs(phb, bus);
}

static void spapr_pci_unplug(HotplugHandler *plug_handler,
                             DeviceState *plugged_dev, Error **errp)
{
    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(plugged_dev);
    SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));

    /* 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(plugged_dev));

    if (pc->is_bridge) {
        spapr_pci_bridge_unplug(phb, PCI_BRIDGE(plugged_dev));
        return;
    }

    qdev_unrealize(plugged_dev);
}

static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
                                     DeviceState *plugged_dev, Error **errp)
{
    SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
    PCIDevice *pdev = PCI_DEVICE(plugged_dev);
    SpaprDrc *drc = drc_from_dev(phb, pdev);

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

    g_assert(drc);
    g_assert(drc->dev == plugged_dev);

    if (!spapr_drc_unplug_requested(drc)) {
        PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(plugged_dev);
        uint32_t slotnr = PCI_SLOT(pdev->devfn);
        SpaprDrc *func_drc;
        SpaprDrcClass *func_drck;
        SpaprDREntitySense state;
        int i;
        uint8_t chassis = chassis_from_bus(pci_get_bus(pdev));

        if (pc->is_bridge) {
            error_setg(errp, "PCI: Hot unplug of PCI bridges not supported");
            return;
        }
        if (object_property_get_uint(OBJECT(pdev), "nvlink2-tgt", NULL)) {
            error_setg(errp, "PCI: Cannot unplug NVLink2 devices");
            return;
        }

        /* ensure any other present functions are pending unplug */
        if (PCI_FUNC(pdev->devfn) == 0) {
            for (i = 1; i < 8; i++) {
                func_drc = drc_from_devfn(phb, chassis, PCI_DEVFN(slotnr, i));
                func_drck = SPAPR_DR_CONNECTOR_GET_CLASS(func_drc);
                state = func_drck->dr_entity_sense(func_drc);
                if (state == SPAPR_DR_ENTITY_SENSE_PRESENT
                    && !spapr_drc_unplug_requested(func_drc)) {
                    /*
                     * Attempting to remove function 0 of a multifunction
                     * device will will cascade into removing all child
                     * functions, even if their unplug weren't requested
                     * beforehand.
                     */
                    spapr_drc_unplug_request(func_drc);
                }
            }
        }

        spapr_drc_unplug_request(drc);

        /* if this isn't func 0, defer unplug event. otherwise signal removal
         * for all present functions
         */
        if (PCI_FUNC(pdev->devfn) == 0) {
            for (i = 7; i >= 0; i--) {
                func_drc = drc_from_devfn(phb, chassis, PCI_DEVFN(slotnr, i));
                func_drck = SPAPR_DR_CONNECTOR_GET_CLASS(func_drc);
                state = func_drck->dr_entity_sense(func_drc);
                if (state == SPAPR_DR_ENTITY_SENSE_PRESENT) {
                    spapr_hotplug_req_remove_by_index(func_drc);
                }
            }
        }
    } else {
        error_setg(errp,
                   "PCI device unplug already in progress for device %s",
                   drc->dev->id);
    }
}

static void spapr_phb_finalizefn(Object *obj)
{
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(obj);

    g_free(sphb->dtbusname);
    sphb->dtbusname = NULL;
}

static void spapr_phb_unrealize(DeviceState *dev)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
    SysBusDevice *s = SYS_BUS_DEVICE(dev);
    PCIHostState *phb = PCI_HOST_BRIDGE(s);
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(phb);
    SpaprTceTable *tcet;
    int i;
    const unsigned windows_supported = spapr_phb_windows_supported(sphb);

    spapr_phb_nvgpu_free(sphb);

    if (sphb->msi) {
        g_hash_table_unref(sphb->msi);
        sphb->msi = NULL;
    }

    /*
     * Remove IO/MMIO subregions and aliases, rest should get cleaned
     * via PHB's unrealize->object_finalize
     */
    for (i = windows_supported - 1; i >= 0; i--) {
        tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[i]);
        if (tcet) {
            memory_region_del_subregion(&sphb->iommu_root,
                                        spapr_tce_get_iommu(tcet));
        }
    }

    remove_drcs(sphb, phb->bus);

    for (i = PCI_NUM_PINS - 1; i >= 0; i--) {
        if (sphb->lsi_table[i].irq) {
            spapr_irq_free(spapr, sphb->lsi_table[i].irq, 1);
            sphb->lsi_table[i].irq = 0;
        }
    }

    QLIST_REMOVE(sphb, list);

    memory_region_del_subregion(&sphb->iommu_root, &sphb->msiwindow);

    /*
     * An attached PCI device may have memory listeners, eg. VFIO PCI. We have
     * unmapped all sections. Remove the listeners now, before destroying the
     * address space.
     */
    address_space_remove_listeners(&sphb->iommu_as);
    address_space_destroy(&sphb->iommu_as);

    qbus_set_hotplug_handler(BUS(phb->bus), NULL);
    pci_unregister_root_bus(phb->bus);

    memory_region_del_subregion(get_system_memory(), &sphb->iowindow);
    if (sphb->mem64_win_pciaddr != (hwaddr)-1) {
        memory_region_del_subregion(get_system_memory(), &sphb->mem64window);
    }
    memory_region_del_subregion(get_system_memory(), &sphb->mem32window);
}

static void spapr_phb_destroy_msi(gpointer opaque)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
    SpaprPciMsi *msi = opaque;

    if (!smc->legacy_irq_allocation) {
        spapr_irq_msi_free(spapr, msi->first_irq, msi->num);
    }
    spapr_irq_free(spapr, msi->first_irq, msi->num);
    g_free(msi);
}

static void spapr_phb_realize(DeviceState *dev, Error **errp)
{
    ERRP_GUARD();
    /* We don't use SPAPR_MACHINE() in order to exit gracefully if the user
     * tries to add a sPAPR PHB to a non-pseries machine.
     */
    SpaprMachineState *spapr =
        (SpaprMachineState *) object_dynamic_cast(qdev_get_machine(),
                                                  TYPE_SPAPR_MACHINE);
    SpaprMachineClass *smc = spapr ? SPAPR_MACHINE_GET_CLASS(spapr) : NULL;
    SysBusDevice *s = SYS_BUS_DEVICE(dev);
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
    PCIHostState *phb = PCI_HOST_BRIDGE(s);
    MachineState *ms = MACHINE(spapr);
    char *namebuf;
    int i;
    PCIBus *bus;
    uint64_t msi_window_size = 4096;
    SpaprTceTable *tcet;
    const unsigned windows_supported = spapr_phb_windows_supported(sphb);

    if (!spapr) {
        error_setg(errp, TYPE_SPAPR_PCI_HOST_BRIDGE " needs a pseries machine");
        return;
    }

    assert(sphb->index != (uint32_t)-1); /* checked in spapr_phb_pre_plug() */

    if (sphb->mem64_win_size != 0) {
        if (sphb->mem_win_size > SPAPR_PCI_MEM32_WIN_SIZE) {
            error_setg(errp, "32-bit memory window of size 0x%"HWADDR_PRIx
                       " (max 2 GiB)", sphb->mem_win_size);
            return;
        }

        /* 64-bit window defaults to identity mapping */
        sphb->mem64_win_pciaddr = sphb->mem64_win_addr;
    } else if (sphb->mem_win_size > SPAPR_PCI_MEM32_WIN_SIZE) {
        /*
         * For compatibility with old configuration, if no 64-bit MMIO
         * window is specified, but the ordinary (32-bit) memory
         * window is specified as > 2GiB, we treat it as a 2GiB 32-bit
         * window, with a 64-bit MMIO window following on immediately
         * afterwards
         */
        sphb->mem64_win_size = sphb->mem_win_size - SPAPR_PCI_MEM32_WIN_SIZE;
        sphb->mem64_win_addr = sphb->mem_win_addr + SPAPR_PCI_MEM32_WIN_SIZE;
        sphb->mem64_win_pciaddr =
            SPAPR_PCI_MEM_WIN_BUS_OFFSET + SPAPR_PCI_MEM32_WIN_SIZE;
        sphb->mem_win_size = SPAPR_PCI_MEM32_WIN_SIZE;
    }

    if (spapr_pci_find_phb(spapr, sphb->buid)) {
        SpaprPhbState *s;

        error_setg(errp, "PCI host bridges must have unique indexes");
        error_append_hint(errp, "The following indexes are already in use:");
        QLIST_FOREACH(s, &spapr->phbs, list) {
            error_append_hint(errp, " %d", s->index);
        }
        error_append_hint(errp, "\nTry another value for the index property\n");
        return;
    }

    if (sphb->numa_node != -1 &&
        (sphb->numa_node >= MAX_NODES ||
         !ms->numa_state->nodes[sphb->numa_node].present)) {
        error_setg(errp, "Invalid NUMA node ID for PCI host bridge");
        return;
    }

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

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

    namebuf = g_strdup_printf("%s.mmio32-alias", sphb->dtbusname);
    memory_region_init_alias(&sphb->mem32window, OBJECT(sphb),
                             namebuf, &sphb->memspace,
                             SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size);
    g_free(namebuf);
    memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,
                                &sphb->mem32window);

    if (sphb->mem64_win_size != 0) {
        namebuf = g_strdup_printf("%s.mmio64-alias", sphb->dtbusname);
        memory_region_init_alias(&sphb->mem64window, OBJECT(sphb),
                                 namebuf, &sphb->memspace,
                                 sphb->mem64_win_pciaddr, sphb->mem64_win_size);
        g_free(namebuf);

        memory_region_add_subregion(get_system_memory(),
                                    sphb->mem64_win_addr,
                                    &sphb->mem64window);
    }

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

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

    bus = pci_register_root_bus(dev, NULL,
                                pci_spapr_set_irq, pci_swizzle_map_irq_fn, sphb,
                                &sphb->memspace, &sphb->iospace,
                                PCI_DEVFN(0, 0), PCI_NUM_PINS,
                                TYPE_PCI_BUS);

    /*
     * Despite resembling a vanilla PCI bus in most ways, the PAPR
     * para-virtualized PCI bus *does* permit PCI-E extended config
     * space access
     */
    if (sphb->pcie_ecs) {
        bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
    }
    phb->bus = bus;
    qbus_set_hotplug_handler(BUS(phb->bus), OBJECT(sphb));

    /*
     * 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.
     */
    namebuf = g_strdup_printf("%s.iommu-root", sphb->dtbusname);
    memory_region_init(&sphb->iommu_root, OBJECT(sphb),
                       namebuf, UINT64_MAX);
    g_free(namebuf);
    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.
     */
    if (kvm_enabled()) {
        msi_window_size = qemu_real_host_page_size;
    }

    memory_region_init_io(&sphb->msiwindow, OBJECT(sphb), &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++) {
        int irq = SPAPR_IRQ_PCI_LSI + sphb->index * PCI_NUM_PINS + i;

        if (smc->legacy_irq_allocation) {
            irq = spapr_irq_findone(spapr, errp);
            if (irq < 0) {
                error_prepend(errp, "can't allocate LSIs: ");
                /*
                 * Older machines will never support PHB hotplug, ie, this is an
                 * init only path and QEMU will terminate. No need to rollback.
                 */
                return;
            }
        }

        if (spapr_irq_claim(spapr, irq, true, errp) < 0) {
            error_prepend(errp, "can't allocate LSIs: ");
            goto unrealize;
        }

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

    /* allocate connectors for child PCI devices */
    add_drcs(sphb, phb->bus);

    /* DMA setup */
    for (i = 0; i < windows_supported; ++i) {
        tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn[i]);
        if (!tcet) {
            error_setg(errp, "Creating window#%d failed for %s",
                       i, sphb->dtbusname);
            goto unrealize;
        }
        memory_region_add_subregion(&sphb->iommu_root, 0,
                                    spapr_tce_get_iommu(tcet));
    }

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

unrealize:
    spapr_phb_unrealize(dev);
}

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

    if (dev) {
        device_legacy_reset(dev);
    }

    return 0;
}

void spapr_phb_dma_reset(SpaprPhbState *sphb)
{
    int i;
    SpaprTceTable *tcet;

    for (i = 0; i < SPAPR_PCI_DMA_MAX_WINDOWS; ++i) {
        tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[i]);

        if (tcet && tcet->nb_table) {
            spapr_tce_table_disable(tcet);
        }
    }

    /* Register default 32bit DMA window */
    tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[0]);
    spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr,
                           sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT);
}

static void spapr_phb_reset(DeviceState *qdev)
{
    SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
    Error *err = NULL;

    spapr_phb_dma_reset(sphb);
    spapr_phb_nvgpu_free(sphb);
    spapr_phb_nvgpu_setup(sphb, &err);
    if (err) {
        error_report_err(err);
    }

    /* Reset the IOMMU state */
    object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL);

    if (spapr_phb_eeh_available(SPAPR_PCI_HOST_BRIDGE(qdev))) {
        spapr_phb_vfio_reset(qdev);
    }

    g_hash_table_remove_all(sphb->msi);
}

static Property spapr_phb_properties[] = {
    DEFINE_PROP_UINT32("index", SpaprPhbState, index, -1),
    DEFINE_PROP_UINT64("mem_win_size", SpaprPhbState, mem_win_size,
                       SPAPR_PCI_MEM32_WIN_SIZE),
    DEFINE_PROP_UINT64("mem64_win_size", SpaprPhbState, mem64_win_size,
                       SPAPR_PCI_MEM64_WIN_SIZE),
    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_UINT64("dma64_win_addr", SpaprPhbState, dma64_win_addr,
                       0x800000000000000ULL),
    DEFINE_PROP_BOOL("ddw", SpaprPhbState, ddw_enabled, true),
    DEFINE_PROP_UINT64("pgsz", SpaprPhbState, page_size_mask,
                       (1ULL << 12) | (1ULL << 16)
                       | (1ULL << 21) | (1ULL << 24)),
    DEFINE_PROP_UINT32("numa_node", SpaprPhbState, numa_node, -1),
    DEFINE_PROP_BOOL("pre-2.8-migration", SpaprPhbState,
                     pre_2_8_migration, false),
    DEFINE_PROP_BOOL("pcie-extended-configuration-space", SpaprPhbState,
                     pcie_ecs, true),
    DEFINE_PROP_UINT64("gpa", SpaprPhbState, nv2_gpa_win_addr, 0),
    DEFINE_PROP_UINT64("atsd", SpaprPhbState, nv2_atsd_win_addr, 0),
    DEFINE_PROP_BOOL("pre-5.1-associativity", SpaprPhbState,
                     pre_5_1_assoc, false),
    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, SpaprPciLsi, NULL),

        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, SpaprPciMsiMig),
        VMSTATE_UINT32(value.first_irq, SpaprPciMsiMig),
        VMSTATE_UINT32(value.num, SpaprPciMsiMig),
        VMSTATE_END_OF_LIST()
    },
};

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

    if (sphb->pre_2_8_migration) {
        sphb->mig_liobn = sphb->dma_liobn[0];
        sphb->mig_mem_win_addr = sphb->mem_win_addr;
        sphb->mig_mem_win_size = sphb->mem_win_size;
        sphb->mig_io_win_addr = sphb->io_win_addr;
        sphb->mig_io_win_size = sphb->io_win_size;

        if ((sphb->mem64_win_size != 0)
            && (sphb->mem64_win_addr
                == (sphb->mem_win_addr + sphb->mem_win_size))) {
            sphb->mig_mem_win_size += sphb->mem64_win_size;
        }
    }

    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 0;
    }
    sphb->msi_devs = g_new(SpaprPciMsiMig, sphb->msi_devs_num);

    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 = *(SpaprPciMsi *) value;
    }

    return 0;
}

static int spapr_pci_post_save(void *opaque)
{
    SpaprPhbState *sphb = opaque;

    g_free(sphb->msi_devs);
    sphb->msi_devs = NULL;
    sphb->msi_devs_num = 0;
    return 0;
}

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 bool pre_2_8_migration(void *opaque, int version_id)
{
    SpaprPhbState *sphb = opaque;

    return sphb->pre_2_8_migration;
}

static const VMStateDescription vmstate_spapr_pci = {
    .name = "spapr_pci",
    .version_id = 2,
    .minimum_version_id = 2,
    .pre_save = spapr_pci_pre_save,
    .post_save = spapr_pci_post_save,
    .post_load = spapr_pci_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64_EQUAL(buid, SpaprPhbState, NULL),
        VMSTATE_UINT32_TEST(mig_liobn, SpaprPhbState, pre_2_8_migration),
        VMSTATE_UINT64_TEST(mig_mem_win_addr, SpaprPhbState, pre_2_8_migration),
        VMSTATE_UINT64_TEST(mig_mem_win_size, SpaprPhbState, pre_2_8_migration),
        VMSTATE_UINT64_TEST(mig_io_win_addr, SpaprPhbState, pre_2_8_migration),
        VMSTATE_UINT64_TEST(mig_io_win_size, SpaprPhbState, pre_2_8_migration),
        VMSTATE_STRUCT_ARRAY(lsi_table, SpaprPhbState, PCI_NUM_PINS, 0,
                             vmstate_spapr_pci_lsi, SpaprPciLsi),
        VMSTATE_INT32(msi_devs_num, SpaprPhbState),
        VMSTATE_STRUCT_VARRAY_ALLOC(msi_devs, SpaprPhbState, msi_devs_num, 0,
                                    vmstate_spapr_pci_msi, SpaprPciMsiMig),
        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);
    HotplugHandlerClass *hp = HOTPLUG_HANDLER_CLASS(klass);

    hc->root_bus_path = spapr_phb_root_bus_path;
    dc->realize = spapr_phb_realize;
    dc->unrealize = spapr_phb_unrealize;
    device_class_set_props(dc, spapr_phb_properties);
    dc->reset = spapr_phb_reset;
    dc->vmsd = &vmstate_spapr_pci;
    /* Supported by TYPE_SPAPR_MACHINE */
    dc->user_creatable = true;
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    hp->pre_plug = spapr_pci_pre_plug;
    hp->plug = spapr_pci_plug;
    hp->unplug = spapr_pci_unplug;
    hp->unplug_request = spapr_pci_unplug_request;
}

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

static void spapr_phb_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
                                           void *opaque)
{
    unsigned int *bus_no = opaque;
    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, pci_dev_bus_num(pdev), 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_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_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb,
                 uint32_t intc_phandle, void *fdt, int *node_offset)
{
    int bus_off, i, j, ret;
    uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
    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(phb->mem_win_size),
        },
        {
            cpu_to_be32(b_ss(3)), cpu_to_be64(phb->mem64_win_pciaddr),
            cpu_to_be64(phb->mem64_win_addr),
            cpu_to_be64(phb->mem64_win_size),
        },
    };
    const unsigned sizeof_ranges =
        (phb->mem64_win_size ? 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];
    uint32_t ddw_applicable[] = {
        cpu_to_be32(RTAS_IBM_QUERY_PE_DMA_WINDOW),
        cpu_to_be32(RTAS_IBM_CREATE_PE_DMA_WINDOW),
        cpu_to_be32(RTAS_IBM_REMOVE_PE_DMA_WINDOW)
    };
    uint32_t ddw_extensions[] = {
        cpu_to_be32(1),
        cpu_to_be32(RTAS_IBM_RESET_PE_DMA_WINDOW)
    };
    SpaprTceTable *tcet;
    SpaprDrc *drc;
    Error *err = NULL;

    /* Start populating the FDT */
    _FDT(bus_off = fdt_add_subnode(fdt, 0, phb->dtbusname));
    if (node_offset) {
        *node_offset = 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, "#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",
                          spapr_irq_nr_msis(spapr)));

    /* Dynamic DMA window */
    if (phb->ddw_enabled) {
        _FDT(fdt_setprop(fdt, bus_off, "ibm,ddw-applicable", &ddw_applicable,
                         sizeof(ddw_applicable)));
        _FDT(fdt_setprop(fdt, bus_off, "ibm,ddw-extensions",
                         &ddw_extensions, sizeof(ddw_extensions)));
    }

    /* Advertise NUMA via ibm,associativity */
    if (phb->numa_node != -1) {
        spapr_numa_write_associativity_dt(spapr, fdt, bus_off, phb->numa_node);
    }

    /* Build the interrupt-map, this must matches what is done
     * in pci_swizzle_map_irq_fn
     */
    _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_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(intc_phandle);
            spapr_dt_irq(&irqmap[5], phb->lsi_table[lsi_num].irq, true);
        }
    }
    /* Write interrupt map */
    _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map,
                     sizeof(interrupt_map)));

    tcet = spapr_tce_find_by_liobn(phb->dma_liobn[0]);
    if (!tcet) {
        return -1;
    }
    spapr_dma_dt(fdt, bus_off, "ibm,dma-window",
                 tcet->liobn, tcet->bus_offset,
                 tcet->nb_table << tcet->page_shift);

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, phb->index);
    if (drc) {
        uint32_t drc_index = cpu_to_be32(spapr_drc_index(drc));

        _FDT(fdt_setprop(fdt, bus_off, "ibm,my-drc-index", &drc_index,
                         sizeof(drc_index)));
    }

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

    /* Walk the bridge and subordinate buses */
    ret = spapr_dt_pci_bus(phb, PCI_HOST_BRIDGE(phb)->bus, fdt, bus_off);
    if (ret < 0) {
        return ret;
    }

    spapr_phb_nvgpu_populate_dt(phb, fdt, bus_off, &err);
    if (err) {
        error_report_err(err);
    }
    spapr_phb_nvgpu_ram_populate_dt(phb, fdt);

    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_nonbroken) {
        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_dynamic_cast(OBJECT(dev), "bochs-display")
        || object_dynamic_cast(OBJECT(dev), "virtio-vga")) {
        object_property_set_bool(OBJECT(dev), "big-endian-framebuffer", be,
                                 &error_abort);
    }
    return 0;
}

void spapr_pci_switch_vga(SpaprMachineState *spapr, bool big_endian)
{
    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);
    }
}
