/*
 * 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.
 *
 * Authors: Jairo Balart
 */

#include "dev/arm/gic_v3_cpu_interface.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"

Gicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
    : BaseISADevice(),
      gic(gic),
      redistributor(nullptr),
      distributor(nullptr),
      cpuId(cpu_id)
{
}

Gicv3CPUInterface::~Gicv3CPUInterface()
{
}

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

void
Gicv3CPUInterface::initState()
{
    reset();
}

void
Gicv3CPUInterface::reset()
{
    hppi.prio = 0xff;
}

bool
Gicv3CPUInterface::getHCREL2FMO()
{
    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()
{
    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) {
      case MISCREG_ICC_AP1R0:
      case MISCREG_ICC_AP1R0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
          }

          break;
      }

      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;

      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;

      case MISCREG_ICC_IGRPEN0:
      case MISCREG_ICC_IGRPEN0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
              return isa->readMiscRegNoEffect(MISCREG_ICV_IGRPEN0_EL1);
          }

          break;
      }

      case MISCREG_ICC_IGRPEN1:
      case MISCREG_ICC_IGRPEN1_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return isa->readMiscRegNoEffect(MISCREG_ICV_IGRPEN1_EL1);
          }

          break;
      }

      case MISCREG_ICC_MGRPEN1:
      case MISCREG_ICC_IGRPEN1_EL3: {
          // EnableGrp1S and EnableGrp1NS are aliased with
          // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable
          bool enable_grp_1s =
              isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S) &
              ICC_IGRPEN1_EL1_ENABLE;
          bool enable_grp_1ns =
              isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
              ICC_IGRPEN1_EL1_ENABLE;
          value = 0;

          if (enable_grp_1s) {
              value |= ICC_IGRPEN1_EL3_ENABLEGRP1S;
          }

          if (enable_grp_1ns) {
              value |= ICC_IGRPEN1_EL3_ENABLEGRP1NS;
          }

          break;
      }

      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))) {
              /* NS GIC access and Group 0 is inaccessible to NS */
              if ((rprio & 0x80) == 0) {
                  /* NS should not see priorities in the Secure half of the
                   * range */
                  rprio = 0;
              } else if (rprio != 0xff) {
                  /* Non-idle priority: show the Non-secure view of it */
                  rprio = (rprio << 1) & 0xff;
              }
          }

          value = rprio;
          break;
      }

      case MISCREG_ICV_RPR_EL1: {
          value = virtualHighestActivePriority();
          break;
      }

      case MISCREG_ICC_HPPIR0:
      case MISCREG_ICC_HPPIR0_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
              return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
          }

          value = getHPPIR0();
          break;
      }

      case MISCREG_ICV_HPPIR0_EL1: {
          value = Gicv3::INTID_SPURIOUS;
          int lr_idx = getHPPVILR();

          if (lr_idx >= 0) {
              RegVal lr =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
              Gicv3::GroupId group =
                  lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;

              if (group == Gicv3::G0S) {
                  value = bits(lr, 31, 0);
              }
          }

          break;
      }

      case MISCREG_ICC_HPPIR1:
      case MISCREG_ICC_HPPIR1_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
          }

          value = getHPPIR1();
          break;
      }

      case MISCREG_ICV_HPPIR1_EL1: {
          value = Gicv3::INTID_SPURIOUS;
          int lr_idx = getHPPVILR();

          if (lr_idx >= 0) {
              RegVal lr =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
              Gicv3::GroupId group =
                  lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;

              if (group == Gicv3::G1NS) {
                  value = bits(lr, 31, 0);
              }
          }

          break;
      }

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

        M5_FALLTHROUGH;

      case MISCREG_ICC_BPR1:
      case MISCREG_ICC_BPR1_EL1:
        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
            return readMiscReg(MISCREG_ICV_BPR1_EL1);
        }

        {
            Gicv3::GroupId group =
                misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;

            if (group == Gicv3::G1S && !inSecureState()) {
                group = Gicv3::G1NS;
            }

            if ((group == Gicv3::G1S) &&
                    !isEL3OrMon() &&
                    (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S)
                     & ICC_CTLR_EL1_CBPR)) {
                group = Gicv3::G0S;
            }

            bool sat_inc = false;

            if ((group == Gicv3::G1NS) &&
                    (currEL() < EL3) &&
                    (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS)
                     & ICC_CTLR_EL1_CBPR)) {
                // Reads return BPR0 + 1 saturated to 7, WI
                group = Gicv3::G0S;
                sat_inc = true;
            }

            uint8_t bpr;

            if (group == Gicv3::G0S) {
                bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
            } else {
                bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1);
            }

            if (sat_inc) {
                bpr++;

                if (bpr > 7) {
                    bpr = 7;
                }
            }

            value = bpr;
            break;
        }

      case MISCREG_ICV_BPR0_EL1:
      case MISCREG_ICV_BPR1_EL1: {
          Gicv3::GroupId group =
              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          bool sat_inc = false;

          if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
              // reads return bpr0 + 1 saturated to 7, writes ignored
              group = Gicv3::G0S;
              sat_inc = true;
          }

          uint8_t vbpr;

          if (group == Gicv3::G0S) {
              vbpr = bits(ich_vmcr_el2, 23, 21);
          } else {
              vbpr = bits(ich_vmcr_el2, 20, 18);
          }

          if (sat_inc) {
              vbpr++;

              if (vbpr > 7) {
                  vbpr = 7;
              }
          }

          value = vbpr;
          break;
      }

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

        if (haveEL(EL3) && !inSecureState() &&
                (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
            /* NS GIC access and Group 0 is inaccessible to NS */
            if ((value & 0x80) == 0) {
                /* NS should not see priorities in the Secure half of the
                 * range */
                value = 0;
            } else if (value != 0xff) {
                /* Non-idle priority: show the Non-secure view of it */
                value = (value << 1) & 0xff;
            }
        }

        break;

      case MISCREG_ICC_IAR0:
      case MISCREG_ICC_IAR0_EL1: { // Interrupt Acknowledge Register 0
          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) {
                  activateIRQ(int_id, hppi.group);
              }
          } else {
              int_id = Gicv3::INTID_SPURIOUS;
          }

          value = int_id;
          break;
      }

      case MISCREG_ICV_IAR0_EL1: {
          int lr_idx = getHPPVILR();
          uint32_t int_id = Gicv3::INTID_SPURIOUS;

          if (lr_idx >= 0) {
              RegVal lr =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

              if (!(lr & ICH_LR_EL2_GROUP) && hppviCanPreempt(lr_idx)) {
                  int_id = value = bits(lr, 31, 0);

                  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...
                      lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
                              lr);
                  }
              }
          }

          value = int_id;
          virtualUpdate();
          break;
      }

      case MISCREG_ICC_IAR1:
      case MISCREG_ICC_IAR1_EL1: { // Interrupt Acknowledge Register 1
          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) {
                  activateIRQ(int_id, hppi.group);
              }

              // LPIs are not activated and when acked their pending
              // bit is cleared
              if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID)
              {
                  redistributor->setClrLPI(int_id, false);
              }

          } else {
              int_id = Gicv3::INTID_SPURIOUS;
          }

          value = int_id;
          break;
      }

      case MISCREG_ICV_IAR1_EL1: {
          int lr_idx = getHPPVILR();
          uint32_t int_id = Gicv3::INTID_SPURIOUS;

          if (lr_idx >= 0) {
              RegVal lr =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

              if (lr & ICH_LR_EL2_GROUP && hppviCanPreempt(lr_idx)) {
                  int_id = value = bits(lr, 31, 0);

                  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...
                      lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
                              lr);
                  }
              }
          }

          value = int_id;
          virtualUpdate();
          break;
      }

      case MISCREG_ICC_SRE:
      case MISCREG_ICC_SRE_EL1: { // System Register Enable Register
          bool dfb;
          bool dib;

          if (haveEL(EL3) && !distributor->DS) {
              // DIB is RO alias of ICC_SRE_EL3.DIB
              // DFB is RO alias of ICC_SRE_EL3.DFB
              RegVal icc_sre_el3 =
                  isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
              dfb = icc_sre_el3 & ICC_SRE_EL3_DFB;
              dib = icc_sre_el3 & ICC_SRE_EL3_DIB;
          } else if (haveEL(EL3) && distributor->DS) {
              // DIB is RW alias of ICC_SRE_EL3.DIB
              // DFB is RW alias of ICC_SRE_EL3.DFB
              RegVal icc_sre_el3 =
                  isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
              dfb = icc_sre_el3 & ICC_SRE_EL3_DFB;
              dib = icc_sre_el3 & ICC_SRE_EL3_DIB;
          } else if ((!haveEL(EL3) || distributor->DS) and haveEL(EL2)) {
              // DIB is RO alias of ICC_SRE_EL2.DIB
              // DFB is RO alias of ICC_SRE_EL2.DFB
              RegVal icc_sre_el2 =
                  isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL2);
              dfb = icc_sre_el2 & ICC_SRE_EL2_DFB;
              dib = icc_sre_el2 & ICC_SRE_EL2_DIB;
          } else {
              dfb = value & ICC_SRE_EL1_DFB;
              dib = value & ICC_SRE_EL1_DIB;
          }

          value = ICC_SRE_EL1_SRE;

          if (dfb) {
              value |= ICC_SRE_EL1_DFB;
          }

          if (dib) {
              value |= ICC_SRE_EL1_DIB;
          }

          break;
      }

      case MISCREG_ICC_HSRE:
      case MISCREG_ICC_SRE_EL2: // System Register Enable Register
        /*
         * Enable [3] == 1
         * (Secure EL1 accesses to Secure 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)
         */
        value = ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_DIB | ICC_SRE_EL2_DFB |
            ICC_SRE_EL2_SRE;
        break;

      case MISCREG_ICC_MSRE:
      case MISCREG_ICC_SRE_EL3: // System Register Enable Register
        /*
         * Enable [3] == 1
         * (Secure EL1 accesses to Secure ICC_SRE_EL1 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)
         */
        value = ICC_SRE_EL3_ENABLE | ICC_SRE_EL3_DIB | ICC_SRE_EL3_DFB |
            ICC_SRE_EL3_SRE;
        break;

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

          // Add value for RO bits
          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
          // PRIbits [10:8], number of priority bits implemented, minus one
          value |= ICC_CTLR_EL1_RSS | ICC_CTLR_EL1_A3V |
              (1 << 11) | ((PRIORITY_BITS - 1) << 8);
          break;
      }

      case MISCREG_ICV_CTLR_EL1: {
          value = ICC_CTLR_EL1_A3V | (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
              (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

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

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

          break;
      }

      case MISCREG_ICC_MCTLR:
      case MISCREG_ICC_CTLR_EL3: {
          // Add value for RO bits
          // RSS [18]
          // A3V [15]
          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
          // PRIbits [10:8], number of priority bits implemented, minus one
          value |= ICC_CTLR_EL3_RSS | ICC_CTLR_EL3_A3V | (0 << 11) |
              ((PRIORITY_BITS - 1) << 8);
          // Aliased bits...
          RegVal icc_ctlr_el1_ns =
              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
          RegVal icc_ctlr_el1_s =
              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);

          if (icc_ctlr_el1_ns & ICC_CTLR_EL1_EOIMODE) {
              value |= ICC_CTLR_EL3_EOIMODE_EL1NS;
          }

          if (icc_ctlr_el1_ns & ICC_CTLR_EL1_CBPR) {
              value |= ICC_CTLR_EL3_CBPR_EL1NS;
          }

          if (icc_ctlr_el1_s & ICC_CTLR_EL1_EOIMODE) {
              value |= ICC_CTLR_EL3_EOIMODE_EL1S;
          }

          if (icc_ctlr_el1_s & ICC_CTLR_EL1_CBPR) {
              value |= ICC_CTLR_EL3_CBPR_EL1S;
          }

          break;
      }

      case MISCREG_ICH_HCR:
      case MISCREG_ICH_HCR_EL2:
        break;

      case MISCREG_ICH_AP0R0:
      case MISCREG_ICH_AP0R0_EL2:
        break;

      case MISCREG_ICH_AP1R0:
      case MISCREG_ICH_AP1R0_EL2:
        break;

      case MISCREG_ICH_MISR:
      case MISCREG_ICH_MISR_EL2: {
          value = 0;
          // Scan list registers and fill in the U, NP and EOI bits
          eoiMaintenanceInterruptStatus((uint32_t *) &value);
          RegVal ich_hcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

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

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

          if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) &&
                  !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
              value |= ICH_MISR_EL2_VGRP0D;
          }

          if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) &&
                  (ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
              value |= ICH_MISR_EL2_VGRP1E;
          }

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

          break;
      }

      case MISCREG_ICH_VTR:
      case MISCREG_ICH_VTR_EL2:
        /*
         * PRIbits [31:29]
         * PREbits [28:26]
         * IDbits [25:23]
         * SEIS [22] == 0 (SEI Support)
         * A3V [21] == 1
         * (Non-zero values supported for Affinity 3 in SGI genearion)
         * nV4 [20] == 0
         * (Support for direct injection of virtual interrupts)
         * TDS [19] == 0 (Implementation supports ICH_HCR_EL2.TDIR)
         * ListRegs [4:0]
         */
        value = (16 - 1) << 0 |
            (5 - 1) << 26 |
            (5 - 1) << 29;
        value =
            ((VIRTUAL_NUM_LIST_REGS - 1) << ICH_VTR_EL2_LISTREGS_SHIFT) |
            // ICH_VTR_EL2_TDS |
            // ICH_VTR_EL2_NV4 |
            ICH_VTR_EL2_A3V |
            (1 << ICH_VTR_EL2_IDBITS_SHIFT) |
            ((VIRTUAL_PREEMPTION_BITS - 1) << ICH_VTR_EL2_PREBITS_SHIFT) |
            ((VIRTUAL_PRIORITY_BITS - 1) << ICH_VTR_EL2_PRIBITS_SHIFT);
        break;

      case MISCREG_ICH_EISR:
      case MISCREG_ICH_EISR_EL2:
        value = eoiMaintenanceInterruptStatus(nullptr);
        break;

      case MISCREG_ICH_ELRSR:
      case MISCREG_ICH_ELRSR_EL2:
        value = 0;

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

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

        break;

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

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

      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
        break;

      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) {
      case MISCREG_ICC_AP1R0:
      case MISCREG_ICC_AP1R0_EL1:
        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
            return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
        }

        break;

      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;

      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;

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

          Gicv3::GroupId group = Gicv3::G0S;

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

          dropPriority(group);

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

          break;
      }

      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 {
              RegVal lr =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
              Gicv3::GroupId lr_group =
                  lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
              uint8_t lr_group_prio = bits(lr, 55, 48) & 0xf8;

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

          virtualUpdate();
          break;
      }

      case MISCREG_ICC_EOIR1:
      case MISCREG_ICC_EOIR1_EL1: { // End Of Interrupt Register 1
          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) {
              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;
      }

      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 LR found matching
              virtualIncrementEOICount();
          } else {
              RegVal lr =
                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
              Gicv3::GroupId lr_group =
                  lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
              uint8_t lr_group_prio = bits(lr, 55, 48) & 0xf8;

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

          virtualUpdate();
          break;
      }

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

          int int_id = val & 0xffffff;

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

          if (!isEOISplitMode()) {
              return;
          }

          /*
           * Check whether we're allowed to deactivate.
           * These checks are correspond to the spec's pseudocode.
           */
          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;
      }

      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 LR found matching
              virtualIncrementEOICount();
          } else {
              virtualDeactivateIRQ(lr_idx);
          }

          virtualUpdate();
          break;
      }

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

          Gicv3::GroupId group =
              misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;

          if (group == Gicv3::G1S && !inSecureState()) {
              group = Gicv3::G1NS;
          }

          if ((group == Gicv3::G1S) &&
                  !isEL3OrMon() &&
                  (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S) &
                   ICC_CTLR_EL1_CBPR)) {
              group = Gicv3::G0S;
          }

          if ((group == Gicv3::G1NS) &&
                  (currEL() < EL3) &&
                  (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS) &
                   ICC_CTLR_EL1_CBPR)) {
              // Reads return BPR0 + 1 saturated to 7, WI
              return;
          }

          uint8_t min_val = (group == Gicv3::G1NS) ?
              GIC_MIN_BPR_NS : GIC_MIN_BPR;
          val &= 0x7;

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

          break;
      }

      case MISCREG_ICV_BPR0_EL1:
      case MISCREG_ICV_BPR1_EL1: {
          Gicv3::GroupId group =
              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

          if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
              // reads return bpr0 + 1 saturated to 7, writes ignored
              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 = insertBits(ich_vmcr_el2,
                      ICH_VMCR_EL2_VBPR0_SHIFT + 2, ICH_VMCR_EL2_VBPR0_SHIFT,
                      val);
          } else {
              ich_vmcr_el2 = insertBits(ich_vmcr_el2,
                      ICH_VMCR_EL2_VBPR1_SHIFT + 2, ICH_VMCR_EL2_VBPR1_SHIFT,
                      val);
          }

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

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

          /*
           * RSS is RO.
           * A3V is RO.
           * SEIS is RO.
           * IDbits is RO.
           * PRIbits is RO.
           * If EL3 is implemented and GICD_CTLR.DS == 0, then PMHE is RO.
           * So, only CBPR[0] and EOIMODE[1] are RW.
           * If EL3 is implemented and GICD_CTLR.DS == 0, then CBPR is RO.
           */
          uint64_t mask;

          if (haveEL(EL3) and distributor->DS == 0) {
              mask = ICC_CTLR_EL1_EOIMODE;
          } else if (haveEL(EL3) and distributor->DS == 1) {
              mask = ICC_CTLR_EL1_PMHE | ICC_CTLR_EL1_CBPR |
                  ICC_CTLR_EL1_EOIMODE;
          } else {
              mask = ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE;
          }

          RegVal old_val =
              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
          old_val &= ~mask;
          val = old_val | (val & mask);
          break;
      }

      case MISCREG_ICV_CTLR_EL1: {
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          ich_vmcr_el2 = insertBits(ich_vmcr_el2, ICH_VMCR_EL2_VCBPR_SHIFT,
                  val & ICC_CTLR_EL1_CBPR ? 1 : 0);
          ich_vmcr_el2 = insertBits(ich_vmcr_el2, ICH_VMCR_EL2_VEOIM_SHIFT,
                  val & ICC_CTLR_EL1_EOIMODE ? 1 : 0);
          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
          do_virtual_update = true;
          break;
      }

      case MISCREG_ICC_MCTLR:
      case MISCREG_ICC_CTLR_EL3: {
          RegVal icc_ctlr_el1_s =
              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
          RegVal 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
          if (val & ICC_CTLR_EL3_EOIMODE_EL1NS) {
              icc_ctlr_el1_ns |= ICC_CTLR_EL1_EOIMODE;
          } else {
              icc_ctlr_el1_ns &= ~ICC_CTLR_EL1_EOIMODE;
          }

          // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
          if (val & ICC_CTLR_EL3_CBPR_EL1NS) {
              icc_ctlr_el1_ns |= ICC_CTLR_EL1_CBPR;
          } else {
              icc_ctlr_el1_ns &= ~ICC_CTLR_EL1_CBPR;
          }

          // ICC_CTLR_EL1(S).EOImode is an alias of ICC_CTLR_EL3.EOImode_EL1S
          if (val & ICC_CTLR_EL3_EOIMODE_EL1S) {
              icc_ctlr_el1_s |= ICC_CTLR_EL1_EOIMODE;
          } else {
              icc_ctlr_el1_s &= ~ICC_CTLR_EL1_EOIMODE;
          }

          // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
          if (val & ICC_CTLR_EL3_CBPR_EL1S) {
              icc_ctlr_el1_s |= ICC_CTLR_EL1_CBPR;
          } else {
              icc_ctlr_el1_s &= ~ICC_CTLR_EL1_CBPR;
          }

          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS, icc_ctlr_el1_ns);
          // Only ICC_CTLR_EL3_EOIMODE_EL3 is writable
          RegVal old_icc_ctlr_el3 =
              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
          old_icc_ctlr_el3 &= ~(ICC_CTLR_EL3_EOIMODE_EL3 | ICC_CTLR_EL3_RM);
          val = old_icc_ctlr_el3 |
              (val & (ICC_CTLR_EL3_EOIMODE_EL3 | ICC_CTLR_EL3_RM));
          break;
      }

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

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

          if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
              /*
               * NS access and Group 0 is inaccessible to NS: return the
               * NS view of the current priority
               */
              RegVal old_icc_pmr_el1 =
                  isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);

              if (!(old_icc_pmr_el1 & 0x80)) {
                  /* Current PMR in the secure range, don't allow NS to
                   * change it */
                  return;
              }

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

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

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

          break;
      }

      case MISCREG_ICV_IGRPEN0_EL1: {
          bool enable = val & 0x1;
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          ich_vmcr_el2 = insertBits(ich_vmcr_el2,
                  ICH_VMCR_EL2_VENG0_SHIFT, enable);
          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
          virtualUpdate();
          return;
      }

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

          break;
      }

      case MISCREG_ICV_IGRPEN1_EL1: {
          bool enable = val & 0x1;
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          ich_vmcr_el2 = insertBits(ich_vmcr_el2,
                  ICH_VMCR_EL2_VENG1_SHIFT, enable);
          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
          virtualUpdate();
          return;
      }

      case MISCREG_ICC_MGRPEN1:
      case MISCREG_ICC_IGRPEN1_EL3: {
          // EnableGrp1S and EnableGrp1NS are aliased with
          // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable
          bool enable_grp_1s = val & ICC_IGRPEN1_EL3_ENABLEGRP1S;
          bool enable_grp_1ns = val & ICC_IGRPEN1_EL3_ENABLEGRP1NS;
          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S, enable_grp_1s);
          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS, enable_grp_1ns);
          return;
      }

        // Software Generated Interrupt Group 0 Register
      case MISCREG_ICC_SGI0R:
      case MISCREG_ICC_SGI0R_EL1:

        // Software Generated Interrupt Group 1 Register
      case MISCREG_ICC_SGI1R:
      case MISCREG_ICC_SGI1R_EL1:

        // Alias Software Generated Interrupt Group 1 Register
      case MISCREG_ICC_ASGI1R:
      case MISCREG_ICC_ASGI1R_EL1: {
          bool ns = !inSecureState();
          Gicv3::GroupId group;

          if (misc_reg == MISCREG_ICC_SGI1R_EL1) {
              group = ns ? Gicv3::G1NS : Gicv3::G1S;
          } else if (misc_reg == MISCREG_ICC_ASGI1R_EL1) {
              group = ns ? Gicv3::G1S : Gicv3::G1NS;
          } else {
              group = Gicv3::G0S;
          }

          if (distributor->DS && group == Gicv3::G1S) {
              group = Gicv3::G0S;
          }

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

          for (int i = 0; i < gic->getSystem()->numContexts(); 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);
          }

          break;
      }

      case MISCREG_ICC_SRE:
      case MISCREG_ICC_SRE_EL1: { // System Register Enable Register EL1
          if (!(val & ICC_SRE_EL1_SRE)) {
              warn("Gicv3CPUInterface::setMiscReg(): "
                      "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n");
          }

          bool dfb = val & ICC_SRE_EL1_DFB;
          bool dib = val & ICC_SRE_EL1_DIB;

          if (haveEL(EL3) && !distributor->DS) {
              // DIB is RO alias of ICC_SRE_EL3.DIB
              // DFB is RO alias of ICC_SRE_EL3.DFB
          } else if (haveEL(EL3) && distributor->DS) {
              // DIB is RW alias of ICC_SRE_EL3.DIB
              // DFB is RW alias of ICC_SRE_EL3.DFB
              RegVal icc_sre_el3 =
                  isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
              icc_sre_el3 = insertBits(icc_sre_el3, ICC_SRE_EL3_DFB, dfb);
              icc_sre_el3 = insertBits(icc_sre_el3, ICC_SRE_EL3_DIB, dib);
              isa->setMiscRegNoEffect(MISCREG_ICC_SRE_EL3, icc_sre_el3);
          } else if ((!haveEL(EL3) || distributor->DS) and haveEL(EL2)) {
              // DIB is RO alias of ICC_SRE_EL2.DIB
              // DFB is RO alias of ICC_SRE_EL2.DFB
          } else {
              isa->setMiscRegNoEffect(misc_reg, val);
          }

          return;
      }

      case MISCREG_ICC_HSRE:
      case MISCREG_ICC_SRE_EL2: // System Register Enable Register EL2
      case MISCREG_ICC_MSRE:
      case MISCREG_ICC_SRE_EL3: // System Register Enable Register EL3
        if (!(val & (1 << 0))) {
            warn("Gicv3CPUInterface::setMiscReg(): "
                    "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n");
        }

        // All bits are RAO/WI
        break;

      case MISCREG_ICH_HCR:
      case MISCREG_ICH_HCR_EL2:
        val &= ICH_HCR_EL2_EN | ICH_HCR_EL2_UIE | ICH_HCR_EL2_LRENPIE |
            ICH_HCR_EL2_NPIE | ICH_HCR_EL2_VGRP0EIE |
            ICH_HCR_EL2_VGRP0DIE | ICH_HCR_EL2_VGRP1EIE |
            ICH_HCR_EL2_VGRP1DIE | ICH_HCR_EL2_TC | ICH_HCR_EL2_TALL0 |
            ICH_HCR_EL2_TALL1 | ICH_HCR_EL2_TDIR |
            ICH_HCR_EL2_EOICOUNT_MASK;
        do_virtual_update = true;
        break;

      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
        {
            // Enforce RES0 bits in priority field, 5 of 8 bits used
            val = insertBits(val, ICH_LRC_PRIORITY_SHIFT + 2,
                    ICH_LRC_PRIORITY_SHIFT, 0);
            RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
            val = (old_val & 0xffffffff) | (val << 32);
            do_virtual_update = true;
            break;
        }

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

      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
          // Enforce RES0 bits in priority field, 5 of 8 bits used
          val = insertBits(val, ICH_LR_EL2_PRIORITY_SHIFT + 2,
                  ICH_LR_EL2_PRIORITY_SHIFT, 0);
          do_virtual_update = true;
          break;
      }

      case MISCREG_ICH_VMCR:
      case MISCREG_ICH_VMCR_EL2: {
          val &= ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1 |
              ICH_VMCR_EL2_VCBPR | ICH_VMCR_EL2_VEOIM |
              ICH_VMCR_EL2_VBPR1_MASK | ICH_VMCR_EL2_VBPR0_MASK |
              ICH_VMCR_EL2_VPMR_MASK;
          val |= ICH_VMCR_EL2_VFIQEN; // RES1
          // Check VBPRs against minimun allowed value
          uint8_t vbpr0 = bits(val, 23, 21);
          uint8_t vbpr1 = bits(val, 20, 18);
          uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
          uint8_t min_vpr1 = min_vpr0 + 1;
          vbpr0 = vbpr0 < min_vpr0 ? min_vpr0 : vbpr0;
          vbpr1 = vbpr1 < min_vpr1 ? min_vpr1 : vbpr1;
          val = insertBits(val, ICH_VMCR_EL2_VBPR0_SHIFT + 2,
                  ICH_VMCR_EL2_VBPR0_SHIFT, vbpr0);
          val = insertBits(val, ICH_VMCR_EL2_VBPR1_SHIFT + 2,
                  ICH_VMCR_EL2_VBPR1_SHIFT, vbpr1);
          break;
      }

      case MISCREG_ICH_AP0R0 ... MISCREG_ICH_AP0R3:
      case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_AP0R3_EL2:
      case MISCREG_ICH_AP1R0 ... MISCREG_ICH_AP1R3:
      case MISCREG_ICH_AP1R0_EL2 ... MISCREG_ICH_AP1R3_EL2:
        break;

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

    isa->setMiscRegNoEffect(misc_reg, val);

    if (do_virtual_update) {
        virtualUpdate();
    }
}

int
Gicv3CPUInterface::virtualFindActive(uint32_t int_id)
{
    for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
        RegVal lr =
            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
        uint32_t lr_intid = bits(lr, 31, 0);

        if ((lr & ICH_LR_EL2_STATE_ACTIVE_BIT) && lr_intid == int_id) {
            return lr_idx;
        }
    }

    return -1;
}

uint32_t
Gicv3CPUInterface::getHPPIR0()
{
    if (hppi.prio == 0xff) {
        return Gicv3::INTID_SPURIOUS;
    }

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

    if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
        /* Indicate to EL3 that there's a Group 1 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()
{
    if (hppi.prio == 0xff) {
        return Gicv3::INTID_SPURIOUS;
    }

    //if ((currEL() == EL3) && ICC_CTLR_EL3_RM)
    if ((currEL() == EL3) &&
            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_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;
    RegVal apr;
    apr_misc_reg = group == Gicv3::G0S ?
                   MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
    apr = isa->readMiscRegNoEffect(apr_misc_reg);

    if (apr) {
        /* Clear the lowest set bit */
        apr &= apr - 1;
        isa->setMiscRegNoEffect(apr_misc_reg, apr);
    }

    update();
}

uint8_t
Gicv3CPUInterface::virtualDropPriority()
{
    /* Drop the priority of the currently active virtual interrupt
     * (favouring group 0 if there is a set active bit at
     * the same priority for both group 0 and group 1).
     * Return the priority value for the bit we just cleared,
     * or 0xff if no bits were set in the AP registers at all.
     * Note that though the ich_apr[] are uint64_t only the low
     * 32 bits are actually relevant.
     */
    int 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) {
            /* Clear the lowest set bit */
            vapr0 &= vapr0 - 1;
            isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
            return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
        } else {
            /* Clear the lowest set bit */
            vapr1 &= vapr1 - 1;
            isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
            return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
        }
    }

    return 0xff;
}

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 = group == Gicv3::G0S ?
                 MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
    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);
        redistributor->updateAndInformCPUInterface();
    } else if (int_id < Gicv3::INTID_SECURE) {
        // SPI, distributor
        distributor->activateIRQ(int_id);
        distributor->updateAndInformCPUInterfaces();
    }
}

void
Gicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
{
    // Update active priority registers.
    RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
            lr_idx);
    Gicv3::GroupId group = lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
    uint8_t prio = bits(lr, 55, 48) & 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.
    lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
    lr |= ICH_LR_EL2_STATE_ACTIVE_BIT;
    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, lr);
}

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);
        redistributor->updateAndInformCPUInterface();
    } else if (int_id < Gicv3::INTID_SECURE) {
        // SPI, distributor
        distributor->deactivateIRQ(int_id);
        distributor->updateAndInformCPUInterfaces();
    } else {
        return;
    }
}

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

    if (lr & ICH_LR_EL2_HW) {
        // Deactivate the associated physical interrupt
        int pintid = bits(lr, 41, 32);

        if (pintid < Gicv3::INTID_SECURE) {
            Gicv3::GroupId group =
                pintid >= 32 ? distributor->getIntGroup(pintid) :
                redistributor->getIntGroup(pintid);
            deactivateIRQ(pintid, group);
        }
    }

    //  Remove the active bit
    lr &= ~ICH_LR_EL2_STATE_ACTIVE_BIT;
    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, lr);
}

/*
 * Return a mask word which clears the subpriority bits from
 * a priority value for an interrupt in the specified group.
 * This depends on the BPR value. For CBPR0 (S or NS):
 *  a BPR of 0 means the group priority bits are [7:1];
 *  a BPR of 1 means they are [7:2], and so on down to
 *  ...
 *  a BPR of 7 meaning no group priority bits at all.
 * For CBPR1 NS:
 *  a BPR of 0 is impossible (the minimum value is 1)
 *  a BPR of 1 means the group priority bits are [7:1];
 *  a BPR of 2 means they are [7:2], and so on down to
 *  ...
 *  a BPR of 7 meaning the group priority is [7].
 *
 * Which BPR to use depends on the group of the interrupt and
 * the current ICC_CTLR.CBPR settings.
 *
 * This corresponds to the GroupBits() pseudocode from 4.8.2.
 */
uint32_t
Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
{
    if ((group == Gicv3::G1S &&
            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S)
            & ICC_CTLR_EL1_CBPR) ||
            (group == Gicv3::G1NS &&
             isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS)
             & ICC_CTLR_EL1_CBPR)) {
        group = Gicv3::G0S;
    }

    int bpr;

    if (group == Gicv3::G0S) {
        bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1) & 0x7;
    } else {
        bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1) & 0x7;
    }

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

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

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

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

    int bpr;

    if (group == Gicv3::G0S) {
        bpr = bits(ich_vmcr_el2, 23, 21);
    } else {
        bpr = bits(ich_vmcr_el2, 20, 18);
    }

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

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

bool
Gicv3CPUInterface::isEOISplitMode()
{
    if (isEL3OrMon()) {
        return isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3) &
               ICC_CTLR_EL3_EOIMODE_EL3;
    } else {
        return isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1) &
               ICC_CTLR_EL1_EOIMODE;
    }
}

bool
Gicv3CPUInterface::virtualIsEOISplitMode()
{
    RegVal ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
    return ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM;
}

int
Gicv3CPUInterface::highestActiveGroup()
{
    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::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()) {
        ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
        DPRINTF(GIC, "Gicv3CPUInterface::update(): "
                "posting int as %d!\n", int_type);
        int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
    }

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

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

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

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

        if (hppviCanPreempt(lr_idx)) {
            if (ich_lr_el2 & ICH_LR_EL2_GROUP) {
                signal_IRQ = true;
            } else {
                signal_FIQ = true;
            }
        }
    }

    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);

    if (ich_hcr_el2 & ICH_HCR_EL2_EN) {
        if (maintenanceInterruptStatus()) {
            redistributor->sendPPInt(25);
        }
    }

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

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

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

    if (!(ich_vmcr_el2 & (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++) {
        RegVal ich_lri_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
        uint8_t state = bits(ich_lri_el2, 63, 62);

        if (state != Gicv3::INT_PENDING) {
            continue;
        }

        if (ich_lri_el2 & ICH_LR_EL2_GROUP) {
            // VG1
            if (!(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
                continue;
            }
        } else {
            // VG0
            if (!(ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
                continue;
            }
        }

        uint8_t prio = bits(ich_lri_el2, 55, 48);

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

    return idx;
}

bool
Gicv3CPUInterface::hppviCanPreempt(int lr_idx)
{
    RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);

    if (!(isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2) & ICH_HCR_EL2_EN)) {
        // virtual interface is disabled
        return false;
    }

    uint8_t prio = bits(lr, 55, 48);
    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 = lr & 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()
{
    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);
}

/*
 * Should we signal the interrupt as IRQ or FIQ?
 * see spec section 4.6.2
 */
ArmISA::InterruptTypes
Gicv3CPUInterface::intSignalType(Gicv3::GroupId group)
{
    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 ArmISA::INT_FIQ;
    } else {
        return ArmISA::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()
{
    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)
{
    switch (group) {
      case Gicv3::G0S:
        return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1) &
            ICC_IGRPEN0_EL1_ENABLE;

      case Gicv3::G1S:
        //if (distributor->DS)
        //{
        //    return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
        //           ICC_IGRPEN1_EL1_ENABLE;
        //}
        //else
        //{
        return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S) &
            ICC_IGRPEN1_EL1_ENABLE;

        //}

      case Gicv3::G1NS:
        return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
            ICC_IGRPEN1_EL1_ENABLE;

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

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

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

int
Gicv3CPUInterface::currEL()
{
    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)
{
    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()
{
    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
    return haveEL(EL3) && scr.ns == 0;
}

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

bool
Gicv3CPUInterface::isEL3OrMon()
{
    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;
}

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

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

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

        if ((lr & ICH_LR_EL2_STATE_MASK)) {
            valid_count++;
        }

        if (bits(lr, ICH_LR_EL2_STATE_SHIFT + ICH_LR_EL2_STATE_LENGTH,
                 ICH_LR_EL2_STATE_SHIFT) == ICH_LR_EL2_STATE_PENDING) {
            seen_pending = true;
        }
    }

    if (misr) {
        RegVal ich_hcr_el2 =
            isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);

        if (valid_count < 2 && (ich_hcr_el2 & ICH_HCR_EL2_UIE)) {
            *misr |= ICH_MISR_EL2_U;
        }

        if (!seen_pending && (ich_hcr_el2 & ICH_HCR_EL2_NPIE)) {
            *misr |= ICH_MISR_EL2_NP;
        }

        if (value) {
            *misr |= ICH_MISR_EL2_EOI;
        }
    }

    return value;
}

uint32_t
Gicv3CPUInterface::maintenanceInterruptStatus()
{
    /* Return a set of bits indicating the maintenance interrupt status
     * (as seen in the ICH_MISR_EL2 register).
     */
    uint32_t value = 0;
    /* Scan list registers and fill in the U, NP and EOI bits */
    eoiMaintenanceInterruptStatus(&value);
    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
    RegVal ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

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

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

    if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) &&
            !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
        value |= ICH_MISR_EL2_VGRP0D;
    }

    if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) &&
            (ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
        value |= ICH_MISR_EL2_VGRP1E;
    }

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

    return value;
}

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