/*
 * ARM GICv3 emulation: Redistributor
 *
 * Copyright (c) 2015 Huawei.
 * Copyright (c) 2016 Linaro Limited.
 * Written by Shlomo Pongratz, Peter Maydell
 *
 * This code is licensed under the GPL, version 2 or (at your option)
 * any later version.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "trace.h"
#include "gicv3_internal.h"

static uint32_t mask_group(GICv3CPUState *cs, MemTxAttrs attrs)
{
    /* Return a 32-bit mask which should be applied for this set of 32
     * interrupts; each bit is 1 if access is permitted by the
     * combination of attrs.secure and GICR_GROUPR. (GICR_NSACR does
     * not affect config register accesses, unlike GICD_NSACR.)
     */
    if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
        /* bits for Group 0 or Secure Group 1 interrupts are RAZ/WI */
        return cs->gicr_igroupr0;
    }
    return 0xFFFFFFFFU;
}

static int gicr_ns_access(GICv3CPUState *cs, int irq)
{
    /* Return the 2 bit NSACR.NS_access field for this SGI */
    assert(irq < 16);
    return extract32(cs->gicr_nsacr, irq * 2, 2);
}

static void gicr_write_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
                                  uint32_t *reg, uint32_t val)
{
    /* Helper routine to implement writing to a "set" register */
    val &= mask_group(cs, attrs);
    *reg = val;
    gicv3_redist_update(cs);
}

static void gicr_write_set_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
                                      uint32_t *reg, uint32_t val)
{
    /* Helper routine to implement writing to a "set-bitmap" register */
    val &= mask_group(cs, attrs);
    *reg |= val;
    gicv3_redist_update(cs);
}

static void gicr_write_clear_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
                                        uint32_t *reg, uint32_t val)
{
    /* Helper routine to implement writing to a "clear-bitmap" register */
    val &= mask_group(cs, attrs);
    *reg &= ~val;
    gicv3_redist_update(cs);
}

static uint32_t gicr_read_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
                                     uint32_t reg)
{
    reg &= mask_group(cs, attrs);
    return reg;
}

static bool vcpu_resident(GICv3CPUState *cs, uint64_t vptaddr)
{
    /*
     * Return true if a vCPU is resident, which is defined by
     * whether the GICR_VPENDBASER register is marked VALID and
     * has the right virtual pending table address.
     */
    if (!FIELD_EX64(cs->gicr_vpendbaser, GICR_VPENDBASER, VALID)) {
        return false;
    }
    return vptaddr == (cs->gicr_vpendbaser & R_GICR_VPENDBASER_PHYADDR_MASK);
}

/**
 * update_for_one_lpi: Update pending information if this LPI is better
 *
 * @cs: GICv3CPUState
 * @irq: interrupt to look up in the LPI Configuration table
 * @ctbase: physical address of the LPI Configuration table to use
 * @ds: true if priority value should not be shifted
 * @hpp: points to pending information to update
 *
 * Look up @irq in the Configuration table specified by @ctbase
 * to see if it is enabled and what its priority is. If it is an
 * enabled interrupt with a higher priority than that currently
 * recorded in @hpp, update @hpp.
 */
static void update_for_one_lpi(GICv3CPUState *cs, int irq,
                               uint64_t ctbase, bool ds, PendingIrq *hpp)
{
    uint8_t lpite;
    uint8_t prio;

    address_space_read(&cs->gic->dma_as,
                       ctbase + ((irq - GICV3_LPI_INTID_START) * sizeof(lpite)),
                       MEMTXATTRS_UNSPECIFIED, &lpite, sizeof(lpite));

    if (!(lpite & LPI_CTE_ENABLED)) {
        return;
    }

    if (ds) {
        prio = lpite & LPI_PRIORITY_MASK;
    } else {
        prio = ((lpite & LPI_PRIORITY_MASK) >> 1) | 0x80;
    }

    if ((prio < hpp->prio) ||
        ((prio == hpp->prio) && (irq <= hpp->irq))) {
        hpp->irq = irq;
        hpp->prio = prio;
        hpp->nmi = false;
        /* LPIs and vLPIs are always non-secure Grp1 interrupts */
        hpp->grp = GICV3_G1NS;
    }
}

/**
 * update_for_all_lpis: Fully scan LPI tables and find best pending LPI
 *
 * @cs: GICv3CPUState
 * @ptbase: physical address of LPI Pending table
 * @ctbase: physical address of LPI Configuration table
 * @ptsizebits: size of tables, specified as number of interrupt ID bits minus 1
 * @ds: true if priority value should not be shifted
 * @hpp: points to pending information to set
 *
 * Recalculate the highest priority pending enabled LPI from scratch,
 * and set @hpp accordingly.
 *
 * We scan the LPI pending table @ptbase; for each pending LPI, we read the
 * corresponding entry in the LPI configuration table @ctbase to extract
 * the priority and enabled information.
 *
 * We take @ptsizebits in the form idbits-1 because this is the way that
 * LPI table sizes are architecturally specified in GICR_PROPBASER.IDBits
 * and in the VMAPP command's VPT_size field.
 */
static void update_for_all_lpis(GICv3CPUState *cs, uint64_t ptbase,
                                uint64_t ctbase, unsigned ptsizebits,
                                bool ds, PendingIrq *hpp)
{
    AddressSpace *as = &cs->gic->dma_as;
    uint8_t pend;
    uint32_t pendt_size = (1ULL << (ptsizebits + 1));
    int i, bit;

    hpp->prio = 0xff;
    hpp->nmi = false;

    for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
        address_space_read(as, ptbase + i, MEMTXATTRS_UNSPECIFIED, &pend, 1);
        while (pend) {
            bit = ctz32(pend);
            update_for_one_lpi(cs, i * 8 + bit, ctbase, ds, hpp);
            pend &= ~(1 << bit);
        }
    }
}

/**
 * set_lpi_pending_bit: Set or clear pending bit for an LPI
 *
 * @cs: GICv3CPUState
 * @ptbase: physical address of LPI Pending table
 * @irq: LPI to change pending state for
 * @level: false to clear pending state, true to set
 *
 * Returns true if we needed to do something, false if the pending bit
 * was already at @level.
 */
static bool set_pending_table_bit(GICv3CPUState *cs, uint64_t ptbase,
                                  int irq, bool level)
{
    AddressSpace *as = &cs->gic->dma_as;
    uint64_t addr = ptbase + irq / 8;
    uint8_t pend;

    address_space_read(as, addr, MEMTXATTRS_UNSPECIFIED, &pend, 1);
    if (extract32(pend, irq % 8, 1) == level) {
        /* Bit already at requested state, no action required */
        return false;
    }
    pend = deposit32(pend, irq % 8, 1, level ? 1 : 0);
    address_space_write(as, addr, MEMTXATTRS_UNSPECIFIED, &pend, 1);
    return true;
}

static uint8_t gicr_read_ipriorityr(GICv3CPUState *cs, MemTxAttrs attrs,
                                    int irq)
{
    /* Read the value of GICR_IPRIORITYR<n> for the specified interrupt,
     * honouring security state (these are RAZ/WI for Group 0 or Secure
     * Group 1 interrupts).
     */
    uint32_t prio;

    prio = cs->gicr_ipriorityr[irq];

    if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
        if (!(cs->gicr_igroupr0 & (1U << irq))) {
            /* Fields for Group 0 or Secure Group 1 interrupts are RAZ/WI */
            return 0;
        }
        /* NS view of the interrupt priority */
        prio = (prio << 1) & 0xff;
    }
    return prio;
}

static void gicr_write_ipriorityr(GICv3CPUState *cs, MemTxAttrs attrs, int irq,
                                  uint8_t value)
{
    /* Write the value of GICD_IPRIORITYR<n> for the specified interrupt,
     * honouring security state (these are RAZ/WI for Group 0 or Secure
     * Group 1 interrupts).
     */
    if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
        if (!(cs->gicr_igroupr0 & (1U << irq))) {
            /* Fields for Group 0 or Secure Group 1 interrupts are RAZ/WI */
            return;
        }
        /* NS view of the interrupt priority */
        value = 0x80 | (value >> 1);
    }
    cs->gicr_ipriorityr[irq] = value;
}

static void gicv3_redist_update_vlpi_only(GICv3CPUState *cs)
{
    uint64_t ptbase, ctbase, idbits;

    if (!FIELD_EX64(cs->gicr_vpendbaser, GICR_VPENDBASER, VALID)) {
        cs->hppvlpi.prio = 0xff;
        cs->hppvlpi.nmi = false;
        return;
    }

    ptbase = cs->gicr_vpendbaser & R_GICR_VPENDBASER_PHYADDR_MASK;
    ctbase = cs->gicr_vpropbaser & R_GICR_VPROPBASER_PHYADDR_MASK;
    idbits = FIELD_EX64(cs->gicr_vpropbaser, GICR_VPROPBASER, IDBITS);

    update_for_all_lpis(cs, ptbase, ctbase, idbits, true, &cs->hppvlpi);
}

static void gicv3_redist_update_vlpi(GICv3CPUState *cs)
{
    gicv3_redist_update_vlpi_only(cs);
    gicv3_cpuif_virt_irq_fiq_update(cs);
}

static void gicr_write_vpendbaser(GICv3CPUState *cs, uint64_t newval)
{
    /* Write @newval to GICR_VPENDBASER, handling its effects */
    bool oldvalid = FIELD_EX64(cs->gicr_vpendbaser, GICR_VPENDBASER, VALID);
    bool newvalid = FIELD_EX64(newval, GICR_VPENDBASER, VALID);
    bool pendinglast;

    /*
     * The DIRTY bit is read-only and for us is always zero;
     * other fields are writable.
     */
    newval &= R_GICR_VPENDBASER_INNERCACHE_MASK |
        R_GICR_VPENDBASER_SHAREABILITY_MASK |
        R_GICR_VPENDBASER_PHYADDR_MASK |
        R_GICR_VPENDBASER_OUTERCACHE_MASK |
        R_GICR_VPENDBASER_PENDINGLAST_MASK |
        R_GICR_VPENDBASER_IDAI_MASK |
        R_GICR_VPENDBASER_VALID_MASK;

    if (oldvalid && newvalid) {
        /*
         * Changing other fields while VALID is 1 is UNPREDICTABLE;
         * we choose to log and ignore the write.
         */
        if (cs->gicr_vpendbaser ^ newval) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "%s: Changing GICR_VPENDBASER when VALID=1 "
                          "is UNPREDICTABLE\n", __func__);
        }
        return;
    }
    if (!oldvalid && !newvalid) {
        cs->gicr_vpendbaser = newval;
        return;
    }

    if (newvalid) {
        /*
         * Valid going from 0 to 1: update hppvlpi from tables.
         * If IDAI is 0 we are allowed to use the info we cached in
         * the IMPDEF area of the table.
         * PendingLast is RES1 when we make this transition.
         */
        pendinglast = true;
    } else {
        /*
         * Valid going from 1 to 0:
         * Set PendingLast if there was a pending enabled interrupt
         * for the vPE that was just descheduled.
         * If we cache info in the IMPDEF area, write it out here.
         */
        pendinglast = cs->hppvlpi.prio != 0xff;
    }

    newval = FIELD_DP64(newval, GICR_VPENDBASER, PENDINGLAST, pendinglast);
    cs->gicr_vpendbaser = newval;
    gicv3_redist_update_vlpi(cs);
}

static MemTxResult gicr_readb(GICv3CPUState *cs, hwaddr offset,
                              uint64_t *data, MemTxAttrs attrs)
{
    switch (offset) {
    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
        *data = gicr_read_ipriorityr(cs, attrs, offset - GICR_IPRIORITYR);
        return MEMTX_OK;
    default:
        return MEMTX_ERROR;
    }
}

static MemTxResult gicr_writeb(GICv3CPUState *cs, hwaddr offset,
                               uint64_t value, MemTxAttrs attrs)
{
    switch (offset) {
    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
        gicr_write_ipriorityr(cs, attrs, offset - GICR_IPRIORITYR, value);
        gicv3_redist_update(cs);
        return MEMTX_OK;
    default:
        return MEMTX_ERROR;
    }
}

static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
                              uint64_t *data, MemTxAttrs attrs)
{
    switch (offset) {
    case GICR_CTLR:
        *data = cs->gicr_ctlr;
        return MEMTX_OK;
    case GICR_IIDR:
        *data = gicv3_iidr();
        return MEMTX_OK;
    case GICR_TYPER:
        *data = extract64(cs->gicr_typer, 0, 32);
        return MEMTX_OK;
    case GICR_TYPER + 4:
        *data = extract64(cs->gicr_typer, 32, 32);
        return MEMTX_OK;
    case GICR_STATUSR:
        /* RAZ/WI for us (this is an optional register and our implementation
         * does not track RO/WO/reserved violations to report them to the guest)
         */
        *data = 0;
        return MEMTX_OK;
    case GICR_WAKER:
        *data = cs->gicr_waker;
        return MEMTX_OK;
    case GICR_PROPBASER:
        *data = extract64(cs->gicr_propbaser, 0, 32);
        return MEMTX_OK;
    case GICR_PROPBASER + 4:
        *data = extract64(cs->gicr_propbaser, 32, 32);
        return MEMTX_OK;
    case GICR_PENDBASER:
        *data = extract64(cs->gicr_pendbaser, 0, 32);
        return MEMTX_OK;
    case GICR_PENDBASER + 4:
        *data = extract64(cs->gicr_pendbaser, 32, 32);
        return MEMTX_OK;
    case GICR_IGROUPR0:
        if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
            *data = 0;
            return MEMTX_OK;
        }
        *data = cs->gicr_igroupr0;
        return MEMTX_OK;
    case GICR_ISENABLER0:
    case GICR_ICENABLER0:
        *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_ienabler0);
        return MEMTX_OK;
    case GICR_ISPENDR0:
    case GICR_ICPENDR0:
    {
        /* The pending register reads as the logical OR of the pending
         * latch and the input line level for level-triggered interrupts.
         */
        uint32_t val = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level);
        *data = gicr_read_bitmap_reg(cs, attrs, val);
        return MEMTX_OK;
    }
    case GICR_ISACTIVER0:
    case GICR_ICACTIVER0:
        *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_iactiver0);
        return MEMTX_OK;
    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
    {
        int i, irq = offset - GICR_IPRIORITYR;
        uint32_t value = 0;

        for (i = irq + 3; i >= irq; i--) {
            value <<= 8;
            value |= gicr_read_ipriorityr(cs, attrs, i);
        }
        *data = value;
        return MEMTX_OK;
    }
    case GICR_INMIR0:
        *data = cs->gic->nmi_support ?
                gicr_read_bitmap_reg(cs, attrs, cs->gicr_inmir0) : 0;
        return MEMTX_OK;
    case GICR_ICFGR0:
    case GICR_ICFGR1:
    {
        /* Our edge_trigger bitmap is one bit per irq; take the correct
         * half of it, and spread it out into the odd bits.
         */
        uint32_t value;

        value = cs->edge_trigger & mask_group(cs, attrs);
        value = extract32(value, (offset == GICR_ICFGR1) ? 16 : 0, 16);
        value = half_shuffle32(value) << 1;
        *data = value;
        return MEMTX_OK;
    }
    case GICR_IGRPMODR0:
        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
            /* RAZ/WI if security disabled, or if
             * security enabled and this is an NS access
             */
            *data = 0;
            return MEMTX_OK;
        }
        *data = cs->gicr_igrpmodr0;
        return MEMTX_OK;
    case GICR_NSACR:
        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
            /* RAZ/WI if security disabled, or if
             * security enabled and this is an NS access
             */
            *data = 0;
            return MEMTX_OK;
        }
        *data = cs->gicr_nsacr;
        return MEMTX_OK;
    case GICR_IDREGS ... GICR_IDREGS + 0x2f:
        *data = gicv3_idreg(cs->gic, offset - GICR_IDREGS, GICV3_PIDR0_REDIST);
        return MEMTX_OK;
        /*
         * VLPI frame registers. We don't need a version check for
         * VPROPBASER and VPENDBASER because gicv3_redist_size() will
         * prevent pre-v4 GIC from passing us offsets this high.
         */
    case GICR_VPROPBASER:
        *data = extract64(cs->gicr_vpropbaser, 0, 32);
        return MEMTX_OK;
    case GICR_VPROPBASER + 4:
        *data = extract64(cs->gicr_vpropbaser, 32, 32);
        return MEMTX_OK;
    case GICR_VPENDBASER:
        *data = extract64(cs->gicr_vpendbaser, 0, 32);
        return MEMTX_OK;
    case GICR_VPENDBASER + 4:
        *data = extract64(cs->gicr_vpendbaser, 32, 32);
        return MEMTX_OK;
    default:
        return MEMTX_ERROR;
    }
}

static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
                               uint64_t value, MemTxAttrs attrs)
{
    switch (offset) {
    case GICR_CTLR:
        /* For our implementation, GICR_TYPER.DPGS is 0 and so all
         * the DPG bits are RAZ/WI. We don't do anything asynchronously,
         * so UWP and RWP are RAZ/WI. GICR_TYPER.LPIS is 1 (we
         * implement LPIs) so Enable_LPIs is programmable.
         */
        if (cs->gicr_typer & GICR_TYPER_PLPIS) {
            if (value & GICR_CTLR_ENABLE_LPIS) {
                cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
                /* Check for any pending interr in pending table */
                gicv3_redist_update_lpi(cs);
            } else {
                cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
                /* cs->hppi might have been an LPI; recalculate */
                gicv3_redist_update(cs);
            }
        }
        return MEMTX_OK;
    case GICR_STATUSR:
        /* RAZ/WI for our implementation */
        return MEMTX_OK;
    case GICR_WAKER:
        /* Only the ProcessorSleep bit is writable. When the guest sets
         * it, it requests that we transition the channel between the
         * redistributor and the cpu interface to quiescent, and that
         * we set the ChildrenAsleep bit once the interface has reached the
         * quiescent state.
         * Setting the ProcessorSleep to 0 reverses the quiescing, and
         * ChildrenAsleep is cleared once the transition is complete.
         * Since our interface is not asynchronous, we complete these
         * transitions instantaneously, so we set ChildrenAsleep to the
         * same value as ProcessorSleep here.
         */
        value &= GICR_WAKER_ProcessorSleep;
        if (value & GICR_WAKER_ProcessorSleep) {
            value |= GICR_WAKER_ChildrenAsleep;
        }
        cs->gicr_waker = value;
        return MEMTX_OK;
    case GICR_PROPBASER:
        cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 0, 32, value);
        return MEMTX_OK;
    case GICR_PROPBASER + 4:
        cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 32, 32, value);
        return MEMTX_OK;
    case GICR_PENDBASER:
        cs->gicr_pendbaser = deposit64(cs->gicr_pendbaser, 0, 32, value);
        return MEMTX_OK;
    case GICR_PENDBASER + 4:
        cs->gicr_pendbaser = deposit64(cs->gicr_pendbaser, 32, 32, value);
        return MEMTX_OK;
    case GICR_IGROUPR0:
        if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
            return MEMTX_OK;
        }
        cs->gicr_igroupr0 = value;
        gicv3_redist_update(cs);
        return MEMTX_OK;
    case GICR_ISENABLER0:
        gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_ienabler0, value);
        return MEMTX_OK;
    case GICR_ICENABLER0:
        gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_ienabler0, value);
        return MEMTX_OK;
    case GICR_ISPENDR0:
        gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_ipendr0, value);
        return MEMTX_OK;
    case GICR_ICPENDR0:
        gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_ipendr0, value);
        return MEMTX_OK;
    case GICR_ISACTIVER0:
        gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_iactiver0, value);
        return MEMTX_OK;
    case GICR_ICACTIVER0:
        gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_iactiver0, value);
        return MEMTX_OK;
    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
    {
        int i, irq = offset - GICR_IPRIORITYR;

        for (i = irq; i < irq + 4; i++, value >>= 8) {
            gicr_write_ipriorityr(cs, attrs, i, value);
        }
        gicv3_redist_update(cs);
        return MEMTX_OK;
    }
    case GICR_INMIR0:
        if (cs->gic->nmi_support) {
            gicr_write_bitmap_reg(cs, attrs, &cs->gicr_inmir0, value);
        }
        return MEMTX_OK;

    case GICR_ICFGR0:
        /* Register is all RAZ/WI or RAO/WI bits */
        return MEMTX_OK;
    case GICR_ICFGR1:
    {
        uint32_t mask;

        /* Since our edge_trigger bitmap is one bit per irq, our input
         * 32-bits will compress down into 16 bits which we need
         * to write into the bitmap.
         */
        value = half_unshuffle32(value >> 1) << 16;
        mask = mask_group(cs, attrs) & 0xffff0000U;

        cs->edge_trigger &= ~mask;
        cs->edge_trigger |= (value & mask);

        gicv3_redist_update(cs);
        return MEMTX_OK;
    }
    case GICR_IGRPMODR0:
        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
            /* RAZ/WI if security disabled, or if
             * security enabled and this is an NS access
             */
            return MEMTX_OK;
        }
        cs->gicr_igrpmodr0 = value;
        gicv3_redist_update(cs);
        return MEMTX_OK;
    case GICR_NSACR:
        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
            /* RAZ/WI if security disabled, or if
             * security enabled and this is an NS access
             */
            return MEMTX_OK;
        }
        cs->gicr_nsacr = value;
        /* no update required as this only affects access permission checks */
        return MEMTX_OK;
    case GICR_IIDR:
    case GICR_TYPER:
    case GICR_IDREGS ... GICR_IDREGS + 0x2f:
        /* RO registers, ignore the write */
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: invalid guest write to RO register at offset "
                      HWADDR_FMT_plx "\n", __func__, offset);
        return MEMTX_OK;
        /*
         * VLPI frame registers. We don't need a version check for
         * VPROPBASER and VPENDBASER because gicv3_redist_size() will
         * prevent pre-v4 GIC from passing us offsets this high.
         */
    case GICR_VPROPBASER:
        cs->gicr_vpropbaser = deposit64(cs->gicr_vpropbaser, 0, 32, value);
        return MEMTX_OK;
    case GICR_VPROPBASER + 4:
        cs->gicr_vpropbaser = deposit64(cs->gicr_vpropbaser, 32, 32, value);
        return MEMTX_OK;
    case GICR_VPENDBASER:
        gicr_write_vpendbaser(cs, deposit64(cs->gicr_vpendbaser, 0, 32, value));
        return MEMTX_OK;
    case GICR_VPENDBASER + 4:
        gicr_write_vpendbaser(cs, deposit64(cs->gicr_vpendbaser, 32, 32, value));
        return MEMTX_OK;
    default:
        return MEMTX_ERROR;
    }
}

static MemTxResult gicr_readll(GICv3CPUState *cs, hwaddr offset,
                               uint64_t *data, MemTxAttrs attrs)
{
    switch (offset) {
    case GICR_TYPER:
        *data = cs->gicr_typer;
        return MEMTX_OK;
    case GICR_PROPBASER:
        *data = cs->gicr_propbaser;
        return MEMTX_OK;
    case GICR_PENDBASER:
        *data = cs->gicr_pendbaser;
        return MEMTX_OK;
        /*
         * VLPI frame registers. We don't need a version check for
         * VPROPBASER and VPENDBASER because gicv3_redist_size() will
         * prevent pre-v4 GIC from passing us offsets this high.
         */
    case GICR_VPROPBASER:
        *data = cs->gicr_vpropbaser;
        return MEMTX_OK;
    case GICR_VPENDBASER:
        *data = cs->gicr_vpendbaser;
        return MEMTX_OK;
    default:
        return MEMTX_ERROR;
    }
}

static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset,
                                uint64_t value, MemTxAttrs attrs)
{
    switch (offset) {
    case GICR_PROPBASER:
        cs->gicr_propbaser = value;
        return MEMTX_OK;
    case GICR_PENDBASER:
        cs->gicr_pendbaser = value;
        return MEMTX_OK;
    case GICR_TYPER:
        /* RO register, ignore the write */
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: invalid guest write to RO register at offset "
                      HWADDR_FMT_plx "\n", __func__, offset);
        return MEMTX_OK;
        /*
         * VLPI frame registers. We don't need a version check for
         * VPROPBASER and VPENDBASER because gicv3_redist_size() will
         * prevent pre-v4 GIC from passing us offsets this high.
         */
    case GICR_VPROPBASER:
        cs->gicr_vpropbaser = value;
        return MEMTX_OK;
    case GICR_VPENDBASER:
        gicr_write_vpendbaser(cs, value);
        return MEMTX_OK;
    default:
        return MEMTX_ERROR;
    }
}

MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
                              unsigned size, MemTxAttrs attrs)
{
    GICv3RedistRegion *region = opaque;
    GICv3State *s = region->gic;
    GICv3CPUState *cs;
    MemTxResult r;
    int cpuidx;

    assert((offset & (size - 1)) == 0);

    /*
     * There are (for GICv3) two 64K redistributor pages per CPU.
     * In some cases the redistributor pages for all CPUs are not
     * contiguous (eg on the virt board they are split into two
     * parts if there are too many CPUs to all fit in the same place
     * in the memory map); if so then the GIC has multiple MemoryRegions
     * for the redistributors.
     */
    cpuidx = region->cpuidx + offset / gicv3_redist_size(s);
    offset %= gicv3_redist_size(s);

    cs = &s->cpu[cpuidx];

    switch (size) {
    case 1:
        r = gicr_readb(cs, offset, data, attrs);
        break;
    case 4:
        r = gicr_readl(cs, offset, data, attrs);
        break;
    case 8:
        r = gicr_readll(cs, offset, data, attrs);
        break;
    default:
        r = MEMTX_ERROR;
        break;
    }

    if (r != MEMTX_OK) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: invalid guest read at offset " HWADDR_FMT_plx
                      " size %u\n", __func__, offset, size);
        trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
                                   size, attrs.secure);
        /* The spec requires that reserved registers are RAZ/WI;
         * so use MEMTX_ERROR returns from leaf functions as a way to
         * trigger the guest-error logging but don't return it to
         * the caller, or we'll cause a spurious guest data abort.
         */
        r = MEMTX_OK;
        *data = 0;
    } else {
        trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data,
                                size, attrs.secure);
    }
    return r;
}

MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
                               unsigned size, MemTxAttrs attrs)
{
    GICv3RedistRegion *region = opaque;
    GICv3State *s = region->gic;
    GICv3CPUState *cs;
    MemTxResult r;
    int cpuidx;

    assert((offset & (size - 1)) == 0);

    /*
     * There are (for GICv3) two 64K redistributor pages per CPU.
     * In some cases the redistributor pages for all CPUs are not
     * contiguous (eg on the virt board they are split into two
     * parts if there are too many CPUs to all fit in the same place
     * in the memory map); if so then the GIC has multiple MemoryRegions
     * for the redistributors.
     */
    cpuidx = region->cpuidx + offset / gicv3_redist_size(s);
    offset %= gicv3_redist_size(s);

    cs = &s->cpu[cpuidx];

    switch (size) {
    case 1:
        r = gicr_writeb(cs, offset, data, attrs);
        break;
    case 4:
        r = gicr_writel(cs, offset, data, attrs);
        break;
    case 8:
        r = gicr_writell(cs, offset, data, attrs);
        break;
    default:
        r = MEMTX_ERROR;
        break;
    }

    if (r != MEMTX_OK) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: invalid guest write at offset " HWADDR_FMT_plx
                      " size %u\n", __func__, offset, size);
        trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
                                    size, attrs.secure);
        /* The spec requires that reserved registers are RAZ/WI;
         * so use MEMTX_ERROR returns from leaf functions as a way to
         * trigger the guest-error logging but don't return it to
         * the caller, or we'll cause a spurious guest data abort.
         */
        r = MEMTX_OK;
    } else {
        trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data,
                                 size, attrs.secure);
    }
    return r;
}

static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq)
{
    uint64_t lpict_baddr = cs->gicr_propbaser & R_GICR_PROPBASER_PHYADDR_MASK;

    update_for_one_lpi(cs, irq, lpict_baddr,
                       cs->gic->gicd_ctlr & GICD_CTLR_DS,
                       &cs->hpplpi);
}

void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
{
    /*
     * This function scans the LPI pending table and for each pending
     * LPI, reads the corresponding entry from LPI configuration table
     * to extract the priority info and determine if the current LPI
     * priority is lower than the last computed high priority lpi interrupt.
     * If yes, replace current LPI as the new high priority lpi interrupt.
     */
    uint64_t lpipt_baddr, lpict_baddr;
    uint64_t idbits;

    idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
                 GICD_TYPER_IDBITS);

    if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
        return;
    }

    lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
    lpict_baddr = cs->gicr_propbaser & R_GICR_PROPBASER_PHYADDR_MASK;

    update_for_all_lpis(cs, lpipt_baddr, lpict_baddr, idbits,
                        cs->gic->gicd_ctlr & GICD_CTLR_DS, &cs->hpplpi);
}

void gicv3_redist_update_lpi(GICv3CPUState *cs)
{
    gicv3_redist_update_lpi_only(cs);
    gicv3_redist_update(cs);
}

void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
{
    /*
     * This function updates the pending bit in lpi pending table for
     * the irq being activated or deactivated.
     */
    uint64_t lpipt_baddr;

    lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
    if (!set_pending_table_bit(cs, lpipt_baddr, irq, level)) {
        /* no change in the value of pending bit, return */
        return;
    }

    /*
     * check if this LPI is better than the current hpplpi, if yes
     * just set hpplpi.prio and .irq without doing a full rescan
     */
    if (level) {
        gicv3_redist_check_lpi_priority(cs, irq);
        gicv3_redist_update(cs);
    } else {
        if (irq == cs->hpplpi.irq) {
            gicv3_redist_update_lpi(cs);
        }
    }
}

void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
{
    uint64_t idbits;

    idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
                 GICD_TYPER_IDBITS);

    if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
        (irq > (1ULL << (idbits + 1)) - 1) || irq < GICV3_LPI_INTID_START) {
        return;
    }

    /* set/clear the pending bit for this irq */
    gicv3_redist_lpi_pending(cs, irq, level);
}

void gicv3_redist_inv_lpi(GICv3CPUState *cs, int irq)
{
    /*
     * The only cached information for LPIs we have is the HPPLPI.
     * We could be cleverer about identifying when we don't need
     * to do a full rescan of the pending table, but until we find
     * this is a performance issue, just always recalculate.
     */
    gicv3_redist_update_lpi(cs);
}

void gicv3_redist_mov_lpi(GICv3CPUState *src, GICv3CPUState *dest, int irq)
{
    /*
     * Move the specified LPI's pending state from the source redistributor
     * to the destination.
     *
     * If LPIs are disabled on dest this is CONSTRAINED UNPREDICTABLE:
     * we choose to NOP. If LPIs are disabled on source there's nothing
     * to be transferred anyway.
     */
    uint64_t idbits;
    uint32_t pendt_size;
    uint64_t src_baddr;

    if (!(src->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
        !(dest->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
        return;
    }

    idbits = MIN(FIELD_EX64(src->gicr_propbaser, GICR_PROPBASER, IDBITS),
                 GICD_TYPER_IDBITS);
    idbits = MIN(FIELD_EX64(dest->gicr_propbaser, GICR_PROPBASER, IDBITS),
                 idbits);

    pendt_size = 1ULL << (idbits + 1);
    if ((irq / 8) >= pendt_size) {
        return;
    }

    src_baddr = src->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;

    if (!set_pending_table_bit(src, src_baddr, irq, 0)) {
        /* Not pending on source, nothing to do */
        return;
    }
    if (irq == src->hpplpi.irq) {
        /*
         * We just made this LPI not-pending so only need to update
         * if it was previously the highest priority pending LPI
         */
        gicv3_redist_update_lpi(src);
    }
    /* Mark it pending on the destination */
    gicv3_redist_lpi_pending(dest, irq, 1);
}

void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest)
{
    /*
     * We must move all pending LPIs from the source redistributor
     * to the destination. That is, for every pending LPI X on
     * src, we must set it not-pending on src and pending on dest.
     * LPIs that are already pending on dest are not cleared.
     *
     * If LPIs are disabled on dest this is CONSTRAINED UNPREDICTABLE:
     * we choose to NOP. If LPIs are disabled on source there's nothing
     * to be transferred anyway.
     */
    AddressSpace *as = &src->gic->dma_as;
    uint64_t idbits;
    uint32_t pendt_size;
    uint64_t src_baddr, dest_baddr;
    int i;

    if (!(src->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
        !(dest->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
        return;
    }

    idbits = MIN(FIELD_EX64(src->gicr_propbaser, GICR_PROPBASER, IDBITS),
                 GICD_TYPER_IDBITS);
    idbits = MIN(FIELD_EX64(dest->gicr_propbaser, GICR_PROPBASER, IDBITS),
                 idbits);

    pendt_size = 1ULL << (idbits + 1);
    src_baddr = src->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
    dest_baddr = dest->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;

    for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
        uint8_t src_pend, dest_pend;

        address_space_read(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
                           &src_pend, sizeof(src_pend));
        if (!src_pend) {
            continue;
        }
        address_space_read(as, dest_baddr + i, MEMTXATTRS_UNSPECIFIED,
                           &dest_pend, sizeof(dest_pend));
        dest_pend |= src_pend;
        src_pend = 0;
        address_space_write(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
                            &src_pend, sizeof(src_pend));
        address_space_write(as, dest_baddr + i, MEMTXATTRS_UNSPECIFIED,
                            &dest_pend, sizeof(dest_pend));
    }

    gicv3_redist_update_lpi(src);
    gicv3_redist_update_lpi(dest);
}

void gicv3_redist_vlpi_pending(GICv3CPUState *cs, int irq, int level)
{
    /*
     * Change the pending state of the specified vLPI.
     * Unlike gicv3_redist_process_vlpi(), we know here that the
     * vCPU is definitely resident on this redistributor, and that
     * the irq is in range.
     */
    uint64_t vptbase, ctbase;

    vptbase = FIELD_EX64(cs->gicr_vpendbaser, GICR_VPENDBASER, PHYADDR) << 16;

    if (set_pending_table_bit(cs, vptbase, irq, level)) {
        if (level) {
            /* Check whether this vLPI is now the best */
            ctbase = cs->gicr_vpropbaser & R_GICR_VPROPBASER_PHYADDR_MASK;
            update_for_one_lpi(cs, irq, ctbase, true, &cs->hppvlpi);
            gicv3_cpuif_virt_irq_fiq_update(cs);
        } else {
            /* Only need to recalculate if this was previously the best vLPI */
            if (irq == cs->hppvlpi.irq) {
                gicv3_redist_update_vlpi(cs);
            }
        }
    }
}

void gicv3_redist_process_vlpi(GICv3CPUState *cs, int irq, uint64_t vptaddr,
                               int doorbell, int level)
{
    bool bit_changed;
    bool resident = vcpu_resident(cs, vptaddr);
    uint64_t ctbase;

    if (resident) {
        uint32_t idbits = FIELD_EX64(cs->gicr_vpropbaser, GICR_VPROPBASER, IDBITS);
        if (irq >= (1ULL << (idbits + 1))) {
            return;
        }
    }

    bit_changed = set_pending_table_bit(cs, vptaddr, irq, level);
    if (resident && bit_changed) {
        if (level) {
            /* Check whether this vLPI is now the best */
            ctbase = cs->gicr_vpropbaser & R_GICR_VPROPBASER_PHYADDR_MASK;
            update_for_one_lpi(cs, irq, ctbase, true, &cs->hppvlpi);
            gicv3_cpuif_virt_irq_fiq_update(cs);
        } else {
            /* Only need to recalculate if this was previously the best vLPI */
            if (irq == cs->hppvlpi.irq) {
                gicv3_redist_update_vlpi(cs);
            }
        }
    }

    if (!resident && level && doorbell != INTID_SPURIOUS &&
        (cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
        /* vCPU is not currently resident: ring the doorbell */
        gicv3_redist_process_lpi(cs, doorbell, 1);
    }
}

void gicv3_redist_mov_vlpi(GICv3CPUState *src, uint64_t src_vptaddr,
                           GICv3CPUState *dest, uint64_t dest_vptaddr,
                           int irq, int doorbell)
{
    /*
     * Move the specified vLPI's pending state from the source redistributor
     * to the destination.
     */
    if (!set_pending_table_bit(src, src_vptaddr, irq, 0)) {
        /* Not pending on source, nothing to do */
        return;
    }
    if (vcpu_resident(src, src_vptaddr) && irq == src->hppvlpi.irq) {
        /*
         * Update src's cached highest-priority pending vLPI if we just made
         * it not-pending
         */
        gicv3_redist_update_vlpi(src);
    }
    /*
     * Mark the vLPI pending on the destination (ringing the doorbell
     * if the vCPU isn't resident)
     */
    gicv3_redist_process_vlpi(dest, irq, dest_vptaddr, doorbell, irq);
}

void gicv3_redist_vinvall(GICv3CPUState *cs, uint64_t vptaddr)
{
    if (!vcpu_resident(cs, vptaddr)) {
        /* We don't have anything cached if the vCPU isn't resident */
        return;
    }

    /* Otherwise, our only cached information is the HPPVLPI info */
    gicv3_redist_update_vlpi(cs);
}

void gicv3_redist_inv_vlpi(GICv3CPUState *cs, int irq, uint64_t vptaddr)
{
    /*
     * The only cached information for LPIs we have is the HPPLPI.
     * We could be cleverer about identifying when we don't need
     * to do a full rescan of the pending table, but until we find
     * this is a performance issue, just always recalculate.
     */
    gicv3_redist_vinvall(cs, vptaddr);
}

void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
{
    /* Update redistributor state for a change in an external PPI input line */
    if (level == extract32(cs->level, irq, 1)) {
        return;
    }

    trace_gicv3_redist_set_irq(gicv3_redist_affid(cs), irq, level);

    cs->level = deposit32(cs->level, irq, 1, level);

    if (level) {
        /* 0->1 edges latch the pending bit for edge-triggered interrupts */
        if (extract32(cs->edge_trigger, irq, 1)) {
            cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1);
        }
    }

    gicv3_redist_update(cs);
}

void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns)
{
    /* Update redistributor state for a generated SGI */
    int irqgrp = gicv3_irq_group(cs->gic, cs, irq);

    /* If we are asked for a Secure Group 1 SGI and it's actually
     * configured as Secure Group 0 this is OK (subject to the usual
     * NSACR checks).
     */
    if (grp == GICV3_G1 && irqgrp == GICV3_G0) {
        grp = GICV3_G0;
    }

    if (grp != irqgrp) {
        return;
    }

    if (ns && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
        /* If security is enabled we must test the NSACR bits */
        int nsaccess = gicr_ns_access(cs, irq);

        if ((irqgrp == GICV3_G0 && nsaccess < 1) ||
            (irqgrp == GICV3_G1 && nsaccess < 2)) {
            return;
        }
    }

    /* OK, we can accept the SGI */
    trace_gicv3_redist_send_sgi(gicv3_redist_affid(cs), irq);
    cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1);
    gicv3_redist_update(cs);
}
