/*
 * 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 readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
          }

          break;
      }

      case MISCREG_ICV_IGRPEN0_EL1: {
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          value = bits(ich_vmcr_el2, ICH_VMCR_EL2_VENG0_SHIFT);
          break;
      }

      case MISCREG_ICC_IGRPEN1:
      case MISCREG_ICC_IGRPEN1_EL1: {
          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
              return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
          }

          break;
      }

      case MISCREG_ICV_IGRPEN1_EL1: {
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          value = bits(ich_vmcr_el2, ICH_VMCR_EL2_VENG1_SHIFT);
          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 readMiscReg(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_ICV_PMR_EL1: { // Priority Mask Register
          RegVal ich_vmcr_el2 =
              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);

          value = ich_vmcr_el2 >> ICH_VMCR_EL2_VPMR_SHIFT;
          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 setMiscReg(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_ICV_PMR_EL1: { // Priority Mask Register
          RegVal ich_vmcr_el2 =
             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
          ich_vmcr_el2 = insertBits(
              ich_vmcr_el2,
              ICH_VMCR_EL2_VPMR_SHIFT + ICH_VMCR_EL2_VPMR_LENGTH - 1,
              ICH_VMCR_EL2_VPMR_SHIFT, val);

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

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