/*
 * ARM Generic Interrupt Controller v3 (emulation)
 *
 * Copyright (c) 2016 Linaro Limited
 * Written by Peter Maydell
 *
 * This code is licensed under the GPL, version 2 or (at your option)
 * any later version.
 */

/* This file contains the code for the system register interface
 * portions of the GICv3.
 */

#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "trace.h"
#include "gicv3_internal.h"
#include "hw/irq.h"
#include "cpu.h"
#include "target/arm/cpregs.h"
#include "target/arm/cpu-features.h"
#include "sysemu/tcg.h"
#include "sysemu/qtest.h"

/*
 * Special case return value from hppvi_index(); must be larger than
 * the architecturally maximum possible list register index (which is 15)
 */
#define HPPVI_INDEX_VLPI 16

static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
{
    return env->gicv3state;
}

static bool gicv3_use_ns_bank(CPUARMState *env)
{
    /* Return true if we should use the NonSecure bank for a banked GIC
     * CPU interface register. Note that this differs from the
     * access_secure_reg() function because GICv3 banked registers are
     * banked even for AArch64, unlike the other CPU system registers.
     */
    return !arm_is_secure_below_el3(env);
}

/* The minimum BPR for the virtual interface is a configurable property */
static inline int icv_min_vbpr(GICv3CPUState *cs)
{
    return 7 - cs->vprebits;
}

static inline int ich_num_aprs(GICv3CPUState *cs)
{
    /* Return the number of virtual APR registers (1, 2, or 4) */
    int aprmax = 1 << (cs->vprebits - 5);
    assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
    return aprmax;
}

/* Simple accessor functions for LR fields */
static uint32_t ich_lr_vintid(uint64_t lr)
{
    return extract64(lr, ICH_LR_EL2_VINTID_SHIFT, ICH_LR_EL2_VINTID_LENGTH);
}

static uint32_t ich_lr_pintid(uint64_t lr)
{
    return extract64(lr, ICH_LR_EL2_PINTID_SHIFT, ICH_LR_EL2_PINTID_LENGTH);
}

static uint32_t ich_lr_prio(uint64_t lr)
{
    return extract64(lr, ICH_LR_EL2_PRIORITY_SHIFT, ICH_LR_EL2_PRIORITY_LENGTH);
}

static int ich_lr_state(uint64_t lr)
{
    return extract64(lr, ICH_LR_EL2_STATE_SHIFT, ICH_LR_EL2_STATE_LENGTH);
}

static bool icv_access(CPUARMState *env, int hcr_flags)
{
    /* Return true if this ICC_ register access should really be
     * directed to an ICV_ access. hcr_flags is a mask of
     * HCR_EL2 bits to check: we treat this as an ICV_ access
     * if we are in NS EL1 and at least one of the specified
     * HCR_EL2 bits is set.
     *
     * ICV registers fall into four categories:
     *  * access if NS EL1 and HCR_EL2.FMO == 1:
     *    all ICV regs with '0' in their name
     *  * access if NS EL1 and HCR_EL2.IMO == 1:
     *    all ICV regs with '1' in their name
     *  * access if NS EL1 and either IMO or FMO == 1:
     *    CTLR, DIR, PMR, RPR
     */
    uint64_t hcr_el2 = arm_hcr_el2_eff(env);
    bool flagmatch = hcr_el2 & hcr_flags & (HCR_IMO | HCR_FMO);

    return flagmatch && arm_current_el(env) == 1
        && !arm_is_secure_below_el3(env);
}

static int read_vbpr(GICv3CPUState *cs, int grp)
{
    /* Read VBPR value out of the VMCR field (caller must handle
     * VCBPR effects if required)
     */
    if (grp == GICV3_G0) {
        return extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VBPR0_SHIFT,
                     ICH_VMCR_EL2_VBPR0_LENGTH);
    } else {
        return extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VBPR1_SHIFT,
                         ICH_VMCR_EL2_VBPR1_LENGTH);
    }
}

static void write_vbpr(GICv3CPUState *cs, int grp, int value)
{
    /* Write new VBPR1 value, handling the "writing a value less than
     * the minimum sets it to the minimum" semantics.
     */
    int min = icv_min_vbpr(cs);

    if (grp != GICV3_G0) {
        min++;
    }

    value = MAX(value, min);

    if (grp == GICV3_G0) {
        cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VBPR0_SHIFT,
                                     ICH_VMCR_EL2_VBPR0_LENGTH, value);
    } else {
        cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VBPR1_SHIFT,
                                     ICH_VMCR_EL2_VBPR1_LENGTH, value);
    }
}

static uint32_t icv_fullprio_mask(GICv3CPUState *cs)
{
    /* Return a mask word which clears the unimplemented priority bits
     * from a priority value for a virtual interrupt. (Not to be confused
     * with the group priority, whose mask depends on the value of VBPR
     * for the interrupt group.)
     */
    return (~0U << (8 - cs->vpribits)) & 0xff;
}

static int ich_highest_active_virt_prio(GICv3CPUState *cs)
{
    /* Calculate the current running priority based on the set bits
     * in the ICH Active Priority Registers.
     */
    int i;
    int aprmax = ich_num_aprs(cs);

    if (cs->ich_apr[GICV3_G1NS][0] & ICV_AP1R_EL1_NMI) {
        return 0x0;
    }

    for (i = 0; i < aprmax; i++) {
        uint32_t apr = cs->ich_apr[GICV3_G0][i] |
            cs->ich_apr[GICV3_G1NS][i];

        if (!apr) {
            continue;
        }
        return (i * 32 + ctz32(apr)) << (icv_min_vbpr(cs) + 1);
    }
    /* No current active interrupts: return idle priority */
    return 0xff;
}

static int hppvi_index(GICv3CPUState *cs)
{
    /*
     * Return the list register index of the highest priority pending
     * virtual interrupt, as per the HighestPriorityVirtualInterrupt
     * pseudocode. If no pending virtual interrupts, return -1.
     * If the highest priority pending virtual interrupt is a vLPI,
     * return HPPVI_INDEX_VLPI.
     * (The pseudocode handles checking whether the vLPI is higher
     * priority than the highest priority list register at every
     * callsite of HighestPriorityVirtualInterrupt; we check it here.)
     */
    ARMCPU *cpu = ARM_CPU(cs->cpu);
    CPUARMState *env = &cpu->env;
    int idx = -1;
    int i;
    /* Note that a list register entry with a priority of 0xff will
     * never be reported by this function; this is the architecturally
     * correct behaviour.
     */
    int prio = 0xff;
    bool nmi = false;

    if (!(cs->ich_vmcr_el2 & (ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1))) {
        /* Both groups disabled, definitely nothing to do */
        return idx;
    }

    for (i = 0; i < cs->num_list_regs; i++) {
        uint64_t lr = cs->ich_lr_el2[i];
        bool thisnmi;
        int thisprio;

        if (ich_lr_state(lr) != ICH_LR_EL2_STATE_PENDING) {
            /* Not Pending */
            continue;
        }

        /* Ignore interrupts if relevant group enable not set */
        if (lr & ICH_LR_EL2_GROUP) {
            if (!(cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
                continue;
            }
        } else {
            if (!(cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
                continue;
            }
        }

        thisnmi = lr & ICH_LR_EL2_NMI;
        thisprio = ich_lr_prio(lr);

        if ((thisprio < prio) || ((thisprio == prio) && (thisnmi & (!nmi)))) {
            prio = thisprio;
            nmi = thisnmi;
            idx = i;
        }
    }

    /*
     * "no pending vLPI" is indicated with prio = 0xff, which always
     * fails the priority check here. vLPIs are only considered
     * when we are in Non-Secure state.
     */
    if (cs->hppvlpi.prio < prio && !arm_is_secure(env)) {
        if (cs->hppvlpi.grp == GICV3_G0) {
            if (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG0) {
                return HPPVI_INDEX_VLPI;
            }
        } else {
            if (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1) {
                return HPPVI_INDEX_VLPI;
            }
        }
    }

    return idx;
}

static uint32_t icv_gprio_mask(GICv3CPUState *cs, int group)
{
    /* Return a mask word which clears the subpriority bits from
     * a priority value for a virtual interrupt in the specified group.
     * This depends on the VBPR value.
     * If using VBPR0 then:
     *  a BPR of 0 means the group priority bits are [7:1];
     *  a BPR of 1 means they are [7:2], and so on down to
     *  a BPR of 7 meaning no group priority bits at all.
     * If using VBPR1 then:
     *  a BPR of 0 is impossible (the minimum value is 1)
     *  a BPR of 1 means the group priority bits are [7:1];
     *  a BPR of 2 means they are [7:2], and so on down to
     *  a BPR of 7 meaning the group priority is [7].
     *
     * Which BPR to use depends on the group of the interrupt and
     * the current ICH_VMCR_EL2.VCBPR settings.
     *
     * This corresponds to the VGroupBits() pseudocode.
     */
    int bpr;

    if (group == GICV3_G1NS && cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) {
        group = GICV3_G0;
    }

    bpr = read_vbpr(cs, group);
    if (group == GICV3_G1NS) {
        assert(bpr > 0);
        bpr--;
    }

    return ~0U << (bpr + 1);
}

static bool icv_hppi_can_preempt(GICv3CPUState *cs, uint64_t lr)
{
    /* Return true if we can signal this virtual interrupt defined by
     * the given list register value; see the pseudocode functions
     * CanSignalVirtualInterrupt and CanSignalVirtualInt.
     * Compare also icc_hppi_can_preempt() which is the non-virtual
     * equivalent of these checks.
     */
    int grp;
    bool is_nmi;
    uint32_t mask, prio, rprio, vpmr;

    if (!(cs->ich_hcr_el2 & ICH_HCR_EL2_EN)) {
        /* Virtual interface disabled */
        return false;
    }

    /* We don't need to check that this LR is in Pending state because
     * that has already been done in hppvi_index().
     */

    prio = ich_lr_prio(lr);
    is_nmi = lr & ICH_LR_EL2_NMI;
    vpmr = extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VPMR_SHIFT,
                     ICH_VMCR_EL2_VPMR_LENGTH);

    if (!is_nmi && prio >= vpmr) {
        /* Priority mask masks this interrupt */
        return false;
    }

    rprio = ich_highest_active_virt_prio(cs);
    if (rprio == 0xff) {
        /* No running interrupt so we can preempt */
        return true;
    }

    grp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;

    mask = icv_gprio_mask(cs, grp);

    /* We only preempt a running interrupt if the pending interrupt's
     * group priority is sufficient (the subpriorities are not considered).
     */
    if ((prio & mask) < (rprio & mask)) {
        return true;
    }

    if ((prio & mask) == (rprio & mask) && is_nmi &&
        !(cs->ich_apr[GICV3_G1NS][0] & ICV_AP1R_EL1_NMI)) {
        return true;
    }

    return false;
}

static bool icv_hppvlpi_can_preempt(GICv3CPUState *cs)
{
    /*
     * Return true if we can signal the highest priority pending vLPI.
     * We can assume we're Non-secure because hppvi_index() already
     * tested for that.
     */
    uint32_t mask, rprio, vpmr;

    if (!(cs->ich_hcr_el2 & ICH_HCR_EL2_EN)) {
        /* Virtual interface disabled */
        return false;
    }

    vpmr = extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VPMR_SHIFT,
                     ICH_VMCR_EL2_VPMR_LENGTH);

    if (cs->hppvlpi.prio >= vpmr) {
        /* Priority mask masks this interrupt */
        return false;
    }

    rprio = ich_highest_active_virt_prio(cs);
    if (rprio == 0xff) {
        /* No running interrupt so we can preempt */
        return true;
    }

    mask = icv_gprio_mask(cs, cs->hppvlpi.grp);

    /*
     * We only preempt a running interrupt if the pending interrupt's
     * group priority is sufficient (the subpriorities are not considered).
     */
    if ((cs->hppvlpi.prio & mask) < (rprio & mask)) {
        return true;
    }

    return false;
}

static uint32_t eoi_maintenance_interrupt_state(GICv3CPUState *cs,
                                                uint32_t *misr)
{
    /* Return a set of bits indicating the EOI maintenance interrupt status
     * for each list register. The EOI maintenance interrupt status is
     * 1 if LR.State == 0 && LR.HW == 0 && LR.EOI == 1
     * (see the GICv3 spec for the ICH_EISR_EL2 register).
     * If misr is not NULL then we should also collect the information
     * about the MISR.EOI, MISR.NP and MISR.U bits.
     */
    uint32_t value = 0;
    int validcount = 0;
    bool seenpending = false;
    int i;

    for (i = 0; i < cs->num_list_regs; i++) {
        uint64_t lr = cs->ich_lr_el2[i];

        if ((lr & (ICH_LR_EL2_STATE_MASK | ICH_LR_EL2_HW | ICH_LR_EL2_EOI))
            == ICH_LR_EL2_EOI) {
            value |= (1 << i);
        }
        if ((lr & ICH_LR_EL2_STATE_MASK)) {
            validcount++;
        }
        if (ich_lr_state(lr) == ICH_LR_EL2_STATE_PENDING) {
            seenpending = true;
        }
    }

    if (misr) {
        if (validcount < 2 && (cs->ich_hcr_el2 & ICH_HCR_EL2_UIE)) {
            *misr |= ICH_MISR_EL2_U;
        }
        if (!seenpending && (cs->ich_hcr_el2 & ICH_HCR_EL2_NPIE)) {
            *misr |= ICH_MISR_EL2_NP;
        }
        if (value) {
            *misr |= ICH_MISR_EL2_EOI;
        }
    }
    return value;
}

static uint32_t maintenance_interrupt_state(GICv3CPUState *cs)
{
    /* Return a set of bits indicating the maintenance interrupt status
     * (as seen in the ICH_MISR_EL2 register).
     */
    uint32_t value = 0;

    /* Scan list registers and fill in the U, NP and EOI bits */
    eoi_maintenance_interrupt_state(cs, &value);

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_LRENPIE) &&
        (cs->ich_hcr_el2 & ICH_HCR_EL2_EOICOUNT_MASK)) {
        value |= ICH_MISR_EL2_LRENP;
    }

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_VGRP0EIE) &&
        (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
        value |= ICH_MISR_EL2_VGRP0E;
    }

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) &&
        !(cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
        value |= ICH_MISR_EL2_VGRP0D;
    }
    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) &&
        (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
        value |= ICH_MISR_EL2_VGRP1E;
    }

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_VGRP1DIE) &&
        !(cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
        value |= ICH_MISR_EL2_VGRP1D;
    }

    return value;
}

void gicv3_cpuif_virt_irq_fiq_update(GICv3CPUState *cs)
{
    /*
     * Tell the CPU about any pending virtual interrupts.
     * This should only be called for changes that affect the
     * vIRQ and vFIQ status and do not change the maintenance
     * interrupt status. This means that unlike gicv3_cpuif_virt_update()
     * this function won't recursively call back into the GIC code.
     * The main use of this is when the redistributor has changed the
     * highest priority pending virtual LPI.
     */
    int idx;
    int irqlevel = 0;
    int fiqlevel = 0;
    int nmilevel = 0;

    idx = hppvi_index(cs);
    trace_gicv3_cpuif_virt_update(gicv3_redist_affid(cs), idx,
                                  cs->hppvlpi.irq, cs->hppvlpi.grp,
                                  cs->hppvlpi.prio);
    if (idx == HPPVI_INDEX_VLPI) {
        if (icv_hppvlpi_can_preempt(cs)) {
            if (cs->hppvlpi.grp == GICV3_G0) {
                fiqlevel = 1;
            } else {
                irqlevel = 1;
            }
        }
    } else if (idx >= 0) {
        uint64_t lr = cs->ich_lr_el2[idx];

        if (icv_hppi_can_preempt(cs, lr)) {
            /*
             * Virtual interrupts are simple: G0 are always FIQ, and G1 are
             * IRQ or NMI which depends on the ICH_LR<n>_EL2.NMI to have
             * non-maskable property.
             */
            if (lr & ICH_LR_EL2_GROUP) {
                if (lr & ICH_LR_EL2_NMI) {
                    nmilevel = 1;
                } else {
                    irqlevel = 1;
                }
            } else {
                fiqlevel = 1;
            }
        }
    }

    trace_gicv3_cpuif_virt_set_irqs(gicv3_redist_affid(cs), fiqlevel, irqlevel);
    qemu_set_irq(cs->parent_vfiq, fiqlevel);
    qemu_set_irq(cs->parent_virq, irqlevel);
    qemu_set_irq(cs->parent_vnmi, nmilevel);
}

static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
{
    /*
     * Tell the CPU about any pending virtual interrupts or
     * maintenance interrupts, following a change to the state
     * of the CPU interface relevant to virtual interrupts.
     *
     * CAUTION: this function will call qemu_set_irq() on the
     * CPU maintenance IRQ line, which is typically wired up
     * to the GIC as a per-CPU interrupt. This means that it
     * will recursively call back into the GIC code via
     * gicv3_redist_set_irq() and thus into the CPU interface code's
     * gicv3_cpuif_update(). It is therefore important that this
     * function is only called as the final action of a CPU interface
     * register write implementation, after all the GIC state
     * fields have been updated. gicv3_cpuif_update() also must
     * not cause this function to be called, but that happens
     * naturally as a result of there being no architectural
     * linkage between the physical and virtual GIC logic.
     */
    ARMCPU *cpu = ARM_CPU(cs->cpu);
    int maintlevel = 0;

    gicv3_cpuif_virt_irq_fiq_update(cs);

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_EN) &&
        maintenance_interrupt_state(cs) != 0) {
        maintlevel = 1;
    }

    trace_gicv3_cpuif_virt_set_maint_irq(gicv3_redist_affid(cs), maintlevel);
    qemu_set_irq(cpu->gicv3_maintenance_interrupt, maintlevel);
}

static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int regno = ri->opc2 & 3;
    int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
    uint64_t value = cs->ich_apr[grp][regno];

    trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
    return value;
}

static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int regno = ri->opc2 & 3;
    int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;

    trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);

    if (cs->nmi_support) {
        cs->ich_apr[grp][regno] = value & (0xFFFFFFFFU | ICV_AP1R_EL1_NMI);
    } else {
        cs->ich_apr[grp][regno] = value & 0xFFFFFFFFU;
    }

    gicv3_cpuif_virt_irq_fiq_update(cs);
    return;
}

static uint64_t icv_bpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1NS;
    uint64_t bpr;
    bool satinc = false;

    if (grp == GICV3_G1NS && (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
        /* reads return bpr0 + 1 saturated to 7, writes ignored */
        grp = GICV3_G0;
        satinc = true;
    }

    bpr = read_vbpr(cs, grp);

    if (satinc) {
        bpr++;
        bpr = MIN(bpr, 7);
    }

    trace_gicv3_icv_bpr_read(ri->crm == 8 ? 0 : 1, gicv3_redist_affid(cs), bpr);

    return bpr;
}

static void icv_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1NS;

    trace_gicv3_icv_bpr_write(ri->crm == 8 ? 0 : 1,
                              gicv3_redist_affid(cs), value);

    if (grp == GICV3_G1NS && (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
        /* reads return bpr0 + 1 saturated to 7, writes ignored */
        return;
    }

    write_vbpr(cs, grp, value);

    gicv3_cpuif_virt_irq_fiq_update(cs);
}

static uint64_t icv_pmr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value;

    value = extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VPMR_SHIFT,
                      ICH_VMCR_EL2_VPMR_LENGTH);

    trace_gicv3_icv_pmr_read(gicv3_redist_affid(cs), value);
    return value;
}

static void icv_pmr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    trace_gicv3_icv_pmr_write(gicv3_redist_affid(cs), value);

    value &= icv_fullprio_mask(cs);

    cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VPMR_SHIFT,
                                 ICH_VMCR_EL2_VPMR_LENGTH, value);

    gicv3_cpuif_virt_irq_fiq_update(cs);
}

static uint64_t icv_igrpen_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int enbit;
    uint64_t value;

    enbit = ri->opc2 & 1 ? ICH_VMCR_EL2_VENG1_SHIFT : ICH_VMCR_EL2_VENG0_SHIFT;
    value = extract64(cs->ich_vmcr_el2, enbit, 1);

    trace_gicv3_icv_igrpen_read(ri->opc2 & 1 ? 1 : 0,
                                gicv3_redist_affid(cs), value);
    return value;
}

static void icv_igrpen_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int enbit;

    trace_gicv3_icv_igrpen_write(ri->opc2 & 1 ? 1 : 0,
                                 gicv3_redist_affid(cs), value);

    enbit = ri->opc2 & 1 ? ICH_VMCR_EL2_VENG1_SHIFT : ICH_VMCR_EL2_VENG0_SHIFT;

    cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, enbit, 1, value);
    gicv3_cpuif_virt_update(cs);
}

static uint64_t icv_ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value;

    /* Note that the fixed fields here (A3V, SEIS, IDbits, PRIbits)
     * should match the ones reported in ich_vtr_read().
     */
    value = ICC_CTLR_EL1_A3V | (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
        ((cs->vpribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);

    if (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM) {
        value |= ICC_CTLR_EL1_EOIMODE;
    }

    if (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) {
        value |= ICC_CTLR_EL1_CBPR;
    }

    trace_gicv3_icv_ctlr_read(gicv3_redist_affid(cs), value);
    return value;
}

static void icv_ctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                               uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    trace_gicv3_icv_ctlr_write(gicv3_redist_affid(cs), value);

    cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VCBPR_SHIFT,
                                 1, value & ICC_CTLR_EL1_CBPR ? 1 : 0);
    cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VEOIM_SHIFT,
                                 1, value & ICC_CTLR_EL1_EOIMODE ? 1 : 0);

    gicv3_cpuif_virt_irq_fiq_update(cs);
}

static uint64_t icv_rpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t prio = ich_highest_active_virt_prio(cs);

    if (cs->ich_apr[GICV3_G1NS][0] & ICV_AP1R_EL1_NMI) {
        prio |= ICV_RPR_EL1_NMI;
    }

    trace_gicv3_icv_rpr_read(gicv3_redist_affid(cs), prio);
    return prio;
}

static uint64_t icv_hppir_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp = ri->crm == 8 ? GICV3_G0 : GICV3_G1NS;
    int idx = hppvi_index(cs);
    uint64_t value = INTID_SPURIOUS;

    if (idx == HPPVI_INDEX_VLPI) {
        if (cs->hppvlpi.grp == grp) {
            value = cs->hppvlpi.irq;
        }
    } else if (idx >= 0) {
        uint64_t lr = cs->ich_lr_el2[idx];
        int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;

        if (grp == thisgrp) {
            value = ich_lr_vintid(lr);
        }
    }

    trace_gicv3_icv_hppir_read(ri->crm == 8 ? 0 : 1,
                               gicv3_redist_affid(cs), value);
    return value;
}

static void icv_activate_irq(GICv3CPUState *cs, int idx, int grp)
{
    /* Activate the interrupt in the specified list register
     * by moving it from Pending to Active state, and update the
     * Active Priority Registers.
     */
    uint32_t mask = icv_gprio_mask(cs, grp);
    int prio = ich_lr_prio(cs->ich_lr_el2[idx]) & mask;
    bool nmi = cs->ich_lr_el2[idx] & ICH_LR_EL2_NMI;
    int aprbit = prio >> (8 - cs->vprebits);
    int regno = aprbit / 32;
    int regbit = aprbit % 32;

    cs->ich_lr_el2[idx] &= ~ICH_LR_EL2_STATE_PENDING_BIT;
    cs->ich_lr_el2[idx] |= ICH_LR_EL2_STATE_ACTIVE_BIT;

    if (nmi) {
        cs->ich_apr[grp][regno] |= ICV_AP1R_EL1_NMI;
    } else {
        cs->ich_apr[grp][regno] |= (1U << regbit);
    }
}

static void icv_activate_vlpi(GICv3CPUState *cs)
{
    uint32_t mask = icv_gprio_mask(cs, cs->hppvlpi.grp);
    int prio = cs->hppvlpi.prio & mask;
    int aprbit = prio >> (8 - cs->vprebits);
    int regno = aprbit / 32;
    int regbit = aprbit % 32;

    cs->ich_apr[cs->hppvlpi.grp][regno] |= (1U << regbit);
    gicv3_redist_vlpi_pending(cs, cs->hppvlpi.irq, 0);
}

static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp = ri->crm == 8 ? GICV3_G0 : GICV3_G1NS;
    int idx = hppvi_index(cs);
    uint64_t intid = INTID_SPURIOUS;
    int el = arm_current_el(env);

    if (idx == HPPVI_INDEX_VLPI) {
        if (cs->hppvlpi.grp == grp && icv_hppvlpi_can_preempt(cs)) {
            intid = cs->hppvlpi.irq;
            icv_activate_vlpi(cs);
        }
    } else if (idx >= 0) {
        uint64_t lr = cs->ich_lr_el2[idx];
        int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
        bool nmi = env->cp15.sctlr_el[el] & SCTLR_NMI && lr & ICH_LR_EL2_NMI;

        if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) {
            intid = ich_lr_vintid(lr);
            if (!gicv3_intid_is_special(intid)) {
                if (!nmi) {
                    icv_activate_irq(cs, idx, grp);
                } else {
                    intid = INTID_NMI;
                }
            } else {
                /* Interrupt goes from Pending to Invalid */
                cs->ich_lr_el2[idx] &= ~ICH_LR_EL2_STATE_PENDING_BIT;
                /* We will now return the (bogus) ID from the list register,
                 * as per the pseudocode.
                 */
            }
        }
    }

    trace_gicv3_icv_iar_read(ri->crm == 8 ? 0 : 1,
                             gicv3_redist_affid(cs), intid);

    gicv3_cpuif_virt_update(cs);

    return intid;
}

static uint64_t icv_nmiar1_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int idx = hppvi_index(cs);
    uint64_t intid = INTID_SPURIOUS;

    if (idx >= 0 && idx != HPPVI_INDEX_VLPI) {
        uint64_t lr = cs->ich_lr_el2[idx];
        int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;

        if ((thisgrp == GICV3_G1NS) && icv_hppi_can_preempt(cs, lr)) {
            intid = ich_lr_vintid(lr);
            if (!gicv3_intid_is_special(intid)) {
                if (lr & ICH_LR_EL2_NMI) {
                    icv_activate_irq(cs, idx, GICV3_G1NS);
                } else {
                    intid = INTID_SPURIOUS;
                }
            } else {
                /* Interrupt goes from Pending to Invalid */
                cs->ich_lr_el2[idx] &= ~ICH_LR_EL2_STATE_PENDING_BIT;
                /*
                 * We will now return the (bogus) ID from the list register,
                 * as per the pseudocode.
                 */
            }
        }
    }

    trace_gicv3_icv_nmiar1_read(gicv3_redist_affid(cs), intid);

    gicv3_cpuif_virt_update(cs);

    return intid;
}

static uint32_t icc_fullprio_mask(GICv3CPUState *cs)
{
    /*
     * Return a mask word which clears the unimplemented priority bits
     * from a priority value for a physical interrupt. (Not to be confused
     * with the group priority, whose mask depends on the value of BPR
     * for the interrupt group.)
     */
    return (~0U << (8 - cs->pribits)) & 0xff;
}

static inline int icc_min_bpr(GICv3CPUState *cs)
{
    /* The minimum BPR for the physical interface. */
    return 7 - cs->prebits;
}

static inline int icc_min_bpr_ns(GICv3CPUState *cs)
{
    return icc_min_bpr(cs) + 1;
}

static inline int icc_num_aprs(GICv3CPUState *cs)
{
    /* Return the number of APR registers (1, 2, or 4) */
    int aprmax = 1 << MAX(cs->prebits - 5, 0);
    assert(aprmax <= ARRAY_SIZE(cs->icc_apr[0]));
    return aprmax;
}

static int icc_highest_active_prio(GICv3CPUState *cs)
{
    /* Calculate the current running priority based on the set bits
     * in the Active Priority Registers.
     */
    int i;

    if (cs->nmi_support) {
        /*
         * If an NMI is active this takes precedence over anything else
         * for priority purposes; the NMI bit is only in the AP1R0 bit.
         * We return here the effective priority of the NMI, which is
         * either 0x0 or 0x80. Callers will need to check NMI again for
         * purposes of either setting the RPR register bits or for
         * prioritization of NMI vs non-NMI.
         */
        if (cs->icc_apr[GICV3_G1][0] & ICC_AP1R_EL1_NMI) {
            return 0;
        }
        if (cs->icc_apr[GICV3_G1NS][0] & ICC_AP1R_EL1_NMI) {
            return (cs->gic->gicd_ctlr & GICD_CTLR_DS) ? 0 : 0x80;
        }
    }

    for (i = 0; i < icc_num_aprs(cs); i++) {
        uint32_t apr = cs->icc_apr[GICV3_G0][i] |
            cs->icc_apr[GICV3_G1][i] | cs->icc_apr[GICV3_G1NS][i];

        if (!apr) {
            continue;
        }
        return (i * 32 + ctz32(apr)) << (icc_min_bpr(cs) + 1);
    }
    /* No current active interrupts: return idle priority */
    return 0xff;
}

static uint32_t icc_gprio_mask(GICv3CPUState *cs, int group)
{
    /* Return a mask word which clears the subpriority bits from
     * a priority value for an interrupt in the specified group.
     * This depends on the BPR value. For CBPR0 (S or NS):
     *  a BPR of 0 means the group priority bits are [7:1];
     *  a BPR of 1 means they are [7:2], and so on down to
     *  a BPR of 7 meaning no group priority bits at all.
     * For CBPR1 NS:
     *  a BPR of 0 is impossible (the minimum value is 1)
     *  a BPR of 1 means the group priority bits are [7:1];
     *  a BPR of 2 means they are [7:2], and so on down to
     *  a BPR of 7 meaning the group priority is [7].
     *
     * Which BPR to use depends on the group of the interrupt and
     * the current ICC_CTLR.CBPR settings.
     *
     * This corresponds to the GroupBits() pseudocode.
     */
    int bpr;

    if ((group == GICV3_G1 && cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR) ||
        (group == GICV3_G1NS &&
         cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) {
        group = GICV3_G0;
    }

    bpr = cs->icc_bpr[group] & 7;

    if (group == GICV3_G1NS) {
        assert(bpr > 0);
        bpr--;
    }

    return ~0U << (bpr + 1);
}

static bool icc_no_enabled_hppi(GICv3CPUState *cs)
{
    /* Return true if there is no pending interrupt, or the
     * highest priority pending interrupt is in a group which has been
     * disabled at the CPU interface by the ICC_IGRPEN* register enable bits.
     */
    return cs->hppi.prio == 0xff || (cs->icc_igrpen[cs->hppi.grp] == 0);
}

static bool icc_hppi_can_preempt(GICv3CPUState *cs)
{
    /* Return true if we have a pending interrupt of sufficient
     * priority to preempt.
     */
    int rprio;
    uint32_t mask;
    ARMCPU *cpu = ARM_CPU(cs->cpu);
    CPUARMState *env = &cpu->env;

    if (icc_no_enabled_hppi(cs)) {
        return false;
    }

    if (cs->hppi.nmi) {
        if (!(cs->gic->gicd_ctlr & GICD_CTLR_DS) &&
            cs->hppi.grp == GICV3_G1NS) {
            if (cs->icc_pmr_el1 < 0x80) {
                return false;
            }
            if (arm_is_secure(env) && cs->icc_pmr_el1 == 0x80) {
                return false;
            }
        }
    } else if (cs->hppi.prio >= cs->icc_pmr_el1) {
        /* Priority mask masks this interrupt */
        return false;
    }

    rprio = icc_highest_active_prio(cs);
    if (rprio == 0xff) {
        /* No currently running interrupt so we can preempt */
        return true;
    }

    mask = icc_gprio_mask(cs, cs->hppi.grp);

    /* We only preempt a running interrupt if the pending interrupt's
     * group priority is sufficient (the subpriorities are not considered).
     */
    if ((cs->hppi.prio & mask) < (rprio & mask)) {
        return true;
    }

    if (cs->hppi.nmi && (cs->hppi.prio & mask) == (rprio & mask)) {
        if (!(cs->icc_apr[cs->hppi.grp][0] & ICC_AP1R_EL1_NMI)) {
            return true;
        }
    }

    return false;
}

void gicv3_cpuif_update(GICv3CPUState *cs)
{
    /* Tell the CPU about its highest priority pending interrupt */
    int irqlevel = 0;
    int fiqlevel = 0;
    int nmilevel = 0;
    ARMCPU *cpu = ARM_CPU(cs->cpu);
    CPUARMState *env = &cpu->env;

    g_assert(bql_locked());

    trace_gicv3_cpuif_update(gicv3_redist_affid(cs), cs->hppi.irq,
                             cs->hppi.grp, cs->hppi.prio);

    if (cs->hppi.grp == GICV3_G1 && !arm_feature(env, ARM_FEATURE_EL3)) {
        /* If a Security-enabled GIC sends a G1S interrupt to a
         * Security-disabled CPU, we must treat it as if it were G0.
         */
        cs->hppi.grp = GICV3_G0;
    }

    if (icc_hppi_can_preempt(cs)) {
        /* We have an interrupt: should we signal it as IRQ or FIQ?
         * This is described in the GICv3 spec section 4.6.2.
         */
        bool isfiq;

        switch (cs->hppi.grp) {
        case GICV3_G0:
            isfiq = true;
            break;
        case GICV3_G1:
            isfiq = (!arm_is_secure(env) ||
                     (arm_current_el(env) == 3 && arm_el_is_aa64(env, 3)));
            break;
        case GICV3_G1NS:
            isfiq = arm_is_secure(env);
            break;
        default:
            g_assert_not_reached();
        }

        if (isfiq) {
            fiqlevel = 1;
        } else if (cs->hppi.nmi) {
            nmilevel = 1;
        } else {
            irqlevel = 1;
        }
    }

    trace_gicv3_cpuif_set_irqs(gicv3_redist_affid(cs), fiqlevel, irqlevel);

    qemu_set_irq(cs->parent_fiq, fiqlevel);
    qemu_set_irq(cs->parent_irq, irqlevel);
    qemu_set_irq(cs->parent_nmi, nmilevel);
}

static uint64_t icc_pmr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint32_t value = cs->icc_pmr_el1;

    if (icv_access(env, HCR_FMO | HCR_IMO)) {
        return icv_pmr_read(env, ri);
    }

    if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env) &&
        (env->cp15.scr_el3 & SCR_FIQ)) {
        /* NS access and Group 0 is inaccessible to NS: return the
         * NS view of the current priority
         */
        if ((value & 0x80) == 0) {
            /* Secure priorities not visible to NS */
            value = 0;
        } else if (value != 0xff) {
            value = (value << 1) & 0xff;
        }
    }

    trace_gicv3_icc_pmr_read(gicv3_redist_affid(cs), value);

    return value;
}

static void icc_pmr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    if (icv_access(env, HCR_FMO | HCR_IMO)) {
        return icv_pmr_write(env, ri, value);
    }

    trace_gicv3_icc_pmr_write(gicv3_redist_affid(cs), value);

    if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env) &&
        (env->cp15.scr_el3 & SCR_FIQ)) {
        /* NS access and Group 0 is inaccessible to NS: return the
         * NS view of the current priority
         */
        if (!(cs->icc_pmr_el1 & 0x80)) {
            /* Current PMR in the secure range, don't allow NS to change it */
            return;
        }
        value = (value >> 1) | 0x80;
    }
    value &= icc_fullprio_mask(cs);
    cs->icc_pmr_el1 = value;
    gicv3_cpuif_update(cs);
}

static void icc_activate_irq(GICv3CPUState *cs, int irq)
{
    /* Move the interrupt from the Pending state to Active, and update
     * the Active Priority Registers
     */
    uint32_t mask = icc_gprio_mask(cs, cs->hppi.grp);
    int prio = cs->hppi.prio & mask;
    int aprbit = prio >> (8 - cs->prebits);
    int regno = aprbit / 32;
    int regbit = aprbit % 32;
    bool nmi = cs->hppi.nmi;

    if (nmi) {
        cs->icc_apr[cs->hppi.grp][regno] |= ICC_AP1R_EL1_NMI;
    } else {
        cs->icc_apr[cs->hppi.grp][regno] |= (1U << regbit);
    }

    if (irq < GIC_INTERNAL) {
        cs->gicr_iactiver0 = deposit32(cs->gicr_iactiver0, irq, 1, 1);
        cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 0);
        gicv3_redist_update(cs);
    } else if (irq < GICV3_LPI_INTID_START) {
        gicv3_gicd_active_set(cs->gic, irq);
        gicv3_gicd_pending_clear(cs->gic, irq);
        gicv3_update(cs->gic, irq, 1);
    } else {
        gicv3_redist_lpi_pending(cs, irq, 0);
    }
}

static uint64_t icc_hppir0_value(GICv3CPUState *cs, CPUARMState *env)
{
    /* Return the highest priority pending interrupt register value
     * for group 0.
     */
    bool irq_is_secure;

    if (icc_no_enabled_hppi(cs)) {
        return INTID_SPURIOUS;
    }

    /* Check whether we can return the interrupt or if we should return
     * a special identifier, as per the CheckGroup0ForSpecialIdentifiers
     * pseudocode. (We can simplify a little because for us ICC_SRE_EL1.RM
     * is always zero.)
     */
    irq_is_secure = (!(cs->gic->gicd_ctlr & GICD_CTLR_DS) &&
                     (cs->hppi.grp != GICV3_G1NS));

    if (cs->hppi.grp != GICV3_G0 && !arm_is_el3_or_mon(env)) {
        return INTID_SPURIOUS;
    }
    if (irq_is_secure && !arm_is_secure(env)) {
        /* Secure interrupts not visible to Nonsecure */
        return INTID_SPURIOUS;
    }

    if (cs->hppi.grp != GICV3_G0) {
        /* Indicate to EL3 that there's a Group 1 interrupt for the other
         * state pending.
         */
        return irq_is_secure ? INTID_SECURE : INTID_NONSECURE;
    }

    return cs->hppi.irq;
}

static uint64_t icc_hppir1_value(GICv3CPUState *cs, CPUARMState *env)
{
    /* Return the highest priority pending interrupt register value
     * for group 1.
     */
    bool irq_is_secure;

    if (icc_no_enabled_hppi(cs)) {
        return INTID_SPURIOUS;
    }

    /* Check whether we can return the interrupt or if we should return
     * a special identifier, as per the CheckGroup1ForSpecialIdentifiers
     * pseudocode. (We can simplify a little because for us ICC_SRE_EL1.RM
     * is always zero.)
     */
    irq_is_secure = (!(cs->gic->gicd_ctlr & GICD_CTLR_DS) &&
                     (cs->hppi.grp != GICV3_G1NS));

    if (cs->hppi.grp == GICV3_G0) {
        /* Group 0 interrupts not visible via HPPIR1 */
        return INTID_SPURIOUS;
    }
    if (irq_is_secure) {
        if (!arm_is_secure(env)) {
            /* Secure interrupts not visible in Non-secure */
            return INTID_SPURIOUS;
        }
    } else if (!arm_is_el3_or_mon(env) && arm_is_secure(env)) {
        /* Group 1 non-secure interrupts not visible in Secure EL1 */
        return INTID_SPURIOUS;
    }

    return cs->hppi.irq;
}

static uint64_t icc_iar0_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t intid;

    if (icv_access(env, HCR_FMO)) {
        return icv_iar_read(env, ri);
    }

    if (!icc_hppi_can_preempt(cs)) {
        intid = INTID_SPURIOUS;
    } else {
        intid = icc_hppir0_value(cs, env);
    }

    if (!gicv3_intid_is_special(intid)) {
        icc_activate_irq(cs, intid);
    }

    trace_gicv3_icc_iar0_read(gicv3_redist_affid(cs), intid);
    return intid;
}

static uint64_t icc_iar1_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int el = arm_current_el(env);
    uint64_t intid;

    if (icv_access(env, HCR_IMO)) {
        return icv_iar_read(env, ri);
    }

    if (!icc_hppi_can_preempt(cs)) {
        intid = INTID_SPURIOUS;
    } else {
        intid = icc_hppir1_value(cs, env);
    }

    if (!gicv3_intid_is_special(intid)) {
        if (cs->hppi.nmi && env->cp15.sctlr_el[el] & SCTLR_NMI) {
            intid = INTID_NMI;
        } else {
            icc_activate_irq(cs, intid);
        }
    }

    trace_gicv3_icc_iar1_read(gicv3_redist_affid(cs), intid);
    return intid;
}

static uint64_t icc_nmiar1_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t intid;

    if (icv_access(env, HCR_IMO)) {
        return icv_nmiar1_read(env, ri);
    }

    if (!icc_hppi_can_preempt(cs)) {
        intid = INTID_SPURIOUS;
    } else {
        intid = icc_hppir1_value(cs, env);
    }

    if (!gicv3_intid_is_special(intid)) {
        if (!cs->hppi.nmi) {
            intid = INTID_SPURIOUS;
        } else {
            icc_activate_irq(cs, intid);
        }
    }

    trace_gicv3_icc_nmiar1_read(gicv3_redist_affid(cs), intid);
    return intid;
}

static void icc_drop_prio(GICv3CPUState *cs, int grp)
{
    /* Drop the priority of the currently active interrupt in
     * the specified group.
     *
     * Note that we can guarantee (because of the requirement to nest
     * ICC_IAR reads [which activate an interrupt and raise priority]
     * with ICC_EOIR writes [which drop the priority for the interrupt])
     * that the interrupt we're being called for is the highest priority
     * active interrupt, meaning that it has the lowest set bit in the
     * APR registers.
     *
     * If the guest does not honour the ordering constraints then the
     * behaviour of the GIC is UNPREDICTABLE, which for us means that
     * the values of the APR registers might become incorrect and the
     * running priority will be wrong, so interrupts that should preempt
     * might not do so, and interrupts that should not preempt might do so.
     */
    int i;

    for (i = 0; i < icc_num_aprs(cs); i++) {
        uint64_t *papr = &cs->icc_apr[grp][i];

        if (!*papr) {
            continue;
        }

        if (i == 0 && cs->nmi_support && (*papr & ICC_AP1R_EL1_NMI)) {
            *papr &= (~ICC_AP1R_EL1_NMI);
            break;
        }

        /* Clear the lowest set bit */
        *papr &= *papr - 1;
        break;
    }

    /* running priority change means we need an update for this cpu i/f */
    gicv3_cpuif_update(cs);
}

static bool icc_eoi_split(CPUARMState *env, GICv3CPUState *cs)
{
    /* Return true if we should split priority drop and interrupt
     * deactivation, ie whether the relevant EOIMode bit is set.
     */
    if (arm_is_el3_or_mon(env)) {
        return cs->icc_ctlr_el3 & ICC_CTLR_EL3_EOIMODE_EL3;
    }
    if (arm_is_secure_below_el3(env)) {
        return cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_EOIMODE;
    } else {
        return cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_EOIMODE;
    }
}

static int icc_highest_active_group(GICv3CPUState *cs)
{
    /* Return the group with the highest priority active interrupt.
     * We can do this by just comparing the APRs to see which one
     * has the lowest set bit.
     * (If more than one group is active at the same priority then
     * we're in UNPREDICTABLE territory.)
     */
    int i;

    if (cs->nmi_support) {
        if (cs->icc_apr[GICV3_G1][0] & ICC_AP1R_EL1_NMI) {
            return GICV3_G1;
        }
        if (cs->icc_apr[GICV3_G1NS][0] & ICC_AP1R_EL1_NMI) {
            return GICV3_G1NS;
        }
    }

    for (i = 0; i < ARRAY_SIZE(cs->icc_apr[0]); i++) {
        int g0ctz = ctz32(cs->icc_apr[GICV3_G0][i]);
        int g1ctz = ctz32(cs->icc_apr[GICV3_G1][i]);
        int g1nsctz = ctz32(cs->icc_apr[GICV3_G1NS][i]);

        if (g1nsctz < g0ctz && g1nsctz < g1ctz) {
            return GICV3_G1NS;
        }
        if (g1ctz < g0ctz) {
            return GICV3_G1;
        }
        if (g0ctz < 32) {
            return GICV3_G0;
        }
    }
    /* No set active bits? UNPREDICTABLE; return -1 so the caller
     * ignores the spurious EOI attempt.
     */
    return -1;
}

static void icc_deactivate_irq(GICv3CPUState *cs, int irq)
{
    if (irq < GIC_INTERNAL) {
        cs->gicr_iactiver0 = deposit32(cs->gicr_iactiver0, irq, 1, 0);
        gicv3_redist_update(cs);
    } else {
        gicv3_gicd_active_clear(cs->gic, irq);
        gicv3_update(cs->gic, irq, 1);
    }
}

static bool icv_eoi_split(CPUARMState *env, GICv3CPUState *cs)
{
    /* Return true if we should split priority drop and interrupt
     * deactivation, ie whether the virtual EOIMode bit is set.
     */
    return cs->ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM;
}

static int icv_find_active(GICv3CPUState *cs, int irq)
{
    /* Given an interrupt number for an active interrupt, return the index
     * of the corresponding list register, or -1 if there is no match.
     * Corresponds to FindActiveVirtualInterrupt pseudocode.
     */
    int i;

    for (i = 0; i < cs->num_list_regs; i++) {
        uint64_t lr = cs->ich_lr_el2[i];

        if ((lr & ICH_LR_EL2_STATE_ACTIVE_BIT) && ich_lr_vintid(lr) == irq) {
            return i;
        }
    }

    return -1;
}

static void icv_deactivate_irq(GICv3CPUState *cs, int idx)
{
    /* Deactivate the interrupt in the specified list register index */
    uint64_t lr = cs->ich_lr_el2[idx];

    if (lr & ICH_LR_EL2_HW) {
        /* Deactivate the associated physical interrupt */
        int pirq = ich_lr_pintid(lr);

        if (pirq < INTID_SECURE) {
            icc_deactivate_irq(cs, pirq);
        }
    }

    /* Clear the 'active' part of the state, so ActivePending->Pending
     * and Active->Invalid.
     */
    lr &= ~ICH_LR_EL2_STATE_ACTIVE_BIT;
    cs->ich_lr_el2[idx] = lr;
}

static void icv_increment_eoicount(GICv3CPUState *cs)
{
    /* Increment the EOICOUNT field in ICH_HCR_EL2 */
    int eoicount = extract64(cs->ich_hcr_el2, ICH_HCR_EL2_EOICOUNT_SHIFT,
                             ICH_HCR_EL2_EOICOUNT_LENGTH);

    cs->ich_hcr_el2 = deposit64(cs->ich_hcr_el2, ICH_HCR_EL2_EOICOUNT_SHIFT,
                                ICH_HCR_EL2_EOICOUNT_LENGTH, eoicount + 1);
}

static int icv_drop_prio(GICv3CPUState *cs, bool *nmi)
{
    /* Drop the priority of the currently active virtual interrupt
     * (favouring group 0 if there is a set active bit at
     * the same priority for both group 0 and group 1).
     * Return the priority value for the bit we just cleared,
     * or 0xff if no bits were set in the AP registers at all.
     * Note that though the ich_apr[] are uint64_t only the low
     * 32 bits are actually relevant.
     */
    int i;
    int aprmax = ich_num_aprs(cs);

    for (i = 0; i < aprmax; i++) {
        uint64_t *papr0 = &cs->ich_apr[GICV3_G0][i];
        uint64_t *papr1 = &cs->ich_apr[GICV3_G1NS][i];
        int apr0count, apr1count;

        if (!*papr0 && !*papr1) {
            continue;
        }

        if (i == 0 && cs->nmi_support && (*papr1 & ICV_AP1R_EL1_NMI)) {
            *papr1 &= (~ICV_AP1R_EL1_NMI);
            *nmi = true;
            return 0xff;
        }

        /* We can't just use the bit-twiddling hack icc_drop_prio() does
         * because we need to return the bit number we cleared so
         * it can be compared against the list register's priority field.
         */
        apr0count = ctz32(*papr0);
        apr1count = ctz32(*papr1);

        if (apr0count <= apr1count) {
            *papr0 &= *papr0 - 1;
            return (apr0count + i * 32) << (icv_min_vbpr(cs) + 1);
        } else {
            *papr1 &= *papr1 - 1;
            return (apr1count + i * 32) << (icv_min_vbpr(cs) + 1);
        }
    }
    return 0xff;
}

static void icv_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
{
    /* Deactivate interrupt */
    GICv3CPUState *cs = icc_cs_from_env(env);
    int idx;
    int irq = value & 0xffffff;

    trace_gicv3_icv_dir_write(gicv3_redist_affid(cs), value);

    if (irq >= GICV3_MAXIRQ) {
        /* Also catches special interrupt numbers and LPIs */
        return;
    }

    if (!icv_eoi_split(env, cs)) {
        return;
    }

    idx = icv_find_active(cs, irq);

    if (idx < 0) {
        /* No list register matching this, so increment the EOI count
         * (might trigger a maintenance interrupt)
         */
        icv_increment_eoicount(cs);
    } else {
        icv_deactivate_irq(cs, idx);
    }

    gicv3_cpuif_virt_update(cs);
}

static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
                           uint64_t value)
{
    /* End of Interrupt */
    GICv3CPUState *cs = icc_cs_from_env(env);
    int irq = value & 0xffffff;
    int grp = ri->crm == 8 ? GICV3_G0 : GICV3_G1NS;
    int idx, dropprio;
    bool nmi = false;

    trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1,
                               gicv3_redist_affid(cs), value);

    if (gicv3_intid_is_special(irq)) {
        return;
    }

    /* We implement the IMPDEF choice of "drop priority before doing
     * error checks" (because that lets us avoid scanning the AP
     * registers twice).
     */
    dropprio = icv_drop_prio(cs, &nmi);
    if (dropprio == 0xff && !nmi) {
        /* No active interrupt. It is CONSTRAINED UNPREDICTABLE
         * whether the list registers are checked in this
         * situation; we choose not to.
         */
        return;
    }

    idx = icv_find_active(cs, irq);

    if (idx < 0) {
        /*
         * No valid list register corresponding to EOI ID; if this is a vLPI
         * not in the list regs then do nothing; otherwise increment EOI count
         */
        if (irq < GICV3_LPI_INTID_START) {
            icv_increment_eoicount(cs);
        }
    } else {
        uint64_t lr = cs->ich_lr_el2[idx];
        int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
        int lr_gprio = ich_lr_prio(lr) & icv_gprio_mask(cs, grp);
        bool thisnmi = lr & ICH_LR_EL2_NMI;

        if (thisgrp == grp && (lr_gprio == dropprio || (thisnmi & nmi))) {
            if (!icv_eoi_split(env, cs) || irq >= GICV3_LPI_INTID_START) {
                /*
                 * Priority drop and deactivate not split: deactivate irq now.
                 * LPIs always get their active state cleared immediately
                 * because no separate deactivate is expected.
                 */
                icv_deactivate_irq(cs, idx);
            }
        }
    }

    gicv3_cpuif_virt_update(cs);
}

static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
                           uint64_t value)
{
    /* End of Interrupt */
    GICv3CPUState *cs = icc_cs_from_env(env);
    int irq = value & 0xffffff;
    int grp;
    bool is_eoir0 = ri->crm == 8;

    if (icv_access(env, is_eoir0 ? HCR_FMO : HCR_IMO)) {
        icv_eoir_write(env, ri, value);
        return;
    }

    trace_gicv3_icc_eoir_write(is_eoir0 ? 0 : 1,
                               gicv3_redist_affid(cs), value);

    if ((irq >= cs->gic->num_irq) &&
        !(cs->gic->lpi_enable && (irq >= GICV3_LPI_INTID_START))) {
        /* This handles two cases:
         * 1. If software writes the ID of a spurious interrupt [ie 1020-1023]
         * to the GICC_EOIR, the GIC ignores that write.
         * 2. If software writes the number of a non-existent interrupt
         * this must be a subcase of "value written does not match the last
         * valid interrupt value read from the Interrupt Acknowledge
         * register" and so this is UNPREDICTABLE. We choose to ignore it.
         */
        return;
    }

    grp = icc_highest_active_group(cs);
    switch (grp) {
    case GICV3_G0:
        if (!is_eoir0) {
            return;
        }
        if (!(cs->gic->gicd_ctlr & GICD_CTLR_DS)
            && arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env)) {
            return;
        }
        break;
    case GICV3_G1:
        if (is_eoir0) {
            return;
        }
        if (!arm_is_secure(env)) {
            return;
        }
        break;
    case GICV3_G1NS:
        if (is_eoir0) {
            return;
        }
        if (!arm_is_el3_or_mon(env) && arm_is_secure(env)) {
            return;
        }
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: IRQ %d isn't active\n", __func__, irq);
        return;
    }

    icc_drop_prio(cs, grp);

    if (!icc_eoi_split(env, cs)) {
        /* Priority drop and deactivate not split: deactivate irq now */
        icc_deactivate_irq(cs, irq);
    }
}

static uint64_t icc_hppir0_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value;

    if (icv_access(env, HCR_FMO)) {
        return icv_hppir_read(env, ri);
    }

    value = icc_hppir0_value(cs, env);
    trace_gicv3_icc_hppir0_read(gicv3_redist_affid(cs), value);
    return value;
}

static uint64_t icc_hppir1_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value;

    if (icv_access(env, HCR_IMO)) {
        return icv_hppir_read(env, ri);
    }

    value = icc_hppir1_value(cs, env);
    trace_gicv3_icc_hppir1_read(gicv3_redist_affid(cs), value);
    return value;
}

static uint64_t icc_bpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1;
    bool satinc = false;
    uint64_t bpr;

    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
        return icv_bpr_read(env, ri);
    }

    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
        grp = GICV3_G1NS;
    }

    if (grp == GICV3_G1 && !arm_is_el3_or_mon(env) &&
        (cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR)) {
        /* CBPR_EL1S means secure EL1 or AArch32 EL3 !Mon BPR1 accesses
         * modify BPR0
         */
        grp = GICV3_G0;
    }

    if (grp == GICV3_G1NS && arm_current_el(env) < 3 &&
        (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) {
        /* reads return bpr0 + 1 sat to 7, writes ignored */
        grp = GICV3_G0;
        satinc = true;
    }

    bpr = cs->icc_bpr[grp];
    if (satinc) {
        bpr++;
        bpr = MIN(bpr, 7);
    }

    trace_gicv3_icc_bpr_read(ri->crm == 8 ? 0 : 1, gicv3_redist_affid(cs), bpr);

    return bpr;
}

static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1;
    uint64_t minval;

    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
        icv_bpr_write(env, ri, value);
        return;
    }

    trace_gicv3_icc_bpr_write(ri->crm == 8 ? 0 : 1,
                              gicv3_redist_affid(cs), value);

    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
        grp = GICV3_G1NS;
    }

    if (grp == GICV3_G1 && !arm_is_el3_or_mon(env) &&
        (cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR)) {
        /* CBPR_EL1S means secure EL1 or AArch32 EL3 !Mon BPR1 accesses
         * modify BPR0
         */
        grp = GICV3_G0;
    }

    if (grp == GICV3_G1NS && arm_current_el(env) < 3 &&
        (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) {
        /* reads return bpr0 + 1 sat to 7, writes ignored */
        return;
    }

    minval = (grp == GICV3_G1NS) ? icc_min_bpr_ns(cs) : icc_min_bpr(cs);
    if (value < minval) {
        value = minval;
    }

    cs->icc_bpr[grp] = value & 7;
    gicv3_cpuif_update(cs);
}

static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value;

    int regno = ri->opc2 & 3;
    int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;

    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
        return icv_ap_read(env, ri);
    }

    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
        grp = GICV3_G1NS;
    }

    value = cs->icc_apr[grp][regno];

    trace_gicv3_icc_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
    return value;
}

static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    int regno = ri->opc2 & 3;
    int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;

    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
        icv_ap_write(env, ri, value);
        return;
    }

    trace_gicv3_icc_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);

    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
        grp = GICV3_G1NS;
    }

    /* It's not possible to claim that a Non-secure interrupt is active
     * at a priority outside the Non-secure range (128..255), since this
     * would otherwise allow malicious NS code to block delivery of S interrupts
     * by writing a bad value to these registers.
     */
    if (grp == GICV3_G1NS && regno < 2 && arm_feature(env, ARM_FEATURE_EL3)) {
        return;
    }

    if (cs->nmi_support) {
        cs->icc_apr[grp][regno] = value & (0xFFFFFFFFU | ICC_AP1R_EL1_NMI);
    } else {
        cs->icc_apr[grp][regno] = value & 0xFFFFFFFFU;
    }
    gicv3_cpuif_update(cs);
}

static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
{
    /* Deactivate interrupt */
    GICv3CPUState *cs = icc_cs_from_env(env);
    int irq = value & 0xffffff;
    bool irq_is_secure, single_sec_state, irq_is_grp0;
    bool route_fiq_to_el3, route_irq_to_el3, route_fiq_to_el2, route_irq_to_el2;

    if (icv_access(env, HCR_FMO | HCR_IMO)) {
        icv_dir_write(env, ri, value);
        return;
    }

    trace_gicv3_icc_dir_write(gicv3_redist_affid(cs), value);

    if (irq >= cs->gic->num_irq) {
        /* Also catches special interrupt numbers and LPIs */
        return;
    }

    if (!icc_eoi_split(env, cs)) {
        return;
    }

    int grp = gicv3_irq_group(cs->gic, cs, irq);

    single_sec_state = cs->gic->gicd_ctlr & GICD_CTLR_DS;
    irq_is_secure = !single_sec_state && (grp != GICV3_G1NS);
    irq_is_grp0 = grp == GICV3_G0;

    /* Check whether we're allowed to deactivate this interrupt based
     * on its group and the current CPU state.
     * These checks are laid out to correspond to the spec's pseudocode.
     */
    route_fiq_to_el3 = env->cp15.scr_el3 & SCR_FIQ;
    route_irq_to_el3 = env->cp15.scr_el3 & SCR_IRQ;
    /* No need to include !IsSecure in route_*_to_el2 as it's only
     * tested in cases where we know !IsSecure is true.
     */
    uint64_t hcr_el2 = arm_hcr_el2_eff(env);
    route_fiq_to_el2 = hcr_el2 & HCR_FMO;
    route_irq_to_el2 = hcr_el2 & HCR_IMO;

    switch (arm_current_el(env)) {
    case 3:
        break;
    case 2:
        if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
            break;
        }
        if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
            break;
        }
        return;
    case 1:
        if (!arm_is_secure_below_el3(env)) {
            if (single_sec_state && irq_is_grp0 &&
                !route_fiq_to_el3 && !route_fiq_to_el2) {
                break;
            }
            if (!irq_is_secure && !irq_is_grp0 &&
                !route_irq_to_el3 && !route_irq_to_el2) {
                break;
            }
        } else {
            if (irq_is_grp0 && !route_fiq_to_el3) {
                break;
            }
            if (!irq_is_grp0 &&
                (!irq_is_secure || !single_sec_state) &&
                !route_irq_to_el3) {
                break;
            }
        }
        return;
    default:
        g_assert_not_reached();
    }

    icc_deactivate_irq(cs, irq);
}

static uint64_t icc_rpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t prio;

    if (icv_access(env, HCR_FMO | HCR_IMO)) {
        return icv_rpr_read(env, ri);
    }

    prio = icc_highest_active_prio(cs);

    if (arm_feature(env, ARM_FEATURE_EL3) &&
        !arm_is_secure(env) && (env->cp15.scr_el3 & SCR_FIQ)) {
        /* NS GIC access and Group 0 is inaccessible to NS */
        if ((prio & 0x80) == 0) {
            /* NS mustn't see priorities in the Secure half of the range */
            prio = 0;
        } else if (prio != 0xff) {
            /* Non-idle priority: show the Non-secure view of it */
            prio = (prio << 1) & 0xff;
        }
    }

    if (cs->nmi_support) {
        /* NMI info is reported in the high bits of RPR */
        if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env)) {
            if (cs->icc_apr[GICV3_G1NS][0] & ICC_AP1R_EL1_NMI) {
                prio |= ICC_RPR_EL1_NMI;
            }
        } else {
            if (cs->icc_apr[GICV3_G1NS][0] & ICC_AP1R_EL1_NMI) {
                prio |= ICC_RPR_EL1_NSNMI;
            }
            if (cs->icc_apr[GICV3_G1][0] & ICC_AP1R_EL1_NMI) {
                prio |= ICC_RPR_EL1_NMI;
            }
        }
    }

    trace_gicv3_icc_rpr_read(gicv3_redist_affid(cs), prio);
    return prio;
}

static void icc_generate_sgi(CPUARMState *env, GICv3CPUState *cs,
                             uint64_t value, int grp, bool ns)
{
    GICv3State *s = cs->gic;

    /* Extract Aff3/Aff2/Aff1 and shift into the bottom 24 bits */
    uint64_t aff = extract64(value, 48, 8) << 16 |
        extract64(value, 32, 8) << 8 |
        extract64(value, 16, 8);
    uint32_t targetlist = extract64(value, 0, 16);
    uint32_t irq = extract64(value, 24, 4);
    bool irm = extract64(value, 40, 1);
    int i;

    if (grp == GICV3_G1 && s->gicd_ctlr & GICD_CTLR_DS) {
        /* If GICD_CTLR.DS == 1, the Distributor treats Secure Group 1
         * interrupts as Group 0 interrupts and must send Secure Group 0
         * interrupts to the target CPUs.
         */
        grp = GICV3_G0;
    }

    trace_gicv3_icc_generate_sgi(gicv3_redist_affid(cs), irq, irm,
                                 aff, targetlist);

    for (i = 0; i < s->num_cpu; i++) {
        GICv3CPUState *ocs = &s->cpu[i];

        if (irm) {
            /* IRM == 1 : route to all CPUs except self */
            if (cs == ocs) {
                continue;
            }
        } else {
            /* IRM == 0 : route to Aff3.Aff2.Aff1.n for all n in [0..15]
             * where the corresponding bit is set in targetlist
             */
            int aff0;

            if (ocs->gicr_typer >> 40 != aff) {
                continue;
            }
            aff0 = extract64(ocs->gicr_typer, 32, 8);
            if (aff0 > 15 || extract32(targetlist, aff0, 1) == 0) {
                continue;
            }
        }

        /* The redistributor will check against its own GICR_NSACR as needed */
        gicv3_redist_send_sgi(ocs, grp, irq, ns);
    }
}

static void icc_sgi0r_write(CPUARMState *env, const ARMCPRegInfo *ri,
                           uint64_t value)
{
    /* Generate Secure Group 0 SGI. */
    GICv3CPUState *cs = icc_cs_from_env(env);
    bool ns = !arm_is_secure(env);

    icc_generate_sgi(env, cs, value, GICV3_G0, ns);
}

static void icc_sgi1r_write(CPUARMState *env, const ARMCPRegInfo *ri,
                           uint64_t value)
{
    /* Generate Group 1 SGI for the current Security state */
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp;
    bool ns = !arm_is_secure(env);

    grp = ns ? GICV3_G1NS : GICV3_G1;
    icc_generate_sgi(env, cs, value, grp, ns);
}

static void icc_asgi1r_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
{
    /* Generate Group 1 SGI for the Security state that is not
     * the current state
     */
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp;
    bool ns = !arm_is_secure(env);

    grp = ns ? GICV3_G1 : GICV3_G1NS;
    icc_generate_sgi(env, cs, value, grp, ns);
}

static uint64_t icc_igrpen_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp = ri->opc2 & 1 ? GICV3_G1 : GICV3_G0;
    uint64_t value;

    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
        return icv_igrpen_read(env, ri);
    }

    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
        grp = GICV3_G1NS;
    }

    value = cs->icc_igrpen[grp];
    trace_gicv3_icc_igrpen_read(ri->opc2 & 1 ? 1 : 0,
                                gicv3_redist_affid(cs), value);
    return value;
}

static void icc_igrpen_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int grp = ri->opc2 & 1 ? GICV3_G1 : GICV3_G0;

    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
        icv_igrpen_write(env, ri, value);
        return;
    }

    trace_gicv3_icc_igrpen_write(ri->opc2 & 1 ? 1 : 0,
                                 gicv3_redist_affid(cs), value);

    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
        grp = GICV3_G1NS;
    }

    cs->icc_igrpen[grp] = value & ICC_IGRPEN_ENABLE;
    gicv3_cpuif_update(cs);
}

static uint64_t icc_igrpen1_el3_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value;

    /* IGRPEN1_EL3 bits 0 and 1 are r/w aliases into IGRPEN1_EL1 NS and S */
    value = cs->icc_igrpen[GICV3_G1NS] | (cs->icc_igrpen[GICV3_G1] << 1);
    trace_gicv3_icc_igrpen1_el3_read(gicv3_redist_affid(cs), value);
    return value;
}

static void icc_igrpen1_el3_write(CPUARMState *env, const ARMCPRegInfo *ri,
                                  uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    trace_gicv3_icc_igrpen1_el3_write(gicv3_redist_affid(cs), value);

    /* IGRPEN1_EL3 bits 0 and 1 are r/w aliases into IGRPEN1_EL1 NS and S */
    cs->icc_igrpen[GICV3_G1NS] = extract32(value, 0, 1);
    cs->icc_igrpen[GICV3_G1] = extract32(value, 1, 1);
    gicv3_cpuif_update(cs);
}

static uint64_t icc_ctlr_el1_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int bank = gicv3_use_ns_bank(env) ? GICV3_NS : GICV3_S;
    uint64_t value;

    if (icv_access(env, HCR_FMO | HCR_IMO)) {
        return icv_ctlr_read(env, ri);
    }

    value = cs->icc_ctlr_el1[bank];
    trace_gicv3_icc_ctlr_read(gicv3_redist_affid(cs), value);
    return value;
}

static void icc_ctlr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
                               uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int bank = gicv3_use_ns_bank(env) ? GICV3_NS : GICV3_S;
    uint64_t mask;

    if (icv_access(env, HCR_FMO | HCR_IMO)) {
        icv_ctlr_write(env, ri, value);
        return;
    }

    trace_gicv3_icc_ctlr_write(gicv3_redist_affid(cs), value);

    /* Only CBPR and EOIMODE can be RW;
     * for us PMHE is RAZ/WI (we don't implement 1-of-N interrupts or
     * the asseciated priority-based routing of them);
     * if EL3 is implemented and GICD_CTLR.DS == 0, then PMHE and CBPR are RO.
     */
    if (arm_feature(env, ARM_FEATURE_EL3) &&
        ((cs->gic->gicd_ctlr & GICD_CTLR_DS) == 0)) {
        mask = ICC_CTLR_EL1_EOIMODE;
    } else {
        mask = ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE;
    }

    cs->icc_ctlr_el1[bank] &= ~mask;
    cs->icc_ctlr_el1[bank] |= (value & mask);
    gicv3_cpuif_update(cs);
}


static uint64_t icc_ctlr_el3_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value;

    value = cs->icc_ctlr_el3;
    if (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_EOIMODE) {
        value |= ICC_CTLR_EL3_EOIMODE_EL1NS;
    }
    if (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR) {
        value |= ICC_CTLR_EL3_CBPR_EL1NS;
    }
    if (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_EOIMODE) {
        value |= ICC_CTLR_EL3_EOIMODE_EL1S;
    }
    if (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR) {
        value |= ICC_CTLR_EL3_CBPR_EL1S;
    }

    trace_gicv3_icc_ctlr_el3_read(gicv3_redist_affid(cs), value);
    return value;
}

static void icc_ctlr_el3_write(CPUARMState *env, const ARMCPRegInfo *ri,
                               uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t mask;

    trace_gicv3_icc_ctlr_el3_write(gicv3_redist_affid(cs), value);

    /* *_EL1NS and *_EL1S bits are aliases into the ICC_CTLR_EL1 bits. */
    cs->icc_ctlr_el1[GICV3_NS] &= ~(ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE);
    if (value & ICC_CTLR_EL3_EOIMODE_EL1NS) {
        cs->icc_ctlr_el1[GICV3_NS] |= ICC_CTLR_EL1_EOIMODE;
    }
    if (value & ICC_CTLR_EL3_CBPR_EL1NS) {
        cs->icc_ctlr_el1[GICV3_NS] |= ICC_CTLR_EL1_CBPR;
    }

    cs->icc_ctlr_el1[GICV3_S] &= ~(ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE);
    if (value & ICC_CTLR_EL3_EOIMODE_EL1S) {
        cs->icc_ctlr_el1[GICV3_S] |= ICC_CTLR_EL1_EOIMODE;
    }
    if (value & ICC_CTLR_EL3_CBPR_EL1S) {
        cs->icc_ctlr_el1[GICV3_S] |= ICC_CTLR_EL1_CBPR;
    }

    /* The only bit stored in icc_ctlr_el3 which is writable is EOIMODE_EL3: */
    mask = ICC_CTLR_EL3_EOIMODE_EL3;

    cs->icc_ctlr_el3 &= ~mask;
    cs->icc_ctlr_el3 |= (value & mask);
    gicv3_cpuif_update(cs);
}

static CPAccessResult gicv3_irqfiq_access(CPUARMState *env,
                                          const ARMCPRegInfo *ri, bool isread)
{
    CPAccessResult r = CP_ACCESS_OK;
    GICv3CPUState *cs = icc_cs_from_env(env);
    int el = arm_current_el(env);

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_TC) &&
        el == 1 && !arm_is_secure_below_el3(env)) {
        /* Takes priority over a possible EL3 trap */
        return CP_ACCESS_TRAP_EL2;
    }

    if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) {
        switch (el) {
        case 1:
            /* Note that arm_hcr_el2_eff takes secure state into account.  */
            if ((arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) == 0) {
                r = CP_ACCESS_TRAP_EL3;
            }
            break;
        case 2:
            r = CP_ACCESS_TRAP_EL3;
            break;
        case 3:
            if (!is_a64(env) && !arm_is_el3_or_mon(env)) {
                r = CP_ACCESS_TRAP_EL3;
            }
            break;
        default:
            g_assert_not_reached();
        }
    }

    if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) {
        r = CP_ACCESS_TRAP;
    }
    return r;
}

static CPAccessResult gicv3_dir_access(CPUARMState *env,
                                       const ARMCPRegInfo *ri, bool isread)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_TDIR) &&
        arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) {
        /* Takes priority over a possible EL3 trap */
        return CP_ACCESS_TRAP_EL2;
    }

    return gicv3_irqfiq_access(env, ri, isread);
}

static CPAccessResult gicv3_sgi_access(CPUARMState *env,
                                       const ARMCPRegInfo *ri, bool isread)
{
    if (arm_current_el(env) == 1 &&
        (arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) != 0) {
        /* Takes priority over a possible EL3 trap */
        return CP_ACCESS_TRAP_EL2;
    }

    return gicv3_irqfiq_access(env, ri, isread);
}

static CPAccessResult gicv3_fiq_access(CPUARMState *env,
                                       const ARMCPRegInfo *ri, bool isread)
{
    CPAccessResult r = CP_ACCESS_OK;
    GICv3CPUState *cs = icc_cs_from_env(env);
    int el = arm_current_el(env);

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_TALL0) &&
        el == 1 && !arm_is_secure_below_el3(env)) {
        /* Takes priority over a possible EL3 trap */
        return CP_ACCESS_TRAP_EL2;
    }

    if (env->cp15.scr_el3 & SCR_FIQ) {
        switch (el) {
        case 1:
            if ((arm_hcr_el2_eff(env) & HCR_FMO) == 0) {
                r = CP_ACCESS_TRAP_EL3;
            }
            break;
        case 2:
            r = CP_ACCESS_TRAP_EL3;
            break;
        case 3:
            if (!is_a64(env) && !arm_is_el3_or_mon(env)) {
                r = CP_ACCESS_TRAP_EL3;
            }
            break;
        default:
            g_assert_not_reached();
        }
    }

    if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) {
        r = CP_ACCESS_TRAP;
    }
    return r;
}

static CPAccessResult gicv3_irq_access(CPUARMState *env,
                                       const ARMCPRegInfo *ri, bool isread)
{
    CPAccessResult r = CP_ACCESS_OK;
    GICv3CPUState *cs = icc_cs_from_env(env);
    int el = arm_current_el(env);

    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_TALL1) &&
        el == 1 && !arm_is_secure_below_el3(env)) {
        /* Takes priority over a possible EL3 trap */
        return CP_ACCESS_TRAP_EL2;
    }

    if (env->cp15.scr_el3 & SCR_IRQ) {
        switch (el) {
        case 1:
            if ((arm_hcr_el2_eff(env) & HCR_IMO) == 0) {
                r = CP_ACCESS_TRAP_EL3;
            }
            break;
        case 2:
            r = CP_ACCESS_TRAP_EL3;
            break;
        case 3:
            if (!is_a64(env) && !arm_is_el3_or_mon(env)) {
                r = CP_ACCESS_TRAP_EL3;
            }
            break;
        default:
            g_assert_not_reached();
        }
    }

    if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) {
        r = CP_ACCESS_TRAP;
    }
    return r;
}

static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    cs->icc_ctlr_el1[GICV3_S] = ICC_CTLR_EL1_A3V |
        (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
        ((cs->pribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);
    cs->icc_ctlr_el1[GICV3_NS] = ICC_CTLR_EL1_A3V |
        (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
        ((cs->pribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);
    cs->icc_pmr_el1 = 0;
    cs->icc_bpr[GICV3_G0] = icc_min_bpr(cs);
    cs->icc_bpr[GICV3_G1] = icc_min_bpr(cs);
    cs->icc_bpr[GICV3_G1NS] = icc_min_bpr_ns(cs);
    memset(cs->icc_apr, 0, sizeof(cs->icc_apr));
    memset(cs->icc_igrpen, 0, sizeof(cs->icc_igrpen));
    cs->icc_ctlr_el3 = ICC_CTLR_EL3_NDS | ICC_CTLR_EL3_A3V |
        (1 << ICC_CTLR_EL3_IDBITS_SHIFT) |
        ((cs->pribits - 1) << ICC_CTLR_EL3_PRIBITS_SHIFT);

    memset(cs->ich_apr, 0, sizeof(cs->ich_apr));
    cs->ich_hcr_el2 = 0;
    memset(cs->ich_lr_el2, 0, sizeof(cs->ich_lr_el2));
    cs->ich_vmcr_el2 = ICH_VMCR_EL2_VFIQEN |
        ((icv_min_vbpr(cs) + 1) << ICH_VMCR_EL2_VBPR1_SHIFT) |
        (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR0_SHIFT);
}

static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
    { .name = "ICC_PMR_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 6, .opc2 = 0,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_irqfiq_access,
      .readfn = icc_pmr_read,
      .writefn = icc_pmr_write,
      /* We hang the whole cpu interface reset routine off here
       * rather than parcelling it out into one little function
       * per register
       */
      .resetfn = icc_reset,
    },
    { .name = "ICC_IAR0_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 0,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_R, .accessfn = gicv3_fiq_access,
      .readfn = icc_iar0_read,
    },
    { .name = "ICC_EOIR0_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 1,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_fiq_access,
      .writefn = icc_eoir_write,
    },
    { .name = "ICC_HPPIR0_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 2,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_R, .accessfn = gicv3_fiq_access,
      .readfn = icc_hppir0_read,
    },
    { .name = "ICC_BPR0_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 3,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_fiq_access,
      .readfn = icc_bpr_read,
      .writefn = icc_bpr_write,
    },
    { .name = "ICC_AP0R0_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 4,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_fiq_access,
      .readfn = icc_ap_read,
      .writefn = icc_ap_write,
    },
    /* All the ICC_AP1R*_EL1 registers are banked */
    { .name = "ICC_AP1R0_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 0,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_irq_access,
      .readfn = icc_ap_read,
      .writefn = icc_ap_write,
    },
    { .name = "ICC_DIR_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 1,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_dir_access,
      .writefn = icc_dir_write,
    },
    { .name = "ICC_RPR_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 3,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_R, .accessfn = gicv3_irqfiq_access,
      .readfn = icc_rpr_read,
    },
    { .name = "ICC_SGI1R_EL1", .state = ARM_CP_STATE_AA64,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 5,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_sgi_access,
      .writefn = icc_sgi1r_write,
    },
    { .name = "ICC_SGI1R",
      .cp = 15, .opc1 = 0, .crm = 12,
      .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_sgi_access,
      .writefn = icc_sgi1r_write,
    },
    { .name = "ICC_ASGI1R_EL1", .state = ARM_CP_STATE_AA64,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 6,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_sgi_access,
      .writefn = icc_asgi1r_write,
    },
    { .name = "ICC_ASGI1R",
      .cp = 15, .opc1 = 1, .crm = 12,
      .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_sgi_access,
      .writefn = icc_asgi1r_write,
    },
    { .name = "ICC_SGI0R_EL1", .state = ARM_CP_STATE_AA64,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 7,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_sgi_access,
      .writefn = icc_sgi0r_write,
    },
    { .name = "ICC_SGI0R",
      .cp = 15, .opc1 = 2, .crm = 12,
      .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_sgi_access,
      .writefn = icc_sgi0r_write,
    },
    { .name = "ICC_IAR1_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 0,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_R, .accessfn = gicv3_irq_access,
      .readfn = icc_iar1_read,
    },
    { .name = "ICC_EOIR1_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 1,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_W, .accessfn = gicv3_irq_access,
      .writefn = icc_eoir_write,
    },
    { .name = "ICC_HPPIR1_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 2,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_R, .accessfn = gicv3_irq_access,
      .readfn = icc_hppir1_read,
    },
    /* This register is banked */
    { .name = "ICC_BPR1_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 3,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_irq_access,
      .readfn = icc_bpr_read,
      .writefn = icc_bpr_write,
    },
    /* This register is banked */
    { .name = "ICC_CTLR_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 4,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_irqfiq_access,
      .readfn = icc_ctlr_el1_read,
      .writefn = icc_ctlr_el1_write,
    },
    { .name = "ICC_SRE_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 5,
      .type = ARM_CP_NO_RAW | ARM_CP_CONST,
      .access = PL1_RW,
      /* We don't support IRQ/FIQ bypass and system registers are
       * always enabled, so all our bits are RAZ/WI or RAO/WI.
       * This register is banked but since it's constant we don't
       * need to do anything special.
       */
      .resetvalue = 0x7,
    },
    { .name = "ICC_IGRPEN0_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_fiq_access,
      .fgt = FGT_ICC_IGRPENN_EL1,
      .readfn = icc_igrpen_read,
      .writefn = icc_igrpen_write,
    },
    /* This register is banked */
    { .name = "ICC_IGRPEN1_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 7,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_irq_access,
      .fgt = FGT_ICC_IGRPENN_EL1,
      .readfn = icc_igrpen_read,
      .writefn = icc_igrpen_write,
    },
    { .name = "ICC_SRE_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 5,
      .type = ARM_CP_NO_RAW | ARM_CP_CONST,
      .access = PL2_RW,
      /* We don't support IRQ/FIQ bypass and system registers are
       * always enabled, so all our bits are RAZ/WI or RAO/WI.
       */
      .resetvalue = 0xf,
    },
    { .name = "ICC_CTLR_EL3", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 12, .opc2 = 4,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL3_RW,
      .readfn = icc_ctlr_el3_read,
      .writefn = icc_ctlr_el3_write,
    },
    { .name = "ICC_SRE_EL3", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 12, .opc2 = 5,
      .type = ARM_CP_NO_RAW | ARM_CP_CONST,
      .access = PL3_RW,
      /* We don't support IRQ/FIQ bypass and system registers are
       * always enabled, so all our bits are RAZ/WI or RAO/WI.
       */
      .resetvalue = 0xf,
    },
    { .name = "ICC_IGRPEN1_EL3", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 12, .opc2 = 7,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL3_RW,
      .readfn = icc_igrpen1_el3_read,
      .writefn = icc_igrpen1_el3_write,
    },
};

static const ARMCPRegInfo gicv3_cpuif_icc_apxr1_reginfo[] = {
    { .name = "ICC_AP0R1_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 5,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_fiq_access,
      .readfn = icc_ap_read,
      .writefn = icc_ap_write,
    },
    { .name = "ICC_AP1R1_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 1,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_irq_access,
      .readfn = icc_ap_read,
      .writefn = icc_ap_write,
    },
};

static const ARMCPRegInfo gicv3_cpuif_icc_apxr23_reginfo[] = {
    { .name = "ICC_AP0R2_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 6,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_fiq_access,
      .readfn = icc_ap_read,
      .writefn = icc_ap_write,
    },
    { .name = "ICC_AP0R3_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 7,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_fiq_access,
      .readfn = icc_ap_read,
      .writefn = icc_ap_write,
    },
    { .name = "ICC_AP1R2_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 2,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_irq_access,
      .readfn = icc_ap_read,
      .writefn = icc_ap_write,
    },
    { .name = "ICC_AP1R3_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 3,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_RW, .accessfn = gicv3_irq_access,
      .readfn = icc_ap_read,
      .writefn = icc_ap_write,
    },
};

static const ARMCPRegInfo gicv3_cpuif_gicv3_nmi_reginfo[] = {
    { .name = "ICC_NMIAR1_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 5,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL1_R, .accessfn = gicv3_irq_access,
      .readfn = icc_nmiar1_read,
    },
};

static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int regno = ri->opc2 & 3;
    int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
    uint64_t value;

    value = cs->ich_apr[grp][regno];
    trace_gicv3_ich_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
    return value;
}

static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int regno = ri->opc2 & 3;
    int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;

    trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);

    if (cs->nmi_support) {
        cs->ich_apr[grp][regno] = value & (0xFFFFFFFFU | ICV_AP1R_EL1_NMI);
    } else {
        cs->ich_apr[grp][regno] = value & 0xFFFFFFFFU;
    }
    gicv3_cpuif_virt_irq_fiq_update(cs);
}

static uint64_t ich_hcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value = cs->ich_hcr_el2;

    trace_gicv3_ich_hcr_read(gicv3_redist_affid(cs), value);
    return value;
}

static void ich_hcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    trace_gicv3_ich_hcr_write(gicv3_redist_affid(cs), value);

    value &= ICH_HCR_EL2_EN | ICH_HCR_EL2_UIE | ICH_HCR_EL2_LRENPIE |
        ICH_HCR_EL2_NPIE | ICH_HCR_EL2_VGRP0EIE | ICH_HCR_EL2_VGRP0DIE |
        ICH_HCR_EL2_VGRP1EIE | ICH_HCR_EL2_VGRP1DIE | ICH_HCR_EL2_TC |
        ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 | ICH_HCR_EL2_TSEI |
        ICH_HCR_EL2_TDIR | ICH_HCR_EL2_EOICOUNT_MASK;

    cs->ich_hcr_el2 = value;
    gicv3_cpuif_virt_update(cs);
}

static uint64_t ich_vmcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value = cs->ich_vmcr_el2;

    trace_gicv3_ich_vmcr_read(gicv3_redist_affid(cs), value);
    return value;
}

static void ich_vmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);

    trace_gicv3_ich_vmcr_write(gicv3_redist_affid(cs), value);

    value &= ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1 | ICH_VMCR_EL2_VCBPR |
        ICH_VMCR_EL2_VEOIM | ICH_VMCR_EL2_VBPR1_MASK |
        ICH_VMCR_EL2_VBPR0_MASK | ICH_VMCR_EL2_VPMR_MASK;
    value |= ICH_VMCR_EL2_VFIQEN;

    cs->ich_vmcr_el2 = value;
    /* Enforce "writing BPRs to less than minimum sets them to the minimum"
     * by reading and writing back the fields.
     */
    write_vbpr(cs, GICV3_G0, read_vbpr(cs, GICV3_G0));
    write_vbpr(cs, GICV3_G1, read_vbpr(cs, GICV3_G1));

    gicv3_cpuif_virt_update(cs);
}

static uint64_t ich_lr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int regno = ri->opc2 | ((ri->crm & 1) << 3);
    uint64_t value;

    /* This read function handles all of:
     * 64-bit reads of the whole LR
     * 32-bit reads of the low half of the LR
     * 32-bit reads of the high half of the LR
     */
    if (ri->state == ARM_CP_STATE_AA32) {
        if (ri->crm >= 14) {
            value = extract64(cs->ich_lr_el2[regno], 32, 32);
            trace_gicv3_ich_lrc_read(regno, gicv3_redist_affid(cs), value);
        } else {
            value = extract64(cs->ich_lr_el2[regno], 0, 32);
            trace_gicv3_ich_lr32_read(regno, gicv3_redist_affid(cs), value);
        }
    } else {
        value = cs->ich_lr_el2[regno];
        trace_gicv3_ich_lr_read(regno, gicv3_redist_affid(cs), value);
    }

    return value;
}

static void ich_lr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    int regno = ri->opc2 | ((ri->crm & 1) << 3);

    /* This write function handles all of:
     * 64-bit writes to the whole LR
     * 32-bit writes to the low half of the LR
     * 32-bit writes to the high half of the LR
     */
    if (ri->state == ARM_CP_STATE_AA32) {
        if (ri->crm >= 14) {
            trace_gicv3_ich_lrc_write(regno, gicv3_redist_affid(cs), value);
            value = deposit64(cs->ich_lr_el2[regno], 32, 32, value);
        } else {
            trace_gicv3_ich_lr32_write(regno, gicv3_redist_affid(cs), value);
            value = deposit64(cs->ich_lr_el2[regno], 0, 32, value);
        }
    } else {
        trace_gicv3_ich_lr_write(regno, gicv3_redist_affid(cs), value);
    }

    /* Enforce RES0 bits in priority field */
    if (cs->vpribits < 8) {
        value = deposit64(value, ICH_LR_EL2_PRIORITY_SHIFT,
                          8 - cs->vpribits, 0);
    }

    /* Enforce RES0 bit in NMI field when FEAT_GICv3_NMI is not implemented */
    if (!cs->nmi_support) {
        value &= ~ICH_LR_EL2_NMI;
    }

    cs->ich_lr_el2[regno] = value;
    gicv3_cpuif_virt_update(cs);
}

static uint64_t ich_vtr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value;

    value = ((cs->num_list_regs - 1) << ICH_VTR_EL2_LISTREGS_SHIFT)
        | ICH_VTR_EL2_TDS | ICH_VTR_EL2_A3V
        | (1 << ICH_VTR_EL2_IDBITS_SHIFT)
        | ((cs->vprebits - 1) << ICH_VTR_EL2_PREBITS_SHIFT)
        | ((cs->vpribits - 1) << ICH_VTR_EL2_PRIBITS_SHIFT);

    if (cs->gic->revision < 4) {
        value |= ICH_VTR_EL2_NV4;
    }

    trace_gicv3_ich_vtr_read(gicv3_redist_affid(cs), value);
    return value;
}

static uint64_t ich_misr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value = maintenance_interrupt_state(cs);

    trace_gicv3_ich_misr_read(gicv3_redist_affid(cs), value);
    return value;
}

static uint64_t ich_eisr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value = eoi_maintenance_interrupt_state(cs, NULL);

    trace_gicv3_ich_eisr_read(gicv3_redist_affid(cs), value);
    return value;
}

static uint64_t ich_elrsr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3CPUState *cs = icc_cs_from_env(env);
    uint64_t value = 0;
    int i;

    for (i = 0; i < cs->num_list_regs; i++) {
        uint64_t lr = cs->ich_lr_el2[i];

        if ((lr & ICH_LR_EL2_STATE_MASK) == 0 &&
            ((lr & ICH_LR_EL2_HW) != 0 || (lr & ICH_LR_EL2_EOI) == 0)) {
            value |= (1 << i);
        }
    }

    trace_gicv3_ich_elrsr_read(gicv3_redist_affid(cs), value);
    return value;
}

static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
    { .name = "ICH_AP0R0_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 0,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x480,
      .access = PL2_RW,
      .readfn = ich_ap_read,
      .writefn = ich_ap_write,
    },
    { .name = "ICH_AP1R0_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 0,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x4a0,
      .access = PL2_RW,
      .readfn = ich_ap_read,
      .writefn = ich_ap_write,
    },
    { .name = "ICH_HCR_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 0,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x4c0,
      .access = PL2_RW,
      .readfn = ich_hcr_read,
      .writefn = ich_hcr_write,
    },
    { .name = "ICH_VTR_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 1,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL2_R,
      .readfn = ich_vtr_read,
    },
    { .name = "ICH_MISR_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 2,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL2_R,
      .readfn = ich_misr_read,
    },
    { .name = "ICH_EISR_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 3,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL2_R,
      .readfn = ich_eisr_read,
    },
    { .name = "ICH_ELRSR_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 5,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .access = PL2_R,
      .readfn = ich_elrsr_read,
    },
    { .name = "ICH_VMCR_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 7,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x4c8,
      .access = PL2_RW,
      .readfn = ich_vmcr_read,
      .writefn = ich_vmcr_write,
    },
};

static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
    { .name = "ICH_AP0R1_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 1,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x488,
      .access = PL2_RW,
      .readfn = ich_ap_read,
      .writefn = ich_ap_write,
    },
    { .name = "ICH_AP1R1_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 1,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x4a8,
      .access = PL2_RW,
      .readfn = ich_ap_read,
      .writefn = ich_ap_write,
    },
};

static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
    { .name = "ICH_AP0R2_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 2,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x490,
      .access = PL2_RW,
      .readfn = ich_ap_read,
      .writefn = ich_ap_write,
    },
    { .name = "ICH_AP0R3_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 3,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x498,
      .access = PL2_RW,
      .readfn = ich_ap_read,
      .writefn = ich_ap_write,
    },
    { .name = "ICH_AP1R2_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 2,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x4b0,
      .access = PL2_RW,
      .readfn = ich_ap_read,
      .writefn = ich_ap_write,
    },
    { .name = "ICH_AP1R3_EL2", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 3,
      .type = ARM_CP_IO | ARM_CP_NO_RAW,
      .nv2_redirect_offset = 0x4b8,
      .access = PL2_RW,
      .readfn = ich_ap_read,
      .writefn = ich_ap_write,
    },
};

static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)
{
    GICv3CPUState *cs = opaque;

    gicv3_cpuif_update(cs);
    /*
     * Because vLPIs are only pending in NonSecure state,
     * an EL change can change the VIRQ/VFIQ status (but
     * cannot affect the maintenance interrupt state)
     */
    gicv3_cpuif_virt_irq_fiq_update(cs);
}

void gicv3_init_cpuif(GICv3State *s)
{
    /* Called from the GICv3 realize function; register our system
     * registers with the CPU
     */
    int i;

    for (i = 0; i < s->num_cpu; i++) {
        ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
        GICv3CPUState *cs = &s->cpu[i];

        /*
         * If the CPU doesn't define a GICv3 configuration, probably because
         * in real hardware it doesn't have one, then we use default values
         * matching the one used by most Arm CPUs. This applies to:
         *  cpu->gic_num_lrs
         *  cpu->gic_vpribits
         *  cpu->gic_vprebits
         *  cpu->gic_pribits
         */

        /* Note that we can't just use the GICv3CPUState as an opaque pointer
         * in define_arm_cp_regs_with_opaque(), because when we're called back
         * it might be with code translated by CPU 0 but run by CPU 1, in
         * which case we'd get the wrong value.
         * So instead we define the regs with no ri->opaque info, and
         * get back to the GICv3CPUState from the CPUARMState.
         *
         * These CP regs callbacks can be called from either TCG or HVF code.
         */
        define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);

        /*
         * If the CPU implements FEAT_NMI and FEAT_GICv3 it must also
         * implement FEAT_GICv3_NMI, which is the CPU interface part
         * of NMI support. This is distinct from whether the GIC proper
         * (redistributors and distributor) have NMI support. In QEMU
         * that is a property of the GIC device in s->nmi_support;
         * cs->nmi_support indicates the CPU interface's support.
         */
        if (cpu_isar_feature(aa64_nmi, cpu)) {
            cs->nmi_support = true;
            define_arm_cp_regs(cpu, gicv3_cpuif_gicv3_nmi_reginfo);
        }

        /*
         * The CPU implementation specifies the number of supported
         * bits of physical priority. For backwards compatibility
         * of migration, we have a compat property that forces use
         * of 8 priority bits regardless of what the CPU really has.
         */
        if (s->force_8bit_prio) {
            cs->pribits = 8;
        } else {
            cs->pribits = cpu->gic_pribits ?: 5;
        }

        /*
         * The GICv3 has separate ID register fields for virtual priority
         * and preemption bit values, but only a single ID register field
         * for the physical priority bits. The preemption bit count is
         * always the same as the priority bit count, except that 8 bits
         * of priority means 7 preemption bits. We precalculate the
         * preemption bits because it simplifies the code and makes the
         * parallels between the virtual and physical bits of the GIC
         * a bit clearer.
         */
        cs->prebits = cs->pribits;
        if (cs->prebits == 8) {
            cs->prebits--;
        }
        /*
         * Check that CPU code defining pribits didn't violate
         * architectural constraints our implementation relies on.
         */
        g_assert(cs->pribits >= 4 && cs->pribits <= 8);

        /*
         * gicv3_cpuif_reginfo[] defines ICC_AP*R0_EL1; add definitions
         * for ICC_AP*R{1,2,3}_EL1 if the prebits value requires them.
         */
        if (cs->prebits >= 6) {
            define_arm_cp_regs(cpu, gicv3_cpuif_icc_apxr1_reginfo);
        }
        if (cs->prebits == 7) {
            define_arm_cp_regs(cpu, gicv3_cpuif_icc_apxr23_reginfo);
        }

        if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
            int j;

            cs->num_list_regs = cpu->gic_num_lrs ?: 4;
            cs->vpribits = cpu->gic_vpribits ?: 5;
            cs->vprebits = cpu->gic_vprebits ?: 5;

            /* Check against architectural constraints: getting these
             * wrong would be a bug in the CPU code defining these,
             * and the implementation relies on them holding.
             */
            g_assert(cs->vprebits <= cs->vpribits);
            g_assert(cs->vprebits >= 5 && cs->vprebits <= 7);
            g_assert(cs->vpribits >= 5 && cs->vpribits <= 8);

            define_arm_cp_regs(cpu, gicv3_cpuif_hcr_reginfo);

            for (j = 0; j < cs->num_list_regs; j++) {
                /* Note that the AArch64 LRs are 64-bit; the AArch32 LRs
                 * are split into two cp15 regs, LR (the low part, with the
                 * same encoding as the AArch64 LR) and LRC (the high part).
                 */
                ARMCPRegInfo lr_regset[] = {
                    { .name = "ICH_LRn_EL2", .state = ARM_CP_STATE_BOTH,
                      .opc0 = 3, .opc1 = 4, .crn = 12,
                      .crm = 12 + (j >> 3), .opc2 = j & 7,
                      .type = ARM_CP_IO | ARM_CP_NO_RAW,
                      .nv2_redirect_offset = 0x400 + 8 * j,
                      .access = PL2_RW,
                      .readfn = ich_lr_read,
                      .writefn = ich_lr_write,
                    },
                    { .name = "ICH_LRCn_EL2", .state = ARM_CP_STATE_AA32,
                      .cp = 15, .opc1 = 4, .crn = 12,
                      .crm = 14 + (j >> 3), .opc2 = j & 7,
                      .type = ARM_CP_IO | ARM_CP_NO_RAW,
                      .access = PL2_RW,
                      .readfn = ich_lr_read,
                      .writefn = ich_lr_write,
                    },
                };
                define_arm_cp_regs(cpu, lr_regset);
            }
            if (cs->vprebits >= 6) {
                define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr1_reginfo);
            }
            if (cs->vprebits == 7) {
                define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
            }
        }
        if (tcg_enabled() || qtest_enabled()) {
            /*
             * We can only trap EL changes with TCG. However the GIC interrupt
             * state only changes on EL changes involving EL2 or EL3, so for
             * the non-TCG case this is OK, as EL2 and EL3 can't exist.
             */
            arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
        } else {
            assert(!arm_feature(&cpu->env, ARM_FEATURE_EL2));
            assert(!arm_feature(&cpu->env, ARM_FEATURE_EL3));
        }
    }
}
