/*
 * Copyright (c) 2019 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2018 Metempsy Technology Consulting
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "dev/arm/gic_v3_cpu_interface.hh"

#include "arch/arm/faults.hh"
#include "arch/arm/isa.hh"
#include "debug/GIC.hh"
#include "dev/arm/gic_v3.hh"
#include "dev/arm/gic_v3_distributor.hh"
#include "dev/arm/gic_v3_redistributor.hh"

using namespace ArmISA;

const uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
const uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;

Gicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
    : BaseISADevice(),
      gic(gic),
      redistributor(nullptr),
      distributor(nullptr),
      cpuId(cpu_id)
{
    hppi.prio = 0xff;
    hppi.intid = Gicv3::INTID_SPURIOUS;
}

void
Gicv3CPUInterface::init()
{
    redistributor = gic->getRedistributor(cpuId);
    distributor = gic->getDistributor();
}

void
Gicv3CPUInterface::resetHppi(uint32_t intid)
{
    if (intid == hppi.intid)
        hppi.prio = 0xff;
}

void
Gicv3CPUInterface::setThreadContext(ThreadContext *tc)
{
    maintenanceInterrupt = gic->params()->maint_int->get(tc);
    fatal_if(maintenanceInterrupt->num() >= redistributor->irqPending.size(),
        "Invalid maintenance interrupt number\n");
}

bool
Gicv3CPUInterface::getHCREL2FMO() const
{
    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);

    if (hcr.tge && hcr.e2h) {
        return false;
    } else if (hcr.tge) {
        return true;
    } else {
        return hcr.fmo;
    }
}

bool
Gicv3CPUInterface::getHCREL2IMO() const
{
    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);

    if (hcr.tge && hcr.e2h) {
        return false;
    } else if (hcr.tge) {
        return true;
    } else {
        return hcr.imo;
    }
}

RegVal
Gicv3CPUInterface::readMiscReg(int misc_reg)
{
    RegVal value = isa->readMiscRegNoEffect(misc_reg);
    bool hcr_fmo = getHCREL2FMO();
    bool hcr_imo = getHCREL2IMO();

    switch (misc_reg) {
      // Active Priorities Group 1 Registers
      case MISCREG_ICC_AP1R0:
      case MISCREG_ICC_AP1R0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
          }

          return readBankedMiscReg(MISCREG_ICC_AP1R0_EL1);
      }

      case MISCREG_ICC_AP1R1:
      case MISCREG_ICC_AP1R1_EL1:

        // only implemented if supporting 6 or more bits of priority
      case MISCREG_ICC_AP1R2:
      case MISCREG_ICC_AP1R2_EL1:

        // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICC_AP1R3:
      case MISCREG_ICC_AP1R3_EL1:
        // only implemented if supporting 7 or more bits of priority
        return 0;

      // Active Priorities Group 0 Registers
      case MISCREG_ICC_AP0R0:
      case MISCREG_ICC_AP0R0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
              return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
          }

          break;
      }

      case MISCREG_ICC_AP0R1:
      case MISCREG_ICC_AP0R1_EL1:

        // only implemented if supporting 6 or more bits of priority
      case MISCREG_ICC_AP0R2:
      case MISCREG_ICC_AP0R2_EL1:

        // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICC_AP0R3:
      case MISCREG_ICC_AP0R3_EL1:
        // only implemented if supporting 7 or more bits of priority
        return 0;

      // Interrupt Group 0 Enable register EL1
      case MISCREG_ICC_IGRPEN0:
      case MISCREG_ICC_IGRPEN0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
              return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
          }

          break;
      }

      case MISCREG_ICV_IGRPEN0_EL1: {
          ICH_VMCR_EL2 ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          value = ich_vmcr_el2.VENG0;
          break;
      }

      // Interrupt Group 1 Enable register EL1
      case MISCREG_ICC_IGRPEN1:
      case MISCREG_ICC_IGRPEN1_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
          }

          value = readBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1);
          break;
      }

      case MISCREG_ICV_IGRPEN1_EL1: {
          ICH_VMCR_EL2 ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          value = ich_vmcr_el2.VENG1;
          break;
      }

      // Interrupt Group 1 Enable register EL3
      case MISCREG_ICC_MGRPEN1:
      case MISCREG_ICC_IGRPEN1_EL3: {
          ICC_IGRPEN1_EL3 igrp_el3 = 0;
          igrp_el3.EnableGrp1S = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
              MISCREG_ICC_IGRPEN1_EL1_S)).Enable;

          igrp_el3.EnableGrp1NS = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
              MISCREG_ICC_IGRPEN1_EL1_NS)).Enable;

          value = igrp_el3;
          break;
      }

      // Running Priority Register
      case MISCREG_ICC_RPR:
      case MISCREG_ICC_RPR_EL1: {
          if ((currEL() == EL1) && !inSecureState() &&
              (hcr_imo || hcr_fmo)) {
              return readMiscReg(MISCREG_ICV_RPR_EL1);
          }

          uint8_t rprio = highestActivePriority();

          if (haveEL(EL3) && !inSecureState() &&
              (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
              // Spec section 4.8.1
              // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
              if ((rprio & 0x80) == 0) {
                  // If the current priority mask value is in the range of
                  // 0x00-0x7F a read access returns the value 0x0
                  rprio = 0;
              } else if (rprio != 0xff) {
                  // If the current priority mask value is in the range of
                  // 0x80-0xFF a read access returns the Non-secure read of
                  // the current value
                  rprio = (rprio << 1) & 0xff;
              }
          }

          value = rprio;
          break;
      }

      // Virtual Running Priority Register
      case MISCREG_ICV_RPR_EL1: {
          value = virtualHighestActivePriority();
          break;
      }

      // Highest Priority Pending Interrupt Register 0
      case MISCREG_ICC_HPPIR0:
      case MISCREG_ICC_HPPIR0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
              return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
          }

          value = getHPPIR0();
          break;
      }

      // Virtual Highest Priority Pending Interrupt Register 0
      case MISCREG_ICV_HPPIR0_EL1: {
          value = Gicv3::INTID_SPURIOUS;
          int lr_idx = getHPPVILR();

          if (lr_idx >= 0) {
              ICH_LR_EL2 ich_lr_el2 =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
              Gicv3::GroupId group =
                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;

              if (group == Gicv3::G0S) {
                  value = ich_lr_el2.vINTID;
              }
          }

          break;
      }

      // Highest Priority Pending Interrupt Register 1
      case MISCREG_ICC_HPPIR1:
      case MISCREG_ICC_HPPIR1_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
          }

          value = getHPPIR1();
          break;
      }

      // Virtual Highest Priority Pending Interrupt Register 1
      case MISCREG_ICV_HPPIR1_EL1: {
          value = Gicv3::INTID_SPURIOUS;
          int lr_idx = getHPPVILR();

          if (lr_idx >= 0) {
              ICH_LR_EL2 ich_lr_el2 =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
              Gicv3::GroupId group =
                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;

              if (group == Gicv3::G1NS) {
                  value = ich_lr_el2.vINTID;
              }
          }

          break;
      }

      // Binary Point Register 0
      case MISCREG_ICC_BPR0:
      case MISCREG_ICC_BPR0_EL1: {
        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
            return readMiscReg(MISCREG_ICV_BPR0_EL1);
        }

        value = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
        break;
      }

      // Binary Point Register 1
      case MISCREG_ICC_BPR1:
      case MISCREG_ICC_BPR1_EL1: {
        value = bpr1(isSecureBelowEL3() ? Gicv3::G1S : Gicv3::G1NS);
        break;
      }

      // Virtual Binary Point Register 0
      case MISCREG_ICV_BPR0_EL1: {
        ICH_VMCR_EL2 ich_vmcr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

        value = ich_vmcr_el2.VBPR0;
        break;
      }

      // Virtual Binary Point Register 1
      case MISCREG_ICV_BPR1_EL1: {
        ICH_VMCR_EL2 ich_vmcr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

        if (ich_vmcr_el2.VCBPR) {
            // bpr0 + 1 saturated to 7, WI
            value = ich_vmcr_el2.VBPR0 + 1;
            value = value < 7 ? value : 7;
        } else {
            value = ich_vmcr_el2.VBPR1;
        }

        break;
      }

      // Interrupt Priority Mask Register
      case MISCREG_ICC_PMR:
      case MISCREG_ICC_PMR_EL1:
        if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
            return readMiscReg(MISCREG_ICV_PMR_EL1);
        }

        if (haveEL(EL3) && !inSecureState() &&
            (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
            // Spec section 4.8.1
            // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
            if ((value & 0x80) == 0) {
                // If the current priority mask value is in the range of
                // 0x00-0x7F a read access returns the value 0x00.
                value = 0;
            } else if (value != 0xff) {
                // If the current priority mask value is in the range of
                // 0x80-0xFF a read access returns the Non-secure read of the
                // current value.
                value = (value << 1) & 0xff;
            }
        }

        break;

      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
          ICH_VMCR_EL2 ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

          value = ich_vmcr_el2.VPMR;
          break;
      }

      // Interrupt Acknowledge Register 0
      case MISCREG_ICC_IAR0:
      case MISCREG_ICC_IAR0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
              return readMiscReg(MISCREG_ICV_IAR0_EL1);
          }

          uint32_t int_id;

          if (hppiCanPreempt()) {
              int_id = getHPPIR0();

              // avoid activation for special interrupts
              if (int_id < Gicv3::INTID_SECURE ||
                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
                  activateIRQ(int_id, hppi.group);
              }
          } else {
              int_id = Gicv3::INTID_SPURIOUS;
          }

          value = int_id;
          break;
      }

      // Virtual Interrupt Acknowledge Register 0
      case MISCREG_ICV_IAR0_EL1: {
          int lr_idx = getHPPVILR();
          uint32_t int_id = Gicv3::INTID_SPURIOUS;

          if (lr_idx >= 0) {
              ICH_LR_EL2 ich_lr_el2 =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

              if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
                  int_id = ich_lr_el2.vINTID;

                  if (int_id < Gicv3::INTID_SECURE ||
                      int_id > Gicv3::INTID_SPURIOUS) {
                      virtualActivateIRQ(lr_idx);
                  } else {
                      // Bogus... Pseudocode says:
                      // - Move from pending to invalid...
                      // - Return de bogus id...
                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
                                              ich_lr_el2);
                  }
              }
          }

          value = int_id;
          virtualUpdate();
          break;
      }

      // Interrupt Acknowledge Register 1
      case MISCREG_ICC_IAR1:
      case MISCREG_ICC_IAR1_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return readMiscReg(MISCREG_ICV_IAR1_EL1);
          }

          uint32_t int_id;

          if (hppiCanPreempt()) {
              int_id = getHPPIR1();

              // avoid activation for special interrupts
              if (int_id < Gicv3::INTID_SECURE ||
                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
                  activateIRQ(int_id, hppi.group);
              }
          } else {
              int_id = Gicv3::INTID_SPURIOUS;
          }

          value = int_id;
          break;
      }

      // Virtual Interrupt Acknowledge Register 1
      case MISCREG_ICV_IAR1_EL1: {
          int lr_idx = getHPPVILR();
          uint32_t int_id = Gicv3::INTID_SPURIOUS;

          if (lr_idx >= 0) {
              ICH_LR_EL2 ich_lr_el2 =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

              if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
                  int_id = ich_lr_el2.vINTID;

                  if (int_id < Gicv3::INTID_SECURE ||
                      int_id > Gicv3::INTID_SPURIOUS) {
                      virtualActivateIRQ(lr_idx);
                  } else {
                      // Bogus... Pseudocode says:
                      // - Move from pending to invalid...
                      // - Return de bogus id...
                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
                                              ich_lr_el2);
                  }
              }
          }

          value = int_id;
          virtualUpdate();
          break;
      }

      // System Register Enable Register EL1
      case MISCREG_ICC_SRE:
      case MISCREG_ICC_SRE_EL1: {
        /*
         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
         */
          ICC_SRE_EL1 icc_sre_el1 = 0;
          icc_sre_el1.SRE = 1;
          icc_sre_el1.DIB = 1;
          icc_sre_el1.DFB = 1;
          value = icc_sre_el1;
          break;
      }

      // System Register Enable Register EL2
      case MISCREG_ICC_HSRE:
      case MISCREG_ICC_SRE_EL2: {
        /*
         * Enable [3] == 1
         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
         */
        ICC_SRE_EL2 icc_sre_el2 = 0;
        icc_sre_el2.SRE = 1;
        icc_sre_el2.DIB = 1;
        icc_sre_el2.DFB = 1;
        icc_sre_el2.Enable = 1;
        value = icc_sre_el2;
        break;
      }

      // System Register Enable Register EL3
      case MISCREG_ICC_MSRE:
      case MISCREG_ICC_SRE_EL3: {
        /*
         * Enable [3] == 1
         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
         *  EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
         *  RAO/WI)
         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
         */
        ICC_SRE_EL3 icc_sre_el3 = 0;
        icc_sre_el3.SRE = 1;
        icc_sre_el3.DIB = 1;
        icc_sre_el3.DFB = 1;
        icc_sre_el3.Enable = 1;
        value = icc_sre_el3;
        break;
      }

      // Control Register
      case MISCREG_ICC_CTLR:
      case MISCREG_ICC_CTLR_EL1: {
          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
              return readMiscReg(MISCREG_ICV_CTLR_EL1);
          }

          value = readBankedMiscReg(MISCREG_ICC_CTLR_EL1);
          // Enforce value for RO bits
          // ExtRange [19], INTIDs in the range 1024..8191 not supported
          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
          // A3V [15], supports non-zero values of the Aff3 field in SGI
          //           generation System registers
          // SEIS [14], does not support generation of SEIs (deprecated)
          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
          // PRIbits [10:8], number of priority bits implemented, minus one
          ICC_CTLR_EL1 icc_ctlr_el1 = value;
          icc_ctlr_el1.ExtRange = 0;
          icc_ctlr_el1.RSS = 1;
          icc_ctlr_el1.A3V = 1;
          icc_ctlr_el1.SEIS = 0;
          icc_ctlr_el1.IDbits = 1;
          icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
          value = icc_ctlr_el1;
          break;
      }

      // Virtual Control Register
      case MISCREG_ICV_CTLR_EL1: {
          ICV_CTLR_EL1 icv_ctlr_el1 = value;
          icv_ctlr_el1.RSS = 0;
          icv_ctlr_el1.A3V = 1;
          icv_ctlr_el1.SEIS = 0;
          icv_ctlr_el1.IDbits = 1;
          icv_ctlr_el1.PRIbits = 7;
          value = icv_ctlr_el1;
          break;
      }

      // Control Register
      case MISCREG_ICC_MCTLR:
      case MISCREG_ICC_CTLR_EL3: {
          // Enforce value for RO bits
          // ExtRange [19], INTIDs in the range 1024..8191 not supported
          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
          // nDS [17], supports disabling of security
          // A3V [15], supports non-zero values of the Aff3 field in SGI
          //           generation System registers
          // SEIS [14], does not support generation of SEIs (deprecated)
          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
          // PRIbits [10:8], number of priority bits implemented, minus one
          ICC_CTLR_EL3 icc_ctlr_el3 = value;
          icc_ctlr_el3.ExtRange = 0;
          icc_ctlr_el3.RSS = 1;
          icc_ctlr_el3.nDS = 0;
          icc_ctlr_el3.A3V = 1;
          icc_ctlr_el3.SEIS = 0;
          icc_ctlr_el3.IDbits = 0;
          icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
          value = icc_ctlr_el3;
          break;
      }

      // Hyp Control Register
      case MISCREG_ICH_HCR:
      case MISCREG_ICH_HCR_EL2:
        break;

      // Hyp Active Priorities Group 0 Registers
      case MISCREG_ICH_AP0R0:
      case MISCREG_ICH_AP0R0_EL2:
        break;

      // only implemented if supporting 6 or more bits of priority
      case MISCREG_ICH_AP0R1:
      case MISCREG_ICH_AP0R1_EL2:
      // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICH_AP0R2:
      case MISCREG_ICH_AP0R2_EL2:
      // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICH_AP0R3:
      case MISCREG_ICH_AP0R3_EL2:
        // Unimplemented registers are RAZ/WI
        return 0;

      // Hyp Active Priorities Group 1 Registers
      case MISCREG_ICH_AP1R0:
      case MISCREG_ICH_AP1R0_EL2:
        break;

      // only implemented if supporting 6 or more bits of priority
      case MISCREG_ICH_AP1R1:
      case MISCREG_ICH_AP1R1_EL2:
      // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICH_AP1R2:
      case MISCREG_ICH_AP1R2_EL2:
      // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICH_AP1R3:
      case MISCREG_ICH_AP1R3_EL2:
        // Unimplemented registers are RAZ/WI
        return 0;

      // Maintenance Interrupt State Register
      case MISCREG_ICH_MISR:
      case MISCREG_ICH_MISR_EL2:
        value = maintenanceInterruptStatus();
        break;

      // VGIC Type Register
      case MISCREG_ICH_VTR:
      case MISCREG_ICH_VTR_EL2: {
        ICH_VTR_EL2 ich_vtr_el2 = value;

        ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
        ich_vtr_el2.A3V = 1;
        ich_vtr_el2.IDbits = 1;
        ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
        ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;

        value = ich_vtr_el2;
        break;
      }

      // End of Interrupt Status Register
      case MISCREG_ICH_EISR:
      case MISCREG_ICH_EISR_EL2:
        value = eoiMaintenanceInterruptStatus();
        break;

      // Empty List Register Status Register
      case MISCREG_ICH_ELRSR:
      case MISCREG_ICH_ELRSR_EL2:
        value = 0;

        for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
            ICH_LR_EL2 ich_lr_el2 =
                isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

            if ((ich_lr_el2.State  == ICH_LR_EL2_STATE_INVALID) &&
                (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
                value |= (1 << lr_idx);
            }
        }

        break;

      // List Registers
      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
        value = value >> 32;
        break;

      // List Registers
      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
        value = value & 0xffffffff;
        break;

      // List Registers
      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
        break;

      // Virtual Machine Control Register
      case MISCREG_ICH_VMCR:
      case MISCREG_ICH_VMCR_EL2:
        break;

      default:
        panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
              misc_reg, miscRegName[misc_reg]);
    }

    DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
            miscRegName[misc_reg], value);
    return value;
}

void
Gicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
{
    bool do_virtual_update = false;
    DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
            miscRegName[misc_reg], val);
    bool hcr_fmo = getHCREL2FMO();
    bool hcr_imo = getHCREL2IMO();

    switch (misc_reg) {
      // Active Priorities Group 1 Registers
      case MISCREG_ICC_AP1R0:
      case MISCREG_ICC_AP1R0_EL1:
        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
            return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
        }

        setBankedMiscReg(MISCREG_ICC_AP1R0_EL1, val);
        return;

      case MISCREG_ICC_AP1R1:
      case MISCREG_ICC_AP1R1_EL1:

        // only implemented if supporting 6 or more bits of priority
      case MISCREG_ICC_AP1R2:
      case MISCREG_ICC_AP1R2_EL1:

        // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICC_AP1R3:
      case MISCREG_ICC_AP1R3_EL1:
        // only implemented if supporting 7 or more bits of priority
        break;

      // Active Priorities Group 0 Registers
      case MISCREG_ICC_AP0R0:
      case MISCREG_ICC_AP0R0_EL1:
        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
            return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
        }

        break;

      case MISCREG_ICC_AP0R1:
      case MISCREG_ICC_AP0R1_EL1:

        // only implemented if supporting 6 or more bits of priority
      case MISCREG_ICC_AP0R2:
      case MISCREG_ICC_AP0R2_EL1:

        // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICC_AP0R3:
      case MISCREG_ICC_AP0R3_EL1:
        // only implemented if supporting 7 or more bits of priority
        break;

      // End Of Interrupt Register 0
      case MISCREG_ICC_EOIR0:
      case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
              return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
          }

          int int_id = val & 0xffffff;

          // avoid activation for special interrupts
          if (int_id >= Gicv3::INTID_SECURE &&
              int_id <= Gicv3::INTID_SPURIOUS) {
              return;
          }

          Gicv3::GroupId group = Gicv3::G0S;

          if (highestActiveGroup() != group) {
              return;
          }

          dropPriority(group);

          if (!isEOISplitMode()) {
              deactivateIRQ(int_id, group);
          }

          break;
      }

      // Virtual End Of Interrupt Register 0
      case MISCREG_ICV_EOIR0_EL1: {
          int int_id = val & 0xffffff;

          // avoid deactivation for special interrupts
          if (int_id >= Gicv3::INTID_SECURE &&
                  int_id <= Gicv3::INTID_SPURIOUS) {
              return;
          }

          uint8_t drop_prio = virtualDropPriority();

          if (drop_prio == 0xff) {
              return;
          }

          int lr_idx = virtualFindActive(int_id);

          if (lr_idx < 0) {
              // No LR found matching
              virtualIncrementEOICount();
          } else {
              ICH_LR_EL2 ich_lr_el2 =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
              Gicv3::GroupId lr_group =
                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;

              if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
                  //if (!virtualIsEOISplitMode())
                  {
                      virtualDeactivateIRQ(lr_idx);
                  }
              }
          }

          virtualUpdate();
          break;
      }

      // End Of Interrupt Register 1
      case MISCREG_ICC_EOIR1:
      case MISCREG_ICC_EOIR1_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return setMiscReg(MISCREG_ICV_EOIR1_EL1, val);
          }

          int int_id = val & 0xffffff;

          // avoid deactivation for special interrupts
          if (int_id >= Gicv3::INTID_SECURE &&
              int_id <= Gicv3::INTID_SPURIOUS) {
              return;
          }

          Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;

          if (highestActiveGroup() == Gicv3::G0S) {
              return;
          }

          if (distributor->DS == 0) {
              if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) {
                  return;
              } else if (highestActiveGroup() == Gicv3::G1NS &&
                         !(!inSecureState() or (currEL() == EL3))) {
                  return;
              }
          }

          dropPriority(group);

          if (!isEOISplitMode()) {
              deactivateIRQ(int_id, group);
          }

          break;
      }

      // Virtual End Of Interrupt Register 1
      case MISCREG_ICV_EOIR1_EL1: {
          int int_id = val & 0xffffff;

          // avoid deactivation for special interrupts
          if (int_id >= Gicv3::INTID_SECURE &&
              int_id <= Gicv3::INTID_SPURIOUS) {
              return;
          }

          uint8_t drop_prio = virtualDropPriority();

          if (drop_prio == 0xff) {
              return;
          }

          int lr_idx = virtualFindActive(int_id);

          if (lr_idx < 0) {
              // No matching LR found
              virtualIncrementEOICount();
          } else {
              ICH_LR_EL2 ich_lr_el2 =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
              Gicv3::GroupId lr_group =
                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;

              if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
                  if (!virtualIsEOISplitMode()) {
                      virtualDeactivateIRQ(lr_idx);
                  }
              }
          }

          virtualUpdate();
          break;
      }

      // Deactivate Interrupt Register
      case MISCREG_ICC_DIR:
      case MISCREG_ICC_DIR_EL1: {
          if ((currEL() == EL1) && !inSecureState() &&
              (hcr_imo || hcr_fmo)) {
              return setMiscReg(MISCREG_ICV_DIR_EL1, val);
          }

          int int_id = val & 0xffffff;

          // The following checks are as per spec pseudocode
          // aarch64/support/ICC_DIR_EL1

          // Check for spurious ID
          if (int_id >= Gicv3::INTID_SECURE) {
              return;
          }

          // EOI mode is not set, so don't deactivate
          if (!isEOISplitMode()) {
              return;
          }

          Gicv3::GroupId group =
              int_id >= 32 ? distributor->getIntGroup(int_id) :
              redistributor->getIntGroup(int_id);
          bool irq_is_grp0 = group == Gicv3::G0S;
          bool single_sec_state = distributor->DS;
          bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
          bool route_fiq_to_el3 = scr_el3.fiq;
          bool route_irq_to_el3 = scr_el3.irq;
          bool route_fiq_to_el2 = hcr_fmo;
          bool route_irq_to_el2 = hcr_imo;

          switch (currEL()) {
            case EL3:
              break;

            case EL2:
              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 EL1:
              if (!isSecureBelowEL3()) {
                  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:
              break;
          }

          deactivateIRQ(int_id, group);
          break;
      }

      // Deactivate Virtual Interrupt Register
      case MISCREG_ICV_DIR_EL1: {
          int int_id = val & 0xffffff;

          // avoid deactivation for special interrupts
          if (int_id >= Gicv3::INTID_SECURE &&
              int_id <= Gicv3::INTID_SPURIOUS) {
              return;
          }

          if (!virtualIsEOISplitMode()) {
              return;
          }

          int lr_idx = virtualFindActive(int_id);

          if (lr_idx < 0) {
              // No matching LR found
              virtualIncrementEOICount();
          } else {
              virtualDeactivateIRQ(lr_idx);
          }

          virtualUpdate();
          break;
      }

      // Binary Point Register 0
      case MISCREG_ICC_BPR0:
      case MISCREG_ICC_BPR0_EL1: {
        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
            return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
        }
        break;
      }
      // Binary Point Register 1
      case MISCREG_ICC_BPR1:
      case MISCREG_ICC_BPR1_EL1: {
        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
            return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
        }

        val &= 0x7;

        if (isSecureBelowEL3()) {
            // group == Gicv3::G1S
            ICC_CTLR_EL1 icc_ctlr_el1_s =
                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);

            val = val > GIC_MIN_BPR ? val : GIC_MIN_BPR;
            if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
                isa->setMiscRegNoEffect(MISCREG_ICC_BPR0_EL1, val);
            } else {
                isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S, val);
            }
            return;
        } else {
            // group == Gicv3::G1NS
            ICC_CTLR_EL1 icc_ctlr_el1_ns =
                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);

            val = val > GIC_MIN_BPR_NS ? val : GIC_MIN_BPR_NS;
            if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
                // Non secure writes from EL1 and EL2 are ignored
            } else {
                isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS, val);
            }
            return;
        }

        break;
      }

      // Virtual Binary Point Register 0
      case MISCREG_ICV_BPR0_EL1:
      // Virtual Binary Point Register 1
      case MISCREG_ICV_BPR1_EL1: {
          Gicv3::GroupId group =
              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
          ICH_VMCR_EL2 ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

          if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
              // BPR0 + 1 saturated to 7, WI
              return;
          }

          uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;

          if (group != Gicv3::G0S) {
              min_VPBR++;
          }

          if (val < min_VPBR) {
              val = min_VPBR;
          }

          if (group == Gicv3::G0S) {
              ich_vmcr_el2.VBPR0 = val;
          } else {
              ich_vmcr_el2.VBPR1 = val;
          }

          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
          do_virtual_update = true;
          break;
      }

      // Control Register EL1
      case MISCREG_ICC_CTLR:
      case MISCREG_ICC_CTLR_EL1: {
          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
              return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
          }

          /*
           * ExtRange is RO.
           * RSS is RO.
           * A3V is RO.
           * SEIS is RO.
           * IDbits is RO.
           * PRIbits is RO.
           */
          ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
          ICC_CTLR_EL1 icc_ctlr_el1 =
              readBankedMiscReg(MISCREG_ICC_CTLR_EL1);

          ICC_CTLR_EL3 icc_ctlr_el3 =
              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);

          // The following could be refactored but it is following
          // spec description section 9.2.6 point by point.

          // PMHE
          if (haveEL(EL3)) {
              // PMHE is alias of ICC_CTLR_EL3.PMHE

              if (distributor->DS == 0) {
                  // PMHE is RO
              } else if (distributor->DS == 1) {
                  // PMHE is RW
                  icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
                  icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
              }
          } else {
              // PMHE is RW (by implementation choice)
              icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
          }

          // EOImode
          icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;

          if (inSecureState()) {
              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
              icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
          } else {
              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
              icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
          }

          // CBPR
          if (haveEL(EL3)) {
              // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}

              if (distributor->DS == 0) {
                  // CBPR is RO
              } else {
                  // CBPR is RW
                  icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;

                  if (inSecureState()) {
                      icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
                  } else {
                      icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
                  }
              }
          } else {
              // CBPR is RW
              icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
          }

          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);

          setBankedMiscReg(MISCREG_ICC_CTLR_EL1, icc_ctlr_el1);
          return;
      }

      // Virtual Control Register
      case MISCREG_ICV_CTLR_EL1: {
         ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
         ICV_CTLR_EL1 icv_ctlr_el1 =
             isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
         icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
         icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
         val = icv_ctlr_el1;

         // Aliases
         // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
         // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
         ICH_VMCR_EL2 ich_vmcr_el2 =
             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
         ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
         ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
         isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
         break;
      }

      // Control Register EL3
      case MISCREG_ICC_MCTLR:
      case MISCREG_ICC_CTLR_EL3: {
          /*
           * ExtRange is RO.
           * RSS is RO.
           * nDS is RO.
           * A3V is RO.
           * SEIS is RO.
           * IDbits is RO.
           * PRIbits is RO.
           * PMHE is RAO/WI, priority-based routing is always used.
           */
          ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;

          // Aliases
          if (haveEL(EL3))
          {
              ICC_CTLR_EL1 icc_ctlr_el1_s =
                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
              ICC_CTLR_EL1 icc_ctlr_el1_ns =
                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);

              // ICC_CTLR_EL1(NS).EOImode is an alias of
              // ICC_CTLR_EL3.EOImode_EL1NS
              icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
              // ICC_CTLR_EL1(S).EOImode is an alias of
              // ICC_CTLR_EL3.EOImode_EL1S
              icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
              // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
              icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
              // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
              icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;

              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
                                      icc_ctlr_el1_ns);
          }

          ICC_CTLR_EL3 icc_ctlr_el3 =
              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);

          icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
          icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
          icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
          icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
          icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
          icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;

          val = icc_ctlr_el3;
          break;
      }

      // Priority Mask Register
      case MISCREG_ICC_PMR:
      case MISCREG_ICC_PMR_EL1: {
          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
              return setMiscReg(MISCREG_ICV_PMR_EL1, val);
          }

          val &= 0xff;
          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);

          if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
              // Spec section 4.8.1
              // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
              RegVal old_icc_pmr_el1 =
                  isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);

              if (!(old_icc_pmr_el1 & 0x80)) {
                  // If the current priority mask value is in the range of
                  // 0x00-0x7F then WI
                  return;
              }

              // If the current priority mask value is in the range of
              // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
              // based on the Non-secure read of the priority mask value
              // written to the register.

              val = (val >> 1) | 0x80;
          }

          val &= ~0U << (8 - PRIORITY_BITS);
          break;
      }

      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
          ICH_VMCR_EL2 ich_vmcr_el2 =
             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          ich_vmcr_el2.VPMR = val & 0xff;

          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
          virtualUpdate();
          return;
      }

      // Interrupt Group 0 Enable Register EL1
      case MISCREG_ICC_IGRPEN0:
      case MISCREG_ICC_IGRPEN0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
              return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
          }

          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1, val);
          updateDistributor();
          return;
      }

      // Virtual Interrupt Group 0 Enable register
      case MISCREG_ICV_IGRPEN0_EL1: {
          bool enable = val & 0x1;
          ICH_VMCR_EL2 ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          ich_vmcr_el2.VENG0 = enable;
          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
          virtualUpdate();
          return;
      }

      // Interrupt Group 1 Enable register EL1
      case MISCREG_ICC_IGRPEN1:
      case MISCREG_ICC_IGRPEN1_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
          }

          setBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1, val);
          updateDistributor();
          return;
      }

      // Virtual Interrupt Group 1 Enable register
      case MISCREG_ICV_IGRPEN1_EL1: {
          bool enable = val & 0x1;
          ICH_VMCR_EL2 ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          ich_vmcr_el2.VENG1 = enable;
          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
          virtualUpdate();
          return;
      }

      // Interrupt Group 1 Enable register
      case MISCREG_ICC_MGRPEN1:
      case MISCREG_ICC_IGRPEN1_EL3: {
          ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;

          isa->setMiscRegNoEffect(
              MISCREG_ICC_IGRPEN1_EL1_S, icc_igrpen1_el3.EnableGrp1S);
          isa->setMiscRegNoEffect(
              MISCREG_ICC_IGRPEN1_EL1_NS, icc_igrpen1_el3.EnableGrp1NS);
          updateDistributor();
          return;
      }

      // Software Generated Interrupt Group 0 Register
      case MISCREG_ICC_SGI0R:
      case MISCREG_ICC_SGI0R_EL1:
        generateSGI(val, Gicv3::G0S);
        break;

      // Software Generated Interrupt Group 1 Register
      case MISCREG_ICC_SGI1R:
      case MISCREG_ICC_SGI1R_EL1: {
        Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;

        generateSGI(val, group);
        break;
      }

      // Alias Software Generated Interrupt Group 1 Register
      case MISCREG_ICC_ASGI1R:
      case MISCREG_ICC_ASGI1R_EL1: {
        Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S;

        generateSGI(val, group);
        break;
      }

      // System Register Enable Register EL1
      case MISCREG_ICC_SRE:
      case MISCREG_ICC_SRE_EL1:
      // System Register Enable Register EL2
      case MISCREG_ICC_HSRE:
      case MISCREG_ICC_SRE_EL2:
      // System Register Enable Register EL3
      case MISCREG_ICC_MSRE:
      case MISCREG_ICC_SRE_EL3:
        // All bits are RAO/WI
        return;

      // Hyp Control Register
      case MISCREG_ICH_HCR:
      case MISCREG_ICH_HCR_EL2: {
        ICH_HCR_EL2 requested_ich_hcr_el2 = val;
        ICH_HCR_EL2 ich_hcr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);

        if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
        {
            // EOIcount - Permitted behaviors are:
            // - Increment EOIcount.
            // - Leave EOIcount unchanged.
            ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
        }

        ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
        ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
        ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
        ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
        ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
        ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
        ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
        ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
        ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
        ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
        ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
        ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
        ich_hcr_el2.En = requested_ich_hcr_el2.En;
        val = ich_hcr_el2;
        do_virtual_update = true;
        break;
      }

      // List Registers
      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
        ICH_LRC requested_ich_lrc = val;
        ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);

        ich_lrc.State = requested_ich_lrc.State;
        ich_lrc.HW = requested_ich_lrc.HW;
        ich_lrc.Group = requested_ich_lrc.Group;

        // Priority, bits [23:16]
        // At least five bits must be implemented.
        // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
        // We implement 5 bits.
        ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
                           (ich_lrc.Priority & 0x07);

        // pINTID, bits [12:0]
        // When ICH_LR<n>.HW is 0 this field has the following meaning:
        // - Bits[12:10] : RES0.
        // - Bit[9] : EOI.
        // - Bits[8:0] : RES0.
        // When ICH_LR<n>.HW is 1:
        // - This field is only required to implement enough bits to hold a
        // valid value for the implemented INTID size. Any unused higher
        // order bits are RES0.
        if (requested_ich_lrc.HW == 0) {
            ich_lrc.EOI = requested_ich_lrc.EOI;
        } else {
            ich_lrc.pINTID = requested_ich_lrc.pINTID;
        }

        val = ich_lrc;
        do_virtual_update = true;
        break;
      }

      // List Registers
      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
          // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
          RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
          val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
          do_virtual_update = true;
          break;
      }

      // List Registers
      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
          ICH_LR_EL2 requested_ich_lr_el2 = val;
          ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);

          ich_lr_el2.State = requested_ich_lr_el2.State;
          ich_lr_el2.HW = requested_ich_lr_el2.HW;
          ich_lr_el2.Group = requested_ich_lr_el2.Group;

          // Priority, bits [55:48]
          // At least five bits must be implemented.
          // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
          // We implement 5 bits.
          ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
                                (ich_lr_el2.Priority & 0x07);

          // pINTID, bits [44:32]
          // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
          // - Bits[44:42] : RES0.
          // - Bit[41] : EOI.
          // - Bits[40:32] : RES0.
          // When ICH_LR<n>_EL2.HW is 1:
          // - This field is only required to implement enough bits to hold a
          // valid value for the implemented INTID size. Any unused higher
          // order bits are RES0.
          if (requested_ich_lr_el2.HW == 0) {
              ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
          } else {
              ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
          }

          // vINTID, bits [31:0]
          // It is IMPLEMENTATION DEFINED how many bits are implemented,
          // though at least 16 bits must be implemented.
          // Unimplemented bits are RES0.
          ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;

          val = ich_lr_el2;
          do_virtual_update = true;
          break;
      }

      // Virtual Machine Control Register
      case MISCREG_ICH_VMCR:
      case MISCREG_ICH_VMCR_EL2: {
          ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
          ICH_VMCR_EL2 ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
          uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;

          if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
              ich_vmcr_el2.VBPR0 = min_vpr0;
          } else {
              ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
          }

          uint8_t min_vpr1 = min_vpr0 + 1;

          if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
              ich_vmcr_el2.VBPR1 = min_vpr1;
          } else {
              ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
          }

          ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
          ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
          ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
          ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
          val = ich_vmcr_el2;
          break;
      }

      // Hyp Active Priorities Group 0 Registers
      case MISCREG_ICH_AP0R0:
      case MISCREG_ICH_AP0R0_EL2:
        break;

      // only implemented if supporting 6 or more bits of priority
      case MISCREG_ICH_AP0R1:
      case MISCREG_ICH_AP0R1_EL2:
      // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICH_AP0R2:
      case MISCREG_ICH_AP0R2_EL2:
      // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICH_AP0R3:
      case MISCREG_ICH_AP0R3_EL2:
        // Unimplemented registers are RAZ/WI
        return;

      // Hyp Active Priorities Group 1 Registers
      case MISCREG_ICH_AP1R0:
      case MISCREG_ICH_AP1R0_EL2:
        break;

      // only implemented if supporting 6 or more bits of priority
      case MISCREG_ICH_AP1R1:
      case MISCREG_ICH_AP1R1_EL2:
      // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICH_AP1R2:
      case MISCREG_ICH_AP1R2_EL2:
      // only implemented if supporting 7 or more bits of priority
      case MISCREG_ICH_AP1R3:
      case MISCREG_ICH_AP1R3_EL2:
        // Unimplemented registers are RAZ/WI
        return;

      default:
        panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
              misc_reg, miscRegName[misc_reg]);
    }

    isa->setMiscRegNoEffect(misc_reg, val);

    if (do_virtual_update) {
        virtualUpdate();
    }
}

RegVal
Gicv3CPUInterface::readBankedMiscReg(MiscRegIndex misc_reg) const
{
    return isa->readMiscRegNoEffect(
        isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()));
}

void
Gicv3CPUInterface::setBankedMiscReg(MiscRegIndex misc_reg, RegVal val) const
{
    isa->setMiscRegNoEffect(
        isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()), val);
}

int
Gicv3CPUInterface::virtualFindActive(uint32_t int_id) const
{
    for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
        ICH_LR_EL2 ich_lr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

        if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
             (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
            (ich_lr_el2.vINTID == int_id)) {
            return lr_idx;
        }
    }

    return -1;
}

uint32_t
Gicv3CPUInterface::getHPPIR0() const
{
    if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
        return Gicv3::INTID_SPURIOUS;
    }

    bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;

    if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
        // interrupt for the other state pending
        return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
    }

    if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
        return Gicv3::INTID_SPURIOUS;
    }

    if (irq_is_secure && !inSecureState()) {
        // Secure interrupts not visible in Non-secure
        return Gicv3::INTID_SPURIOUS;
    }

    return hppi.intid;
}

uint32_t
Gicv3CPUInterface::getHPPIR1() const
{
    if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
        return Gicv3::INTID_SPURIOUS;
    }

    ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
    if ((currEL() == EL3) && icc_ctlr_el3.RM) {
        if (hppi.group == Gicv3::G0S) {
            return Gicv3::INTID_SECURE;
        } else if (hppi.group == Gicv3::G1NS) {
            return Gicv3::INTID_NONSECURE;
        }
    }

    if (hppi.group == Gicv3::G0S) {
        return Gicv3::INTID_SPURIOUS;
    }

    bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);

    if (irq_is_secure) {
        if (!inSecureState()) {
            // Secure interrupts not visible in Non-secure
            return Gicv3::INTID_SPURIOUS;
        }
    } else if (!isEL3OrMon() && inSecureState()) {
        // Group 1 non-secure interrupts not visible in Secure EL1
        return Gicv3::INTID_SPURIOUS;
    }

    return hppi.intid;
}

void
Gicv3CPUInterface::dropPriority(Gicv3::GroupId group)
{
    int apr_misc_reg = 0;

    switch (group) {
      case Gicv3::G0S:
        apr_misc_reg = MISCREG_ICC_AP0R0_EL1;
        break;
      case Gicv3::G1S:
        apr_misc_reg = MISCREG_ICC_AP1R0_EL1_S;
        break;
      case Gicv3::G1NS:
        apr_misc_reg = MISCREG_ICC_AP1R0_EL1_NS;
        break;
      default:
        panic("Invalid Gicv3::GroupId");
    }

    RegVal apr = isa->readMiscRegNoEffect(apr_misc_reg);

    if (apr) {
        apr &= apr - 1;
        isa->setMiscRegNoEffect(apr_misc_reg, apr);
    }

    update();
}

uint8_t
Gicv3CPUInterface::virtualDropPriority()
{
    int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);

    for (int i = 0; i < apr_max; i++) {
        RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
        RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);

        if (!vapr0 && !vapr1) {
            continue;
        }

        int vapr0_count = ctz32(vapr0);
        int vapr1_count = ctz32(vapr1);

        if (vapr0_count <= vapr1_count) {
            vapr0 &= vapr0 - 1;
            isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
            return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
        } else {
            vapr1 &= vapr1 - 1;
            isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
            return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
        }
    }

    return 0xff;
}

void
Gicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
{
    uint8_t aff3 = bits(val, 55, 48);
    uint8_t aff2 = bits(val, 39, 32);
    uint8_t aff1 = bits(val, 23, 16);;
    uint16_t target_list = bits(val, 15, 0);
    uint32_t int_id = bits(val, 27, 24);
    bool irm = bits(val, 40, 40);
    uint8_t rs = bits(val, 47, 44);

    bool ns = !inSecureState();

    for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
        Gicv3Redistributor * redistributor_i =
            gic->getRedistributor(i);
        uint32_t affinity_i = redistributor_i->getAffinity();

        if (irm) {
            // Interrupts routed to all PEs in the system,
            // excluding "self"
            if (affinity_i == redistributor->getAffinity()) {
                continue;
            }
        } else {
            // Interrupts routed to the PEs specified by
            // Aff3.Aff2.Aff1.<target list>
            if ((affinity_i >> 8) !=
                ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
                continue;
            }

            uint8_t aff0_i = bits(affinity_i, 7, 0);

            if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
                ((0x1 << (aff0_i - rs * 16)) & target_list))) {
                continue;
            }
        }

        redistributor_i->sendSGI(int_id, group, ns);
    }
}

void
Gicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
{
    // Update active priority registers.
    uint32_t prio = hppi.prio & 0xf8;
    int apr_bit = prio >> (8 - PRIORITY_BITS);
    int reg_bit = apr_bit % 32;

    int apr_idx = 0;
    switch (group) {
      case Gicv3::G0S:
        apr_idx = MISCREG_ICC_AP0R0_EL1;
        break;
      case Gicv3::G1S:
        apr_idx = MISCREG_ICC_AP1R0_EL1_S;
        break;
      case Gicv3::G1NS:
        apr_idx = MISCREG_ICC_AP1R0_EL1_NS;
        break;
      default:
        panic("Invalid Gicv3::GroupId");
    }

    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
    apr |= (1 << reg_bit);
    isa->setMiscRegNoEffect(apr_idx, apr);

    // Move interrupt state from pending to active.
    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
        // SGI or PPI, redistributor
        redistributor->activateIRQ(int_id);
    } else if (int_id < Gicv3::INTID_SECURE) {
        // SPI, distributor
        distributor->activateIRQ(int_id);
    } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
        // LPI, Redistributor
        redistributor->setClrLPI(int_id, false);
    }

    // By setting the priority to 0xff we are effectively
    // making the int_id not pending anymore at the cpu
    // interface.
    resetHppi(int_id);
    updateDistributor();
}

void
Gicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
{
    // Update active priority registers.
    ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
            lr_idx);
    Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
    uint8_t prio = ich_lr_el.Priority & 0xf8;
    int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
    int reg_no = apr_bit / 32;
    int reg_bit = apr_bit % 32;
    int apr_idx = group == Gicv3::G0S ?
        MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
    apr |= (1 << reg_bit);
    isa->setMiscRegNoEffect(apr_idx, apr);
    // Move interrupt state from pending to active.
    ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
}

void
Gicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
{
    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
        // SGI or PPI, redistributor
        redistributor->deactivateIRQ(int_id);
    } else if (int_id < Gicv3::INTID_SECURE) {
        // SPI, distributor
        distributor->deactivateIRQ(int_id);
    }

    updateDistributor();
}

void
Gicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
{
    ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
            lr_idx);

    if (ich_lr_el2.HW) {
        // Deactivate the associated physical interrupt
        if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
            Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
                distributor->getIntGroup(ich_lr_el2.pINTID) :
                redistributor->getIntGroup(ich_lr_el2.pINTID);
            deactivateIRQ(ich_lr_el2.pINTID, group);
        }
    }

    //  Remove the active bit
    ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
}

/*
 * Returns the priority group field for the current BPR value for the group.
 * GroupBits() Pseudocode from spec.
 */
uint32_t
Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
{
    ICC_CTLR_EL1 icc_ctlr_el1_s =
        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
    ICC_CTLR_EL1 icc_ctlr_el1_ns =
        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);

    if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
        (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
        group = Gicv3::G0S;
    }

    int bpr;

    if (group == Gicv3::G0S) {
        bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
    } else if (group == Gicv3::G1S) {
        bpr = bpr1(Gicv3::G1S) & 0x7;
    } else {
        bpr = bpr1(Gicv3::G1NS) & 0x7;
    }

    if (group == Gicv3::G1NS) {
        assert(bpr > 0);
        bpr--;
    }

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

uint32_t
Gicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
{
    ICH_VMCR_EL2 ich_vmcr_el2 =
        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

    if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
        group = Gicv3::G0S;
    }

    int bpr;

    if (group == Gicv3::G0S) {
        bpr = ich_vmcr_el2.VBPR0;
    } else {
        bpr = ich_vmcr_el2.VBPR1;
    }

    if (group == Gicv3::G1NS) {
        assert(bpr > 0);
        bpr--;
    }

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

bool
Gicv3CPUInterface::isEOISplitMode() const
{
    if (isEL3OrMon()) {
        ICC_CTLR_EL3 icc_ctlr_el3 =
            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
        return icc_ctlr_el3.EOImode_EL3;
    } else {
        ICC_CTLR_EL1 icc_ctlr_el1 = 0;
        if (inSecureState())
            icc_ctlr_el1 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
        else
            icc_ctlr_el1 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
        return icc_ctlr_el1.EOImode;
    }
}

bool
Gicv3CPUInterface::virtualIsEOISplitMode() const
{
    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
    return ich_vmcr_el2.VEOIM;
}

int
Gicv3CPUInterface::highestActiveGroup() const
{
    int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
    int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
    int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));

    if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
        return Gicv3::G1NS;
    }

    if (gq_ctz < g0_ctz) {
        return Gicv3::G1S;
    }

    if (g0_ctz < 32) {
        return Gicv3::G0S;
    }

    return -1;
}

void
Gicv3CPUInterface::updateDistributor()
{
    distributor->update();
}

void
Gicv3CPUInterface::update()
{
    bool signal_IRQ = false;
    bool signal_FIQ = false;

    if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
        /*
         * Secure enabled GIC sending a G1S IRQ to a secure disabled
         * CPU -> send G0 IRQ
         */
        hppi.group = Gicv3::G0S;
    }

    if (hppiCanPreempt()) {
        InterruptTypes int_type = intSignalType(hppi.group);
        DPRINTF(GIC, "Gicv3CPUInterface::update(): "
                "posting int as %d!\n", int_type);
        int_type == INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
    }

    if (signal_IRQ) {
        gic->postInt(cpuId, INT_IRQ);
    } else {
        gic->deassertInt(cpuId, INT_IRQ);
    }

    if (signal_FIQ) {
        gic->postInt(cpuId, INT_FIQ);
    } else {
        gic->deassertInt(cpuId, INT_FIQ);
    }
}

void
Gicv3CPUInterface::virtualUpdate()
{
    bool signal_IRQ = false;
    bool signal_FIQ = false;
    int lr_idx = getHPPVILR();

    if (lr_idx >= 0) {
        ICH_LR_EL2 ich_lr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

        if (hppviCanPreempt(lr_idx)) {
            if (ich_lr_el2.Group) {
                signal_IRQ = true;
            } else {
                signal_FIQ = true;
            }
        }
    }

    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);

    const bool maint_pending = redistributor->irqPending[
        maintenanceInterrupt->num()];

    if (ich_hcr_el2.En && !maint_pending && maintenanceInterruptStatus()) {
        maintenanceInterrupt->raise();
    } else if (maint_pending) {
        maintenanceInterrupt->clear();
    }

    if (signal_IRQ) {
        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
                "posting int as %d!\n", INT_VIRT_IRQ);
        gic->postInt(cpuId, INT_VIRT_IRQ);
    } else {
        gic->deassertInt(cpuId, INT_VIRT_IRQ);
    }

    if (signal_FIQ) {
        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
                "posting int as %d!\n", INT_VIRT_FIQ);
        gic->postInt(cpuId, INT_VIRT_FIQ);
    } else {
        gic->deassertInt(cpuId, INT_VIRT_FIQ);
    }
}

// Returns the index of the LR with the HPPI
int
Gicv3CPUInterface::getHPPVILR() const
{
    int idx = -1;
    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

    if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
        // VG0 and VG1 disabled...
        return idx;
    }

    uint8_t highest_prio = 0xff;

    for (int i = 0; i < 16; i++) {
        ICH_LR_EL2 ich_lr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);

        if (ich_lr_el2.State != Gicv3::INT_PENDING) {
            continue;
        }

        if (ich_lr_el2.Group) {
            // VG1
            if (!ich_vmcr_el2.VENG1) {
                continue;
            }
        } else {
            // VG0
            if (!ich_vmcr_el2.VENG0) {
                continue;
            }
        }

        uint8_t prio = ich_lr_el2.Priority;

        if (prio < highest_prio) {
            highest_prio = prio;
            idx = i;
        }
    }

    return idx;
}

bool
Gicv3CPUInterface::hppviCanPreempt(int lr_idx) const
{
    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
    if (!ich_hcr_el2.En) {
        // virtual interface is disabled
        return false;
    }

    ICH_LR_EL2 ich_lr_el2 =
        isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
    uint8_t prio = ich_lr_el2.Priority;
    uint8_t vpmr =
        bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);

    if (prio >= vpmr) {
        // prioriry masked
        return false;
    }

    uint8_t rprio = virtualHighestActivePriority();

    if (rprio == 0xff) {
        return true;
    }

    Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
    uint32_t prio_mask = virtualGroupPriorityMask(group);

    if ((prio & prio_mask) < (rprio & prio_mask)) {
        return true;
    }

    return false;
}

uint8_t
Gicv3CPUInterface::virtualHighestActivePriority() const
{
    uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);

    for (int i = 0; i < num_aprs; i++) {
        RegVal vapr =
            isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
            isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);

        if (!vapr) {
            continue;
        }

        return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
    }

    // no active interrups, return idle priority
    return 0xff;
}

void
Gicv3CPUInterface::virtualIncrementEOICount()
{
    // Increment the EOICOUNT field in ICH_HCR_EL2
    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
    uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
    EOI_cout++;
    ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
    isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
}

// spec section 4.6.2
InterruptTypes
Gicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
{
    bool is_fiq = false;

    switch (group) {
      case Gicv3::G0S:
        is_fiq = true;
        break;

      case Gicv3::G1S:
        is_fiq = (distributor->DS == 0) &&
            (!inSecureState() || ((currEL() == EL3) && isAA64()));
        break;

      case Gicv3::G1NS:
        is_fiq = (distributor->DS == 0) && inSecureState();
        break;

      default:
        panic("Gicv3CPUInterface::intSignalType(): invalid group!");
    }

    if (is_fiq) {
        return INT_FIQ;
    } else {
        return INT_IRQ;
    }
}

bool
Gicv3CPUInterface::hppiCanPreempt()
{
    if (hppi.prio == 0xff) {
        // there is no pending interrupt
        return false;
    }

    if (!groupEnabled(hppi.group)) {
        // group disabled at CPU interface
        return false;
    }

    if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
        // priority masked
        return false;
    }

    uint8_t rprio = highestActivePriority();

    if (rprio == 0xff) {
        return true;
    }

    uint32_t prio_mask = groupPriorityMask(hppi.group);

    if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
        return true;
    }

    return false;
}

uint8_t
Gicv3CPUInterface::highestActivePriority() const
{
    uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);

    if (apr) {
        return ctz32(apr) << (GIC_MIN_BPR + 1);
    }

    // no active interrups, return idle priority
    return 0xff;
}

bool
Gicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
{
    switch (group) {
      case Gicv3::G0S: {
        ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
        return icc_igrpen0_el1.Enable && distributor->EnableGrp0;
      }

      case Gicv3::G1S: {
        ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
        return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
      }

      case Gicv3::G1NS: {
        ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
        return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS;
      }

      default:
        panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
    }
}

bool
Gicv3CPUInterface::inSecureState() const
{
    if (!gic->getSystem()->haveSecurity()) {
        return false;
    }

    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
    return ::inSecureState(scr, cpsr);
}

int
Gicv3CPUInterface::currEL() const
{
    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
    bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);

    if (is_64) {
        return (ExceptionLevel)(uint8_t) cpsr.el;
    } else {
        switch (cpsr.mode) {
          case MODE_USER:
            return 0;

          case MODE_HYP:
            return 2;

          case MODE_MON:
            return 3;

          default:
            return 1;
        }
    }
}

bool
Gicv3CPUInterface::haveEL(ExceptionLevel el) const
{
    switch (el) {
      case EL0:
      case EL1:
        return true;

      case EL2:
        return gic->getSystem()->haveVirtualization();

      case EL3:
        return gic->getSystem()->haveSecurity();

      default:
        warn("Unimplemented Exception Level\n");
        return false;
    }
}

bool
Gicv3CPUInterface::isSecureBelowEL3() const
{
    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
    return haveEL(EL3) && scr.ns == 0;
}

bool
Gicv3CPUInterface::isAA64() const
{
    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
    return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
}

bool
Gicv3CPUInterface::isEL3OrMon() const
{
    if (haveEL(EL3)) {
        CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
        bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);

        if (is_64 && (cpsr.el == EL3)) {
            return true;
        } else if (!is_64 && (cpsr.mode == MODE_MON)) {
            return true;
        }
    }

    return false;
}

// Computes ICH_EISR_EL2
uint64_t
Gicv3CPUInterface::eoiMaintenanceInterruptStatus() const
{
    // ICH_EISR_EL2
    // Bits [63:16] - RES0
    // Status<n>, bit [n], for n = 0 to 15
    //   EOI maintenance interrupt status bit for List register <n>:
    //     0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
    //     maintenance interrupt.
    //     1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
    //     interrupt that has not been handled.
    //
    // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
    // of the following are true:
    // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
    // - ICH_LR<n>_EL2.HW is 0.
    // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.

    uint64_t value = 0;

    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
        ICH_LR_EL2 ich_lr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

        if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
            !ich_lr_el2.HW && ich_lr_el2.EOI) {
            value |= (1 << lr_idx);
        }
    }

    return value;
}

Gicv3CPUInterface::ICH_MISR_EL2
Gicv3CPUInterface::maintenanceInterruptStatus() const
{
    // Comments are copied from SPEC section 9.4.7 (ID012119)
    ICH_MISR_EL2 ich_misr_el2 = 0;
    ICH_HCR_EL2 ich_hcr_el2 =
        isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
    ICH_VMCR_EL2 ich_vmcr_el2 =
        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

    // End Of Interrupt. [bit 0]
    // This maintenance interrupt is asserted when at least one bit in
    // ICH_EISR_EL2 is 1.

    if (eoiMaintenanceInterruptStatus()) {
        ich_misr_el2.EOI = 1;
    }

    // Underflow. [bit 1]
    // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
    // zero or one of the List register entries are marked as a valid
    // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
    // do not equal 0x0.
    uint32_t num_valid_interrupts = 0;
    uint32_t num_pending_interrupts = 0;

    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
        ICH_LR_EL2 ich_lr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

        if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
            num_valid_interrupts++;
        }

        if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
            num_pending_interrupts++;
        }
    }

    if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
        ich_misr_el2.U = 1;
    }

    // List Register Entry Not Present. [bit 2]
    // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
    // and ICH_HCR_EL2.EOIcount is non-zero.
    if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
        ich_misr_el2.LRENP = 1;
    }

    // No Pending. [bit 3]
    // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
    // no List register is in pending state.
    if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
        ich_misr_el2.NP = 1;
    }

    // vPE Group 0 Enabled. [bit 4]
    // This maintenance interrupt is asserted when
    // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
    if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
        ich_misr_el2.VGrp0E = 1;
    }

    // vPE Group 0 Disabled. [bit 5]
    // This maintenance interrupt is asserted when
    // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
    if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
        ich_misr_el2.VGrp0D = 1;
    }

    // vPE Group 1 Enabled. [bit 6]
    // This maintenance interrupt is asserted when
    // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
    if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
        ich_misr_el2.VGrp1E = 1;
    }

    // vPE Group 1 Disabled. [bit 7]
    // This maintenance interrupt is asserted when
    // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
    if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
        ich_misr_el2.VGrp1D = 1;
    }

    return ich_misr_el2;
}

RegVal
Gicv3CPUInterface::bpr1(Gicv3::GroupId group)
{
    bool hcr_imo = getHCREL2IMO();
    if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
        return readMiscReg(MISCREG_ICV_BPR1_EL1);
    }

    RegVal bpr = 0;

    if (group == Gicv3::G1S) {
        ICC_CTLR_EL1 icc_ctlr_el1_s =
            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);

        if (!isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
        } else {
            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S);
            bpr = bpr > GIC_MIN_BPR ? bpr : GIC_MIN_BPR;
        }
    } else if (group == Gicv3::G1NS) {
        ICC_CTLR_EL1 icc_ctlr_el1_ns =
            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);

        // Check if EL3 is implemented and this is a non secure accesses at
        // EL1 and EL2
        if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
            // Reads return BPR0 + 1 saturated to 7, WI
            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1) + 1;
            bpr = bpr < 7 ? bpr : 7;
        } else {
            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS);
            bpr = bpr > GIC_MIN_BPR_NS ? bpr : GIC_MIN_BPR_NS;
        }
    } else {
        panic("Should be used with G1S and G1NS only\n");
    }

    return bpr;
}

bool
Gicv3CPUInterface::havePendingInterrupts() const
{
    return gic->haveAsserted(cpuId) || hppi.prio != 0xff;
}

void
Gicv3CPUInterface::clearPendingInterrupts()
{
    gic->deassertAll(cpuId);
    resetHppi(hppi.intid);
}

void
Gicv3CPUInterface::assertWakeRequest()
{
    auto *tc = gic->getSystem()->threads[cpuId];
    if (ArmSystem::callSetWakeRequest(tc)) {
        Reset().invoke(tc);
        tc->activate();
    }
}

void
Gicv3CPUInterface::deassertWakeRequest()
{
    auto *tc = gic->getSystem()->threads[cpuId];
    ArmSystem::callClearWakeRequest(tc);
}

void
Gicv3CPUInterface::serialize(CheckpointOut & cp) const
{
    SERIALIZE_SCALAR(hppi.intid);
    SERIALIZE_SCALAR(hppi.prio);
    SERIALIZE_ENUM(hppi.group);
}

void
Gicv3CPUInterface::unserialize(CheckpointIn & cp)
{
    UNSERIALIZE_SCALAR(hppi.intid);
    UNSERIALIZE_SCALAR(hppi.prio);
    UNSERIALIZE_ENUM(hppi.group);
}
