gic_v3_cpu_interface.cc revision 14057
113531Sjairo.balart@metempsy.com/*
213531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
313531Sjairo.balart@metempsy.com * All rights reserved.
413531Sjairo.balart@metempsy.com *
513531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
613531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
713531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
813531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
913531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
1013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
1113531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
1213531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
1313531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
1413531Sjairo.balart@metempsy.com * this software without specific prior written permission.
1513531Sjairo.balart@metempsy.com *
1613531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713531Sjairo.balart@metempsy.com *
2813531Sjairo.balart@metempsy.com * Authors: Jairo Balart
2913531Sjairo.balart@metempsy.com */
3013531Sjairo.balart@metempsy.com
3113531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh"
3213531Sjairo.balart@metempsy.com
3313531Sjairo.balart@metempsy.com#include "arch/arm/isa.hh"
3413531Sjairo.balart@metempsy.com#include "debug/GIC.hh"
3513531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh"
3613531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh"
3713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_redistributor.hh"
3813531Sjairo.balart@metempsy.com
3913926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
4013926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;
4113926Sgiacomo.travaglini@arm.com
4213531Sjairo.balart@metempsy.comGicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
4313531Sjairo.balart@metempsy.com    : BaseISADevice(),
4413531Sjairo.balart@metempsy.com      gic(gic),
4513531Sjairo.balart@metempsy.com      redistributor(nullptr),
4613531Sjairo.balart@metempsy.com      distributor(nullptr),
4713531Sjairo.balart@metempsy.com      cpuId(cpu_id)
4813531Sjairo.balart@metempsy.com{
4913531Sjairo.balart@metempsy.com}
5013531Sjairo.balart@metempsy.com
5113531Sjairo.balart@metempsy.comvoid
5213531Sjairo.balart@metempsy.comGicv3CPUInterface::init()
5313531Sjairo.balart@metempsy.com{
5413531Sjairo.balart@metempsy.com    redistributor = gic->getRedistributor(cpuId);
5513531Sjairo.balart@metempsy.com    distributor = gic->getDistributor();
5613531Sjairo.balart@metempsy.com}
5713531Sjairo.balart@metempsy.com
5813531Sjairo.balart@metempsy.comvoid
5913531Sjairo.balart@metempsy.comGicv3CPUInterface::initState()
6013531Sjairo.balart@metempsy.com{
6113531Sjairo.balart@metempsy.com    reset();
6213531Sjairo.balart@metempsy.com}
6313531Sjairo.balart@metempsy.com
6413531Sjairo.balart@metempsy.comvoid
6513531Sjairo.balart@metempsy.comGicv3CPUInterface::reset()
6613531Sjairo.balart@metempsy.com{
6713531Sjairo.balart@metempsy.com    hppi.prio = 0xff;
6813531Sjairo.balart@metempsy.com}
6913531Sjairo.balart@metempsy.com
7013826Sgiacomo.travaglini@arm.comvoid
7113826Sgiacomo.travaglini@arm.comGicv3CPUInterface::setThreadContext(ThreadContext *tc)
7213826Sgiacomo.travaglini@arm.com{
7313826Sgiacomo.travaglini@arm.com    maintenanceInterrupt = gic->params()->maint_int->get(tc);
7413826Sgiacomo.travaglini@arm.com}
7513826Sgiacomo.travaglini@arm.com
7613531Sjairo.balart@metempsy.combool
7713760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2FMO() const
7813531Sjairo.balart@metempsy.com{
7913531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
8013531Sjairo.balart@metempsy.com
8113531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
8213531Sjairo.balart@metempsy.com        return false;
8313531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
8413531Sjairo.balart@metempsy.com        return true;
8513531Sjairo.balart@metempsy.com    } else {
8613531Sjairo.balart@metempsy.com        return hcr.fmo;
8713531Sjairo.balart@metempsy.com    }
8813531Sjairo.balart@metempsy.com}
8913531Sjairo.balart@metempsy.com
9013531Sjairo.balart@metempsy.combool
9113760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2IMO() const
9213531Sjairo.balart@metempsy.com{
9313531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
9413531Sjairo.balart@metempsy.com
9513531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
9613531Sjairo.balart@metempsy.com        return false;
9713531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
9813531Sjairo.balart@metempsy.com        return true;
9913531Sjairo.balart@metempsy.com    } else {
10013531Sjairo.balart@metempsy.com        return hcr.imo;
10113531Sjairo.balart@metempsy.com    }
10213531Sjairo.balart@metempsy.com}
10313531Sjairo.balart@metempsy.com
10413580Sgabeblack@google.comRegVal
10513531Sjairo.balart@metempsy.comGicv3CPUInterface::readMiscReg(int misc_reg)
10613531Sjairo.balart@metempsy.com{
10713580Sgabeblack@google.com    RegVal value = isa->readMiscRegNoEffect(misc_reg);
10813531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
10913531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
11013531Sjairo.balart@metempsy.com
11113531Sjairo.balart@metempsy.com    switch (misc_reg) {
11213760Sjairo.balart@metempsy.com      // Active Priorities Group 1 Registers
11313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
11413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1: {
11513531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
11613531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
11713531Sjairo.balart@metempsy.com          }
11813531Sjairo.balart@metempsy.com
11913531Sjairo.balart@metempsy.com          break;
12013531Sjairo.balart@metempsy.com      }
12113531Sjairo.balart@metempsy.com
12213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
12313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
12413531Sjairo.balart@metempsy.com
12513531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
12613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
12713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
12813531Sjairo.balart@metempsy.com
12913531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
13013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
13113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
13213531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
13313531Sjairo.balart@metempsy.com        return 0;
13413531Sjairo.balart@metempsy.com
13513760Sjairo.balart@metempsy.com      // Active Priorities Group 0 Registers
13613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
13713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1: {
13813531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
13913531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
14013531Sjairo.balart@metempsy.com          }
14113531Sjairo.balart@metempsy.com
14213531Sjairo.balart@metempsy.com          break;
14313531Sjairo.balart@metempsy.com      }
14413531Sjairo.balart@metempsy.com
14513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
14613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
14713531Sjairo.balart@metempsy.com
14813531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
14913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
15013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
15113531Sjairo.balart@metempsy.com
15213531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
15313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
15413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
15513531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
15613531Sjairo.balart@metempsy.com        return 0;
15713531Sjairo.balart@metempsy.com
15813760Sjairo.balart@metempsy.com      // Interrupt Group 0 Enable register EL1
15913531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
16013531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
16113531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
16214057Sgiacomo.travaglini@arm.com              return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
16313531Sjairo.balart@metempsy.com          }
16413531Sjairo.balart@metempsy.com
16513531Sjairo.balart@metempsy.com          break;
16613531Sjairo.balart@metempsy.com      }
16713531Sjairo.balart@metempsy.com
16814057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_IGRPEN0_EL1: {
16914057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
17014057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
17114057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VENG0;
17214057Sgiacomo.travaglini@arm.com          break;
17314057Sgiacomo.travaglini@arm.com      }
17414057Sgiacomo.travaglini@arm.com
17513760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL1
17613531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
17713531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
17813531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
17914057Sgiacomo.travaglini@arm.com              return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
18013531Sjairo.balart@metempsy.com          }
18113531Sjairo.balart@metempsy.com
18213531Sjairo.balart@metempsy.com          break;
18313531Sjairo.balart@metempsy.com      }
18413531Sjairo.balart@metempsy.com
18514057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_IGRPEN1_EL1: {
18614057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
18714057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
18814057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VENG1;
18914057Sgiacomo.travaglini@arm.com          break;
19014057Sgiacomo.travaglini@arm.com      }
19114057Sgiacomo.travaglini@arm.com
19213760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL3
19313760Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
19413760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL3:
19513739Sgiacomo.travaglini@arm.com          break;
19613760Sjairo.balart@metempsy.com
19713760Sjairo.balart@metempsy.com      // Running Priority Register
19813531Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR:
19913531Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR_EL1: {
20013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
20113760Sjairo.balart@metempsy.com              (hcr_imo || hcr_fmo)) {
20213531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_RPR_EL1);
20313531Sjairo.balart@metempsy.com          }
20413531Sjairo.balart@metempsy.com
20513531Sjairo.balart@metempsy.com          uint8_t rprio = highestActivePriority();
20613531Sjairo.balart@metempsy.com
20713531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() &&
20813760Sjairo.balart@metempsy.com              (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
20913760Sjairo.balart@metempsy.com              // Spec section 4.8.1
21013760Sjairo.balart@metempsy.com              // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
21113531Sjairo.balart@metempsy.com              if ((rprio & 0x80) == 0) {
21213760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
21313760Sjairo.balart@metempsy.com                  // 0x00-0x7F a read access returns the value 0x0
21413531Sjairo.balart@metempsy.com                  rprio = 0;
21513531Sjairo.balart@metempsy.com              } else if (rprio != 0xff) {
21613760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
21713760Sjairo.balart@metempsy.com                  // 0x80-0xFF a read access returns the Non-secure read of
21813760Sjairo.balart@metempsy.com                  // the current value
21913531Sjairo.balart@metempsy.com                  rprio = (rprio << 1) & 0xff;
22013531Sjairo.balart@metempsy.com              }
22113531Sjairo.balart@metempsy.com          }
22213531Sjairo.balart@metempsy.com
22313531Sjairo.balart@metempsy.com          value = rprio;
22413531Sjairo.balart@metempsy.com          break;
22513531Sjairo.balart@metempsy.com      }
22613531Sjairo.balart@metempsy.com
22713760Sjairo.balart@metempsy.com      // Virtual Running Priority Register
22813531Sjairo.balart@metempsy.com      case MISCREG_ICV_RPR_EL1: {
22913531Sjairo.balart@metempsy.com          value = virtualHighestActivePriority();
23013531Sjairo.balart@metempsy.com          break;
23113531Sjairo.balart@metempsy.com      }
23213531Sjairo.balart@metempsy.com
23313760Sjairo.balart@metempsy.com      // Highest Priority Pending Interrupt Register 0
23413531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0:
23513531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0_EL1: {
23613531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
23713531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
23813531Sjairo.balart@metempsy.com          }
23913531Sjairo.balart@metempsy.com
24013531Sjairo.balart@metempsy.com          value = getHPPIR0();
24113531Sjairo.balart@metempsy.com          break;
24213531Sjairo.balart@metempsy.com      }
24313531Sjairo.balart@metempsy.com
24413760Sjairo.balart@metempsy.com      // Virtual Highest Priority Pending Interrupt Register 0
24513531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR0_EL1: {
24613531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
24713531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
24813531Sjairo.balart@metempsy.com
24913531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
25013760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
25113531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
25213531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
25313760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
25413531Sjairo.balart@metempsy.com
25513531Sjairo.balart@metempsy.com              if (group == Gicv3::G0S) {
25613760Sjairo.balart@metempsy.com                  value = ich_lr_el2.vINTID;
25713531Sjairo.balart@metempsy.com              }
25813531Sjairo.balart@metempsy.com          }
25913531Sjairo.balart@metempsy.com
26013531Sjairo.balart@metempsy.com          break;
26113531Sjairo.balart@metempsy.com      }
26213531Sjairo.balart@metempsy.com
26313760Sjairo.balart@metempsy.com      // Highest Priority Pending Interrupt Register 1
26413531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1:
26513531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1_EL1: {
26613531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
26713531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
26813531Sjairo.balart@metempsy.com          }
26913531Sjairo.balart@metempsy.com
27013531Sjairo.balart@metempsy.com          value = getHPPIR1();
27113531Sjairo.balart@metempsy.com          break;
27213531Sjairo.balart@metempsy.com      }
27313531Sjairo.balart@metempsy.com
27413760Sjairo.balart@metempsy.com      // Virtual Highest Priority Pending Interrupt Register 1
27513531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR1_EL1: {
27613531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
27713531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
27813531Sjairo.balart@metempsy.com
27913531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
28013760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
28113531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
28213531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
28313760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
28413531Sjairo.balart@metempsy.com
28513531Sjairo.balart@metempsy.com              if (group == Gicv3::G1NS) {
28613760Sjairo.balart@metempsy.com                  value = ich_lr_el2.vINTID;
28713531Sjairo.balart@metempsy.com              }
28813531Sjairo.balart@metempsy.com          }
28913531Sjairo.balart@metempsy.com
29013531Sjairo.balart@metempsy.com          break;
29113531Sjairo.balart@metempsy.com      }
29213531Sjairo.balart@metempsy.com
29313760Sjairo.balart@metempsy.com      // Binary Point Register 0
29413531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
29513531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0_EL1:
29613531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
29713531Sjairo.balart@metempsy.com            return readMiscReg(MISCREG_ICV_BPR0_EL1);
29813531Sjairo.balart@metempsy.com        }
29913531Sjairo.balart@metempsy.com
30013531Sjairo.balart@metempsy.com        M5_FALLTHROUGH;
30113531Sjairo.balart@metempsy.com
30213760Sjairo.balart@metempsy.com      // Binary Point Register 1
30313531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
30413760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: {
30513760Sjairo.balart@metempsy.com            if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
30613760Sjairo.balart@metempsy.com                return readMiscReg(MISCREG_ICV_BPR1_EL1);
30713760Sjairo.balart@metempsy.com            }
30813760Sjairo.balart@metempsy.com
30913531Sjairo.balart@metempsy.com            Gicv3::GroupId group =
31013531Sjairo.balart@metempsy.com                misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;
31113531Sjairo.balart@metempsy.com
31213531Sjairo.balart@metempsy.com            if (group == Gicv3::G1S && !inSecureState()) {
31313531Sjairo.balart@metempsy.com                group = Gicv3::G1NS;
31413531Sjairo.balart@metempsy.com            }
31513531Sjairo.balart@metempsy.com
31613760Sjairo.balart@metempsy.com            ICC_CTLR_EL1 icc_ctlr_el1_s =
31713760Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
31813760Sjairo.balart@metempsy.com
31913760Sjairo.balart@metempsy.com            if ((group == Gicv3::G1S) && !isEL3OrMon() &&
32013760Sjairo.balart@metempsy.com                icc_ctlr_el1_s.CBPR) {
32113531Sjairo.balart@metempsy.com                group = Gicv3::G0S;
32213531Sjairo.balart@metempsy.com            }
32313531Sjairo.balart@metempsy.com
32413531Sjairo.balart@metempsy.com            bool sat_inc = false;
32513531Sjairo.balart@metempsy.com
32613760Sjairo.balart@metempsy.com            ICC_CTLR_EL1 icc_ctlr_el1_ns =
32713760Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
32813760Sjairo.balart@metempsy.com
32913760Sjairo.balart@metempsy.com            if ((group == Gicv3::G1NS) && (currEL() < EL3) &&
33013760Sjairo.balart@metempsy.com                icc_ctlr_el1_ns.CBPR) {
33113531Sjairo.balart@metempsy.com                // Reads return BPR0 + 1 saturated to 7, WI
33213531Sjairo.balart@metempsy.com                group = Gicv3::G0S;
33313531Sjairo.balart@metempsy.com                sat_inc = true;
33413531Sjairo.balart@metempsy.com            }
33513531Sjairo.balart@metempsy.com
33613531Sjairo.balart@metempsy.com            uint8_t bpr;
33713531Sjairo.balart@metempsy.com
33813531Sjairo.balart@metempsy.com            if (group == Gicv3::G0S) {
33913531Sjairo.balart@metempsy.com                bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
34013531Sjairo.balart@metempsy.com            } else {
34113531Sjairo.balart@metempsy.com                bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1);
34213926Sgiacomo.travaglini@arm.com                bpr = std::max(bpr, group == Gicv3::G1S ?
34313926Sgiacomo.travaglini@arm.com                    GIC_MIN_BPR : GIC_MIN_BPR_NS);
34413531Sjairo.balart@metempsy.com            }
34513531Sjairo.balart@metempsy.com
34613531Sjairo.balart@metempsy.com            if (sat_inc) {
34713531Sjairo.balart@metempsy.com                bpr++;
34813531Sjairo.balart@metempsy.com
34913531Sjairo.balart@metempsy.com                if (bpr > 7) {
35013531Sjairo.balart@metempsy.com                    bpr = 7;
35113531Sjairo.balart@metempsy.com                }
35213531Sjairo.balart@metempsy.com            }
35313531Sjairo.balart@metempsy.com
35413531Sjairo.balart@metempsy.com            value = bpr;
35513531Sjairo.balart@metempsy.com            break;
35613760Sjairo.balart@metempsy.com      }
35713760Sjairo.balart@metempsy.com
35813760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 1
35913531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR0_EL1:
36013531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
36113531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
36213531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
36313760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
36413531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
36513531Sjairo.balart@metempsy.com          bool sat_inc = false;
36613531Sjairo.balart@metempsy.com
36713760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
36813760Sjairo.balart@metempsy.com              // bpr0 + 1 saturated to 7, WI
36913531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
37013531Sjairo.balart@metempsy.com              sat_inc = true;
37113531Sjairo.balart@metempsy.com          }
37213531Sjairo.balart@metempsy.com
37313531Sjairo.balart@metempsy.com          uint8_t vbpr;
37413531Sjairo.balart@metempsy.com
37513531Sjairo.balart@metempsy.com          if (group == Gicv3::G0S) {
37613760Sjairo.balart@metempsy.com              vbpr = ich_vmcr_el2.VBPR0;
37713531Sjairo.balart@metempsy.com          } else {
37813760Sjairo.balart@metempsy.com              vbpr = ich_vmcr_el2.VBPR1;
37913531Sjairo.balart@metempsy.com          }
38013531Sjairo.balart@metempsy.com
38113531Sjairo.balart@metempsy.com          if (sat_inc) {
38213531Sjairo.balart@metempsy.com              vbpr++;
38313531Sjairo.balart@metempsy.com
38413531Sjairo.balart@metempsy.com              if (vbpr > 7) {
38513531Sjairo.balart@metempsy.com                  vbpr = 7;
38613531Sjairo.balart@metempsy.com              }
38713531Sjairo.balart@metempsy.com          }
38813531Sjairo.balart@metempsy.com
38913531Sjairo.balart@metempsy.com          value = vbpr;
39013531Sjairo.balart@metempsy.com          break;
39113531Sjairo.balart@metempsy.com      }
39213531Sjairo.balart@metempsy.com
39313760Sjairo.balart@metempsy.com      // Interrupt Priority Mask Register
39413531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
39513760Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1:
39613760Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
39714057Sgiacomo.travaglini@arm.com            return readMiscReg(MISCREG_ICV_PMR_EL1);
39813531Sjairo.balart@metempsy.com        }
39913531Sjairo.balart@metempsy.com
40013531Sjairo.balart@metempsy.com        if (haveEL(EL3) && !inSecureState() &&
40113760Sjairo.balart@metempsy.com            (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
40213760Sjairo.balart@metempsy.com            // Spec section 4.8.1
40313760Sjairo.balart@metempsy.com            // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
40413531Sjairo.balart@metempsy.com            if ((value & 0x80) == 0) {
40513760Sjairo.balart@metempsy.com                // If the current priority mask value is in the range of
40613760Sjairo.balart@metempsy.com                // 0x00-0x7F a read access returns the value 0x00.
40713531Sjairo.balart@metempsy.com                value = 0;
40813531Sjairo.balart@metempsy.com            } else if (value != 0xff) {
40913760Sjairo.balart@metempsy.com                // If the current priority mask value is in the range of
41013760Sjairo.balart@metempsy.com                // 0x80-0xFF a read access returns the Non-secure read of the
41113760Sjairo.balart@metempsy.com                // current value.
41213531Sjairo.balart@metempsy.com                value = (value << 1) & 0xff;
41313531Sjairo.balart@metempsy.com            }
41413531Sjairo.balart@metempsy.com        }
41513531Sjairo.balart@metempsy.com
41613531Sjairo.balart@metempsy.com        break;
41713531Sjairo.balart@metempsy.com
41814057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
41914057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
42014057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
42114057Sgiacomo.travaglini@arm.com
42214057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VPMR;
42314057Sgiacomo.travaglini@arm.com          break;
42414057Sgiacomo.travaglini@arm.com      }
42514057Sgiacomo.travaglini@arm.com
42613760Sjairo.balart@metempsy.com      // Interrupt Acknowledge Register 0
42713531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0:
42813760Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0_EL1: {
42913531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
43013531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR0_EL1);
43113531Sjairo.balart@metempsy.com          }
43213531Sjairo.balart@metempsy.com
43313531Sjairo.balart@metempsy.com          uint32_t int_id;
43413531Sjairo.balart@metempsy.com
43513531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
43613531Sjairo.balart@metempsy.com              int_id = getHPPIR0();
43713531Sjairo.balart@metempsy.com
43813531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
43913923Sgiacomo.travaglini@arm.com              if (int_id < Gicv3::INTID_SECURE ||
44013923Sgiacomo.travaglini@arm.com                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
44113531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
44213531Sjairo.balart@metempsy.com              }
44313531Sjairo.balart@metempsy.com          } else {
44413531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
44513531Sjairo.balart@metempsy.com          }
44613531Sjairo.balart@metempsy.com
44713531Sjairo.balart@metempsy.com          value = int_id;
44813531Sjairo.balart@metempsy.com          break;
44913531Sjairo.balart@metempsy.com      }
45013531Sjairo.balart@metempsy.com
45113760Sjairo.balart@metempsy.com      // Virtual Interrupt Acknowledge Register 0
45213531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR0_EL1: {
45313531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
45413531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
45513531Sjairo.balart@metempsy.com
45613531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
45713760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
45813531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
45913531Sjairo.balart@metempsy.com
46013760Sjairo.balart@metempsy.com              if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
46113760Sjairo.balart@metempsy.com                  int_id = ich_lr_el2.vINTID;
46213531Sjairo.balart@metempsy.com
46313531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
46413760Sjairo.balart@metempsy.com                      int_id > Gicv3::INTID_SPURIOUS) {
46513531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
46613531Sjairo.balart@metempsy.com                  } else {
46713531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
46813531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
46913531Sjairo.balart@metempsy.com                      // - Return de bogus id...
47013760Sjairo.balart@metempsy.com                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
47113531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
47213760Sjairo.balart@metempsy.com                                              ich_lr_el2);
47313531Sjairo.balart@metempsy.com                  }
47413531Sjairo.balart@metempsy.com              }
47513531Sjairo.balart@metempsy.com          }
47613531Sjairo.balart@metempsy.com
47713531Sjairo.balart@metempsy.com          value = int_id;
47813531Sjairo.balart@metempsy.com          virtualUpdate();
47913531Sjairo.balart@metempsy.com          break;
48013531Sjairo.balart@metempsy.com      }
48113531Sjairo.balart@metempsy.com
48213760Sjairo.balart@metempsy.com      // Interrupt Acknowledge Register 1
48313531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1:
48413760Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1_EL1: {
48513531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
48613531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR1_EL1);
48713531Sjairo.balart@metempsy.com          }
48813531Sjairo.balart@metempsy.com
48913531Sjairo.balart@metempsy.com          uint32_t int_id;
49013531Sjairo.balart@metempsy.com
49113531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
49213531Sjairo.balart@metempsy.com              int_id = getHPPIR1();
49313531Sjairo.balart@metempsy.com
49413531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
49513923Sgiacomo.travaglini@arm.com              if (int_id < Gicv3::INTID_SECURE ||
49613923Sgiacomo.travaglini@arm.com                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
49713531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
49813531Sjairo.balart@metempsy.com              }
49913531Sjairo.balart@metempsy.com          } else {
50013531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
50113531Sjairo.balart@metempsy.com          }
50213531Sjairo.balart@metempsy.com
50313531Sjairo.balart@metempsy.com          value = int_id;
50413531Sjairo.balart@metempsy.com          break;
50513531Sjairo.balart@metempsy.com      }
50613531Sjairo.balart@metempsy.com
50713760Sjairo.balart@metempsy.com      // Virtual Interrupt Acknowledge Register 1
50813531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR1_EL1: {
50913531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
51013531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
51113531Sjairo.balart@metempsy.com
51213531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
51313760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
51413531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
51513531Sjairo.balart@metempsy.com
51613760Sjairo.balart@metempsy.com              if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
51713760Sjairo.balart@metempsy.com                  int_id = ich_lr_el2.vINTID;
51813531Sjairo.balart@metempsy.com
51913531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
52013760Sjairo.balart@metempsy.com                      int_id > Gicv3::INTID_SPURIOUS) {
52113531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
52213531Sjairo.balart@metempsy.com                  } else {
52313531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
52413531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
52513531Sjairo.balart@metempsy.com                      // - Return de bogus id...
52613760Sjairo.balart@metempsy.com                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
52713531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
52813760Sjairo.balart@metempsy.com                                              ich_lr_el2);
52913531Sjairo.balart@metempsy.com                  }
53013531Sjairo.balart@metempsy.com              }
53113531Sjairo.balart@metempsy.com          }
53213531Sjairo.balart@metempsy.com
53313531Sjairo.balart@metempsy.com          value = int_id;
53413531Sjairo.balart@metempsy.com          virtualUpdate();
53513531Sjairo.balart@metempsy.com          break;
53613531Sjairo.balart@metempsy.com      }
53713531Sjairo.balart@metempsy.com
53813760Sjairo.balart@metempsy.com      // System Register Enable Register EL1
53913531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
54013760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1: {
54113531Sjairo.balart@metempsy.com        /*
54213531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
54313531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
54413531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
54513531Sjairo.balart@metempsy.com         */
54613760Sjairo.balart@metempsy.com          ICC_SRE_EL1 icc_sre_el1 = 0;
54713760Sjairo.balart@metempsy.com          icc_sre_el1.SRE = 1;
54813760Sjairo.balart@metempsy.com          icc_sre_el1.DIB = 1;
54913760Sjairo.balart@metempsy.com          icc_sre_el1.DFB = 1;
55013760Sjairo.balart@metempsy.com          value = icc_sre_el1;
55113760Sjairo.balart@metempsy.com          break;
55213760Sjairo.balart@metempsy.com      }
55313760Sjairo.balart@metempsy.com
55413760Sjairo.balart@metempsy.com      // System Register Enable Register EL2
55513760Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
55613760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2: {
55713531Sjairo.balart@metempsy.com        /*
55813531Sjairo.balart@metempsy.com         * Enable [3] == 1
55913760Sjairo.balart@metempsy.com         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
56013531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
56113531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
56213531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
56313531Sjairo.balart@metempsy.com         */
56413760Sjairo.balart@metempsy.com        ICC_SRE_EL2 icc_sre_el2 = 0;
56513760Sjairo.balart@metempsy.com        icc_sre_el2.SRE = 1;
56613760Sjairo.balart@metempsy.com        icc_sre_el2.DIB = 1;
56713760Sjairo.balart@metempsy.com        icc_sre_el2.DFB = 1;
56813760Sjairo.balart@metempsy.com        icc_sre_el2.Enable = 1;
56913760Sjairo.balart@metempsy.com        value = icc_sre_el2;
57013531Sjairo.balart@metempsy.com        break;
57113760Sjairo.balart@metempsy.com      }
57213760Sjairo.balart@metempsy.com
57313760Sjairo.balart@metempsy.com      // System Register Enable Register EL3
57413760Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
57513760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3: {
57613760Sjairo.balart@metempsy.com        /*
57713760Sjairo.balart@metempsy.com         * Enable [3] == 1
57813760Sjairo.balart@metempsy.com         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
57913760Sjairo.balart@metempsy.com         *  EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
58013760Sjairo.balart@metempsy.com         *  RAO/WI)
58113760Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
58213760Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
58313760Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
58413760Sjairo.balart@metempsy.com         */
58513760Sjairo.balart@metempsy.com        ICC_SRE_EL3 icc_sre_el3 = 0;
58613760Sjairo.balart@metempsy.com        icc_sre_el3.SRE = 1;
58713760Sjairo.balart@metempsy.com        icc_sre_el3.DIB = 1;
58813760Sjairo.balart@metempsy.com        icc_sre_el3.DFB = 1;
58913760Sjairo.balart@metempsy.com        icc_sre_el3.Enable = 1;
59013760Sjairo.balart@metempsy.com        value = icc_sre_el3;
59113760Sjairo.balart@metempsy.com        break;
59213760Sjairo.balart@metempsy.com      }
59313760Sjairo.balart@metempsy.com
59413760Sjairo.balart@metempsy.com      // Control Register
59513531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
59613760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: {
59713760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
59813531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_CTLR_EL1);
59913531Sjairo.balart@metempsy.com          }
60013531Sjairo.balart@metempsy.com
60113760Sjairo.balart@metempsy.com          // Enforce value for RO bits
60213760Sjairo.balart@metempsy.com          // ExtRange [19], INTIDs in the range 1024..8191 not supported
60313760Sjairo.balart@metempsy.com          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
60413760Sjairo.balart@metempsy.com          // A3V [15], supports non-zero values of the Aff3 field in SGI
60513760Sjairo.balart@metempsy.com          //           generation System registers
60613760Sjairo.balart@metempsy.com          // SEIS [14], does not support generation of SEIs (deprecated)
60713531Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
60813531Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
60913760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1 = value;
61013760Sjairo.balart@metempsy.com          icc_ctlr_el1.ExtRange = 0;
61113760Sjairo.balart@metempsy.com          icc_ctlr_el1.RSS = 1;
61213760Sjairo.balart@metempsy.com          icc_ctlr_el1.A3V = 1;
61313760Sjairo.balart@metempsy.com          icc_ctlr_el1.SEIS = 0;
61413760Sjairo.balart@metempsy.com          icc_ctlr_el1.IDbits = 1;
61513760Sjairo.balart@metempsy.com          icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
61613760Sjairo.balart@metempsy.com          value = icc_ctlr_el1;
61713531Sjairo.balart@metempsy.com          break;
61813531Sjairo.balart@metempsy.com      }
61913531Sjairo.balart@metempsy.com
62013760Sjairo.balart@metempsy.com      // Virtual Control Register
62113531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
62213760Sjairo.balart@metempsy.com          ICV_CTLR_EL1 icv_ctlr_el1 = value;
62313760Sjairo.balart@metempsy.com          icv_ctlr_el1.RSS = 0;
62413760Sjairo.balart@metempsy.com          icv_ctlr_el1.A3V = 1;
62513760Sjairo.balart@metempsy.com          icv_ctlr_el1.SEIS = 0;
62613760Sjairo.balart@metempsy.com          icv_ctlr_el1.IDbits = 1;
62713760Sjairo.balart@metempsy.com          icv_ctlr_el1.PRIbits = 7;
62813760Sjairo.balart@metempsy.com          value = icv_ctlr_el1;
62913531Sjairo.balart@metempsy.com          break;
63013531Sjairo.balart@metempsy.com      }
63113531Sjairo.balart@metempsy.com
63213760Sjairo.balart@metempsy.com      // Control Register
63313531Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
63413531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
63513760Sjairo.balart@metempsy.com          // Enforce value for RO bits
63613760Sjairo.balart@metempsy.com          // ExtRange [19], INTIDs in the range 1024..8191 not supported
63713760Sjairo.balart@metempsy.com          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
63813760Sjairo.balart@metempsy.com          // nDS [17], supports disabling of security
63913760Sjairo.balart@metempsy.com          // A3V [15], supports non-zero values of the Aff3 field in SGI
64013760Sjairo.balart@metempsy.com          //           generation System registers
64113760Sjairo.balart@metempsy.com          // SEIS [14], does not support generation of SEIs (deprecated)
64213531Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
64313531Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
64413760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 = value;
64513760Sjairo.balart@metempsy.com          icc_ctlr_el3.ExtRange = 0;
64613760Sjairo.balart@metempsy.com          icc_ctlr_el3.RSS = 1;
64713760Sjairo.balart@metempsy.com          icc_ctlr_el3.nDS = 0;
64813760Sjairo.balart@metempsy.com          icc_ctlr_el3.A3V = 1;
64913760Sjairo.balart@metempsy.com          icc_ctlr_el3.SEIS = 0;
65013760Sjairo.balart@metempsy.com          icc_ctlr_el3.IDbits = 0;
65113760Sjairo.balart@metempsy.com          icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
65213760Sjairo.balart@metempsy.com          value = icc_ctlr_el3;
65313531Sjairo.balart@metempsy.com          break;
65413531Sjairo.balart@metempsy.com      }
65513531Sjairo.balart@metempsy.com
65613760Sjairo.balart@metempsy.com      // Hyp Control Register
65713531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
65813531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2:
65913531Sjairo.balart@metempsy.com        break;
66013531Sjairo.balart@metempsy.com
66113760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 0 Registers
66213531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0:
66313531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0_EL2:
66413531Sjairo.balart@metempsy.com        break;
66513531Sjairo.balart@metempsy.com
66613760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 1 Registers
66713531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0:
66813531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0_EL2:
66913531Sjairo.balart@metempsy.com        break;
67013531Sjairo.balart@metempsy.com
67113760Sjairo.balart@metempsy.com      // Maintenance Interrupt State Register
67213531Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR:
67313760Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR_EL2:
67413760Sjairo.balart@metempsy.com        value = maintenanceInterruptStatus();
67513760Sjairo.balart@metempsy.com        break;
67613760Sjairo.balart@metempsy.com
67713760Sjairo.balart@metempsy.com      // VGIC Type Register
67813760Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR:
67913760Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR_EL2: {
68013760Sjairo.balart@metempsy.com        ICH_VTR_EL2 ich_vtr_el2 = value;
68113760Sjairo.balart@metempsy.com
68213760Sjairo.balart@metempsy.com        ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
68313760Sjairo.balart@metempsy.com        ich_vtr_el2.A3V = 1;
68413760Sjairo.balart@metempsy.com        ich_vtr_el2.IDbits = 1;
68513760Sjairo.balart@metempsy.com        ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
68613760Sjairo.balart@metempsy.com        ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
68713760Sjairo.balart@metempsy.com
68813760Sjairo.balart@metempsy.com        value = ich_vtr_el2;
68913760Sjairo.balart@metempsy.com        break;
69013531Sjairo.balart@metempsy.com      }
69113531Sjairo.balart@metempsy.com
69213760Sjairo.balart@metempsy.com      // End of Interrupt Status Register
69313531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR:
69413531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR_EL2:
69513760Sjairo.balart@metempsy.com        value = eoiMaintenanceInterruptStatus();
69613531Sjairo.balart@metempsy.com        break;
69713531Sjairo.balart@metempsy.com
69813760Sjairo.balart@metempsy.com      // Empty List Register Status Register
69913531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR:
70013531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR_EL2:
70113531Sjairo.balart@metempsy.com        value = 0;
70213531Sjairo.balart@metempsy.com
70313531Sjairo.balart@metempsy.com        for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
70413760Sjairo.balart@metempsy.com            ICH_LR_EL2 ich_lr_el2 =
70513531Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
70613531Sjairo.balart@metempsy.com
70713760Sjairo.balart@metempsy.com            if ((ich_lr_el2.State  == ICH_LR_EL2_STATE_INVALID) &&
70813760Sjairo.balart@metempsy.com                (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
70913531Sjairo.balart@metempsy.com                value |= (1 << lr_idx);
71013531Sjairo.balart@metempsy.com            }
71113531Sjairo.balart@metempsy.com        }
71213531Sjairo.balart@metempsy.com
71313531Sjairo.balart@metempsy.com        break;
71413531Sjairo.balart@metempsy.com
71513760Sjairo.balart@metempsy.com      // List Registers
71613531Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
71713531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
71813531Sjairo.balart@metempsy.com        value = value >> 32;
71913531Sjairo.balart@metempsy.com        break;
72013531Sjairo.balart@metempsy.com
72113760Sjairo.balart@metempsy.com      // List Registers
72213531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
72313531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
72413531Sjairo.balart@metempsy.com        value = value & 0xffffffff;
72513531Sjairo.balart@metempsy.com        break;
72613531Sjairo.balart@metempsy.com
72713760Sjairo.balart@metempsy.com      // List Registers
72813531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
72913531Sjairo.balart@metempsy.com        break;
73013531Sjairo.balart@metempsy.com
73113760Sjairo.balart@metempsy.com      // Virtual Machine Control Register
73213531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
73313531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2:
73413531Sjairo.balart@metempsy.com        break;
73513531Sjairo.balart@metempsy.com
73613531Sjairo.balart@metempsy.com      default:
73713760Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
73813760Sjairo.balart@metempsy.com              misc_reg, miscRegName[misc_reg]);
73913531Sjairo.balart@metempsy.com    }
74013531Sjairo.balart@metempsy.com
74113760Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
74213760Sjairo.balart@metempsy.com            miscRegName[misc_reg], value);
74313531Sjairo.balart@metempsy.com    return value;
74413531Sjairo.balart@metempsy.com}
74513531Sjairo.balart@metempsy.com
74613531Sjairo.balart@metempsy.comvoid
74713580Sgabeblack@google.comGicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
74813531Sjairo.balart@metempsy.com{
74913531Sjairo.balart@metempsy.com    bool do_virtual_update = false;
75013760Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
75113760Sjairo.balart@metempsy.com            miscRegName[misc_reg], val);
75213531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
75313531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
75413531Sjairo.balart@metempsy.com
75513531Sjairo.balart@metempsy.com    switch (misc_reg) {
75613760Sjairo.balart@metempsy.com      // Active Priorities Group 1 Registers
75713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
75813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1:
75913531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
76013531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
76113531Sjairo.balart@metempsy.com        }
76213531Sjairo.balart@metempsy.com
76313531Sjairo.balart@metempsy.com        break;
76413531Sjairo.balart@metempsy.com
76513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
76613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
76713531Sjairo.balart@metempsy.com
76813531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
76913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
77013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
77113531Sjairo.balart@metempsy.com
77213531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
77313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
77413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
77513531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
77613531Sjairo.balart@metempsy.com        break;
77713531Sjairo.balart@metempsy.com
77813760Sjairo.balart@metempsy.com      // Active Priorities Group 0 Registers
77913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
78013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1:
78113531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
78213531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
78313531Sjairo.balart@metempsy.com        }
78413531Sjairo.balart@metempsy.com
78513531Sjairo.balart@metempsy.com        break;
78613531Sjairo.balart@metempsy.com
78713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
78813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
78913531Sjairo.balart@metempsy.com
79013531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
79113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
79213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
79313531Sjairo.balart@metempsy.com
79413531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
79513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
79613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
79713531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
79813531Sjairo.balart@metempsy.com        break;
79913531Sjairo.balart@metempsy.com
80013760Sjairo.balart@metempsy.com      // End Of Interrupt Register 0
80113531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0:
80213531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
80313531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
80413531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
80513531Sjairo.balart@metempsy.com          }
80613531Sjairo.balart@metempsy.com
80713531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
80813531Sjairo.balart@metempsy.com
80913531Sjairo.balart@metempsy.com          // avoid activation for special interrupts
81013923Sgiacomo.travaglini@arm.com          if (int_id >= Gicv3::INTID_SECURE &&
81113923Sgiacomo.travaglini@arm.com              int_id <= Gicv3::INTID_SPURIOUS) {
81213531Sjairo.balart@metempsy.com              return;
81313531Sjairo.balart@metempsy.com          }
81413531Sjairo.balart@metempsy.com
81513531Sjairo.balart@metempsy.com          Gicv3::GroupId group = Gicv3::G0S;
81613531Sjairo.balart@metempsy.com
81713531Sjairo.balart@metempsy.com          if (highestActiveGroup() != group) {
81813531Sjairo.balart@metempsy.com              return;
81913531Sjairo.balart@metempsy.com          }
82013531Sjairo.balart@metempsy.com
82113531Sjairo.balart@metempsy.com          dropPriority(group);
82213531Sjairo.balart@metempsy.com
82313531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
82413531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
82513531Sjairo.balart@metempsy.com          }
82613531Sjairo.balart@metempsy.com
82713531Sjairo.balart@metempsy.com          break;
82813531Sjairo.balart@metempsy.com      }
82913531Sjairo.balart@metempsy.com
83013760Sjairo.balart@metempsy.com      // Virtual End Of Interrupt Register 0
83113531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR0_EL1: {
83213531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
83313531Sjairo.balart@metempsy.com
83413531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
83513531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
83613531Sjairo.balart@metempsy.com                  int_id <= Gicv3::INTID_SPURIOUS) {
83713531Sjairo.balart@metempsy.com              return;
83813531Sjairo.balart@metempsy.com          }
83913531Sjairo.balart@metempsy.com
84013531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
84113531Sjairo.balart@metempsy.com
84213531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
84313531Sjairo.balart@metempsy.com              return;
84413531Sjairo.balart@metempsy.com          }
84513531Sjairo.balart@metempsy.com
84613531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
84713531Sjairo.balart@metempsy.com
84813531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
84913531Sjairo.balart@metempsy.com              // No LR found matching
85013531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
85113531Sjairo.balart@metempsy.com          } else {
85213760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
85313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
85413531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
85513760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
85613760Sjairo.balart@metempsy.com              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
85713531Sjairo.balart@metempsy.com
85813531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
85913760Sjairo.balart@metempsy.com                  //if (!virtualIsEOISplitMode())
86013531Sjairo.balart@metempsy.com                  {
86113531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
86213531Sjairo.balart@metempsy.com                  }
86313531Sjairo.balart@metempsy.com              }
86413531Sjairo.balart@metempsy.com          }
86513531Sjairo.balart@metempsy.com
86613531Sjairo.balart@metempsy.com          virtualUpdate();
86713531Sjairo.balart@metempsy.com          break;
86813531Sjairo.balart@metempsy.com      }
86913531Sjairo.balart@metempsy.com
87013760Sjairo.balart@metempsy.com      // End Of Interrupt Register 1
87113531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1:
87213760Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1_EL1: {
87313531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
87413531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR1_EL1, val);
87513531Sjairo.balart@metempsy.com          }
87613531Sjairo.balart@metempsy.com
87713531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
87813531Sjairo.balart@metempsy.com
87913531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
88013923Sgiacomo.travaglini@arm.com          if (int_id >= Gicv3::INTID_SECURE &&
88113923Sgiacomo.travaglini@arm.com              int_id <= Gicv3::INTID_SPURIOUS) {
88213531Sjairo.balart@metempsy.com              return;
88313531Sjairo.balart@metempsy.com          }
88413531Sjairo.balart@metempsy.com
88513760Sjairo.balart@metempsy.com          Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
88613531Sjairo.balart@metempsy.com
88713531Sjairo.balart@metempsy.com          if (highestActiveGroup() == Gicv3::G0S) {
88813531Sjairo.balart@metempsy.com              return;
88913531Sjairo.balart@metempsy.com          }
89013531Sjairo.balart@metempsy.com
89113531Sjairo.balart@metempsy.com          if (distributor->DS == 0) {
89213531Sjairo.balart@metempsy.com              if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) {
89313531Sjairo.balart@metempsy.com                  return;
89413531Sjairo.balart@metempsy.com              } else if (highestActiveGroup() == Gicv3::G1NS &&
89513760Sjairo.balart@metempsy.com                         !(!inSecureState() or (currEL() == EL3))) {
89613531Sjairo.balart@metempsy.com                  return;
89713531Sjairo.balart@metempsy.com              }
89813531Sjairo.balart@metempsy.com          }
89913531Sjairo.balart@metempsy.com
90013531Sjairo.balart@metempsy.com          dropPriority(group);
90113531Sjairo.balart@metempsy.com
90213531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
90313531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
90413531Sjairo.balart@metempsy.com          }
90513531Sjairo.balart@metempsy.com
90613531Sjairo.balart@metempsy.com          break;
90713531Sjairo.balart@metempsy.com      }
90813531Sjairo.balart@metempsy.com
90913760Sjairo.balart@metempsy.com      // Virtual End Of Interrupt Register 1
91013531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR1_EL1: {
91113531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
91213531Sjairo.balart@metempsy.com
91313531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
91413531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
91513760Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
91613531Sjairo.balart@metempsy.com              return;
91713531Sjairo.balart@metempsy.com          }
91813531Sjairo.balart@metempsy.com
91913531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
92013531Sjairo.balart@metempsy.com
92113531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
92213531Sjairo.balart@metempsy.com              return;
92313531Sjairo.balart@metempsy.com          }
92413531Sjairo.balart@metempsy.com
92513531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
92613531Sjairo.balart@metempsy.com
92713531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
92813760Sjairo.balart@metempsy.com              // No matching LR found
92913531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
93013531Sjairo.balart@metempsy.com          } else {
93113760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
93213531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
93313531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
93413760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
93513760Sjairo.balart@metempsy.com              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
93613531Sjairo.balart@metempsy.com
93713531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
93813531Sjairo.balart@metempsy.com                  if (!virtualIsEOISplitMode()) {
93913531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
94013531Sjairo.balart@metempsy.com                  }
94113531Sjairo.balart@metempsy.com              }
94213531Sjairo.balart@metempsy.com          }
94313531Sjairo.balart@metempsy.com
94413531Sjairo.balart@metempsy.com          virtualUpdate();
94513531Sjairo.balart@metempsy.com          break;
94613531Sjairo.balart@metempsy.com      }
94713531Sjairo.balart@metempsy.com
94813760Sjairo.balart@metempsy.com      // Deactivate Interrupt Register
94913531Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR:
95013760Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR_EL1: {
95113531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
95213760Sjairo.balart@metempsy.com              (hcr_imo || hcr_fmo)) {
95313531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_DIR_EL1, val);
95413531Sjairo.balart@metempsy.com          }
95513531Sjairo.balart@metempsy.com
95613531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
95713531Sjairo.balart@metempsy.com
95813760Sjairo.balart@metempsy.com          // The following checks are as per spec pseudocode
95913760Sjairo.balart@metempsy.com          // aarch64/support/ICC_DIR_EL1
96013760Sjairo.balart@metempsy.com
96113760Sjairo.balart@metempsy.com          // Check for spurious ID
96213531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE) {
96313531Sjairo.balart@metempsy.com              return;
96413531Sjairo.balart@metempsy.com          }
96513531Sjairo.balart@metempsy.com
96613760Sjairo.balart@metempsy.com          // EOI mode is not set, so don't deactivate
96713531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
96813531Sjairo.balart@metempsy.com              return;
96913531Sjairo.balart@metempsy.com          }
97013531Sjairo.balart@metempsy.com
97113531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
97213531Sjairo.balart@metempsy.com              int_id >= 32 ? distributor->getIntGroup(int_id) :
97313531Sjairo.balart@metempsy.com              redistributor->getIntGroup(int_id);
97413531Sjairo.balart@metempsy.com          bool irq_is_grp0 = group == Gicv3::G0S;
97513531Sjairo.balart@metempsy.com          bool single_sec_state = distributor->DS;
97613531Sjairo.balart@metempsy.com          bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
97713531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
97813531Sjairo.balart@metempsy.com          bool route_fiq_to_el3 = scr_el3.fiq;
97913531Sjairo.balart@metempsy.com          bool route_irq_to_el3 = scr_el3.irq;
98013531Sjairo.balart@metempsy.com          bool route_fiq_to_el2 = hcr_fmo;
98113531Sjairo.balart@metempsy.com          bool route_irq_to_el2 = hcr_imo;
98213531Sjairo.balart@metempsy.com
98313531Sjairo.balart@metempsy.com          switch (currEL()) {
98413531Sjairo.balart@metempsy.com            case EL3:
98513531Sjairo.balart@metempsy.com              break;
98613531Sjairo.balart@metempsy.com
98713531Sjairo.balart@metempsy.com            case EL2:
98813531Sjairo.balart@metempsy.com              if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
98913531Sjairo.balart@metempsy.com                  break;
99013531Sjairo.balart@metempsy.com              }
99113531Sjairo.balart@metempsy.com
99213531Sjairo.balart@metempsy.com              if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
99313531Sjairo.balart@metempsy.com                  break;
99413531Sjairo.balart@metempsy.com              }
99513531Sjairo.balart@metempsy.com
99613531Sjairo.balart@metempsy.com              return;
99713531Sjairo.balart@metempsy.com
99813531Sjairo.balart@metempsy.com            case EL1:
99913531Sjairo.balart@metempsy.com              if (!isSecureBelowEL3()) {
100013531Sjairo.balart@metempsy.com                  if (single_sec_state && irq_is_grp0 &&
100113760Sjairo.balart@metempsy.com                      !route_fiq_to_el3 && !route_fiq_to_el2) {
100213531Sjairo.balart@metempsy.com                      break;
100313531Sjairo.balart@metempsy.com                  }
100413531Sjairo.balart@metempsy.com
100513531Sjairo.balart@metempsy.com                  if (!irq_is_secure && !irq_is_grp0 &&
100613760Sjairo.balart@metempsy.com                      !route_irq_to_el3 && !route_irq_to_el2) {
100713531Sjairo.balart@metempsy.com                      break;
100813531Sjairo.balart@metempsy.com                  }
100913531Sjairo.balart@metempsy.com              } else {
101013531Sjairo.balart@metempsy.com                  if (irq_is_grp0 && !route_fiq_to_el3) {
101113531Sjairo.balart@metempsy.com                      break;
101213531Sjairo.balart@metempsy.com                  }
101313531Sjairo.balart@metempsy.com
101413531Sjairo.balart@metempsy.com                  if (!irq_is_grp0 &&
101513760Sjairo.balart@metempsy.com                      (!irq_is_secure || !single_sec_state) &&
101613760Sjairo.balart@metempsy.com                      !route_irq_to_el3) {
101713531Sjairo.balart@metempsy.com                      break;
101813531Sjairo.balart@metempsy.com                  }
101913531Sjairo.balart@metempsy.com              }
102013531Sjairo.balart@metempsy.com
102113531Sjairo.balart@metempsy.com              return;
102213531Sjairo.balart@metempsy.com
102313531Sjairo.balart@metempsy.com            default:
102413531Sjairo.balart@metempsy.com              break;
102513531Sjairo.balart@metempsy.com          }
102613531Sjairo.balart@metempsy.com
102713531Sjairo.balart@metempsy.com          deactivateIRQ(int_id, group);
102813531Sjairo.balart@metempsy.com          break;
102913531Sjairo.balart@metempsy.com      }
103013531Sjairo.balart@metempsy.com
103113760Sjairo.balart@metempsy.com      // Deactivate Virtual Interrupt Register
103213531Sjairo.balart@metempsy.com      case MISCREG_ICV_DIR_EL1: {
103313531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
103413531Sjairo.balart@metempsy.com
103513531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
103613531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
103713760Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
103813531Sjairo.balart@metempsy.com              return;
103913531Sjairo.balart@metempsy.com          }
104013531Sjairo.balart@metempsy.com
104113531Sjairo.balart@metempsy.com          if (!virtualIsEOISplitMode()) {
104213531Sjairo.balart@metempsy.com              return;
104313531Sjairo.balart@metempsy.com          }
104413531Sjairo.balart@metempsy.com
104513531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
104613531Sjairo.balart@metempsy.com
104713531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
104813760Sjairo.balart@metempsy.com              // No matching LR found
104913531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
105013531Sjairo.balart@metempsy.com          } else {
105113531Sjairo.balart@metempsy.com              virtualDeactivateIRQ(lr_idx);
105213531Sjairo.balart@metempsy.com          }
105313531Sjairo.balart@metempsy.com
105413531Sjairo.balart@metempsy.com          virtualUpdate();
105513531Sjairo.balart@metempsy.com          break;
105613531Sjairo.balart@metempsy.com      }
105713531Sjairo.balart@metempsy.com
105813760Sjairo.balart@metempsy.com      // Binary Point Register 0
105913531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
106013760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0_EL1:
106113760Sjairo.balart@metempsy.com      // Binary Point Register 1
106213531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
106313760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: {
106413531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState()) {
106513531Sjairo.balart@metempsy.com              if (misc_reg == MISCREG_ICC_BPR0_EL1 && hcr_fmo) {
106613531Sjairo.balart@metempsy.com                  return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
106713531Sjairo.balart@metempsy.com              } else if (misc_reg == MISCREG_ICC_BPR1_EL1 && hcr_imo) {
106813531Sjairo.balart@metempsy.com                  return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
106913531Sjairo.balart@metempsy.com              }
107013531Sjairo.balart@metempsy.com          }
107113531Sjairo.balart@metempsy.com
107213531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
107313531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;
107413531Sjairo.balart@metempsy.com
107513531Sjairo.balart@metempsy.com          if (group == Gicv3::G1S && !inSecureState()) {
107613531Sjairo.balart@metempsy.com              group = Gicv3::G1NS;
107713531Sjairo.balart@metempsy.com          }
107813531Sjairo.balart@metempsy.com
107913760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1_s =
108013760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
108113760Sjairo.balart@metempsy.com
108213760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1S) && !isEL3OrMon() &&
108313760Sjairo.balart@metempsy.com              icc_ctlr_el1_s.CBPR) {
108413531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
108513531Sjairo.balart@metempsy.com          }
108613531Sjairo.balart@metempsy.com
108713760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1_ns =
108813760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
108913760Sjairo.balart@metempsy.com
109013760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) && (currEL() < EL3) &&
109113760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.CBPR) {
109213760Sjairo.balart@metempsy.com              // BPR0 + 1 saturated to 7, WI
109313531Sjairo.balart@metempsy.com              return;
109413531Sjairo.balart@metempsy.com          }
109513531Sjairo.balart@metempsy.com
109613531Sjairo.balart@metempsy.com          uint8_t min_val = (group == Gicv3::G1NS) ?
109713531Sjairo.balart@metempsy.com              GIC_MIN_BPR_NS : GIC_MIN_BPR;
109813531Sjairo.balart@metempsy.com          val &= 0x7;
109913531Sjairo.balart@metempsy.com
110013531Sjairo.balart@metempsy.com          if (val < min_val) {
110113531Sjairo.balart@metempsy.com              val = min_val;
110213531Sjairo.balart@metempsy.com          }
110313531Sjairo.balart@metempsy.com
110413531Sjairo.balart@metempsy.com          break;
110513531Sjairo.balart@metempsy.com      }
110613531Sjairo.balart@metempsy.com
110713760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 0
110813531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR0_EL1:
110913760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 1
111013531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
111113531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
111213531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
111313760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
111413531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
111513531Sjairo.balart@metempsy.com
111613760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
111713760Sjairo.balart@metempsy.com              // BPR0 + 1 saturated to 7, WI
111813531Sjairo.balart@metempsy.com              return;
111913531Sjairo.balart@metempsy.com          }
112013531Sjairo.balart@metempsy.com
112113531Sjairo.balart@metempsy.com          uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
112213531Sjairo.balart@metempsy.com
112313531Sjairo.balart@metempsy.com          if (group != Gicv3::G0S) {
112413531Sjairo.balart@metempsy.com              min_VPBR++;
112513531Sjairo.balart@metempsy.com          }
112613531Sjairo.balart@metempsy.com
112713531Sjairo.balart@metempsy.com          if (val < min_VPBR) {
112813531Sjairo.balart@metempsy.com              val = min_VPBR;
112913531Sjairo.balart@metempsy.com          }
113013531Sjairo.balart@metempsy.com
113113531Sjairo.balart@metempsy.com          if (group == Gicv3::G0S) {
113213760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = val;
113313531Sjairo.balart@metempsy.com          } else {
113413760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = val;
113513531Sjairo.balart@metempsy.com          }
113613531Sjairo.balart@metempsy.com
113713531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
113813531Sjairo.balart@metempsy.com          do_virtual_update = true;
113913531Sjairo.balart@metempsy.com          break;
114013531Sjairo.balart@metempsy.com      }
114113531Sjairo.balart@metempsy.com
114213760Sjairo.balart@metempsy.com      // Control Register EL1
114313531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
114413760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: {
114513760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
114613531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
114713531Sjairo.balart@metempsy.com          }
114813531Sjairo.balart@metempsy.com
114913531Sjairo.balart@metempsy.com          /*
115013760Sjairo.balart@metempsy.com           * ExtRange is RO.
115113531Sjairo.balart@metempsy.com           * RSS is RO.
115213531Sjairo.balart@metempsy.com           * A3V is RO.
115313531Sjairo.balart@metempsy.com           * SEIS is RO.
115413531Sjairo.balart@metempsy.com           * IDbits is RO.
115513531Sjairo.balart@metempsy.com           * PRIbits is RO.
115613531Sjairo.balart@metempsy.com           */
115713760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
115813760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1 =
115913760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
116013760Sjairo.balart@metempsy.com
116113760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 =
116213760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
116313760Sjairo.balart@metempsy.com
116413760Sjairo.balart@metempsy.com          // The following could be refactored but it is following
116513760Sjairo.balart@metempsy.com          // spec description section 9.2.6 point by point.
116613760Sjairo.balart@metempsy.com
116713760Sjairo.balart@metempsy.com          // PMHE
116813760Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
116913760Sjairo.balart@metempsy.com              // PMHE is alias of ICC_CTLR_EL3.PMHE
117013760Sjairo.balart@metempsy.com
117113760Sjairo.balart@metempsy.com              if (distributor->DS == 0) {
117213760Sjairo.balart@metempsy.com                  // PMHE is RO
117313760Sjairo.balart@metempsy.com              } else if (distributor->DS == 1) {
117413760Sjairo.balart@metempsy.com                  // PMHE is RW
117513760Sjairo.balart@metempsy.com                  icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
117613760Sjairo.balart@metempsy.com                  icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
117713760Sjairo.balart@metempsy.com              }
117813531Sjairo.balart@metempsy.com          } else {
117913760Sjairo.balart@metempsy.com              // PMHE is RW (by implementation choice)
118013760Sjairo.balart@metempsy.com              icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
118113531Sjairo.balart@metempsy.com          }
118213531Sjairo.balart@metempsy.com
118313760Sjairo.balart@metempsy.com          // EOImode
118413760Sjairo.balart@metempsy.com          icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
118513760Sjairo.balart@metempsy.com
118613760Sjairo.balart@metempsy.com          if (inSecureState()) {
118713760Sjairo.balart@metempsy.com              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
118813760Sjairo.balart@metempsy.com              icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
118913760Sjairo.balart@metempsy.com          } else {
119013760Sjairo.balart@metempsy.com              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
119113760Sjairo.balart@metempsy.com              icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
119213760Sjairo.balart@metempsy.com          }
119313760Sjairo.balart@metempsy.com
119413760Sjairo.balart@metempsy.com          // CBPR
119513760Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
119613760Sjairo.balart@metempsy.com              // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
119713760Sjairo.balart@metempsy.com
119813760Sjairo.balart@metempsy.com              if (distributor->DS == 0) {
119913760Sjairo.balart@metempsy.com                  // CBPR is RO
120013760Sjairo.balart@metempsy.com              } else {
120113760Sjairo.balart@metempsy.com                  // CBPR is RW
120213760Sjairo.balart@metempsy.com                  icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
120313760Sjairo.balart@metempsy.com
120413760Sjairo.balart@metempsy.com                  if (inSecureState()) {
120513760Sjairo.balart@metempsy.com                      icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
120613760Sjairo.balart@metempsy.com                  } else {
120713760Sjairo.balart@metempsy.com                      icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
120813760Sjairo.balart@metempsy.com                  }
120913760Sjairo.balart@metempsy.com              }
121013760Sjairo.balart@metempsy.com          } else {
121113760Sjairo.balart@metempsy.com              // CBPR is RW
121213760Sjairo.balart@metempsy.com              icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
121313760Sjairo.balart@metempsy.com          }
121413760Sjairo.balart@metempsy.com
121513760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);
121613760Sjairo.balart@metempsy.com
121713760Sjairo.balart@metempsy.com          val = icc_ctlr_el1;
121813531Sjairo.balart@metempsy.com          break;
121913531Sjairo.balart@metempsy.com      }
122013531Sjairo.balart@metempsy.com
122113760Sjairo.balart@metempsy.com      // Virtual Control Register
122213531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
122313760Sjairo.balart@metempsy.com         ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
122413760Sjairo.balart@metempsy.com         ICV_CTLR_EL1 icv_ctlr_el1 =
122513760Sjairo.balart@metempsy.com             isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
122613760Sjairo.balart@metempsy.com         icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
122713760Sjairo.balart@metempsy.com         icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
122813760Sjairo.balart@metempsy.com         val = icv_ctlr_el1;
122913760Sjairo.balart@metempsy.com
123013760Sjairo.balart@metempsy.com         // Aliases
123113760Sjairo.balart@metempsy.com         // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
123213760Sjairo.balart@metempsy.com         // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
123313760Sjairo.balart@metempsy.com         ICH_VMCR_EL2 ich_vmcr_el2 =
123413760Sjairo.balart@metempsy.com             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
123513760Sjairo.balart@metempsy.com         ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
123613760Sjairo.balart@metempsy.com         ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
123713760Sjairo.balart@metempsy.com         isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
123813760Sjairo.balart@metempsy.com         break;
123913760Sjairo.balart@metempsy.com      }
124013760Sjairo.balart@metempsy.com
124113760Sjairo.balart@metempsy.com      // Control Register EL3
124213760Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
124313760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
124413760Sjairo.balart@metempsy.com          /*
124513760Sjairo.balart@metempsy.com           * ExtRange is RO.
124613760Sjairo.balart@metempsy.com           * RSS is RO.
124713760Sjairo.balart@metempsy.com           * nDS is RO.
124813760Sjairo.balart@metempsy.com           * A3V is RO.
124913760Sjairo.balart@metempsy.com           * SEIS is RO.
125013760Sjairo.balart@metempsy.com           * IDbits is RO.
125113760Sjairo.balart@metempsy.com           * PRIbits is RO.
125213760Sjairo.balart@metempsy.com           * PMHE is RAO/WI, priority-based routing is always used.
125313760Sjairo.balart@metempsy.com           */
125413760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
125513760Sjairo.balart@metempsy.com
125613760Sjairo.balart@metempsy.com          // Aliases
125713760Sjairo.balart@metempsy.com          if (haveEL(EL3))
125813760Sjairo.balart@metempsy.com          {
125913760Sjairo.balart@metempsy.com              ICC_CTLR_EL1 icc_ctlr_el1_s =
126013760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
126113760Sjairo.balart@metempsy.com              ICC_CTLR_EL1 icc_ctlr_el1_ns =
126213760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
126313760Sjairo.balart@metempsy.com
126413760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(NS).EOImode is an alias of
126513760Sjairo.balart@metempsy.com              // ICC_CTLR_EL3.EOImode_EL1NS
126613760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
126713760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(S).EOImode is an alias of
126813760Sjairo.balart@metempsy.com              // ICC_CTLR_EL3.EOImode_EL1S
126913760Sjairo.balart@metempsy.com              icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
127013760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
127113760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
127213760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
127313760Sjairo.balart@metempsy.com              icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
127413760Sjairo.balart@metempsy.com
127513760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
127613760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
127713760Sjairo.balart@metempsy.com                                      icc_ctlr_el1_ns);
127813760Sjairo.balart@metempsy.com          }
127913760Sjairo.balart@metempsy.com
128013760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 =
128113760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
128213760Sjairo.balart@metempsy.com
128313760Sjairo.balart@metempsy.com          icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
128413760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
128513760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
128613760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
128713760Sjairo.balart@metempsy.com          icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
128813760Sjairo.balart@metempsy.com          icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
128913760Sjairo.balart@metempsy.com
129013760Sjairo.balart@metempsy.com          val = icc_ctlr_el3;
129113531Sjairo.balart@metempsy.com          break;
129213531Sjairo.balart@metempsy.com      }
129313531Sjairo.balart@metempsy.com
129413760Sjairo.balart@metempsy.com      // Priority Mask Register
129513531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
129613760Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1: {
129713760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
129814057Sgiacomo.travaglini@arm.com              return setMiscReg(MISCREG_ICV_PMR_EL1, val);
129913531Sjairo.balart@metempsy.com          }
130013531Sjairo.balart@metempsy.com
130113531Sjairo.balart@metempsy.com          val &= 0xff;
130213531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
130313531Sjairo.balart@metempsy.com
130413531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
130513760Sjairo.balart@metempsy.com              // Spec section 4.8.1
130613760Sjairo.balart@metempsy.com              // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
130713580Sgabeblack@google.com              RegVal old_icc_pmr_el1 =
130813531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);
130913531Sjairo.balart@metempsy.com
131013531Sjairo.balart@metempsy.com              if (!(old_icc_pmr_el1 & 0x80)) {
131113760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
131213760Sjairo.balart@metempsy.com                  // 0x00-0x7F then WI
131313531Sjairo.balart@metempsy.com                  return;
131413531Sjairo.balart@metempsy.com              }
131513531Sjairo.balart@metempsy.com
131613760Sjairo.balart@metempsy.com              // If the current priority mask value is in the range of
131713760Sjairo.balart@metempsy.com              // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
131813760Sjairo.balart@metempsy.com              // based on the Non-secure read of the priority mask value
131913760Sjairo.balart@metempsy.com              // written to the register.
132013760Sjairo.balart@metempsy.com
132113531Sjairo.balart@metempsy.com              val = (val >> 1) | 0x80;
132213531Sjairo.balart@metempsy.com          }
132313531Sjairo.balart@metempsy.com
132413531Sjairo.balart@metempsy.com          val &= ~0U << (8 - PRIORITY_BITS);
132513531Sjairo.balart@metempsy.com          break;
132613531Sjairo.balart@metempsy.com      }
132713531Sjairo.balart@metempsy.com
132814057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
132914057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
133014057Sgiacomo.travaglini@arm.com             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
133114057Sgiacomo.travaglini@arm.com          ich_vmcr_el2.VPMR = val & 0xff;
133214057Sgiacomo.travaglini@arm.com
133314057Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
133414057Sgiacomo.travaglini@arm.com          virtualUpdate();
133514057Sgiacomo.travaglini@arm.com          return;
133614057Sgiacomo.travaglini@arm.com      }
133714057Sgiacomo.travaglini@arm.com
133813760Sjairo.balart@metempsy.com      // Interrupt Group 0 Enable Register EL1
133913760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
134013760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
134113760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
134213760Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
134313760Sjairo.balart@metempsy.com          }
134413760Sjairo.balart@metempsy.com
134513760Sjairo.balart@metempsy.com          break;
134613760Sjairo.balart@metempsy.com      }
134713760Sjairo.balart@metempsy.com
134813760Sjairo.balart@metempsy.com      // Virtual Interrupt Group 0 Enable register
134913760Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN0_EL1: {
135013760Sjairo.balart@metempsy.com          bool enable = val & 0x1;
135113760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
135213760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
135313760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG0 = enable;
135413740Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
135513740Sgiacomo.travaglini@arm.com          virtualUpdate();
135613740Sgiacomo.travaglini@arm.com          return;
135713740Sgiacomo.travaglini@arm.com      }
135813740Sgiacomo.travaglini@arm.com
135913760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL1
136013760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
136113760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
136213760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
136313760Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
136413760Sjairo.balart@metempsy.com          }
136513760Sjairo.balart@metempsy.com
136613760Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
136713760Sjairo.balart@metempsy.com              ICC_IGRPEN1_EL1 icc_igrpen1_el1 = val;
136813760Sjairo.balart@metempsy.com              ICC_IGRPEN1_EL3 icc_igrpen1_el3 =
136913760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3);
137013760Sjairo.balart@metempsy.com
137113760Sjairo.balart@metempsy.com              if (inSecureState()) {
137213760Sjairo.balart@metempsy.com                  // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1S
137313760Sjairo.balart@metempsy.com                  icc_igrpen1_el3.EnableGrp1S = icc_igrpen1_el1.Enable;
137413760Sjairo.balart@metempsy.com              } else {
137513760Sjairo.balart@metempsy.com                  // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1NS
137613760Sjairo.balart@metempsy.com                  icc_igrpen1_el3.EnableGrp1NS = icc_igrpen1_el1.Enable;
137713760Sjairo.balart@metempsy.com              }
137813760Sjairo.balart@metempsy.com
137913760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3,
138013760Sjairo.balart@metempsy.com                                      icc_igrpen1_el3);
138113531Sjairo.balart@metempsy.com          }
138213531Sjairo.balart@metempsy.com
138313531Sjairo.balart@metempsy.com          break;
138413531Sjairo.balart@metempsy.com      }
138513531Sjairo.balart@metempsy.com
138613760Sjairo.balart@metempsy.com      // Virtual Interrupt Group 1 Enable register
138713760Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN1_EL1: {
138813531Sjairo.balart@metempsy.com          bool enable = val & 0x1;
138913760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
139013531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
139113760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG1 = enable;
139213531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
139313531Sjairo.balart@metempsy.com          virtualUpdate();
139413531Sjairo.balart@metempsy.com          return;
139513531Sjairo.balart@metempsy.com      }
139613531Sjairo.balart@metempsy.com
139713760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register
139813760Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
139913760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL3: {
140013760Sjairo.balart@metempsy.com          ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
140113760Sjairo.balart@metempsy.com          ICC_IGRPEN1_EL1 icc_igrpen1_el1 =
140213760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1);
140313760Sjairo.balart@metempsy.com
140413760Sjairo.balart@metempsy.com          if (inSecureState()) {
140513760Sjairo.balart@metempsy.com              // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1S
140613760Sjairo.balart@metempsy.com              icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1S;
140713760Sjairo.balart@metempsy.com          } else {
140813760Sjairo.balart@metempsy.com              // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1NS
140913760Sjairo.balart@metempsy.com              icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1NS;
141013531Sjairo.balart@metempsy.com          }
141113531Sjairo.balart@metempsy.com
141213760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1, icc_igrpen1_el1);
141313531Sjairo.balart@metempsy.com          break;
141413531Sjairo.balart@metempsy.com      }
141513531Sjairo.balart@metempsy.com
141613760Sjairo.balart@metempsy.com      // Software Generated Interrupt Group 0 Register
141713531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R:
141813531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R_EL1:
141913531Sjairo.balart@metempsy.com
142013760Sjairo.balart@metempsy.com      // Software Generated Interrupt Group 1 Register
142113531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI1R:
142213531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI1R_EL1:
142313531Sjairo.balart@metempsy.com
142413760Sjairo.balart@metempsy.com      // Alias Software Generated Interrupt Group 1 Register
142513531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R:
142613531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R_EL1: {
142713531Sjairo.balart@metempsy.com          bool ns = !inSecureState();
142813531Sjairo.balart@metempsy.com          Gicv3::GroupId group;
142913531Sjairo.balart@metempsy.com
143013531Sjairo.balart@metempsy.com          if (misc_reg == MISCREG_ICC_SGI1R_EL1) {
143113531Sjairo.balart@metempsy.com              group = ns ? Gicv3::G1NS : Gicv3::G1S;
143213531Sjairo.balart@metempsy.com          } else if (misc_reg == MISCREG_ICC_ASGI1R_EL1) {
143313531Sjairo.balart@metempsy.com              group = ns ? Gicv3::G1S : Gicv3::G1NS;
143413531Sjairo.balart@metempsy.com          } else {
143513531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
143613531Sjairo.balart@metempsy.com          }
143713531Sjairo.balart@metempsy.com
143813531Sjairo.balart@metempsy.com          if (distributor->DS && group == Gicv3::G1S) {
143913531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
144013531Sjairo.balart@metempsy.com          }
144113531Sjairo.balart@metempsy.com
144213531Sjairo.balart@metempsy.com          uint8_t aff3 = bits(val, 55, 48);
144313531Sjairo.balart@metempsy.com          uint8_t aff2 = bits(val, 39, 32);
144413531Sjairo.balart@metempsy.com          uint8_t aff1 = bits(val, 23, 16);;
144513531Sjairo.balart@metempsy.com          uint16_t target_list = bits(val, 15, 0);
144613531Sjairo.balart@metempsy.com          uint32_t int_id = bits(val, 27, 24);
144713531Sjairo.balart@metempsy.com          bool irm = bits(val, 40, 40);
144813531Sjairo.balart@metempsy.com          uint8_t rs = bits(val, 47, 44);
144913531Sjairo.balart@metempsy.com
145013531Sjairo.balart@metempsy.com          for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
145113531Sjairo.balart@metempsy.com              Gicv3Redistributor * redistributor_i =
145213531Sjairo.balart@metempsy.com                  gic->getRedistributor(i);
145313531Sjairo.balart@metempsy.com              uint32_t affinity_i = redistributor_i->getAffinity();
145413531Sjairo.balart@metempsy.com
145513531Sjairo.balart@metempsy.com              if (irm) {
145613531Sjairo.balart@metempsy.com                  // Interrupts routed to all PEs in the system,
145713531Sjairo.balart@metempsy.com                  // excluding "self"
145813531Sjairo.balart@metempsy.com                  if (affinity_i == redistributor->getAffinity()) {
145913531Sjairo.balart@metempsy.com                      continue;
146013531Sjairo.balart@metempsy.com                  }
146113531Sjairo.balart@metempsy.com              } else {
146213531Sjairo.balart@metempsy.com                  // Interrupts routed to the PEs specified by
146313531Sjairo.balart@metempsy.com                  // Aff3.Aff2.Aff1.<target list>
146413531Sjairo.balart@metempsy.com                  if ((affinity_i >> 8) !=
146513760Sjairo.balart@metempsy.com                      ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
146613531Sjairo.balart@metempsy.com                      continue;
146713531Sjairo.balart@metempsy.com                  }
146813531Sjairo.balart@metempsy.com
146913531Sjairo.balart@metempsy.com                  uint8_t aff0_i = bits(affinity_i, 7, 0);
147013531Sjairo.balart@metempsy.com
147113531Sjairo.balart@metempsy.com                  if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
147213760Sjairo.balart@metempsy.com                      ((0x1 << (aff0_i - rs * 16)) & target_list))) {
147313531Sjairo.balart@metempsy.com                      continue;
147413531Sjairo.balart@metempsy.com                  }
147513531Sjairo.balart@metempsy.com              }
147613531Sjairo.balart@metempsy.com
147713531Sjairo.balart@metempsy.com              redistributor_i->sendSGI(int_id, group, ns);
147813531Sjairo.balart@metempsy.com          }
147913531Sjairo.balart@metempsy.com
148013531Sjairo.balart@metempsy.com          break;
148113531Sjairo.balart@metempsy.com      }
148213531Sjairo.balart@metempsy.com
148313760Sjairo.balart@metempsy.com      // System Register Enable Register EL1
148413531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
148513760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1:
148613760Sjairo.balart@metempsy.com      // System Register Enable Register EL2
148713531Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
148813760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2:
148913760Sjairo.balart@metempsy.com      // System Register Enable Register EL3
149013531Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
149113760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3:
149213760Sjairo.balart@metempsy.com        // All bits are RAO/WI
149313760Sjairo.balart@metempsy.com        return;
149413760Sjairo.balart@metempsy.com
149513760Sjairo.balart@metempsy.com      // Hyp Control Register
149613760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
149713760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2: {
149813760Sjairo.balart@metempsy.com        ICH_HCR_EL2 requested_ich_hcr_el2 = val;
149913760Sjairo.balart@metempsy.com        ICH_HCR_EL2 ich_hcr_el2 =
150013760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
150113760Sjairo.balart@metempsy.com
150213760Sjairo.balart@metempsy.com        if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
150313760Sjairo.balart@metempsy.com        {
150413760Sjairo.balart@metempsy.com            // EOIcount - Permitted behaviors are:
150513760Sjairo.balart@metempsy.com            // - Increment EOIcount.
150613760Sjairo.balart@metempsy.com            // - Leave EOIcount unchanged.
150713760Sjairo.balart@metempsy.com            ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
150813531Sjairo.balart@metempsy.com        }
150913531Sjairo.balart@metempsy.com
151013760Sjairo.balart@metempsy.com        ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
151113760Sjairo.balart@metempsy.com        ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
151213760Sjairo.balart@metempsy.com        ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
151313760Sjairo.balart@metempsy.com        ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
151413760Sjairo.balart@metempsy.com        ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
151513760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
151613760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
151713760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
151813760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
151913760Sjairo.balart@metempsy.com        ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
152013760Sjairo.balart@metempsy.com        ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
152113760Sjairo.balart@metempsy.com        ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
152213760Sjairo.balart@metempsy.com        ich_hcr_el2.En = requested_ich_hcr_el2.En;
152313760Sjairo.balart@metempsy.com        val = ich_hcr_el2;
152413531Sjairo.balart@metempsy.com        do_virtual_update = true;
152513531Sjairo.balart@metempsy.com        break;
152613760Sjairo.balart@metempsy.com      }
152713760Sjairo.balart@metempsy.com
152813760Sjairo.balart@metempsy.com      // List Registers
152913760Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
153013531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
153113760Sjairo.balart@metempsy.com        ICH_LRC requested_ich_lrc = val;
153213760Sjairo.balart@metempsy.com        ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
153313760Sjairo.balart@metempsy.com
153413760Sjairo.balart@metempsy.com        ich_lrc.State = requested_ich_lrc.State;
153513760Sjairo.balart@metempsy.com        ich_lrc.HW = requested_ich_lrc.HW;
153613760Sjairo.balart@metempsy.com        ich_lrc.Group = requested_ich_lrc.Group;
153713760Sjairo.balart@metempsy.com
153813760Sjairo.balart@metempsy.com        // Priority, bits [23:16]
153913760Sjairo.balart@metempsy.com        // At least five bits must be implemented.
154013760Sjairo.balart@metempsy.com        // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
154113760Sjairo.balart@metempsy.com        // We implement 5 bits.
154213760Sjairo.balart@metempsy.com        ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
154313760Sjairo.balart@metempsy.com                           (ich_lrc.Priority & 0x07);
154413760Sjairo.balart@metempsy.com
154513760Sjairo.balart@metempsy.com        // pINTID, bits [12:0]
154613760Sjairo.balart@metempsy.com        // When ICH_LR<n>.HW is 0 this field has the following meaning:
154713760Sjairo.balart@metempsy.com        // - Bits[12:10] : RES0.
154813760Sjairo.balart@metempsy.com        // - Bit[9] : EOI.
154913760Sjairo.balart@metempsy.com        // - Bits[8:0] : RES0.
155013760Sjairo.balart@metempsy.com        // When ICH_LR<n>.HW is 1:
155113760Sjairo.balart@metempsy.com        // - This field is only required to implement enough bits to hold a
155213760Sjairo.balart@metempsy.com        // valid value for the implemented INTID size. Any unused higher
155313760Sjairo.balart@metempsy.com        // order bits are RES0.
155413760Sjairo.balart@metempsy.com        if (requested_ich_lrc.HW == 0) {
155513760Sjairo.balart@metempsy.com            ich_lrc.EOI = requested_ich_lrc.EOI;
155613760Sjairo.balart@metempsy.com        } else {
155713760Sjairo.balart@metempsy.com            ich_lrc.pINTID = requested_ich_lrc.pINTID;
155813531Sjairo.balart@metempsy.com        }
155913531Sjairo.balart@metempsy.com
156013760Sjairo.balart@metempsy.com        val = ich_lrc;
156113760Sjairo.balart@metempsy.com        do_virtual_update = true;
156213760Sjairo.balart@metempsy.com        break;
156313760Sjairo.balart@metempsy.com      }
156413760Sjairo.balart@metempsy.com
156513760Sjairo.balart@metempsy.com      // List Registers
156613531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
156713531Sjairo.balart@metempsy.com          // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
156813580Sgabeblack@google.com          RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
156913531Sjairo.balart@metempsy.com          val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
157013531Sjairo.balart@metempsy.com          do_virtual_update = true;
157113531Sjairo.balart@metempsy.com          break;
157213531Sjairo.balart@metempsy.com      }
157313531Sjairo.balart@metempsy.com
157413760Sjairo.balart@metempsy.com      // List Registers
157513531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
157613760Sjairo.balart@metempsy.com          ICH_LR_EL2 requested_ich_lr_el2 = val;
157713760Sjairo.balart@metempsy.com          ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
157813760Sjairo.balart@metempsy.com
157913760Sjairo.balart@metempsy.com          ich_lr_el2.State = requested_ich_lr_el2.State;
158013760Sjairo.balart@metempsy.com          ich_lr_el2.HW = requested_ich_lr_el2.HW;
158113760Sjairo.balart@metempsy.com          ich_lr_el2.Group = requested_ich_lr_el2.Group;
158213760Sjairo.balart@metempsy.com
158313760Sjairo.balart@metempsy.com          // Priority, bits [55:48]
158413760Sjairo.balart@metempsy.com          // At least five bits must be implemented.
158513760Sjairo.balart@metempsy.com          // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
158613760Sjairo.balart@metempsy.com          // We implement 5 bits.
158713760Sjairo.balart@metempsy.com          ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
158813760Sjairo.balart@metempsy.com                                (ich_lr_el2.Priority & 0x07);
158913760Sjairo.balart@metempsy.com
159013760Sjairo.balart@metempsy.com          // pINTID, bits [44:32]
159113760Sjairo.balart@metempsy.com          // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
159213760Sjairo.balart@metempsy.com          // - Bits[44:42] : RES0.
159313760Sjairo.balart@metempsy.com          // - Bit[41] : EOI.
159413760Sjairo.balart@metempsy.com          // - Bits[40:32] : RES0.
159513760Sjairo.balart@metempsy.com          // When ICH_LR<n>_EL2.HW is 1:
159613760Sjairo.balart@metempsy.com          // - This field is only required to implement enough bits to hold a
159713760Sjairo.balart@metempsy.com          // valid value for the implemented INTID size. Any unused higher
159813760Sjairo.balart@metempsy.com          // order bits are RES0.
159913760Sjairo.balart@metempsy.com          if (requested_ich_lr_el2.HW == 0) {
160013760Sjairo.balart@metempsy.com              ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
160113760Sjairo.balart@metempsy.com          } else {
160213760Sjairo.balart@metempsy.com              ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
160313760Sjairo.balart@metempsy.com          }
160413760Sjairo.balart@metempsy.com
160513760Sjairo.balart@metempsy.com          // vINTID, bits [31:0]
160613760Sjairo.balart@metempsy.com          // It is IMPLEMENTATION DEFINED how many bits are implemented,
160713760Sjairo.balart@metempsy.com          // though at least 16 bits must be implemented.
160813760Sjairo.balart@metempsy.com          // Unimplemented bits are RES0.
160913760Sjairo.balart@metempsy.com          ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
161013760Sjairo.balart@metempsy.com
161113760Sjairo.balart@metempsy.com          val = ich_lr_el2;
161213531Sjairo.balart@metempsy.com          do_virtual_update = true;
161313531Sjairo.balart@metempsy.com          break;
161413531Sjairo.balart@metempsy.com      }
161513531Sjairo.balart@metempsy.com
161613760Sjairo.balart@metempsy.com      // Virtual Machine Control Register
161713531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
161813531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2: {
161913760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
162013760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
162113760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
162213760Sjairo.balart@metempsy.com          ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
162313531Sjairo.balart@metempsy.com          uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
162413760Sjairo.balart@metempsy.com
162513760Sjairo.balart@metempsy.com          if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
162613760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = min_vpr0;
162713760Sjairo.balart@metempsy.com          } else {
162813760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
162913760Sjairo.balart@metempsy.com          }
163013760Sjairo.balart@metempsy.com
163113531Sjairo.balart@metempsy.com          uint8_t min_vpr1 = min_vpr0 + 1;
163213760Sjairo.balart@metempsy.com
163313760Sjairo.balart@metempsy.com          if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
163413760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = min_vpr1;
163513760Sjairo.balart@metempsy.com          } else {
163613760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
163713760Sjairo.balart@metempsy.com          }
163813760Sjairo.balart@metempsy.com
163913760Sjairo.balart@metempsy.com          ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
164013760Sjairo.balart@metempsy.com          ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
164113760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
164213760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
164313760Sjairo.balart@metempsy.com          val = ich_vmcr_el2;
164413531Sjairo.balart@metempsy.com          break;
164513531Sjairo.balart@metempsy.com      }
164613531Sjairo.balart@metempsy.com
164713760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 0 Registers
164813531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0 ... MISCREG_ICH_AP0R3:
164913531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_AP0R3_EL2:
165013760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 1 Registers
165113531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0 ... MISCREG_ICH_AP1R3:
165213531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0_EL2 ... MISCREG_ICH_AP1R3_EL2:
165313531Sjairo.balart@metempsy.com        break;
165413531Sjairo.balart@metempsy.com
165513531Sjairo.balart@metempsy.com      default:
165613760Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
165713760Sjairo.balart@metempsy.com              misc_reg, miscRegName[misc_reg]);
165813531Sjairo.balart@metempsy.com    }
165913531Sjairo.balart@metempsy.com
166013531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(misc_reg, val);
166113531Sjairo.balart@metempsy.com
166213531Sjairo.balart@metempsy.com    if (do_virtual_update) {
166313531Sjairo.balart@metempsy.com        virtualUpdate();
166413531Sjairo.balart@metempsy.com    }
166513531Sjairo.balart@metempsy.com}
166613531Sjairo.balart@metempsy.com
166713531Sjairo.balart@metempsy.comint
166813760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualFindActive(uint32_t int_id) const
166913531Sjairo.balart@metempsy.com{
167013531Sjairo.balart@metempsy.com    for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
167113760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
167213531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
167313760Sjairo.balart@metempsy.com
167413760Sjairo.balart@metempsy.com        if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
167513760Sjairo.balart@metempsy.com             (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
167613760Sjairo.balart@metempsy.com            (ich_lr_el2.vINTID == int_id)) {
167713531Sjairo.balart@metempsy.com            return lr_idx;
167813531Sjairo.balart@metempsy.com        }
167913531Sjairo.balart@metempsy.com    }
168013531Sjairo.balart@metempsy.com
168113531Sjairo.balart@metempsy.com    return -1;
168213531Sjairo.balart@metempsy.com}
168313531Sjairo.balart@metempsy.com
168413531Sjairo.balart@metempsy.comuint32_t
168513760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR0() const
168613531Sjairo.balart@metempsy.com{
168713531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff) {
168813531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
168913531Sjairo.balart@metempsy.com    }
169013531Sjairo.balart@metempsy.com
169113531Sjairo.balart@metempsy.com    bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
169213531Sjairo.balart@metempsy.com
169313531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
169413760Sjairo.balart@metempsy.com        // interrupt for the other state pending
169513531Sjairo.balart@metempsy.com        return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
169613531Sjairo.balart@metempsy.com    }
169713531Sjairo.balart@metempsy.com
169813531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
169913531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
170013531Sjairo.balart@metempsy.com    }
170113531Sjairo.balart@metempsy.com
170213531Sjairo.balart@metempsy.com    if (irq_is_secure && !inSecureState()) {
170313531Sjairo.balart@metempsy.com        // Secure interrupts not visible in Non-secure
170413531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
170513531Sjairo.balart@metempsy.com    }
170613531Sjairo.balart@metempsy.com
170713531Sjairo.balart@metempsy.com    return hppi.intid;
170813531Sjairo.balart@metempsy.com}
170913531Sjairo.balart@metempsy.com
171013531Sjairo.balart@metempsy.comuint32_t
171113760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR1() const
171213531Sjairo.balart@metempsy.com{
171313531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff) {
171413531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
171513531Sjairo.balart@metempsy.com    }
171613531Sjairo.balart@metempsy.com
171713760Sjairo.balart@metempsy.com    ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
171813760Sjairo.balart@metempsy.com    if ((currEL() == EL3) && icc_ctlr_el3.RM) {
171913531Sjairo.balart@metempsy.com        if (hppi.group == Gicv3::G0S) {
172013531Sjairo.balart@metempsy.com            return Gicv3::INTID_SECURE;
172113531Sjairo.balart@metempsy.com        } else if (hppi.group == Gicv3::G1NS) {
172213531Sjairo.balart@metempsy.com            return Gicv3::INTID_NONSECURE;
172313531Sjairo.balart@metempsy.com        }
172413531Sjairo.balart@metempsy.com    }
172513531Sjairo.balart@metempsy.com
172613531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G0S) {
172713531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
172813531Sjairo.balart@metempsy.com    }
172913531Sjairo.balart@metempsy.com
173013531Sjairo.balart@metempsy.com    bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
173113531Sjairo.balart@metempsy.com
173213531Sjairo.balart@metempsy.com    if (irq_is_secure) {
173313531Sjairo.balart@metempsy.com        if (!inSecureState()) {
173413531Sjairo.balart@metempsy.com            // Secure interrupts not visible in Non-secure
173513531Sjairo.balart@metempsy.com            return Gicv3::INTID_SPURIOUS;
173613531Sjairo.balart@metempsy.com        }
173713531Sjairo.balart@metempsy.com    } else if (!isEL3OrMon() && inSecureState()) {
173813531Sjairo.balart@metempsy.com        // Group 1 non-secure interrupts not visible in Secure EL1
173913531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
174013531Sjairo.balart@metempsy.com    }
174113531Sjairo.balart@metempsy.com
174213531Sjairo.balart@metempsy.com    return hppi.intid;
174313531Sjairo.balart@metempsy.com}
174413531Sjairo.balart@metempsy.com
174513531Sjairo.balart@metempsy.comvoid
174613531Sjairo.balart@metempsy.comGicv3CPUInterface::dropPriority(Gicv3::GroupId group)
174713531Sjairo.balart@metempsy.com{
174813531Sjairo.balart@metempsy.com    int apr_misc_reg;
174913580Sgabeblack@google.com    RegVal apr;
175013531Sjairo.balart@metempsy.com    apr_misc_reg = group == Gicv3::G0S ?
175113531Sjairo.balart@metempsy.com                   MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
175213531Sjairo.balart@metempsy.com    apr = isa->readMiscRegNoEffect(apr_misc_reg);
175313531Sjairo.balart@metempsy.com
175413531Sjairo.balart@metempsy.com    if (apr) {
175513531Sjairo.balart@metempsy.com        apr &= apr - 1;
175613531Sjairo.balart@metempsy.com        isa->setMiscRegNoEffect(apr_misc_reg, apr);
175713531Sjairo.balart@metempsy.com    }
175813531Sjairo.balart@metempsy.com
175913531Sjairo.balart@metempsy.com    update();
176013531Sjairo.balart@metempsy.com}
176113531Sjairo.balart@metempsy.com
176213531Sjairo.balart@metempsy.comuint8_t
176313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDropPriority()
176413531Sjairo.balart@metempsy.com{
176513531Sjairo.balart@metempsy.com    int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
176613531Sjairo.balart@metempsy.com
176713531Sjairo.balart@metempsy.com    for (int i = 0; i < apr_max; i++) {
176813580Sgabeblack@google.com        RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
176913580Sgabeblack@google.com        RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
177013531Sjairo.balart@metempsy.com
177113531Sjairo.balart@metempsy.com        if (!vapr0 && !vapr1) {
177213531Sjairo.balart@metempsy.com            continue;
177313531Sjairo.balart@metempsy.com        }
177413531Sjairo.balart@metempsy.com
177513531Sjairo.balart@metempsy.com        int vapr0_count = ctz32(vapr0);
177613531Sjairo.balart@metempsy.com        int vapr1_count = ctz32(vapr1);
177713531Sjairo.balart@metempsy.com
177813531Sjairo.balart@metempsy.com        if (vapr0_count <= vapr1_count) {
177913531Sjairo.balart@metempsy.com            vapr0 &= vapr0 - 1;
178013531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
178113531Sjairo.balart@metempsy.com            return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
178213531Sjairo.balart@metempsy.com        } else {
178313531Sjairo.balart@metempsy.com            vapr1 &= vapr1 - 1;
178413531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
178513531Sjairo.balart@metempsy.com            return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
178613531Sjairo.balart@metempsy.com        }
178713531Sjairo.balart@metempsy.com    }
178813531Sjairo.balart@metempsy.com
178913531Sjairo.balart@metempsy.com    return 0xff;
179013531Sjairo.balart@metempsy.com}
179113531Sjairo.balart@metempsy.com
179213531Sjairo.balart@metempsy.comvoid
179313531Sjairo.balart@metempsy.comGicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
179413531Sjairo.balart@metempsy.com{
179513531Sjairo.balart@metempsy.com    // Update active priority registers.
179613531Sjairo.balart@metempsy.com    uint32_t prio = hppi.prio & 0xf8;
179713531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - PRIORITY_BITS);
179813531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
179913531Sjairo.balart@metempsy.com    int apr_idx = group == Gicv3::G0S ?
180013531Sjairo.balart@metempsy.com                 MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
180113580Sgabeblack@google.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
180213531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
180313531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
180413531Sjairo.balart@metempsy.com
180513531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
180613531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
180713531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
180813531Sjairo.balart@metempsy.com        redistributor->activateIRQ(int_id);
180913531Sjairo.balart@metempsy.com        redistributor->updateAndInformCPUInterface();
181013531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
181113531Sjairo.balart@metempsy.com        // SPI, distributor
181213531Sjairo.balart@metempsy.com        distributor->activateIRQ(int_id);
181313531Sjairo.balart@metempsy.com        distributor->updateAndInformCPUInterfaces();
181413923Sgiacomo.travaglini@arm.com    } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
181513923Sgiacomo.travaglini@arm.com        // LPI, Redistributor
181613923Sgiacomo.travaglini@arm.com        redistributor->setClrLPI(int_id, false);
181713531Sjairo.balart@metempsy.com    }
181813531Sjairo.balart@metempsy.com}
181913531Sjairo.balart@metempsy.com
182013531Sjairo.balart@metempsy.comvoid
182113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
182213531Sjairo.balart@metempsy.com{
182313531Sjairo.balart@metempsy.com    // Update active priority registers.
182413760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
182513531Sjairo.balart@metempsy.com            lr_idx);
182613760Sjairo.balart@metempsy.com    Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
182713760Sjairo.balart@metempsy.com    uint8_t prio = ich_lr_el.Priority & 0xf8;
182813531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
182913531Sjairo.balart@metempsy.com    int reg_no = apr_bit / 32;
183013531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
183113531Sjairo.balart@metempsy.com    int apr_idx = group == Gicv3::G0S ?
183213531Sjairo.balart@metempsy.com        MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
183313580Sgabeblack@google.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
183413531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
183513531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
183613531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
183713760Sjairo.balart@metempsy.com    ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
183813760Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
183913531Sjairo.balart@metempsy.com}
184013531Sjairo.balart@metempsy.com
184113531Sjairo.balart@metempsy.comvoid
184213531Sjairo.balart@metempsy.comGicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
184313531Sjairo.balart@metempsy.com{
184413531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
184513531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
184613531Sjairo.balart@metempsy.com        redistributor->deactivateIRQ(int_id);
184713531Sjairo.balart@metempsy.com        redistributor->updateAndInformCPUInterface();
184813531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
184913531Sjairo.balart@metempsy.com        // SPI, distributor
185013531Sjairo.balart@metempsy.com        distributor->deactivateIRQ(int_id);
185113531Sjairo.balart@metempsy.com        distributor->updateAndInformCPUInterfaces();
185213531Sjairo.balart@metempsy.com    } else {
185313923Sgiacomo.travaglini@arm.com        // LPI, redistributor, shouldn't deactivate
185413923Sgiacomo.travaglini@arm.com        redistributor->updateAndInformCPUInterface();
185513531Sjairo.balart@metempsy.com    }
185613531Sjairo.balart@metempsy.com}
185713531Sjairo.balart@metempsy.com
185813531Sjairo.balart@metempsy.comvoid
185913531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
186013531Sjairo.balart@metempsy.com{
186113760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
186213531Sjairo.balart@metempsy.com            lr_idx);
186313531Sjairo.balart@metempsy.com
186413760Sjairo.balart@metempsy.com    if (ich_lr_el2.HW) {
186513531Sjairo.balart@metempsy.com        // Deactivate the associated physical interrupt
186613760Sjairo.balart@metempsy.com        if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
186713760Sjairo.balart@metempsy.com            Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
186813760Sjairo.balart@metempsy.com                distributor->getIntGroup(ich_lr_el2.pINTID) :
186913760Sjairo.balart@metempsy.com                redistributor->getIntGroup(ich_lr_el2.pINTID);
187013760Sjairo.balart@metempsy.com            deactivateIRQ(ich_lr_el2.pINTID, group);
187113531Sjairo.balart@metempsy.com        }
187213531Sjairo.balart@metempsy.com    }
187313531Sjairo.balart@metempsy.com
187413531Sjairo.balart@metempsy.com    //  Remove the active bit
187513760Sjairo.balart@metempsy.com    ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
187613760Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
187713531Sjairo.balart@metempsy.com}
187813531Sjairo.balart@metempsy.com
187913531Sjairo.balart@metempsy.com/*
188013760Sjairo.balart@metempsy.com * Returns the priority group field for the current BPR value for the group.
188113760Sjairo.balart@metempsy.com * GroupBits() Pseudocode from spec.
188213531Sjairo.balart@metempsy.com */
188313531Sjairo.balart@metempsy.comuint32_t
188413926Sgiacomo.travaglini@arm.comGicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
188513531Sjairo.balart@metempsy.com{
188613760Sjairo.balart@metempsy.com    ICC_CTLR_EL1 icc_ctlr_el1_s =
188713760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
188813760Sjairo.balart@metempsy.com    ICC_CTLR_EL1 icc_ctlr_el1_ns =
188913760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
189013760Sjairo.balart@metempsy.com
189113760Sjairo.balart@metempsy.com    if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
189213760Sjairo.balart@metempsy.com        (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
189313531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
189413531Sjairo.balart@metempsy.com    }
189513531Sjairo.balart@metempsy.com
189613531Sjairo.balart@metempsy.com    int bpr;
189713531Sjairo.balart@metempsy.com
189813531Sjairo.balart@metempsy.com    if (group == Gicv3::G0S) {
189913926Sgiacomo.travaglini@arm.com        bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
190013531Sjairo.balart@metempsy.com    } else {
190113926Sgiacomo.travaglini@arm.com        bpr = readMiscReg(MISCREG_ICC_BPR1_EL1) & 0x7;
190213531Sjairo.balart@metempsy.com    }
190313531Sjairo.balart@metempsy.com
190413531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS) {
190513531Sjairo.balart@metempsy.com        assert(bpr > 0);
190613531Sjairo.balart@metempsy.com        bpr--;
190713531Sjairo.balart@metempsy.com    }
190813531Sjairo.balart@metempsy.com
190913531Sjairo.balart@metempsy.com    return ~0U << (bpr + 1);
191013531Sjairo.balart@metempsy.com}
191113531Sjairo.balart@metempsy.com
191213531Sjairo.balart@metempsy.comuint32_t
191313760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
191413531Sjairo.balart@metempsy.com{
191513760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 =
191613531Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
191713531Sjairo.balart@metempsy.com
191813760Sjairo.balart@metempsy.com    if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
191913531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
192013531Sjairo.balart@metempsy.com    }
192113531Sjairo.balart@metempsy.com
192213531Sjairo.balart@metempsy.com    int bpr;
192313531Sjairo.balart@metempsy.com
192413531Sjairo.balart@metempsy.com    if (group == Gicv3::G0S) {
192513760Sjairo.balart@metempsy.com        bpr = ich_vmcr_el2.VBPR0;
192613531Sjairo.balart@metempsy.com    } else {
192713760Sjairo.balart@metempsy.com        bpr = ich_vmcr_el2.VBPR1;
192813531Sjairo.balart@metempsy.com    }
192913531Sjairo.balart@metempsy.com
193013531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS) {
193113531Sjairo.balart@metempsy.com        assert(bpr > 0);
193213531Sjairo.balart@metempsy.com        bpr--;
193313531Sjairo.balart@metempsy.com    }
193413531Sjairo.balart@metempsy.com
193513531Sjairo.balart@metempsy.com    return ~0U << (bpr + 1);
193613531Sjairo.balart@metempsy.com}
193713531Sjairo.balart@metempsy.com
193813531Sjairo.balart@metempsy.combool
193913760Sjairo.balart@metempsy.comGicv3CPUInterface::isEOISplitMode() const
194013531Sjairo.balart@metempsy.com{
194113531Sjairo.balart@metempsy.com    if (isEL3OrMon()) {
194213760Sjairo.balart@metempsy.com        ICC_CTLR_EL3 icc_ctlr_el3 =
194313760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
194413760Sjairo.balart@metempsy.com        return icc_ctlr_el3.EOImode_EL3;
194513531Sjairo.balart@metempsy.com    } else {
194613760Sjairo.balart@metempsy.com        ICC_CTLR_EL1 icc_ctlr_el1 =
194713760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
194813760Sjairo.balart@metempsy.com        return icc_ctlr_el1.EOImode;
194913531Sjairo.balart@metempsy.com    }
195013531Sjairo.balart@metempsy.com}
195113531Sjairo.balart@metempsy.com
195213531Sjairo.balart@metempsy.combool
195313760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIsEOISplitMode() const
195413531Sjairo.balart@metempsy.com{
195513760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
195613760Sjairo.balart@metempsy.com    return ich_vmcr_el2.VEOIM;
195713531Sjairo.balart@metempsy.com}
195813531Sjairo.balart@metempsy.com
195913531Sjairo.balart@metempsy.comint
196013760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActiveGroup() const
196113531Sjairo.balart@metempsy.com{
196213531Sjairo.balart@metempsy.com    int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
196313531Sjairo.balart@metempsy.com    int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
196413531Sjairo.balart@metempsy.com    int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));
196513531Sjairo.balart@metempsy.com
196613531Sjairo.balart@metempsy.com    if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
196713531Sjairo.balart@metempsy.com        return Gicv3::G1NS;
196813531Sjairo.balart@metempsy.com    }
196913531Sjairo.balart@metempsy.com
197013531Sjairo.balart@metempsy.com    if (gq_ctz < g0_ctz) {
197113531Sjairo.balart@metempsy.com        return Gicv3::G1S;
197213531Sjairo.balart@metempsy.com    }
197313531Sjairo.balart@metempsy.com
197413531Sjairo.balart@metempsy.com    if (g0_ctz < 32) {
197513531Sjairo.balart@metempsy.com        return Gicv3::G0S;
197613531Sjairo.balart@metempsy.com    }
197713531Sjairo.balart@metempsy.com
197813531Sjairo.balart@metempsy.com    return -1;
197913531Sjairo.balart@metempsy.com}
198013531Sjairo.balart@metempsy.com
198113531Sjairo.balart@metempsy.comvoid
198213531Sjairo.balart@metempsy.comGicv3CPUInterface::update()
198313531Sjairo.balart@metempsy.com{
198413531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
198513531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
198613531Sjairo.balart@metempsy.com
198713531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
198813531Sjairo.balart@metempsy.com        /*
198913531Sjairo.balart@metempsy.com         * Secure enabled GIC sending a G1S IRQ to a secure disabled
199013531Sjairo.balart@metempsy.com         * CPU -> send G0 IRQ
199113531Sjairo.balart@metempsy.com         */
199213531Sjairo.balart@metempsy.com        hppi.group = Gicv3::G0S;
199313531Sjairo.balart@metempsy.com    }
199413531Sjairo.balart@metempsy.com
199513531Sjairo.balart@metempsy.com    if (hppiCanPreempt()) {
199613531Sjairo.balart@metempsy.com        ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
199713531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::update(): "
199813531Sjairo.balart@metempsy.com                "posting int as %d!\n", int_type);
199913531Sjairo.balart@metempsy.com        int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
200013531Sjairo.balart@metempsy.com    }
200113531Sjairo.balart@metempsy.com
200213531Sjairo.balart@metempsy.com    if (signal_IRQ) {
200313531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_IRQ);
200413531Sjairo.balart@metempsy.com    } else {
200513531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_IRQ);
200613531Sjairo.balart@metempsy.com    }
200713531Sjairo.balart@metempsy.com
200813531Sjairo.balart@metempsy.com    if (signal_FIQ) {
200913531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_FIQ);
201013531Sjairo.balart@metempsy.com    } else {
201113531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_FIQ);
201213531Sjairo.balart@metempsy.com    }
201313531Sjairo.balart@metempsy.com}
201413531Sjairo.balart@metempsy.com
201513531Sjairo.balart@metempsy.comvoid
201613531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualUpdate()
201713531Sjairo.balart@metempsy.com{
201813531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
201913531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
202013531Sjairo.balart@metempsy.com    int lr_idx = getHPPVILR();
202113531Sjairo.balart@metempsy.com
202213531Sjairo.balart@metempsy.com    if (lr_idx >= 0) {
202313760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
202413531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
202513531Sjairo.balart@metempsy.com
202613531Sjairo.balart@metempsy.com        if (hppviCanPreempt(lr_idx)) {
202713760Sjairo.balart@metempsy.com            if (ich_lr_el2.Group) {
202813531Sjairo.balart@metempsy.com                signal_IRQ = true;
202913531Sjairo.balart@metempsy.com            } else {
203013531Sjairo.balart@metempsy.com                signal_FIQ = true;
203113531Sjairo.balart@metempsy.com            }
203213531Sjairo.balart@metempsy.com        }
203313531Sjairo.balart@metempsy.com    }
203413531Sjairo.balart@metempsy.com
203513760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
203613760Sjairo.balart@metempsy.com
203713760Sjairo.balart@metempsy.com    if (ich_hcr_el2.En) {
203813531Sjairo.balart@metempsy.com        if (maintenanceInterruptStatus()) {
203913826Sgiacomo.travaglini@arm.com            maintenanceInterrupt->raise();
204013531Sjairo.balart@metempsy.com        }
204113531Sjairo.balart@metempsy.com    }
204213531Sjairo.balart@metempsy.com
204313531Sjairo.balart@metempsy.com    if (signal_IRQ) {
204413531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
204513531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
204613531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ);
204713531Sjairo.balart@metempsy.com    } else {
204813531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ);
204913531Sjairo.balart@metempsy.com    }
205013531Sjairo.balart@metempsy.com
205113531Sjairo.balart@metempsy.com    if (signal_FIQ) {
205213531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
205313531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
205413531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ);
205513531Sjairo.balart@metempsy.com    } else {
205613531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ);
205713531Sjairo.balart@metempsy.com    }
205813531Sjairo.balart@metempsy.com}
205913531Sjairo.balart@metempsy.com
206013760Sjairo.balart@metempsy.com// Returns the index of the LR with the HPPI
206113531Sjairo.balart@metempsy.comint
206213760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPVILR() const
206313531Sjairo.balart@metempsy.com{
206413531Sjairo.balart@metempsy.com    int idx = -1;
206513760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
206613760Sjairo.balart@metempsy.com
206713760Sjairo.balart@metempsy.com    if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
206813531Sjairo.balart@metempsy.com        // VG0 and VG1 disabled...
206913531Sjairo.balart@metempsy.com        return idx;
207013531Sjairo.balart@metempsy.com    }
207113531Sjairo.balart@metempsy.com
207213531Sjairo.balart@metempsy.com    uint8_t highest_prio = 0xff;
207313531Sjairo.balart@metempsy.com
207413531Sjairo.balart@metempsy.com    for (int i = 0; i < 16; i++) {
207513760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
207613531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
207713760Sjairo.balart@metempsy.com
207813760Sjairo.balart@metempsy.com        if (ich_lr_el2.State != Gicv3::INT_PENDING) {
207913531Sjairo.balart@metempsy.com            continue;
208013531Sjairo.balart@metempsy.com        }
208113531Sjairo.balart@metempsy.com
208213760Sjairo.balart@metempsy.com        if (ich_lr_el2.Group) {
208313531Sjairo.balart@metempsy.com            // VG1
208413760Sjairo.balart@metempsy.com            if (!ich_vmcr_el2.VENG1) {
208513531Sjairo.balart@metempsy.com                continue;
208613531Sjairo.balart@metempsy.com            }
208713531Sjairo.balart@metempsy.com        } else {
208813531Sjairo.balart@metempsy.com            // VG0
208913760Sjairo.balart@metempsy.com            if (!ich_vmcr_el2.VENG0) {
209013531Sjairo.balart@metempsy.com                continue;
209113531Sjairo.balart@metempsy.com            }
209213531Sjairo.balart@metempsy.com        }
209313531Sjairo.balart@metempsy.com
209413760Sjairo.balart@metempsy.com        uint8_t prio = ich_lr_el2.Priority;
209513531Sjairo.balart@metempsy.com
209613531Sjairo.balart@metempsy.com        if (prio < highest_prio) {
209713531Sjairo.balart@metempsy.com            highest_prio = prio;
209813531Sjairo.balart@metempsy.com            idx = i;
209913531Sjairo.balart@metempsy.com        }
210013531Sjairo.balart@metempsy.com    }
210113531Sjairo.balart@metempsy.com
210213531Sjairo.balart@metempsy.com    return idx;
210313531Sjairo.balart@metempsy.com}
210413531Sjairo.balart@metempsy.com
210513531Sjairo.balart@metempsy.combool
210613760Sjairo.balart@metempsy.comGicv3CPUInterface::hppviCanPreempt(int lr_idx) const
210713531Sjairo.balart@metempsy.com{
210813760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
210913760Sjairo.balart@metempsy.com    if (!ich_hcr_el2.En) {
211013531Sjairo.balart@metempsy.com        // virtual interface is disabled
211113531Sjairo.balart@metempsy.com        return false;
211213531Sjairo.balart@metempsy.com    }
211313531Sjairo.balart@metempsy.com
211413760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el2 =
211513760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
211613760Sjairo.balart@metempsy.com    uint8_t prio = ich_lr_el2.Priority;
211713531Sjairo.balart@metempsy.com    uint8_t vpmr =
211813531Sjairo.balart@metempsy.com        bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);
211913531Sjairo.balart@metempsy.com
212013531Sjairo.balart@metempsy.com    if (prio >= vpmr) {
212113531Sjairo.balart@metempsy.com        // prioriry masked
212213531Sjairo.balart@metempsy.com        return false;
212313531Sjairo.balart@metempsy.com    }
212413531Sjairo.balart@metempsy.com
212513531Sjairo.balart@metempsy.com    uint8_t rprio = virtualHighestActivePriority();
212613531Sjairo.balart@metempsy.com
212713531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
212813531Sjairo.balart@metempsy.com        return true;
212913531Sjairo.balart@metempsy.com    }
213013531Sjairo.balart@metempsy.com
213113760Sjairo.balart@metempsy.com    Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
213213531Sjairo.balart@metempsy.com    uint32_t prio_mask = virtualGroupPriorityMask(group);
213313531Sjairo.balart@metempsy.com
213413531Sjairo.balart@metempsy.com    if ((prio & prio_mask) < (rprio & prio_mask)) {
213513531Sjairo.balart@metempsy.com        return true;
213613531Sjairo.balart@metempsy.com    }
213713531Sjairo.balart@metempsy.com
213813531Sjairo.balart@metempsy.com    return false;
213913531Sjairo.balart@metempsy.com}
214013531Sjairo.balart@metempsy.com
214113531Sjairo.balart@metempsy.comuint8_t
214213760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualHighestActivePriority() const
214313531Sjairo.balart@metempsy.com{
214413531Sjairo.balart@metempsy.com    uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
214513531Sjairo.balart@metempsy.com
214613531Sjairo.balart@metempsy.com    for (int i = 0; i < num_aprs; i++) {
214713580Sgabeblack@google.com        RegVal vapr =
214813531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
214913531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
215013531Sjairo.balart@metempsy.com
215113531Sjairo.balart@metempsy.com        if (!vapr) {
215213531Sjairo.balart@metempsy.com            continue;
215313531Sjairo.balart@metempsy.com        }
215413531Sjairo.balart@metempsy.com
215513531Sjairo.balart@metempsy.com        return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
215613531Sjairo.balart@metempsy.com    }
215713531Sjairo.balart@metempsy.com
215813531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
215913531Sjairo.balart@metempsy.com    return 0xff;
216013531Sjairo.balart@metempsy.com}
216113531Sjairo.balart@metempsy.com
216213531Sjairo.balart@metempsy.comvoid
216313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIncrementEOICount()
216413531Sjairo.balart@metempsy.com{
216513531Sjairo.balart@metempsy.com    // Increment the EOICOUNT field in ICH_HCR_EL2
216613580Sgabeblack@google.com    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
216713531Sjairo.balart@metempsy.com    uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
216813531Sjairo.balart@metempsy.com    EOI_cout++;
216913531Sjairo.balart@metempsy.com    ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
217013531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
217113531Sjairo.balart@metempsy.com}
217213531Sjairo.balart@metempsy.com
217313760Sjairo.balart@metempsy.com// spec section 4.6.2
217413531Sjairo.balart@metempsy.comArmISA::InterruptTypes
217513760Sjairo.balart@metempsy.comGicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
217613531Sjairo.balart@metempsy.com{
217713531Sjairo.balart@metempsy.com    bool is_fiq = false;
217813531Sjairo.balart@metempsy.com
217913531Sjairo.balart@metempsy.com    switch (group) {
218013531Sjairo.balart@metempsy.com      case Gicv3::G0S:
218113531Sjairo.balart@metempsy.com        is_fiq = true;
218213531Sjairo.balart@metempsy.com        break;
218313531Sjairo.balart@metempsy.com
218413531Sjairo.balart@metempsy.com      case Gicv3::G1S:
218513531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) &&
218613531Sjairo.balart@metempsy.com            (!inSecureState() || ((currEL() == EL3) && isAA64()));
218713531Sjairo.balart@metempsy.com        break;
218813531Sjairo.balart@metempsy.com
218913531Sjairo.balart@metempsy.com      case Gicv3::G1NS:
219013531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) && inSecureState();
219113531Sjairo.balart@metempsy.com        break;
219213531Sjairo.balart@metempsy.com
219313531Sjairo.balart@metempsy.com      default:
219413531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::intSignalType(): invalid group!");
219513531Sjairo.balart@metempsy.com    }
219613531Sjairo.balart@metempsy.com
219713531Sjairo.balart@metempsy.com    if (is_fiq) {
219813531Sjairo.balart@metempsy.com        return ArmISA::INT_FIQ;
219913531Sjairo.balart@metempsy.com    } else {
220013531Sjairo.balart@metempsy.com        return ArmISA::INT_IRQ;
220113531Sjairo.balart@metempsy.com    }
220213531Sjairo.balart@metempsy.com}
220313531Sjairo.balart@metempsy.com
220413531Sjairo.balart@metempsy.combool
220513926Sgiacomo.travaglini@arm.comGicv3CPUInterface::hppiCanPreempt()
220613531Sjairo.balart@metempsy.com{
220713531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff) {
220813531Sjairo.balart@metempsy.com        // there is no pending interrupt
220913531Sjairo.balart@metempsy.com        return false;
221013531Sjairo.balart@metempsy.com    }
221113531Sjairo.balart@metempsy.com
221213531Sjairo.balart@metempsy.com    if (!groupEnabled(hppi.group)) {
221313531Sjairo.balart@metempsy.com        // group disabled at CPU interface
221413531Sjairo.balart@metempsy.com        return false;
221513531Sjairo.balart@metempsy.com    }
221613531Sjairo.balart@metempsy.com
221713531Sjairo.balart@metempsy.com    if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
221813531Sjairo.balart@metempsy.com        // priority masked
221913531Sjairo.balart@metempsy.com        return false;
222013531Sjairo.balart@metempsy.com    }
222113531Sjairo.balart@metempsy.com
222213531Sjairo.balart@metempsy.com    uint8_t rprio = highestActivePriority();
222313531Sjairo.balart@metempsy.com
222413531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
222513531Sjairo.balart@metempsy.com        return true;
222613531Sjairo.balart@metempsy.com    }
222713531Sjairo.balart@metempsy.com
222813531Sjairo.balart@metempsy.com    uint32_t prio_mask = groupPriorityMask(hppi.group);
222913531Sjairo.balart@metempsy.com
223013531Sjairo.balart@metempsy.com    if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
223113531Sjairo.balart@metempsy.com        return true;
223213531Sjairo.balart@metempsy.com    }
223313531Sjairo.balart@metempsy.com
223413531Sjairo.balart@metempsy.com    return false;
223513531Sjairo.balart@metempsy.com}
223613531Sjairo.balart@metempsy.com
223713531Sjairo.balart@metempsy.comuint8_t
223813760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActivePriority() const
223913531Sjairo.balart@metempsy.com{
224013531Sjairo.balart@metempsy.com    uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
224113531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
224213531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);
224313531Sjairo.balart@metempsy.com
224413531Sjairo.balart@metempsy.com    if (apr) {
224513531Sjairo.balart@metempsy.com        return ctz32(apr) << (GIC_MIN_BPR + 1);
224613531Sjairo.balart@metempsy.com    }
224713531Sjairo.balart@metempsy.com
224813531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
224913531Sjairo.balart@metempsy.com    return 0xff;
225013531Sjairo.balart@metempsy.com}
225113531Sjairo.balart@metempsy.com
225213531Sjairo.balart@metempsy.combool
225313760Sjairo.balart@metempsy.comGicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
225413531Sjairo.balart@metempsy.com{
225513531Sjairo.balart@metempsy.com    switch (group) {
225613760Sjairo.balart@metempsy.com      case Gicv3::G0S: {
225713760Sjairo.balart@metempsy.com        ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
225813760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
225913760Sjairo.balart@metempsy.com        return icc_igrpen0_el1.Enable;
226013760Sjairo.balart@metempsy.com      }
226113760Sjairo.balart@metempsy.com
226213760Sjairo.balart@metempsy.com      case Gicv3::G1S: {
226313760Sjairo.balart@metempsy.com        ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
226413760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
226513760Sjairo.balart@metempsy.com        return icc_igrpen1_el1_s.Enable;
226613760Sjairo.balart@metempsy.com      }
226713760Sjairo.balart@metempsy.com
226813760Sjairo.balart@metempsy.com      case Gicv3::G1NS: {
226913760Sjairo.balart@metempsy.com        ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
227013760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
227113760Sjairo.balart@metempsy.com        return icc_igrpen1_el1_ns.Enable;
227213760Sjairo.balart@metempsy.com      }
227313531Sjairo.balart@metempsy.com
227413531Sjairo.balart@metempsy.com      default:
227513531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
227613531Sjairo.balart@metempsy.com    }
227713531Sjairo.balart@metempsy.com}
227813531Sjairo.balart@metempsy.com
227913531Sjairo.balart@metempsy.combool
228013760Sjairo.balart@metempsy.comGicv3CPUInterface::inSecureState() const
228113531Sjairo.balart@metempsy.com{
228213531Sjairo.balart@metempsy.com    if (!gic->getSystem()->haveSecurity()) {
228313531Sjairo.balart@metempsy.com        return false;
228413531Sjairo.balart@metempsy.com    }
228513531Sjairo.balart@metempsy.com
228613531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
228713531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
228813531Sjairo.balart@metempsy.com    return ArmISA::inSecureState(scr, cpsr);
228913531Sjairo.balart@metempsy.com}
229013531Sjairo.balart@metempsy.com
229113531Sjairo.balart@metempsy.comint
229213760Sjairo.balart@metempsy.comGicv3CPUInterface::currEL() const
229313531Sjairo.balart@metempsy.com{
229413531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
229513531Sjairo.balart@metempsy.com    bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
229613531Sjairo.balart@metempsy.com
229713531Sjairo.balart@metempsy.com    if (is_64) {
229813531Sjairo.balart@metempsy.com        return (ExceptionLevel)(uint8_t) cpsr.el;
229913531Sjairo.balart@metempsy.com    } else {
230013531Sjairo.balart@metempsy.com        switch (cpsr.mode) {
230113531Sjairo.balart@metempsy.com          case MODE_USER:
230213531Sjairo.balart@metempsy.com            return 0;
230313531Sjairo.balart@metempsy.com
230413531Sjairo.balart@metempsy.com          case MODE_HYP:
230513531Sjairo.balart@metempsy.com            return 2;
230613531Sjairo.balart@metempsy.com
230713531Sjairo.balart@metempsy.com          case MODE_MON:
230813531Sjairo.balart@metempsy.com            return 3;
230913531Sjairo.balart@metempsy.com
231013531Sjairo.balart@metempsy.com          default:
231113531Sjairo.balart@metempsy.com            return 1;
231213531Sjairo.balart@metempsy.com        }
231313531Sjairo.balart@metempsy.com    }
231413531Sjairo.balart@metempsy.com}
231513531Sjairo.balart@metempsy.com
231613531Sjairo.balart@metempsy.combool
231713760Sjairo.balart@metempsy.comGicv3CPUInterface::haveEL(ExceptionLevel el) const
231813531Sjairo.balart@metempsy.com{
231913531Sjairo.balart@metempsy.com    switch (el) {
232013531Sjairo.balart@metempsy.com      case EL0:
232113531Sjairo.balart@metempsy.com      case EL1:
232213531Sjairo.balart@metempsy.com        return true;
232313531Sjairo.balart@metempsy.com
232413531Sjairo.balart@metempsy.com      case EL2:
232513531Sjairo.balart@metempsy.com        return gic->getSystem()->haveVirtualization();
232613531Sjairo.balart@metempsy.com
232713531Sjairo.balart@metempsy.com      case EL3:
232813531Sjairo.balart@metempsy.com        return gic->getSystem()->haveSecurity();
232913531Sjairo.balart@metempsy.com
233013531Sjairo.balart@metempsy.com      default:
233113531Sjairo.balart@metempsy.com        warn("Unimplemented Exception Level\n");
233213531Sjairo.balart@metempsy.com        return false;
233313531Sjairo.balart@metempsy.com    }
233413531Sjairo.balart@metempsy.com}
233513531Sjairo.balart@metempsy.com
233613531Sjairo.balart@metempsy.combool
233713760Sjairo.balart@metempsy.comGicv3CPUInterface::isSecureBelowEL3() const
233813531Sjairo.balart@metempsy.com{
233913531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
234013531Sjairo.balart@metempsy.com    return haveEL(EL3) && scr.ns == 0;
234113531Sjairo.balart@metempsy.com}
234213531Sjairo.balart@metempsy.com
234313531Sjairo.balart@metempsy.combool
234413760Sjairo.balart@metempsy.comGicv3CPUInterface::isAA64() const
234513531Sjairo.balart@metempsy.com{
234613531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
234713531Sjairo.balart@metempsy.com    return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
234813531Sjairo.balart@metempsy.com}
234913531Sjairo.balart@metempsy.com
235013531Sjairo.balart@metempsy.combool
235113760Sjairo.balart@metempsy.comGicv3CPUInterface::isEL3OrMon() const
235213531Sjairo.balart@metempsy.com{
235313531Sjairo.balart@metempsy.com    if (haveEL(EL3)) {
235413531Sjairo.balart@metempsy.com        CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
235513531Sjairo.balart@metempsy.com        bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
235613531Sjairo.balart@metempsy.com
235713531Sjairo.balart@metempsy.com        if (is_64 && (cpsr.el == EL3)) {
235813531Sjairo.balart@metempsy.com            return true;
235913531Sjairo.balart@metempsy.com        } else if (!is_64 && (cpsr.mode == MODE_MON)) {
236013531Sjairo.balart@metempsy.com            return true;
236113531Sjairo.balart@metempsy.com        }
236213531Sjairo.balart@metempsy.com    }
236313531Sjairo.balart@metempsy.com
236413531Sjairo.balart@metempsy.com    return false;
236513531Sjairo.balart@metempsy.com}
236613531Sjairo.balart@metempsy.com
236713760Sjairo.balart@metempsy.com// Computes ICH_EISR_EL2
236813760Sjairo.balart@metempsy.comuint64_t
236913760Sjairo.balart@metempsy.comGicv3CPUInterface::eoiMaintenanceInterruptStatus() const
237013531Sjairo.balart@metempsy.com{
237113760Sjairo.balart@metempsy.com    // ICH_EISR_EL2
237213760Sjairo.balart@metempsy.com    // Bits [63:16] - RES0
237313760Sjairo.balart@metempsy.com    // Status<n>, bit [n], for n = 0 to 15
237413760Sjairo.balart@metempsy.com    //   EOI maintenance interrupt status bit for List register <n>:
237513760Sjairo.balart@metempsy.com    //     0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
237613760Sjairo.balart@metempsy.com    //     maintenance interrupt.
237713760Sjairo.balart@metempsy.com    //     1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
237813760Sjairo.balart@metempsy.com    //     interrupt that has not been handled.
237913760Sjairo.balart@metempsy.com    //
238013760Sjairo.balart@metempsy.com    // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
238113760Sjairo.balart@metempsy.com    // of the following are true:
238213760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
238313760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.HW is 0.
238413760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
238513760Sjairo.balart@metempsy.com
238613760Sjairo.balart@metempsy.com    uint64_t value = 0;
238713531Sjairo.balart@metempsy.com
238813531Sjairo.balart@metempsy.com    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
238913760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
239013760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
239113760Sjairo.balart@metempsy.com
239213760Sjairo.balart@metempsy.com        if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
239313760Sjairo.balart@metempsy.com            !ich_lr_el2.HW && ich_lr_el2.EOI) {
239413531Sjairo.balart@metempsy.com            value |= (1 << lr_idx);
239513531Sjairo.balart@metempsy.com        }
239613760Sjairo.balart@metempsy.com    }
239713760Sjairo.balart@metempsy.com
239813760Sjairo.balart@metempsy.com    return value;
239913760Sjairo.balart@metempsy.com}
240013760Sjairo.balart@metempsy.com
240113760Sjairo.balart@metempsy.comGicv3CPUInterface::ICH_MISR_EL2
240213760Sjairo.balart@metempsy.comGicv3CPUInterface::maintenanceInterruptStatus() const
240313760Sjairo.balart@metempsy.com{
240413760Sjairo.balart@metempsy.com    // Comments are copied from SPEC section 9.4.7 (ID012119)
240513760Sjairo.balart@metempsy.com    ICH_MISR_EL2 ich_misr_el2 = 0;
240613760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 =
240713760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
240813760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 =
240913760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
241013760Sjairo.balart@metempsy.com
241113760Sjairo.balart@metempsy.com    // End Of Interrupt. [bit 0]
241213760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when at least one bit in
241313760Sjairo.balart@metempsy.com    // ICH_EISR_EL2 is 1.
241413760Sjairo.balart@metempsy.com
241513760Sjairo.balart@metempsy.com    if (eoiMaintenanceInterruptStatus()) {
241613760Sjairo.balart@metempsy.com        ich_misr_el2.EOI = 1;
241713760Sjairo.balart@metempsy.com    }
241813760Sjairo.balart@metempsy.com
241913760Sjairo.balart@metempsy.com    // Underflow. [bit 1]
242013760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
242113760Sjairo.balart@metempsy.com    // zero or one of the List register entries are marked as a valid
242213760Sjairo.balart@metempsy.com    // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
242313760Sjairo.balart@metempsy.com    // do not equal 0x0.
242413760Sjairo.balart@metempsy.com    uint32_t num_valid_interrupts = 0;
242513760Sjairo.balart@metempsy.com    uint32_t num_pending_interrupts = 0;
242613760Sjairo.balart@metempsy.com
242713760Sjairo.balart@metempsy.com    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
242813760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
242913760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
243013760Sjairo.balart@metempsy.com
243113760Sjairo.balart@metempsy.com        if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
243213760Sjairo.balart@metempsy.com            num_valid_interrupts++;
243313531Sjairo.balart@metempsy.com        }
243413531Sjairo.balart@metempsy.com
243513760Sjairo.balart@metempsy.com        if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
243613760Sjairo.balart@metempsy.com            num_pending_interrupts++;
243713531Sjairo.balart@metempsy.com        }
243813531Sjairo.balart@metempsy.com    }
243913531Sjairo.balart@metempsy.com
244013760Sjairo.balart@metempsy.com    if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
244113760Sjairo.balart@metempsy.com        ich_misr_el2.U = 1;
244213531Sjairo.balart@metempsy.com    }
244313531Sjairo.balart@metempsy.com
244413760Sjairo.balart@metempsy.com    // List Register Entry Not Present. [bit 2]
244513760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
244613760Sjairo.balart@metempsy.com    // and ICH_HCR_EL2.EOIcount is non-zero.
244713760Sjairo.balart@metempsy.com    if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
244813760Sjairo.balart@metempsy.com        ich_misr_el2.LRENP = 1;
244913531Sjairo.balart@metempsy.com    }
245013531Sjairo.balart@metempsy.com
245113760Sjairo.balart@metempsy.com    // No Pending. [bit 3]
245213760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
245313760Sjairo.balart@metempsy.com    // no List register is in pending state.
245413760Sjairo.balart@metempsy.com    if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
245513760Sjairo.balart@metempsy.com        ich_misr_el2.NP = 1;
245613531Sjairo.balart@metempsy.com    }
245713531Sjairo.balart@metempsy.com
245813760Sjairo.balart@metempsy.com    // vPE Group 0 Enabled. [bit 4]
245913760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
246013760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
246113760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
246213760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp0E = 1;
246313531Sjairo.balart@metempsy.com    }
246413531Sjairo.balart@metempsy.com
246513760Sjairo.balart@metempsy.com    // vPE Group 0 Disabled. [bit 5]
246613760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
246713760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
246813760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
246913760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp0D = 1;
247013531Sjairo.balart@metempsy.com    }
247113531Sjairo.balart@metempsy.com
247213760Sjairo.balart@metempsy.com    // vPE Group 1 Enabled. [bit 6]
247313760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
247413760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
247513760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
247613760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp1E = 1;
247713531Sjairo.balart@metempsy.com    }
247813531Sjairo.balart@metempsy.com
247913760Sjairo.balart@metempsy.com    // vPE Group 1 Disabled. [bit 7]
248013760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
248113760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
248213760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
248313760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp1D = 1;
248413760Sjairo.balart@metempsy.com    }
248513760Sjairo.balart@metempsy.com
248613760Sjairo.balart@metempsy.com    return ich_misr_el2;
248713531Sjairo.balart@metempsy.com}
248813531Sjairo.balart@metempsy.com
248913531Sjairo.balart@metempsy.comvoid
249013531Sjairo.balart@metempsy.comGicv3CPUInterface::serialize(CheckpointOut & cp) const
249113531Sjairo.balart@metempsy.com{
249213531Sjairo.balart@metempsy.com    SERIALIZE_SCALAR(hppi.intid);
249313531Sjairo.balart@metempsy.com    SERIALIZE_SCALAR(hppi.prio);
249413531Sjairo.balart@metempsy.com    SERIALIZE_ENUM(hppi.group);
249513531Sjairo.balart@metempsy.com}
249613531Sjairo.balart@metempsy.com
249713531Sjairo.balart@metempsy.comvoid
249813531Sjairo.balart@metempsy.comGicv3CPUInterface::unserialize(CheckpointIn & cp)
249913531Sjairo.balart@metempsy.com{
250013531Sjairo.balart@metempsy.com    UNSERIALIZE_SCALAR(hppi.intid);
250113531Sjairo.balart@metempsy.com    UNSERIALIZE_SCALAR(hppi.prio);
250213531Sjairo.balart@metempsy.com    UNSERIALIZE_ENUM(hppi.group);
250313531Sjairo.balart@metempsy.com}
2504