gic_v3_cpu_interface.cc revision 13739
113531Sjairo.balart@metempsy.com/*
214227Sgiacomo.travaglini@arm.com * Copyright (c) 2018 Metempsy Technology Consulting
314227Sgiacomo.travaglini@arm.com * All rights reserved.
414227Sgiacomo.travaglini@arm.com *
514227Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without
614227Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are
714227Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright
814227Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer;
914227Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright
1014227Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the
1114227Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution;
1214227Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its
1314227Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from
1413531Sjairo.balart@metempsy.com * this software without specific prior written permission.
1513531Sjairo.balart@metempsy.com *
1613531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713531Sjairo.balart@metempsy.com *
2813531Sjairo.balart@metempsy.com * Authors: Jairo Balart
2913531Sjairo.balart@metempsy.com */
3013531Sjairo.balart@metempsy.com
3113531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh"
3213531Sjairo.balart@metempsy.com
3313531Sjairo.balart@metempsy.com#include "arch/arm/isa.hh"
3413531Sjairo.balart@metempsy.com#include "debug/GIC.hh"
3513531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh"
3613531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh"
3713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_redistributor.hh"
3813531Sjairo.balart@metempsy.com
3913531Sjairo.balart@metempsy.comGicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
4013531Sjairo.balart@metempsy.com    : BaseISADevice(),
4113531Sjairo.balart@metempsy.com      gic(gic),
4213531Sjairo.balart@metempsy.com      redistributor(nullptr),
4313531Sjairo.balart@metempsy.com      distributor(nullptr),
4413531Sjairo.balart@metempsy.com      cpuId(cpu_id)
4513531Sjairo.balart@metempsy.com{
4613531Sjairo.balart@metempsy.com}
4713531Sjairo.balart@metempsy.com
4813531Sjairo.balart@metempsy.comGicv3CPUInterface::~Gicv3CPUInterface()
4913531Sjairo.balart@metempsy.com{
5013531Sjairo.balart@metempsy.com}
5113926Sgiacomo.travaglini@arm.com
5213926Sgiacomo.travaglini@arm.comvoid
5313926Sgiacomo.travaglini@arm.comGicv3CPUInterface::init()
5413531Sjairo.balart@metempsy.com{
5513531Sjairo.balart@metempsy.com    redistributor = gic->getRedistributor(cpuId);
5613531Sjairo.balart@metempsy.com    distributor = gic->getDistributor();
5713531Sjairo.balart@metempsy.com}
5813531Sjairo.balart@metempsy.com
5913531Sjairo.balart@metempsy.comvoid
6013531Sjairo.balart@metempsy.comGicv3CPUInterface::initState()
6113531Sjairo.balart@metempsy.com{
6213531Sjairo.balart@metempsy.com    reset();
6313531Sjairo.balart@metempsy.com}
6413531Sjairo.balart@metempsy.com
6513531Sjairo.balart@metempsy.comvoid
6613531Sjairo.balart@metempsy.comGicv3CPUInterface::reset()
6713531Sjairo.balart@metempsy.com{
6813531Sjairo.balart@metempsy.com    hppi.prio = 0xff;
6913531Sjairo.balart@metempsy.com}
7013531Sjairo.balart@metempsy.com
7113531Sjairo.balart@metempsy.combool
7213531Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2FMO()
7313531Sjairo.balart@metempsy.com{
7413531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
7513531Sjairo.balart@metempsy.com
7613531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
7713531Sjairo.balart@metempsy.com        return false;
7813531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
7913531Sjairo.balart@metempsy.com        return true;
8013531Sjairo.balart@metempsy.com    } else {
8113531Sjairo.balart@metempsy.com        return hcr.fmo;
8213826Sgiacomo.travaglini@arm.com    }
8313826Sgiacomo.travaglini@arm.com}
8413826Sgiacomo.travaglini@arm.com
8513826Sgiacomo.travaglini@arm.combool
8613826Sgiacomo.travaglini@arm.comGicv3CPUInterface::getHCREL2IMO()
8713826Sgiacomo.travaglini@arm.com{
8813531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
8913760Sjairo.balart@metempsy.com
9013531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
9113531Sjairo.balart@metempsy.com        return false;
9213531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
9313531Sjairo.balart@metempsy.com        return true;
9413531Sjairo.balart@metempsy.com    } else {
9513531Sjairo.balart@metempsy.com        return hcr.imo;
9613531Sjairo.balart@metempsy.com    }
9713531Sjairo.balart@metempsy.com}
9813531Sjairo.balart@metempsy.com
9913531Sjairo.balart@metempsy.comRegVal
10013531Sjairo.balart@metempsy.comGicv3CPUInterface::readMiscReg(int misc_reg)
10113531Sjairo.balart@metempsy.com{
10213531Sjairo.balart@metempsy.com    RegVal value = isa->readMiscRegNoEffect(misc_reg);
10313760Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
10413531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
10513531Sjairo.balart@metempsy.com
10613531Sjairo.balart@metempsy.com    switch (misc_reg) {
10713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
10813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1: {
10913531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
11013531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
11113531Sjairo.balart@metempsy.com          }
11213531Sjairo.balart@metempsy.com
11313531Sjairo.balart@metempsy.com          break;
11413531Sjairo.balart@metempsy.com      }
11513531Sjairo.balart@metempsy.com
11613580Sgabeblack@google.com      case MISCREG_ICC_AP1R1:
11713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
11813531Sjairo.balart@metempsy.com
11913580Sgabeblack@google.com        // only implemented if supporting 6 or more bits of priority
12013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
12113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
12213531Sjairo.balart@metempsy.com
12313531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
12413760Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
12513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
12613531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
12713531Sjairo.balart@metempsy.com        return 0;
12813531Sjairo.balart@metempsy.com
12913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
13013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1: {
13114246Sgiacomo.travaglini@arm.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
13213531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
13313531Sjairo.balart@metempsy.com          }
13413531Sjairo.balart@metempsy.com
13513531Sjairo.balart@metempsy.com          break;
13613531Sjairo.balart@metempsy.com      }
13713531Sjairo.balart@metempsy.com
13813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
13913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
14013531Sjairo.balart@metempsy.com
14113531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
14213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
14313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
14413531Sjairo.balart@metempsy.com
14513531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
14613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
14713760Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
14813531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
14913531Sjairo.balart@metempsy.com        return 0;
15013531Sjairo.balart@metempsy.com
15113531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
15213531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
15313531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
15413531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
15513531Sjairo.balart@metempsy.com          }
15613531Sjairo.balart@metempsy.com
15713531Sjairo.balart@metempsy.com          break;
15813531Sjairo.balart@metempsy.com      }
15913531Sjairo.balart@metempsy.com
16013531Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN0_EL1: {
16113531Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
16213531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
16313531Sjairo.balart@metempsy.com          value = bits(ich_vmcr_el2, ICH_VMCR_EL2_VENG0_SHIFT);
16413531Sjairo.balart@metempsy.com          break;
16513531Sjairo.balart@metempsy.com      }
16613531Sjairo.balart@metempsy.com
16713531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
16813531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
16913531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
17013760Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
17113531Sjairo.balart@metempsy.com          }
17213531Sjairo.balart@metempsy.com
17313531Sjairo.balart@metempsy.com          break;
17414057Sgiacomo.travaglini@arm.com      }
17513531Sjairo.balart@metempsy.com
17613531Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN1_EL1: {
17713531Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
17813531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
17913531Sjairo.balart@metempsy.com          value = bits(ich_vmcr_el2, ICH_VMCR_EL2_VENG1_SHIFT);
18014057Sgiacomo.travaglini@arm.com          break;
18114057Sgiacomo.travaglini@arm.com      }
18214057Sgiacomo.travaglini@arm.com
18314057Sgiacomo.travaglini@arm.com      case MISCREG_ICC_MGRPEN1:
18414057Sgiacomo.travaglini@arm.com      case MISCREG_ICC_IGRPEN1_EL3: {
18514057Sgiacomo.travaglini@arm.com          // EnableGrp1S and EnableGrp1NS are aliased with
18614057Sgiacomo.travaglini@arm.com          // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable
18713760Sjairo.balart@metempsy.com          bool enable_grp_1s =
18813531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S) &
18913531Sjairo.balart@metempsy.com              ICC_IGRPEN1_EL1_ENABLE;
19013531Sjairo.balart@metempsy.com          bool enable_grp_1ns =
19114057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
19213531Sjairo.balart@metempsy.com              ICC_IGRPEN1_EL1_ENABLE;
19313531Sjairo.balart@metempsy.com          value = 0;
19414247Sgiacomo.travaglini@arm.com
19513531Sjairo.balart@metempsy.com          if (enable_grp_1s) {
19613531Sjairo.balart@metempsy.com              value |= ICC_IGRPEN1_EL3_ENABLEGRP1S;
19713531Sjairo.balart@metempsy.com          }
19814057Sgiacomo.travaglini@arm.com
19914057Sgiacomo.travaglini@arm.com          if (enable_grp_1ns) {
20014057Sgiacomo.travaglini@arm.com              value |= ICC_IGRPEN1_EL3_ENABLEGRP1NS;
20114057Sgiacomo.travaglini@arm.com          }
20214057Sgiacomo.travaglini@arm.com
20314057Sgiacomo.travaglini@arm.com          break;
20414057Sgiacomo.travaglini@arm.com      }
20513760Sjairo.balart@metempsy.com
20613760Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR:
20714254Sgiacomo.travaglini@arm.com      case MISCREG_ICC_RPR_EL1: {
20814254Sgiacomo.travaglini@arm.com          if ((currEL() == EL1) && !inSecureState() &&
20914254Sgiacomo.travaglini@arm.com                  (hcr_imo || hcr_fmo)) {
21014254Sgiacomo.travaglini@arm.com              return readMiscReg(MISCREG_ICV_RPR_EL1);
21114254Sgiacomo.travaglini@arm.com          }
21214254Sgiacomo.travaglini@arm.com
21314254Sgiacomo.travaglini@arm.com          uint8_t rprio = highestActivePriority();
21414254Sgiacomo.travaglini@arm.com
21514254Sgiacomo.travaglini@arm.com          if (haveEL(EL3) && !inSecureState() &&
21613739Sgiacomo.travaglini@arm.com                  (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
21714254Sgiacomo.travaglini@arm.com              /* NS GIC access and Group 0 is inaccessible to NS */
21813760Sjairo.balart@metempsy.com              if ((rprio & 0x80) == 0) {
21913760Sjairo.balart@metempsy.com                  /* NS should not see priorities in the Secure half of the
22013531Sjairo.balart@metempsy.com                   * range */
22113531Sjairo.balart@metempsy.com                  rprio = 0;
22213531Sjairo.balart@metempsy.com              } else if (rprio != 0xff) {
22313760Sjairo.balart@metempsy.com                  /* Non-idle priority: show the Non-secure view of it */
22413531Sjairo.balart@metempsy.com                  rprio = (rprio << 1) & 0xff;
22513531Sjairo.balart@metempsy.com              }
22613531Sjairo.balart@metempsy.com          }
22713531Sjairo.balart@metempsy.com
22813531Sjairo.balart@metempsy.com          value = rprio;
22913531Sjairo.balart@metempsy.com          break;
23013760Sjairo.balart@metempsy.com      }
23113760Sjairo.balart@metempsy.com
23213760Sjairo.balart@metempsy.com      case MISCREG_ICV_RPR_EL1: {
23313531Sjairo.balart@metempsy.com          value = virtualHighestActivePriority();
23413760Sjairo.balart@metempsy.com          break;
23513760Sjairo.balart@metempsy.com      }
23613531Sjairo.balart@metempsy.com
23713531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0:
23813760Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0_EL1: {
23913760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
24013760Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
24113531Sjairo.balart@metempsy.com          }
24213531Sjairo.balart@metempsy.com
24313531Sjairo.balart@metempsy.com          value = getHPPIR0();
24413531Sjairo.balart@metempsy.com          break;
24513531Sjairo.balart@metempsy.com      }
24613531Sjairo.balart@metempsy.com
24713531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR0_EL1: {
24813531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
24913760Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
25013531Sjairo.balart@metempsy.com
25113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
25213531Sjairo.balart@metempsy.com              RegVal lr =
25313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
25413531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
25513760Sjairo.balart@metempsy.com                  lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
25613531Sjairo.balart@metempsy.com
25713531Sjairo.balart@metempsy.com              if (group == Gicv3::G0S) {
25813531Sjairo.balart@metempsy.com                  value = bits(lr, 31, 0);
25913531Sjairo.balart@metempsy.com              }
26013531Sjairo.balart@metempsy.com          }
26113531Sjairo.balart@metempsy.com
26213531Sjairo.balart@metempsy.com          break;
26313531Sjairo.balart@metempsy.com      }
26413531Sjairo.balart@metempsy.com
26513531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1:
26613760Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1_EL1: {
26713531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
26813531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
26913531Sjairo.balart@metempsy.com          }
27013531Sjairo.balart@metempsy.com
27113531Sjairo.balart@metempsy.com          value = getHPPIR1();
27213760Sjairo.balart@metempsy.com          break;
27313531Sjairo.balart@metempsy.com      }
27413531Sjairo.balart@metempsy.com
27513760Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR1_EL1: {
27613531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
27713531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
27813760Sjairo.balart@metempsy.com
27913531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
28013531Sjairo.balart@metempsy.com              RegVal lr =
28113531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
28213531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
28313531Sjairo.balart@metempsy.com                  lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
28413531Sjairo.balart@metempsy.com
28513760Sjairo.balart@metempsy.com              if (group == Gicv3::G1NS) {
28613531Sjairo.balart@metempsy.com                  value = bits(lr, 31, 0);
28713531Sjairo.balart@metempsy.com              }
28813531Sjairo.balart@metempsy.com          }
28913531Sjairo.balart@metempsy.com
29013531Sjairo.balart@metempsy.com          break;
29113531Sjairo.balart@metempsy.com      }
29213531Sjairo.balart@metempsy.com
29313531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
29413531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0_EL1:
29513531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
29613760Sjairo.balart@metempsy.com            return readMiscReg(MISCREG_ICV_BPR0_EL1);
29713531Sjairo.balart@metempsy.com        }
29813531Sjairo.balart@metempsy.com
29913531Sjairo.balart@metempsy.com        M5_FALLTHROUGH;
30013531Sjairo.balart@metempsy.com
30113531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
30213760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1:
30313531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
30413531Sjairo.balart@metempsy.com            return readMiscReg(MISCREG_ICV_BPR1_EL1);
30513760Sjairo.balart@metempsy.com        }
30613531Sjairo.balart@metempsy.com
30713531Sjairo.balart@metempsy.com        {
30813760Sjairo.balart@metempsy.com            Gicv3::GroupId group =
30913531Sjairo.balart@metempsy.com                misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;
31013531Sjairo.balart@metempsy.com
31113531Sjairo.balart@metempsy.com            if (group == Gicv3::G1S && !inSecureState()) {
31213531Sjairo.balart@metempsy.com                group = Gicv3::G1NS;
31313531Sjairo.balart@metempsy.com            }
31413531Sjairo.balart@metempsy.com
31513760Sjairo.balart@metempsy.com            if ((group == Gicv3::G1S) &&
31613531Sjairo.balart@metempsy.com                    !isEL3OrMon() &&
31714237Sgiacomo.travaglini@arm.com                    (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S)
31813531Sjairo.balart@metempsy.com                     & ICC_CTLR_EL1_CBPR)) {
31913531Sjairo.balart@metempsy.com                group = Gicv3::G0S;
32013531Sjairo.balart@metempsy.com            }
32113531Sjairo.balart@metempsy.com
32214237Sgiacomo.travaglini@arm.com            bool sat_inc = false;
32314237Sgiacomo.travaglini@arm.com
32414237Sgiacomo.travaglini@arm.com            if ((group == Gicv3::G1NS) &&
32513531Sjairo.balart@metempsy.com                    (currEL() < EL3) &&
32613760Sjairo.balart@metempsy.com                    (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS)
32713531Sjairo.balart@metempsy.com                     & ICC_CTLR_EL1_CBPR)) {
32813760Sjairo.balart@metempsy.com                // Reads return BPR0 + 1 saturated to 7, WI
32914237Sgiacomo.travaglini@arm.com                group = Gicv3::G0S;
33014237Sgiacomo.travaglini@arm.com                sat_inc = true;
33113760Sjairo.balart@metempsy.com            }
33213760Sjairo.balart@metempsy.com
33314237Sgiacomo.travaglini@arm.com            uint8_t bpr;
33414237Sgiacomo.travaglini@arm.com
33514237Sgiacomo.travaglini@arm.com            if (group == Gicv3::G0S) {
33614237Sgiacomo.travaglini@arm.com                bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
33714237Sgiacomo.travaglini@arm.com            } else {
33814237Sgiacomo.travaglini@arm.com                bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1);
33914237Sgiacomo.travaglini@arm.com            }
34014237Sgiacomo.travaglini@arm.com
34114237Sgiacomo.travaglini@arm.com            if (sat_inc) {
34213760Sjairo.balart@metempsy.com                bpr++;
34313531Sjairo.balart@metempsy.com
34414237Sgiacomo.travaglini@arm.com                if (bpr > 7) {
34514237Sgiacomo.travaglini@arm.com                    bpr = 7;
34614237Sgiacomo.travaglini@arm.com                }
34714237Sgiacomo.travaglini@arm.com            }
34814237Sgiacomo.travaglini@arm.com
34914237Sgiacomo.travaglini@arm.com            value = bpr;
35014237Sgiacomo.travaglini@arm.com            break;
35114237Sgiacomo.travaglini@arm.com        }
35214237Sgiacomo.travaglini@arm.com
35314237Sgiacomo.travaglini@arm.com      case MISCREG_ICV_BPR0_EL1:
35414237Sgiacomo.travaglini@arm.com      case MISCREG_ICV_BPR1_EL1: {
35514237Sgiacomo.travaglini@arm.com          Gicv3::GroupId group =
35613531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
35713531Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
35813760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
35913531Sjairo.balart@metempsy.com          bool sat_inc = false;
36013760Sjairo.balart@metempsy.com
36113760Sjairo.balart@metempsy.com          if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
36214057Sgiacomo.travaglini@arm.com              // reads return bpr0 + 1 saturated to 7, writes ignored
36313531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
36413531Sjairo.balart@metempsy.com              sat_inc = true;
36513531Sjairo.balart@metempsy.com          }
36613760Sjairo.balart@metempsy.com
36713760Sjairo.balart@metempsy.com          uint8_t vbpr;
36813760Sjairo.balart@metempsy.com
36913531Sjairo.balart@metempsy.com          if (group == Gicv3::G0S) {
37013760Sjairo.balart@metempsy.com              vbpr = bits(ich_vmcr_el2, 23, 21);
37113760Sjairo.balart@metempsy.com          } else {
37213531Sjairo.balart@metempsy.com              vbpr = bits(ich_vmcr_el2, 20, 18);
37313531Sjairo.balart@metempsy.com          }
37413760Sjairo.balart@metempsy.com
37513760Sjairo.balart@metempsy.com          if (sat_inc) {
37613760Sjairo.balart@metempsy.com              vbpr++;
37713531Sjairo.balart@metempsy.com
37813531Sjairo.balart@metempsy.com              if (vbpr > 7) {
37913531Sjairo.balart@metempsy.com                  vbpr = 7;
38013531Sjairo.balart@metempsy.com              }
38113531Sjairo.balart@metempsy.com          }
38213531Sjairo.balart@metempsy.com
38314057Sgiacomo.travaglini@arm.com          value = vbpr;
38414057Sgiacomo.travaglini@arm.com          break;
38514057Sgiacomo.travaglini@arm.com      }
38614057Sgiacomo.travaglini@arm.com
38714057Sgiacomo.travaglini@arm.com      case MISCREG_ICC_PMR:
38814057Sgiacomo.travaglini@arm.com      case MISCREG_ICC_PMR_EL1: // Priority Mask Register
38914057Sgiacomo.travaglini@arm.com        if ((currEL() == EL1) && !inSecureState() &&
39014057Sgiacomo.travaglini@arm.com                (hcr_imo || hcr_fmo)) {
39113760Sjairo.balart@metempsy.com            return isa->readMiscRegNoEffect(MISCREG_ICV_PMR_EL1);
39213531Sjairo.balart@metempsy.com        }
39313760Sjairo.balart@metempsy.com
39413531Sjairo.balart@metempsy.com        if (haveEL(EL3) && !inSecureState() &&
39513531Sjairo.balart@metempsy.com                (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
39613531Sjairo.balart@metempsy.com            /* NS GIC access and Group 0 is inaccessible to NS */
39713531Sjairo.balart@metempsy.com            if ((value & 0x80) == 0) {
39813531Sjairo.balart@metempsy.com                /* NS should not see priorities in the Secure half of the
39913531Sjairo.balart@metempsy.com                 * range */
40013531Sjairo.balart@metempsy.com                value = 0;
40113531Sjairo.balart@metempsy.com            } else if (value != 0xff) {
40213531Sjairo.balart@metempsy.com                /* Non-idle priority: show the Non-secure view of it */
40313531Sjairo.balart@metempsy.com                value = (value << 1) & 0xff;
40413923Sgiacomo.travaglini@arm.com            }
40513923Sgiacomo.travaglini@arm.com        }
40613531Sjairo.balart@metempsy.com
40713531Sjairo.balart@metempsy.com        break;
40813531Sjairo.balart@metempsy.com
40913531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0:
41013531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0_EL1: { // Interrupt Acknowledge Register 0
41113531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
41213531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR0_EL1);
41313531Sjairo.balart@metempsy.com          }
41413531Sjairo.balart@metempsy.com
41513531Sjairo.balart@metempsy.com          uint32_t int_id;
41613760Sjairo.balart@metempsy.com
41713531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
41813531Sjairo.balart@metempsy.com              int_id = getHPPIR0();
41913531Sjairo.balart@metempsy.com
42013531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
42113531Sjairo.balart@metempsy.com              if (int_id < Gicv3::INTID_SECURE) {
42213760Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
42313531Sjairo.balart@metempsy.com              }
42413531Sjairo.balart@metempsy.com          } else {
42513760Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
42613760Sjairo.balart@metempsy.com          }
42713531Sjairo.balart@metempsy.com
42813531Sjairo.balart@metempsy.com          value = int_id;
42913760Sjairo.balart@metempsy.com          break;
43013531Sjairo.balart@metempsy.com      }
43113531Sjairo.balart@metempsy.com
43213531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR0_EL1: {
43313531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
43413531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
43513760Sjairo.balart@metempsy.com
43613531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
43713760Sjairo.balart@metempsy.com              RegVal lr =
43813531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
43913531Sjairo.balart@metempsy.com
44013531Sjairo.balart@metempsy.com              if (!(lr & ICH_LR_EL2_GROUP) && hppviCanPreempt(lr_idx)) {
44113531Sjairo.balart@metempsy.com                  int_id = value = bits(lr, 31, 0);
44213531Sjairo.balart@metempsy.com
44313531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
44413531Sjairo.balart@metempsy.com                          int_id > Gicv3::INTID_SPURIOUS) {
44513531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
44613531Sjairo.balart@metempsy.com                  } else {
44713760Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
44813531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
44913760Sjairo.balart@metempsy.com                      // - Return de bogus id...
45013531Sjairo.balart@metempsy.com                      lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
45113531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
45213531Sjairo.balart@metempsy.com                              lr);
45313531Sjairo.balart@metempsy.com                  }
45413531Sjairo.balart@metempsy.com              }
45513531Sjairo.balart@metempsy.com          }
45613531Sjairo.balart@metempsy.com
45713531Sjairo.balart@metempsy.com          value = int_id;
45813531Sjairo.balart@metempsy.com          virtualUpdate();
45913531Sjairo.balart@metempsy.com          break;
46013923Sgiacomo.travaglini@arm.com      }
46113923Sgiacomo.travaglini@arm.com
46213531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1:
46313531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1_EL1: { // Interrupt Acknowledge Register 1
46413531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
46513531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR1_EL1);
46613531Sjairo.balart@metempsy.com          }
46713531Sjairo.balart@metempsy.com
46813531Sjairo.balart@metempsy.com          uint32_t int_id;
46913531Sjairo.balart@metempsy.com
47013531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
47113531Sjairo.balart@metempsy.com              int_id = getHPPIR1();
47213760Sjairo.balart@metempsy.com
47313531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
47413531Sjairo.balart@metempsy.com              if (int_id < Gicv3::INTID_SECURE) {
47513531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
47613531Sjairo.balart@metempsy.com              }
47713531Sjairo.balart@metempsy.com
47813760Sjairo.balart@metempsy.com              // LPIs are not activated and when acked their pending
47913531Sjairo.balart@metempsy.com              // bit is cleared
48013531Sjairo.balart@metempsy.com              if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID)
48113760Sjairo.balart@metempsy.com              {
48213760Sjairo.balart@metempsy.com                  redistributor->setClrLPI(int_id, false);
48313531Sjairo.balart@metempsy.com              }
48413531Sjairo.balart@metempsy.com
48513760Sjairo.balart@metempsy.com          } else {
48613531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
48713531Sjairo.balart@metempsy.com          }
48813531Sjairo.balart@metempsy.com
48913531Sjairo.balart@metempsy.com          value = int_id;
49013531Sjairo.balart@metempsy.com          break;
49113760Sjairo.balart@metempsy.com      }
49213531Sjairo.balart@metempsy.com
49313760Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR1_EL1: {
49413531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
49513531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
49613531Sjairo.balart@metempsy.com
49713531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
49813531Sjairo.balart@metempsy.com              RegVal lr =
49913531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
50013531Sjairo.balart@metempsy.com
50113531Sjairo.balart@metempsy.com              if (lr & ICH_LR_EL2_GROUP && hppviCanPreempt(lr_idx)) {
50213531Sjairo.balart@metempsy.com                  int_id = value = bits(lr, 31, 0);
50313760Sjairo.balart@metempsy.com
50413531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
50513760Sjairo.balart@metempsy.com                          int_id > Gicv3::INTID_SPURIOUS) {
50613531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
50713531Sjairo.balart@metempsy.com                  } else {
50813531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
50913531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
51013531Sjairo.balart@metempsy.com                      // - Return de bogus id...
51113760Sjairo.balart@metempsy.com                      lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
51213760Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
51313760Sjairo.balart@metempsy.com                              lr);
51413760Sjairo.balart@metempsy.com                  }
51513760Sjairo.balart@metempsy.com              }
51613760Sjairo.balart@metempsy.com          }
51713760Sjairo.balart@metempsy.com
51813760Sjairo.balart@metempsy.com          value = int_id;
51913760Sjairo.balart@metempsy.com          virtualUpdate();
52013760Sjairo.balart@metempsy.com          break;
52113760Sjairo.balart@metempsy.com      }
52213531Sjairo.balart@metempsy.com
52313531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
52413760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1: { // System Register Enable Register
52513531Sjairo.balart@metempsy.com          bool dfb;
52613531Sjairo.balart@metempsy.com          bool dib;
52713531Sjairo.balart@metempsy.com
52813531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !distributor->DS) {
52913760Sjairo.balart@metempsy.com              // DIB is RO alias of ICC_SRE_EL3.DIB
53013760Sjairo.balart@metempsy.com              // DFB is RO alias of ICC_SRE_EL3.DFB
53113760Sjairo.balart@metempsy.com              RegVal icc_sre_el3 =
53213760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
53313760Sjairo.balart@metempsy.com              dfb = icc_sre_el3 & ICC_SRE_EL3_DFB;
53413760Sjairo.balart@metempsy.com              dib = icc_sre_el3 & ICC_SRE_EL3_DIB;
53513531Sjairo.balart@metempsy.com          } else if (haveEL(EL3) && distributor->DS) {
53613760Sjairo.balart@metempsy.com              // DIB is RW alias of ICC_SRE_EL3.DIB
53713760Sjairo.balart@metempsy.com              // DFB is RW alias of ICC_SRE_EL3.DFB
53813760Sjairo.balart@metempsy.com              RegVal icc_sre_el3 =
53913760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
54013760Sjairo.balart@metempsy.com              dfb = icc_sre_el3 & ICC_SRE_EL3_DFB;
54113760Sjairo.balart@metempsy.com              dib = icc_sre_el3 & ICC_SRE_EL3_DIB;
54213760Sjairo.balart@metempsy.com          } else if ((!haveEL(EL3) || distributor->DS) and haveEL(EL2)) {
54313760Sjairo.balart@metempsy.com              // DIB is RO alias of ICC_SRE_EL2.DIB
54413760Sjairo.balart@metempsy.com              // DFB is RO alias of ICC_SRE_EL2.DFB
54513760Sjairo.balart@metempsy.com              RegVal icc_sre_el2 =
54613760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL2);
54713760Sjairo.balart@metempsy.com              dfb = icc_sre_el2 & ICC_SRE_EL2_DFB;
54813760Sjairo.balart@metempsy.com              dib = icc_sre_el2 & ICC_SRE_EL2_DIB;
54913760Sjairo.balart@metempsy.com          } else {
55013760Sjairo.balart@metempsy.com              dfb = value & ICC_SRE_EL1_DFB;
55113760Sjairo.balart@metempsy.com              dib = value & ICC_SRE_EL1_DIB;
55213760Sjairo.balart@metempsy.com          }
55313760Sjairo.balart@metempsy.com
55413760Sjairo.balart@metempsy.com          value = ICC_SRE_EL1_SRE;
55513760Sjairo.balart@metempsy.com
55613760Sjairo.balart@metempsy.com          if (dfb) {
55713760Sjairo.balart@metempsy.com              value |= ICC_SRE_EL1_DFB;
55813760Sjairo.balart@metempsy.com          }
55913760Sjairo.balart@metempsy.com
56013531Sjairo.balart@metempsy.com          if (dib) {
56113760Sjairo.balart@metempsy.com              value |= ICC_SRE_EL1_DIB;
56213760Sjairo.balart@metempsy.com          }
56313531Sjairo.balart@metempsy.com
56413531Sjairo.balart@metempsy.com          break;
56513531Sjairo.balart@metempsy.com      }
56614245Sgiacomo.travaglini@arm.com
56713760Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
56813760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2: // System Register Enable Register
56913760Sjairo.balart@metempsy.com        /*
57013760Sjairo.balart@metempsy.com         * Enable [3] == 1
57113760Sjairo.balart@metempsy.com         * (Secure EL1 accesses to Secure ICC_SRE_EL1 do not trap to EL2,
57213760Sjairo.balart@metempsy.com         * RAO/WI)
57313531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
57413531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
57513760Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
57613760Sjairo.balart@metempsy.com         */
57713760Sjairo.balart@metempsy.com        value = ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_DIB | ICC_SRE_EL2_DFB |
57813760Sjairo.balart@metempsy.com            ICC_SRE_EL2_SRE;
57913760Sjairo.balart@metempsy.com        break;
58013760Sjairo.balart@metempsy.com
58113760Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
58213760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3: // System Register Enable Register
58313531Sjairo.balart@metempsy.com        /*
58413531Sjairo.balart@metempsy.com         * Enable [3] == 1
58513531Sjairo.balart@metempsy.com         * (Secure EL1 accesses to Secure ICC_SRE_EL1 do not trap to EL3,
58613760Sjairo.balart@metempsy.com         * RAO/WI)
58713531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
58813760Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
58913760Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
59013760Sjairo.balart@metempsy.com         */
59113760Sjairo.balart@metempsy.com        value = ICC_SRE_EL3_ENABLE | ICC_SRE_EL3_DIB | ICC_SRE_EL3_DFB |
59213760Sjairo.balart@metempsy.com            ICC_SRE_EL3_SRE;
59313760Sjairo.balart@metempsy.com        break;
59413760Sjairo.balart@metempsy.com
59513531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
59613531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: { // Control Register
59713531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
59813760Sjairo.balart@metempsy.com                  (hcr_imo || hcr_fmo)) {
59913531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_CTLR_EL1);
60013531Sjairo.balart@metempsy.com          }
60113760Sjairo.balart@metempsy.com
60213760Sjairo.balart@metempsy.com          // Add value for RO bits
60313760Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
60413760Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
60513760Sjairo.balart@metempsy.com          value |= ICC_CTLR_EL1_RSS | ICC_CTLR_EL1_A3V |
60613760Sjairo.balart@metempsy.com              (1 << 11) | ((PRIORITY_BITS - 1) << 8);
60713760Sjairo.balart@metempsy.com          break;
60813531Sjairo.balart@metempsy.com      }
60913531Sjairo.balart@metempsy.com
61013760Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
61113760Sjairo.balart@metempsy.com          value = ICC_CTLR_EL1_A3V | (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
61213760Sjairo.balart@metempsy.com              (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
61313760Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
61413760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
61513760Sjairo.balart@metempsy.com
61613760Sjairo.balart@metempsy.com          if (ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM) {
61713760Sjairo.balart@metempsy.com              value |= ICC_CTLR_EL1_EOIMODE;
61813760Sjairo.balart@metempsy.com          }
61913531Sjairo.balart@metempsy.com
62013531Sjairo.balart@metempsy.com          if (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) {
62113531Sjairo.balart@metempsy.com              value |= ICC_CTLR_EL1_CBPR;
62213760Sjairo.balart@metempsy.com          }
62313531Sjairo.balart@metempsy.com
62413531Sjairo.balart@metempsy.com          break;
62513531Sjairo.balart@metempsy.com      }
62613531Sjairo.balart@metempsy.com
62713760Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
62813531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
62913531Sjairo.balart@metempsy.com          // Add value for RO bits
63013531Sjairo.balart@metempsy.com          // RSS [18]
63113531Sjairo.balart@metempsy.com          // A3V [15]
63214236Sgiacomo.travaglini@arm.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
63314236Sgiacomo.travaglini@arm.com          // PRIbits [10:8], number of priority bits implemented, minus one
63414236Sgiacomo.travaglini@arm.com          value |= ICC_CTLR_EL3_RSS | ICC_CTLR_EL3_A3V | (0 << 11) |
63514236Sgiacomo.travaglini@arm.com              ((PRIORITY_BITS - 1) << 8);
63614236Sgiacomo.travaglini@arm.com          // Aliased bits...
63714236Sgiacomo.travaglini@arm.com          RegVal icc_ctlr_el1_ns =
63814236Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
63914236Sgiacomo.travaglini@arm.com          RegVal icc_ctlr_el1_s =
64014236Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
64114236Sgiacomo.travaglini@arm.com
64214236Sgiacomo.travaglini@arm.com          if (icc_ctlr_el1_ns & ICC_CTLR_EL1_EOIMODE) {
64314236Sgiacomo.travaglini@arm.com              value |= ICC_CTLR_EL3_EOIMODE_EL1NS;
64413760Sjairo.balart@metempsy.com          }
64513531Sjairo.balart@metempsy.com
64613531Sjairo.balart@metempsy.com          if (icc_ctlr_el1_ns & ICC_CTLR_EL1_CBPR) {
64713531Sjairo.balart@metempsy.com              value |= ICC_CTLR_EL3_CBPR_EL1NS;
64813531Sjairo.balart@metempsy.com          }
64914236Sgiacomo.travaglini@arm.com
65014236Sgiacomo.travaglini@arm.com          if (icc_ctlr_el1_s & ICC_CTLR_EL1_EOIMODE) {
65114236Sgiacomo.travaglini@arm.com              value |= ICC_CTLR_EL3_EOIMODE_EL1S;
65214236Sgiacomo.travaglini@arm.com          }
65314236Sgiacomo.travaglini@arm.com
65414236Sgiacomo.travaglini@arm.com          if (icc_ctlr_el1_s & ICC_CTLR_EL1_CBPR) {
65514236Sgiacomo.travaglini@arm.com              value |= ICC_CTLR_EL3_CBPR_EL1S;
65614236Sgiacomo.travaglini@arm.com          }
65714236Sgiacomo.travaglini@arm.com
65814236Sgiacomo.travaglini@arm.com          break;
65914236Sgiacomo.travaglini@arm.com      }
66014236Sgiacomo.travaglini@arm.com
66113760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
66213531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2:
66313760Sjairo.balart@metempsy.com        break;
66413760Sjairo.balart@metempsy.com
66513760Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0:
66613760Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0_EL2:
66713760Sjairo.balart@metempsy.com        break;
66813760Sjairo.balart@metempsy.com
66913760Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0:
67013760Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0_EL2:
67113760Sjairo.balart@metempsy.com        break;
67213760Sjairo.balart@metempsy.com
67313760Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR:
67413760Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR_EL2: {
67513760Sjairo.balart@metempsy.com          value = 0;
67613760Sjairo.balart@metempsy.com          // Scan list registers and fill in the U, NP and EOI bits
67713760Sjairo.balart@metempsy.com          eoiMaintenanceInterruptStatus((uint32_t *) &value);
67813760Sjairo.balart@metempsy.com          RegVal ich_hcr_el2 =
67913760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
68013531Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
68113531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
68213760Sjairo.balart@metempsy.com
68313531Sjairo.balart@metempsy.com          if (ich_hcr_el2 &
68413531Sjairo.balart@metempsy.com                  (ICH_HCR_EL2_LRENPIE | ICH_HCR_EL2_EOICOUNT_MASK)) {
68513760Sjairo.balart@metempsy.com              value |= ICH_MISR_EL2_LRENP;
68613531Sjairo.balart@metempsy.com          }
68713531Sjairo.balart@metempsy.com
68813760Sjairo.balart@metempsy.com          if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0EIE) &&
68913531Sjairo.balart@metempsy.com                  (ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
69013531Sjairo.balart@metempsy.com              value |= ICH_MISR_EL2_VGRP0E;
69113531Sjairo.balart@metempsy.com          }
69213531Sjairo.balart@metempsy.com
69313531Sjairo.balart@metempsy.com          if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) &&
69413760Sjairo.balart@metempsy.com                  !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
69513531Sjairo.balart@metempsy.com              value |= ICH_MISR_EL2_VGRP0D;
69613531Sjairo.balart@metempsy.com          }
69713760Sjairo.balart@metempsy.com
69813760Sjairo.balart@metempsy.com          if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) &&
69913531Sjairo.balart@metempsy.com                  (ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
70013531Sjairo.balart@metempsy.com              value |= ICH_MISR_EL2_VGRP1E;
70113531Sjairo.balart@metempsy.com          }
70213531Sjairo.balart@metempsy.com
70313531Sjairo.balart@metempsy.com          if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1DIE) &&
70413531Sjairo.balart@metempsy.com                  !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
70513760Sjairo.balart@metempsy.com              value |= ICH_MISR_EL2_VGRP1D;
70613531Sjairo.balart@metempsy.com          }
70713531Sjairo.balart@metempsy.com
70813531Sjairo.balart@metempsy.com          break;
70913531Sjairo.balart@metempsy.com      }
71013531Sjairo.balart@metempsy.com
71113760Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR:
71213531Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR_EL2:
71313531Sjairo.balart@metempsy.com        /*
71413531Sjairo.balart@metempsy.com         * PRIbits [31:29]
71513531Sjairo.balart@metempsy.com         * PREbits [28:26]
71613531Sjairo.balart@metempsy.com         * IDbits [25:23]
71713760Sjairo.balart@metempsy.com         * SEIS [22] == 0 (SEI Support)
71813531Sjairo.balart@metempsy.com         * A3V [21] == 1
71913531Sjairo.balart@metempsy.com         * (Non-zero values supported for Affinity 3 in SGI genearion)
72013531Sjairo.balart@metempsy.com         * nV4 [20] == 0
72113760Sjairo.balart@metempsy.com         * (Support for direct injection of virtual interrupts)
72213531Sjairo.balart@metempsy.com         * TDS [19] == 0 (Implementation supports ICH_HCR_EL2.TDIR)
72313531Sjairo.balart@metempsy.com         * ListRegs [4:0]
72413531Sjairo.balart@metempsy.com         */
72513531Sjairo.balart@metempsy.com        value = (16 - 1) << 0 |
72613531Sjairo.balart@metempsy.com            (5 - 1) << 26 |
72713760Sjairo.balart@metempsy.com            (5 - 1) << 29;
72813760Sjairo.balart@metempsy.com        value =
72913531Sjairo.balart@metempsy.com            ((VIRTUAL_NUM_LIST_REGS - 1) << ICH_VTR_EL2_LISTREGS_SHIFT) |
73013531Sjairo.balart@metempsy.com            // ICH_VTR_EL2_TDS |
73113760Sjairo.balart@metempsy.com            // ICH_VTR_EL2_NV4 |
73213760Sjairo.balart@metempsy.com            ICH_VTR_EL2_A3V |
73313531Sjairo.balart@metempsy.com            (1 << ICH_VTR_EL2_IDBITS_SHIFT) |
73413531Sjairo.balart@metempsy.com            ((VIRTUAL_PREEMPTION_BITS - 1) << ICH_VTR_EL2_PREBITS_SHIFT) |
73513531Sjairo.balart@metempsy.com            ((VIRTUAL_PRIORITY_BITS - 1) << ICH_VTR_EL2_PRIBITS_SHIFT);
73613531Sjairo.balart@metempsy.com        break;
73713580Sgabeblack@google.com
73813531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR:
73913531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR_EL2:
74013760Sjairo.balart@metempsy.com        value = eoiMaintenanceInterruptStatus(nullptr);
74113760Sjairo.balart@metempsy.com        break;
74213531Sjairo.balart@metempsy.com
74313531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR:
74413531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR_EL2:
74513531Sjairo.balart@metempsy.com        value = 0;
74613760Sjairo.balart@metempsy.com
74713531Sjairo.balart@metempsy.com        for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
74813531Sjairo.balart@metempsy.com            RegVal lr =
74913531Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
75013531Sjairo.balart@metempsy.com
75113531Sjairo.balart@metempsy.com            if ((lr & ICH_LR_EL2_STATE_MASK) == 0 &&
75213531Sjairo.balart@metempsy.com                    ((lr & ICH_LR_EL2_HW) != 0 ||
75314246Sgiacomo.travaglini@arm.com                     (lr & ICH_LR_EL2_EOI) == 0)) {
75414246Sgiacomo.travaglini@arm.com                value |= (1 << lr_idx);
75513531Sjairo.balart@metempsy.com            }
75613531Sjairo.balart@metempsy.com        }
75713531Sjairo.balart@metempsy.com
75813531Sjairo.balart@metempsy.com        break;
75913531Sjairo.balart@metempsy.com
76013531Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
76113531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
76213531Sjairo.balart@metempsy.com        value = value >> 32;
76313531Sjairo.balart@metempsy.com        break;
76413531Sjairo.balart@metempsy.com
76513531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
76613531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
76713531Sjairo.balart@metempsy.com        value = value & 0xffffffff;
76813531Sjairo.balart@metempsy.com        break;
76913760Sjairo.balart@metempsy.com
77013531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
77113531Sjairo.balart@metempsy.com        break;
77213531Sjairo.balart@metempsy.com
77313531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
77413531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2:
77513531Sjairo.balart@metempsy.com        break;
77613531Sjairo.balart@metempsy.com
77713531Sjairo.balart@metempsy.com      default:
77813531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::readMiscReg(): "
77913531Sjairo.balart@metempsy.com                "unknown register %d (%s)",
78013531Sjairo.balart@metempsy.com                misc_reg, miscRegName[misc_reg]);
78113531Sjairo.balart@metempsy.com    }
78213531Sjairo.balart@metempsy.com
78313531Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): "
78413531Sjairo.balart@metempsy.com            "register %s value %#x\n", miscRegName[misc_reg], value);
78513531Sjairo.balart@metempsy.com    return value;
78613531Sjairo.balart@metempsy.com}
78713531Sjairo.balart@metempsy.com
78813531Sjairo.balart@metempsy.comvoid
78913531Sjairo.balart@metempsy.comGicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
79013531Sjairo.balart@metempsy.com{
79113760Sjairo.balart@metempsy.com    bool do_virtual_update = false;
79213531Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): "
79313531Sjairo.balart@metempsy.com            "register %s value %#x\n", miscRegName[misc_reg], val);
79413531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
79513531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
79613531Sjairo.balart@metempsy.com
79713531Sjairo.balart@metempsy.com    switch (misc_reg) {
79813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
79913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1:
80013531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
80113923Sgiacomo.travaglini@arm.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
80213923Sgiacomo.travaglini@arm.com        }
80313531Sjairo.balart@metempsy.com
80413531Sjairo.balart@metempsy.com        break;
80513531Sjairo.balart@metempsy.com
80613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
80713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
80813531Sjairo.balart@metempsy.com
80913531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
81013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
81113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
81213531Sjairo.balart@metempsy.com
81313531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
81413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
81513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
81613531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
81713531Sjairo.balart@metempsy.com        break;
81813531Sjairo.balart@metempsy.com
81913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
82013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1:
82113760Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
82213531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
82313531Sjairo.balart@metempsy.com        }
82413531Sjairo.balart@metempsy.com
82513531Sjairo.balart@metempsy.com        break;
82613531Sjairo.balart@metempsy.com
82713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
82813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
82913531Sjairo.balart@metempsy.com
83013531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
83113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
83213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
83313531Sjairo.balart@metempsy.com
83413531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
83513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
83613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
83713531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
83813531Sjairo.balart@metempsy.com        break;
83913531Sjairo.balart@metempsy.com
84013531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0:
84113531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
84213531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
84313760Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
84413531Sjairo.balart@metempsy.com          }
84513531Sjairo.balart@metempsy.com
84613760Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
84713760Sjairo.balart@metempsy.com
84813531Sjairo.balart@metempsy.com          // avoid activation for special interrupts
84913531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE) {
85013760Sjairo.balart@metempsy.com              return;
85113531Sjairo.balart@metempsy.com          }
85213531Sjairo.balart@metempsy.com
85313531Sjairo.balart@metempsy.com          Gicv3::GroupId group = Gicv3::G0S;
85413531Sjairo.balart@metempsy.com
85513531Sjairo.balart@metempsy.com          if (highestActiveGroup() != group) {
85613531Sjairo.balart@metempsy.com              return;
85713531Sjairo.balart@metempsy.com          }
85813531Sjairo.balart@metempsy.com
85913531Sjairo.balart@metempsy.com          dropPriority(group);
86013531Sjairo.balart@metempsy.com
86113760Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
86213531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
86313760Sjairo.balart@metempsy.com          }
86413531Sjairo.balart@metempsy.com
86513531Sjairo.balart@metempsy.com          break;
86613531Sjairo.balart@metempsy.com      }
86713531Sjairo.balart@metempsy.com
86813531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR0_EL1: {
86913531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
87013531Sjairo.balart@metempsy.com
87113923Sgiacomo.travaglini@arm.com          // avoid deactivation for special interrupts
87213923Sgiacomo.travaglini@arm.com          if (int_id >= Gicv3::INTID_SECURE &&
87313531Sjairo.balart@metempsy.com                  int_id <= Gicv3::INTID_SPURIOUS) {
87413531Sjairo.balart@metempsy.com              return;
87513531Sjairo.balart@metempsy.com          }
87613760Sjairo.balart@metempsy.com
87713531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
87813531Sjairo.balart@metempsy.com
87913531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
88013531Sjairo.balart@metempsy.com              return;
88113531Sjairo.balart@metempsy.com          }
88213531Sjairo.balart@metempsy.com
88313531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
88413531Sjairo.balart@metempsy.com
88513531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
88613760Sjairo.balart@metempsy.com              // No LR found matching
88713531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
88813531Sjairo.balart@metempsy.com          } else {
88913531Sjairo.balart@metempsy.com              RegVal lr =
89013531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
89113531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
89213531Sjairo.balart@metempsy.com                  lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
89313531Sjairo.balart@metempsy.com              uint8_t lr_group_prio = bits(lr, 55, 48) & 0xf8;
89413531Sjairo.balart@metempsy.com
89513531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
89613531Sjairo.balart@metempsy.com                  //JAIRO if (!virtualIsEOISplitMode())
89713531Sjairo.balart@metempsy.com                  {
89813531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
89913531Sjairo.balart@metempsy.com                  }
90013760Sjairo.balart@metempsy.com              }
90113531Sjairo.balart@metempsy.com          }
90213531Sjairo.balart@metempsy.com
90313531Sjairo.balart@metempsy.com          virtualUpdate();
90413531Sjairo.balart@metempsy.com          break;
90513531Sjairo.balart@metempsy.com      }
90613760Sjairo.balart@metempsy.com
90713531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1:
90813531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1_EL1: { // End Of Interrupt Register 1
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
91613531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE) {
91713531Sjairo.balart@metempsy.com              return;
91813531Sjairo.balart@metempsy.com          }
91913760Sjairo.balart@metempsy.com
92013531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
92113531Sjairo.balart@metempsy.com              inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
92213760Sjairo.balart@metempsy.com
92313531Sjairo.balart@metempsy.com          if (highestActiveGroup() == Gicv3::G0S) {
92413531Sjairo.balart@metempsy.com              return;
92513760Sjairo.balart@metempsy.com          }
92613760Sjairo.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 &&
93113531Sjairo.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()) {
93913760Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
94013531Sjairo.balart@metempsy.com          }
94113760Sjairo.balart@metempsy.com
94213531Sjairo.balart@metempsy.com          break;
94313760Sjairo.balart@metempsy.com      }
94413531Sjairo.balart@metempsy.com
94513531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR1_EL1: {
94613531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
94713531Sjairo.balart@metempsy.com
94813531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
94913760Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
95013760Sjairo.balart@metempsy.com                  int_id <= Gicv3::INTID_SPURIOUS) {
95113760Sjairo.balart@metempsy.com              return;
95213760Sjairo.balart@metempsy.com          }
95313531Sjairo.balart@metempsy.com
95413531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
95513531Sjairo.balart@metempsy.com
95613531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
95713760Sjairo.balart@metempsy.com              return;
95813531Sjairo.balart@metempsy.com          }
95913531Sjairo.balart@metempsy.com
96013531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
96113531Sjairo.balart@metempsy.com
96213531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
96313531Sjairo.balart@metempsy.com              // No LR found matching
96413531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
96513531Sjairo.balart@metempsy.com          } else {
96613531Sjairo.balart@metempsy.com              RegVal lr =
96713531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
96813531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
96913531Sjairo.balart@metempsy.com                  lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
97013531Sjairo.balart@metempsy.com              uint8_t lr_group_prio = bits(lr, 55, 48) & 0xf8;
97113531Sjairo.balart@metempsy.com
97213531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
97313531Sjairo.balart@metempsy.com                  if (!virtualIsEOISplitMode()) {
97413531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
97513531Sjairo.balart@metempsy.com                  }
97613531Sjairo.balart@metempsy.com              }
97713531Sjairo.balart@metempsy.com          }
97813531Sjairo.balart@metempsy.com
97913531Sjairo.balart@metempsy.com          virtualUpdate();
98013531Sjairo.balart@metempsy.com          break;
98113531Sjairo.balart@metempsy.com      }
98213531Sjairo.balart@metempsy.com
98313531Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR:
98413531Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR_EL1: { // Deactivate Interrupt Register
98513531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
98613531Sjairo.balart@metempsy.com                  (hcr_imo || hcr_fmo)) {
98713531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_DIR_EL1, val);
98813531Sjairo.balart@metempsy.com          }
98913531Sjairo.balart@metempsy.com
99013531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
99113531Sjairo.balart@metempsy.com
99213760Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
99313531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE) {
99413531Sjairo.balart@metempsy.com              return;
99513531Sjairo.balart@metempsy.com          }
99613531Sjairo.balart@metempsy.com
99713760Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
99813531Sjairo.balart@metempsy.com              return;
99913531Sjairo.balart@metempsy.com          }
100013531Sjairo.balart@metempsy.com
100113531Sjairo.balart@metempsy.com          /*
100213531Sjairo.balart@metempsy.com           * Check whether we're allowed to deactivate.
100313531Sjairo.balart@metempsy.com           * These checks are correspond to the spec's pseudocode.
100413531Sjairo.balart@metempsy.com           */
100513531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
100613760Sjairo.balart@metempsy.com              int_id >= 32 ? distributor->getIntGroup(int_id) :
100713760Sjairo.balart@metempsy.com              redistributor->getIntGroup(int_id);
100813531Sjairo.balart@metempsy.com          bool irq_is_grp0 = group == Gicv3::G0S;
100913531Sjairo.balart@metempsy.com          bool single_sec_state = distributor->DS;
101013531Sjairo.balart@metempsy.com          bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
101113531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
101213531Sjairo.balart@metempsy.com          bool route_fiq_to_el3 = scr_el3.fiq;
101313531Sjairo.balart@metempsy.com          bool route_irq_to_el3 = scr_el3.irq;
101413531Sjairo.balart@metempsy.com          bool route_fiq_to_el2 = hcr_fmo;
101513531Sjairo.balart@metempsy.com          bool route_irq_to_el2 = hcr_imo;
101613531Sjairo.balart@metempsy.com
101713531Sjairo.balart@metempsy.com          switch (currEL()) {
101813531Sjairo.balart@metempsy.com            case EL3:
101913531Sjairo.balart@metempsy.com              break;
102013531Sjairo.balart@metempsy.com
102113531Sjairo.balart@metempsy.com            case EL2:
102213760Sjairo.balart@metempsy.com              if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
102313531Sjairo.balart@metempsy.com                  break;
102413531Sjairo.balart@metempsy.com              }
102513531Sjairo.balart@metempsy.com
102613531Sjairo.balart@metempsy.com              if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
102713531Sjairo.balart@metempsy.com                  break;
102813760Sjairo.balart@metempsy.com              }
102913531Sjairo.balart@metempsy.com
103013531Sjairo.balart@metempsy.com              return;
103113531Sjairo.balart@metempsy.com
103213531Sjairo.balart@metempsy.com            case EL1:
103313531Sjairo.balart@metempsy.com              if (!isSecureBelowEL3()) {
103413531Sjairo.balart@metempsy.com                  if (single_sec_state && irq_is_grp0 &&
103513531Sjairo.balart@metempsy.com                          !route_fiq_to_el3 && !route_fiq_to_el2) {
103613531Sjairo.balart@metempsy.com                      break;
103713531Sjairo.balart@metempsy.com                  }
103813531Sjairo.balart@metempsy.com
103913760Sjairo.balart@metempsy.com                  if (!irq_is_secure && !irq_is_grp0 &&
104013531Sjairo.balart@metempsy.com                          !route_irq_to_el3 && !route_irq_to_el2) {
104113531Sjairo.balart@metempsy.com                      break;
104213531Sjairo.balart@metempsy.com                  }
104313531Sjairo.balart@metempsy.com              } else {
104413531Sjairo.balart@metempsy.com                  if (irq_is_grp0 && !route_fiq_to_el3) {
104513531Sjairo.balart@metempsy.com                      break;
104613531Sjairo.balart@metempsy.com                  }
104713531Sjairo.balart@metempsy.com
104813531Sjairo.balart@metempsy.com                  if (!irq_is_grp0 &&
104913760Sjairo.balart@metempsy.com                          (!irq_is_secure || !single_sec_state) &&
105013531Sjairo.balart@metempsy.com                          !route_irq_to_el3) {
105114237Sgiacomo.travaglini@arm.com                      break;
105214237Sgiacomo.travaglini@arm.com                  }
105314237Sgiacomo.travaglini@arm.com              }
105414237Sgiacomo.travaglini@arm.com
105514237Sgiacomo.travaglini@arm.com              return;
105614237Sgiacomo.travaglini@arm.com
105713760Sjairo.balart@metempsy.com            default:
105813531Sjairo.balart@metempsy.com              break;
105913760Sjairo.balart@metempsy.com          }
106014237Sgiacomo.travaglini@arm.com
106114237Sgiacomo.travaglini@arm.com          deactivateIRQ(int_id, group);
106214237Sgiacomo.travaglini@arm.com          break;
106314237Sgiacomo.travaglini@arm.com      }
106414237Sgiacomo.travaglini@arm.com
106514237Sgiacomo.travaglini@arm.com      case MISCREG_ICV_DIR_EL1: {
106614237Sgiacomo.travaglini@arm.com          int int_id = val & 0xffffff;
106714237Sgiacomo.travaglini@arm.com
106814237Sgiacomo.travaglini@arm.com          // avoid deactivation for special interrupts
106914237Sgiacomo.travaglini@arm.com          if (int_id >= Gicv3::INTID_SECURE &&
107014237Sgiacomo.travaglini@arm.com                  int_id <= Gicv3::INTID_SPURIOUS) {
107114237Sgiacomo.travaglini@arm.com              return;
107214237Sgiacomo.travaglini@arm.com          }
107314237Sgiacomo.travaglini@arm.com
107414237Sgiacomo.travaglini@arm.com          if (!virtualIsEOISplitMode()) {
107514237Sgiacomo.travaglini@arm.com              return;
107614237Sgiacomo.travaglini@arm.com          }
107714237Sgiacomo.travaglini@arm.com
107814237Sgiacomo.travaglini@arm.com          int lr_idx = virtualFindActive(int_id);
107914237Sgiacomo.travaglini@arm.com
108014237Sgiacomo.travaglini@arm.com          if (lr_idx < 0) {
108114237Sgiacomo.travaglini@arm.com              // No LR found matching
108214237Sgiacomo.travaglini@arm.com              virtualIncrementEOICount();
108314237Sgiacomo.travaglini@arm.com          } else {
108414237Sgiacomo.travaglini@arm.com              virtualDeactivateIRQ(lr_idx);
108514237Sgiacomo.travaglini@arm.com          }
108614237Sgiacomo.travaglini@arm.com
108714237Sgiacomo.travaglini@arm.com          virtualUpdate();
108814237Sgiacomo.travaglini@arm.com          break;
108914237Sgiacomo.travaglini@arm.com      }
109014237Sgiacomo.travaglini@arm.com
109114237Sgiacomo.travaglini@arm.com      case MISCREG_ICC_BPR0:
109214237Sgiacomo.travaglini@arm.com      case MISCREG_ICC_BPR0_EL1: // Binary Point Register 0
109313531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
109413531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: { // Binary Point Register 1
109513760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState()) {
109613531Sjairo.balart@metempsy.com              if (misc_reg == MISCREG_ICC_BPR0_EL1 && hcr_fmo) {
109713760Sjairo.balart@metempsy.com                  return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
109813531Sjairo.balart@metempsy.com              } else if (misc_reg == MISCREG_ICC_BPR1_EL1 && hcr_imo) {
109913531Sjairo.balart@metempsy.com                  return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
110013531Sjairo.balart@metempsy.com              }
110113760Sjairo.balart@metempsy.com          }
110213531Sjairo.balart@metempsy.com
110313531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
110413760Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;
110513760Sjairo.balart@metempsy.com
110613531Sjairo.balart@metempsy.com          if (group == Gicv3::G1S && !inSecureState()) {
110713531Sjairo.balart@metempsy.com              group = Gicv3::G1NS;
110813531Sjairo.balart@metempsy.com          }
110913531Sjairo.balart@metempsy.com
111013531Sjairo.balart@metempsy.com          if ((group == Gicv3::G1S) &&
111113531Sjairo.balart@metempsy.com                  !isEL3OrMon() &&
111213531Sjairo.balart@metempsy.com                  (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S) &
111313531Sjairo.balart@metempsy.com                   ICC_CTLR_EL1_CBPR)) {
111413531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
111513531Sjairo.balart@metempsy.com          }
111613531Sjairo.balart@metempsy.com
111713531Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) &&
111813531Sjairo.balart@metempsy.com                  (currEL() < EL3) &&
111913531Sjairo.balart@metempsy.com                  (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS) &
112013760Sjairo.balart@metempsy.com                   ICC_CTLR_EL1_CBPR)) {
112113531Sjairo.balart@metempsy.com              // Reads return BPR0 + 1 saturated to 7, WI
112213760Sjairo.balart@metempsy.com              return;
112313531Sjairo.balart@metempsy.com          }
112413531Sjairo.balart@metempsy.com
112513531Sjairo.balart@metempsy.com          uint8_t min_val = (group == Gicv3::G1NS) ?
112613531Sjairo.balart@metempsy.com              GIC_MIN_BPR_NS : GIC_MIN_BPR;
112713531Sjairo.balart@metempsy.com          val &= 0x7;
112813531Sjairo.balart@metempsy.com
112913531Sjairo.balart@metempsy.com          if (val < min_val) {
113013760Sjairo.balart@metempsy.com              val = min_val;
113113531Sjairo.balart@metempsy.com          }
113213760Sjairo.balart@metempsy.com
113313760Sjairo.balart@metempsy.com          break;
113413531Sjairo.balart@metempsy.com      }
113513531Sjairo.balart@metempsy.com
113613531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR0_EL1:
113713531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
113813760Sjairo.balart@metempsy.com          Gicv3::GroupId group =
113913531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
114013531Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
114113531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
114213531Sjairo.balart@metempsy.com
114313531Sjairo.balart@metempsy.com          if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
114413531Sjairo.balart@metempsy.com              // reads return bpr0 + 1 saturated to 7, writes ignored
114513760Sjairo.balart@metempsy.com              return;
114613760Sjairo.balart@metempsy.com          }
114714245Sgiacomo.travaglini@arm.com
114813760Sjairo.balart@metempsy.com          uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
114913760Sjairo.balart@metempsy.com
115013760Sjairo.balart@metempsy.com          if (group != Gicv3::G0S) {
115113760Sjairo.balart@metempsy.com              min_VPBR++;
115213760Sjairo.balart@metempsy.com          }
115313760Sjairo.balart@metempsy.com
115413760Sjairo.balart@metempsy.com          if (val < min_VPBR) {
115513760Sjairo.balart@metempsy.com              val = min_VPBR;
115613760Sjairo.balart@metempsy.com          }
115713760Sjairo.balart@metempsy.com
115813760Sjairo.balart@metempsy.com          if (group == Gicv3::G0S) {
115913760Sjairo.balart@metempsy.com              ich_vmcr_el2 = insertBits(ich_vmcr_el2,
116013760Sjairo.balart@metempsy.com                      ICH_VMCR_EL2_VBPR0_SHIFT + 2, ICH_VMCR_EL2_VBPR0_SHIFT,
116113760Sjairo.balart@metempsy.com                      val);
116213760Sjairo.balart@metempsy.com          } else {
116313760Sjairo.balart@metempsy.com              ich_vmcr_el2 = insertBits(ich_vmcr_el2,
116413760Sjairo.balart@metempsy.com                      ICH_VMCR_EL2_VBPR1_SHIFT + 2, ICH_VMCR_EL2_VBPR1_SHIFT,
116513760Sjairo.balart@metempsy.com                      val);
116613531Sjairo.balart@metempsy.com          }
116713760Sjairo.balart@metempsy.com
116813760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
116913531Sjairo.balart@metempsy.com          do_virtual_update = true;
117013531Sjairo.balart@metempsy.com          break;
117113760Sjairo.balart@metempsy.com      }
117213760Sjairo.balart@metempsy.com
117313760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
117413760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: { // Control Register
117513760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
117613760Sjairo.balart@metempsy.com                  (hcr_imo || hcr_fmo)) {
117713760Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
117813760Sjairo.balart@metempsy.com          }
117913760Sjairo.balart@metempsy.com
118013760Sjairo.balart@metempsy.com          /*
118113760Sjairo.balart@metempsy.com           * RSS is RO.
118213760Sjairo.balart@metempsy.com           * A3V is RO.
118313760Sjairo.balart@metempsy.com           * SEIS is RO.
118413760Sjairo.balart@metempsy.com           * IDbits is RO.
118513760Sjairo.balart@metempsy.com           * PRIbits is RO.
118613760Sjairo.balart@metempsy.com           * If EL3 is implemented and GICD_CTLR.DS == 0, then PMHE is RO.
118713760Sjairo.balart@metempsy.com           * So, only CBPR[0] and EOIMODE[1] are RW.
118813760Sjairo.balart@metempsy.com           * If EL3 is implemented and GICD_CTLR.DS == 0, then CBPR is RO.
118913760Sjairo.balart@metempsy.com           */
119013760Sjairo.balart@metempsy.com          uint64_t mask;
119113760Sjairo.balart@metempsy.com
119213760Sjairo.balart@metempsy.com          if (haveEL(EL3) and distributor->DS == 0) {
119313760Sjairo.balart@metempsy.com              mask = ICC_CTLR_EL1_EOIMODE;
119413760Sjairo.balart@metempsy.com          } else if (haveEL(EL3) and distributor->DS == 1) {
119513760Sjairo.balart@metempsy.com              mask = ICC_CTLR_EL1_PMHE | ICC_CTLR_EL1_CBPR |
119613760Sjairo.balart@metempsy.com                  ICC_CTLR_EL1_EOIMODE;
119713760Sjairo.balart@metempsy.com          } else {
119813760Sjairo.balart@metempsy.com              mask = ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE;
119913760Sjairo.balart@metempsy.com          }
120013760Sjairo.balart@metempsy.com
120113760Sjairo.balart@metempsy.com          RegVal old_val =
120213760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
120313760Sjairo.balart@metempsy.com          old_val &= ~mask;
120413760Sjairo.balart@metempsy.com          val = old_val | (val & mask);
120514245Sgiacomo.travaglini@arm.com          break;
120614245Sgiacomo.travaglini@arm.com      }
120713531Sjairo.balart@metempsy.com
120813531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
120913760Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
121013531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
121113760Sjairo.balart@metempsy.com          ich_vmcr_el2 = insertBits(ich_vmcr_el2, ICH_VMCR_EL2_VCBPR_SHIFT,
121213760Sjairo.balart@metempsy.com                  val & ICC_CTLR_EL1_CBPR ? 1 : 0);
121313760Sjairo.balart@metempsy.com          ich_vmcr_el2 = insertBits(ich_vmcr_el2, ICH_VMCR_EL2_VEOIM_SHIFT,
121413760Sjairo.balart@metempsy.com                  val & ICC_CTLR_EL1_EOIMODE ? 1 : 0);
121513760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
121613760Sjairo.balart@metempsy.com          do_virtual_update = true;
121713760Sjairo.balart@metempsy.com          break;
121813760Sjairo.balart@metempsy.com      }
121913760Sjairo.balart@metempsy.com
122013760Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
122113760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
122213760Sjairo.balart@metempsy.com          RegVal icc_ctlr_el1_s =
122313760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
122413760Sjairo.balart@metempsy.com          RegVal icc_ctlr_el1_ns =
122513760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
122613760Sjairo.balart@metempsy.com
122713760Sjairo.balart@metempsy.com          // ICC_CTLR_EL1(NS).EOImode is an alias of
122813760Sjairo.balart@metempsy.com          // ICC_CTLR_EL3.EOImode_EL1NS
122913760Sjairo.balart@metempsy.com          if (val & ICC_CTLR_EL3_EOIMODE_EL1NS) {
123013760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns |= ICC_CTLR_EL1_EOIMODE;
123113760Sjairo.balart@metempsy.com          } else {
123213760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns &= ~ICC_CTLR_EL1_EOIMODE;
123313760Sjairo.balart@metempsy.com          }
123413760Sjairo.balart@metempsy.com
123513760Sjairo.balart@metempsy.com          // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
123613760Sjairo.balart@metempsy.com          if (val & ICC_CTLR_EL3_CBPR_EL1NS) {
123713760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns |= ICC_CTLR_EL1_CBPR;
123813760Sjairo.balart@metempsy.com          } else {
123913760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns &= ~ICC_CTLR_EL1_CBPR;
124013760Sjairo.balart@metempsy.com          }
124113760Sjairo.balart@metempsy.com
124213760Sjairo.balart@metempsy.com          // ICC_CTLR_EL1(S).EOImode is an alias of ICC_CTLR_EL3.EOImode_EL1S
124313760Sjairo.balart@metempsy.com          if (val & ICC_CTLR_EL3_EOIMODE_EL1S) {
124413760Sjairo.balart@metempsy.com              icc_ctlr_el1_s |= ICC_CTLR_EL1_EOIMODE;
124513760Sjairo.balart@metempsy.com          } else {
124613760Sjairo.balart@metempsy.com              icc_ctlr_el1_s &= ~ICC_CTLR_EL1_EOIMODE;
124713760Sjairo.balart@metempsy.com          }
124813760Sjairo.balart@metempsy.com
124913760Sjairo.balart@metempsy.com          // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
125013760Sjairo.balart@metempsy.com          if (val & ICC_CTLR_EL3_CBPR_EL1S) {
125113760Sjairo.balart@metempsy.com              icc_ctlr_el1_s |= ICC_CTLR_EL1_CBPR;
125213760Sjairo.balart@metempsy.com          } else {
125313760Sjairo.balart@metempsy.com              icc_ctlr_el1_s &= ~ICC_CTLR_EL1_CBPR;
125413760Sjairo.balart@metempsy.com          }
125513760Sjairo.balart@metempsy.com
125613760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
125713760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS, icc_ctlr_el1_ns);
125813760Sjairo.balart@metempsy.com          // Only ICC_CTLR_EL3_EOIMODE_EL3 is writable
125913760Sjairo.balart@metempsy.com          RegVal old_icc_ctlr_el3 =
126013760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
126113760Sjairo.balart@metempsy.com          old_icc_ctlr_el3 &= ~(ICC_CTLR_EL3_EOIMODE_EL3 | ICC_CTLR_EL3_RM);
126213760Sjairo.balart@metempsy.com          val = old_icc_ctlr_el3 |
126313760Sjairo.balart@metempsy.com              (val & (ICC_CTLR_EL3_EOIMODE_EL3 | ICC_CTLR_EL3_RM));
126413760Sjairo.balart@metempsy.com          break;
126513760Sjairo.balart@metempsy.com      }
126613760Sjairo.balart@metempsy.com
126713760Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
126813760Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1: { // Priority Mask Register
126913760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
127013760Sjairo.balart@metempsy.com                  (hcr_imo || hcr_fmo)) {
127113760Sjairo.balart@metempsy.com              return isa->setMiscRegNoEffect(MISCREG_ICV_PMR_EL1, val);
127213760Sjairo.balart@metempsy.com          }
127313760Sjairo.balart@metempsy.com
127413760Sjairo.balart@metempsy.com          val &= 0xff;
127513760Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
127613760Sjairo.balart@metempsy.com
127713760Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
127813760Sjairo.balart@metempsy.com              /*
127913531Sjairo.balart@metempsy.com               * NS access and Group 0 is inaccessible to NS: return the
128013531Sjairo.balart@metempsy.com               * NS view of the current priority
128113531Sjairo.balart@metempsy.com               */
128213760Sjairo.balart@metempsy.com              RegVal old_icc_pmr_el1 =
128313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);
128413760Sjairo.balart@metempsy.com
128513760Sjairo.balart@metempsy.com              if (!(old_icc_pmr_el1 & 0x80)) {
128614057Sgiacomo.travaglini@arm.com                  /* Current PMR in the secure range, don't allow NS to
128713531Sjairo.balart@metempsy.com                   * change it */
128813531Sjairo.balart@metempsy.com                  return;
128913531Sjairo.balart@metempsy.com              }
129013531Sjairo.balart@metempsy.com
129113531Sjairo.balart@metempsy.com              val = (val >> 1) | 0x80;
129213531Sjairo.balart@metempsy.com          }
129313760Sjairo.balart@metempsy.com
129413760Sjairo.balart@metempsy.com          val &= ~0U << (8 - PRIORITY_BITS);
129513580Sgabeblack@google.com          break;
129613531Sjairo.balart@metempsy.com      }
129713531Sjairo.balart@metempsy.com
129813531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
129913760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: { // Interrupt Group 0 Enable Register
130013760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
130113531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
130213531Sjairo.balart@metempsy.com          }
130313531Sjairo.balart@metempsy.com
130413760Sjairo.balart@metempsy.com          break;
130513760Sjairo.balart@metempsy.com      }
130613760Sjairo.balart@metempsy.com
130713760Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN0_EL1: {
130813760Sjairo.balart@metempsy.com          bool enable = val & 0x1;
130913531Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
131013531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
131113531Sjairo.balart@metempsy.com          ich_vmcr_el2 = insertBits(ich_vmcr_el2,
131213531Sjairo.balart@metempsy.com                  ICH_VMCR_EL2_VENG0_SHIFT, enable);
131313531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
131413531Sjairo.balart@metempsy.com          virtualUpdate();
131513531Sjairo.balart@metempsy.com          return;
131614057Sgiacomo.travaglini@arm.com      }
131714057Sgiacomo.travaglini@arm.com
131814057Sgiacomo.travaglini@arm.com      case MISCREG_ICC_IGRPEN1:
131914057Sgiacomo.travaglini@arm.com      case MISCREG_ICC_IGRPEN1_EL1: { // Interrupt Group 1 Enable Register
132014057Sgiacomo.travaglini@arm.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
132114057Sgiacomo.travaglini@arm.com              return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
132214057Sgiacomo.travaglini@arm.com          }
132314057Sgiacomo.travaglini@arm.com
132414057Sgiacomo.travaglini@arm.com          break;
132514057Sgiacomo.travaglini@arm.com      }
132613760Sjairo.balart@metempsy.com
132713760Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN1_EL1: {
132813760Sjairo.balart@metempsy.com          bool enable = val & 0x1;
132913760Sjairo.balart@metempsy.com          RegVal ich_vmcr_el2 =
133013760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
133113760Sjairo.balart@metempsy.com          ich_vmcr_el2 = insertBits(ich_vmcr_el2,
133213760Sjairo.balart@metempsy.com                  ICH_VMCR_EL2_VENG1_SHIFT, enable);
133314248Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
133414248Sgiacomo.travaglini@arm.com          virtualUpdate();
133514248Sgiacomo.travaglini@arm.com          return;
133613760Sjairo.balart@metempsy.com      }
133713760Sjairo.balart@metempsy.com
133813760Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
133913760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL3: {
134013760Sjairo.balart@metempsy.com          // EnableGrp1S and EnableGrp1NS are aliased with
134113760Sjairo.balart@metempsy.com          // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable
134213760Sjairo.balart@metempsy.com          bool enable_grp_1s = val & ICC_IGRPEN1_EL3_ENABLEGRP1S;
134313760Sjairo.balart@metempsy.com          bool enable_grp_1ns = val & ICC_IGRPEN1_EL3_ENABLEGRP1NS;
134413740Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S, enable_grp_1s);
134513740Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS, enable_grp_1ns);
134613740Sgiacomo.travaglini@arm.com          return;
134713740Sgiacomo.travaglini@arm.com      }
134813740Sgiacomo.travaglini@arm.com
134913760Sjairo.balart@metempsy.com        // Software Generated Interrupt Group 0 Register
135013760Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R:
135113760Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R_EL1:
135213760Sjairo.balart@metempsy.com
135313760Sjairo.balart@metempsy.com        // Software Generated Interrupt Group 1 Register
135413760Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI1R:
135513760Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI1R_EL1:
135614247Sgiacomo.travaglini@arm.com
135714248Sgiacomo.travaglini@arm.com        // Alias Software Generated Interrupt Group 1 Register
135814247Sgiacomo.travaglini@arm.com      case MISCREG_ICC_ASGI1R:
135913531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R_EL1: {
136013531Sjairo.balart@metempsy.com          bool ns = !inSecureState();
136113760Sjairo.balart@metempsy.com          Gicv3::GroupId group;
136213760Sjairo.balart@metempsy.com
136313531Sjairo.balart@metempsy.com          if (misc_reg == MISCREG_ICC_SGI1R_EL1) {
136413760Sjairo.balart@metempsy.com              group = ns ? Gicv3::G1NS : Gicv3::G1S;
136513531Sjairo.balart@metempsy.com          } else if (misc_reg == MISCREG_ICC_ASGI1R_EL1) {
136613760Sjairo.balart@metempsy.com              group = ns ? Gicv3::G1S : Gicv3::G1NS;
136713531Sjairo.balart@metempsy.com          } else {
136813531Sjairo.balart@metempsy.com              group = Gicv3::G0S;
136913531Sjairo.balart@metempsy.com          }
137013531Sjairo.balart@metempsy.com
137113531Sjairo.balart@metempsy.com          if (distributor->DS && group == Gicv3::G1S) {
137213760Sjairo.balart@metempsy.com              group = Gicv3::G0S;
137313760Sjairo.balart@metempsy.com          }
137413760Sjairo.balart@metempsy.com
137513760Sjairo.balart@metempsy.com          uint8_t aff3 = bits(val, 55, 48);
137614254Sgiacomo.travaglini@arm.com          uint8_t aff2 = bits(val, 39, 32);
137714254Sgiacomo.travaglini@arm.com          uint8_t aff1 = bits(val, 23, 16);;
137814254Sgiacomo.travaglini@arm.com          uint16_t target_list = bits(val, 15, 0);
137914254Sgiacomo.travaglini@arm.com          uint32_t int_id = bits(val, 27, 24);
138014254Sgiacomo.travaglini@arm.com          bool irm = bits(val, 40, 40);
138114256Sgiacomo.travaglini@arm.com          uint8_t rs = bits(val, 47, 44);
138214254Sgiacomo.travaglini@arm.com
138313531Sjairo.balart@metempsy.com          for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
138413531Sjairo.balart@metempsy.com              Gicv3Redistributor * redistributor_i =
138513760Sjairo.balart@metempsy.com                  gic->getRedistributor(i);
138613531Sjairo.balart@metempsy.com              uint32_t affinity_i = redistributor_i->getAffinity();
138713531Sjairo.balart@metempsy.com
138814227Sgiacomo.travaglini@arm.com              if (irm) {
138914227Sgiacomo.travaglini@arm.com                  // Interrupts routed to all PEs in the system,
139013531Sjairo.balart@metempsy.com                  // excluding "self"
139113760Sjairo.balart@metempsy.com                  if (affinity_i == redistributor->getAffinity()) {
139213531Sjairo.balart@metempsy.com                      continue;
139314227Sgiacomo.travaglini@arm.com                  }
139414227Sgiacomo.travaglini@arm.com              } else {
139514227Sgiacomo.travaglini@arm.com                  // Interrupts routed to the PEs specified by
139614227Sgiacomo.travaglini@arm.com                  // Aff3.Aff2.Aff1.<target list>
139714227Sgiacomo.travaglini@arm.com                  if ((affinity_i >> 8) !=
139814227Sgiacomo.travaglini@arm.com                          ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
139913531Sjairo.balart@metempsy.com                      continue;
140013760Sjairo.balart@metempsy.com                  }
140113531Sjairo.balart@metempsy.com
140213531Sjairo.balart@metempsy.com                  uint8_t aff0_i = bits(affinity_i, 7, 0);
140314227Sgiacomo.travaglini@arm.com
140414227Sgiacomo.travaglini@arm.com                  if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
140514227Sgiacomo.travaglini@arm.com                              ((0x1 << (aff0_i - rs * 16)) & target_list))) {
140614227Sgiacomo.travaglini@arm.com                      continue;
140713531Sjairo.balart@metempsy.com                  }
140813531Sjairo.balart@metempsy.com              }
140913760Sjairo.balart@metempsy.com
141013531Sjairo.balart@metempsy.com              redistributor_i->sendSGI(int_id, group, ns);
141113760Sjairo.balart@metempsy.com          }
141213760Sjairo.balart@metempsy.com
141313531Sjairo.balart@metempsy.com          break;
141413760Sjairo.balart@metempsy.com      }
141513760Sjairo.balart@metempsy.com
141613531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
141713760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1: { // System Register Enable Register EL1
141813760Sjairo.balart@metempsy.com          if (!(val & ICC_SRE_EL1_SRE)) {
141913760Sjairo.balart@metempsy.com              warn("Gicv3CPUInterface::setMiscReg(): "
142013760Sjairo.balart@metempsy.com                      "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n");
142113760Sjairo.balart@metempsy.com          }
142213760Sjairo.balart@metempsy.com
142313760Sjairo.balart@metempsy.com          bool dfb = val & ICC_SRE_EL1_DFB;
142413760Sjairo.balart@metempsy.com          bool dib = val & ICC_SRE_EL1_DIB;
142513760Sjairo.balart@metempsy.com
142613760Sjairo.balart@metempsy.com          if (haveEL(EL3) && !distributor->DS) {
142713760Sjairo.balart@metempsy.com              // DIB is RO alias of ICC_SRE_EL3.DIB
142813760Sjairo.balart@metempsy.com              // DFB is RO alias of ICC_SRE_EL3.DFB
142913760Sjairo.balart@metempsy.com          } else if (haveEL(EL3) && distributor->DS) {
143013760Sjairo.balart@metempsy.com              // DIB is RW alias of ICC_SRE_EL3.DIB
143113760Sjairo.balart@metempsy.com              // DFB is RW alias of ICC_SRE_EL3.DFB
143213760Sjairo.balart@metempsy.com              RegVal icc_sre_el3 =
143313760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
143413531Sjairo.balart@metempsy.com              icc_sre_el3 = insertBits(icc_sre_el3, ICC_SRE_EL3_DFB, dfb);
143513531Sjairo.balart@metempsy.com              icc_sre_el3 = insertBits(icc_sre_el3, ICC_SRE_EL3_DIB, dib);
143613760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_SRE_EL3, icc_sre_el3);
143713760Sjairo.balart@metempsy.com          } else if ((!haveEL(EL3) || distributor->DS) and haveEL(EL2)) {
143813760Sjairo.balart@metempsy.com              // DIB is RO alias of ICC_SRE_EL2.DIB
143913760Sjairo.balart@metempsy.com              // DFB is RO alias of ICC_SRE_EL2.DFB
144013760Sjairo.balart@metempsy.com          } else {
144113760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(misc_reg, val);
144213760Sjairo.balart@metempsy.com          }
144313760Sjairo.balart@metempsy.com
144413760Sjairo.balart@metempsy.com          return;
144513760Sjairo.balart@metempsy.com      }
144613760Sjairo.balart@metempsy.com
144713760Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
144813760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2: // System Register Enable Register EL2
144913760Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
145013531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3: // System Register Enable Register EL3
145113531Sjairo.balart@metempsy.com        if (!(val & (1 << 0))) {
145213760Sjairo.balart@metempsy.com            warn("Gicv3CPUInterface::setMiscReg(): "
145313760Sjairo.balart@metempsy.com                    "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n");
145413760Sjairo.balart@metempsy.com        }
145513760Sjairo.balart@metempsy.com
145613531Sjairo.balart@metempsy.com        // All bits are RAO/WI
145713760Sjairo.balart@metempsy.com        break;
145813760Sjairo.balart@metempsy.com
145913760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
146013760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2:
146113760Sjairo.balart@metempsy.com        val &= ICH_HCR_EL2_EN | ICH_HCR_EL2_UIE | ICH_HCR_EL2_LRENPIE |
146213760Sjairo.balart@metempsy.com            ICH_HCR_EL2_NPIE | ICH_HCR_EL2_VGRP0EIE |
146313760Sjairo.balart@metempsy.com            ICH_HCR_EL2_VGRP0DIE | ICH_HCR_EL2_VGRP1EIE |
146413760Sjairo.balart@metempsy.com            ICH_HCR_EL2_VGRP1DIE | ICH_HCR_EL2_TC | ICH_HCR_EL2_TALL0 |
146513760Sjairo.balart@metempsy.com            ICH_HCR_EL2_TALL1 | ICH_HCR_EL2_TDIR |
146613760Sjairo.balart@metempsy.com            ICH_HCR_EL2_EOICOUNT_MASK;
146713760Sjairo.balart@metempsy.com        do_virtual_update = true;
146813760Sjairo.balart@metempsy.com        break;
146913760Sjairo.balart@metempsy.com
147013760Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
147113760Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
147213760Sjairo.balart@metempsy.com        {
147313760Sjairo.balart@metempsy.com            // Enforce RES0 bits in priority field, 5 of 8 bits used
147413760Sjairo.balart@metempsy.com            val = insertBits(val, ICH_LRC_PRIORITY_SHIFT + 2,
147513760Sjairo.balart@metempsy.com                    ICH_LRC_PRIORITY_SHIFT, 0);
147613760Sjairo.balart@metempsy.com            RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
147713760Sjairo.balart@metempsy.com            val = (old_val & 0xffffffff) | (val << 32);
147813760Sjairo.balart@metempsy.com            do_virtual_update = true;
147913760Sjairo.balart@metempsy.com            break;
148013760Sjairo.balart@metempsy.com        }
148113760Sjairo.balart@metempsy.com
148213760Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
148313760Sjairo.balart@metempsy.com          // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
148413531Sjairo.balart@metempsy.com          RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
148513531Sjairo.balart@metempsy.com          val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
148613760Sjairo.balart@metempsy.com          do_virtual_update = true;
148713760Sjairo.balart@metempsy.com          break;
148813760Sjairo.balart@metempsy.com      }
148913760Sjairo.balart@metempsy.com
149013760Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
149113760Sjairo.balart@metempsy.com          // Enforce RES0 bits in priority field, 5 of 8 bits used
149213531Sjairo.balart@metempsy.com          val = insertBits(val, ICH_LR_EL2_PRIORITY_SHIFT + 2,
149313531Sjairo.balart@metempsy.com                  ICH_LR_EL2_PRIORITY_SHIFT, 0);
149413580Sgabeblack@google.com          do_virtual_update = true;
149513531Sjairo.balart@metempsy.com          break;
149613531Sjairo.balart@metempsy.com      }
149713531Sjairo.balart@metempsy.com
149813531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
149913531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2: {
150013760Sjairo.balart@metempsy.com          val &= ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1 |
150113531Sjairo.balart@metempsy.com              ICH_VMCR_EL2_VCBPR | ICH_VMCR_EL2_VEOIM |
150213760Sjairo.balart@metempsy.com              ICH_VMCR_EL2_VBPR1_MASK | ICH_VMCR_EL2_VBPR0_MASK |
150313760Sjairo.balart@metempsy.com              ICH_VMCR_EL2_VPMR_MASK;
150413760Sjairo.balart@metempsy.com          val |= ICH_VMCR_EL2_VFIQEN; // RES1
150513760Sjairo.balart@metempsy.com          // Check VBPRs against minimun allowed value
150613760Sjairo.balart@metempsy.com          uint8_t vbpr0 = bits(val, 23, 21);
150713760Sjairo.balart@metempsy.com          uint8_t vbpr1 = bits(val, 20, 18);
150813760Sjairo.balart@metempsy.com          uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
150913760Sjairo.balart@metempsy.com          uint8_t min_vpr1 = min_vpr0 + 1;
151013760Sjairo.balart@metempsy.com          vbpr0 = vbpr0 < min_vpr0 ? min_vpr0 : vbpr0;
151113760Sjairo.balart@metempsy.com          vbpr1 = vbpr1 < min_vpr1 ? min_vpr1 : vbpr1;
151213760Sjairo.balart@metempsy.com          val = insertBits(val, ICH_VMCR_EL2_VBPR0_SHIFT + 2,
151313760Sjairo.balart@metempsy.com                  ICH_VMCR_EL2_VBPR0_SHIFT, vbpr0);
151413760Sjairo.balart@metempsy.com          val = insertBits(val, ICH_VMCR_EL2_VBPR1_SHIFT + 2,
151513760Sjairo.balart@metempsy.com                  ICH_VMCR_EL2_VBPR1_SHIFT, vbpr1);
151613760Sjairo.balart@metempsy.com          break;
151713760Sjairo.balart@metempsy.com      }
151813760Sjairo.balart@metempsy.com
151913760Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0 ... MISCREG_ICH_AP0R3:
152013760Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_AP0R3_EL2:
152113760Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0 ... MISCREG_ICH_AP1R3:
152213760Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0_EL2 ... MISCREG_ICH_AP1R3_EL2:
152313760Sjairo.balart@metempsy.com        break;
152413760Sjairo.balart@metempsy.com
152513760Sjairo.balart@metempsy.com      default:
152613760Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::setMiscReg(): "
152713760Sjairo.balart@metempsy.com                "unknown register %d (%s)",
152813760Sjairo.balart@metempsy.com                misc_reg, miscRegName[misc_reg]);
152913760Sjairo.balart@metempsy.com    }
153013760Sjairo.balart@metempsy.com
153113760Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(misc_reg, val);
153213760Sjairo.balart@metempsy.com
153313760Sjairo.balart@metempsy.com    if (do_virtual_update) {
153413760Sjairo.balart@metempsy.com        virtualUpdate();
153513760Sjairo.balart@metempsy.com    }
153613760Sjairo.balart@metempsy.com}
153713760Sjairo.balart@metempsy.com
153813531Sjairo.balart@metempsy.comint
153913531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualFindActive(uint32_t int_id)
154013531Sjairo.balart@metempsy.com{
154113531Sjairo.balart@metempsy.com    for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
154213760Sjairo.balart@metempsy.com        RegVal lr =
154313531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
154413531Sjairo.balart@metempsy.com        uint32_t lr_intid = bits(lr, 31, 0);
154513760Sjairo.balart@metempsy.com
154613760Sjairo.balart@metempsy.com        if ((lr & ICH_LR_EL2_STATE_ACTIVE_BIT) && lr_intid == int_id) {
154713760Sjairo.balart@metempsy.com            return lr_idx;
154813760Sjairo.balart@metempsy.com        }
154913531Sjairo.balart@metempsy.com    }
155013760Sjairo.balart@metempsy.com
155113760Sjairo.balart@metempsy.com    return -1;
155213760Sjairo.balart@metempsy.com}
155313760Sjairo.balart@metempsy.com
155413760Sjairo.balart@metempsy.comuint32_t
155513760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR0()
155613760Sjairo.balart@metempsy.com{
155713531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff) {
155813760Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
155913760Sjairo.balart@metempsy.com    }
156013760Sjairo.balart@metempsy.com
156113760Sjairo.balart@metempsy.com    bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
156213760Sjairo.balart@metempsy.com
156313760Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
156413760Sjairo.balart@metempsy.com        /* Indicate to EL3 that there's a Group 1 interrupt for the
156513760Sjairo.balart@metempsy.com         * other state pending.
156613760Sjairo.balart@metempsy.com         */
156713760Sjairo.balart@metempsy.com        return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
156813760Sjairo.balart@metempsy.com    }
156913760Sjairo.balart@metempsy.com
157013531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
157113531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
157213531Sjairo.balart@metempsy.com    }
157313760Sjairo.balart@metempsy.com
157414236Sgiacomo.travaglini@arm.com    if (irq_is_secure && !inSecureState()) {
157514236Sgiacomo.travaglini@arm.com        // Secure interrupts not visible in Non-secure
157614236Sgiacomo.travaglini@arm.com        return Gicv3::INTID_SPURIOUS;
157714236Sgiacomo.travaglini@arm.com    }
157814236Sgiacomo.travaglini@arm.com
157914236Sgiacomo.travaglini@arm.com    return hppi.intid;
158014236Sgiacomo.travaglini@arm.com}
158114236Sgiacomo.travaglini@arm.com
158214236Sgiacomo.travaglini@arm.comuint32_t
158314236Sgiacomo.travaglini@arm.comGicv3CPUInterface::getHPPIR1()
158414236Sgiacomo.travaglini@arm.com{
158514236Sgiacomo.travaglini@arm.com    if (hppi.prio == 0xff) {
158614236Sgiacomo.travaglini@arm.com        return Gicv3::INTID_SPURIOUS;
158714236Sgiacomo.travaglini@arm.com    }
158814236Sgiacomo.travaglini@arm.com
158914236Sgiacomo.travaglini@arm.com    //if ((currEL() == EL3) && ICC_CTLR_EL3_RM)
159013760Sjairo.balart@metempsy.com    if ((currEL() == EL3) &&
159114236Sgiacomo.travaglini@arm.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3) & ICC_CTLR_EL3_RM) {
159214236Sgiacomo.travaglini@arm.com        if (hppi.group == Gicv3::G0S) {
159313531Sjairo.balart@metempsy.com            return Gicv3::INTID_SECURE;
159413531Sjairo.balart@metempsy.com        } else if (hppi.group == Gicv3::G1NS) {
159514236Sgiacomo.travaglini@arm.com            return Gicv3::INTID_NONSECURE;
159614236Sgiacomo.travaglini@arm.com        }
159714236Sgiacomo.travaglini@arm.com    }
159814236Sgiacomo.travaglini@arm.com
159914236Sgiacomo.travaglini@arm.com    if (hppi.group == Gicv3::G0S) {
160014236Sgiacomo.travaglini@arm.com        return Gicv3::INTID_SPURIOUS;
160114236Sgiacomo.travaglini@arm.com    }
160214236Sgiacomo.travaglini@arm.com
160314236Sgiacomo.travaglini@arm.com    bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
160414236Sgiacomo.travaglini@arm.com
160514236Sgiacomo.travaglini@arm.com    if (irq_is_secure) {
160614236Sgiacomo.travaglini@arm.com        if (!inSecureState()) {
160713531Sjairo.balart@metempsy.com            // Secure interrupts not visible in Non-secure
160813760Sjairo.balart@metempsy.com            return Gicv3::INTID_SPURIOUS;
160913760Sjairo.balart@metempsy.com        }
161013531Sjairo.balart@metempsy.com    } else if (!isEL3OrMon() && inSecureState()) {
161113531Sjairo.balart@metempsy.com        // Group 1 non-secure interrupts not visible in Secure EL1
161213531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
161313531Sjairo.balart@metempsy.com    }
161413531Sjairo.balart@metempsy.com
161513531Sjairo.balart@metempsy.com    return hppi.intid;
161613531Sjairo.balart@metempsy.com}
161713531Sjairo.balart@metempsy.com
161813531Sjairo.balart@metempsy.comvoid
161914243Sgiacomo.travaglini@arm.comGicv3CPUInterface::dropPriority(Gicv3::GroupId group)
162014243Sgiacomo.travaglini@arm.com{
162114243Sgiacomo.travaglini@arm.com    int apr_misc_reg;
162214243Sgiacomo.travaglini@arm.com    RegVal apr;
162314243Sgiacomo.travaglini@arm.com    apr_misc_reg = group == Gicv3::G0S ?
162414243Sgiacomo.travaglini@arm.com                   MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
162514243Sgiacomo.travaglini@arm.com    apr = isa->readMiscRegNoEffect(apr_misc_reg);
162614243Sgiacomo.travaglini@arm.com
162714243Sgiacomo.travaglini@arm.com    if (apr) {
162814243Sgiacomo.travaglini@arm.com        /* Clear the lowest set bit */
162914243Sgiacomo.travaglini@arm.com        apr &= apr - 1;
163014243Sgiacomo.travaglini@arm.com        isa->setMiscRegNoEffect(apr_misc_reg, apr);
163114243Sgiacomo.travaglini@arm.com    }
163214243Sgiacomo.travaglini@arm.com
163313531Sjairo.balart@metempsy.com    update();
163413760Sjairo.balart@metempsy.com}
163513531Sjairo.balart@metempsy.com
163613531Sjairo.balart@metempsy.comuint8_t
163713760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDropPriority()
163813531Sjairo.balart@metempsy.com{
163913760Sjairo.balart@metempsy.com    /* Drop the priority of the currently active virtual interrupt
164013760Sjairo.balart@metempsy.com     * (favouring group 0 if there is a set active bit at
164113760Sjairo.balart@metempsy.com     * the same priority for both group 0 and group 1).
164213760Sjairo.balart@metempsy.com     * Return the priority value for the bit we just cleared,
164313531Sjairo.balart@metempsy.com     * or 0xff if no bits were set in the AP registers at all.
164413531Sjairo.balart@metempsy.com     * Note that though the ich_apr[] are uint64_t only the low
164513531Sjairo.balart@metempsy.com     * 32 bits are actually relevant.
164613531Sjairo.balart@metempsy.com     */
164713531Sjairo.balart@metempsy.com    int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
164813531Sjairo.balart@metempsy.com
164913531Sjairo.balart@metempsy.com    for (int i = 0; i < apr_max; i++) {
165013531Sjairo.balart@metempsy.com        RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
165113760Sjairo.balart@metempsy.com        RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
165213531Sjairo.balart@metempsy.com
165314233Sgiacomo.travaglini@arm.com        if (!vapr0 && !vapr1) {
165413531Sjairo.balart@metempsy.com            continue;
165513531Sjairo.balart@metempsy.com        }
165613531Sjairo.balart@metempsy.com
165713531Sjairo.balart@metempsy.com        int vapr0_count = ctz32(vapr0);
165813531Sjairo.balart@metempsy.com        int vapr1_count = ctz32(vapr1);
165913531Sjairo.balart@metempsy.com
166013760Sjairo.balart@metempsy.com        if (vapr0_count <= vapr1_count) {
166113531Sjairo.balart@metempsy.com            /* Clear the lowest set bit */
166213531Sjairo.balart@metempsy.com            vapr0 &= vapr0 - 1;
166313531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
166413531Sjairo.balart@metempsy.com            return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
166513531Sjairo.balart@metempsy.com        } else {
166613531Sjairo.balart@metempsy.com            /* Clear the lowest set bit */
166713531Sjairo.balart@metempsy.com            vapr1 &= vapr1 - 1;
166813531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
166913531Sjairo.balart@metempsy.com            return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
167013531Sjairo.balart@metempsy.com        }
167113531Sjairo.balart@metempsy.com    }
167213531Sjairo.balart@metempsy.com
167313531Sjairo.balart@metempsy.com    return 0xff;
167413531Sjairo.balart@metempsy.com}
167513531Sjairo.balart@metempsy.com
167613531Sjairo.balart@metempsy.comvoid
167713760Sjairo.balart@metempsy.comGicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
167813531Sjairo.balart@metempsy.com{
167914233Sgiacomo.travaglini@arm.com    // Update active priority registers.
168013531Sjairo.balart@metempsy.com    uint32_t prio = hppi.prio & 0xf8;
168113531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - PRIORITY_BITS);
168213531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
168313760Sjairo.balart@metempsy.com    int apr_idx = group == Gicv3::G0S ?
168413760Sjairo.balart@metempsy.com                 MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
168513531Sjairo.balart@metempsy.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
168613531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
168713531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
168813531Sjairo.balart@metempsy.com
168913531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
169013531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
169113531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
169213531Sjairo.balart@metempsy.com        redistributor->activateIRQ(int_id);
169313531Sjairo.balart@metempsy.com        redistributor->updateAndInformCPUInterface();
169413531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
169513531Sjairo.balart@metempsy.com        // SPI, distributor
169613531Sjairo.balart@metempsy.com        distributor->activateIRQ(int_id);
169713531Sjairo.balart@metempsy.com        distributor->updateAndInformCPUInterfaces();
169813531Sjairo.balart@metempsy.com    }
169913531Sjairo.balart@metempsy.com}
170013531Sjairo.balart@metempsy.com
170113531Sjairo.balart@metempsy.comvoid
170213531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
170313531Sjairo.balart@metempsy.com{
170413531Sjairo.balart@metempsy.com    // Update active priority registers.
170513531Sjairo.balart@metempsy.com    RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
170613531Sjairo.balart@metempsy.com            lr_idx);
170713531Sjairo.balart@metempsy.com    Gicv3::GroupId group = lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
170813531Sjairo.balart@metempsy.com    uint8_t prio = bits(lr, 55, 48) & 0xf8;
170913531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
171013531Sjairo.balart@metempsy.com    int reg_no = apr_bit / 32;
171113531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
171213531Sjairo.balart@metempsy.com    int apr_idx = group == Gicv3::G0S ?
171313531Sjairo.balart@metempsy.com        MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
171414246Sgiacomo.travaglini@arm.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
171514246Sgiacomo.travaglini@arm.com    apr |= (1 << reg_bit);
171614246Sgiacomo.travaglini@arm.com    isa->setMiscRegNoEffect(apr_idx, apr);
171714246Sgiacomo.travaglini@arm.com    // Move interrupt state from pending to active.
171814246Sgiacomo.travaglini@arm.com    lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
171914246Sgiacomo.travaglini@arm.com    lr |= ICH_LR_EL2_STATE_ACTIVE_BIT;
172014246Sgiacomo.travaglini@arm.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, lr);
172114246Sgiacomo.travaglini@arm.com}
172214246Sgiacomo.travaglini@arm.com
172314246Sgiacomo.travaglini@arm.comvoid
172414246Sgiacomo.travaglini@arm.comGicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
172514246Sgiacomo.travaglini@arm.com{
172614246Sgiacomo.travaglini@arm.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
172714246Sgiacomo.travaglini@arm.com        // SGI or PPI, redistributor
172814246Sgiacomo.travaglini@arm.com        redistributor->deactivateIRQ(int_id);
172914246Sgiacomo.travaglini@arm.com        redistributor->updateAndInformCPUInterface();
173014246Sgiacomo.travaglini@arm.com    } else if (int_id < Gicv3::INTID_SECURE) {
173113531Sjairo.balart@metempsy.com        // SPI, distributor
173213531Sjairo.balart@metempsy.com        distributor->deactivateIRQ(int_id);
173313531Sjairo.balart@metempsy.com        distributor->updateAndInformCPUInterfaces();
173413531Sjairo.balart@metempsy.com    } else {
173513531Sjairo.balart@metempsy.com        return;
173613531Sjairo.balart@metempsy.com    }
173713531Sjairo.balart@metempsy.com}
173813531Sjairo.balart@metempsy.com
173913531Sjairo.balart@metempsy.comvoid
174013531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
174113531Sjairo.balart@metempsy.com{
174213531Sjairo.balart@metempsy.com    RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
174313531Sjairo.balart@metempsy.com            lr_idx);
174413531Sjairo.balart@metempsy.com
174513531Sjairo.balart@metempsy.com    if (lr & ICH_LR_EL2_HW) {
174613580Sgabeblack@google.com        // Deactivate the associated physical interrupt
174713580Sgabeblack@google.com        int pintid = bits(lr, 41, 32);
174813531Sjairo.balart@metempsy.com
174913531Sjairo.balart@metempsy.com        if (pintid < Gicv3::INTID_SECURE) {
175013531Sjairo.balart@metempsy.com            Gicv3::GroupId group =
175113531Sjairo.balart@metempsy.com                pintid >= 32 ? distributor->getIntGroup(pintid) :
175213531Sjairo.balart@metempsy.com                redistributor->getIntGroup(pintid);
175313531Sjairo.balart@metempsy.com            deactivateIRQ(pintid, group);
175413531Sjairo.balart@metempsy.com        }
175513531Sjairo.balart@metempsy.com    }
175613531Sjairo.balart@metempsy.com
175713531Sjairo.balart@metempsy.com    //  Remove the active bit
175813531Sjairo.balart@metempsy.com    lr &= ~ICH_LR_EL2_STATE_ACTIVE_BIT;
175913531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, lr);
176013531Sjairo.balart@metempsy.com}
176113531Sjairo.balart@metempsy.com
176213531Sjairo.balart@metempsy.com/*
176313531Sjairo.balart@metempsy.com * Return a mask word which clears the subpriority bits from
176413531Sjairo.balart@metempsy.com * a priority value for an interrupt in the specified group.
176513531Sjairo.balart@metempsy.com * This depends on the BPR value. For CBPR0 (S or NS):
176613531Sjairo.balart@metempsy.com *  a BPR of 0 means the group priority bits are [7:1];
176713531Sjairo.balart@metempsy.com *  a BPR of 1 means they are [7:2], and so on down to
176813531Sjairo.balart@metempsy.com *  ...
176913531Sjairo.balart@metempsy.com *  a BPR of 7 meaning no group priority bits at all.
177013531Sjairo.balart@metempsy.com * For CBPR1 NS:
177114227Sgiacomo.travaglini@arm.com *  a BPR of 0 is impossible (the minimum value is 1)
177214227Sgiacomo.travaglini@arm.com *  a BPR of 1 means the group priority bits are [7:1];
177314227Sgiacomo.travaglini@arm.com *  a BPR of 2 means they are [7:2], and so on down to
177414227Sgiacomo.travaglini@arm.com *  ...
177514227Sgiacomo.travaglini@arm.com *  a BPR of 7 meaning the group priority is [7].
177614227Sgiacomo.travaglini@arm.com *
177714227Sgiacomo.travaglini@arm.com * Which BPR to use depends on the group of the interrupt and
177814227Sgiacomo.travaglini@arm.com * the current ICC_CTLR.CBPR settings.
177914227Sgiacomo.travaglini@arm.com *
178014227Sgiacomo.travaglini@arm.com * This corresponds to the GroupBits() pseudocode from 4.8.2.
178114227Sgiacomo.travaglini@arm.com */
178214227Sgiacomo.travaglini@arm.comuint32_t
178314227Sgiacomo.travaglini@arm.comGicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
178414227Sgiacomo.travaglini@arm.com{
178514227Sgiacomo.travaglini@arm.com    if ((group == Gicv3::G1S &&
178614227Sgiacomo.travaglini@arm.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S)
178714227Sgiacomo.travaglini@arm.com            & ICC_CTLR_EL1_CBPR) ||
178814227Sgiacomo.travaglini@arm.com            (group == Gicv3::G1NS &&
178914227Sgiacomo.travaglini@arm.com             isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS)
179014227Sgiacomo.travaglini@arm.com             & ICC_CTLR_EL1_CBPR)) {
179114227Sgiacomo.travaglini@arm.com        group = Gicv3::G0S;
179214227Sgiacomo.travaglini@arm.com    }
179314227Sgiacomo.travaglini@arm.com
179414227Sgiacomo.travaglini@arm.com    int bpr;
179514227Sgiacomo.travaglini@arm.com
179614227Sgiacomo.travaglini@arm.com    if (group == Gicv3::G0S) {
179714227Sgiacomo.travaglini@arm.com        bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1) & 0x7;
179814227Sgiacomo.travaglini@arm.com    } else {
179914227Sgiacomo.travaglini@arm.com        bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1) & 0x7;
180014227Sgiacomo.travaglini@arm.com    }
180114227Sgiacomo.travaglini@arm.com
180214227Sgiacomo.travaglini@arm.com    if (group == Gicv3::G1NS) {
180314227Sgiacomo.travaglini@arm.com        assert(bpr > 0);
180414227Sgiacomo.travaglini@arm.com        bpr--;
180514227Sgiacomo.travaglini@arm.com    }
180614227Sgiacomo.travaglini@arm.com
180714227Sgiacomo.travaglini@arm.com    return ~0U << (bpr + 1);
180814227Sgiacomo.travaglini@arm.com}
180914227Sgiacomo.travaglini@arm.com
181014227Sgiacomo.travaglini@arm.comuint32_t
181114227Sgiacomo.travaglini@arm.comGicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group)
181214227Sgiacomo.travaglini@arm.com{
181314227Sgiacomo.travaglini@arm.com    RegVal ich_vmcr_el2 =
181414227Sgiacomo.travaglini@arm.com        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
181513531Sjairo.balart@metempsy.com
181613531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
181713531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
181813531Sjairo.balart@metempsy.com    }
181913531Sjairo.balart@metempsy.com
182013531Sjairo.balart@metempsy.com    int bpr;
182114246Sgiacomo.travaglini@arm.com
182214246Sgiacomo.travaglini@arm.com    if (group == Gicv3::G0S) {
182314246Sgiacomo.travaglini@arm.com        bpr = bits(ich_vmcr_el2, 23, 21);
182414246Sgiacomo.travaglini@arm.com    } else {
182514246Sgiacomo.travaglini@arm.com        bpr = bits(ich_vmcr_el2, 20, 18);
182614246Sgiacomo.travaglini@arm.com    }
182714246Sgiacomo.travaglini@arm.com
182814246Sgiacomo.travaglini@arm.com    if (group == Gicv3::G1NS) {
182914246Sgiacomo.travaglini@arm.com        assert(bpr > 0);
183014246Sgiacomo.travaglini@arm.com        bpr--;
183114246Sgiacomo.travaglini@arm.com    }
183214246Sgiacomo.travaglini@arm.com
183314246Sgiacomo.travaglini@arm.com    return ~0U << (bpr + 1);
183414246Sgiacomo.travaglini@arm.com}
183514246Sgiacomo.travaglini@arm.com
183614246Sgiacomo.travaglini@arm.combool
183713580Sgabeblack@google.comGicv3CPUInterface::isEOISplitMode()
183813531Sjairo.balart@metempsy.com{
183913531Sjairo.balart@metempsy.com    if (isEL3OrMon()) {
184013531Sjairo.balart@metempsy.com        return isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3) &
184113531Sjairo.balart@metempsy.com               ICC_CTLR_EL3_EOIMODE_EL3;
184213531Sjairo.balart@metempsy.com    } else {
184313531Sjairo.balart@metempsy.com        return isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1) &
184413531Sjairo.balart@metempsy.com               ICC_CTLR_EL1_EOIMODE;
184513531Sjairo.balart@metempsy.com    }
184613531Sjairo.balart@metempsy.com}
184713531Sjairo.balart@metempsy.com
184813923Sgiacomo.travaglini@arm.combool
184913923Sgiacomo.travaglini@arm.comGicv3CPUInterface::virtualIsEOISplitMode()
185013923Sgiacomo.travaglini@arm.com{
185113531Sjairo.balart@metempsy.com    RegVal ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
185214231Sgiacomo.travaglini@arm.com    return ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM;
185314231Sgiacomo.travaglini@arm.com}
185414231Sgiacomo.travaglini@arm.com
185514231Sgiacomo.travaglini@arm.comint
185614231Sgiacomo.travaglini@arm.comGicv3CPUInterface::highestActiveGroup()
185714231Sgiacomo.travaglini@arm.com{
185813531Sjairo.balart@metempsy.com    int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
185913531Sjairo.balart@metempsy.com    int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
186013531Sjairo.balart@metempsy.com    int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));
186113531Sjairo.balart@metempsy.com
186213531Sjairo.balart@metempsy.com    if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
186313531Sjairo.balart@metempsy.com        return Gicv3::G1NS;
186413760Sjairo.balart@metempsy.com    }
186513531Sjairo.balart@metempsy.com
186613760Sjairo.balart@metempsy.com    if (gq_ctz < g0_ctz) {
186713760Sjairo.balart@metempsy.com        return Gicv3::G1S;
186813531Sjairo.balart@metempsy.com    }
186913531Sjairo.balart@metempsy.com
187013531Sjairo.balart@metempsy.com    if (g0_ctz < 32) {
187113531Sjairo.balart@metempsy.com        return Gicv3::G0S;
187213531Sjairo.balart@metempsy.com    }
187313580Sgabeblack@google.com
187413531Sjairo.balart@metempsy.com    return -1;
187513531Sjairo.balart@metempsy.com}
187613531Sjairo.balart@metempsy.com
187713760Sjairo.balart@metempsy.comvoid
187813760Sjairo.balart@metempsy.comGicv3CPUInterface::update()
187913531Sjairo.balart@metempsy.com{
188013531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
188113531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
188213531Sjairo.balart@metempsy.com
188313531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
188413531Sjairo.balart@metempsy.com        /*
188513531Sjairo.balart@metempsy.com         * Secure enabled GIC sending a G1S IRQ to a secure disabled
188613531Sjairo.balart@metempsy.com         * CPU -> send G0 IRQ
188713531Sjairo.balart@metempsy.com         */
188813531Sjairo.balart@metempsy.com        hppi.group = Gicv3::G0S;
188913531Sjairo.balart@metempsy.com    }
189013531Sjairo.balart@metempsy.com
189114231Sgiacomo.travaglini@arm.com    if (hppiCanPreempt()) {
189214231Sgiacomo.travaglini@arm.com        ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
189313531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::update(): "
189413531Sjairo.balart@metempsy.com                "posting int as %d!\n", int_type);
189513531Sjairo.balart@metempsy.com        int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
189613531Sjairo.balart@metempsy.com    }
189713531Sjairo.balart@metempsy.com
189813760Sjairo.balart@metempsy.com    if (signal_IRQ) {
189913531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_IRQ);
190013531Sjairo.balart@metempsy.com    } else {
190113760Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_IRQ);
190213531Sjairo.balart@metempsy.com    }
190313760Sjairo.balart@metempsy.com
190413760Sjairo.balart@metempsy.com    if (signal_FIQ) {
190513760Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_FIQ);
190613760Sjairo.balart@metempsy.com    } else {
190713760Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_FIQ);
190813531Sjairo.balart@metempsy.com    }
190913531Sjairo.balart@metempsy.com}
191013531Sjairo.balart@metempsy.com
191113531Sjairo.balart@metempsy.comvoid
191213760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualUpdate()
191313760Sjairo.balart@metempsy.com{
191413531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
191513531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
191613531Sjairo.balart@metempsy.com    int lr_idx = getHPPVILR();
191713760Sjairo.balart@metempsy.com
191813760Sjairo.balart@metempsy.com    if (lr_idx >= 0) {
191913531Sjairo.balart@metempsy.com        RegVal ich_lr_el2 =
192013531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
192113926Sgiacomo.travaglini@arm.com
192213531Sjairo.balart@metempsy.com        if (hppviCanPreempt(lr_idx)) {
192313760Sjairo.balart@metempsy.com            if (ich_lr_el2 & ICH_LR_EL2_GROUP) {
192413760Sjairo.balart@metempsy.com                signal_IRQ = true;
192513760Sjairo.balart@metempsy.com            } else {
192613760Sjairo.balart@metempsy.com                signal_FIQ = true;
192713760Sjairo.balart@metempsy.com            }
192813760Sjairo.balart@metempsy.com        }
192913760Sjairo.balart@metempsy.com    }
193013531Sjairo.balart@metempsy.com
193113531Sjairo.balart@metempsy.com    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
193213531Sjairo.balart@metempsy.com
193313531Sjairo.balart@metempsy.com    if (ich_hcr_el2 & ICH_HCR_EL2_EN) {
193413531Sjairo.balart@metempsy.com        if (maintenanceInterruptStatus()) {
193513531Sjairo.balart@metempsy.com            redistributor->sendPPInt(25);
193613926Sgiacomo.travaglini@arm.com        }
193714237Sgiacomo.travaglini@arm.com    }
193814237Sgiacomo.travaglini@arm.com
193913531Sjairo.balart@metempsy.com    if (signal_IRQ) {
194014237Sgiacomo.travaglini@arm.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
194113531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
194213531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ);
194313531Sjairo.balart@metempsy.com    } else {
194413531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ);
194513531Sjairo.balart@metempsy.com    }
194613531Sjairo.balart@metempsy.com
194713531Sjairo.balart@metempsy.com    if (signal_FIQ) {
194813531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
194913531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
195013531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ);
195113531Sjairo.balart@metempsy.com    } else {
195213760Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ);
195313531Sjairo.balart@metempsy.com    }
195413760Sjairo.balart@metempsy.com}
195513531Sjairo.balart@metempsy.com
195613531Sjairo.balart@metempsy.com// Returns the intex of the LR with the HPPI
195713760Sjairo.balart@metempsy.comint
195813531Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPVILR()
195913531Sjairo.balart@metempsy.com{
196013531Sjairo.balart@metempsy.com    int idx = -1;
196113531Sjairo.balart@metempsy.com    RegVal ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
196213531Sjairo.balart@metempsy.com
196313531Sjairo.balart@metempsy.com    if (!(ich_vmcr_el2 & (ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1))) {
196413760Sjairo.balart@metempsy.com        // VG0 and VG1 disabled...
196513531Sjairo.balart@metempsy.com        return idx;
196613760Sjairo.balart@metempsy.com    }
196713531Sjairo.balart@metempsy.com
196813531Sjairo.balart@metempsy.com    uint8_t highest_prio = 0xff;
196913531Sjairo.balart@metempsy.com
197013531Sjairo.balart@metempsy.com    for (int i = 0; i < 16; i++) {
197113531Sjairo.balart@metempsy.com        RegVal ich_lri_el2 =
197213531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
197313531Sjairo.balart@metempsy.com        uint8_t state = bits(ich_lri_el2, 63, 62);
197413531Sjairo.balart@metempsy.com
197513531Sjairo.balart@metempsy.com        if (state != Gicv3::INT_PENDING) {
197613531Sjairo.balart@metempsy.com            continue;
197713531Sjairo.balart@metempsy.com        }
197813760Sjairo.balart@metempsy.com
197913531Sjairo.balart@metempsy.com        if (ich_lri_el2 & ICH_LR_EL2_GROUP) {
198013531Sjairo.balart@metempsy.com            // VG1
198113760Sjairo.balart@metempsy.com            if (!(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
198213760Sjairo.balart@metempsy.com                continue;
198313760Sjairo.balart@metempsy.com            }
198413531Sjairo.balart@metempsy.com        } else {
198514245Sgiacomo.travaglini@arm.com            // VG0
198614245Sgiacomo.travaglini@arm.com            if (!(ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
198714245Sgiacomo.travaglini@arm.com                continue;
198814245Sgiacomo.travaglini@arm.com            }
198914245Sgiacomo.travaglini@arm.com        }
199013760Sjairo.balart@metempsy.com
199113531Sjairo.balart@metempsy.com        uint8_t prio = bits(ich_lri_el2, 55, 48);
199213531Sjairo.balart@metempsy.com
199313531Sjairo.balart@metempsy.com        if (prio < highest_prio) {
199413531Sjairo.balart@metempsy.com            highest_prio = prio;
199513760Sjairo.balart@metempsy.com            idx = i;
199613531Sjairo.balart@metempsy.com        }
199713760Sjairo.balart@metempsy.com    }
199813760Sjairo.balart@metempsy.com
199913531Sjairo.balart@metempsy.com    return idx;
200013531Sjairo.balart@metempsy.com}
200113531Sjairo.balart@metempsy.com
200213760Sjairo.balart@metempsy.combool
200313531Sjairo.balart@metempsy.comGicv3CPUInterface::hppviCanPreempt(int lr_idx)
200413531Sjairo.balart@metempsy.com{
200513531Sjairo.balart@metempsy.com    RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
200613531Sjairo.balart@metempsy.com
200713531Sjairo.balart@metempsy.com    if (!(isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2) & ICH_HCR_EL2_EN)) {
200813531Sjairo.balart@metempsy.com        // virtual interface is disabled
200913531Sjairo.balart@metempsy.com        return false;
201013531Sjairo.balart@metempsy.com    }
201113531Sjairo.balart@metempsy.com
201213531Sjairo.balart@metempsy.com    uint8_t prio = bits(lr, 55, 48);
201313531Sjairo.balart@metempsy.com    uint8_t vpmr =
201413531Sjairo.balart@metempsy.com        bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);
201513531Sjairo.balart@metempsy.com
201613531Sjairo.balart@metempsy.com    if (prio >= vpmr) {
201713531Sjairo.balart@metempsy.com        // prioriry masked
201813531Sjairo.balart@metempsy.com        return false;
201913531Sjairo.balart@metempsy.com    }
202013531Sjairo.balart@metempsy.com
202113531Sjairo.balart@metempsy.com    uint8_t rprio = virtualHighestActivePriority();
202213531Sjairo.balart@metempsy.com
202313531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
202414231Sgiacomo.travaglini@arm.com        return true;
202514231Sgiacomo.travaglini@arm.com    }
202614231Sgiacomo.travaglini@arm.com
202714231Sgiacomo.travaglini@arm.com    Gicv3::GroupId group = lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
202814231Sgiacomo.travaglini@arm.com    uint32_t prio_mask = virtualGroupPriorityMask(group);
202914231Sgiacomo.travaglini@arm.com
203013531Sjairo.balart@metempsy.com    if ((prio & prio_mask) < (rprio & prio_mask)) {
203113531Sjairo.balart@metempsy.com        return true;
203213531Sjairo.balart@metempsy.com    }
203313531Sjairo.balart@metempsy.com
203413531Sjairo.balart@metempsy.com    return false;
203513531Sjairo.balart@metempsy.com}
203613531Sjairo.balart@metempsy.com
203713531Sjairo.balart@metempsy.comuint8_t
203813531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualHighestActivePriority()
203913531Sjairo.balart@metempsy.com{
204013531Sjairo.balart@metempsy.com    uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
204113531Sjairo.balart@metempsy.com
204213531Sjairo.balart@metempsy.com    for (int i = 0; i < num_aprs; i++) {
204313531Sjairo.balart@metempsy.com        RegVal vapr =
204413531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
204513531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
204613531Sjairo.balart@metempsy.com
204713531Sjairo.balart@metempsy.com        if (!vapr) {
204813531Sjairo.balart@metempsy.com            continue;
204913531Sjairo.balart@metempsy.com        }
205013531Sjairo.balart@metempsy.com
205113531Sjairo.balart@metempsy.com        return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
205213531Sjairo.balart@metempsy.com    }
205313531Sjairo.balart@metempsy.com
205413531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
205513531Sjairo.balart@metempsy.com    return 0xff;
205613531Sjairo.balart@metempsy.com}
205713531Sjairo.balart@metempsy.com
205813531Sjairo.balart@metempsy.comvoid
205913531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIncrementEOICount()
206013531Sjairo.balart@metempsy.com{
206113531Sjairo.balart@metempsy.com    // Increment the EOICOUNT field in ICH_HCR_EL2
206213531Sjairo.balart@metempsy.com    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
206313531Sjairo.balart@metempsy.com    uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
206413531Sjairo.balart@metempsy.com    EOI_cout++;
206513531Sjairo.balart@metempsy.com    ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
206613531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
206713531Sjairo.balart@metempsy.com}
206813531Sjairo.balart@metempsy.com
206913531Sjairo.balart@metempsy.com/*
207013531Sjairo.balart@metempsy.com * Should we signal the interrupt as IRQ or FIQ?
207113760Sjairo.balart@metempsy.com * see spec section 4.6.2
207213531Sjairo.balart@metempsy.com */
207313531Sjairo.balart@metempsy.comArmISA::InterruptTypes
207413531Sjairo.balart@metempsy.comGicv3CPUInterface::intSignalType(Gicv3::GroupId group)
207513760Sjairo.balart@metempsy.com{
207613531Sjairo.balart@metempsy.com    bool is_fiq = false;
207713531Sjairo.balart@metempsy.com
207813531Sjairo.balart@metempsy.com    switch (group) {
207913531Sjairo.balart@metempsy.com      case Gicv3::G0S:
208013531Sjairo.balart@metempsy.com        is_fiq = true;
208113531Sjairo.balart@metempsy.com        break;
208213531Sjairo.balart@metempsy.com
208313760Sjairo.balart@metempsy.com      case Gicv3::G1S:
208413760Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) &&
208513760Sjairo.balart@metempsy.com            (!inSecureState() || ((currEL() == EL3) && isAA64()));
208613531Sjairo.balart@metempsy.com        break;
208713826Sgiacomo.travaglini@arm.com
208813531Sjairo.balart@metempsy.com      case Gicv3::G1NS:
208913531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) && inSecureState();
209013531Sjairo.balart@metempsy.com        break;
209113531Sjairo.balart@metempsy.com
209213531Sjairo.balart@metempsy.com      default:
209313531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::intSignalType(): invalid group!");
209413531Sjairo.balart@metempsy.com    }
209513531Sjairo.balart@metempsy.com
209613531Sjairo.balart@metempsy.com    if (is_fiq) {
209713531Sjairo.balart@metempsy.com        return ArmISA::INT_FIQ;
209813531Sjairo.balart@metempsy.com    } else {
209913531Sjairo.balart@metempsy.com        return ArmISA::INT_IRQ;
210013531Sjairo.balart@metempsy.com    }
210113531Sjairo.balart@metempsy.com}
210213531Sjairo.balart@metempsy.com
210313531Sjairo.balart@metempsy.combool
210413531Sjairo.balart@metempsy.comGicv3CPUInterface::hppiCanPreempt()
210513531Sjairo.balart@metempsy.com{
210613531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff) {
210713531Sjairo.balart@metempsy.com        // there is no pending interrupt
210813760Sjairo.balart@metempsy.com        return false;
210913531Sjairo.balart@metempsy.com    }
211013760Sjairo.balart@metempsy.com
211113531Sjairo.balart@metempsy.com    if (!groupEnabled(hppi.group)) {
211213531Sjairo.balart@metempsy.com        // group disabled at CPU interface
211313760Sjairo.balart@metempsy.com        return false;
211413760Sjairo.balart@metempsy.com    }
211513760Sjairo.balart@metempsy.com
211613531Sjairo.balart@metempsy.com    if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
211713531Sjairo.balart@metempsy.com        // priority masked
211813531Sjairo.balart@metempsy.com        return false;
211913531Sjairo.balart@metempsy.com    }
212013531Sjairo.balart@metempsy.com
212113531Sjairo.balart@metempsy.com    uint8_t rprio = highestActivePriority();
212213531Sjairo.balart@metempsy.com
212313760Sjairo.balart@metempsy.com    if (rprio == 0xff) {
212413531Sjairo.balart@metempsy.com        return true;
212513760Sjairo.balart@metempsy.com    }
212613760Sjairo.balart@metempsy.com
212713531Sjairo.balart@metempsy.com    uint32_t prio_mask = groupPriorityMask(hppi.group);
212813531Sjairo.balart@metempsy.com
212913531Sjairo.balart@metempsy.com    if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
213013760Sjairo.balart@metempsy.com        return true;
213113531Sjairo.balart@metempsy.com    }
213213760Sjairo.balart@metempsy.com
213313531Sjairo.balart@metempsy.com    return false;
213413531Sjairo.balart@metempsy.com}
213513531Sjairo.balart@metempsy.com
213613531Sjairo.balart@metempsy.comuint8_t
213713760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActivePriority()
213813531Sjairo.balart@metempsy.com{
213913531Sjairo.balart@metempsy.com    uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
214013531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
214113531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);
214213760Sjairo.balart@metempsy.com
214313531Sjairo.balart@metempsy.com    if (apr) {
214413531Sjairo.balart@metempsy.com        return ctz32(apr) << (GIC_MIN_BPR + 1);
214513531Sjairo.balart@metempsy.com    }
214613531Sjairo.balart@metempsy.com
214713531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
214813531Sjairo.balart@metempsy.com    return 0xff;
214913531Sjairo.balart@metempsy.com}
215013531Sjairo.balart@metempsy.com
215113531Sjairo.balart@metempsy.combool
215213531Sjairo.balart@metempsy.comGicv3CPUInterface::groupEnabled(Gicv3::GroupId group)
215313531Sjairo.balart@metempsy.com{
215413760Sjairo.balart@metempsy.com    switch (group) {
215513531Sjairo.balart@metempsy.com      case Gicv3::G0S:
215613760Sjairo.balart@metempsy.com        return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1) &
215713760Sjairo.balart@metempsy.com            ICC_IGRPEN0_EL1_ENABLE;
215813531Sjairo.balart@metempsy.com
215913531Sjairo.balart@metempsy.com      case Gicv3::G1S:
216013531Sjairo.balart@metempsy.com        //if (distributor->DS)
216113531Sjairo.balart@metempsy.com        //{
216213760Sjairo.balart@metempsy.com        //    return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
216313760Sjairo.balart@metempsy.com        //           ICC_IGRPEN1_EL1_ENABLE;
216413760Sjairo.balart@metempsy.com        //}
216513531Sjairo.balart@metempsy.com        //else
216613531Sjairo.balart@metempsy.com        //{
216713531Sjairo.balart@metempsy.com        return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S) &
216813531Sjairo.balart@metempsy.com            ICC_IGRPEN1_EL1_ENABLE;
216913531Sjairo.balart@metempsy.com
217013531Sjairo.balart@metempsy.com        //}
217113531Sjairo.balart@metempsy.com
217213531Sjairo.balart@metempsy.com      case Gicv3::G1NS:
217313531Sjairo.balart@metempsy.com        return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
217413531Sjairo.balart@metempsy.com            ICC_IGRPEN1_EL1_ENABLE;
217513531Sjairo.balart@metempsy.com
217613531Sjairo.balart@metempsy.com      default:
217713531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
217813531Sjairo.balart@metempsy.com    }
217913760Sjairo.balart@metempsy.com}
218013531Sjairo.balart@metempsy.com
218113531Sjairo.balart@metempsy.combool
218213531Sjairo.balart@metempsy.comGicv3CPUInterface::inSecureState()
218313531Sjairo.balart@metempsy.com{
218413531Sjairo.balart@metempsy.com    if (!gic->getSystem()->haveSecurity()) {
218513531Sjairo.balart@metempsy.com        return false;
218613531Sjairo.balart@metempsy.com    }
218713531Sjairo.balart@metempsy.com
218813531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
218913531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
219013760Sjairo.balart@metempsy.com    return ArmISA::inSecureState(scr, cpsr);
219113531Sjairo.balart@metempsy.com}
219213531Sjairo.balart@metempsy.com
219313531Sjairo.balart@metempsy.comint
219413531Sjairo.balart@metempsy.comGicv3CPUInterface::currEL()
219513580Sgabeblack@google.com{
219613531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
219713531Sjairo.balart@metempsy.com    bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
219813531Sjairo.balart@metempsy.com
219913531Sjairo.balart@metempsy.com    if (is_64) {
220013531Sjairo.balart@metempsy.com        return (ExceptionLevel)(uint8_t) cpsr.el;
220113531Sjairo.balart@metempsy.com    } else {
220213531Sjairo.balart@metempsy.com        switch (cpsr.mode) {
220313531Sjairo.balart@metempsy.com          case MODE_USER:
220413531Sjairo.balart@metempsy.com            return 0;
220513531Sjairo.balart@metempsy.com
220613531Sjairo.balart@metempsy.com          case MODE_HYP:
220713531Sjairo.balart@metempsy.com            return 2;
220813531Sjairo.balart@metempsy.com
220913531Sjairo.balart@metempsy.com          case MODE_MON:
221013531Sjairo.balart@metempsy.com            return 3;
221113531Sjairo.balart@metempsy.com
221213531Sjairo.balart@metempsy.com          default:
221313531Sjairo.balart@metempsy.com            return 1;
221413580Sgabeblack@google.com        }
221513531Sjairo.balart@metempsy.com    }
221613531Sjairo.balart@metempsy.com}
221713531Sjairo.balart@metempsy.com
221813531Sjairo.balart@metempsy.combool
221913531Sjairo.balart@metempsy.comGicv3CPUInterface::haveEL(ExceptionLevel el)
222013531Sjairo.balart@metempsy.com{
222113760Sjairo.balart@metempsy.com    switch (el) {
222213531Sjairo.balart@metempsy.com      case EL0:
222313760Sjairo.balart@metempsy.com      case EL1:
222413531Sjairo.balart@metempsy.com        return true;
222513531Sjairo.balart@metempsy.com
222613531Sjairo.balart@metempsy.com      case EL2:
222713531Sjairo.balart@metempsy.com        return gic->getSystem()->haveVirtualization();
222813531Sjairo.balart@metempsy.com
222913531Sjairo.balart@metempsy.com      case EL3:
223013531Sjairo.balart@metempsy.com        return gic->getSystem()->haveSecurity();
223113531Sjairo.balart@metempsy.com
223213531Sjairo.balart@metempsy.com      default:
223313531Sjairo.balart@metempsy.com        warn("Unimplemented Exception Level\n");
223413531Sjairo.balart@metempsy.com        return false;
223513531Sjairo.balart@metempsy.com    }
223613531Sjairo.balart@metempsy.com}
223713531Sjairo.balart@metempsy.com
223813531Sjairo.balart@metempsy.combool
223913531Sjairo.balart@metempsy.comGicv3CPUInterface::isSecureBelowEL3()
224013531Sjairo.balart@metempsy.com{
224113531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
224213531Sjairo.balart@metempsy.com    return haveEL(EL3) && scr.ns == 0;
224313531Sjairo.balart@metempsy.com}
224413531Sjairo.balart@metempsy.com
224513531Sjairo.balart@metempsy.combool
224613531Sjairo.balart@metempsy.comGicv3CPUInterface::isAA64()
224713531Sjairo.balart@metempsy.com{
224813531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
224913531Sjairo.balart@metempsy.com    return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
225013531Sjairo.balart@metempsy.com}
225113531Sjairo.balart@metempsy.com
225213531Sjairo.balart@metempsy.combool
225313926Sgiacomo.travaglini@arm.comGicv3CPUInterface::isEL3OrMon()
225413531Sjairo.balart@metempsy.com{
225513531Sjairo.balart@metempsy.com    if (haveEL(EL3)) {
225613531Sjairo.balart@metempsy.com        CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
225713531Sjairo.balart@metempsy.com        bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
225813531Sjairo.balart@metempsy.com
225913531Sjairo.balart@metempsy.com        if (is_64 && (cpsr.el == EL3)) {
226013531Sjairo.balart@metempsy.com            return true;
226113531Sjairo.balart@metempsy.com        } else if (!is_64 && (cpsr.mode == MODE_MON)) {
226213531Sjairo.balart@metempsy.com            return true;
226313531Sjairo.balart@metempsy.com        }
226413531Sjairo.balart@metempsy.com    }
226513531Sjairo.balart@metempsy.com
226613531Sjairo.balart@metempsy.com    return false;
226713531Sjairo.balart@metempsy.com}
226813531Sjairo.balart@metempsy.com
226913531Sjairo.balart@metempsy.comuint32_t
227013531Sjairo.balart@metempsy.comGicv3CPUInterface::eoiMaintenanceInterruptStatus(uint32_t * misr)
227113531Sjairo.balart@metempsy.com{
227213531Sjairo.balart@metempsy.com    /* Return a set of bits indicating the EOI maintenance interrupt status
227313531Sjairo.balart@metempsy.com     * for each list register. The EOI maintenance interrupt status is
227413531Sjairo.balart@metempsy.com     * 1 if LR.State == 0 && LR.HW == 0 && LR.EOI == 1
227513531Sjairo.balart@metempsy.com     * (see the GICv3 spec for the ICH_EISR_EL2 register).
227613531Sjairo.balart@metempsy.com     * If misr is not NULL then we should also collect the information
227713531Sjairo.balart@metempsy.com     * about the MISR.EOI, MISR.NP and MISR.U bits.
227813531Sjairo.balart@metempsy.com     */
227913531Sjairo.balart@metempsy.com    uint32_t value = 0;
228013531Sjairo.balart@metempsy.com    int valid_count = 0;
228113531Sjairo.balart@metempsy.com    bool seen_pending = false;
228213531Sjairo.balart@metempsy.com
228313531Sjairo.balart@metempsy.com    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
228413531Sjairo.balart@metempsy.com        RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
228513531Sjairo.balart@metempsy.com
228613760Sjairo.balart@metempsy.com        if ((lr & (ICH_LR_EL2_STATE_MASK | ICH_LR_EL2_HW | ICH_LR_EL2_EOI)) ==
228713531Sjairo.balart@metempsy.com                ICH_LR_EL2_EOI) {
228813531Sjairo.balart@metempsy.com            value |= (1 << lr_idx);
228913531Sjairo.balart@metempsy.com        }
229013531Sjairo.balart@metempsy.com
229113531Sjairo.balart@metempsy.com        if ((lr & ICH_LR_EL2_STATE_MASK)) {
229213531Sjairo.balart@metempsy.com            valid_count++;
229313531Sjairo.balart@metempsy.com        }
229413531Sjairo.balart@metempsy.com
229513531Sjairo.balart@metempsy.com        if (bits(lr, ICH_LR_EL2_STATE_SHIFT + ICH_LR_EL2_STATE_LENGTH,
229613531Sjairo.balart@metempsy.com                 ICH_LR_EL2_STATE_SHIFT) == ICH_LR_EL2_STATE_PENDING) {
229713531Sjairo.balart@metempsy.com            seen_pending = true;
229813531Sjairo.balart@metempsy.com        }
229913531Sjairo.balart@metempsy.com    }
230013531Sjairo.balart@metempsy.com
230113760Sjairo.balart@metempsy.com    if (misr) {
230213531Sjairo.balart@metempsy.com        RegVal ich_hcr_el2 =
230313531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
230413760Sjairo.balart@metempsy.com
230513760Sjairo.balart@metempsy.com        if (valid_count < 2 && (ich_hcr_el2 & ICH_HCR_EL2_UIE)) {
230613760Sjairo.balart@metempsy.com            *misr |= ICH_MISR_EL2_U;
230714234Sgiacomo.travaglini@arm.com        }
230813760Sjairo.balart@metempsy.com
230913760Sjairo.balart@metempsy.com        if (!seen_pending && (ich_hcr_el2 & ICH_HCR_EL2_NPIE)) {
231013760Sjairo.balart@metempsy.com            *misr |= ICH_MISR_EL2_NP;
231113760Sjairo.balart@metempsy.com        }
231213760Sjairo.balart@metempsy.com
231314234Sgiacomo.travaglini@arm.com        if (value) {
231413760Sjairo.balart@metempsy.com            *misr |= ICH_MISR_EL2_EOI;
231513760Sjairo.balart@metempsy.com        }
231613760Sjairo.balart@metempsy.com    }
231713760Sjairo.balart@metempsy.com
231813760Sjairo.balart@metempsy.com    return value;
231914234Sgiacomo.travaglini@arm.com}
232013760Sjairo.balart@metempsy.com
232113531Sjairo.balart@metempsy.comuint32_t
232213531Sjairo.balart@metempsy.comGicv3CPUInterface::maintenanceInterruptStatus()
232313531Sjairo.balart@metempsy.com{
232413531Sjairo.balart@metempsy.com    /* Return a set of bits indicating the maintenance interrupt status
232513531Sjairo.balart@metempsy.com     * (as seen in the ICH_MISR_EL2 register).
232613531Sjairo.balart@metempsy.com     */
232713531Sjairo.balart@metempsy.com    uint32_t value = 0;
232813760Sjairo.balart@metempsy.com    /* Scan list registers and fill in the U, NP and EOI bits */
232913531Sjairo.balart@metempsy.com    eoiMaintenanceInterruptStatus(&value);
233013531Sjairo.balart@metempsy.com    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
233113531Sjairo.balart@metempsy.com    RegVal ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
233213531Sjairo.balart@metempsy.com
233313531Sjairo.balart@metempsy.com    if (ich_hcr_el2 & (ICH_HCR_EL2_LRENPIE | ICH_HCR_EL2_EOICOUNT_MASK)) {
233413531Sjairo.balart@metempsy.com        value |= ICH_MISR_EL2_LRENP;
233513531Sjairo.balart@metempsy.com    }
233613531Sjairo.balart@metempsy.com
233713531Sjairo.balart@metempsy.com    if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0EIE) &&
233813531Sjairo.balart@metempsy.com            (ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
233913531Sjairo.balart@metempsy.com        value |= ICH_MISR_EL2_VGRP0E;
234013760Sjairo.balart@metempsy.com    }
234113531Sjairo.balart@metempsy.com
234213531Sjairo.balart@metempsy.com    if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) &&
234313531Sjairo.balart@metempsy.com            !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
234413531Sjairo.balart@metempsy.com        value |= ICH_MISR_EL2_VGRP0D;
234513531Sjairo.balart@metempsy.com    }
234613531Sjairo.balart@metempsy.com
234713531Sjairo.balart@metempsy.com    if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) &&
234813531Sjairo.balart@metempsy.com            (ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
234913531Sjairo.balart@metempsy.com        value |= ICH_MISR_EL2_VGRP1E;
235013531Sjairo.balart@metempsy.com    }
235113531Sjairo.balart@metempsy.com
235213531Sjairo.balart@metempsy.com    if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1DIE) &&
235313531Sjairo.balart@metempsy.com            !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
235413531Sjairo.balart@metempsy.com        value |= ICH_MISR_EL2_VGRP1D;
235513531Sjairo.balart@metempsy.com    }
235613531Sjairo.balart@metempsy.com
235713531Sjairo.balart@metempsy.com    return value;
235813531Sjairo.balart@metempsy.com}
235913531Sjairo.balart@metempsy.com
236013531Sjairo.balart@metempsy.comvoid
236113531Sjairo.balart@metempsy.comGicv3CPUInterface::serialize(CheckpointOut & cp) const
236213531Sjairo.balart@metempsy.com{
236313531Sjairo.balart@metempsy.com    SERIALIZE_SCALAR(hppi.intid);
236413531Sjairo.balart@metempsy.com    SERIALIZE_SCALAR(hppi.prio);
236513760Sjairo.balart@metempsy.com    SERIALIZE_ENUM(hppi.group);
236613531Sjairo.balart@metempsy.com}
236713531Sjairo.balart@metempsy.com
236813531Sjairo.balart@metempsy.comvoid
236913531Sjairo.balart@metempsy.comGicv3CPUInterface::unserialize(CheckpointIn & cp)
237013531Sjairo.balart@metempsy.com{
237113531Sjairo.balart@metempsy.com    UNSERIALIZE_SCALAR(hppi.intid);
237213531Sjairo.balart@metempsy.com    UNSERIALIZE_SCALAR(hppi.prio);
237313531Sjairo.balart@metempsy.com    UNSERIALIZE_ENUM(hppi.group);
237413531Sjairo.balart@metempsy.com}
237513531Sjairo.balart@metempsy.com