/*
 * Copyright (c) 2019, 2021-2022 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"

namespace gem5
{

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)
{
    tc = _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 = tc->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 = tc->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() &&
              (tc->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() &&
            (tc->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 = tc->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 = tc->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()
{
    if (gic->blockIntUpdate())
        return;

    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()
{
    if (gic->blockIntUpdate())
        return;

    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
{
    return ArmISA::isSecure(tc);
}

ExceptionLevel
Gicv3CPUInterface::currEL() const
{
    return ArmISA::currEL(tc);
}

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

      case EL2:
        return gic->getSystem()->has(ArmExtension::VIRTUALIZATION);

      case EL3:
        return gic->getSystem()->has(ArmExtension::SECURITY);

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

bool
Gicv3CPUInterface::isSecureBelowEL3() const
{
    return ArmISA::isSecureBelowEL3(tc);
}

bool
Gicv3CPUInterface::isAA64() const
{
    return ArmISA::inAArch64(tc);
}

bool
Gicv3CPUInterface::isEL3OrMon() const
{
    return currEL() == EL3;
}

// 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::copy(Gicv3Registers *from, Gicv3Registers *to)
{
    const auto affinity = redistributor->getAffinity();
    gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_PMR_EL1);

    gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_AP1R0_EL1);
    if (PRIORITY_BITS >= 6) {
        gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_AP1R1_EL1);
    }

    if (PRIORITY_BITS >= 7) {
        gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_AP1R2_EL1);
        gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_AP1R3_EL1);
    }

    gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_BPR1_EL1);
    gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_CTLR_EL1);
    gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_SRE_EL1);
    gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_IGRPEN0_EL1);
    gic->copyCpuRegister(from, to, affinity, MISCREG_ICC_IGRPEN1_EL1);
}

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

} // namespace gem5
