gic_v3_cpu_interface.cc revision 14236
113531Sjairo.balart@metempsy.com/*
214227Sgiacomo.travaglini@arm.com * Copyright (c) 2019 ARM Limited
314227Sgiacomo.travaglini@arm.com * All rights reserved
414227Sgiacomo.travaglini@arm.com *
514227Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall
614227Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual
714227Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating
814227Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software
914227Sgiacomo.travaglini@arm.com * licensed hereunder.  You may use the software subject to the license
1014227Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated
1114227Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software,
1214227Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form.
1314227Sgiacomo.travaglini@arm.com *
1413531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
1513531Sjairo.balart@metempsy.com * All rights reserved.
1613531Sjairo.balart@metempsy.com *
1713531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
1813531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
1913531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
2013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
2113531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
2213531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
2313531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
2413531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
2513531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
2613531Sjairo.balart@metempsy.com * this software without specific prior written permission.
2713531Sjairo.balart@metempsy.com *
2813531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2913531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3013531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3113531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3213531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3313531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3413531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3513531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3613531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3713531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3813531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3913531Sjairo.balart@metempsy.com *
4013531Sjairo.balart@metempsy.com * Authors: Jairo Balart
4113531Sjairo.balart@metempsy.com */
4213531Sjairo.balart@metempsy.com
4313531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh"
4413531Sjairo.balart@metempsy.com
4513531Sjairo.balart@metempsy.com#include "arch/arm/isa.hh"
4613531Sjairo.balart@metempsy.com#include "debug/GIC.hh"
4713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh"
4813531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh"
4913531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_redistributor.hh"
5013531Sjairo.balart@metempsy.com
5113926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
5213926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;
5313926Sgiacomo.travaglini@arm.com
5413531Sjairo.balart@metempsy.comGicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
5513531Sjairo.balart@metempsy.com    : BaseISADevice(),
5613531Sjairo.balart@metempsy.com      gic(gic),
5713531Sjairo.balart@metempsy.com      redistributor(nullptr),
5813531Sjairo.balart@metempsy.com      distributor(nullptr),
5913531Sjairo.balart@metempsy.com      cpuId(cpu_id)
6013531Sjairo.balart@metempsy.com{
6113531Sjairo.balart@metempsy.com}
6213531Sjairo.balart@metempsy.com
6313531Sjairo.balart@metempsy.comvoid
6413531Sjairo.balart@metempsy.comGicv3CPUInterface::init()
6513531Sjairo.balart@metempsy.com{
6613531Sjairo.balart@metempsy.com    redistributor = gic->getRedistributor(cpuId);
6713531Sjairo.balart@metempsy.com    distributor = gic->getDistributor();
6813531Sjairo.balart@metempsy.com}
6913531Sjairo.balart@metempsy.com
7013531Sjairo.balart@metempsy.comvoid
7113531Sjairo.balart@metempsy.comGicv3CPUInterface::initState()
7213531Sjairo.balart@metempsy.com{
7313531Sjairo.balart@metempsy.com    reset();
7413531Sjairo.balart@metempsy.com}
7513531Sjairo.balart@metempsy.com
7613531Sjairo.balart@metempsy.comvoid
7713531Sjairo.balart@metempsy.comGicv3CPUInterface::reset()
7813531Sjairo.balart@metempsy.com{
7913531Sjairo.balart@metempsy.com    hppi.prio = 0xff;
8013531Sjairo.balart@metempsy.com}
8113531Sjairo.balart@metempsy.com
8213826Sgiacomo.travaglini@arm.comvoid
8313826Sgiacomo.travaglini@arm.comGicv3CPUInterface::setThreadContext(ThreadContext *tc)
8413826Sgiacomo.travaglini@arm.com{
8513826Sgiacomo.travaglini@arm.com    maintenanceInterrupt = gic->params()->maint_int->get(tc);
8613826Sgiacomo.travaglini@arm.com}
8713826Sgiacomo.travaglini@arm.com
8813531Sjairo.balart@metempsy.combool
8913760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2FMO() const
9013531Sjairo.balart@metempsy.com{
9113531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
9213531Sjairo.balart@metempsy.com
9313531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
9413531Sjairo.balart@metempsy.com        return false;
9513531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
9613531Sjairo.balart@metempsy.com        return true;
9713531Sjairo.balart@metempsy.com    } else {
9813531Sjairo.balart@metempsy.com        return hcr.fmo;
9913531Sjairo.balart@metempsy.com    }
10013531Sjairo.balart@metempsy.com}
10113531Sjairo.balart@metempsy.com
10213531Sjairo.balart@metempsy.combool
10313760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2IMO() const
10413531Sjairo.balart@metempsy.com{
10513531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
10613531Sjairo.balart@metempsy.com
10713531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
10813531Sjairo.balart@metempsy.com        return false;
10913531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
11013531Sjairo.balart@metempsy.com        return true;
11113531Sjairo.balart@metempsy.com    } else {
11213531Sjairo.balart@metempsy.com        return hcr.imo;
11313531Sjairo.balart@metempsy.com    }
11413531Sjairo.balart@metempsy.com}
11513531Sjairo.balart@metempsy.com
11613580Sgabeblack@google.comRegVal
11713531Sjairo.balart@metempsy.comGicv3CPUInterface::readMiscReg(int misc_reg)
11813531Sjairo.balart@metempsy.com{
11913580Sgabeblack@google.com    RegVal value = isa->readMiscRegNoEffect(misc_reg);
12013531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
12113531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
12213531Sjairo.balart@metempsy.com
12313531Sjairo.balart@metempsy.com    switch (misc_reg) {
12413760Sjairo.balart@metempsy.com      // Active Priorities Group 1 Registers
12513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
12613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1: {
12713531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
12813531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
12913531Sjairo.balart@metempsy.com          }
13013531Sjairo.balart@metempsy.com
13113531Sjairo.balart@metempsy.com          break;
13213531Sjairo.balart@metempsy.com      }
13313531Sjairo.balart@metempsy.com
13413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
13513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
13613531Sjairo.balart@metempsy.com
13713531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
13813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
13913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
14013531Sjairo.balart@metempsy.com
14113531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
14213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
14313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
14413531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
14513531Sjairo.balart@metempsy.com        return 0;
14613531Sjairo.balart@metempsy.com
14713760Sjairo.balart@metempsy.com      // Active Priorities Group 0 Registers
14813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
14913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1: {
15013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
15113531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
15213531Sjairo.balart@metempsy.com          }
15313531Sjairo.balart@metempsy.com
15413531Sjairo.balart@metempsy.com          break;
15513531Sjairo.balart@metempsy.com      }
15613531Sjairo.balart@metempsy.com
15713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
15813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
15913531Sjairo.balart@metempsy.com
16013531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
16113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
16213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
16313531Sjairo.balart@metempsy.com
16413531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
16513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
16613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
16713531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
16813531Sjairo.balart@metempsy.com        return 0;
16913531Sjairo.balart@metempsy.com
17013760Sjairo.balart@metempsy.com      // Interrupt Group 0 Enable register EL1
17113531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
17213531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
17313531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
17414057Sgiacomo.travaglini@arm.com              return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
17513531Sjairo.balart@metempsy.com          }
17613531Sjairo.balart@metempsy.com
17713531Sjairo.balart@metempsy.com          break;
17813531Sjairo.balart@metempsy.com      }
17913531Sjairo.balart@metempsy.com
18014057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_IGRPEN0_EL1: {
18114057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
18214057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
18314057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VENG0;
18414057Sgiacomo.travaglini@arm.com          break;
18514057Sgiacomo.travaglini@arm.com      }
18614057Sgiacomo.travaglini@arm.com
18713760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL1
18813531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
18913531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
19013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
19114057Sgiacomo.travaglini@arm.com              return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
19213531Sjairo.balart@metempsy.com          }
19313531Sjairo.balart@metempsy.com
19413531Sjairo.balart@metempsy.com          break;
19513531Sjairo.balart@metempsy.com      }
19613531Sjairo.balart@metempsy.com
19714057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_IGRPEN1_EL1: {
19814057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
19914057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
20014057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VENG1;
20114057Sgiacomo.travaglini@arm.com          break;
20214057Sgiacomo.travaglini@arm.com      }
20314057Sgiacomo.travaglini@arm.com
20413760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL3
20513760Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
20613760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL3:
20713739Sgiacomo.travaglini@arm.com          break;
20813760Sjairo.balart@metempsy.com
20913760Sjairo.balart@metempsy.com      // Running Priority Register
21013531Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR:
21113531Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR_EL1: {
21213531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
21313760Sjairo.balart@metempsy.com              (hcr_imo || hcr_fmo)) {
21413531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_RPR_EL1);
21513531Sjairo.balart@metempsy.com          }
21613531Sjairo.balart@metempsy.com
21713531Sjairo.balart@metempsy.com          uint8_t rprio = highestActivePriority();
21813531Sjairo.balart@metempsy.com
21913531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() &&
22013760Sjairo.balart@metempsy.com              (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
22113760Sjairo.balart@metempsy.com              // Spec section 4.8.1
22213760Sjairo.balart@metempsy.com              // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
22313531Sjairo.balart@metempsy.com              if ((rprio & 0x80) == 0) {
22413760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
22513760Sjairo.balart@metempsy.com                  // 0x00-0x7F a read access returns the value 0x0
22613531Sjairo.balart@metempsy.com                  rprio = 0;
22713531Sjairo.balart@metempsy.com              } else if (rprio != 0xff) {
22813760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
22913760Sjairo.balart@metempsy.com                  // 0x80-0xFF a read access returns the Non-secure read of
23013760Sjairo.balart@metempsy.com                  // the current value
23113531Sjairo.balart@metempsy.com                  rprio = (rprio << 1) & 0xff;
23213531Sjairo.balart@metempsy.com              }
23313531Sjairo.balart@metempsy.com          }
23413531Sjairo.balart@metempsy.com
23513531Sjairo.balart@metempsy.com          value = rprio;
23613531Sjairo.balart@metempsy.com          break;
23713531Sjairo.balart@metempsy.com      }
23813531Sjairo.balart@metempsy.com
23913760Sjairo.balart@metempsy.com      // Virtual Running Priority Register
24013531Sjairo.balart@metempsy.com      case MISCREG_ICV_RPR_EL1: {
24113531Sjairo.balart@metempsy.com          value = virtualHighestActivePriority();
24213531Sjairo.balart@metempsy.com          break;
24313531Sjairo.balart@metempsy.com      }
24413531Sjairo.balart@metempsy.com
24513760Sjairo.balart@metempsy.com      // Highest Priority Pending Interrupt Register 0
24613531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0:
24713531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0_EL1: {
24813531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
24913531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
25013531Sjairo.balart@metempsy.com          }
25113531Sjairo.balart@metempsy.com
25213531Sjairo.balart@metempsy.com          value = getHPPIR0();
25313531Sjairo.balart@metempsy.com          break;
25413531Sjairo.balart@metempsy.com      }
25513531Sjairo.balart@metempsy.com
25613760Sjairo.balart@metempsy.com      // Virtual Highest Priority Pending Interrupt Register 0
25713531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR0_EL1: {
25813531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
25913531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
26013531Sjairo.balart@metempsy.com
26113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
26213760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
26313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
26413531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
26513760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
26613531Sjairo.balart@metempsy.com
26713531Sjairo.balart@metempsy.com              if (group == Gicv3::G0S) {
26813760Sjairo.balart@metempsy.com                  value = ich_lr_el2.vINTID;
26913531Sjairo.balart@metempsy.com              }
27013531Sjairo.balart@metempsy.com          }
27113531Sjairo.balart@metempsy.com
27213531Sjairo.balart@metempsy.com          break;
27313531Sjairo.balart@metempsy.com      }
27413531Sjairo.balart@metempsy.com
27513760Sjairo.balart@metempsy.com      // Highest Priority Pending Interrupt Register 1
27613531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1:
27713531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1_EL1: {
27813531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
27913531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
28013531Sjairo.balart@metempsy.com          }
28113531Sjairo.balart@metempsy.com
28213531Sjairo.balart@metempsy.com          value = getHPPIR1();
28313531Sjairo.balart@metempsy.com          break;
28413531Sjairo.balart@metempsy.com      }
28513531Sjairo.balart@metempsy.com
28613760Sjairo.balart@metempsy.com      // Virtual Highest Priority Pending Interrupt Register 1
28713531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR1_EL1: {
28813531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
28913531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
29013531Sjairo.balart@metempsy.com
29113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
29213760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
29313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
29413531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
29513760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
29613531Sjairo.balart@metempsy.com
29713531Sjairo.balart@metempsy.com              if (group == Gicv3::G1NS) {
29813760Sjairo.balart@metempsy.com                  value = ich_lr_el2.vINTID;
29913531Sjairo.balart@metempsy.com              }
30013531Sjairo.balart@metempsy.com          }
30113531Sjairo.balart@metempsy.com
30213531Sjairo.balart@metempsy.com          break;
30313531Sjairo.balart@metempsy.com      }
30413531Sjairo.balart@metempsy.com
30513760Sjairo.balart@metempsy.com      // Binary Point Register 0
30613531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
30713531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0_EL1:
30813531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
30913531Sjairo.balart@metempsy.com            return readMiscReg(MISCREG_ICV_BPR0_EL1);
31013531Sjairo.balart@metempsy.com        }
31113531Sjairo.balart@metempsy.com
31213531Sjairo.balart@metempsy.com        M5_FALLTHROUGH;
31313531Sjairo.balart@metempsy.com
31413760Sjairo.balart@metempsy.com      // Binary Point Register 1
31513531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
31613760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: {
31713760Sjairo.balart@metempsy.com            if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
31813760Sjairo.balart@metempsy.com                return readMiscReg(MISCREG_ICV_BPR1_EL1);
31913760Sjairo.balart@metempsy.com            }
32013760Sjairo.balart@metempsy.com
32113531Sjairo.balart@metempsy.com            Gicv3::GroupId group =
32213531Sjairo.balart@metempsy.com                misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;
32313531Sjairo.balart@metempsy.com
32413531Sjairo.balart@metempsy.com            if (group == Gicv3::G1S && !inSecureState()) {
32513531Sjairo.balart@metempsy.com                group = Gicv3::G1NS;
32613531Sjairo.balart@metempsy.com            }
32713531Sjairo.balart@metempsy.com
32813760Sjairo.balart@metempsy.com            ICC_CTLR_EL1 icc_ctlr_el1_s =
32913760Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
33013760Sjairo.balart@metempsy.com
33113760Sjairo.balart@metempsy.com            if ((group == Gicv3::G1S) && !isEL3OrMon() &&
33213760Sjairo.balart@metempsy.com                icc_ctlr_el1_s.CBPR) {
33313531Sjairo.balart@metempsy.com                group = Gicv3::G0S;
33413531Sjairo.balart@metempsy.com            }
33513531Sjairo.balart@metempsy.com
33613531Sjairo.balart@metempsy.com            bool sat_inc = false;
33713531Sjairo.balart@metempsy.com
33813760Sjairo.balart@metempsy.com            ICC_CTLR_EL1 icc_ctlr_el1_ns =
33913760Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
34013760Sjairo.balart@metempsy.com
34113760Sjairo.balart@metempsy.com            if ((group == Gicv3::G1NS) && (currEL() < EL3) &&
34213760Sjairo.balart@metempsy.com                icc_ctlr_el1_ns.CBPR) {
34313531Sjairo.balart@metempsy.com                // Reads return BPR0 + 1 saturated to 7, WI
34413531Sjairo.balart@metempsy.com                group = Gicv3::G0S;
34513531Sjairo.balart@metempsy.com                sat_inc = true;
34613531Sjairo.balart@metempsy.com            }
34713531Sjairo.balart@metempsy.com
34813531Sjairo.balart@metempsy.com            uint8_t bpr;
34913531Sjairo.balart@metempsy.com
35013531Sjairo.balart@metempsy.com            if (group == Gicv3::G0S) {
35113531Sjairo.balart@metempsy.com                bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
35213531Sjairo.balart@metempsy.com            } else {
35313531Sjairo.balart@metempsy.com                bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1);
35413926Sgiacomo.travaglini@arm.com                bpr = std::max(bpr, group == Gicv3::G1S ?
35513926Sgiacomo.travaglini@arm.com                    GIC_MIN_BPR : GIC_MIN_BPR_NS);
35613531Sjairo.balart@metempsy.com            }
35713531Sjairo.balart@metempsy.com
35813531Sjairo.balart@metempsy.com            if (sat_inc) {
35913531Sjairo.balart@metempsy.com                bpr++;
36013531Sjairo.balart@metempsy.com
36113531Sjairo.balart@metempsy.com                if (bpr > 7) {
36213531Sjairo.balart@metempsy.com                    bpr = 7;
36313531Sjairo.balart@metempsy.com                }
36413531Sjairo.balart@metempsy.com            }
36513531Sjairo.balart@metempsy.com
36613531Sjairo.balart@metempsy.com            value = bpr;
36713531Sjairo.balart@metempsy.com            break;
36813760Sjairo.balart@metempsy.com      }
36913760Sjairo.balart@metempsy.com
37013760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 1
37113531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR0_EL1:
37213531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
37313531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
37413531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
37513760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
37613531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
37713531Sjairo.balart@metempsy.com          bool sat_inc = false;
37813531Sjairo.balart@metempsy.com
37913760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
38013760Sjairo.balart@metempsy.com              // bpr0 + 1 saturated to 7, WI
38113531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
38213531Sjairo.balart@metempsy.com              sat_inc = true;
38313531Sjairo.balart@metempsy.com          }
38413531Sjairo.balart@metempsy.com
38513531Sjairo.balart@metempsy.com          uint8_t vbpr;
38613531Sjairo.balart@metempsy.com
38713531Sjairo.balart@metempsy.com          if (group == Gicv3::G0S) {
38813760Sjairo.balart@metempsy.com              vbpr = ich_vmcr_el2.VBPR0;
38913531Sjairo.balart@metempsy.com          } else {
39013760Sjairo.balart@metempsy.com              vbpr = ich_vmcr_el2.VBPR1;
39113531Sjairo.balart@metempsy.com          }
39213531Sjairo.balart@metempsy.com
39313531Sjairo.balart@metempsy.com          if (sat_inc) {
39413531Sjairo.balart@metempsy.com              vbpr++;
39513531Sjairo.balart@metempsy.com
39613531Sjairo.balart@metempsy.com              if (vbpr > 7) {
39713531Sjairo.balart@metempsy.com                  vbpr = 7;
39813531Sjairo.balart@metempsy.com              }
39913531Sjairo.balart@metempsy.com          }
40013531Sjairo.balart@metempsy.com
40113531Sjairo.balart@metempsy.com          value = vbpr;
40213531Sjairo.balart@metempsy.com          break;
40313531Sjairo.balart@metempsy.com      }
40413531Sjairo.balart@metempsy.com
40513760Sjairo.balart@metempsy.com      // Interrupt Priority Mask Register
40613531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
40713760Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1:
40813760Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
40914057Sgiacomo.travaglini@arm.com            return readMiscReg(MISCREG_ICV_PMR_EL1);
41013531Sjairo.balart@metempsy.com        }
41113531Sjairo.balart@metempsy.com
41213531Sjairo.balart@metempsy.com        if (haveEL(EL3) && !inSecureState() &&
41313760Sjairo.balart@metempsy.com            (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
41413760Sjairo.balart@metempsy.com            // Spec section 4.8.1
41513760Sjairo.balart@metempsy.com            // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
41613531Sjairo.balart@metempsy.com            if ((value & 0x80) == 0) {
41713760Sjairo.balart@metempsy.com                // If the current priority mask value is in the range of
41813760Sjairo.balart@metempsy.com                // 0x00-0x7F a read access returns the value 0x00.
41913531Sjairo.balart@metempsy.com                value = 0;
42013531Sjairo.balart@metempsy.com            } else if (value != 0xff) {
42113760Sjairo.balart@metempsy.com                // If the current priority mask value is in the range of
42213760Sjairo.balart@metempsy.com                // 0x80-0xFF a read access returns the Non-secure read of the
42313760Sjairo.balart@metempsy.com                // current value.
42413531Sjairo.balart@metempsy.com                value = (value << 1) & 0xff;
42513531Sjairo.balart@metempsy.com            }
42613531Sjairo.balart@metempsy.com        }
42713531Sjairo.balart@metempsy.com
42813531Sjairo.balart@metempsy.com        break;
42913531Sjairo.balart@metempsy.com
43014057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
43114057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
43214057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
43314057Sgiacomo.travaglini@arm.com
43414057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VPMR;
43514057Sgiacomo.travaglini@arm.com          break;
43614057Sgiacomo.travaglini@arm.com      }
43714057Sgiacomo.travaglini@arm.com
43813760Sjairo.balart@metempsy.com      // Interrupt Acknowledge Register 0
43913531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0:
44013760Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0_EL1: {
44113531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
44213531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR0_EL1);
44313531Sjairo.balart@metempsy.com          }
44413531Sjairo.balart@metempsy.com
44513531Sjairo.balart@metempsy.com          uint32_t int_id;
44613531Sjairo.balart@metempsy.com
44713531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
44813531Sjairo.balart@metempsy.com              int_id = getHPPIR0();
44913531Sjairo.balart@metempsy.com
45013531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
45113923Sgiacomo.travaglini@arm.com              if (int_id < Gicv3::INTID_SECURE ||
45213923Sgiacomo.travaglini@arm.com                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
45313531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
45413531Sjairo.balart@metempsy.com              }
45513531Sjairo.balart@metempsy.com          } else {
45613531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
45713531Sjairo.balart@metempsy.com          }
45813531Sjairo.balart@metempsy.com
45913531Sjairo.balart@metempsy.com          value = int_id;
46013531Sjairo.balart@metempsy.com          break;
46113531Sjairo.balart@metempsy.com      }
46213531Sjairo.balart@metempsy.com
46313760Sjairo.balart@metempsy.com      // Virtual Interrupt Acknowledge Register 0
46413531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR0_EL1: {
46513531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
46613531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
46713531Sjairo.balart@metempsy.com
46813531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
46913760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
47013531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
47113531Sjairo.balart@metempsy.com
47213760Sjairo.balart@metempsy.com              if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
47313760Sjairo.balart@metempsy.com                  int_id = ich_lr_el2.vINTID;
47413531Sjairo.balart@metempsy.com
47513531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
47613760Sjairo.balart@metempsy.com                      int_id > Gicv3::INTID_SPURIOUS) {
47713531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
47813531Sjairo.balart@metempsy.com                  } else {
47913531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
48013531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
48113531Sjairo.balart@metempsy.com                      // - Return de bogus id...
48213760Sjairo.balart@metempsy.com                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
48313531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
48413760Sjairo.balart@metempsy.com                                              ich_lr_el2);
48513531Sjairo.balart@metempsy.com                  }
48613531Sjairo.balart@metempsy.com              }
48713531Sjairo.balart@metempsy.com          }
48813531Sjairo.balart@metempsy.com
48913531Sjairo.balart@metempsy.com          value = int_id;
49013531Sjairo.balart@metempsy.com          virtualUpdate();
49113531Sjairo.balart@metempsy.com          break;
49213531Sjairo.balart@metempsy.com      }
49313531Sjairo.balart@metempsy.com
49413760Sjairo.balart@metempsy.com      // Interrupt Acknowledge Register 1
49513531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1:
49613760Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1_EL1: {
49713531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
49813531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR1_EL1);
49913531Sjairo.balart@metempsy.com          }
50013531Sjairo.balart@metempsy.com
50113531Sjairo.balart@metempsy.com          uint32_t int_id;
50213531Sjairo.balart@metempsy.com
50313531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
50413531Sjairo.balart@metempsy.com              int_id = getHPPIR1();
50513531Sjairo.balart@metempsy.com
50613531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
50713923Sgiacomo.travaglini@arm.com              if (int_id < Gicv3::INTID_SECURE ||
50813923Sgiacomo.travaglini@arm.com                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
50913531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
51013531Sjairo.balart@metempsy.com              }
51113531Sjairo.balart@metempsy.com          } else {
51213531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
51313531Sjairo.balart@metempsy.com          }
51413531Sjairo.balart@metempsy.com
51513531Sjairo.balart@metempsy.com          value = int_id;
51613531Sjairo.balart@metempsy.com          break;
51713531Sjairo.balart@metempsy.com      }
51813531Sjairo.balart@metempsy.com
51913760Sjairo.balart@metempsy.com      // Virtual Interrupt Acknowledge Register 1
52013531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR1_EL1: {
52113531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
52213531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
52313531Sjairo.balart@metempsy.com
52413531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
52513760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
52613531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
52713531Sjairo.balart@metempsy.com
52813760Sjairo.balart@metempsy.com              if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
52913760Sjairo.balart@metempsy.com                  int_id = ich_lr_el2.vINTID;
53013531Sjairo.balart@metempsy.com
53113531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
53213760Sjairo.balart@metempsy.com                      int_id > Gicv3::INTID_SPURIOUS) {
53313531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
53413531Sjairo.balart@metempsy.com                  } else {
53513531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
53613531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
53713531Sjairo.balart@metempsy.com                      // - Return de bogus id...
53813760Sjairo.balart@metempsy.com                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
53913531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
54013760Sjairo.balart@metempsy.com                                              ich_lr_el2);
54113531Sjairo.balart@metempsy.com                  }
54213531Sjairo.balart@metempsy.com              }
54313531Sjairo.balart@metempsy.com          }
54413531Sjairo.balart@metempsy.com
54513531Sjairo.balart@metempsy.com          value = int_id;
54613531Sjairo.balart@metempsy.com          virtualUpdate();
54713531Sjairo.balart@metempsy.com          break;
54813531Sjairo.balart@metempsy.com      }
54913531Sjairo.balart@metempsy.com
55013760Sjairo.balart@metempsy.com      // System Register Enable Register EL1
55113531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
55213760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1: {
55313531Sjairo.balart@metempsy.com        /*
55413531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
55513531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
55613531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
55713531Sjairo.balart@metempsy.com         */
55813760Sjairo.balart@metempsy.com          ICC_SRE_EL1 icc_sre_el1 = 0;
55913760Sjairo.balart@metempsy.com          icc_sre_el1.SRE = 1;
56013760Sjairo.balart@metempsy.com          icc_sre_el1.DIB = 1;
56113760Sjairo.balart@metempsy.com          icc_sre_el1.DFB = 1;
56213760Sjairo.balart@metempsy.com          value = icc_sre_el1;
56313760Sjairo.balart@metempsy.com          break;
56413760Sjairo.balart@metempsy.com      }
56513760Sjairo.balart@metempsy.com
56613760Sjairo.balart@metempsy.com      // System Register Enable Register EL2
56713760Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
56813760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2: {
56913531Sjairo.balart@metempsy.com        /*
57013531Sjairo.balart@metempsy.com         * Enable [3] == 1
57113760Sjairo.balart@metempsy.com         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
57213531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
57313531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
57413531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
57513531Sjairo.balart@metempsy.com         */
57613760Sjairo.balart@metempsy.com        ICC_SRE_EL2 icc_sre_el2 = 0;
57713760Sjairo.balart@metempsy.com        icc_sre_el2.SRE = 1;
57813760Sjairo.balart@metempsy.com        icc_sre_el2.DIB = 1;
57913760Sjairo.balart@metempsy.com        icc_sre_el2.DFB = 1;
58013760Sjairo.balart@metempsy.com        icc_sre_el2.Enable = 1;
58113760Sjairo.balart@metempsy.com        value = icc_sre_el2;
58213531Sjairo.balart@metempsy.com        break;
58313760Sjairo.balart@metempsy.com      }
58413760Sjairo.balart@metempsy.com
58513760Sjairo.balart@metempsy.com      // System Register Enable Register EL3
58613760Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
58713760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3: {
58813760Sjairo.balart@metempsy.com        /*
58913760Sjairo.balart@metempsy.com         * Enable [3] == 1
59013760Sjairo.balart@metempsy.com         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
59113760Sjairo.balart@metempsy.com         *  EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
59213760Sjairo.balart@metempsy.com         *  RAO/WI)
59313760Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
59413760Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
59513760Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
59613760Sjairo.balart@metempsy.com         */
59713760Sjairo.balart@metempsy.com        ICC_SRE_EL3 icc_sre_el3 = 0;
59813760Sjairo.balart@metempsy.com        icc_sre_el3.SRE = 1;
59913760Sjairo.balart@metempsy.com        icc_sre_el3.DIB = 1;
60013760Sjairo.balart@metempsy.com        icc_sre_el3.DFB = 1;
60113760Sjairo.balart@metempsy.com        icc_sre_el3.Enable = 1;
60213760Sjairo.balart@metempsy.com        value = icc_sre_el3;
60313760Sjairo.balart@metempsy.com        break;
60413760Sjairo.balart@metempsy.com      }
60513760Sjairo.balart@metempsy.com
60613760Sjairo.balart@metempsy.com      // Control Register
60713531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
60813760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: {
60913760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
61013531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_CTLR_EL1);
61113531Sjairo.balart@metempsy.com          }
61213531Sjairo.balart@metempsy.com
61313760Sjairo.balart@metempsy.com          // Enforce value for RO bits
61413760Sjairo.balart@metempsy.com          // ExtRange [19], INTIDs in the range 1024..8191 not supported
61513760Sjairo.balart@metempsy.com          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
61613760Sjairo.balart@metempsy.com          // A3V [15], supports non-zero values of the Aff3 field in SGI
61713760Sjairo.balart@metempsy.com          //           generation System registers
61813760Sjairo.balart@metempsy.com          // SEIS [14], does not support generation of SEIs (deprecated)
61913531Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
62013531Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
62113760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1 = value;
62213760Sjairo.balart@metempsy.com          icc_ctlr_el1.ExtRange = 0;
62313760Sjairo.balart@metempsy.com          icc_ctlr_el1.RSS = 1;
62413760Sjairo.balart@metempsy.com          icc_ctlr_el1.A3V = 1;
62513760Sjairo.balart@metempsy.com          icc_ctlr_el1.SEIS = 0;
62613760Sjairo.balart@metempsy.com          icc_ctlr_el1.IDbits = 1;
62713760Sjairo.balart@metempsy.com          icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
62813760Sjairo.balart@metempsy.com          value = icc_ctlr_el1;
62913531Sjairo.balart@metempsy.com          break;
63013531Sjairo.balart@metempsy.com      }
63113531Sjairo.balart@metempsy.com
63213760Sjairo.balart@metempsy.com      // Virtual Control Register
63313531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
63413760Sjairo.balart@metempsy.com          ICV_CTLR_EL1 icv_ctlr_el1 = value;
63513760Sjairo.balart@metempsy.com          icv_ctlr_el1.RSS = 0;
63613760Sjairo.balart@metempsy.com          icv_ctlr_el1.A3V = 1;
63713760Sjairo.balart@metempsy.com          icv_ctlr_el1.SEIS = 0;
63813760Sjairo.balart@metempsy.com          icv_ctlr_el1.IDbits = 1;
63913760Sjairo.balart@metempsy.com          icv_ctlr_el1.PRIbits = 7;
64013760Sjairo.balart@metempsy.com          value = icv_ctlr_el1;
64113531Sjairo.balart@metempsy.com          break;
64213531Sjairo.balart@metempsy.com      }
64313531Sjairo.balart@metempsy.com
64413760Sjairo.balart@metempsy.com      // Control Register
64513531Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
64613531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
64713760Sjairo.balart@metempsy.com          // Enforce value for RO bits
64813760Sjairo.balart@metempsy.com          // ExtRange [19], INTIDs in the range 1024..8191 not supported
64913760Sjairo.balart@metempsy.com          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
65013760Sjairo.balart@metempsy.com          // nDS [17], supports disabling of security
65113760Sjairo.balart@metempsy.com          // A3V [15], supports non-zero values of the Aff3 field in SGI
65213760Sjairo.balart@metempsy.com          //           generation System registers
65313760Sjairo.balart@metempsy.com          // SEIS [14], does not support generation of SEIs (deprecated)
65413531Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
65513531Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
65613760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 = value;
65713760Sjairo.balart@metempsy.com          icc_ctlr_el3.ExtRange = 0;
65813760Sjairo.balart@metempsy.com          icc_ctlr_el3.RSS = 1;
65913760Sjairo.balart@metempsy.com          icc_ctlr_el3.nDS = 0;
66013760Sjairo.balart@metempsy.com          icc_ctlr_el3.A3V = 1;
66113760Sjairo.balart@metempsy.com          icc_ctlr_el3.SEIS = 0;
66213760Sjairo.balart@metempsy.com          icc_ctlr_el3.IDbits = 0;
66313760Sjairo.balart@metempsy.com          icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
66413760Sjairo.balart@metempsy.com          value = icc_ctlr_el3;
66513531Sjairo.balart@metempsy.com          break;
66613531Sjairo.balart@metempsy.com      }
66713531Sjairo.balart@metempsy.com
66813760Sjairo.balart@metempsy.com      // Hyp Control Register
66913531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
67013531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2:
67113531Sjairo.balart@metempsy.com        break;
67213531Sjairo.balart@metempsy.com
67313760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 0 Registers
67413531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0:
67513531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0_EL2:
67613531Sjairo.balart@metempsy.com        break;
67713531Sjairo.balart@metempsy.com
67814236Sgiacomo.travaglini@arm.com      // only implemented if supporting 6 or more bits of priority
67914236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R1:
68014236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R1_EL2:
68114236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
68214236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R2:
68314236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R2_EL2:
68414236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
68514236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R3:
68614236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R3_EL2:
68714236Sgiacomo.travaglini@arm.com        // Unimplemented registers are RAZ/WI
68814236Sgiacomo.travaglini@arm.com        return 0;
68914236Sgiacomo.travaglini@arm.com
69013760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 1 Registers
69113531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0:
69213531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0_EL2:
69313531Sjairo.balart@metempsy.com        break;
69413531Sjairo.balart@metempsy.com
69514236Sgiacomo.travaglini@arm.com      // only implemented if supporting 6 or more bits of priority
69614236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R1:
69714236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R1_EL2:
69814236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
69914236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R2:
70014236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R2_EL2:
70114236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
70214236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R3:
70314236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R3_EL2:
70414236Sgiacomo.travaglini@arm.com        // Unimplemented registers are RAZ/WI
70514236Sgiacomo.travaglini@arm.com        return 0;
70614236Sgiacomo.travaglini@arm.com
70713760Sjairo.balart@metempsy.com      // Maintenance Interrupt State Register
70813531Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR:
70913760Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR_EL2:
71013760Sjairo.balart@metempsy.com        value = maintenanceInterruptStatus();
71113760Sjairo.balart@metempsy.com        break;
71213760Sjairo.balart@metempsy.com
71313760Sjairo.balart@metempsy.com      // VGIC Type Register
71413760Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR:
71513760Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR_EL2: {
71613760Sjairo.balart@metempsy.com        ICH_VTR_EL2 ich_vtr_el2 = value;
71713760Sjairo.balart@metempsy.com
71813760Sjairo.balart@metempsy.com        ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
71913760Sjairo.balart@metempsy.com        ich_vtr_el2.A3V = 1;
72013760Sjairo.balart@metempsy.com        ich_vtr_el2.IDbits = 1;
72113760Sjairo.balart@metempsy.com        ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
72213760Sjairo.balart@metempsy.com        ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
72313760Sjairo.balart@metempsy.com
72413760Sjairo.balart@metempsy.com        value = ich_vtr_el2;
72513760Sjairo.balart@metempsy.com        break;
72613531Sjairo.balart@metempsy.com      }
72713531Sjairo.balart@metempsy.com
72813760Sjairo.balart@metempsy.com      // End of Interrupt Status Register
72913531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR:
73013531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR_EL2:
73113760Sjairo.balart@metempsy.com        value = eoiMaintenanceInterruptStatus();
73213531Sjairo.balart@metempsy.com        break;
73313531Sjairo.balart@metempsy.com
73413760Sjairo.balart@metempsy.com      // Empty List Register Status Register
73513531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR:
73613531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR_EL2:
73713531Sjairo.balart@metempsy.com        value = 0;
73813531Sjairo.balart@metempsy.com
73913531Sjairo.balart@metempsy.com        for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
74013760Sjairo.balart@metempsy.com            ICH_LR_EL2 ich_lr_el2 =
74113531Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
74213531Sjairo.balart@metempsy.com
74313760Sjairo.balart@metempsy.com            if ((ich_lr_el2.State  == ICH_LR_EL2_STATE_INVALID) &&
74413760Sjairo.balart@metempsy.com                (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
74513531Sjairo.balart@metempsy.com                value |= (1 << lr_idx);
74613531Sjairo.balart@metempsy.com            }
74713531Sjairo.balart@metempsy.com        }
74813531Sjairo.balart@metempsy.com
74913531Sjairo.balart@metempsy.com        break;
75013531Sjairo.balart@metempsy.com
75113760Sjairo.balart@metempsy.com      // List Registers
75213531Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
75313531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
75413531Sjairo.balart@metempsy.com        value = value >> 32;
75513531Sjairo.balart@metempsy.com        break;
75613531Sjairo.balart@metempsy.com
75713760Sjairo.balart@metempsy.com      // List Registers
75813531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
75913531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
76013531Sjairo.balart@metempsy.com        value = value & 0xffffffff;
76113531Sjairo.balart@metempsy.com        break;
76213531Sjairo.balart@metempsy.com
76313760Sjairo.balart@metempsy.com      // List Registers
76413531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
76513531Sjairo.balart@metempsy.com        break;
76613531Sjairo.balart@metempsy.com
76713760Sjairo.balart@metempsy.com      // Virtual Machine Control Register
76813531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
76913531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2:
77013531Sjairo.balart@metempsy.com        break;
77113531Sjairo.balart@metempsy.com
77213531Sjairo.balart@metempsy.com      default:
77313760Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
77413760Sjairo.balart@metempsy.com              misc_reg, miscRegName[misc_reg]);
77513531Sjairo.balart@metempsy.com    }
77613531Sjairo.balart@metempsy.com
77713760Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
77813760Sjairo.balart@metempsy.com            miscRegName[misc_reg], value);
77913531Sjairo.balart@metempsy.com    return value;
78013531Sjairo.balart@metempsy.com}
78113531Sjairo.balart@metempsy.com
78213531Sjairo.balart@metempsy.comvoid
78313580Sgabeblack@google.comGicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
78413531Sjairo.balart@metempsy.com{
78513531Sjairo.balart@metempsy.com    bool do_virtual_update = false;
78613760Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
78713760Sjairo.balart@metempsy.com            miscRegName[misc_reg], val);
78813531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
78913531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
79013531Sjairo.balart@metempsy.com
79113531Sjairo.balart@metempsy.com    switch (misc_reg) {
79213760Sjairo.balart@metempsy.com      // Active Priorities Group 1 Registers
79313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
79413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1:
79513531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
79613531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
79713531Sjairo.balart@metempsy.com        }
79813531Sjairo.balart@metempsy.com
79913531Sjairo.balart@metempsy.com        break;
80013531Sjairo.balart@metempsy.com
80113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
80213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
80313531Sjairo.balart@metempsy.com
80413531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
80513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
80613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
80713531Sjairo.balart@metempsy.com
80813531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
80913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
81013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
81113531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
81213531Sjairo.balart@metempsy.com        break;
81313531Sjairo.balart@metempsy.com
81413760Sjairo.balart@metempsy.com      // Active Priorities Group 0 Registers
81513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
81613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1:
81713531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
81813531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
81913531Sjairo.balart@metempsy.com        }
82013531Sjairo.balart@metempsy.com
82113531Sjairo.balart@metempsy.com        break;
82213531Sjairo.balart@metempsy.com
82313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
82413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
82513531Sjairo.balart@metempsy.com
82613531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
82713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
82813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
82913531Sjairo.balart@metempsy.com
83013531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
83113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
83213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
83313531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
83413531Sjairo.balart@metempsy.com        break;
83513531Sjairo.balart@metempsy.com
83613760Sjairo.balart@metempsy.com      // End Of Interrupt Register 0
83713531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0:
83813531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
83913531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
84013531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
84113531Sjairo.balart@metempsy.com          }
84213531Sjairo.balart@metempsy.com
84313531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
84413531Sjairo.balart@metempsy.com
84513531Sjairo.balart@metempsy.com          // avoid activation for special interrupts
84613923Sgiacomo.travaglini@arm.com          if (int_id >= Gicv3::INTID_SECURE &&
84713923Sgiacomo.travaglini@arm.com              int_id <= Gicv3::INTID_SPURIOUS) {
84813531Sjairo.balart@metempsy.com              return;
84913531Sjairo.balart@metempsy.com          }
85013531Sjairo.balart@metempsy.com
85113531Sjairo.balart@metempsy.com          Gicv3::GroupId group = Gicv3::G0S;
85213531Sjairo.balart@metempsy.com
85313531Sjairo.balart@metempsy.com          if (highestActiveGroup() != group) {
85413531Sjairo.balart@metempsy.com              return;
85513531Sjairo.balart@metempsy.com          }
85613531Sjairo.balart@metempsy.com
85713531Sjairo.balart@metempsy.com          dropPriority(group);
85813531Sjairo.balart@metempsy.com
85913531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
86013531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
86113531Sjairo.balart@metempsy.com          }
86213531Sjairo.balart@metempsy.com
86313531Sjairo.balart@metempsy.com          break;
86413531Sjairo.balart@metempsy.com      }
86513531Sjairo.balart@metempsy.com
86613760Sjairo.balart@metempsy.com      // Virtual End Of Interrupt Register 0
86713531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR0_EL1: {
86813531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
86913531Sjairo.balart@metempsy.com
87013531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
87113531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
87213531Sjairo.balart@metempsy.com                  int_id <= Gicv3::INTID_SPURIOUS) {
87313531Sjairo.balart@metempsy.com              return;
87413531Sjairo.balart@metempsy.com          }
87513531Sjairo.balart@metempsy.com
87613531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
87713531Sjairo.balart@metempsy.com
87813531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
87913531Sjairo.balart@metempsy.com              return;
88013531Sjairo.balart@metempsy.com          }
88113531Sjairo.balart@metempsy.com
88213531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
88313531Sjairo.balart@metempsy.com
88413531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
88513531Sjairo.balart@metempsy.com              // No LR found matching
88613531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
88713531Sjairo.balart@metempsy.com          } else {
88813760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
88913531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
89013531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
89113760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
89213760Sjairo.balart@metempsy.com              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
89313531Sjairo.balart@metempsy.com
89413531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
89513760Sjairo.balart@metempsy.com                  //if (!virtualIsEOISplitMode())
89613531Sjairo.balart@metempsy.com                  {
89713531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
89813531Sjairo.balart@metempsy.com                  }
89913531Sjairo.balart@metempsy.com              }
90013531Sjairo.balart@metempsy.com          }
90113531Sjairo.balart@metempsy.com
90213531Sjairo.balart@metempsy.com          virtualUpdate();
90313531Sjairo.balart@metempsy.com          break;
90413531Sjairo.balart@metempsy.com      }
90513531Sjairo.balart@metempsy.com
90613760Sjairo.balart@metempsy.com      // End Of Interrupt Register 1
90713531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1:
90813760Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1_EL1: {
90913531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
91013531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR1_EL1, val);
91113531Sjairo.balart@metempsy.com          }
91213531Sjairo.balart@metempsy.com
91313531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
91413531Sjairo.balart@metempsy.com
91513531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
91613923Sgiacomo.travaglini@arm.com          if (int_id >= Gicv3::INTID_SECURE &&
91713923Sgiacomo.travaglini@arm.com              int_id <= Gicv3::INTID_SPURIOUS) {
91813531Sjairo.balart@metempsy.com              return;
91913531Sjairo.balart@metempsy.com          }
92013531Sjairo.balart@metempsy.com
92113760Sjairo.balart@metempsy.com          Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
92213531Sjairo.balart@metempsy.com
92313531Sjairo.balart@metempsy.com          if (highestActiveGroup() == Gicv3::G0S) {
92413531Sjairo.balart@metempsy.com              return;
92513531Sjairo.balart@metempsy.com          }
92613531Sjairo.balart@metempsy.com
92713531Sjairo.balart@metempsy.com          if (distributor->DS == 0) {
92813531Sjairo.balart@metempsy.com              if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) {
92913531Sjairo.balart@metempsy.com                  return;
93013531Sjairo.balart@metempsy.com              } else if (highestActiveGroup() == Gicv3::G1NS &&
93113760Sjairo.balart@metempsy.com                         !(!inSecureState() or (currEL() == EL3))) {
93213531Sjairo.balart@metempsy.com                  return;
93313531Sjairo.balart@metempsy.com              }
93413531Sjairo.balart@metempsy.com          }
93513531Sjairo.balart@metempsy.com
93613531Sjairo.balart@metempsy.com          dropPriority(group);
93713531Sjairo.balart@metempsy.com
93813531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
93913531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
94013531Sjairo.balart@metempsy.com          }
94113531Sjairo.balart@metempsy.com
94213531Sjairo.balart@metempsy.com          break;
94313531Sjairo.balart@metempsy.com      }
94413531Sjairo.balart@metempsy.com
94513760Sjairo.balart@metempsy.com      // Virtual End Of Interrupt Register 1
94613531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR1_EL1: {
94713531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
94813531Sjairo.balart@metempsy.com
94913531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
95013531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
95113760Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
95213531Sjairo.balart@metempsy.com              return;
95313531Sjairo.balart@metempsy.com          }
95413531Sjairo.balart@metempsy.com
95513531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
95613531Sjairo.balart@metempsy.com
95713531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
95813531Sjairo.balart@metempsy.com              return;
95913531Sjairo.balart@metempsy.com          }
96013531Sjairo.balart@metempsy.com
96113531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
96213531Sjairo.balart@metempsy.com
96313531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
96413760Sjairo.balart@metempsy.com              // No matching LR found
96513531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
96613531Sjairo.balart@metempsy.com          } else {
96713760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
96813531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
96913531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
97013760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
97113760Sjairo.balart@metempsy.com              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
97213531Sjairo.balart@metempsy.com
97313531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
97413531Sjairo.balart@metempsy.com                  if (!virtualIsEOISplitMode()) {
97513531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
97613531Sjairo.balart@metempsy.com                  }
97713531Sjairo.balart@metempsy.com              }
97813531Sjairo.balart@metempsy.com          }
97913531Sjairo.balart@metempsy.com
98013531Sjairo.balart@metempsy.com          virtualUpdate();
98113531Sjairo.balart@metempsy.com          break;
98213531Sjairo.balart@metempsy.com      }
98313531Sjairo.balart@metempsy.com
98413760Sjairo.balart@metempsy.com      // Deactivate Interrupt Register
98513531Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR:
98613760Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR_EL1: {
98713531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
98813760Sjairo.balart@metempsy.com              (hcr_imo || hcr_fmo)) {
98913531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_DIR_EL1, val);
99013531Sjairo.balart@metempsy.com          }
99113531Sjairo.balart@metempsy.com
99213531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
99313531Sjairo.balart@metempsy.com
99413760Sjairo.balart@metempsy.com          // The following checks are as per spec pseudocode
99513760Sjairo.balart@metempsy.com          // aarch64/support/ICC_DIR_EL1
99613760Sjairo.balart@metempsy.com
99713760Sjairo.balart@metempsy.com          // Check for spurious ID
99813531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE) {
99913531Sjairo.balart@metempsy.com              return;
100013531Sjairo.balart@metempsy.com          }
100113531Sjairo.balart@metempsy.com
100213760Sjairo.balart@metempsy.com          // EOI mode is not set, so don't deactivate
100313531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
100413531Sjairo.balart@metempsy.com              return;
100513531Sjairo.balart@metempsy.com          }
100613531Sjairo.balart@metempsy.com
100713531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
100813531Sjairo.balart@metempsy.com              int_id >= 32 ? distributor->getIntGroup(int_id) :
100913531Sjairo.balart@metempsy.com              redistributor->getIntGroup(int_id);
101013531Sjairo.balart@metempsy.com          bool irq_is_grp0 = group == Gicv3::G0S;
101113531Sjairo.balart@metempsy.com          bool single_sec_state = distributor->DS;
101213531Sjairo.balart@metempsy.com          bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
101313531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
101413531Sjairo.balart@metempsy.com          bool route_fiq_to_el3 = scr_el3.fiq;
101513531Sjairo.balart@metempsy.com          bool route_irq_to_el3 = scr_el3.irq;
101613531Sjairo.balart@metempsy.com          bool route_fiq_to_el2 = hcr_fmo;
101713531Sjairo.balart@metempsy.com          bool route_irq_to_el2 = hcr_imo;
101813531Sjairo.balart@metempsy.com
101913531Sjairo.balart@metempsy.com          switch (currEL()) {
102013531Sjairo.balart@metempsy.com            case EL3:
102113531Sjairo.balart@metempsy.com              break;
102213531Sjairo.balart@metempsy.com
102313531Sjairo.balart@metempsy.com            case EL2:
102413531Sjairo.balart@metempsy.com              if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
102513531Sjairo.balart@metempsy.com                  break;
102613531Sjairo.balart@metempsy.com              }
102713531Sjairo.balart@metempsy.com
102813531Sjairo.balart@metempsy.com              if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
102913531Sjairo.balart@metempsy.com                  break;
103013531Sjairo.balart@metempsy.com              }
103113531Sjairo.balart@metempsy.com
103213531Sjairo.balart@metempsy.com              return;
103313531Sjairo.balart@metempsy.com
103413531Sjairo.balart@metempsy.com            case EL1:
103513531Sjairo.balart@metempsy.com              if (!isSecureBelowEL3()) {
103613531Sjairo.balart@metempsy.com                  if (single_sec_state && irq_is_grp0 &&
103713760Sjairo.balart@metempsy.com                      !route_fiq_to_el3 && !route_fiq_to_el2) {
103813531Sjairo.balart@metempsy.com                      break;
103913531Sjairo.balart@metempsy.com                  }
104013531Sjairo.balart@metempsy.com
104113531Sjairo.balart@metempsy.com                  if (!irq_is_secure && !irq_is_grp0 &&
104213760Sjairo.balart@metempsy.com                      !route_irq_to_el3 && !route_irq_to_el2) {
104313531Sjairo.balart@metempsy.com                      break;
104413531Sjairo.balart@metempsy.com                  }
104513531Sjairo.balart@metempsy.com              } else {
104613531Sjairo.balart@metempsy.com                  if (irq_is_grp0 && !route_fiq_to_el3) {
104713531Sjairo.balart@metempsy.com                      break;
104813531Sjairo.balart@metempsy.com                  }
104913531Sjairo.balart@metempsy.com
105013531Sjairo.balart@metempsy.com                  if (!irq_is_grp0 &&
105113760Sjairo.balart@metempsy.com                      (!irq_is_secure || !single_sec_state) &&
105213760Sjairo.balart@metempsy.com                      !route_irq_to_el3) {
105313531Sjairo.balart@metempsy.com                      break;
105413531Sjairo.balart@metempsy.com                  }
105513531Sjairo.balart@metempsy.com              }
105613531Sjairo.balart@metempsy.com
105713531Sjairo.balart@metempsy.com              return;
105813531Sjairo.balart@metempsy.com
105913531Sjairo.balart@metempsy.com            default:
106013531Sjairo.balart@metempsy.com              break;
106113531Sjairo.balart@metempsy.com          }
106213531Sjairo.balart@metempsy.com
106313531Sjairo.balart@metempsy.com          deactivateIRQ(int_id, group);
106413531Sjairo.balart@metempsy.com          break;
106513531Sjairo.balart@metempsy.com      }
106613531Sjairo.balart@metempsy.com
106713760Sjairo.balart@metempsy.com      // Deactivate Virtual Interrupt Register
106813531Sjairo.balart@metempsy.com      case MISCREG_ICV_DIR_EL1: {
106913531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
107013531Sjairo.balart@metempsy.com
107113531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
107213531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
107313760Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
107413531Sjairo.balart@metempsy.com              return;
107513531Sjairo.balart@metempsy.com          }
107613531Sjairo.balart@metempsy.com
107713531Sjairo.balart@metempsy.com          if (!virtualIsEOISplitMode()) {
107813531Sjairo.balart@metempsy.com              return;
107913531Sjairo.balart@metempsy.com          }
108013531Sjairo.balart@metempsy.com
108113531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
108213531Sjairo.balart@metempsy.com
108313531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
108413760Sjairo.balart@metempsy.com              // No matching LR found
108513531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
108613531Sjairo.balart@metempsy.com          } else {
108713531Sjairo.balart@metempsy.com              virtualDeactivateIRQ(lr_idx);
108813531Sjairo.balart@metempsy.com          }
108913531Sjairo.balart@metempsy.com
109013531Sjairo.balart@metempsy.com          virtualUpdate();
109113531Sjairo.balart@metempsy.com          break;
109213531Sjairo.balart@metempsy.com      }
109313531Sjairo.balart@metempsy.com
109413760Sjairo.balart@metempsy.com      // Binary Point Register 0
109513531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
109613760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0_EL1:
109713760Sjairo.balart@metempsy.com      // Binary Point Register 1
109813531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
109913760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: {
110013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState()) {
110113531Sjairo.balart@metempsy.com              if (misc_reg == MISCREG_ICC_BPR0_EL1 && hcr_fmo) {
110213531Sjairo.balart@metempsy.com                  return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
110313531Sjairo.balart@metempsy.com              } else if (misc_reg == MISCREG_ICC_BPR1_EL1 && hcr_imo) {
110413531Sjairo.balart@metempsy.com                  return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
110513531Sjairo.balart@metempsy.com              }
110613531Sjairo.balart@metempsy.com          }
110713531Sjairo.balart@metempsy.com
110813531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
110913531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;
111013531Sjairo.balart@metempsy.com
111113531Sjairo.balart@metempsy.com          if (group == Gicv3::G1S && !inSecureState()) {
111213531Sjairo.balart@metempsy.com              group = Gicv3::G1NS;
111313531Sjairo.balart@metempsy.com          }
111413531Sjairo.balart@metempsy.com
111513760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1_s =
111613760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
111713760Sjairo.balart@metempsy.com
111813760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1S) && !isEL3OrMon() &&
111913760Sjairo.balart@metempsy.com              icc_ctlr_el1_s.CBPR) {
112013531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
112113531Sjairo.balart@metempsy.com          }
112213531Sjairo.balart@metempsy.com
112313760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1_ns =
112413760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
112513760Sjairo.balart@metempsy.com
112613760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) && (currEL() < EL3) &&
112713760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.CBPR) {
112813760Sjairo.balart@metempsy.com              // BPR0 + 1 saturated to 7, WI
112913531Sjairo.balart@metempsy.com              return;
113013531Sjairo.balart@metempsy.com          }
113113531Sjairo.balart@metempsy.com
113213531Sjairo.balart@metempsy.com          uint8_t min_val = (group == Gicv3::G1NS) ?
113313531Sjairo.balart@metempsy.com              GIC_MIN_BPR_NS : GIC_MIN_BPR;
113413531Sjairo.balart@metempsy.com          val &= 0x7;
113513531Sjairo.balart@metempsy.com
113613531Sjairo.balart@metempsy.com          if (val < min_val) {
113713531Sjairo.balart@metempsy.com              val = min_val;
113813531Sjairo.balart@metempsy.com          }
113913531Sjairo.balart@metempsy.com
114013531Sjairo.balart@metempsy.com          break;
114113531Sjairo.balart@metempsy.com      }
114213531Sjairo.balart@metempsy.com
114313760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 0
114413531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR0_EL1:
114513760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 1
114613531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
114713531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
114813531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
114913760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
115013531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
115113531Sjairo.balart@metempsy.com
115213760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
115313760Sjairo.balart@metempsy.com              // BPR0 + 1 saturated to 7, WI
115413531Sjairo.balart@metempsy.com              return;
115513531Sjairo.balart@metempsy.com          }
115613531Sjairo.balart@metempsy.com
115713531Sjairo.balart@metempsy.com          uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
115813531Sjairo.balart@metempsy.com
115913531Sjairo.balart@metempsy.com          if (group != Gicv3::G0S) {
116013531Sjairo.balart@metempsy.com              min_VPBR++;
116113531Sjairo.balart@metempsy.com          }
116213531Sjairo.balart@metempsy.com
116313531Sjairo.balart@metempsy.com          if (val < min_VPBR) {
116413531Sjairo.balart@metempsy.com              val = min_VPBR;
116513531Sjairo.balart@metempsy.com          }
116613531Sjairo.balart@metempsy.com
116713531Sjairo.balart@metempsy.com          if (group == Gicv3::G0S) {
116813760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = val;
116913531Sjairo.balart@metempsy.com          } else {
117013760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = val;
117113531Sjairo.balart@metempsy.com          }
117213531Sjairo.balart@metempsy.com
117313531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
117413531Sjairo.balart@metempsy.com          do_virtual_update = true;
117513531Sjairo.balart@metempsy.com          break;
117613531Sjairo.balart@metempsy.com      }
117713531Sjairo.balart@metempsy.com
117813760Sjairo.balart@metempsy.com      // Control Register EL1
117913531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
118013760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: {
118113760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
118213531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
118313531Sjairo.balart@metempsy.com          }
118413531Sjairo.balart@metempsy.com
118513531Sjairo.balart@metempsy.com          /*
118613760Sjairo.balart@metempsy.com           * ExtRange is RO.
118713531Sjairo.balart@metempsy.com           * RSS is RO.
118813531Sjairo.balart@metempsy.com           * A3V is RO.
118913531Sjairo.balart@metempsy.com           * SEIS is RO.
119013531Sjairo.balart@metempsy.com           * IDbits is RO.
119113531Sjairo.balart@metempsy.com           * PRIbits is RO.
119213531Sjairo.balart@metempsy.com           */
119313760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
119413760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1 =
119513760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
119613760Sjairo.balart@metempsy.com
119713760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 =
119813760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
119913760Sjairo.balart@metempsy.com
120013760Sjairo.balart@metempsy.com          // The following could be refactored but it is following
120113760Sjairo.balart@metempsy.com          // spec description section 9.2.6 point by point.
120213760Sjairo.balart@metempsy.com
120313760Sjairo.balart@metempsy.com          // PMHE
120413760Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
120513760Sjairo.balart@metempsy.com              // PMHE is alias of ICC_CTLR_EL3.PMHE
120613760Sjairo.balart@metempsy.com
120713760Sjairo.balart@metempsy.com              if (distributor->DS == 0) {
120813760Sjairo.balart@metempsy.com                  // PMHE is RO
120913760Sjairo.balart@metempsy.com              } else if (distributor->DS == 1) {
121013760Sjairo.balart@metempsy.com                  // PMHE is RW
121113760Sjairo.balart@metempsy.com                  icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
121213760Sjairo.balart@metempsy.com                  icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
121313760Sjairo.balart@metempsy.com              }
121413531Sjairo.balart@metempsy.com          } else {
121513760Sjairo.balart@metempsy.com              // PMHE is RW (by implementation choice)
121613760Sjairo.balart@metempsy.com              icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
121713531Sjairo.balart@metempsy.com          }
121813531Sjairo.balart@metempsy.com
121913760Sjairo.balart@metempsy.com          // EOImode
122013760Sjairo.balart@metempsy.com          icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
122113760Sjairo.balart@metempsy.com
122213760Sjairo.balart@metempsy.com          if (inSecureState()) {
122313760Sjairo.balart@metempsy.com              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
122413760Sjairo.balart@metempsy.com              icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
122513760Sjairo.balart@metempsy.com          } else {
122613760Sjairo.balart@metempsy.com              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
122713760Sjairo.balart@metempsy.com              icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
122813760Sjairo.balart@metempsy.com          }
122913760Sjairo.balart@metempsy.com
123013760Sjairo.balart@metempsy.com          // CBPR
123113760Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
123213760Sjairo.balart@metempsy.com              // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
123313760Sjairo.balart@metempsy.com
123413760Sjairo.balart@metempsy.com              if (distributor->DS == 0) {
123513760Sjairo.balart@metempsy.com                  // CBPR is RO
123613760Sjairo.balart@metempsy.com              } else {
123713760Sjairo.balart@metempsy.com                  // CBPR is RW
123813760Sjairo.balart@metempsy.com                  icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
123913760Sjairo.balart@metempsy.com
124013760Sjairo.balart@metempsy.com                  if (inSecureState()) {
124113760Sjairo.balart@metempsy.com                      icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
124213760Sjairo.balart@metempsy.com                  } else {
124313760Sjairo.balart@metempsy.com                      icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
124413760Sjairo.balart@metempsy.com                  }
124513760Sjairo.balart@metempsy.com              }
124613760Sjairo.balart@metempsy.com          } else {
124713760Sjairo.balart@metempsy.com              // CBPR is RW
124813760Sjairo.balart@metempsy.com              icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
124913760Sjairo.balart@metempsy.com          }
125013760Sjairo.balart@metempsy.com
125113760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);
125213760Sjairo.balart@metempsy.com
125313760Sjairo.balart@metempsy.com          val = icc_ctlr_el1;
125413531Sjairo.balart@metempsy.com          break;
125513531Sjairo.balart@metempsy.com      }
125613531Sjairo.balart@metempsy.com
125713760Sjairo.balart@metempsy.com      // Virtual Control Register
125813531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
125913760Sjairo.balart@metempsy.com         ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
126013760Sjairo.balart@metempsy.com         ICV_CTLR_EL1 icv_ctlr_el1 =
126113760Sjairo.balart@metempsy.com             isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
126213760Sjairo.balart@metempsy.com         icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
126313760Sjairo.balart@metempsy.com         icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
126413760Sjairo.balart@metempsy.com         val = icv_ctlr_el1;
126513760Sjairo.balart@metempsy.com
126613760Sjairo.balart@metempsy.com         // Aliases
126713760Sjairo.balart@metempsy.com         // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
126813760Sjairo.balart@metempsy.com         // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
126913760Sjairo.balart@metempsy.com         ICH_VMCR_EL2 ich_vmcr_el2 =
127013760Sjairo.balart@metempsy.com             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
127113760Sjairo.balart@metempsy.com         ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
127213760Sjairo.balart@metempsy.com         ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
127313760Sjairo.balart@metempsy.com         isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
127413760Sjairo.balart@metempsy.com         break;
127513760Sjairo.balart@metempsy.com      }
127613760Sjairo.balart@metempsy.com
127713760Sjairo.balart@metempsy.com      // Control Register EL3
127813760Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
127913760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
128013760Sjairo.balart@metempsy.com          /*
128113760Sjairo.balart@metempsy.com           * ExtRange is RO.
128213760Sjairo.balart@metempsy.com           * RSS is RO.
128313760Sjairo.balart@metempsy.com           * nDS is RO.
128413760Sjairo.balart@metempsy.com           * A3V is RO.
128513760Sjairo.balart@metempsy.com           * SEIS is RO.
128613760Sjairo.balart@metempsy.com           * IDbits is RO.
128713760Sjairo.balart@metempsy.com           * PRIbits is RO.
128813760Sjairo.balart@metempsy.com           * PMHE is RAO/WI, priority-based routing is always used.
128913760Sjairo.balart@metempsy.com           */
129013760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
129113760Sjairo.balart@metempsy.com
129213760Sjairo.balart@metempsy.com          // Aliases
129313760Sjairo.balart@metempsy.com          if (haveEL(EL3))
129413760Sjairo.balart@metempsy.com          {
129513760Sjairo.balart@metempsy.com              ICC_CTLR_EL1 icc_ctlr_el1_s =
129613760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
129713760Sjairo.balart@metempsy.com              ICC_CTLR_EL1 icc_ctlr_el1_ns =
129813760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
129913760Sjairo.balart@metempsy.com
130013760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(NS).EOImode is an alias of
130113760Sjairo.balart@metempsy.com              // ICC_CTLR_EL3.EOImode_EL1NS
130213760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
130313760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(S).EOImode is an alias of
130413760Sjairo.balart@metempsy.com              // ICC_CTLR_EL3.EOImode_EL1S
130513760Sjairo.balart@metempsy.com              icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
130613760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
130713760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
130813760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
130913760Sjairo.balart@metempsy.com              icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
131013760Sjairo.balart@metempsy.com
131113760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
131213760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
131313760Sjairo.balart@metempsy.com                                      icc_ctlr_el1_ns);
131413760Sjairo.balart@metempsy.com          }
131513760Sjairo.balart@metempsy.com
131613760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 =
131713760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
131813760Sjairo.balart@metempsy.com
131913760Sjairo.balart@metempsy.com          icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
132013760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
132113760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
132213760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
132313760Sjairo.balart@metempsy.com          icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
132413760Sjairo.balart@metempsy.com          icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
132513760Sjairo.balart@metempsy.com
132613760Sjairo.balart@metempsy.com          val = icc_ctlr_el3;
132713531Sjairo.balart@metempsy.com          break;
132813531Sjairo.balart@metempsy.com      }
132913531Sjairo.balart@metempsy.com
133013760Sjairo.balart@metempsy.com      // Priority Mask Register
133113531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
133213760Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1: {
133313760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
133414057Sgiacomo.travaglini@arm.com              return setMiscReg(MISCREG_ICV_PMR_EL1, val);
133513531Sjairo.balart@metempsy.com          }
133613531Sjairo.balart@metempsy.com
133713531Sjairo.balart@metempsy.com          val &= 0xff;
133813531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
133913531Sjairo.balart@metempsy.com
134013531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
134113760Sjairo.balart@metempsy.com              // Spec section 4.8.1
134213760Sjairo.balart@metempsy.com              // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
134313580Sgabeblack@google.com              RegVal old_icc_pmr_el1 =
134413531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);
134513531Sjairo.balart@metempsy.com
134613531Sjairo.balart@metempsy.com              if (!(old_icc_pmr_el1 & 0x80)) {
134713760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
134813760Sjairo.balart@metempsy.com                  // 0x00-0x7F then WI
134913531Sjairo.balart@metempsy.com                  return;
135013531Sjairo.balart@metempsy.com              }
135113531Sjairo.balart@metempsy.com
135213760Sjairo.balart@metempsy.com              // If the current priority mask value is in the range of
135313760Sjairo.balart@metempsy.com              // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
135413760Sjairo.balart@metempsy.com              // based on the Non-secure read of the priority mask value
135513760Sjairo.balart@metempsy.com              // written to the register.
135613760Sjairo.balart@metempsy.com
135713531Sjairo.balart@metempsy.com              val = (val >> 1) | 0x80;
135813531Sjairo.balart@metempsy.com          }
135913531Sjairo.balart@metempsy.com
136013531Sjairo.balart@metempsy.com          val &= ~0U << (8 - PRIORITY_BITS);
136113531Sjairo.balart@metempsy.com          break;
136213531Sjairo.balart@metempsy.com      }
136313531Sjairo.balart@metempsy.com
136414057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
136514057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
136614057Sgiacomo.travaglini@arm.com             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
136714057Sgiacomo.travaglini@arm.com          ich_vmcr_el2.VPMR = val & 0xff;
136814057Sgiacomo.travaglini@arm.com
136914057Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
137014057Sgiacomo.travaglini@arm.com          virtualUpdate();
137114057Sgiacomo.travaglini@arm.com          return;
137214057Sgiacomo.travaglini@arm.com      }
137314057Sgiacomo.travaglini@arm.com
137413760Sjairo.balart@metempsy.com      // Interrupt Group 0 Enable Register EL1
137513760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
137613760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
137713760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
137813760Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
137913760Sjairo.balart@metempsy.com          }
138013760Sjairo.balart@metempsy.com
138113760Sjairo.balart@metempsy.com          break;
138213760Sjairo.balart@metempsy.com      }
138313760Sjairo.balart@metempsy.com
138413760Sjairo.balart@metempsy.com      // Virtual Interrupt Group 0 Enable register
138513760Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN0_EL1: {
138613760Sjairo.balart@metempsy.com          bool enable = val & 0x1;
138713760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
138813760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
138913760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG0 = enable;
139013740Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
139113740Sgiacomo.travaglini@arm.com          virtualUpdate();
139213740Sgiacomo.travaglini@arm.com          return;
139313740Sgiacomo.travaglini@arm.com      }
139413740Sgiacomo.travaglini@arm.com
139513760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL1
139613760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
139713760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
139813760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
139913760Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
140013760Sjairo.balart@metempsy.com          }
140113760Sjairo.balart@metempsy.com
140213760Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
140313760Sjairo.balart@metempsy.com              ICC_IGRPEN1_EL1 icc_igrpen1_el1 = val;
140413760Sjairo.balart@metempsy.com              ICC_IGRPEN1_EL3 icc_igrpen1_el3 =
140513760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3);
140613760Sjairo.balart@metempsy.com
140713760Sjairo.balart@metempsy.com              if (inSecureState()) {
140813760Sjairo.balart@metempsy.com                  // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1S
140913760Sjairo.balart@metempsy.com                  icc_igrpen1_el3.EnableGrp1S = icc_igrpen1_el1.Enable;
141013760Sjairo.balart@metempsy.com              } else {
141113760Sjairo.balart@metempsy.com                  // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1NS
141213760Sjairo.balart@metempsy.com                  icc_igrpen1_el3.EnableGrp1NS = icc_igrpen1_el1.Enable;
141313760Sjairo.balart@metempsy.com              }
141413760Sjairo.balart@metempsy.com
141513760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3,
141613760Sjairo.balart@metempsy.com                                      icc_igrpen1_el3);
141713531Sjairo.balart@metempsy.com          }
141813531Sjairo.balart@metempsy.com
141913531Sjairo.balart@metempsy.com          break;
142013531Sjairo.balart@metempsy.com      }
142113531Sjairo.balart@metempsy.com
142213760Sjairo.balart@metempsy.com      // Virtual Interrupt Group 1 Enable register
142313760Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN1_EL1: {
142413531Sjairo.balart@metempsy.com          bool enable = val & 0x1;
142513760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
142613531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
142713760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG1 = enable;
142813531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
142913531Sjairo.balart@metempsy.com          virtualUpdate();
143013531Sjairo.balart@metempsy.com          return;
143113531Sjairo.balart@metempsy.com      }
143213531Sjairo.balart@metempsy.com
143313760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register
143413760Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
143513760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL3: {
143613760Sjairo.balart@metempsy.com          ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
143713760Sjairo.balart@metempsy.com          ICC_IGRPEN1_EL1 icc_igrpen1_el1 =
143813760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1);
143913760Sjairo.balart@metempsy.com
144013760Sjairo.balart@metempsy.com          if (inSecureState()) {
144113760Sjairo.balart@metempsy.com              // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1S
144213760Sjairo.balart@metempsy.com              icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1S;
144313760Sjairo.balart@metempsy.com          } else {
144413760Sjairo.balart@metempsy.com              // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1NS
144513760Sjairo.balart@metempsy.com              icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1NS;
144613531Sjairo.balart@metempsy.com          }
144713531Sjairo.balart@metempsy.com
144813760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1, icc_igrpen1_el1);
144913531Sjairo.balart@metempsy.com          break;
145013531Sjairo.balart@metempsy.com      }
145113531Sjairo.balart@metempsy.com
145213760Sjairo.balart@metempsy.com      // Software Generated Interrupt Group 0 Register
145313531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R:
145413531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R_EL1:
145514227Sgiacomo.travaglini@arm.com        generateSGI(val, Gicv3::G0S);
145614227Sgiacomo.travaglini@arm.com        break;
145713531Sjairo.balart@metempsy.com
145813760Sjairo.balart@metempsy.com      // Software Generated Interrupt Group 1 Register
145913531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI1R:
146014227Sgiacomo.travaglini@arm.com      case MISCREG_ICC_SGI1R_EL1: {
146114227Sgiacomo.travaglini@arm.com        Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
146214227Sgiacomo.travaglini@arm.com
146314227Sgiacomo.travaglini@arm.com        generateSGI(val, group);
146414227Sgiacomo.travaglini@arm.com        break;
146514227Sgiacomo.travaglini@arm.com      }
146613531Sjairo.balart@metempsy.com
146713760Sjairo.balart@metempsy.com      // Alias Software Generated Interrupt Group 1 Register
146813531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R:
146913531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R_EL1: {
147014227Sgiacomo.travaglini@arm.com        Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S;
147114227Sgiacomo.travaglini@arm.com
147214227Sgiacomo.travaglini@arm.com        generateSGI(val, group);
147314227Sgiacomo.travaglini@arm.com        break;
147413531Sjairo.balart@metempsy.com      }
147513531Sjairo.balart@metempsy.com
147613760Sjairo.balart@metempsy.com      // System Register Enable Register EL1
147713531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
147813760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1:
147913760Sjairo.balart@metempsy.com      // System Register Enable Register EL2
148013531Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
148113760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2:
148213760Sjairo.balart@metempsy.com      // System Register Enable Register EL3
148313531Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
148413760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3:
148513760Sjairo.balart@metempsy.com        // All bits are RAO/WI
148613760Sjairo.balart@metempsy.com        return;
148713760Sjairo.balart@metempsy.com
148813760Sjairo.balart@metempsy.com      // Hyp Control Register
148913760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
149013760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2: {
149113760Sjairo.balart@metempsy.com        ICH_HCR_EL2 requested_ich_hcr_el2 = val;
149213760Sjairo.balart@metempsy.com        ICH_HCR_EL2 ich_hcr_el2 =
149313760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
149413760Sjairo.balart@metempsy.com
149513760Sjairo.balart@metempsy.com        if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
149613760Sjairo.balart@metempsy.com        {
149713760Sjairo.balart@metempsy.com            // EOIcount - Permitted behaviors are:
149813760Sjairo.balart@metempsy.com            // - Increment EOIcount.
149913760Sjairo.balart@metempsy.com            // - Leave EOIcount unchanged.
150013760Sjairo.balart@metempsy.com            ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
150113531Sjairo.balart@metempsy.com        }
150213531Sjairo.balart@metempsy.com
150313760Sjairo.balart@metempsy.com        ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
150413760Sjairo.balart@metempsy.com        ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
150513760Sjairo.balart@metempsy.com        ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
150613760Sjairo.balart@metempsy.com        ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
150713760Sjairo.balart@metempsy.com        ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
150813760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
150913760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
151013760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
151113760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
151213760Sjairo.balart@metempsy.com        ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
151313760Sjairo.balart@metempsy.com        ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
151413760Sjairo.balart@metempsy.com        ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
151513760Sjairo.balart@metempsy.com        ich_hcr_el2.En = requested_ich_hcr_el2.En;
151613760Sjairo.balart@metempsy.com        val = ich_hcr_el2;
151713531Sjairo.balart@metempsy.com        do_virtual_update = true;
151813531Sjairo.balart@metempsy.com        break;
151913760Sjairo.balart@metempsy.com      }
152013760Sjairo.balart@metempsy.com
152113760Sjairo.balart@metempsy.com      // List Registers
152213760Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
152313531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
152413760Sjairo.balart@metempsy.com        ICH_LRC requested_ich_lrc = val;
152513760Sjairo.balart@metempsy.com        ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
152613760Sjairo.balart@metempsy.com
152713760Sjairo.balart@metempsy.com        ich_lrc.State = requested_ich_lrc.State;
152813760Sjairo.balart@metempsy.com        ich_lrc.HW = requested_ich_lrc.HW;
152913760Sjairo.balart@metempsy.com        ich_lrc.Group = requested_ich_lrc.Group;
153013760Sjairo.balart@metempsy.com
153113760Sjairo.balart@metempsy.com        // Priority, bits [23:16]
153213760Sjairo.balart@metempsy.com        // At least five bits must be implemented.
153313760Sjairo.balart@metempsy.com        // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
153413760Sjairo.balart@metempsy.com        // We implement 5 bits.
153513760Sjairo.balart@metempsy.com        ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
153613760Sjairo.balart@metempsy.com                           (ich_lrc.Priority & 0x07);
153713760Sjairo.balart@metempsy.com
153813760Sjairo.balart@metempsy.com        // pINTID, bits [12:0]
153913760Sjairo.balart@metempsy.com        // When ICH_LR<n>.HW is 0 this field has the following meaning:
154013760Sjairo.balart@metempsy.com        // - Bits[12:10] : RES0.
154113760Sjairo.balart@metempsy.com        // - Bit[9] : EOI.
154213760Sjairo.balart@metempsy.com        // - Bits[8:0] : RES0.
154313760Sjairo.balart@metempsy.com        // When ICH_LR<n>.HW is 1:
154413760Sjairo.balart@metempsy.com        // - This field is only required to implement enough bits to hold a
154513760Sjairo.balart@metempsy.com        // valid value for the implemented INTID size. Any unused higher
154613760Sjairo.balart@metempsy.com        // order bits are RES0.
154713760Sjairo.balart@metempsy.com        if (requested_ich_lrc.HW == 0) {
154813760Sjairo.balart@metempsy.com            ich_lrc.EOI = requested_ich_lrc.EOI;
154913760Sjairo.balart@metempsy.com        } else {
155013760Sjairo.balart@metempsy.com            ich_lrc.pINTID = requested_ich_lrc.pINTID;
155113531Sjairo.balart@metempsy.com        }
155213531Sjairo.balart@metempsy.com
155313760Sjairo.balart@metempsy.com        val = ich_lrc;
155413760Sjairo.balart@metempsy.com        do_virtual_update = true;
155513760Sjairo.balart@metempsy.com        break;
155613760Sjairo.balart@metempsy.com      }
155713760Sjairo.balart@metempsy.com
155813760Sjairo.balart@metempsy.com      // List Registers
155913531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
156013531Sjairo.balart@metempsy.com          // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
156113580Sgabeblack@google.com          RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
156213531Sjairo.balart@metempsy.com          val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
156313531Sjairo.balart@metempsy.com          do_virtual_update = true;
156413531Sjairo.balart@metempsy.com          break;
156513531Sjairo.balart@metempsy.com      }
156613531Sjairo.balart@metempsy.com
156713760Sjairo.balart@metempsy.com      // List Registers
156813531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
156913760Sjairo.balart@metempsy.com          ICH_LR_EL2 requested_ich_lr_el2 = val;
157013760Sjairo.balart@metempsy.com          ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
157113760Sjairo.balart@metempsy.com
157213760Sjairo.balart@metempsy.com          ich_lr_el2.State = requested_ich_lr_el2.State;
157313760Sjairo.balart@metempsy.com          ich_lr_el2.HW = requested_ich_lr_el2.HW;
157413760Sjairo.balart@metempsy.com          ich_lr_el2.Group = requested_ich_lr_el2.Group;
157513760Sjairo.balart@metempsy.com
157613760Sjairo.balart@metempsy.com          // Priority, bits [55:48]
157713760Sjairo.balart@metempsy.com          // At least five bits must be implemented.
157813760Sjairo.balart@metempsy.com          // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
157913760Sjairo.balart@metempsy.com          // We implement 5 bits.
158013760Sjairo.balart@metempsy.com          ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
158113760Sjairo.balart@metempsy.com                                (ich_lr_el2.Priority & 0x07);
158213760Sjairo.balart@metempsy.com
158313760Sjairo.balart@metempsy.com          // pINTID, bits [44:32]
158413760Sjairo.balart@metempsy.com          // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
158513760Sjairo.balart@metempsy.com          // - Bits[44:42] : RES0.
158613760Sjairo.balart@metempsy.com          // - Bit[41] : EOI.
158713760Sjairo.balart@metempsy.com          // - Bits[40:32] : RES0.
158813760Sjairo.balart@metempsy.com          // When ICH_LR<n>_EL2.HW is 1:
158913760Sjairo.balart@metempsy.com          // - This field is only required to implement enough bits to hold a
159013760Sjairo.balart@metempsy.com          // valid value for the implemented INTID size. Any unused higher
159113760Sjairo.balart@metempsy.com          // order bits are RES0.
159213760Sjairo.balart@metempsy.com          if (requested_ich_lr_el2.HW == 0) {
159313760Sjairo.balart@metempsy.com              ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
159413760Sjairo.balart@metempsy.com          } else {
159513760Sjairo.balart@metempsy.com              ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
159613760Sjairo.balart@metempsy.com          }
159713760Sjairo.balart@metempsy.com
159813760Sjairo.balart@metempsy.com          // vINTID, bits [31:0]
159913760Sjairo.balart@metempsy.com          // It is IMPLEMENTATION DEFINED how many bits are implemented,
160013760Sjairo.balart@metempsy.com          // though at least 16 bits must be implemented.
160113760Sjairo.balart@metempsy.com          // Unimplemented bits are RES0.
160213760Sjairo.balart@metempsy.com          ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
160313760Sjairo.balart@metempsy.com
160413760Sjairo.balart@metempsy.com          val = ich_lr_el2;
160513531Sjairo.balart@metempsy.com          do_virtual_update = true;
160613531Sjairo.balart@metempsy.com          break;
160713531Sjairo.balart@metempsy.com      }
160813531Sjairo.balart@metempsy.com
160913760Sjairo.balart@metempsy.com      // Virtual Machine Control Register
161013531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
161113531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2: {
161213760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
161313760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
161413760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
161513760Sjairo.balart@metempsy.com          ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
161613531Sjairo.balart@metempsy.com          uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
161713760Sjairo.balart@metempsy.com
161813760Sjairo.balart@metempsy.com          if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
161913760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = min_vpr0;
162013760Sjairo.balart@metempsy.com          } else {
162113760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
162213760Sjairo.balart@metempsy.com          }
162313760Sjairo.balart@metempsy.com
162413531Sjairo.balart@metempsy.com          uint8_t min_vpr1 = min_vpr0 + 1;
162513760Sjairo.balart@metempsy.com
162613760Sjairo.balart@metempsy.com          if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
162713760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = min_vpr1;
162813760Sjairo.balart@metempsy.com          } else {
162913760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
163013760Sjairo.balart@metempsy.com          }
163113760Sjairo.balart@metempsy.com
163213760Sjairo.balart@metempsy.com          ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
163313760Sjairo.balart@metempsy.com          ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
163413760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
163513760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
163613760Sjairo.balart@metempsy.com          val = ich_vmcr_el2;
163713531Sjairo.balart@metempsy.com          break;
163813531Sjairo.balart@metempsy.com      }
163913531Sjairo.balart@metempsy.com
164013760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 0 Registers
164114236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R0:
164214236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R0_EL2:
164314236Sgiacomo.travaglini@arm.com        break;
164414236Sgiacomo.travaglini@arm.com
164514236Sgiacomo.travaglini@arm.com      // only implemented if supporting 6 or more bits of priority
164614236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R1:
164714236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R1_EL2:
164814236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
164914236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R2:
165014236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R2_EL2:
165114236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
165214236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R3:
165314236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R3_EL2:
165414236Sgiacomo.travaglini@arm.com        // Unimplemented registers are RAZ/WI
165514236Sgiacomo.travaglini@arm.com        return;
165614236Sgiacomo.travaglini@arm.com
165713760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 1 Registers
165814236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R0:
165914236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R0_EL2:
166013531Sjairo.balart@metempsy.com        break;
166113531Sjairo.balart@metempsy.com
166214236Sgiacomo.travaglini@arm.com      // only implemented if supporting 6 or more bits of priority
166314236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R1:
166414236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R1_EL2:
166514236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
166614236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R2:
166714236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R2_EL2:
166814236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
166914236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R3:
167014236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R3_EL2:
167114236Sgiacomo.travaglini@arm.com        // Unimplemented registers are RAZ/WI
167214236Sgiacomo.travaglini@arm.com        return;
167314236Sgiacomo.travaglini@arm.com
167413531Sjairo.balart@metempsy.com      default:
167513760Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
167613760Sjairo.balart@metempsy.com              misc_reg, miscRegName[misc_reg]);
167713531Sjairo.balart@metempsy.com    }
167813531Sjairo.balart@metempsy.com
167913531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(misc_reg, val);
168013531Sjairo.balart@metempsy.com
168113531Sjairo.balart@metempsy.com    if (do_virtual_update) {
168213531Sjairo.balart@metempsy.com        virtualUpdate();
168313531Sjairo.balart@metempsy.com    }
168413531Sjairo.balart@metempsy.com}
168513531Sjairo.balart@metempsy.com
168613531Sjairo.balart@metempsy.comint
168713760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualFindActive(uint32_t int_id) const
168813531Sjairo.balart@metempsy.com{
168913531Sjairo.balart@metempsy.com    for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
169013760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
169113531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
169213760Sjairo.balart@metempsy.com
169313760Sjairo.balart@metempsy.com        if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
169413760Sjairo.balart@metempsy.com             (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
169513760Sjairo.balart@metempsy.com            (ich_lr_el2.vINTID == int_id)) {
169613531Sjairo.balart@metempsy.com            return lr_idx;
169713531Sjairo.balart@metempsy.com        }
169813531Sjairo.balart@metempsy.com    }
169913531Sjairo.balart@metempsy.com
170013531Sjairo.balart@metempsy.com    return -1;
170113531Sjairo.balart@metempsy.com}
170213531Sjairo.balart@metempsy.com
170313531Sjairo.balart@metempsy.comuint32_t
170413760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR0() const
170513531Sjairo.balart@metempsy.com{
170614233Sgiacomo.travaglini@arm.com    if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
170713531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
170813531Sjairo.balart@metempsy.com    }
170913531Sjairo.balart@metempsy.com
171013531Sjairo.balart@metempsy.com    bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
171113531Sjairo.balart@metempsy.com
171213531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
171313760Sjairo.balart@metempsy.com        // interrupt for the other state pending
171413531Sjairo.balart@metempsy.com        return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
171513531Sjairo.balart@metempsy.com    }
171613531Sjairo.balart@metempsy.com
171713531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
171813531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
171913531Sjairo.balart@metempsy.com    }
172013531Sjairo.balart@metempsy.com
172113531Sjairo.balart@metempsy.com    if (irq_is_secure && !inSecureState()) {
172213531Sjairo.balart@metempsy.com        // Secure interrupts not visible in Non-secure
172313531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
172413531Sjairo.balart@metempsy.com    }
172513531Sjairo.balart@metempsy.com
172613531Sjairo.balart@metempsy.com    return hppi.intid;
172713531Sjairo.balart@metempsy.com}
172813531Sjairo.balart@metempsy.com
172913531Sjairo.balart@metempsy.comuint32_t
173013760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR1() const
173113531Sjairo.balart@metempsy.com{
173214233Sgiacomo.travaglini@arm.com    if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
173313531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
173413531Sjairo.balart@metempsy.com    }
173513531Sjairo.balart@metempsy.com
173613760Sjairo.balart@metempsy.com    ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
173713760Sjairo.balart@metempsy.com    if ((currEL() == EL3) && icc_ctlr_el3.RM) {
173813531Sjairo.balart@metempsy.com        if (hppi.group == Gicv3::G0S) {
173913531Sjairo.balart@metempsy.com            return Gicv3::INTID_SECURE;
174013531Sjairo.balart@metempsy.com        } else if (hppi.group == Gicv3::G1NS) {
174113531Sjairo.balart@metempsy.com            return Gicv3::INTID_NONSECURE;
174213531Sjairo.balart@metempsy.com        }
174313531Sjairo.balart@metempsy.com    }
174413531Sjairo.balart@metempsy.com
174513531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G0S) {
174613531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
174713531Sjairo.balart@metempsy.com    }
174813531Sjairo.balart@metempsy.com
174913531Sjairo.balart@metempsy.com    bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
175013531Sjairo.balart@metempsy.com
175113531Sjairo.balart@metempsy.com    if (irq_is_secure) {
175213531Sjairo.balart@metempsy.com        if (!inSecureState()) {
175313531Sjairo.balart@metempsy.com            // Secure interrupts not visible in Non-secure
175413531Sjairo.balart@metempsy.com            return Gicv3::INTID_SPURIOUS;
175513531Sjairo.balart@metempsy.com        }
175613531Sjairo.balart@metempsy.com    } else if (!isEL3OrMon() && inSecureState()) {
175713531Sjairo.balart@metempsy.com        // Group 1 non-secure interrupts not visible in Secure EL1
175813531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
175913531Sjairo.balart@metempsy.com    }
176013531Sjairo.balart@metempsy.com
176113531Sjairo.balart@metempsy.com    return hppi.intid;
176213531Sjairo.balart@metempsy.com}
176313531Sjairo.balart@metempsy.com
176413531Sjairo.balart@metempsy.comvoid
176513531Sjairo.balart@metempsy.comGicv3CPUInterface::dropPriority(Gicv3::GroupId group)
176613531Sjairo.balart@metempsy.com{
176713531Sjairo.balart@metempsy.com    int apr_misc_reg;
176813580Sgabeblack@google.com    RegVal apr;
176913531Sjairo.balart@metempsy.com    apr_misc_reg = group == Gicv3::G0S ?
177013531Sjairo.balart@metempsy.com                   MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
177113531Sjairo.balart@metempsy.com    apr = isa->readMiscRegNoEffect(apr_misc_reg);
177213531Sjairo.balart@metempsy.com
177313531Sjairo.balart@metempsy.com    if (apr) {
177413531Sjairo.balart@metempsy.com        apr &= apr - 1;
177513531Sjairo.balart@metempsy.com        isa->setMiscRegNoEffect(apr_misc_reg, apr);
177613531Sjairo.balart@metempsy.com    }
177713531Sjairo.balart@metempsy.com
177813531Sjairo.balart@metempsy.com    update();
177913531Sjairo.balart@metempsy.com}
178013531Sjairo.balart@metempsy.com
178113531Sjairo.balart@metempsy.comuint8_t
178213531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDropPriority()
178313531Sjairo.balart@metempsy.com{
178413531Sjairo.balart@metempsy.com    int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
178513531Sjairo.balart@metempsy.com
178613531Sjairo.balart@metempsy.com    for (int i = 0; i < apr_max; i++) {
178713580Sgabeblack@google.com        RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
178813580Sgabeblack@google.com        RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
178913531Sjairo.balart@metempsy.com
179013531Sjairo.balart@metempsy.com        if (!vapr0 && !vapr1) {
179113531Sjairo.balart@metempsy.com            continue;
179213531Sjairo.balart@metempsy.com        }
179313531Sjairo.balart@metempsy.com
179413531Sjairo.balart@metempsy.com        int vapr0_count = ctz32(vapr0);
179513531Sjairo.balart@metempsy.com        int vapr1_count = ctz32(vapr1);
179613531Sjairo.balart@metempsy.com
179713531Sjairo.balart@metempsy.com        if (vapr0_count <= vapr1_count) {
179813531Sjairo.balart@metempsy.com            vapr0 &= vapr0 - 1;
179913531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
180013531Sjairo.balart@metempsy.com            return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
180113531Sjairo.balart@metempsy.com        } else {
180213531Sjairo.balart@metempsy.com            vapr1 &= vapr1 - 1;
180313531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
180413531Sjairo.balart@metempsy.com            return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
180513531Sjairo.balart@metempsy.com        }
180613531Sjairo.balart@metempsy.com    }
180713531Sjairo.balart@metempsy.com
180813531Sjairo.balart@metempsy.com    return 0xff;
180913531Sjairo.balart@metempsy.com}
181013531Sjairo.balart@metempsy.com
181113531Sjairo.balart@metempsy.comvoid
181214227Sgiacomo.travaglini@arm.comGicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
181314227Sgiacomo.travaglini@arm.com{
181414227Sgiacomo.travaglini@arm.com    uint8_t aff3 = bits(val, 55, 48);
181514227Sgiacomo.travaglini@arm.com    uint8_t aff2 = bits(val, 39, 32);
181614227Sgiacomo.travaglini@arm.com    uint8_t aff1 = bits(val, 23, 16);;
181714227Sgiacomo.travaglini@arm.com    uint16_t target_list = bits(val, 15, 0);
181814227Sgiacomo.travaglini@arm.com    uint32_t int_id = bits(val, 27, 24);
181914227Sgiacomo.travaglini@arm.com    bool irm = bits(val, 40, 40);
182014227Sgiacomo.travaglini@arm.com    uint8_t rs = bits(val, 47, 44);
182114227Sgiacomo.travaglini@arm.com
182214227Sgiacomo.travaglini@arm.com    bool ns = !inSecureState();
182314227Sgiacomo.travaglini@arm.com
182414227Sgiacomo.travaglini@arm.com    for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
182514227Sgiacomo.travaglini@arm.com        Gicv3Redistributor * redistributor_i =
182614227Sgiacomo.travaglini@arm.com            gic->getRedistributor(i);
182714227Sgiacomo.travaglini@arm.com        uint32_t affinity_i = redistributor_i->getAffinity();
182814227Sgiacomo.travaglini@arm.com
182914227Sgiacomo.travaglini@arm.com        if (irm) {
183014227Sgiacomo.travaglini@arm.com            // Interrupts routed to all PEs in the system,
183114227Sgiacomo.travaglini@arm.com            // excluding "self"
183214227Sgiacomo.travaglini@arm.com            if (affinity_i == redistributor->getAffinity()) {
183314227Sgiacomo.travaglini@arm.com                continue;
183414227Sgiacomo.travaglini@arm.com            }
183514227Sgiacomo.travaglini@arm.com        } else {
183614227Sgiacomo.travaglini@arm.com            // Interrupts routed to the PEs specified by
183714227Sgiacomo.travaglini@arm.com            // Aff3.Aff2.Aff1.<target list>
183814227Sgiacomo.travaglini@arm.com            if ((affinity_i >> 8) !=
183914227Sgiacomo.travaglini@arm.com                ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
184014227Sgiacomo.travaglini@arm.com                continue;
184114227Sgiacomo.travaglini@arm.com            }
184214227Sgiacomo.travaglini@arm.com
184314227Sgiacomo.travaglini@arm.com            uint8_t aff0_i = bits(affinity_i, 7, 0);
184414227Sgiacomo.travaglini@arm.com
184514227Sgiacomo.travaglini@arm.com            if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
184614227Sgiacomo.travaglini@arm.com                ((0x1 << (aff0_i - rs * 16)) & target_list))) {
184714227Sgiacomo.travaglini@arm.com                continue;
184814227Sgiacomo.travaglini@arm.com            }
184914227Sgiacomo.travaglini@arm.com        }
185014227Sgiacomo.travaglini@arm.com
185114227Sgiacomo.travaglini@arm.com        redistributor_i->sendSGI(int_id, group, ns);
185214227Sgiacomo.travaglini@arm.com    }
185314227Sgiacomo.travaglini@arm.com}
185414227Sgiacomo.travaglini@arm.com
185514227Sgiacomo.travaglini@arm.comvoid
185613531Sjairo.balart@metempsy.comGicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
185713531Sjairo.balart@metempsy.com{
185813531Sjairo.balart@metempsy.com    // Update active priority registers.
185913531Sjairo.balart@metempsy.com    uint32_t prio = hppi.prio & 0xf8;
186013531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - PRIORITY_BITS);
186113531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
186213531Sjairo.balart@metempsy.com    int apr_idx = group == Gicv3::G0S ?
186313531Sjairo.balart@metempsy.com                 MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
186413580Sgabeblack@google.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
186513531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
186613531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
186713531Sjairo.balart@metempsy.com
186813531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
186913531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
187013531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
187113531Sjairo.balart@metempsy.com        redistributor->activateIRQ(int_id);
187213531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
187313531Sjairo.balart@metempsy.com        // SPI, distributor
187413531Sjairo.balart@metempsy.com        distributor->activateIRQ(int_id);
187513923Sgiacomo.travaglini@arm.com    } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
187613923Sgiacomo.travaglini@arm.com        // LPI, Redistributor
187713923Sgiacomo.travaglini@arm.com        redistributor->setClrLPI(int_id, false);
187813531Sjairo.balart@metempsy.com    }
187914231Sgiacomo.travaglini@arm.com
188014231Sgiacomo.travaglini@arm.com    // By setting the priority to 0xff we are effectively
188114231Sgiacomo.travaglini@arm.com    // making the int_id not pending anymore at the cpu
188214231Sgiacomo.travaglini@arm.com    // interface.
188314231Sgiacomo.travaglini@arm.com    hppi.prio = 0xff;
188414231Sgiacomo.travaglini@arm.com    updateDistributor();
188513531Sjairo.balart@metempsy.com}
188613531Sjairo.balart@metempsy.com
188713531Sjairo.balart@metempsy.comvoid
188813531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
188913531Sjairo.balart@metempsy.com{
189013531Sjairo.balart@metempsy.com    // Update active priority registers.
189113760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
189213531Sjairo.balart@metempsy.com            lr_idx);
189313760Sjairo.balart@metempsy.com    Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
189413760Sjairo.balart@metempsy.com    uint8_t prio = ich_lr_el.Priority & 0xf8;
189513531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
189613531Sjairo.balart@metempsy.com    int reg_no = apr_bit / 32;
189713531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
189813531Sjairo.balart@metempsy.com    int apr_idx = group == Gicv3::G0S ?
189913531Sjairo.balart@metempsy.com        MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
190013580Sgabeblack@google.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
190113531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
190213531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
190313531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
190413760Sjairo.balart@metempsy.com    ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
190513760Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
190613531Sjairo.balart@metempsy.com}
190713531Sjairo.balart@metempsy.com
190813531Sjairo.balart@metempsy.comvoid
190913531Sjairo.balart@metempsy.comGicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
191013531Sjairo.balart@metempsy.com{
191113531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
191213531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
191313531Sjairo.balart@metempsy.com        redistributor->deactivateIRQ(int_id);
191413531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
191513531Sjairo.balart@metempsy.com        // SPI, distributor
191613531Sjairo.balart@metempsy.com        distributor->deactivateIRQ(int_id);
191713531Sjairo.balart@metempsy.com    }
191814231Sgiacomo.travaglini@arm.com
191914231Sgiacomo.travaglini@arm.com    updateDistributor();
192013531Sjairo.balart@metempsy.com}
192113531Sjairo.balart@metempsy.com
192213531Sjairo.balart@metempsy.comvoid
192313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
192413531Sjairo.balart@metempsy.com{
192513760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
192613531Sjairo.balart@metempsy.com            lr_idx);
192713531Sjairo.balart@metempsy.com
192813760Sjairo.balart@metempsy.com    if (ich_lr_el2.HW) {
192913531Sjairo.balart@metempsy.com        // Deactivate the associated physical interrupt
193013760Sjairo.balart@metempsy.com        if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
193113760Sjairo.balart@metempsy.com            Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
193213760Sjairo.balart@metempsy.com                distributor->getIntGroup(ich_lr_el2.pINTID) :
193313760Sjairo.balart@metempsy.com                redistributor->getIntGroup(ich_lr_el2.pINTID);
193413760Sjairo.balart@metempsy.com            deactivateIRQ(ich_lr_el2.pINTID, group);
193513531Sjairo.balart@metempsy.com        }
193613531Sjairo.balart@metempsy.com    }
193713531Sjairo.balart@metempsy.com
193813531Sjairo.balart@metempsy.com    //  Remove the active bit
193913760Sjairo.balart@metempsy.com    ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
194013760Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
194113531Sjairo.balart@metempsy.com}
194213531Sjairo.balart@metempsy.com
194313531Sjairo.balart@metempsy.com/*
194413760Sjairo.balart@metempsy.com * Returns the priority group field for the current BPR value for the group.
194513760Sjairo.balart@metempsy.com * GroupBits() Pseudocode from spec.
194613531Sjairo.balart@metempsy.com */
194713531Sjairo.balart@metempsy.comuint32_t
194813926Sgiacomo.travaglini@arm.comGicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
194913531Sjairo.balart@metempsy.com{
195013760Sjairo.balart@metempsy.com    ICC_CTLR_EL1 icc_ctlr_el1_s =
195113760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
195213760Sjairo.balart@metempsy.com    ICC_CTLR_EL1 icc_ctlr_el1_ns =
195313760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
195413760Sjairo.balart@metempsy.com
195513760Sjairo.balart@metempsy.com    if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
195613760Sjairo.balart@metempsy.com        (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
195713531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
195813531Sjairo.balart@metempsy.com    }
195913531Sjairo.balart@metempsy.com
196013531Sjairo.balart@metempsy.com    int bpr;
196113531Sjairo.balart@metempsy.com
196213531Sjairo.balart@metempsy.com    if (group == Gicv3::G0S) {
196313926Sgiacomo.travaglini@arm.com        bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
196413531Sjairo.balart@metempsy.com    } else {
196513926Sgiacomo.travaglini@arm.com        bpr = readMiscReg(MISCREG_ICC_BPR1_EL1) & 0x7;
196613531Sjairo.balart@metempsy.com    }
196713531Sjairo.balart@metempsy.com
196813531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS) {
196913531Sjairo.balart@metempsy.com        assert(bpr > 0);
197013531Sjairo.balart@metempsy.com        bpr--;
197113531Sjairo.balart@metempsy.com    }
197213531Sjairo.balart@metempsy.com
197313531Sjairo.balart@metempsy.com    return ~0U << (bpr + 1);
197413531Sjairo.balart@metempsy.com}
197513531Sjairo.balart@metempsy.com
197613531Sjairo.balart@metempsy.comuint32_t
197713760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
197813531Sjairo.balart@metempsy.com{
197913760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 =
198013531Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
198113531Sjairo.balart@metempsy.com
198213760Sjairo.balart@metempsy.com    if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
198313531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
198413531Sjairo.balart@metempsy.com    }
198513531Sjairo.balart@metempsy.com
198613531Sjairo.balart@metempsy.com    int bpr;
198713531Sjairo.balart@metempsy.com
198813531Sjairo.balart@metempsy.com    if (group == Gicv3::G0S) {
198913760Sjairo.balart@metempsy.com        bpr = ich_vmcr_el2.VBPR0;
199013531Sjairo.balart@metempsy.com    } else {
199113760Sjairo.balart@metempsy.com        bpr = ich_vmcr_el2.VBPR1;
199213531Sjairo.balart@metempsy.com    }
199313531Sjairo.balart@metempsy.com
199413531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS) {
199513531Sjairo.balart@metempsy.com        assert(bpr > 0);
199613531Sjairo.balart@metempsy.com        bpr--;
199713531Sjairo.balart@metempsy.com    }
199813531Sjairo.balart@metempsy.com
199913531Sjairo.balart@metempsy.com    return ~0U << (bpr + 1);
200013531Sjairo.balart@metempsy.com}
200113531Sjairo.balart@metempsy.com
200213531Sjairo.balart@metempsy.combool
200313760Sjairo.balart@metempsy.comGicv3CPUInterface::isEOISplitMode() const
200413531Sjairo.balart@metempsy.com{
200513531Sjairo.balart@metempsy.com    if (isEL3OrMon()) {
200613760Sjairo.balart@metempsy.com        ICC_CTLR_EL3 icc_ctlr_el3 =
200713760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
200813760Sjairo.balart@metempsy.com        return icc_ctlr_el3.EOImode_EL3;
200913531Sjairo.balart@metempsy.com    } else {
201013760Sjairo.balart@metempsy.com        ICC_CTLR_EL1 icc_ctlr_el1 =
201113760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
201213760Sjairo.balart@metempsy.com        return icc_ctlr_el1.EOImode;
201313531Sjairo.balart@metempsy.com    }
201413531Sjairo.balart@metempsy.com}
201513531Sjairo.balart@metempsy.com
201613531Sjairo.balart@metempsy.combool
201713760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIsEOISplitMode() const
201813531Sjairo.balart@metempsy.com{
201913760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
202013760Sjairo.balart@metempsy.com    return ich_vmcr_el2.VEOIM;
202113531Sjairo.balart@metempsy.com}
202213531Sjairo.balart@metempsy.com
202313531Sjairo.balart@metempsy.comint
202413760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActiveGroup() const
202513531Sjairo.balart@metempsy.com{
202613531Sjairo.balart@metempsy.com    int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
202713531Sjairo.balart@metempsy.com    int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
202813531Sjairo.balart@metempsy.com    int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));
202913531Sjairo.balart@metempsy.com
203013531Sjairo.balart@metempsy.com    if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
203113531Sjairo.balart@metempsy.com        return Gicv3::G1NS;
203213531Sjairo.balart@metempsy.com    }
203313531Sjairo.balart@metempsy.com
203413531Sjairo.balart@metempsy.com    if (gq_ctz < g0_ctz) {
203513531Sjairo.balart@metempsy.com        return Gicv3::G1S;
203613531Sjairo.balart@metempsy.com    }
203713531Sjairo.balart@metempsy.com
203813531Sjairo.balart@metempsy.com    if (g0_ctz < 32) {
203913531Sjairo.balart@metempsy.com        return Gicv3::G0S;
204013531Sjairo.balart@metempsy.com    }
204113531Sjairo.balart@metempsy.com
204213531Sjairo.balart@metempsy.com    return -1;
204313531Sjairo.balart@metempsy.com}
204413531Sjairo.balart@metempsy.com
204513531Sjairo.balart@metempsy.comvoid
204614231Sgiacomo.travaglini@arm.comGicv3CPUInterface::updateDistributor()
204714231Sgiacomo.travaglini@arm.com{
204814231Sgiacomo.travaglini@arm.com    distributor->update();
204914231Sgiacomo.travaglini@arm.com}
205014231Sgiacomo.travaglini@arm.com
205114231Sgiacomo.travaglini@arm.comvoid
205213531Sjairo.balart@metempsy.comGicv3CPUInterface::update()
205313531Sjairo.balart@metempsy.com{
205413531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
205513531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
205613531Sjairo.balart@metempsy.com
205713531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
205813531Sjairo.balart@metempsy.com        /*
205913531Sjairo.balart@metempsy.com         * Secure enabled GIC sending a G1S IRQ to a secure disabled
206013531Sjairo.balart@metempsy.com         * CPU -> send G0 IRQ
206113531Sjairo.balart@metempsy.com         */
206213531Sjairo.balart@metempsy.com        hppi.group = Gicv3::G0S;
206313531Sjairo.balart@metempsy.com    }
206413531Sjairo.balart@metempsy.com
206513531Sjairo.balart@metempsy.com    if (hppiCanPreempt()) {
206613531Sjairo.balart@metempsy.com        ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
206713531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::update(): "
206813531Sjairo.balart@metempsy.com                "posting int as %d!\n", int_type);
206913531Sjairo.balart@metempsy.com        int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
207013531Sjairo.balart@metempsy.com    }
207113531Sjairo.balart@metempsy.com
207213531Sjairo.balart@metempsy.com    if (signal_IRQ) {
207313531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_IRQ);
207413531Sjairo.balart@metempsy.com    } else {
207513531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_IRQ);
207613531Sjairo.balart@metempsy.com    }
207713531Sjairo.balart@metempsy.com
207813531Sjairo.balart@metempsy.com    if (signal_FIQ) {
207913531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_FIQ);
208013531Sjairo.balart@metempsy.com    } else {
208113531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_FIQ);
208213531Sjairo.balart@metempsy.com    }
208313531Sjairo.balart@metempsy.com}
208413531Sjairo.balart@metempsy.com
208513531Sjairo.balart@metempsy.comvoid
208613531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualUpdate()
208713531Sjairo.balart@metempsy.com{
208813531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
208913531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
209013531Sjairo.balart@metempsy.com    int lr_idx = getHPPVILR();
209113531Sjairo.balart@metempsy.com
209213531Sjairo.balart@metempsy.com    if (lr_idx >= 0) {
209313760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
209413531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
209513531Sjairo.balart@metempsy.com
209613531Sjairo.balart@metempsy.com        if (hppviCanPreempt(lr_idx)) {
209713760Sjairo.balart@metempsy.com            if (ich_lr_el2.Group) {
209813531Sjairo.balart@metempsy.com                signal_IRQ = true;
209913531Sjairo.balart@metempsy.com            } else {
210013531Sjairo.balart@metempsy.com                signal_FIQ = true;
210113531Sjairo.balart@metempsy.com            }
210213531Sjairo.balart@metempsy.com        }
210313531Sjairo.balart@metempsy.com    }
210413531Sjairo.balart@metempsy.com
210513760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
210613760Sjairo.balart@metempsy.com
210713760Sjairo.balart@metempsy.com    if (ich_hcr_el2.En) {
210813531Sjairo.balart@metempsy.com        if (maintenanceInterruptStatus()) {
210913826Sgiacomo.travaglini@arm.com            maintenanceInterrupt->raise();
211013531Sjairo.balart@metempsy.com        }
211113531Sjairo.balart@metempsy.com    }
211213531Sjairo.balart@metempsy.com
211313531Sjairo.balart@metempsy.com    if (signal_IRQ) {
211413531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
211513531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
211613531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ);
211713531Sjairo.balart@metempsy.com    } else {
211813531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ);
211913531Sjairo.balart@metempsy.com    }
212013531Sjairo.balart@metempsy.com
212113531Sjairo.balart@metempsy.com    if (signal_FIQ) {
212213531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
212313531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
212413531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ);
212513531Sjairo.balart@metempsy.com    } else {
212613531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ);
212713531Sjairo.balart@metempsy.com    }
212813531Sjairo.balart@metempsy.com}
212913531Sjairo.balart@metempsy.com
213013760Sjairo.balart@metempsy.com// Returns the index of the LR with the HPPI
213113531Sjairo.balart@metempsy.comint
213213760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPVILR() const
213313531Sjairo.balart@metempsy.com{
213413531Sjairo.balart@metempsy.com    int idx = -1;
213513760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
213613760Sjairo.balart@metempsy.com
213713760Sjairo.balart@metempsy.com    if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
213813531Sjairo.balart@metempsy.com        // VG0 and VG1 disabled...
213913531Sjairo.balart@metempsy.com        return idx;
214013531Sjairo.balart@metempsy.com    }
214113531Sjairo.balart@metempsy.com
214213531Sjairo.balart@metempsy.com    uint8_t highest_prio = 0xff;
214313531Sjairo.balart@metempsy.com
214413531Sjairo.balart@metempsy.com    for (int i = 0; i < 16; i++) {
214513760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
214613531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
214713760Sjairo.balart@metempsy.com
214813760Sjairo.balart@metempsy.com        if (ich_lr_el2.State != Gicv3::INT_PENDING) {
214913531Sjairo.balart@metempsy.com            continue;
215013531Sjairo.balart@metempsy.com        }
215113531Sjairo.balart@metempsy.com
215213760Sjairo.balart@metempsy.com        if (ich_lr_el2.Group) {
215313531Sjairo.balart@metempsy.com            // VG1
215413760Sjairo.balart@metempsy.com            if (!ich_vmcr_el2.VENG1) {
215513531Sjairo.balart@metempsy.com                continue;
215613531Sjairo.balart@metempsy.com            }
215713531Sjairo.balart@metempsy.com        } else {
215813531Sjairo.balart@metempsy.com            // VG0
215913760Sjairo.balart@metempsy.com            if (!ich_vmcr_el2.VENG0) {
216013531Sjairo.balart@metempsy.com                continue;
216113531Sjairo.balart@metempsy.com            }
216213531Sjairo.balart@metempsy.com        }
216313531Sjairo.balart@metempsy.com
216413760Sjairo.balart@metempsy.com        uint8_t prio = ich_lr_el2.Priority;
216513531Sjairo.balart@metempsy.com
216613531Sjairo.balart@metempsy.com        if (prio < highest_prio) {
216713531Sjairo.balart@metempsy.com            highest_prio = prio;
216813531Sjairo.balart@metempsy.com            idx = i;
216913531Sjairo.balart@metempsy.com        }
217013531Sjairo.balart@metempsy.com    }
217113531Sjairo.balart@metempsy.com
217213531Sjairo.balart@metempsy.com    return idx;
217313531Sjairo.balart@metempsy.com}
217413531Sjairo.balart@metempsy.com
217513531Sjairo.balart@metempsy.combool
217613760Sjairo.balart@metempsy.comGicv3CPUInterface::hppviCanPreempt(int lr_idx) const
217713531Sjairo.balart@metempsy.com{
217813760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
217913760Sjairo.balart@metempsy.com    if (!ich_hcr_el2.En) {
218013531Sjairo.balart@metempsy.com        // virtual interface is disabled
218113531Sjairo.balart@metempsy.com        return false;
218213531Sjairo.balart@metempsy.com    }
218313531Sjairo.balart@metempsy.com
218413760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el2 =
218513760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
218613760Sjairo.balart@metempsy.com    uint8_t prio = ich_lr_el2.Priority;
218713531Sjairo.balart@metempsy.com    uint8_t vpmr =
218813531Sjairo.balart@metempsy.com        bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);
218913531Sjairo.balart@metempsy.com
219013531Sjairo.balart@metempsy.com    if (prio >= vpmr) {
219113531Sjairo.balart@metempsy.com        // prioriry masked
219213531Sjairo.balart@metempsy.com        return false;
219313531Sjairo.balart@metempsy.com    }
219413531Sjairo.balart@metempsy.com
219513531Sjairo.balart@metempsy.com    uint8_t rprio = virtualHighestActivePriority();
219613531Sjairo.balart@metempsy.com
219713531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
219813531Sjairo.balart@metempsy.com        return true;
219913531Sjairo.balart@metempsy.com    }
220013531Sjairo.balart@metempsy.com
220113760Sjairo.balart@metempsy.com    Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
220213531Sjairo.balart@metempsy.com    uint32_t prio_mask = virtualGroupPriorityMask(group);
220313531Sjairo.balart@metempsy.com
220413531Sjairo.balart@metempsy.com    if ((prio & prio_mask) < (rprio & prio_mask)) {
220513531Sjairo.balart@metempsy.com        return true;
220613531Sjairo.balart@metempsy.com    }
220713531Sjairo.balart@metempsy.com
220813531Sjairo.balart@metempsy.com    return false;
220913531Sjairo.balart@metempsy.com}
221013531Sjairo.balart@metempsy.com
221113531Sjairo.balart@metempsy.comuint8_t
221213760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualHighestActivePriority() const
221313531Sjairo.balart@metempsy.com{
221413531Sjairo.balart@metempsy.com    uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
221513531Sjairo.balart@metempsy.com
221613531Sjairo.balart@metempsy.com    for (int i = 0; i < num_aprs; i++) {
221713580Sgabeblack@google.com        RegVal vapr =
221813531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
221913531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
222013531Sjairo.balart@metempsy.com
222113531Sjairo.balart@metempsy.com        if (!vapr) {
222213531Sjairo.balart@metempsy.com            continue;
222313531Sjairo.balart@metempsy.com        }
222413531Sjairo.balart@metempsy.com
222513531Sjairo.balart@metempsy.com        return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
222613531Sjairo.balart@metempsy.com    }
222713531Sjairo.balart@metempsy.com
222813531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
222913531Sjairo.balart@metempsy.com    return 0xff;
223013531Sjairo.balart@metempsy.com}
223113531Sjairo.balart@metempsy.com
223213531Sjairo.balart@metempsy.comvoid
223313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIncrementEOICount()
223413531Sjairo.balart@metempsy.com{
223513531Sjairo.balart@metempsy.com    // Increment the EOICOUNT field in ICH_HCR_EL2
223613580Sgabeblack@google.com    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
223713531Sjairo.balart@metempsy.com    uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
223813531Sjairo.balart@metempsy.com    EOI_cout++;
223913531Sjairo.balart@metempsy.com    ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
224013531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
224113531Sjairo.balart@metempsy.com}
224213531Sjairo.balart@metempsy.com
224313760Sjairo.balart@metempsy.com// spec section 4.6.2
224413531Sjairo.balart@metempsy.comArmISA::InterruptTypes
224513760Sjairo.balart@metempsy.comGicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
224613531Sjairo.balart@metempsy.com{
224713531Sjairo.balart@metempsy.com    bool is_fiq = false;
224813531Sjairo.balart@metempsy.com
224913531Sjairo.balart@metempsy.com    switch (group) {
225013531Sjairo.balart@metempsy.com      case Gicv3::G0S:
225113531Sjairo.balart@metempsy.com        is_fiq = true;
225213531Sjairo.balart@metempsy.com        break;
225313531Sjairo.balart@metempsy.com
225413531Sjairo.balart@metempsy.com      case Gicv3::G1S:
225513531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) &&
225613531Sjairo.balart@metempsy.com            (!inSecureState() || ((currEL() == EL3) && isAA64()));
225713531Sjairo.balart@metempsy.com        break;
225813531Sjairo.balart@metempsy.com
225913531Sjairo.balart@metempsy.com      case Gicv3::G1NS:
226013531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) && inSecureState();
226113531Sjairo.balart@metempsy.com        break;
226213531Sjairo.balart@metempsy.com
226313531Sjairo.balart@metempsy.com      default:
226413531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::intSignalType(): invalid group!");
226513531Sjairo.balart@metempsy.com    }
226613531Sjairo.balart@metempsy.com
226713531Sjairo.balart@metempsy.com    if (is_fiq) {
226813531Sjairo.balart@metempsy.com        return ArmISA::INT_FIQ;
226913531Sjairo.balart@metempsy.com    } else {
227013531Sjairo.balart@metempsy.com        return ArmISA::INT_IRQ;
227113531Sjairo.balart@metempsy.com    }
227213531Sjairo.balart@metempsy.com}
227313531Sjairo.balart@metempsy.com
227413531Sjairo.balart@metempsy.combool
227513926Sgiacomo.travaglini@arm.comGicv3CPUInterface::hppiCanPreempt()
227613531Sjairo.balart@metempsy.com{
227713531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff) {
227813531Sjairo.balart@metempsy.com        // there is no pending interrupt
227913531Sjairo.balart@metempsy.com        return false;
228013531Sjairo.balart@metempsy.com    }
228113531Sjairo.balart@metempsy.com
228213531Sjairo.balart@metempsy.com    if (!groupEnabled(hppi.group)) {
228313531Sjairo.balart@metempsy.com        // group disabled at CPU interface
228413531Sjairo.balart@metempsy.com        return false;
228513531Sjairo.balart@metempsy.com    }
228613531Sjairo.balart@metempsy.com
228713531Sjairo.balart@metempsy.com    if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
228813531Sjairo.balart@metempsy.com        // priority masked
228913531Sjairo.balart@metempsy.com        return false;
229013531Sjairo.balart@metempsy.com    }
229113531Sjairo.balart@metempsy.com
229213531Sjairo.balart@metempsy.com    uint8_t rprio = highestActivePriority();
229313531Sjairo.balart@metempsy.com
229413531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
229513531Sjairo.balart@metempsy.com        return true;
229613531Sjairo.balart@metempsy.com    }
229713531Sjairo.balart@metempsy.com
229813531Sjairo.balart@metempsy.com    uint32_t prio_mask = groupPriorityMask(hppi.group);
229913531Sjairo.balart@metempsy.com
230013531Sjairo.balart@metempsy.com    if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
230113531Sjairo.balart@metempsy.com        return true;
230213531Sjairo.balart@metempsy.com    }
230313531Sjairo.balart@metempsy.com
230413531Sjairo.balart@metempsy.com    return false;
230513531Sjairo.balart@metempsy.com}
230613531Sjairo.balart@metempsy.com
230713531Sjairo.balart@metempsy.comuint8_t
230813760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActivePriority() const
230913531Sjairo.balart@metempsy.com{
231013531Sjairo.balart@metempsy.com    uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
231113531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
231213531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);
231313531Sjairo.balart@metempsy.com
231413531Sjairo.balart@metempsy.com    if (apr) {
231513531Sjairo.balart@metempsy.com        return ctz32(apr) << (GIC_MIN_BPR + 1);
231613531Sjairo.balart@metempsy.com    }
231713531Sjairo.balart@metempsy.com
231813531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
231913531Sjairo.balart@metempsy.com    return 0xff;
232013531Sjairo.balart@metempsy.com}
232113531Sjairo.balart@metempsy.com
232213531Sjairo.balart@metempsy.combool
232313760Sjairo.balart@metempsy.comGicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
232413531Sjairo.balart@metempsy.com{
232513531Sjairo.balart@metempsy.com    switch (group) {
232613760Sjairo.balart@metempsy.com      case Gicv3::G0S: {
232713760Sjairo.balart@metempsy.com        ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
232813760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
232914234Sgiacomo.travaglini@arm.com        return icc_igrpen0_el1.Enable && distributor->EnableGrp0;
233013760Sjairo.balart@metempsy.com      }
233113760Sjairo.balart@metempsy.com
233213760Sjairo.balart@metempsy.com      case Gicv3::G1S: {
233313760Sjairo.balart@metempsy.com        ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
233413760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
233514234Sgiacomo.travaglini@arm.com        return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
233613760Sjairo.balart@metempsy.com      }
233713760Sjairo.balart@metempsy.com
233813760Sjairo.balart@metempsy.com      case Gicv3::G1NS: {
233913760Sjairo.balart@metempsy.com        ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
234013760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
234114234Sgiacomo.travaglini@arm.com        return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS;
234213760Sjairo.balart@metempsy.com      }
234313531Sjairo.balart@metempsy.com
234413531Sjairo.balart@metempsy.com      default:
234513531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
234613531Sjairo.balart@metempsy.com    }
234713531Sjairo.balart@metempsy.com}
234813531Sjairo.balart@metempsy.com
234913531Sjairo.balart@metempsy.combool
235013760Sjairo.balart@metempsy.comGicv3CPUInterface::inSecureState() const
235113531Sjairo.balart@metempsy.com{
235213531Sjairo.balart@metempsy.com    if (!gic->getSystem()->haveSecurity()) {
235313531Sjairo.balart@metempsy.com        return false;
235413531Sjairo.balart@metempsy.com    }
235513531Sjairo.balart@metempsy.com
235613531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
235713531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
235813531Sjairo.balart@metempsy.com    return ArmISA::inSecureState(scr, cpsr);
235913531Sjairo.balart@metempsy.com}
236013531Sjairo.balart@metempsy.com
236113531Sjairo.balart@metempsy.comint
236213760Sjairo.balart@metempsy.comGicv3CPUInterface::currEL() const
236313531Sjairo.balart@metempsy.com{
236413531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
236513531Sjairo.balart@metempsy.com    bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
236613531Sjairo.balart@metempsy.com
236713531Sjairo.balart@metempsy.com    if (is_64) {
236813531Sjairo.balart@metempsy.com        return (ExceptionLevel)(uint8_t) cpsr.el;
236913531Sjairo.balart@metempsy.com    } else {
237013531Sjairo.balart@metempsy.com        switch (cpsr.mode) {
237113531Sjairo.balart@metempsy.com          case MODE_USER:
237213531Sjairo.balart@metempsy.com            return 0;
237313531Sjairo.balart@metempsy.com
237413531Sjairo.balart@metempsy.com          case MODE_HYP:
237513531Sjairo.balart@metempsy.com            return 2;
237613531Sjairo.balart@metempsy.com
237713531Sjairo.balart@metempsy.com          case MODE_MON:
237813531Sjairo.balart@metempsy.com            return 3;
237913531Sjairo.balart@metempsy.com
238013531Sjairo.balart@metempsy.com          default:
238113531Sjairo.balart@metempsy.com            return 1;
238213531Sjairo.balart@metempsy.com        }
238313531Sjairo.balart@metempsy.com    }
238413531Sjairo.balart@metempsy.com}
238513531Sjairo.balart@metempsy.com
238613531Sjairo.balart@metempsy.combool
238713760Sjairo.balart@metempsy.comGicv3CPUInterface::haveEL(ExceptionLevel el) const
238813531Sjairo.balart@metempsy.com{
238913531Sjairo.balart@metempsy.com    switch (el) {
239013531Sjairo.balart@metempsy.com      case EL0:
239113531Sjairo.balart@metempsy.com      case EL1:
239213531Sjairo.balart@metempsy.com        return true;
239313531Sjairo.balart@metempsy.com
239413531Sjairo.balart@metempsy.com      case EL2:
239513531Sjairo.balart@metempsy.com        return gic->getSystem()->haveVirtualization();
239613531Sjairo.balart@metempsy.com
239713531Sjairo.balart@metempsy.com      case EL3:
239813531Sjairo.balart@metempsy.com        return gic->getSystem()->haveSecurity();
239913531Sjairo.balart@metempsy.com
240013531Sjairo.balart@metempsy.com      default:
240113531Sjairo.balart@metempsy.com        warn("Unimplemented Exception Level\n");
240213531Sjairo.balart@metempsy.com        return false;
240313531Sjairo.balart@metempsy.com    }
240413531Sjairo.balart@metempsy.com}
240513531Sjairo.balart@metempsy.com
240613531Sjairo.balart@metempsy.combool
240713760Sjairo.balart@metempsy.comGicv3CPUInterface::isSecureBelowEL3() const
240813531Sjairo.balart@metempsy.com{
240913531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
241013531Sjairo.balart@metempsy.com    return haveEL(EL3) && scr.ns == 0;
241113531Sjairo.balart@metempsy.com}
241213531Sjairo.balart@metempsy.com
241313531Sjairo.balart@metempsy.combool
241413760Sjairo.balart@metempsy.comGicv3CPUInterface::isAA64() const
241513531Sjairo.balart@metempsy.com{
241613531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
241713531Sjairo.balart@metempsy.com    return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
241813531Sjairo.balart@metempsy.com}
241913531Sjairo.balart@metempsy.com
242013531Sjairo.balart@metempsy.combool
242113760Sjairo.balart@metempsy.comGicv3CPUInterface::isEL3OrMon() const
242213531Sjairo.balart@metempsy.com{
242313531Sjairo.balart@metempsy.com    if (haveEL(EL3)) {
242413531Sjairo.balart@metempsy.com        CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
242513531Sjairo.balart@metempsy.com        bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
242613531Sjairo.balart@metempsy.com
242713531Sjairo.balart@metempsy.com        if (is_64 && (cpsr.el == EL3)) {
242813531Sjairo.balart@metempsy.com            return true;
242913531Sjairo.balart@metempsy.com        } else if (!is_64 && (cpsr.mode == MODE_MON)) {
243013531Sjairo.balart@metempsy.com            return true;
243113531Sjairo.balart@metempsy.com        }
243213531Sjairo.balart@metempsy.com    }
243313531Sjairo.balart@metempsy.com
243413531Sjairo.balart@metempsy.com    return false;
243513531Sjairo.balart@metempsy.com}
243613531Sjairo.balart@metempsy.com
243713760Sjairo.balart@metempsy.com// Computes ICH_EISR_EL2
243813760Sjairo.balart@metempsy.comuint64_t
243913760Sjairo.balart@metempsy.comGicv3CPUInterface::eoiMaintenanceInterruptStatus() const
244013531Sjairo.balart@metempsy.com{
244113760Sjairo.balart@metempsy.com    // ICH_EISR_EL2
244213760Sjairo.balart@metempsy.com    // Bits [63:16] - RES0
244313760Sjairo.balart@metempsy.com    // Status<n>, bit [n], for n = 0 to 15
244413760Sjairo.balart@metempsy.com    //   EOI maintenance interrupt status bit for List register <n>:
244513760Sjairo.balart@metempsy.com    //     0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
244613760Sjairo.balart@metempsy.com    //     maintenance interrupt.
244713760Sjairo.balart@metempsy.com    //     1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
244813760Sjairo.balart@metempsy.com    //     interrupt that has not been handled.
244913760Sjairo.balart@metempsy.com    //
245013760Sjairo.balart@metempsy.com    // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
245113760Sjairo.balart@metempsy.com    // of the following are true:
245213760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
245313760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.HW is 0.
245413760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
245513760Sjairo.balart@metempsy.com
245613760Sjairo.balart@metempsy.com    uint64_t value = 0;
245713531Sjairo.balart@metempsy.com
245813531Sjairo.balart@metempsy.com    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
245913760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
246013760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
246113760Sjairo.balart@metempsy.com
246213760Sjairo.balart@metempsy.com        if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
246313760Sjairo.balart@metempsy.com            !ich_lr_el2.HW && ich_lr_el2.EOI) {
246413531Sjairo.balart@metempsy.com            value |= (1 << lr_idx);
246513531Sjairo.balart@metempsy.com        }
246613760Sjairo.balart@metempsy.com    }
246713760Sjairo.balart@metempsy.com
246813760Sjairo.balart@metempsy.com    return value;
246913760Sjairo.balart@metempsy.com}
247013760Sjairo.balart@metempsy.com
247113760Sjairo.balart@metempsy.comGicv3CPUInterface::ICH_MISR_EL2
247213760Sjairo.balart@metempsy.comGicv3CPUInterface::maintenanceInterruptStatus() const
247313760Sjairo.balart@metempsy.com{
247413760Sjairo.balart@metempsy.com    // Comments are copied from SPEC section 9.4.7 (ID012119)
247513760Sjairo.balart@metempsy.com    ICH_MISR_EL2 ich_misr_el2 = 0;
247613760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 =
247713760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
247813760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 =
247913760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
248013760Sjairo.balart@metempsy.com
248113760Sjairo.balart@metempsy.com    // End Of Interrupt. [bit 0]
248213760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when at least one bit in
248313760Sjairo.balart@metempsy.com    // ICH_EISR_EL2 is 1.
248413760Sjairo.balart@metempsy.com
248513760Sjairo.balart@metempsy.com    if (eoiMaintenanceInterruptStatus()) {
248613760Sjairo.balart@metempsy.com        ich_misr_el2.EOI = 1;
248713760Sjairo.balart@metempsy.com    }
248813760Sjairo.balart@metempsy.com
248913760Sjairo.balart@metempsy.com    // Underflow. [bit 1]
249013760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
249113760Sjairo.balart@metempsy.com    // zero or one of the List register entries are marked as a valid
249213760Sjairo.balart@metempsy.com    // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
249313760Sjairo.balart@metempsy.com    // do not equal 0x0.
249413760Sjairo.balart@metempsy.com    uint32_t num_valid_interrupts = 0;
249513760Sjairo.balart@metempsy.com    uint32_t num_pending_interrupts = 0;
249613760Sjairo.balart@metempsy.com
249713760Sjairo.balart@metempsy.com    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
249813760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
249913760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
250013760Sjairo.balart@metempsy.com
250113760Sjairo.balart@metempsy.com        if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
250213760Sjairo.balart@metempsy.com            num_valid_interrupts++;
250313531Sjairo.balart@metempsy.com        }
250413531Sjairo.balart@metempsy.com
250513760Sjairo.balart@metempsy.com        if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
250613760Sjairo.balart@metempsy.com            num_pending_interrupts++;
250713531Sjairo.balart@metempsy.com        }
250813531Sjairo.balart@metempsy.com    }
250913531Sjairo.balart@metempsy.com
251013760Sjairo.balart@metempsy.com    if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
251113760Sjairo.balart@metempsy.com        ich_misr_el2.U = 1;
251213531Sjairo.balart@metempsy.com    }
251313531Sjairo.balart@metempsy.com
251413760Sjairo.balart@metempsy.com    // List Register Entry Not Present. [bit 2]
251513760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
251613760Sjairo.balart@metempsy.com    // and ICH_HCR_EL2.EOIcount is non-zero.
251713760Sjairo.balart@metempsy.com    if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
251813760Sjairo.balart@metempsy.com        ich_misr_el2.LRENP = 1;
251913531Sjairo.balart@metempsy.com    }
252013531Sjairo.balart@metempsy.com
252113760Sjairo.balart@metempsy.com    // No Pending. [bit 3]
252213760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
252313760Sjairo.balart@metempsy.com    // no List register is in pending state.
252413760Sjairo.balart@metempsy.com    if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
252513760Sjairo.balart@metempsy.com        ich_misr_el2.NP = 1;
252613531Sjairo.balart@metempsy.com    }
252713531Sjairo.balart@metempsy.com
252813760Sjairo.balart@metempsy.com    // vPE Group 0 Enabled. [bit 4]
252913760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
253013760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
253113760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
253213760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp0E = 1;
253313531Sjairo.balart@metempsy.com    }
253413531Sjairo.balart@metempsy.com
253513760Sjairo.balart@metempsy.com    // vPE Group 0 Disabled. [bit 5]
253613760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
253713760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
253813760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
253913760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp0D = 1;
254013531Sjairo.balart@metempsy.com    }
254113531Sjairo.balart@metempsy.com
254213760Sjairo.balart@metempsy.com    // vPE Group 1 Enabled. [bit 6]
254313760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
254413760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
254513760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
254613760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp1E = 1;
254713531Sjairo.balart@metempsy.com    }
254813531Sjairo.balart@metempsy.com
254913760Sjairo.balart@metempsy.com    // vPE Group 1 Disabled. [bit 7]
255013760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
255113760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
255213760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
255313760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp1D = 1;
255413760Sjairo.balart@metempsy.com    }
255513760Sjairo.balart@metempsy.com
255613760Sjairo.balart@metempsy.com    return ich_misr_el2;
255713531Sjairo.balart@metempsy.com}
255813531Sjairo.balart@metempsy.com
255913531Sjairo.balart@metempsy.comvoid
256013531Sjairo.balart@metempsy.comGicv3CPUInterface::serialize(CheckpointOut & cp) const
256113531Sjairo.balart@metempsy.com{
256213531Sjairo.balart@metempsy.com    SERIALIZE_SCALAR(hppi.intid);
256313531Sjairo.balart@metempsy.com    SERIALIZE_SCALAR(hppi.prio);
256413531Sjairo.balart@metempsy.com    SERIALIZE_ENUM(hppi.group);
256513531Sjairo.balart@metempsy.com}
256613531Sjairo.balart@metempsy.com
256713531Sjairo.balart@metempsy.comvoid
256813531Sjairo.balart@metempsy.comGicv3CPUInterface::unserialize(CheckpointIn & cp)
256913531Sjairo.balart@metempsy.com{
257013531Sjairo.balart@metempsy.com    UNSERIALIZE_SCALAR(hppi.intid);
257113531Sjairo.balart@metempsy.com    UNSERIALIZE_SCALAR(hppi.prio);
257213531Sjairo.balart@metempsy.com    UNSERIALIZE_ENUM(hppi.group);
257313531Sjairo.balart@metempsy.com}
2574