/*
 * QEMU PowerPC PowerNV Processor Service Interface (PSI) model
 *
 * Copyright (c) 2015-2017, IBM Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "exec/address-spaces.h"
#include "hw/irq.h"
#include "target/ppc/cpu.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "sysemu/reset.h"
#include "qapi/error.h"
#include "monitor/monitor.h"


#include "hw/ppc/fdt.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_xscom.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/pnv_psi.h"

#include <libfdt.h>

#define PSIHB_XSCOM_FIR_RW      0x00
#define PSIHB_XSCOM_FIR_AND     0x01
#define PSIHB_XSCOM_FIR_OR      0x02
#define PSIHB_XSCOM_FIRMASK_RW  0x03
#define PSIHB_XSCOM_FIRMASK_AND 0x04
#define PSIHB_XSCOM_FIRMASK_OR  0x05
#define PSIHB_XSCOM_FIRACT0     0x06
#define PSIHB_XSCOM_FIRACT1     0x07

/* Host Bridge Base Address Register */
#define PSIHB_XSCOM_BAR         0x0a
#define   PSIHB_BAR_EN                  0x0000000000000001ull

/* FSP Base Address Register */
#define PSIHB_XSCOM_FSPBAR      0x0b

/* PSI Host Bridge Control/Status Register */
#define PSIHB_XSCOM_CR          0x0e
#define   PSIHB_CR_FSP_CMD_ENABLE       0x8000000000000000ull
#define   PSIHB_CR_FSP_MMIO_ENABLE      0x4000000000000000ull
#define   PSIHB_CR_FSP_IRQ_ENABLE       0x1000000000000000ull
#define   PSIHB_CR_FSP_ERR_RSP_ENABLE   0x0800000000000000ull
#define   PSIHB_CR_PSI_LINK_ENABLE      0x0400000000000000ull
#define   PSIHB_CR_FSP_RESET            0x0200000000000000ull
#define   PSIHB_CR_PSIHB_RESET          0x0100000000000000ull
#define   PSIHB_CR_PSI_IRQ              0x0000800000000000ull
#define   PSIHB_CR_FSP_IRQ              0x0000400000000000ull
#define   PSIHB_CR_FSP_LINK_ACTIVE      0x0000200000000000ull
#define   PSIHB_CR_IRQ_CMD_EXPECT       0x0000010000000000ull
          /* and more ... */

/* PSIHB Status / Error Mask Register */
#define PSIHB_XSCOM_SEMR        0x0f

/* XIVR, to signal interrupts to the CEC firmware. more XIVR below. */
#define PSIHB_XSCOM_XIVR_FSP    0x10
#define   PSIHB_XIVR_SERVER_SH          40
#define   PSIHB_XIVR_SERVER_MSK         (0xffffull << PSIHB_XIVR_SERVER_SH)
#define   PSIHB_XIVR_PRIO_SH            32
#define   PSIHB_XIVR_PRIO_MSK           (0xffull << PSIHB_XIVR_PRIO_SH)
#define   PSIHB_XIVR_SRC_SH             29
#define   PSIHB_XIVR_SRC_MSK            (0x7ull << PSIHB_XIVR_SRC_SH)
#define   PSIHB_XIVR_PENDING            0x01000000ull

/* PSI Host Bridge Set Control/ Status Register */
#define PSIHB_XSCOM_SCR         0x12

/* PSI Host Bridge Clear Control/ Status Register */
#define PSIHB_XSCOM_CCR         0x13

/* DMA Upper Address Register */
#define PSIHB_XSCOM_DMA_UPADD   0x14

/* Interrupt Status */
#define PSIHB_XSCOM_IRQ_STAT    0x15
#define   PSIHB_IRQ_STAT_OCC            0x0000001000000000ull
#define   PSIHB_IRQ_STAT_FSI            0x0000000800000000ull
#define   PSIHB_IRQ_STAT_LPCI2C         0x0000000400000000ull
#define   PSIHB_IRQ_STAT_LOCERR         0x0000000200000000ull
#define   PSIHB_IRQ_STAT_EXT            0x0000000100000000ull

/* remaining XIVR */
#define PSIHB_XSCOM_XIVR_OCC    0x16
#define PSIHB_XSCOM_XIVR_FSI    0x17
#define PSIHB_XSCOM_XIVR_LPCI2C 0x18
#define PSIHB_XSCOM_XIVR_LOCERR 0x19
#define PSIHB_XSCOM_XIVR_EXT    0x1a

/* Interrupt Requester Source Compare Register */
#define PSIHB_XSCOM_IRSN        0x1b
#define   PSIHB_IRSN_COMP_SH            45
#define   PSIHB_IRSN_COMP_MSK           (0x7ffffull << PSIHB_IRSN_COMP_SH)
#define   PSIHB_IRSN_IRQ_MUX            0x0000000800000000ull
#define   PSIHB_IRSN_IRQ_RESET          0x0000000400000000ull
#define   PSIHB_IRSN_DOWNSTREAM_EN      0x0000000200000000ull
#define   PSIHB_IRSN_UPSTREAM_EN        0x0000000100000000ull
#define   PSIHB_IRSN_COMPMASK_SH        13
#define   PSIHB_IRSN_COMPMASK_MSK       (0x7ffffull << PSIHB_IRSN_COMPMASK_SH)

#define PSIHB_BAR_MASK                  0x0003fffffff00000ull
#define PSIHB_FSPBAR_MASK               0x0003ffff00000000ull

#define PSIHB9_BAR_MASK                 0x00fffffffff00000ull
#define PSIHB9_FSPBAR_MASK              0x00ffffff00000000ull

/* mmio address to xscom address */
#define PSIHB_REG(addr) (((addr) >> 3) + PSIHB_XSCOM_BAR)

/* xscom address to mmio address */
#define PSIHB_MMIO(reg) ((reg - PSIHB_XSCOM_BAR) << 3)

static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
{
    PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
    MemoryRegion *sysmem = get_system_memory();
    uint64_t old = psi->regs[PSIHB_XSCOM_BAR];

    psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);

    /* Update MR, always remove it first */
    if (old & PSIHB_BAR_EN) {
        memory_region_del_subregion(sysmem, &psi->regs_mr);
    }

    /* Then add it back if needed */
    if (bar & PSIHB_BAR_EN) {
        uint64_t addr = bar & ppc->bar_mask;
        memory_region_add_subregion(sysmem, addr, &psi->regs_mr);
    }
}

static void pnv_psi_update_fsp_mr(PnvPsi *psi)
{
    /* TODO: Update FSP MR if/when we support FSP BAR */
}

static void pnv_psi_set_cr(PnvPsi *psi, uint64_t cr)
{
    uint64_t old = psi->regs[PSIHB_XSCOM_CR];

    psi->regs[PSIHB_XSCOM_CR] = cr;

    /* Check some bit changes */
    if ((old ^ psi->regs[PSIHB_XSCOM_CR]) & PSIHB_CR_FSP_MMIO_ENABLE) {
        pnv_psi_update_fsp_mr(psi);
    }
}

static void pnv_psi_set_irsn(PnvPsi *psi, uint64_t val)
{
    ICSState *ics = &PNV8_PSI(psi)->ics;

    /* In this model we ignore the up/down enable bits for now
     * as SW doesn't use them (other than setting them at boot).
     * We ignore IRQ_MUX, its meaning isn't clear and we don't use
     * it and finally we ignore reset (XXX fix that ?)
     */
    psi->regs[PSIHB_XSCOM_IRSN] = val & (PSIHB_IRSN_COMP_MSK |
                                         PSIHB_IRSN_IRQ_MUX |
                                         PSIHB_IRSN_IRQ_RESET |
                                         PSIHB_IRSN_DOWNSTREAM_EN |
                                         PSIHB_IRSN_UPSTREAM_EN);

    /* We ignore the compare mask as well, our ICS emulation is too
     * simplistic to make any use if it, and we extract the offset
     * from the compare value
     */
    ics->offset = (val & PSIHB_IRSN_COMP_MSK) >> PSIHB_IRSN_COMP_SH;
}

/*
 * FSP and PSI interrupts are muxed under the same number.
 */
static const uint32_t xivr_regs[PSI_NUM_INTERRUPTS] = {
    [PSIHB_IRQ_FSP]       = PSIHB_XSCOM_XIVR_FSP,
    [PSIHB_IRQ_OCC]       = PSIHB_XSCOM_XIVR_OCC,
    [PSIHB_IRQ_FSI]       = PSIHB_XSCOM_XIVR_FSI,
    [PSIHB_IRQ_LPC_I2C]   = PSIHB_XSCOM_XIVR_LPCI2C,
    [PSIHB_IRQ_LOCAL_ERR] = PSIHB_XSCOM_XIVR_LOCERR,
    [PSIHB_IRQ_EXTERNAL]  = PSIHB_XSCOM_XIVR_EXT,
};

static const uint32_t stat_regs[PSI_NUM_INTERRUPTS] = {
    [PSIHB_IRQ_FSP]       = PSIHB_XSCOM_CR,
    [PSIHB_IRQ_OCC]       = PSIHB_XSCOM_IRQ_STAT,
    [PSIHB_IRQ_FSI]       = PSIHB_XSCOM_IRQ_STAT,
    [PSIHB_IRQ_LPC_I2C]   = PSIHB_XSCOM_IRQ_STAT,
    [PSIHB_IRQ_LOCAL_ERR] = PSIHB_XSCOM_IRQ_STAT,
    [PSIHB_IRQ_EXTERNAL]  = PSIHB_XSCOM_IRQ_STAT,
};

static const uint64_t stat_bits[PSI_NUM_INTERRUPTS] = {
    [PSIHB_IRQ_FSP]       = PSIHB_CR_FSP_IRQ,
    [PSIHB_IRQ_OCC]       = PSIHB_IRQ_STAT_OCC,
    [PSIHB_IRQ_FSI]       = PSIHB_IRQ_STAT_FSI,
    [PSIHB_IRQ_LPC_I2C]   = PSIHB_IRQ_STAT_LPCI2C,
    [PSIHB_IRQ_LOCAL_ERR] = PSIHB_IRQ_STAT_LOCERR,
    [PSIHB_IRQ_EXTERNAL]  = PSIHB_IRQ_STAT_EXT,
};

static void pnv_psi_power8_set_irq(void *opaque, int irq, int state)
{
    PnvPsi *psi = opaque;
    uint32_t xivr_reg;
    uint32_t stat_reg;
    uint32_t src;
    bool masked;

    xivr_reg = xivr_regs[irq];
    stat_reg = stat_regs[irq];

    src = (psi->regs[xivr_reg] & PSIHB_XIVR_SRC_MSK) >> PSIHB_XIVR_SRC_SH;
    if (state) {
        psi->regs[stat_reg] |= stat_bits[irq];
        /* TODO: optimization, check mask here. That means
         * re-evaluating when unmasking
         */
        qemu_irq_raise(psi->qirqs[src]);
    } else {
        psi->regs[stat_reg] &= ~stat_bits[irq];

        /* FSP and PSI are muxed so don't lower if either is still set */
        if (stat_reg != PSIHB_XSCOM_CR ||
            !(psi->regs[stat_reg] & (PSIHB_CR_PSI_IRQ | PSIHB_CR_FSP_IRQ))) {
            qemu_irq_lower(psi->qirqs[src]);
        } else {
            state = true;
        }
    }

    /* Note about the emulation of the pending bit: This isn't
     * entirely correct. The pending bit should be cleared when the
     * EOI has been received. However, we don't have callbacks on EOI
     * (especially not under KVM) so no way to emulate that properly,
     * so instead we just set that bit as the logical "output" of the
     * XIVR (ie pending & !masked)
     *
     * CLG: We could define a new ICS object with a custom eoi()
     * handler to clear the pending bit. But I am not sure this would
     * be useful for the software anyhow.
     */
    masked = (psi->regs[xivr_reg] & PSIHB_XIVR_PRIO_MSK) == PSIHB_XIVR_PRIO_MSK;
    if (state && !masked) {
        psi->regs[xivr_reg] |= PSIHB_XIVR_PENDING;
    } else {
        psi->regs[xivr_reg] &= ~PSIHB_XIVR_PENDING;
    }
}

static void pnv_psi_set_xivr(PnvPsi *psi, uint32_t reg, uint64_t val)
{
    ICSState *ics = &PNV8_PSI(psi)->ics;
    uint16_t server;
    uint8_t prio;
    uint8_t src;

    psi->regs[reg] = (psi->regs[reg] & PSIHB_XIVR_PENDING) |
            (val & (PSIHB_XIVR_SERVER_MSK |
                    PSIHB_XIVR_PRIO_MSK |
                    PSIHB_XIVR_SRC_MSK));
    val = psi->regs[reg];
    server = (val & PSIHB_XIVR_SERVER_MSK) >> PSIHB_XIVR_SERVER_SH;
    prio = (val & PSIHB_XIVR_PRIO_MSK) >> PSIHB_XIVR_PRIO_SH;
    src = (val & PSIHB_XIVR_SRC_MSK) >> PSIHB_XIVR_SRC_SH;

    if (src >= PSI_NUM_INTERRUPTS) {
        qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", src);
        return;
    }

    /* Remove pending bit if the IRQ is masked */
    if ((psi->regs[reg] & PSIHB_XIVR_PRIO_MSK) == PSIHB_XIVR_PRIO_MSK) {
        psi->regs[reg] &= ~PSIHB_XIVR_PENDING;
    }

    /* The low order 2 bits are the link pointer (Type II interrupts).
     * Shift back to get a valid IRQ server.
     */
    server >>= 2;

    /* Now because of source remapping, weird things can happen
     * if you change the source number dynamically, our simple ICS
     * doesn't deal with remapping. So we just poke a different
     * ICS entry based on what source number was written. This will
     * do for now but a more accurate implementation would instead
     * use a fixed server/prio and a remapper of the generated irq.
     */
    ics_write_xive(ics, src, server, prio, prio);
}

static uint64_t pnv_psi_reg_read(PnvPsi *psi, uint32_t offset, bool mmio)
{
    uint64_t val = 0xffffffffffffffffull;

    switch (offset) {
    case PSIHB_XSCOM_FIR_RW:
    case PSIHB_XSCOM_FIRACT0:
    case PSIHB_XSCOM_FIRACT1:
    case PSIHB_XSCOM_BAR:
    case PSIHB_XSCOM_FSPBAR:
    case PSIHB_XSCOM_CR:
    case PSIHB_XSCOM_XIVR_FSP:
    case PSIHB_XSCOM_XIVR_OCC:
    case PSIHB_XSCOM_XIVR_FSI:
    case PSIHB_XSCOM_XIVR_LPCI2C:
    case PSIHB_XSCOM_XIVR_LOCERR:
    case PSIHB_XSCOM_XIVR_EXT:
    case PSIHB_XSCOM_IRQ_STAT:
    case PSIHB_XSCOM_SEMR:
    case PSIHB_XSCOM_DMA_UPADD:
    case PSIHB_XSCOM_IRSN:
        val = psi->regs[offset];
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "PSI: read at 0x%" PRIx32 "\n", offset);
    }
    return val;
}

static void pnv_psi_reg_write(PnvPsi *psi, uint32_t offset, uint64_t val,
                              bool mmio)
{
    switch (offset) {
    case PSIHB_XSCOM_FIR_RW:
    case PSIHB_XSCOM_FIRACT0:
    case PSIHB_XSCOM_FIRACT1:
    case PSIHB_XSCOM_SEMR:
    case PSIHB_XSCOM_DMA_UPADD:
        psi->regs[offset] = val;
        break;
    case PSIHB_XSCOM_FIR_OR:
        psi->regs[PSIHB_XSCOM_FIR_RW] |= val;
        break;
    case PSIHB_XSCOM_FIR_AND:
        psi->regs[PSIHB_XSCOM_FIR_RW] &= val;
        break;
    case PSIHB_XSCOM_BAR:
        /* Only XSCOM can write this one */
        if (!mmio) {
            pnv_psi_set_bar(psi, val);
        } else {
            qemu_log_mask(LOG_GUEST_ERROR, "PSI: invalid write of BAR\n");
        }
        break;
    case PSIHB_XSCOM_FSPBAR:
        psi->regs[PSIHB_XSCOM_FSPBAR] = val & PSIHB_FSPBAR_MASK;
        pnv_psi_update_fsp_mr(psi);
        break;
    case PSIHB_XSCOM_CR:
        pnv_psi_set_cr(psi, val);
        break;
    case PSIHB_XSCOM_SCR:
        pnv_psi_set_cr(psi, psi->regs[PSIHB_XSCOM_CR] | val);
        break;
    case PSIHB_XSCOM_CCR:
        pnv_psi_set_cr(psi, psi->regs[PSIHB_XSCOM_CR] & ~val);
        break;
    case PSIHB_XSCOM_XIVR_FSP:
    case PSIHB_XSCOM_XIVR_OCC:
    case PSIHB_XSCOM_XIVR_FSI:
    case PSIHB_XSCOM_XIVR_LPCI2C:
    case PSIHB_XSCOM_XIVR_LOCERR:
    case PSIHB_XSCOM_XIVR_EXT:
        pnv_psi_set_xivr(psi, offset, val);
        break;
    case PSIHB_XSCOM_IRQ_STAT:
        /* Read only */
        qemu_log_mask(LOG_GUEST_ERROR, "PSI: invalid write of IRQ_STAT\n");
        break;
    case PSIHB_XSCOM_IRSN:
        pnv_psi_set_irsn(psi, val);
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "PSI: write at 0x%" PRIx32 "\n", offset);
    }
}

/*
 * The values of the registers when accessed through the MMIO region
 * follow the relation : xscom = (mmio + 0x50) >> 3
 */
static uint64_t pnv_psi_mmio_read(void *opaque, hwaddr addr, unsigned size)
{
    return pnv_psi_reg_read(opaque, PSIHB_REG(addr), true);
}

static void pnv_psi_mmio_write(void *opaque, hwaddr addr,
                              uint64_t val, unsigned size)
{
    pnv_psi_reg_write(opaque, PSIHB_REG(addr), val, true);
}

static const MemoryRegionOps psi_mmio_ops = {
    .read = pnv_psi_mmio_read,
    .write = pnv_psi_mmio_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .valid = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
};

static uint64_t pnv_psi_xscom_read(void *opaque, hwaddr addr, unsigned size)
{
    return pnv_psi_reg_read(opaque, addr >> 3, false);
}

static void pnv_psi_xscom_write(void *opaque, hwaddr addr,
                                uint64_t val, unsigned size)
{
    pnv_psi_reg_write(opaque, addr >> 3, val, false);
}

static const MemoryRegionOps pnv_psi_xscom_ops = {
    .read = pnv_psi_xscom_read,
    .write = pnv_psi_xscom_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .valid = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    }
};

static void pnv_psi_reset(DeviceState *dev)
{
    PnvPsi *psi = PNV_PSI(dev);

    memset(psi->regs, 0x0, sizeof(psi->regs));

    psi->regs[PSIHB_XSCOM_BAR] = psi->bar | PSIHB_BAR_EN;
}

static void pnv_psi_reset_handler(void *dev)
{
    device_cold_reset(DEVICE(dev));
}

static void pnv_psi_realize(DeviceState *dev, Error **errp)
{
    PnvPsi *psi = PNV_PSI(dev);

    /* Default BAR for MMIO region */
    pnv_psi_set_bar(psi, psi->bar | PSIHB_BAR_EN);

    qemu_register_reset(pnv_psi_reset_handler, dev);
}

static void pnv_psi_power8_instance_init(Object *obj)
{
    Pnv8Psi *psi8 = PNV8_PSI(obj);

    object_initialize_child(obj, "ics-psi", &psi8->ics, TYPE_ICS);
    object_property_add_alias(obj, ICS_PROP_XICS, OBJECT(&psi8->ics),
                              ICS_PROP_XICS);
}

static const uint8_t irq_to_xivr[] = {
    PSIHB_XSCOM_XIVR_FSP,
    PSIHB_XSCOM_XIVR_OCC,
    PSIHB_XSCOM_XIVR_FSI,
    PSIHB_XSCOM_XIVR_LPCI2C,
    PSIHB_XSCOM_XIVR_LOCERR,
    PSIHB_XSCOM_XIVR_EXT,
};

static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
{
    PnvPsi *psi = PNV_PSI(dev);
    ICSState *ics = &PNV8_PSI(psi)->ics;
    unsigned int i;

    /* Create PSI interrupt control source */
    if (!object_property_set_int(OBJECT(ics), "nr-irqs", PSI_NUM_INTERRUPTS,
                                 errp)) {
        return;
    }
    if (!qdev_realize(DEVICE(ics), NULL, errp)) {
        return;
    }

    for (i = 0; i < ics->nr_irqs; i++) {
        ics_set_irq_type(ics, i, true);
    }

    qdev_init_gpio_in(dev, pnv_psi_power8_set_irq, ics->nr_irqs);

    psi->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);

    /* XSCOM region for PSI registers */
    pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_xscom_ops,
                psi, "xscom-psi", PNV_XSCOM_PSIHB_SIZE);

    /* Initialize MMIO region */
    memory_region_init_io(&psi->regs_mr, OBJECT(dev), &psi_mmio_ops, psi,
                          "psihb", PNV_PSIHB_SIZE);

    /* Default sources in XIVR */
    for (i = 0; i < PSI_NUM_INTERRUPTS; i++) {
        uint8_t xivr = irq_to_xivr[i];
        psi->regs[xivr] = PSIHB_XIVR_PRIO_MSK |
            ((uint64_t) i << PSIHB_XIVR_SRC_SH);
    }

    pnv_psi_realize(dev, errp);
}

static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
{
    PnvPsiClass *ppc = PNV_PSI_GET_CLASS(dev);
    char *name;
    int offset;
    uint32_t reg[] = {
        cpu_to_be32(ppc->xscom_pcba),
        cpu_to_be32(ppc->xscom_size)
    };

    name = g_strdup_printf("psihb@%x", ppc->xscom_pcba);
    offset = fdt_add_subnode(fdt, xscom_offset, name);
    _FDT(offset);
    g_free(name);

    _FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
    _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
    _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
    _FDT(fdt_setprop(fdt, offset, "compatible", ppc->compat,
                     ppc->compat_size));
    return 0;
}

static Property pnv_psi_properties[] = {
    DEFINE_PROP_UINT64("bar", PnvPsi, bar, 0),
    DEFINE_PROP_UINT64("fsp-bar", PnvPsi, fsp_bar, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
    static const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x";

    dc->desc    = "PowerNV PSI Controller POWER8";
    dc->realize = pnv_psi_power8_realize;

    ppc->xscom_pcba = PNV_XSCOM_PSIHB_BASE;
    ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE;
    ppc->bar_mask   = PSIHB_BAR_MASK;
    ppc->compat     = compat;
    ppc->compat_size = sizeof(compat);
}

static const TypeInfo pnv_psi_power8_info = {
    .name          = TYPE_PNV8_PSI,
    .parent        = TYPE_PNV_PSI,
    .instance_size = sizeof(Pnv8Psi),
    .instance_init = pnv_psi_power8_instance_init,
    .class_init    = pnv_psi_power8_class_init,
};


/* Common registers */

#define PSIHB9_CR                       0x20
#define PSIHB9_SEMR                     0x28

/* P9 registers */

#define PSIHB9_INTERRUPT_CONTROL        0x58
#define   PSIHB9_IRQ_METHOD             PPC_BIT(0)
#define   PSIHB9_IRQ_RESET              PPC_BIT(1)
#define PSIHB9_ESB_CI_BASE              0x60
#define   PSIHB9_ESB_CI_ADDR_MASK       PPC_BITMASK(8, 47)
#define   PSIHB9_ESB_CI_VALID           PPC_BIT(63)
#define PSIHB9_ESB_NOTIF_ADDR           0x68
#define   PSIHB9_ESB_NOTIF_ADDR_MASK    PPC_BITMASK(8, 60)
#define   PSIHB9_ESB_NOTIF_VALID        PPC_BIT(63)
#define PSIHB9_IVT_OFFSET               0x70
#define   PSIHB9_IVT_OFF_SHIFT          32

#define PSIHB9_IRQ_LEVEL                0x78 /* assertion */
#define   PSIHB9_IRQ_LEVEL_PSI          PPC_BIT(0)
#define   PSIHB9_IRQ_LEVEL_OCC          PPC_BIT(1)
#define   PSIHB9_IRQ_LEVEL_FSI          PPC_BIT(2)
#define   PSIHB9_IRQ_LEVEL_LPCHC        PPC_BIT(3)
#define   PSIHB9_IRQ_LEVEL_LOCAL_ERR    PPC_BIT(4)
#define   PSIHB9_IRQ_LEVEL_GLOBAL_ERR   PPC_BIT(5)
#define   PSIHB9_IRQ_LEVEL_TPM          PPC_BIT(6)
#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ1    PPC_BIT(7)
#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ2    PPC_BIT(8)
#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ3    PPC_BIT(9)
#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ4    PPC_BIT(10)
#define   PSIHB9_IRQ_LEVEL_SBE_I2C      PPC_BIT(11)
#define   PSIHB9_IRQ_LEVEL_DIO          PPC_BIT(12)
#define   PSIHB9_IRQ_LEVEL_PSU          PPC_BIT(13)
#define   PSIHB9_IRQ_LEVEL_I2C_C        PPC_BIT(14)
#define   PSIHB9_IRQ_LEVEL_I2C_D        PPC_BIT(15)
#define   PSIHB9_IRQ_LEVEL_I2C_E        PPC_BIT(16)
#define   PSIHB9_IRQ_LEVEL_SBE          PPC_BIT(19)

#define PSIHB9_IRQ_STAT                 0x80 /* P bit */
#define   PSIHB9_IRQ_STAT_PSI           PPC_BIT(0)
#define   PSIHB9_IRQ_STAT_OCC           PPC_BIT(1)
#define   PSIHB9_IRQ_STAT_FSI           PPC_BIT(2)
#define   PSIHB9_IRQ_STAT_LPCHC         PPC_BIT(3)
#define   PSIHB9_IRQ_STAT_LOCAL_ERR     PPC_BIT(4)
#define   PSIHB9_IRQ_STAT_GLOBAL_ERR    PPC_BIT(5)
#define   PSIHB9_IRQ_STAT_TPM           PPC_BIT(6)
#define   PSIHB9_IRQ_STAT_LPC_SIRQ1     PPC_BIT(7)
#define   PSIHB9_IRQ_STAT_LPC_SIRQ2     PPC_BIT(8)
#define   PSIHB9_IRQ_STAT_LPC_SIRQ3     PPC_BIT(9)
#define   PSIHB9_IRQ_STAT_LPC_SIRQ4     PPC_BIT(10)
#define   PSIHB9_IRQ_STAT_SBE_I2C       PPC_BIT(11)
#define   PSIHB9_IRQ_STAT_DIO           PPC_BIT(12)
#define   PSIHB9_IRQ_STAT_PSU           PPC_BIT(13)

/* P10 register extensions */

#define PSIHB10_CR                       PSIHB9_CR
#define    PSIHB10_CR_STORE_EOI          PPC_BIT(12)

#define PSIHB10_ESB_CI_BASE              PSIHB9_ESB_CI_BASE
#define   PSIHB10_ESB_CI_64K             PPC_BIT(1)

static void pnv_psi_notify(XiveNotifier *xf, uint32_t srcno, bool pq_checked)
{
    PnvPsi *psi = PNV_PSI(xf);
    uint64_t notif_port = psi->regs[PSIHB_REG(PSIHB9_ESB_NOTIF_ADDR)];
    bool valid = notif_port & PSIHB9_ESB_NOTIF_VALID;
    uint64_t notify_addr = notif_port & ~PSIHB9_ESB_NOTIF_VALID;

    uint32_t offset =
        (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
    uint64_t data = offset | srcno;
    MemTxResult result;

    if (pq_checked) {
        data |= XIVE_TRIGGER_PQ;
    }

    if (!valid) {
        return;
    }

    address_space_stq_be(&address_space_memory, notify_addr, data,
                         MEMTXATTRS_UNSPECIFIED, &result);
    if (result != MEMTX_OK) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: trigger failed @%"
                      HWADDR_PRIx "\n", __func__, notif_port);
        return;
    }
}

static uint64_t pnv_psi_p9_mmio_read(void *opaque, hwaddr addr, unsigned size)
{
    PnvPsi *psi = PNV_PSI(opaque);
    uint32_t reg = PSIHB_REG(addr);
    uint64_t val = -1;

    switch (addr) {
    case PSIHB9_CR:
    case PSIHB9_SEMR:
        /* FSP stuff */
    case PSIHB9_INTERRUPT_CONTROL:
    case PSIHB9_ESB_CI_BASE:
    case PSIHB9_ESB_NOTIF_ADDR:
    case PSIHB9_IVT_OFFSET:
        val = psi->regs[reg];
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "PSI: read at 0x%" PRIx64 "\n", addr);
    }

    return val;
}

static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
                                  uint64_t val, unsigned size)
{
    PnvPsi *psi = PNV_PSI(opaque);
    Pnv9Psi *psi9 = PNV9_PSI(psi);
    uint32_t reg = PSIHB_REG(addr);
    MemoryRegion *sysmem = get_system_memory();

    switch (addr) {
    case PSIHB9_CR:
        if (val & PSIHB10_CR_STORE_EOI) {
            psi9->source.esb_flags |= XIVE_SRC_STORE_EOI;
        } else {
            psi9->source.esb_flags &= ~XIVE_SRC_STORE_EOI;
        }
        break;

    case PSIHB9_SEMR:
        /* FSP stuff */
        break;
    case PSIHB9_INTERRUPT_CONTROL:
        if (val & PSIHB9_IRQ_RESET) {
            device_cold_reset(DEVICE(&psi9->source));
        }
        psi->regs[reg] = val;
        break;

    case PSIHB9_ESB_CI_BASE:
        if (val & PSIHB10_ESB_CI_64K) {
            psi9->source.esb_shift = XIVE_ESB_64K;
        } else {
            psi9->source.esb_shift = XIVE_ESB_4K;
        }
        if (!(val & PSIHB9_ESB_CI_VALID)) {
            if (psi->regs[reg] & PSIHB9_ESB_CI_VALID) {
                memory_region_del_subregion(sysmem, &psi9->source.esb_mmio);
            }
        } else {
            if (!(psi->regs[reg] & PSIHB9_ESB_CI_VALID)) {
                hwaddr addr = val & ~(PSIHB9_ESB_CI_VALID | PSIHB10_ESB_CI_64K);
                memory_region_add_subregion(sysmem, addr,
                                            &psi9->source.esb_mmio);
            }
        }
        psi->regs[reg] = val;
        break;

    case PSIHB9_ESB_NOTIF_ADDR:
        psi->regs[reg] = val;
        break;
    case PSIHB9_IVT_OFFSET:
        psi->regs[reg] = val;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "PSI: write at 0x%" PRIx64 "\n", addr);
    }
}

static const MemoryRegionOps pnv_psi_p9_mmio_ops = {
    .read = pnv_psi_p9_mmio_read,
    .write = pnv_psi_p9_mmio_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .valid = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
};

static uint64_t pnv_psi_p9_xscom_read(void *opaque, hwaddr addr, unsigned size)
{
    uint32_t reg = addr >> 3;
    uint64_t val = -1;

    if (reg < PSIHB_XSCOM_BAR) {
        /* FIR, not modeled */
        qemu_log_mask(LOG_UNIMP, "PSI: xscom read at 0x%08x\n", reg);
    } else {
        val = pnv_psi_p9_mmio_read(opaque, PSIHB_MMIO(reg), size);
    }
    return val;
}

static void pnv_psi_p9_xscom_write(void *opaque, hwaddr addr,
                                uint64_t val, unsigned size)
{
    PnvPsi *psi = PNV_PSI(opaque);
    uint32_t reg = addr >> 3;

    if (reg < PSIHB_XSCOM_BAR) {
        /* FIR, not modeled */
        qemu_log_mask(LOG_UNIMP, "PSI: xscom write at 0x%08x\n", reg);
    } else if (reg == PSIHB_XSCOM_BAR) {
        pnv_psi_set_bar(psi, val);
    } else {
        pnv_psi_p9_mmio_write(opaque, PSIHB_MMIO(reg), val, size);
    }
}

static const MemoryRegionOps pnv_psi_p9_xscom_ops = {
    .read = pnv_psi_p9_xscom_read,
    .write = pnv_psi_p9_xscom_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .valid = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    }
};

static void pnv_psi_power9_set_irq(void *opaque, int irq, int state)
{
    PnvPsi *psi = opaque;
    uint64_t irq_method = psi->regs[PSIHB_REG(PSIHB9_INTERRUPT_CONTROL)];

    if (irq_method & PSIHB9_IRQ_METHOD) {
        qemu_log_mask(LOG_GUEST_ERROR, "PSI: LSI IRQ method no supported\n");
        return;
    }

    /* Update LSI levels */
    if (state) {
        psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] |= PPC_BIT(irq);
    } else {
        psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] &= ~PPC_BIT(irq);
    }

    qemu_set_irq(psi->qirqs[irq], state);
}

static void pnv_psi_power9_reset(DeviceState *dev)
{
    Pnv9Psi *psi = PNV9_PSI(dev);

    pnv_psi_reset(dev);

    if (memory_region_is_mapped(&psi->source.esb_mmio)) {
        memory_region_del_subregion(get_system_memory(), &psi->source.esb_mmio);
    }
}

static void pnv_psi_power9_instance_init(Object *obj)
{
    Pnv9Psi *psi = PNV9_PSI(obj);

    object_initialize_child(obj, "source", &psi->source, TYPE_XIVE_SOURCE);
    object_property_add_alias(obj, "shift", OBJECT(&psi->source), "shift");
}

static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
{
    PnvPsi *psi = PNV_PSI(dev);
    XiveSource *xsrc = &PNV9_PSI(psi)->source;
    int i;

    object_property_set_int(OBJECT(xsrc), "nr-irqs", PSIHB9_NUM_IRQS,
                            &error_fatal);
    object_property_set_link(OBJECT(xsrc), "xive", OBJECT(psi), &error_abort);
    object_property_set_int(OBJECT(xsrc), "reset-pq", XIVE_ESB_RESET,
                            &error_abort);
    if (!qdev_realize(DEVICE(xsrc), NULL, errp)) {
        return;
    }

    for (i = 0; i < xsrc->nr_irqs; i++) {
        xive_source_irq_set_lsi(xsrc, i);
    }

    psi->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);

    qdev_init_gpio_in(dev, pnv_psi_power9_set_irq, xsrc->nr_irqs);

    /* XSCOM region for PSI registers */
    pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops,
                psi, "xscom-psi", PNV9_XSCOM_PSIHB_SIZE);

    /* MMIO region for PSI registers */
    memory_region_init_io(&psi->regs_mr, OBJECT(dev), &pnv_psi_p9_mmio_ops, psi,
                          "psihb", PNV9_PSIHB_SIZE);

    pnv_psi_realize(dev, errp);
}

static void pnv_psi_power9_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
    XiveNotifierClass *xfc = XIVE_NOTIFIER_CLASS(klass);
    static const char compat[] = "ibm,power9-psihb-x\0ibm,psihb-x";

    dc->desc    = "PowerNV PSI Controller POWER9";
    dc->realize = pnv_psi_power9_realize;
    dc->reset   = pnv_psi_power9_reset;

    ppc->xscom_pcba = PNV9_XSCOM_PSIHB_BASE;
    ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE;
    ppc->bar_mask   = PSIHB9_BAR_MASK;
    ppc->compat     = compat;
    ppc->compat_size = sizeof(compat);

    xfc->notify      = pnv_psi_notify;
}

static const TypeInfo pnv_psi_power9_info = {
    .name          = TYPE_PNV9_PSI,
    .parent        = TYPE_PNV_PSI,
    .instance_size = sizeof(Pnv9Psi),
    .instance_init = pnv_psi_power9_instance_init,
    .class_init    = pnv_psi_power9_class_init,
    .interfaces = (InterfaceInfo[]) {
            { TYPE_XIVE_NOTIFIER },
            { },
    },
};

static void pnv_psi_power10_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
    static const char compat[] = "ibm,power10-psihb-x\0ibm,psihb-x";

    dc->desc    = "PowerNV PSI Controller POWER10";

    ppc->xscom_pcba = PNV10_XSCOM_PSIHB_BASE;
    ppc->xscom_size = PNV10_XSCOM_PSIHB_SIZE;
    ppc->compat     = compat;
    ppc->compat_size = sizeof(compat);
}

static const TypeInfo pnv_psi_power10_info = {
    .name          = TYPE_PNV10_PSI,
    .parent        = TYPE_PNV9_PSI,
    .class_init    = pnv_psi_power10_class_init,
};

static void pnv_psi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);

    xdc->dt_xscom = pnv_psi_dt_xscom;

    dc->desc = "PowerNV PSI Controller";
    device_class_set_props(dc, pnv_psi_properties);
    dc->reset = pnv_psi_reset;
    dc->user_creatable = false;
}

static const TypeInfo pnv_psi_info = {
    .name          = TYPE_PNV_PSI,
    .parent        = TYPE_DEVICE,
    .instance_size = sizeof(PnvPsi),
    .class_init    = pnv_psi_class_init,
    .class_size    = sizeof(PnvPsiClass),
    .abstract      = true,
    .interfaces    = (InterfaceInfo[]) {
        { TYPE_PNV_XSCOM_INTERFACE },
        { }
    }
};

static void pnv_psi_register_types(void)
{
    type_register_static(&pnv_psi_info);
    type_register_static(&pnv_psi_power8_info);
    type_register_static(&pnv_psi_power9_info);
    type_register_static(&pnv_psi_power10_info);
}

type_init(pnv_psi_register_types);

void pnv_psi_pic_print_info(Pnv9Psi *psi9, Monitor *mon)
{
    PnvPsi *psi = PNV_PSI(psi9);

    uint32_t offset =
        (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);

    monitor_printf(mon, "PSIHB Source %08x .. %08x\n",
                  offset, offset + psi9->source.nr_irqs - 1);
    xive_source_pic_print_info(&psi9->source, offset, mon);
}
