gic_v3_cpu_interface.cc revision 14258
113531Sjairo.balart@metempsy.com/*
214227Sgiacomo.travaglini@arm.com * Copyright (c) 2019 ARM Limited
314227Sgiacomo.travaglini@arm.com * All rights reserved
414227Sgiacomo.travaglini@arm.com *
514227Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall
614227Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual
714227Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating
814227Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software
914227Sgiacomo.travaglini@arm.com * licensed hereunder.  You may use the software subject to the license
1014227Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated
1114227Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software,
1214227Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form.
1314227Sgiacomo.travaglini@arm.com *
1413531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
1513531Sjairo.balart@metempsy.com * All rights reserved.
1613531Sjairo.balart@metempsy.com *
1713531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
1813531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
1913531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
2013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
2113531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
2213531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
2313531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
2413531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
2513531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
2613531Sjairo.balart@metempsy.com * this software without specific prior written permission.
2713531Sjairo.balart@metempsy.com *
2813531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2913531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3013531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3113531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3213531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3313531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3413531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3513531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3613531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3713531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3813531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3913531Sjairo.balart@metempsy.com *
4013531Sjairo.balart@metempsy.com * Authors: Jairo Balart
4113531Sjairo.balart@metempsy.com */
4213531Sjairo.balart@metempsy.com
4313531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh"
4413531Sjairo.balart@metempsy.com
4513531Sjairo.balart@metempsy.com#include "arch/arm/isa.hh"
4613531Sjairo.balart@metempsy.com#include "debug/GIC.hh"
4713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh"
4813531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh"
4913531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_redistributor.hh"
5013531Sjairo.balart@metempsy.com
5113926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
5213926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;
5313926Sgiacomo.travaglini@arm.com
5413531Sjairo.balart@metempsy.comGicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
5513531Sjairo.balart@metempsy.com    : BaseISADevice(),
5613531Sjairo.balart@metempsy.com      gic(gic),
5713531Sjairo.balart@metempsy.com      redistributor(nullptr),
5813531Sjairo.balart@metempsy.com      distributor(nullptr),
5913531Sjairo.balart@metempsy.com      cpuId(cpu_id)
6013531Sjairo.balart@metempsy.com{
6114258Sgiacomo.travaglini@arm.com    hppi.prio = 0xff;
6214258Sgiacomo.travaglini@arm.com    hppi.intid = Gicv3::INTID_SPURIOUS;
6313531Sjairo.balart@metempsy.com}
6413531Sjairo.balart@metempsy.com
6513531Sjairo.balart@metempsy.comvoid
6613531Sjairo.balart@metempsy.comGicv3CPUInterface::init()
6713531Sjairo.balart@metempsy.com{
6813531Sjairo.balart@metempsy.com    redistributor = gic->getRedistributor(cpuId);
6913531Sjairo.balart@metempsy.com    distributor = gic->getDistributor();
7013531Sjairo.balart@metempsy.com}
7113531Sjairo.balart@metempsy.com
7213531Sjairo.balart@metempsy.comvoid
7313826Sgiacomo.travaglini@arm.comGicv3CPUInterface::setThreadContext(ThreadContext *tc)
7413826Sgiacomo.travaglini@arm.com{
7513826Sgiacomo.travaglini@arm.com    maintenanceInterrupt = gic->params()->maint_int->get(tc);
7613826Sgiacomo.travaglini@arm.com}
7713826Sgiacomo.travaglini@arm.com
7813531Sjairo.balart@metempsy.combool
7913760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2FMO() const
8013531Sjairo.balart@metempsy.com{
8113531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
8213531Sjairo.balart@metempsy.com
8313531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
8413531Sjairo.balart@metempsy.com        return false;
8513531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
8613531Sjairo.balart@metempsy.com        return true;
8713531Sjairo.balart@metempsy.com    } else {
8813531Sjairo.balart@metempsy.com        return hcr.fmo;
8913531Sjairo.balart@metempsy.com    }
9013531Sjairo.balart@metempsy.com}
9113531Sjairo.balart@metempsy.com
9213531Sjairo.balart@metempsy.combool
9313760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2IMO() const
9413531Sjairo.balart@metempsy.com{
9513531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
9613531Sjairo.balart@metempsy.com
9713531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
9813531Sjairo.balart@metempsy.com        return false;
9913531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
10013531Sjairo.balart@metempsy.com        return true;
10113531Sjairo.balart@metempsy.com    } else {
10213531Sjairo.balart@metempsy.com        return hcr.imo;
10313531Sjairo.balart@metempsy.com    }
10413531Sjairo.balart@metempsy.com}
10513531Sjairo.balart@metempsy.com
10613580Sgabeblack@google.comRegVal
10713531Sjairo.balart@metempsy.comGicv3CPUInterface::readMiscReg(int misc_reg)
10813531Sjairo.balart@metempsy.com{
10913580Sgabeblack@google.com    RegVal value = isa->readMiscRegNoEffect(misc_reg);
11013531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
11113531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
11213531Sjairo.balart@metempsy.com
11313531Sjairo.balart@metempsy.com    switch (misc_reg) {
11413760Sjairo.balart@metempsy.com      // Active Priorities Group 1 Registers
11513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
11613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1: {
11713531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
11813531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
11913531Sjairo.balart@metempsy.com          }
12013531Sjairo.balart@metempsy.com
12114246Sgiacomo.travaglini@arm.com          return readBankedMiscReg(MISCREG_ICC_AP1R0_EL1);
12213531Sjairo.balart@metempsy.com      }
12313531Sjairo.balart@metempsy.com
12413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
12513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
12613531Sjairo.balart@metempsy.com
12713531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
12813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
12913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
13013531Sjairo.balart@metempsy.com
13113531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
13213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
13313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
13413531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
13513531Sjairo.balart@metempsy.com        return 0;
13613531Sjairo.balart@metempsy.com
13713760Sjairo.balart@metempsy.com      // Active Priorities Group 0 Registers
13813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
13913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1: {
14013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
14113531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
14213531Sjairo.balart@metempsy.com          }
14313531Sjairo.balart@metempsy.com
14413531Sjairo.balart@metempsy.com          break;
14513531Sjairo.balart@metempsy.com      }
14613531Sjairo.balart@metempsy.com
14713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
14813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
14913531Sjairo.balart@metempsy.com
15013531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
15113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
15213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
15313531Sjairo.balart@metempsy.com
15413531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
15513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
15613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
15713531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
15813531Sjairo.balart@metempsy.com        return 0;
15913531Sjairo.balart@metempsy.com
16013760Sjairo.balart@metempsy.com      // Interrupt Group 0 Enable register EL1
16113531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
16213531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
16313531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
16414057Sgiacomo.travaglini@arm.com              return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
16513531Sjairo.balart@metempsy.com          }
16613531Sjairo.balart@metempsy.com
16713531Sjairo.balart@metempsy.com          break;
16813531Sjairo.balart@metempsy.com      }
16913531Sjairo.balart@metempsy.com
17014057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_IGRPEN0_EL1: {
17114057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
17214057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
17314057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VENG0;
17414057Sgiacomo.travaglini@arm.com          break;
17514057Sgiacomo.travaglini@arm.com      }
17614057Sgiacomo.travaglini@arm.com
17713760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL1
17813531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
17913531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
18013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
18114057Sgiacomo.travaglini@arm.com              return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
18213531Sjairo.balart@metempsy.com          }
18313531Sjairo.balart@metempsy.com
18414247Sgiacomo.travaglini@arm.com          value = readBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1);
18513531Sjairo.balart@metempsy.com          break;
18613531Sjairo.balart@metempsy.com      }
18713531Sjairo.balart@metempsy.com
18814057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_IGRPEN1_EL1: {
18914057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
19014057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
19114057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VENG1;
19214057Sgiacomo.travaglini@arm.com          break;
19314057Sgiacomo.travaglini@arm.com      }
19414057Sgiacomo.travaglini@arm.com
19513760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL3
19613760Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
19714254Sgiacomo.travaglini@arm.com      case MISCREG_ICC_IGRPEN1_EL3: {
19814254Sgiacomo.travaglini@arm.com          ICC_IGRPEN1_EL3 igrp_el3 = 0;
19914254Sgiacomo.travaglini@arm.com          igrp_el3.EnableGrp1S = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
20014254Sgiacomo.travaglini@arm.com              MISCREG_ICC_IGRPEN1_EL1_S)).Enable;
20114254Sgiacomo.travaglini@arm.com
20214254Sgiacomo.travaglini@arm.com          igrp_el3.EnableGrp1NS = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
20314254Sgiacomo.travaglini@arm.com              MISCREG_ICC_IGRPEN1_EL1_NS)).Enable;
20414254Sgiacomo.travaglini@arm.com
20514254Sgiacomo.travaglini@arm.com          value = igrp_el3;
20613739Sgiacomo.travaglini@arm.com          break;
20714254Sgiacomo.travaglini@arm.com      }
20813760Sjairo.balart@metempsy.com
20913760Sjairo.balart@metempsy.com      // Running Priority Register
21013531Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR:
21113531Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR_EL1: {
21213531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
21313760Sjairo.balart@metempsy.com              (hcr_imo || hcr_fmo)) {
21413531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_RPR_EL1);
21513531Sjairo.balart@metempsy.com          }
21613531Sjairo.balart@metempsy.com
21713531Sjairo.balart@metempsy.com          uint8_t rprio = highestActivePriority();
21813531Sjairo.balart@metempsy.com
21913531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() &&
22013760Sjairo.balart@metempsy.com              (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
22113760Sjairo.balart@metempsy.com              // Spec section 4.8.1
22213760Sjairo.balart@metempsy.com              // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
22313531Sjairo.balart@metempsy.com              if ((rprio & 0x80) == 0) {
22413760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
22513760Sjairo.balart@metempsy.com                  // 0x00-0x7F a read access returns the value 0x0
22613531Sjairo.balart@metempsy.com                  rprio = 0;
22713531Sjairo.balart@metempsy.com              } else if (rprio != 0xff) {
22813760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
22913760Sjairo.balart@metempsy.com                  // 0x80-0xFF a read access returns the Non-secure read of
23013760Sjairo.balart@metempsy.com                  // the current value
23113531Sjairo.balart@metempsy.com                  rprio = (rprio << 1) & 0xff;
23213531Sjairo.balart@metempsy.com              }
23313531Sjairo.balart@metempsy.com          }
23413531Sjairo.balart@metempsy.com
23513531Sjairo.balart@metempsy.com          value = rprio;
23613531Sjairo.balart@metempsy.com          break;
23713531Sjairo.balart@metempsy.com      }
23813531Sjairo.balart@metempsy.com
23913760Sjairo.balart@metempsy.com      // Virtual Running Priority Register
24013531Sjairo.balart@metempsy.com      case MISCREG_ICV_RPR_EL1: {
24113531Sjairo.balart@metempsy.com          value = virtualHighestActivePriority();
24213531Sjairo.balart@metempsy.com          break;
24313531Sjairo.balart@metempsy.com      }
24413531Sjairo.balart@metempsy.com
24513760Sjairo.balart@metempsy.com      // Highest Priority Pending Interrupt Register 0
24613531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0:
24713531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0_EL1: {
24813531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
24913531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
25013531Sjairo.balart@metempsy.com          }
25113531Sjairo.balart@metempsy.com
25213531Sjairo.balart@metempsy.com          value = getHPPIR0();
25313531Sjairo.balart@metempsy.com          break;
25413531Sjairo.balart@metempsy.com      }
25513531Sjairo.balart@metempsy.com
25613760Sjairo.balart@metempsy.com      // Virtual Highest Priority Pending Interrupt Register 0
25713531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR0_EL1: {
25813531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
25913531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
26013531Sjairo.balart@metempsy.com
26113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
26213760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
26313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
26413531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
26513760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
26613531Sjairo.balart@metempsy.com
26713531Sjairo.balart@metempsy.com              if (group == Gicv3::G0S) {
26813760Sjairo.balart@metempsy.com                  value = ich_lr_el2.vINTID;
26913531Sjairo.balart@metempsy.com              }
27013531Sjairo.balart@metempsy.com          }
27113531Sjairo.balart@metempsy.com
27213531Sjairo.balart@metempsy.com          break;
27313531Sjairo.balart@metempsy.com      }
27413531Sjairo.balart@metempsy.com
27513760Sjairo.balart@metempsy.com      // Highest Priority Pending Interrupt Register 1
27613531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1:
27713531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1_EL1: {
27813531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
27913531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
28013531Sjairo.balart@metempsy.com          }
28113531Sjairo.balart@metempsy.com
28213531Sjairo.balart@metempsy.com          value = getHPPIR1();
28313531Sjairo.balart@metempsy.com          break;
28413531Sjairo.balart@metempsy.com      }
28513531Sjairo.balart@metempsy.com
28613760Sjairo.balart@metempsy.com      // Virtual Highest Priority Pending Interrupt Register 1
28713531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR1_EL1: {
28813531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
28913531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
29013531Sjairo.balart@metempsy.com
29113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
29213760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
29313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
29413531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
29513760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
29613531Sjairo.balart@metempsy.com
29713531Sjairo.balart@metempsy.com              if (group == Gicv3::G1NS) {
29813760Sjairo.balart@metempsy.com                  value = ich_lr_el2.vINTID;
29913531Sjairo.balart@metempsy.com              }
30013531Sjairo.balart@metempsy.com          }
30113531Sjairo.balart@metempsy.com
30213531Sjairo.balart@metempsy.com          break;
30313531Sjairo.balart@metempsy.com      }
30413531Sjairo.balart@metempsy.com
30513760Sjairo.balart@metempsy.com      // Binary Point Register 0
30613531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
30714237Sgiacomo.travaglini@arm.com      case MISCREG_ICC_BPR0_EL1: {
30813531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
30913531Sjairo.balart@metempsy.com            return readMiscReg(MISCREG_ICV_BPR0_EL1);
31013531Sjairo.balart@metempsy.com        }
31113531Sjairo.balart@metempsy.com
31214237Sgiacomo.travaglini@arm.com        value = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
31314237Sgiacomo.travaglini@arm.com        break;
31414237Sgiacomo.travaglini@arm.com      }
31513531Sjairo.balart@metempsy.com
31613760Sjairo.balart@metempsy.com      // Binary Point Register 1
31713531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
31813760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: {
31914237Sgiacomo.travaglini@arm.com        value = bpr1(isSecureBelowEL3() ? Gicv3::G1S : Gicv3::G1NS);
32014237Sgiacomo.travaglini@arm.com        break;
32113760Sjairo.balart@metempsy.com      }
32213760Sjairo.balart@metempsy.com
32314237Sgiacomo.travaglini@arm.com      // Virtual Binary Point Register 0
32414237Sgiacomo.travaglini@arm.com      case MISCREG_ICV_BPR0_EL1: {
32514237Sgiacomo.travaglini@arm.com        ICH_VMCR_EL2 ich_vmcr_el2 =
32614237Sgiacomo.travaglini@arm.com            isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
32714237Sgiacomo.travaglini@arm.com
32814237Sgiacomo.travaglini@arm.com        value = ich_vmcr_el2.VBPR0;
32914237Sgiacomo.travaglini@arm.com        break;
33014237Sgiacomo.travaglini@arm.com      }
33114237Sgiacomo.travaglini@arm.com
33213760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 1
33313531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
33414237Sgiacomo.travaglini@arm.com        ICH_VMCR_EL2 ich_vmcr_el2 =
33514237Sgiacomo.travaglini@arm.com            isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
33614237Sgiacomo.travaglini@arm.com
33714237Sgiacomo.travaglini@arm.com        if (ich_vmcr_el2.VCBPR) {
33814237Sgiacomo.travaglini@arm.com            // bpr0 + 1 saturated to 7, WI
33914237Sgiacomo.travaglini@arm.com            value = ich_vmcr_el2.VBPR0 + 1;
34014237Sgiacomo.travaglini@arm.com            value = value < 7 ? value : 7;
34114237Sgiacomo.travaglini@arm.com        } else {
34214237Sgiacomo.travaglini@arm.com            value = ich_vmcr_el2.VBPR1;
34314237Sgiacomo.travaglini@arm.com        }
34414237Sgiacomo.travaglini@arm.com
34514237Sgiacomo.travaglini@arm.com        break;
34613531Sjairo.balart@metempsy.com      }
34713531Sjairo.balart@metempsy.com
34813760Sjairo.balart@metempsy.com      // Interrupt Priority Mask Register
34913531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
35013760Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1:
35113760Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
35214057Sgiacomo.travaglini@arm.com            return readMiscReg(MISCREG_ICV_PMR_EL1);
35313531Sjairo.balart@metempsy.com        }
35413531Sjairo.balart@metempsy.com
35513531Sjairo.balart@metempsy.com        if (haveEL(EL3) && !inSecureState() &&
35613760Sjairo.balart@metempsy.com            (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
35713760Sjairo.balart@metempsy.com            // Spec section 4.8.1
35813760Sjairo.balart@metempsy.com            // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
35913531Sjairo.balart@metempsy.com            if ((value & 0x80) == 0) {
36013760Sjairo.balart@metempsy.com                // If the current priority mask value is in the range of
36113760Sjairo.balart@metempsy.com                // 0x00-0x7F a read access returns the value 0x00.
36213531Sjairo.balart@metempsy.com                value = 0;
36313531Sjairo.balart@metempsy.com            } else if (value != 0xff) {
36413760Sjairo.balart@metempsy.com                // If the current priority mask value is in the range of
36513760Sjairo.balart@metempsy.com                // 0x80-0xFF a read access returns the Non-secure read of the
36613760Sjairo.balart@metempsy.com                // current value.
36713531Sjairo.balart@metempsy.com                value = (value << 1) & 0xff;
36813531Sjairo.balart@metempsy.com            }
36913531Sjairo.balart@metempsy.com        }
37013531Sjairo.balart@metempsy.com
37113531Sjairo.balart@metempsy.com        break;
37213531Sjairo.balart@metempsy.com
37314057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
37414057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
37514057Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
37614057Sgiacomo.travaglini@arm.com
37714057Sgiacomo.travaglini@arm.com          value = ich_vmcr_el2.VPMR;
37814057Sgiacomo.travaglini@arm.com          break;
37914057Sgiacomo.travaglini@arm.com      }
38014057Sgiacomo.travaglini@arm.com
38113760Sjairo.balart@metempsy.com      // Interrupt Acknowledge Register 0
38213531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0:
38313760Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0_EL1: {
38413531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
38513531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR0_EL1);
38613531Sjairo.balart@metempsy.com          }
38713531Sjairo.balart@metempsy.com
38813531Sjairo.balart@metempsy.com          uint32_t int_id;
38913531Sjairo.balart@metempsy.com
39013531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
39113531Sjairo.balart@metempsy.com              int_id = getHPPIR0();
39213531Sjairo.balart@metempsy.com
39313531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
39413923Sgiacomo.travaglini@arm.com              if (int_id < Gicv3::INTID_SECURE ||
39513923Sgiacomo.travaglini@arm.com                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
39613531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
39713531Sjairo.balart@metempsy.com              }
39813531Sjairo.balart@metempsy.com          } else {
39913531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
40013531Sjairo.balart@metempsy.com          }
40113531Sjairo.balart@metempsy.com
40213531Sjairo.balart@metempsy.com          value = int_id;
40313531Sjairo.balart@metempsy.com          break;
40413531Sjairo.balart@metempsy.com      }
40513531Sjairo.balart@metempsy.com
40613760Sjairo.balart@metempsy.com      // Virtual Interrupt Acknowledge Register 0
40713531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR0_EL1: {
40813531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
40913531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
41013531Sjairo.balart@metempsy.com
41113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
41213760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
41313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
41413531Sjairo.balart@metempsy.com
41513760Sjairo.balart@metempsy.com              if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
41613760Sjairo.balart@metempsy.com                  int_id = ich_lr_el2.vINTID;
41713531Sjairo.balart@metempsy.com
41813531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
41913760Sjairo.balart@metempsy.com                      int_id > Gicv3::INTID_SPURIOUS) {
42013531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
42113531Sjairo.balart@metempsy.com                  } else {
42213531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
42313531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
42413531Sjairo.balart@metempsy.com                      // - Return de bogus id...
42513760Sjairo.balart@metempsy.com                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
42613531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
42713760Sjairo.balart@metempsy.com                                              ich_lr_el2);
42813531Sjairo.balart@metempsy.com                  }
42913531Sjairo.balart@metempsy.com              }
43013531Sjairo.balart@metempsy.com          }
43113531Sjairo.balart@metempsy.com
43213531Sjairo.balart@metempsy.com          value = int_id;
43313531Sjairo.balart@metempsy.com          virtualUpdate();
43413531Sjairo.balart@metempsy.com          break;
43513531Sjairo.balart@metempsy.com      }
43613531Sjairo.balart@metempsy.com
43713760Sjairo.balart@metempsy.com      // Interrupt Acknowledge Register 1
43813531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1:
43913760Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1_EL1: {
44013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
44113531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR1_EL1);
44213531Sjairo.balart@metempsy.com          }
44313531Sjairo.balart@metempsy.com
44413531Sjairo.balart@metempsy.com          uint32_t int_id;
44513531Sjairo.balart@metempsy.com
44613531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
44713531Sjairo.balart@metempsy.com              int_id = getHPPIR1();
44813531Sjairo.balart@metempsy.com
44913531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
45013923Sgiacomo.travaglini@arm.com              if (int_id < Gicv3::INTID_SECURE ||
45113923Sgiacomo.travaglini@arm.com                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
45213531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
45313531Sjairo.balart@metempsy.com              }
45413531Sjairo.balart@metempsy.com          } else {
45513531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
45613531Sjairo.balart@metempsy.com          }
45713531Sjairo.balart@metempsy.com
45813531Sjairo.balart@metempsy.com          value = int_id;
45913531Sjairo.balart@metempsy.com          break;
46013531Sjairo.balart@metempsy.com      }
46113531Sjairo.balart@metempsy.com
46213760Sjairo.balart@metempsy.com      // Virtual Interrupt Acknowledge Register 1
46313531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR1_EL1: {
46413531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
46513531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
46613531Sjairo.balart@metempsy.com
46713531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
46813760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
46913531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
47013531Sjairo.balart@metempsy.com
47113760Sjairo.balart@metempsy.com              if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
47213760Sjairo.balart@metempsy.com                  int_id = ich_lr_el2.vINTID;
47313531Sjairo.balart@metempsy.com
47413531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
47513760Sjairo.balart@metempsy.com                      int_id > Gicv3::INTID_SPURIOUS) {
47613531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
47713531Sjairo.balart@metempsy.com                  } else {
47813531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
47913531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
48013531Sjairo.balart@metempsy.com                      // - Return de bogus id...
48113760Sjairo.balart@metempsy.com                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
48213531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
48313760Sjairo.balart@metempsy.com                                              ich_lr_el2);
48413531Sjairo.balart@metempsy.com                  }
48513531Sjairo.balart@metempsy.com              }
48613531Sjairo.balart@metempsy.com          }
48713531Sjairo.balart@metempsy.com
48813531Sjairo.balart@metempsy.com          value = int_id;
48913531Sjairo.balart@metempsy.com          virtualUpdate();
49013531Sjairo.balart@metempsy.com          break;
49113531Sjairo.balart@metempsy.com      }
49213531Sjairo.balart@metempsy.com
49313760Sjairo.balart@metempsy.com      // System Register Enable Register EL1
49413531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
49513760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1: {
49613531Sjairo.balart@metempsy.com        /*
49713531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
49813531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
49913531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
50013531Sjairo.balart@metempsy.com         */
50113760Sjairo.balart@metempsy.com          ICC_SRE_EL1 icc_sre_el1 = 0;
50213760Sjairo.balart@metempsy.com          icc_sre_el1.SRE = 1;
50313760Sjairo.balart@metempsy.com          icc_sre_el1.DIB = 1;
50413760Sjairo.balart@metempsy.com          icc_sre_el1.DFB = 1;
50513760Sjairo.balart@metempsy.com          value = icc_sre_el1;
50613760Sjairo.balart@metempsy.com          break;
50713760Sjairo.balart@metempsy.com      }
50813760Sjairo.balart@metempsy.com
50913760Sjairo.balart@metempsy.com      // System Register Enable Register EL2
51013760Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
51113760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2: {
51213531Sjairo.balart@metempsy.com        /*
51313531Sjairo.balart@metempsy.com         * Enable [3] == 1
51413760Sjairo.balart@metempsy.com         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
51513531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
51613531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
51713531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
51813531Sjairo.balart@metempsy.com         */
51913760Sjairo.balart@metempsy.com        ICC_SRE_EL2 icc_sre_el2 = 0;
52013760Sjairo.balart@metempsy.com        icc_sre_el2.SRE = 1;
52113760Sjairo.balart@metempsy.com        icc_sre_el2.DIB = 1;
52213760Sjairo.balart@metempsy.com        icc_sre_el2.DFB = 1;
52313760Sjairo.balart@metempsy.com        icc_sre_el2.Enable = 1;
52413760Sjairo.balart@metempsy.com        value = icc_sre_el2;
52513531Sjairo.balart@metempsy.com        break;
52613760Sjairo.balart@metempsy.com      }
52713760Sjairo.balart@metempsy.com
52813760Sjairo.balart@metempsy.com      // System Register Enable Register EL3
52913760Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
53013760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3: {
53113760Sjairo.balart@metempsy.com        /*
53213760Sjairo.balart@metempsy.com         * Enable [3] == 1
53313760Sjairo.balart@metempsy.com         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
53413760Sjairo.balart@metempsy.com         *  EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
53513760Sjairo.balart@metempsy.com         *  RAO/WI)
53613760Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
53713760Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
53813760Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
53913760Sjairo.balart@metempsy.com         */
54013760Sjairo.balart@metempsy.com        ICC_SRE_EL3 icc_sre_el3 = 0;
54113760Sjairo.balart@metempsy.com        icc_sre_el3.SRE = 1;
54213760Sjairo.balart@metempsy.com        icc_sre_el3.DIB = 1;
54313760Sjairo.balart@metempsy.com        icc_sre_el3.DFB = 1;
54413760Sjairo.balart@metempsy.com        icc_sre_el3.Enable = 1;
54513760Sjairo.balart@metempsy.com        value = icc_sre_el3;
54613760Sjairo.balart@metempsy.com        break;
54713760Sjairo.balart@metempsy.com      }
54813760Sjairo.balart@metempsy.com
54913760Sjairo.balart@metempsy.com      // Control Register
55013531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
55113760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: {
55213760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
55313531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_CTLR_EL1);
55413531Sjairo.balart@metempsy.com          }
55513531Sjairo.balart@metempsy.com
55614245Sgiacomo.travaglini@arm.com          value = readBankedMiscReg(MISCREG_ICC_CTLR_EL1);
55713760Sjairo.balart@metempsy.com          // Enforce value for RO bits
55813760Sjairo.balart@metempsy.com          // ExtRange [19], INTIDs in the range 1024..8191 not supported
55913760Sjairo.balart@metempsy.com          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
56013760Sjairo.balart@metempsy.com          // A3V [15], supports non-zero values of the Aff3 field in SGI
56113760Sjairo.balart@metempsy.com          //           generation System registers
56213760Sjairo.balart@metempsy.com          // SEIS [14], does not support generation of SEIs (deprecated)
56313531Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
56413531Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
56513760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1 = value;
56613760Sjairo.balart@metempsy.com          icc_ctlr_el1.ExtRange = 0;
56713760Sjairo.balart@metempsy.com          icc_ctlr_el1.RSS = 1;
56813760Sjairo.balart@metempsy.com          icc_ctlr_el1.A3V = 1;
56913760Sjairo.balart@metempsy.com          icc_ctlr_el1.SEIS = 0;
57013760Sjairo.balart@metempsy.com          icc_ctlr_el1.IDbits = 1;
57113760Sjairo.balart@metempsy.com          icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
57213760Sjairo.balart@metempsy.com          value = icc_ctlr_el1;
57313531Sjairo.balart@metempsy.com          break;
57413531Sjairo.balart@metempsy.com      }
57513531Sjairo.balart@metempsy.com
57613760Sjairo.balart@metempsy.com      // Virtual Control Register
57713531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
57813760Sjairo.balart@metempsy.com          ICV_CTLR_EL1 icv_ctlr_el1 = value;
57913760Sjairo.balart@metempsy.com          icv_ctlr_el1.RSS = 0;
58013760Sjairo.balart@metempsy.com          icv_ctlr_el1.A3V = 1;
58113760Sjairo.balart@metempsy.com          icv_ctlr_el1.SEIS = 0;
58213760Sjairo.balart@metempsy.com          icv_ctlr_el1.IDbits = 1;
58313760Sjairo.balart@metempsy.com          icv_ctlr_el1.PRIbits = 7;
58413760Sjairo.balart@metempsy.com          value = icv_ctlr_el1;
58513531Sjairo.balart@metempsy.com          break;
58613531Sjairo.balart@metempsy.com      }
58713531Sjairo.balart@metempsy.com
58813760Sjairo.balart@metempsy.com      // Control Register
58913531Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
59013531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
59113760Sjairo.balart@metempsy.com          // Enforce value for RO bits
59213760Sjairo.balart@metempsy.com          // ExtRange [19], INTIDs in the range 1024..8191 not supported
59313760Sjairo.balart@metempsy.com          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
59413760Sjairo.balart@metempsy.com          // nDS [17], supports disabling of security
59513760Sjairo.balart@metempsy.com          // A3V [15], supports non-zero values of the Aff3 field in SGI
59613760Sjairo.balart@metempsy.com          //           generation System registers
59713760Sjairo.balart@metempsy.com          // SEIS [14], does not support generation of SEIs (deprecated)
59813531Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
59913531Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
60013760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 = value;
60113760Sjairo.balart@metempsy.com          icc_ctlr_el3.ExtRange = 0;
60213760Sjairo.balart@metempsy.com          icc_ctlr_el3.RSS = 1;
60313760Sjairo.balart@metempsy.com          icc_ctlr_el3.nDS = 0;
60413760Sjairo.balart@metempsy.com          icc_ctlr_el3.A3V = 1;
60513760Sjairo.balart@metempsy.com          icc_ctlr_el3.SEIS = 0;
60613760Sjairo.balart@metempsy.com          icc_ctlr_el3.IDbits = 0;
60713760Sjairo.balart@metempsy.com          icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
60813760Sjairo.balart@metempsy.com          value = icc_ctlr_el3;
60913531Sjairo.balart@metempsy.com          break;
61013531Sjairo.balart@metempsy.com      }
61113531Sjairo.balart@metempsy.com
61213760Sjairo.balart@metempsy.com      // Hyp Control Register
61313531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
61413531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2:
61513531Sjairo.balart@metempsy.com        break;
61613531Sjairo.balart@metempsy.com
61713760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 0 Registers
61813531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0:
61913531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0_EL2:
62013531Sjairo.balart@metempsy.com        break;
62113531Sjairo.balart@metempsy.com
62214236Sgiacomo.travaglini@arm.com      // only implemented if supporting 6 or more bits of priority
62314236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R1:
62414236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R1_EL2:
62514236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
62614236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R2:
62714236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R2_EL2:
62814236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
62914236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R3:
63014236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R3_EL2:
63114236Sgiacomo.travaglini@arm.com        // Unimplemented registers are RAZ/WI
63214236Sgiacomo.travaglini@arm.com        return 0;
63314236Sgiacomo.travaglini@arm.com
63413760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 1 Registers
63513531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0:
63613531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0_EL2:
63713531Sjairo.balart@metempsy.com        break;
63813531Sjairo.balart@metempsy.com
63914236Sgiacomo.travaglini@arm.com      // only implemented if supporting 6 or more bits of priority
64014236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R1:
64114236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R1_EL2:
64214236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
64314236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R2:
64414236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R2_EL2:
64514236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
64614236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R3:
64714236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R3_EL2:
64814236Sgiacomo.travaglini@arm.com        // Unimplemented registers are RAZ/WI
64914236Sgiacomo.travaglini@arm.com        return 0;
65014236Sgiacomo.travaglini@arm.com
65113760Sjairo.balart@metempsy.com      // Maintenance Interrupt State Register
65213531Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR:
65313760Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR_EL2:
65413760Sjairo.balart@metempsy.com        value = maintenanceInterruptStatus();
65513760Sjairo.balart@metempsy.com        break;
65613760Sjairo.balart@metempsy.com
65713760Sjairo.balart@metempsy.com      // VGIC Type Register
65813760Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR:
65913760Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR_EL2: {
66013760Sjairo.balart@metempsy.com        ICH_VTR_EL2 ich_vtr_el2 = value;
66113760Sjairo.balart@metempsy.com
66213760Sjairo.balart@metempsy.com        ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
66313760Sjairo.balart@metempsy.com        ich_vtr_el2.A3V = 1;
66413760Sjairo.balart@metempsy.com        ich_vtr_el2.IDbits = 1;
66513760Sjairo.balart@metempsy.com        ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
66613760Sjairo.balart@metempsy.com        ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
66713760Sjairo.balart@metempsy.com
66813760Sjairo.balart@metempsy.com        value = ich_vtr_el2;
66913760Sjairo.balart@metempsy.com        break;
67013531Sjairo.balart@metempsy.com      }
67113531Sjairo.balart@metempsy.com
67213760Sjairo.balart@metempsy.com      // End of Interrupt Status Register
67313531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR:
67413531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR_EL2:
67513760Sjairo.balart@metempsy.com        value = eoiMaintenanceInterruptStatus();
67613531Sjairo.balart@metempsy.com        break;
67713531Sjairo.balart@metempsy.com
67813760Sjairo.balart@metempsy.com      // Empty List Register Status Register
67913531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR:
68013531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR_EL2:
68113531Sjairo.balart@metempsy.com        value = 0;
68213531Sjairo.balart@metempsy.com
68313531Sjairo.balart@metempsy.com        for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
68413760Sjairo.balart@metempsy.com            ICH_LR_EL2 ich_lr_el2 =
68513531Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
68613531Sjairo.balart@metempsy.com
68713760Sjairo.balart@metempsy.com            if ((ich_lr_el2.State  == ICH_LR_EL2_STATE_INVALID) &&
68813760Sjairo.balart@metempsy.com                (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
68913531Sjairo.balart@metempsy.com                value |= (1 << lr_idx);
69013531Sjairo.balart@metempsy.com            }
69113531Sjairo.balart@metempsy.com        }
69213531Sjairo.balart@metempsy.com
69313531Sjairo.balart@metempsy.com        break;
69413531Sjairo.balart@metempsy.com
69513760Sjairo.balart@metempsy.com      // List Registers
69613531Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
69713531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
69813531Sjairo.balart@metempsy.com        value = value >> 32;
69913531Sjairo.balart@metempsy.com        break;
70013531Sjairo.balart@metempsy.com
70113760Sjairo.balart@metempsy.com      // List Registers
70213531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
70313531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
70413531Sjairo.balart@metempsy.com        value = value & 0xffffffff;
70513531Sjairo.balart@metempsy.com        break;
70613531Sjairo.balart@metempsy.com
70713760Sjairo.balart@metempsy.com      // List Registers
70813531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
70913531Sjairo.balart@metempsy.com        break;
71013531Sjairo.balart@metempsy.com
71113760Sjairo.balart@metempsy.com      // Virtual Machine Control Register
71213531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
71313531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2:
71413531Sjairo.balart@metempsy.com        break;
71513531Sjairo.balart@metempsy.com
71613531Sjairo.balart@metempsy.com      default:
71713760Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
71813760Sjairo.balart@metempsy.com              misc_reg, miscRegName[misc_reg]);
71913531Sjairo.balart@metempsy.com    }
72013531Sjairo.balart@metempsy.com
72113760Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
72213760Sjairo.balart@metempsy.com            miscRegName[misc_reg], value);
72313531Sjairo.balart@metempsy.com    return value;
72413531Sjairo.balart@metempsy.com}
72513531Sjairo.balart@metempsy.com
72613531Sjairo.balart@metempsy.comvoid
72713580Sgabeblack@google.comGicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
72813531Sjairo.balart@metempsy.com{
72913531Sjairo.balart@metempsy.com    bool do_virtual_update = false;
73013760Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
73113760Sjairo.balart@metempsy.com            miscRegName[misc_reg], val);
73213531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
73313531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
73413531Sjairo.balart@metempsy.com
73513531Sjairo.balart@metempsy.com    switch (misc_reg) {
73613760Sjairo.balart@metempsy.com      // Active Priorities Group 1 Registers
73713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
73813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1:
73913531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
74013531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
74113531Sjairo.balart@metempsy.com        }
74213531Sjairo.balart@metempsy.com
74314246Sgiacomo.travaglini@arm.com        setBankedMiscReg(MISCREG_ICC_AP1R0_EL1, val);
74414246Sgiacomo.travaglini@arm.com        return;
74513531Sjairo.balart@metempsy.com
74613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
74713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
74813531Sjairo.balart@metempsy.com
74913531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
75013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
75113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
75213531Sjairo.balart@metempsy.com
75313531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
75413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
75513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
75613531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
75713531Sjairo.balart@metempsy.com        break;
75813531Sjairo.balart@metempsy.com
75913760Sjairo.balart@metempsy.com      // Active Priorities Group 0 Registers
76013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
76113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1:
76213531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
76313531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
76413531Sjairo.balart@metempsy.com        }
76513531Sjairo.balart@metempsy.com
76613531Sjairo.balart@metempsy.com        break;
76713531Sjairo.balart@metempsy.com
76813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
76913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
77013531Sjairo.balart@metempsy.com
77113531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
77213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
77313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
77413531Sjairo.balart@metempsy.com
77513531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
77613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
77713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
77813531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
77913531Sjairo.balart@metempsy.com        break;
78013531Sjairo.balart@metempsy.com
78113760Sjairo.balart@metempsy.com      // End Of Interrupt Register 0
78213531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0:
78313531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
78413531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
78513531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
78613531Sjairo.balart@metempsy.com          }
78713531Sjairo.balart@metempsy.com
78813531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
78913531Sjairo.balart@metempsy.com
79013531Sjairo.balart@metempsy.com          // avoid activation for special interrupts
79113923Sgiacomo.travaglini@arm.com          if (int_id >= Gicv3::INTID_SECURE &&
79213923Sgiacomo.travaglini@arm.com              int_id <= Gicv3::INTID_SPURIOUS) {
79313531Sjairo.balart@metempsy.com              return;
79413531Sjairo.balart@metempsy.com          }
79513531Sjairo.balart@metempsy.com
79613531Sjairo.balart@metempsy.com          Gicv3::GroupId group = Gicv3::G0S;
79713531Sjairo.balart@metempsy.com
79813531Sjairo.balart@metempsy.com          if (highestActiveGroup() != group) {
79913531Sjairo.balart@metempsy.com              return;
80013531Sjairo.balart@metempsy.com          }
80113531Sjairo.balart@metempsy.com
80213531Sjairo.balart@metempsy.com          dropPriority(group);
80313531Sjairo.balart@metempsy.com
80413531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
80513531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
80613531Sjairo.balart@metempsy.com          }
80713531Sjairo.balart@metempsy.com
80813531Sjairo.balart@metempsy.com          break;
80913531Sjairo.balart@metempsy.com      }
81013531Sjairo.balart@metempsy.com
81113760Sjairo.balart@metempsy.com      // Virtual End Of Interrupt Register 0
81213531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR0_EL1: {
81313531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
81413531Sjairo.balart@metempsy.com
81513531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
81613531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
81713531Sjairo.balart@metempsy.com                  int_id <= Gicv3::INTID_SPURIOUS) {
81813531Sjairo.balart@metempsy.com              return;
81913531Sjairo.balart@metempsy.com          }
82013531Sjairo.balart@metempsy.com
82113531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
82213531Sjairo.balart@metempsy.com
82313531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
82413531Sjairo.balart@metempsy.com              return;
82513531Sjairo.balart@metempsy.com          }
82613531Sjairo.balart@metempsy.com
82713531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
82813531Sjairo.balart@metempsy.com
82913531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
83013531Sjairo.balart@metempsy.com              // No LR found matching
83113531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
83213531Sjairo.balart@metempsy.com          } else {
83313760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
83413531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
83513531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
83613760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
83713760Sjairo.balart@metempsy.com              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
83813531Sjairo.balart@metempsy.com
83913531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
84013760Sjairo.balart@metempsy.com                  //if (!virtualIsEOISplitMode())
84113531Sjairo.balart@metempsy.com                  {
84213531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
84313531Sjairo.balart@metempsy.com                  }
84413531Sjairo.balart@metempsy.com              }
84513531Sjairo.balart@metempsy.com          }
84613531Sjairo.balart@metempsy.com
84713531Sjairo.balart@metempsy.com          virtualUpdate();
84813531Sjairo.balart@metempsy.com          break;
84913531Sjairo.balart@metempsy.com      }
85013531Sjairo.balart@metempsy.com
85113760Sjairo.balart@metempsy.com      // End Of Interrupt Register 1
85213531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1:
85313760Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1_EL1: {
85413531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
85513531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR1_EL1, val);
85613531Sjairo.balart@metempsy.com          }
85713531Sjairo.balart@metempsy.com
85813531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
85913531Sjairo.balart@metempsy.com
86013531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
86113923Sgiacomo.travaglini@arm.com          if (int_id >= Gicv3::INTID_SECURE &&
86213923Sgiacomo.travaglini@arm.com              int_id <= Gicv3::INTID_SPURIOUS) {
86313531Sjairo.balart@metempsy.com              return;
86413531Sjairo.balart@metempsy.com          }
86513531Sjairo.balart@metempsy.com
86613760Sjairo.balart@metempsy.com          Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
86713531Sjairo.balart@metempsy.com
86813531Sjairo.balart@metempsy.com          if (highestActiveGroup() == Gicv3::G0S) {
86913531Sjairo.balart@metempsy.com              return;
87013531Sjairo.balart@metempsy.com          }
87113531Sjairo.balart@metempsy.com
87213531Sjairo.balart@metempsy.com          if (distributor->DS == 0) {
87313531Sjairo.balart@metempsy.com              if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) {
87413531Sjairo.balart@metempsy.com                  return;
87513531Sjairo.balart@metempsy.com              } else if (highestActiveGroup() == Gicv3::G1NS &&
87613760Sjairo.balart@metempsy.com                         !(!inSecureState() or (currEL() == EL3))) {
87713531Sjairo.balart@metempsy.com                  return;
87813531Sjairo.balart@metempsy.com              }
87913531Sjairo.balart@metempsy.com          }
88013531Sjairo.balart@metempsy.com
88113531Sjairo.balart@metempsy.com          dropPriority(group);
88213531Sjairo.balart@metempsy.com
88313531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
88413531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
88513531Sjairo.balart@metempsy.com          }
88613531Sjairo.balart@metempsy.com
88713531Sjairo.balart@metempsy.com          break;
88813531Sjairo.balart@metempsy.com      }
88913531Sjairo.balart@metempsy.com
89013760Sjairo.balart@metempsy.com      // Virtual End Of Interrupt Register 1
89113531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR1_EL1: {
89213531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
89313531Sjairo.balart@metempsy.com
89413531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
89513531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
89613760Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
89713531Sjairo.balart@metempsy.com              return;
89813531Sjairo.balart@metempsy.com          }
89913531Sjairo.balart@metempsy.com
90013531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
90113531Sjairo.balart@metempsy.com
90213531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
90313531Sjairo.balart@metempsy.com              return;
90413531Sjairo.balart@metempsy.com          }
90513531Sjairo.balart@metempsy.com
90613531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
90713531Sjairo.balart@metempsy.com
90813531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
90913760Sjairo.balart@metempsy.com              // No matching LR found
91013531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
91113531Sjairo.balart@metempsy.com          } else {
91213760Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
91313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
91413531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
91513760Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
91613760Sjairo.balart@metempsy.com              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
91713531Sjairo.balart@metempsy.com
91813531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
91913531Sjairo.balart@metempsy.com                  if (!virtualIsEOISplitMode()) {
92013531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
92113531Sjairo.balart@metempsy.com                  }
92213531Sjairo.balart@metempsy.com              }
92313531Sjairo.balart@metempsy.com          }
92413531Sjairo.balart@metempsy.com
92513531Sjairo.balart@metempsy.com          virtualUpdate();
92613531Sjairo.balart@metempsy.com          break;
92713531Sjairo.balart@metempsy.com      }
92813531Sjairo.balart@metempsy.com
92913760Sjairo.balart@metempsy.com      // Deactivate Interrupt Register
93013531Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR:
93113760Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR_EL1: {
93213531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
93313760Sjairo.balart@metempsy.com              (hcr_imo || hcr_fmo)) {
93413531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_DIR_EL1, val);
93513531Sjairo.balart@metempsy.com          }
93613531Sjairo.balart@metempsy.com
93713531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
93813531Sjairo.balart@metempsy.com
93913760Sjairo.balart@metempsy.com          // The following checks are as per spec pseudocode
94013760Sjairo.balart@metempsy.com          // aarch64/support/ICC_DIR_EL1
94113760Sjairo.balart@metempsy.com
94213760Sjairo.balart@metempsy.com          // Check for spurious ID
94313531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE) {
94413531Sjairo.balart@metempsy.com              return;
94513531Sjairo.balart@metempsy.com          }
94613531Sjairo.balart@metempsy.com
94713760Sjairo.balart@metempsy.com          // EOI mode is not set, so don't deactivate
94813531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
94913531Sjairo.balart@metempsy.com              return;
95013531Sjairo.balart@metempsy.com          }
95113531Sjairo.balart@metempsy.com
95213531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
95313531Sjairo.balart@metempsy.com              int_id >= 32 ? distributor->getIntGroup(int_id) :
95413531Sjairo.balart@metempsy.com              redistributor->getIntGroup(int_id);
95513531Sjairo.balart@metempsy.com          bool irq_is_grp0 = group == Gicv3::G0S;
95613531Sjairo.balart@metempsy.com          bool single_sec_state = distributor->DS;
95713531Sjairo.balart@metempsy.com          bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
95813531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
95913531Sjairo.balart@metempsy.com          bool route_fiq_to_el3 = scr_el3.fiq;
96013531Sjairo.balart@metempsy.com          bool route_irq_to_el3 = scr_el3.irq;
96113531Sjairo.balart@metempsy.com          bool route_fiq_to_el2 = hcr_fmo;
96213531Sjairo.balart@metempsy.com          bool route_irq_to_el2 = hcr_imo;
96313531Sjairo.balart@metempsy.com
96413531Sjairo.balart@metempsy.com          switch (currEL()) {
96513531Sjairo.balart@metempsy.com            case EL3:
96613531Sjairo.balart@metempsy.com              break;
96713531Sjairo.balart@metempsy.com
96813531Sjairo.balart@metempsy.com            case EL2:
96913531Sjairo.balart@metempsy.com              if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
97013531Sjairo.balart@metempsy.com                  break;
97113531Sjairo.balart@metempsy.com              }
97213531Sjairo.balart@metempsy.com
97313531Sjairo.balart@metempsy.com              if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
97413531Sjairo.balart@metempsy.com                  break;
97513531Sjairo.balart@metempsy.com              }
97613531Sjairo.balart@metempsy.com
97713531Sjairo.balart@metempsy.com              return;
97813531Sjairo.balart@metempsy.com
97913531Sjairo.balart@metempsy.com            case EL1:
98013531Sjairo.balart@metempsy.com              if (!isSecureBelowEL3()) {
98113531Sjairo.balart@metempsy.com                  if (single_sec_state && irq_is_grp0 &&
98213760Sjairo.balart@metempsy.com                      !route_fiq_to_el3 && !route_fiq_to_el2) {
98313531Sjairo.balart@metempsy.com                      break;
98413531Sjairo.balart@metempsy.com                  }
98513531Sjairo.balart@metempsy.com
98613531Sjairo.balart@metempsy.com                  if (!irq_is_secure && !irq_is_grp0 &&
98713760Sjairo.balart@metempsy.com                      !route_irq_to_el3 && !route_irq_to_el2) {
98813531Sjairo.balart@metempsy.com                      break;
98913531Sjairo.balart@metempsy.com                  }
99013531Sjairo.balart@metempsy.com              } else {
99113531Sjairo.balart@metempsy.com                  if (irq_is_grp0 && !route_fiq_to_el3) {
99213531Sjairo.balart@metempsy.com                      break;
99313531Sjairo.balart@metempsy.com                  }
99413531Sjairo.balart@metempsy.com
99513531Sjairo.balart@metempsy.com                  if (!irq_is_grp0 &&
99613760Sjairo.balart@metempsy.com                      (!irq_is_secure || !single_sec_state) &&
99713760Sjairo.balart@metempsy.com                      !route_irq_to_el3) {
99813531Sjairo.balart@metempsy.com                      break;
99913531Sjairo.balart@metempsy.com                  }
100013531Sjairo.balart@metempsy.com              }
100113531Sjairo.balart@metempsy.com
100213531Sjairo.balart@metempsy.com              return;
100313531Sjairo.balart@metempsy.com
100413531Sjairo.balart@metempsy.com            default:
100513531Sjairo.balart@metempsy.com              break;
100613531Sjairo.balart@metempsy.com          }
100713531Sjairo.balart@metempsy.com
100813531Sjairo.balart@metempsy.com          deactivateIRQ(int_id, group);
100913531Sjairo.balart@metempsy.com          break;
101013531Sjairo.balart@metempsy.com      }
101113531Sjairo.balart@metempsy.com
101213760Sjairo.balart@metempsy.com      // Deactivate Virtual Interrupt Register
101313531Sjairo.balart@metempsy.com      case MISCREG_ICV_DIR_EL1: {
101413531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
101513531Sjairo.balart@metempsy.com
101613531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
101713531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
101813760Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
101913531Sjairo.balart@metempsy.com              return;
102013531Sjairo.balart@metempsy.com          }
102113531Sjairo.balart@metempsy.com
102213531Sjairo.balart@metempsy.com          if (!virtualIsEOISplitMode()) {
102313531Sjairo.balart@metempsy.com              return;
102413531Sjairo.balart@metempsy.com          }
102513531Sjairo.balart@metempsy.com
102613531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
102713531Sjairo.balart@metempsy.com
102813531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
102913760Sjairo.balart@metempsy.com              // No matching LR found
103013531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
103113531Sjairo.balart@metempsy.com          } else {
103213531Sjairo.balart@metempsy.com              virtualDeactivateIRQ(lr_idx);
103313531Sjairo.balart@metempsy.com          }
103413531Sjairo.balart@metempsy.com
103513531Sjairo.balart@metempsy.com          virtualUpdate();
103613531Sjairo.balart@metempsy.com          break;
103713531Sjairo.balart@metempsy.com      }
103813531Sjairo.balart@metempsy.com
103913760Sjairo.balart@metempsy.com      // Binary Point Register 0
104013531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
104114237Sgiacomo.travaglini@arm.com      case MISCREG_ICC_BPR0_EL1: {
104214237Sgiacomo.travaglini@arm.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
104314237Sgiacomo.travaglini@arm.com            return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
104414237Sgiacomo.travaglini@arm.com        }
104514237Sgiacomo.travaglini@arm.com        break;
104614237Sgiacomo.travaglini@arm.com      }
104713760Sjairo.balart@metempsy.com      // Binary Point Register 1
104813531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
104913760Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: {
105014237Sgiacomo.travaglini@arm.com        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
105114237Sgiacomo.travaglini@arm.com            return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
105214237Sgiacomo.travaglini@arm.com        }
105314237Sgiacomo.travaglini@arm.com
105414237Sgiacomo.travaglini@arm.com        val &= 0x7;
105514237Sgiacomo.travaglini@arm.com
105614237Sgiacomo.travaglini@arm.com        if (isSecureBelowEL3()) {
105714237Sgiacomo.travaglini@arm.com            // group == Gicv3::G1S
105814237Sgiacomo.travaglini@arm.com            ICC_CTLR_EL1 icc_ctlr_el1_s =
105914237Sgiacomo.travaglini@arm.com                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
106014237Sgiacomo.travaglini@arm.com
106114237Sgiacomo.travaglini@arm.com            val = val > GIC_MIN_BPR ? val : GIC_MIN_BPR;
106214237Sgiacomo.travaglini@arm.com            if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
106314237Sgiacomo.travaglini@arm.com                isa->setMiscRegNoEffect(MISCREG_ICC_BPR0_EL1, val);
106414237Sgiacomo.travaglini@arm.com            } else {
106514237Sgiacomo.travaglini@arm.com                isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S, val);
106614237Sgiacomo.travaglini@arm.com            }
106714237Sgiacomo.travaglini@arm.com            return;
106814237Sgiacomo.travaglini@arm.com        } else {
106914237Sgiacomo.travaglini@arm.com            // group == Gicv3::G1NS
107014237Sgiacomo.travaglini@arm.com            ICC_CTLR_EL1 icc_ctlr_el1_ns =
107114237Sgiacomo.travaglini@arm.com                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
107214237Sgiacomo.travaglini@arm.com
107314237Sgiacomo.travaglini@arm.com            val = val > GIC_MIN_BPR_NS ? val : GIC_MIN_BPR_NS;
107414237Sgiacomo.travaglini@arm.com            if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
107514237Sgiacomo.travaglini@arm.com                // Non secure writes from EL1 and EL2 are ignored
107614237Sgiacomo.travaglini@arm.com            } else {
107714237Sgiacomo.travaglini@arm.com                isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS, val);
107814237Sgiacomo.travaglini@arm.com            }
107914237Sgiacomo.travaglini@arm.com            return;
108014237Sgiacomo.travaglini@arm.com        }
108114237Sgiacomo.travaglini@arm.com
108214237Sgiacomo.travaglini@arm.com        break;
108313531Sjairo.balart@metempsy.com      }
108413531Sjairo.balart@metempsy.com
108513760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 0
108613531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR0_EL1:
108713760Sjairo.balart@metempsy.com      // Virtual Binary Point Register 1
108813531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
108913531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
109013531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
109113760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
109213531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
109313531Sjairo.balart@metempsy.com
109413760Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
109513760Sjairo.balart@metempsy.com              // BPR0 + 1 saturated to 7, WI
109613531Sjairo.balart@metempsy.com              return;
109713531Sjairo.balart@metempsy.com          }
109813531Sjairo.balart@metempsy.com
109913531Sjairo.balart@metempsy.com          uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
110013531Sjairo.balart@metempsy.com
110113531Sjairo.balart@metempsy.com          if (group != Gicv3::G0S) {
110213531Sjairo.balart@metempsy.com              min_VPBR++;
110313531Sjairo.balart@metempsy.com          }
110413531Sjairo.balart@metempsy.com
110513531Sjairo.balart@metempsy.com          if (val < min_VPBR) {
110613531Sjairo.balart@metempsy.com              val = min_VPBR;
110713531Sjairo.balart@metempsy.com          }
110813531Sjairo.balart@metempsy.com
110913531Sjairo.balart@metempsy.com          if (group == Gicv3::G0S) {
111013760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = val;
111113531Sjairo.balart@metempsy.com          } else {
111213760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = val;
111313531Sjairo.balart@metempsy.com          }
111413531Sjairo.balart@metempsy.com
111513531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
111613531Sjairo.balart@metempsy.com          do_virtual_update = true;
111713531Sjairo.balart@metempsy.com          break;
111813531Sjairo.balart@metempsy.com      }
111913531Sjairo.balart@metempsy.com
112013760Sjairo.balart@metempsy.com      // Control Register EL1
112113531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
112213760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: {
112313760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
112413531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
112513531Sjairo.balart@metempsy.com          }
112613531Sjairo.balart@metempsy.com
112713531Sjairo.balart@metempsy.com          /*
112813760Sjairo.balart@metempsy.com           * ExtRange is RO.
112913531Sjairo.balart@metempsy.com           * RSS is RO.
113013531Sjairo.balart@metempsy.com           * A3V is RO.
113113531Sjairo.balart@metempsy.com           * SEIS is RO.
113213531Sjairo.balart@metempsy.com           * IDbits is RO.
113313531Sjairo.balart@metempsy.com           * PRIbits is RO.
113413531Sjairo.balart@metempsy.com           */
113513760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
113613760Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1 =
113714245Sgiacomo.travaglini@arm.com              readBankedMiscReg(MISCREG_ICC_CTLR_EL1);
113813760Sjairo.balart@metempsy.com
113913760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 =
114013760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
114113760Sjairo.balart@metempsy.com
114213760Sjairo.balart@metempsy.com          // The following could be refactored but it is following
114313760Sjairo.balart@metempsy.com          // spec description section 9.2.6 point by point.
114413760Sjairo.balart@metempsy.com
114513760Sjairo.balart@metempsy.com          // PMHE
114613760Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
114713760Sjairo.balart@metempsy.com              // PMHE is alias of ICC_CTLR_EL3.PMHE
114813760Sjairo.balart@metempsy.com
114913760Sjairo.balart@metempsy.com              if (distributor->DS == 0) {
115013760Sjairo.balart@metempsy.com                  // PMHE is RO
115113760Sjairo.balart@metempsy.com              } else if (distributor->DS == 1) {
115213760Sjairo.balart@metempsy.com                  // PMHE is RW
115313760Sjairo.balart@metempsy.com                  icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
115413760Sjairo.balart@metempsy.com                  icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
115513760Sjairo.balart@metempsy.com              }
115613531Sjairo.balart@metempsy.com          } else {
115713760Sjairo.balart@metempsy.com              // PMHE is RW (by implementation choice)
115813760Sjairo.balart@metempsy.com              icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
115913531Sjairo.balart@metempsy.com          }
116013531Sjairo.balart@metempsy.com
116113760Sjairo.balart@metempsy.com          // EOImode
116213760Sjairo.balart@metempsy.com          icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
116313760Sjairo.balart@metempsy.com
116413760Sjairo.balart@metempsy.com          if (inSecureState()) {
116513760Sjairo.balart@metempsy.com              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
116613760Sjairo.balart@metempsy.com              icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
116713760Sjairo.balart@metempsy.com          } else {
116813760Sjairo.balart@metempsy.com              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
116913760Sjairo.balart@metempsy.com              icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
117013760Sjairo.balart@metempsy.com          }
117113760Sjairo.balart@metempsy.com
117213760Sjairo.balart@metempsy.com          // CBPR
117313760Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
117413760Sjairo.balart@metempsy.com              // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
117513760Sjairo.balart@metempsy.com
117613760Sjairo.balart@metempsy.com              if (distributor->DS == 0) {
117713760Sjairo.balart@metempsy.com                  // CBPR is RO
117813760Sjairo.balart@metempsy.com              } else {
117913760Sjairo.balart@metempsy.com                  // CBPR is RW
118013760Sjairo.balart@metempsy.com                  icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
118113760Sjairo.balart@metempsy.com
118213760Sjairo.balart@metempsy.com                  if (inSecureState()) {
118313760Sjairo.balart@metempsy.com                      icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
118413760Sjairo.balart@metempsy.com                  } else {
118513760Sjairo.balart@metempsy.com                      icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
118613760Sjairo.balart@metempsy.com                  }
118713760Sjairo.balart@metempsy.com              }
118813760Sjairo.balart@metempsy.com          } else {
118913760Sjairo.balart@metempsy.com              // CBPR is RW
119013760Sjairo.balart@metempsy.com              icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
119113760Sjairo.balart@metempsy.com          }
119213760Sjairo.balart@metempsy.com
119313760Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);
119413760Sjairo.balart@metempsy.com
119514245Sgiacomo.travaglini@arm.com          setBankedMiscReg(MISCREG_ICC_CTLR_EL1, icc_ctlr_el1);
119614245Sgiacomo.travaglini@arm.com          return;
119713531Sjairo.balart@metempsy.com      }
119813531Sjairo.balart@metempsy.com
119913760Sjairo.balart@metempsy.com      // Virtual Control Register
120013531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
120113760Sjairo.balart@metempsy.com         ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
120213760Sjairo.balart@metempsy.com         ICV_CTLR_EL1 icv_ctlr_el1 =
120313760Sjairo.balart@metempsy.com             isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
120413760Sjairo.balart@metempsy.com         icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
120513760Sjairo.balart@metempsy.com         icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
120613760Sjairo.balart@metempsy.com         val = icv_ctlr_el1;
120713760Sjairo.balart@metempsy.com
120813760Sjairo.balart@metempsy.com         // Aliases
120913760Sjairo.balart@metempsy.com         // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
121013760Sjairo.balart@metempsy.com         // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
121113760Sjairo.balart@metempsy.com         ICH_VMCR_EL2 ich_vmcr_el2 =
121213760Sjairo.balart@metempsy.com             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
121313760Sjairo.balart@metempsy.com         ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
121413760Sjairo.balart@metempsy.com         ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
121513760Sjairo.balart@metempsy.com         isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
121613760Sjairo.balart@metempsy.com         break;
121713760Sjairo.balart@metempsy.com      }
121813760Sjairo.balart@metempsy.com
121913760Sjairo.balart@metempsy.com      // Control Register EL3
122013760Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
122113760Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
122213760Sjairo.balart@metempsy.com          /*
122313760Sjairo.balart@metempsy.com           * ExtRange is RO.
122413760Sjairo.balart@metempsy.com           * RSS is RO.
122513760Sjairo.balart@metempsy.com           * nDS is RO.
122613760Sjairo.balart@metempsy.com           * A3V is RO.
122713760Sjairo.balart@metempsy.com           * SEIS is RO.
122813760Sjairo.balart@metempsy.com           * IDbits is RO.
122913760Sjairo.balart@metempsy.com           * PRIbits is RO.
123013760Sjairo.balart@metempsy.com           * PMHE is RAO/WI, priority-based routing is always used.
123113760Sjairo.balart@metempsy.com           */
123213760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
123313760Sjairo.balart@metempsy.com
123413760Sjairo.balart@metempsy.com          // Aliases
123513760Sjairo.balart@metempsy.com          if (haveEL(EL3))
123613760Sjairo.balart@metempsy.com          {
123713760Sjairo.balart@metempsy.com              ICC_CTLR_EL1 icc_ctlr_el1_s =
123813760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
123913760Sjairo.balart@metempsy.com              ICC_CTLR_EL1 icc_ctlr_el1_ns =
124013760Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
124113760Sjairo.balart@metempsy.com
124213760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(NS).EOImode is an alias of
124313760Sjairo.balart@metempsy.com              // ICC_CTLR_EL3.EOImode_EL1NS
124413760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
124513760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(S).EOImode is an alias of
124613760Sjairo.balart@metempsy.com              // ICC_CTLR_EL3.EOImode_EL1S
124713760Sjairo.balart@metempsy.com              icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
124813760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
124913760Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
125013760Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
125113760Sjairo.balart@metempsy.com              icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
125213760Sjairo.balart@metempsy.com
125313760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
125413760Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
125513760Sjairo.balart@metempsy.com                                      icc_ctlr_el1_ns);
125613760Sjairo.balart@metempsy.com          }
125713760Sjairo.balart@metempsy.com
125813760Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 =
125913760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
126013760Sjairo.balart@metempsy.com
126113760Sjairo.balart@metempsy.com          icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
126213760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
126313760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
126413760Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
126513760Sjairo.balart@metempsy.com          icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
126613760Sjairo.balart@metempsy.com          icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
126713760Sjairo.balart@metempsy.com
126813760Sjairo.balart@metempsy.com          val = icc_ctlr_el3;
126913531Sjairo.balart@metempsy.com          break;
127013531Sjairo.balart@metempsy.com      }
127113531Sjairo.balart@metempsy.com
127213760Sjairo.balart@metempsy.com      // Priority Mask Register
127313531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
127413760Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1: {
127513760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
127614057Sgiacomo.travaglini@arm.com              return setMiscReg(MISCREG_ICV_PMR_EL1, val);
127713531Sjairo.balart@metempsy.com          }
127813531Sjairo.balart@metempsy.com
127913531Sjairo.balart@metempsy.com          val &= 0xff;
128013531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
128113531Sjairo.balart@metempsy.com
128213531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
128313760Sjairo.balart@metempsy.com              // Spec section 4.8.1
128413760Sjairo.balart@metempsy.com              // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
128513580Sgabeblack@google.com              RegVal old_icc_pmr_el1 =
128613531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);
128713531Sjairo.balart@metempsy.com
128813531Sjairo.balart@metempsy.com              if (!(old_icc_pmr_el1 & 0x80)) {
128913760Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
129013760Sjairo.balart@metempsy.com                  // 0x00-0x7F then WI
129113531Sjairo.balart@metempsy.com                  return;
129213531Sjairo.balart@metempsy.com              }
129313531Sjairo.balart@metempsy.com
129413760Sjairo.balart@metempsy.com              // If the current priority mask value is in the range of
129513760Sjairo.balart@metempsy.com              // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
129613760Sjairo.balart@metempsy.com              // based on the Non-secure read of the priority mask value
129713760Sjairo.balart@metempsy.com              // written to the register.
129813760Sjairo.balart@metempsy.com
129913531Sjairo.balart@metempsy.com              val = (val >> 1) | 0x80;
130013531Sjairo.balart@metempsy.com          }
130113531Sjairo.balart@metempsy.com
130213531Sjairo.balart@metempsy.com          val &= ~0U << (8 - PRIORITY_BITS);
130313531Sjairo.balart@metempsy.com          break;
130413531Sjairo.balart@metempsy.com      }
130513531Sjairo.balart@metempsy.com
130614057Sgiacomo.travaglini@arm.com      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
130714057Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
130814057Sgiacomo.travaglini@arm.com             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
130914057Sgiacomo.travaglini@arm.com          ich_vmcr_el2.VPMR = val & 0xff;
131014057Sgiacomo.travaglini@arm.com
131114057Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
131214057Sgiacomo.travaglini@arm.com          virtualUpdate();
131314057Sgiacomo.travaglini@arm.com          return;
131414057Sgiacomo.travaglini@arm.com      }
131514057Sgiacomo.travaglini@arm.com
131613760Sjairo.balart@metempsy.com      // Interrupt Group 0 Enable Register EL1
131713760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
131813760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
131913760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
132013760Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
132113760Sjairo.balart@metempsy.com          }
132213760Sjairo.balart@metempsy.com
132314248Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1, val);
132414248Sgiacomo.travaglini@arm.com          updateDistributor();
132514248Sgiacomo.travaglini@arm.com          return;
132613760Sjairo.balart@metempsy.com      }
132713760Sjairo.balart@metempsy.com
132813760Sjairo.balart@metempsy.com      // Virtual Interrupt Group 0 Enable register
132913760Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN0_EL1: {
133013760Sjairo.balart@metempsy.com          bool enable = val & 0x1;
133113760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
133213760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
133313760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG0 = enable;
133413740Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
133513740Sgiacomo.travaglini@arm.com          virtualUpdate();
133613740Sgiacomo.travaglini@arm.com          return;
133713740Sgiacomo.travaglini@arm.com      }
133813740Sgiacomo.travaglini@arm.com
133913760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL1
134013760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
134113760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
134213760Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
134313760Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
134413760Sjairo.balart@metempsy.com          }
134513760Sjairo.balart@metempsy.com
134614247Sgiacomo.travaglini@arm.com          setBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1, val);
134714248Sgiacomo.travaglini@arm.com          updateDistributor();
134814247Sgiacomo.travaglini@arm.com          return;
134913531Sjairo.balart@metempsy.com      }
135013531Sjairo.balart@metempsy.com
135113760Sjairo.balart@metempsy.com      // Virtual Interrupt Group 1 Enable register
135213760Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN1_EL1: {
135313531Sjairo.balart@metempsy.com          bool enable = val & 0x1;
135413760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
135513531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
135613760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG1 = enable;
135713531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
135813531Sjairo.balart@metempsy.com          virtualUpdate();
135913531Sjairo.balart@metempsy.com          return;
136013531Sjairo.balart@metempsy.com      }
136113531Sjairo.balart@metempsy.com
136213760Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register
136313760Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
136413760Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL3: {
136513760Sjairo.balart@metempsy.com          ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
136614254Sgiacomo.travaglini@arm.com
136714254Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(
136814254Sgiacomo.travaglini@arm.com              MISCREG_ICC_IGRPEN1_EL1_S, icc_igrpen1_el3.EnableGrp1S);
136914254Sgiacomo.travaglini@arm.com          isa->setMiscRegNoEffect(
137014254Sgiacomo.travaglini@arm.com              MISCREG_ICC_IGRPEN1_EL1_NS, icc_igrpen1_el3.EnableGrp1NS);
137114256Sgiacomo.travaglini@arm.com          updateDistributor();
137214254Sgiacomo.travaglini@arm.com          return;
137313531Sjairo.balart@metempsy.com      }
137413531Sjairo.balart@metempsy.com
137513760Sjairo.balart@metempsy.com      // Software Generated Interrupt Group 0 Register
137613531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R:
137713531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R_EL1:
137814227Sgiacomo.travaglini@arm.com        generateSGI(val, Gicv3::G0S);
137914227Sgiacomo.travaglini@arm.com        break;
138013531Sjairo.balart@metempsy.com
138113760Sjairo.balart@metempsy.com      // Software Generated Interrupt Group 1 Register
138213531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI1R:
138314227Sgiacomo.travaglini@arm.com      case MISCREG_ICC_SGI1R_EL1: {
138414227Sgiacomo.travaglini@arm.com        Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
138514227Sgiacomo.travaglini@arm.com
138614227Sgiacomo.travaglini@arm.com        generateSGI(val, group);
138714227Sgiacomo.travaglini@arm.com        break;
138814227Sgiacomo.travaglini@arm.com      }
138913531Sjairo.balart@metempsy.com
139013760Sjairo.balart@metempsy.com      // Alias Software Generated Interrupt Group 1 Register
139113531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R:
139213531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R_EL1: {
139314227Sgiacomo.travaglini@arm.com        Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S;
139414227Sgiacomo.travaglini@arm.com
139514227Sgiacomo.travaglini@arm.com        generateSGI(val, group);
139614227Sgiacomo.travaglini@arm.com        break;
139713531Sjairo.balart@metempsy.com      }
139813531Sjairo.balart@metempsy.com
139913760Sjairo.balart@metempsy.com      // System Register Enable Register EL1
140013531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
140113760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1:
140213760Sjairo.balart@metempsy.com      // System Register Enable Register EL2
140313531Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
140413760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2:
140513760Sjairo.balart@metempsy.com      // System Register Enable Register EL3
140613531Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
140713760Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3:
140813760Sjairo.balart@metempsy.com        // All bits are RAO/WI
140913760Sjairo.balart@metempsy.com        return;
141013760Sjairo.balart@metempsy.com
141113760Sjairo.balart@metempsy.com      // Hyp Control Register
141213760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
141313760Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2: {
141413760Sjairo.balart@metempsy.com        ICH_HCR_EL2 requested_ich_hcr_el2 = val;
141513760Sjairo.balart@metempsy.com        ICH_HCR_EL2 ich_hcr_el2 =
141613760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
141713760Sjairo.balart@metempsy.com
141813760Sjairo.balart@metempsy.com        if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
141913760Sjairo.balart@metempsy.com        {
142013760Sjairo.balart@metempsy.com            // EOIcount - Permitted behaviors are:
142113760Sjairo.balart@metempsy.com            // - Increment EOIcount.
142213760Sjairo.balart@metempsy.com            // - Leave EOIcount unchanged.
142313760Sjairo.balart@metempsy.com            ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
142413531Sjairo.balart@metempsy.com        }
142513531Sjairo.balart@metempsy.com
142613760Sjairo.balart@metempsy.com        ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
142713760Sjairo.balart@metempsy.com        ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
142813760Sjairo.balart@metempsy.com        ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
142913760Sjairo.balart@metempsy.com        ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
143013760Sjairo.balart@metempsy.com        ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
143113760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
143213760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
143313760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
143413760Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
143513760Sjairo.balart@metempsy.com        ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
143613760Sjairo.balart@metempsy.com        ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
143713760Sjairo.balart@metempsy.com        ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
143813760Sjairo.balart@metempsy.com        ich_hcr_el2.En = requested_ich_hcr_el2.En;
143913760Sjairo.balart@metempsy.com        val = ich_hcr_el2;
144013531Sjairo.balart@metempsy.com        do_virtual_update = true;
144113531Sjairo.balart@metempsy.com        break;
144213760Sjairo.balart@metempsy.com      }
144313760Sjairo.balart@metempsy.com
144413760Sjairo.balart@metempsy.com      // List Registers
144513760Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
144613531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
144713760Sjairo.balart@metempsy.com        ICH_LRC requested_ich_lrc = val;
144813760Sjairo.balart@metempsy.com        ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
144913760Sjairo.balart@metempsy.com
145013760Sjairo.balart@metempsy.com        ich_lrc.State = requested_ich_lrc.State;
145113760Sjairo.balart@metempsy.com        ich_lrc.HW = requested_ich_lrc.HW;
145213760Sjairo.balart@metempsy.com        ich_lrc.Group = requested_ich_lrc.Group;
145313760Sjairo.balart@metempsy.com
145413760Sjairo.balart@metempsy.com        // Priority, bits [23:16]
145513760Sjairo.balart@metempsy.com        // At least five bits must be implemented.
145613760Sjairo.balart@metempsy.com        // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
145713760Sjairo.balart@metempsy.com        // We implement 5 bits.
145813760Sjairo.balart@metempsy.com        ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
145913760Sjairo.balart@metempsy.com                           (ich_lrc.Priority & 0x07);
146013760Sjairo.balart@metempsy.com
146113760Sjairo.balart@metempsy.com        // pINTID, bits [12:0]
146213760Sjairo.balart@metempsy.com        // When ICH_LR<n>.HW is 0 this field has the following meaning:
146313760Sjairo.balart@metempsy.com        // - Bits[12:10] : RES0.
146413760Sjairo.balart@metempsy.com        // - Bit[9] : EOI.
146513760Sjairo.balart@metempsy.com        // - Bits[8:0] : RES0.
146613760Sjairo.balart@metempsy.com        // When ICH_LR<n>.HW is 1:
146713760Sjairo.balart@metempsy.com        // - This field is only required to implement enough bits to hold a
146813760Sjairo.balart@metempsy.com        // valid value for the implemented INTID size. Any unused higher
146913760Sjairo.balart@metempsy.com        // order bits are RES0.
147013760Sjairo.balart@metempsy.com        if (requested_ich_lrc.HW == 0) {
147113760Sjairo.balart@metempsy.com            ich_lrc.EOI = requested_ich_lrc.EOI;
147213760Sjairo.balart@metempsy.com        } else {
147313760Sjairo.balart@metempsy.com            ich_lrc.pINTID = requested_ich_lrc.pINTID;
147413531Sjairo.balart@metempsy.com        }
147513531Sjairo.balart@metempsy.com
147613760Sjairo.balart@metempsy.com        val = ich_lrc;
147713760Sjairo.balart@metempsy.com        do_virtual_update = true;
147813760Sjairo.balart@metempsy.com        break;
147913760Sjairo.balart@metempsy.com      }
148013760Sjairo.balart@metempsy.com
148113760Sjairo.balart@metempsy.com      // List Registers
148213531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
148313531Sjairo.balart@metempsy.com          // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
148413580Sgabeblack@google.com          RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
148513531Sjairo.balart@metempsy.com          val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
148613531Sjairo.balart@metempsy.com          do_virtual_update = true;
148713531Sjairo.balart@metempsy.com          break;
148813531Sjairo.balart@metempsy.com      }
148913531Sjairo.balart@metempsy.com
149013760Sjairo.balart@metempsy.com      // List Registers
149113531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
149213760Sjairo.balart@metempsy.com          ICH_LR_EL2 requested_ich_lr_el2 = val;
149313760Sjairo.balart@metempsy.com          ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
149413760Sjairo.balart@metempsy.com
149513760Sjairo.balart@metempsy.com          ich_lr_el2.State = requested_ich_lr_el2.State;
149613760Sjairo.balart@metempsy.com          ich_lr_el2.HW = requested_ich_lr_el2.HW;
149713760Sjairo.balart@metempsy.com          ich_lr_el2.Group = requested_ich_lr_el2.Group;
149813760Sjairo.balart@metempsy.com
149913760Sjairo.balart@metempsy.com          // Priority, bits [55:48]
150013760Sjairo.balart@metempsy.com          // At least five bits must be implemented.
150113760Sjairo.balart@metempsy.com          // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
150213760Sjairo.balart@metempsy.com          // We implement 5 bits.
150313760Sjairo.balart@metempsy.com          ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
150413760Sjairo.balart@metempsy.com                                (ich_lr_el2.Priority & 0x07);
150513760Sjairo.balart@metempsy.com
150613760Sjairo.balart@metempsy.com          // pINTID, bits [44:32]
150713760Sjairo.balart@metempsy.com          // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
150813760Sjairo.balart@metempsy.com          // - Bits[44:42] : RES0.
150913760Sjairo.balart@metempsy.com          // - Bit[41] : EOI.
151013760Sjairo.balart@metempsy.com          // - Bits[40:32] : RES0.
151113760Sjairo.balart@metempsy.com          // When ICH_LR<n>_EL2.HW is 1:
151213760Sjairo.balart@metempsy.com          // - This field is only required to implement enough bits to hold a
151313760Sjairo.balart@metempsy.com          // valid value for the implemented INTID size. Any unused higher
151413760Sjairo.balart@metempsy.com          // order bits are RES0.
151513760Sjairo.balart@metempsy.com          if (requested_ich_lr_el2.HW == 0) {
151613760Sjairo.balart@metempsy.com              ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
151713760Sjairo.balart@metempsy.com          } else {
151813760Sjairo.balart@metempsy.com              ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
151913760Sjairo.balart@metempsy.com          }
152013760Sjairo.balart@metempsy.com
152113760Sjairo.balart@metempsy.com          // vINTID, bits [31:0]
152213760Sjairo.balart@metempsy.com          // It is IMPLEMENTATION DEFINED how many bits are implemented,
152313760Sjairo.balart@metempsy.com          // though at least 16 bits must be implemented.
152413760Sjairo.balart@metempsy.com          // Unimplemented bits are RES0.
152513760Sjairo.balart@metempsy.com          ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
152613760Sjairo.balart@metempsy.com
152713760Sjairo.balart@metempsy.com          val = ich_lr_el2;
152813531Sjairo.balart@metempsy.com          do_virtual_update = true;
152913531Sjairo.balart@metempsy.com          break;
153013531Sjairo.balart@metempsy.com      }
153113531Sjairo.balart@metempsy.com
153213760Sjairo.balart@metempsy.com      // Virtual Machine Control Register
153313531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
153413531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2: {
153513760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
153613760Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
153713760Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
153813760Sjairo.balart@metempsy.com          ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
153913531Sjairo.balart@metempsy.com          uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
154013760Sjairo.balart@metempsy.com
154113760Sjairo.balart@metempsy.com          if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
154213760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = min_vpr0;
154313760Sjairo.balart@metempsy.com          } else {
154413760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
154513760Sjairo.balart@metempsy.com          }
154613760Sjairo.balart@metempsy.com
154713531Sjairo.balart@metempsy.com          uint8_t min_vpr1 = min_vpr0 + 1;
154813760Sjairo.balart@metempsy.com
154913760Sjairo.balart@metempsy.com          if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
155013760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = min_vpr1;
155113760Sjairo.balart@metempsy.com          } else {
155213760Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
155313760Sjairo.balart@metempsy.com          }
155413760Sjairo.balart@metempsy.com
155513760Sjairo.balart@metempsy.com          ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
155613760Sjairo.balart@metempsy.com          ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
155713760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
155813760Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
155913760Sjairo.balart@metempsy.com          val = ich_vmcr_el2;
156013531Sjairo.balart@metempsy.com          break;
156113531Sjairo.balart@metempsy.com      }
156213531Sjairo.balart@metempsy.com
156313760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 0 Registers
156414236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R0:
156514236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R0_EL2:
156614236Sgiacomo.travaglini@arm.com        break;
156714236Sgiacomo.travaglini@arm.com
156814236Sgiacomo.travaglini@arm.com      // only implemented if supporting 6 or more bits of priority
156914236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R1:
157014236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R1_EL2:
157114236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
157214236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R2:
157314236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R2_EL2:
157414236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
157514236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R3:
157614236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP0R3_EL2:
157714236Sgiacomo.travaglini@arm.com        // Unimplemented registers are RAZ/WI
157814236Sgiacomo.travaglini@arm.com        return;
157914236Sgiacomo.travaglini@arm.com
158013760Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 1 Registers
158114236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R0:
158214236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R0_EL2:
158313531Sjairo.balart@metempsy.com        break;
158413531Sjairo.balart@metempsy.com
158514236Sgiacomo.travaglini@arm.com      // only implemented if supporting 6 or more bits of priority
158614236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R1:
158714236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R1_EL2:
158814236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
158914236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R2:
159014236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R2_EL2:
159114236Sgiacomo.travaglini@arm.com      // only implemented if supporting 7 or more bits of priority
159214236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R3:
159314236Sgiacomo.travaglini@arm.com      case MISCREG_ICH_AP1R3_EL2:
159414236Sgiacomo.travaglini@arm.com        // Unimplemented registers are RAZ/WI
159514236Sgiacomo.travaglini@arm.com        return;
159614236Sgiacomo.travaglini@arm.com
159713531Sjairo.balart@metempsy.com      default:
159813760Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
159913760Sjairo.balart@metempsy.com              misc_reg, miscRegName[misc_reg]);
160013531Sjairo.balart@metempsy.com    }
160113531Sjairo.balart@metempsy.com
160213531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(misc_reg, val);
160313531Sjairo.balart@metempsy.com
160413531Sjairo.balart@metempsy.com    if (do_virtual_update) {
160513531Sjairo.balart@metempsy.com        virtualUpdate();
160613531Sjairo.balart@metempsy.com    }
160713531Sjairo.balart@metempsy.com}
160813531Sjairo.balart@metempsy.com
160914243Sgiacomo.travaglini@arm.comRegVal
161014243Sgiacomo.travaglini@arm.comGicv3CPUInterface::readBankedMiscReg(MiscRegIndex misc_reg) const
161114243Sgiacomo.travaglini@arm.com{
161214243Sgiacomo.travaglini@arm.com    return isa->readMiscRegNoEffect(
161314243Sgiacomo.travaglini@arm.com        isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()));
161414243Sgiacomo.travaglini@arm.com}
161514243Sgiacomo.travaglini@arm.com
161614243Sgiacomo.travaglini@arm.comvoid
161714243Sgiacomo.travaglini@arm.comGicv3CPUInterface::setBankedMiscReg(MiscRegIndex misc_reg, RegVal val) const
161814243Sgiacomo.travaglini@arm.com{
161914243Sgiacomo.travaglini@arm.com    isa->setMiscRegNoEffect(
162014243Sgiacomo.travaglini@arm.com        isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()), val);
162114243Sgiacomo.travaglini@arm.com}
162214243Sgiacomo.travaglini@arm.com
162313531Sjairo.balart@metempsy.comint
162413760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualFindActive(uint32_t int_id) const
162513531Sjairo.balart@metempsy.com{
162613531Sjairo.balart@metempsy.com    for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
162713760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
162813531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
162913760Sjairo.balart@metempsy.com
163013760Sjairo.balart@metempsy.com        if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
163113760Sjairo.balart@metempsy.com             (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
163213760Sjairo.balart@metempsy.com            (ich_lr_el2.vINTID == int_id)) {
163313531Sjairo.balart@metempsy.com            return lr_idx;
163413531Sjairo.balart@metempsy.com        }
163513531Sjairo.balart@metempsy.com    }
163613531Sjairo.balart@metempsy.com
163713531Sjairo.balart@metempsy.com    return -1;
163813531Sjairo.balart@metempsy.com}
163913531Sjairo.balart@metempsy.com
164013531Sjairo.balart@metempsy.comuint32_t
164113760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR0() const
164213531Sjairo.balart@metempsy.com{
164314233Sgiacomo.travaglini@arm.com    if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
164413531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
164513531Sjairo.balart@metempsy.com    }
164613531Sjairo.balart@metempsy.com
164713531Sjairo.balart@metempsy.com    bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
164813531Sjairo.balart@metempsy.com
164913531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
165013760Sjairo.balart@metempsy.com        // interrupt for the other state pending
165113531Sjairo.balart@metempsy.com        return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
165213531Sjairo.balart@metempsy.com    }
165313531Sjairo.balart@metempsy.com
165413531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
165513531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
165613531Sjairo.balart@metempsy.com    }
165713531Sjairo.balart@metempsy.com
165813531Sjairo.balart@metempsy.com    if (irq_is_secure && !inSecureState()) {
165913531Sjairo.balart@metempsy.com        // Secure interrupts not visible in Non-secure
166013531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
166113531Sjairo.balart@metempsy.com    }
166213531Sjairo.balart@metempsy.com
166313531Sjairo.balart@metempsy.com    return hppi.intid;
166413531Sjairo.balart@metempsy.com}
166513531Sjairo.balart@metempsy.com
166613531Sjairo.balart@metempsy.comuint32_t
166713760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR1() const
166813531Sjairo.balart@metempsy.com{
166914233Sgiacomo.travaglini@arm.com    if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
167013531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
167113531Sjairo.balart@metempsy.com    }
167213531Sjairo.balart@metempsy.com
167313760Sjairo.balart@metempsy.com    ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
167413760Sjairo.balart@metempsy.com    if ((currEL() == EL3) && icc_ctlr_el3.RM) {
167513531Sjairo.balart@metempsy.com        if (hppi.group == Gicv3::G0S) {
167613531Sjairo.balart@metempsy.com            return Gicv3::INTID_SECURE;
167713531Sjairo.balart@metempsy.com        } else if (hppi.group == Gicv3::G1NS) {
167813531Sjairo.balart@metempsy.com            return Gicv3::INTID_NONSECURE;
167913531Sjairo.balart@metempsy.com        }
168013531Sjairo.balart@metempsy.com    }
168113531Sjairo.balart@metempsy.com
168213531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G0S) {
168313531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
168413531Sjairo.balart@metempsy.com    }
168513531Sjairo.balart@metempsy.com
168613531Sjairo.balart@metempsy.com    bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
168713531Sjairo.balart@metempsy.com
168813531Sjairo.balart@metempsy.com    if (irq_is_secure) {
168913531Sjairo.balart@metempsy.com        if (!inSecureState()) {
169013531Sjairo.balart@metempsy.com            // Secure interrupts not visible in Non-secure
169113531Sjairo.balart@metempsy.com            return Gicv3::INTID_SPURIOUS;
169213531Sjairo.balart@metempsy.com        }
169313531Sjairo.balart@metempsy.com    } else if (!isEL3OrMon() && inSecureState()) {
169413531Sjairo.balart@metempsy.com        // Group 1 non-secure interrupts not visible in Secure EL1
169513531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
169613531Sjairo.balart@metempsy.com    }
169713531Sjairo.balart@metempsy.com
169813531Sjairo.balart@metempsy.com    return hppi.intid;
169913531Sjairo.balart@metempsy.com}
170013531Sjairo.balart@metempsy.com
170113531Sjairo.balart@metempsy.comvoid
170213531Sjairo.balart@metempsy.comGicv3CPUInterface::dropPriority(Gicv3::GroupId group)
170313531Sjairo.balart@metempsy.com{
170414246Sgiacomo.travaglini@arm.com    int apr_misc_reg = 0;
170514246Sgiacomo.travaglini@arm.com
170614246Sgiacomo.travaglini@arm.com    switch (group) {
170714246Sgiacomo.travaglini@arm.com      case Gicv3::G0S:
170814246Sgiacomo.travaglini@arm.com        apr_misc_reg = MISCREG_ICC_AP0R0_EL1;
170914246Sgiacomo.travaglini@arm.com        break;
171014246Sgiacomo.travaglini@arm.com      case Gicv3::G1S:
171114246Sgiacomo.travaglini@arm.com        apr_misc_reg = MISCREG_ICC_AP1R0_EL1_S;
171214246Sgiacomo.travaglini@arm.com        break;
171314246Sgiacomo.travaglini@arm.com      case Gicv3::G1NS:
171414246Sgiacomo.travaglini@arm.com        apr_misc_reg = MISCREG_ICC_AP1R0_EL1_NS;
171514246Sgiacomo.travaglini@arm.com        break;
171614246Sgiacomo.travaglini@arm.com      default:
171714246Sgiacomo.travaglini@arm.com        panic("Invalid Gicv3::GroupId");
171814246Sgiacomo.travaglini@arm.com    }
171914246Sgiacomo.travaglini@arm.com
172014246Sgiacomo.travaglini@arm.com    RegVal apr = isa->readMiscRegNoEffect(apr_misc_reg);
172113531Sjairo.balart@metempsy.com
172213531Sjairo.balart@metempsy.com    if (apr) {
172313531Sjairo.balart@metempsy.com        apr &= apr - 1;
172413531Sjairo.balart@metempsy.com        isa->setMiscRegNoEffect(apr_misc_reg, apr);
172513531Sjairo.balart@metempsy.com    }
172613531Sjairo.balart@metempsy.com
172713531Sjairo.balart@metempsy.com    update();
172813531Sjairo.balart@metempsy.com}
172913531Sjairo.balart@metempsy.com
173013531Sjairo.balart@metempsy.comuint8_t
173113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDropPriority()
173213531Sjairo.balart@metempsy.com{
173313531Sjairo.balart@metempsy.com    int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
173413531Sjairo.balart@metempsy.com
173513531Sjairo.balart@metempsy.com    for (int i = 0; i < apr_max; i++) {
173613580Sgabeblack@google.com        RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
173713580Sgabeblack@google.com        RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
173813531Sjairo.balart@metempsy.com
173913531Sjairo.balart@metempsy.com        if (!vapr0 && !vapr1) {
174013531Sjairo.balart@metempsy.com            continue;
174113531Sjairo.balart@metempsy.com        }
174213531Sjairo.balart@metempsy.com
174313531Sjairo.balart@metempsy.com        int vapr0_count = ctz32(vapr0);
174413531Sjairo.balart@metempsy.com        int vapr1_count = ctz32(vapr1);
174513531Sjairo.balart@metempsy.com
174613531Sjairo.balart@metempsy.com        if (vapr0_count <= vapr1_count) {
174713531Sjairo.balart@metempsy.com            vapr0 &= vapr0 - 1;
174813531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
174913531Sjairo.balart@metempsy.com            return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
175013531Sjairo.balart@metempsy.com        } else {
175113531Sjairo.balart@metempsy.com            vapr1 &= vapr1 - 1;
175213531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
175313531Sjairo.balart@metempsy.com            return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
175413531Sjairo.balart@metempsy.com        }
175513531Sjairo.balart@metempsy.com    }
175613531Sjairo.balart@metempsy.com
175713531Sjairo.balart@metempsy.com    return 0xff;
175813531Sjairo.balart@metempsy.com}
175913531Sjairo.balart@metempsy.com
176013531Sjairo.balart@metempsy.comvoid
176114227Sgiacomo.travaglini@arm.comGicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
176214227Sgiacomo.travaglini@arm.com{
176314227Sgiacomo.travaglini@arm.com    uint8_t aff3 = bits(val, 55, 48);
176414227Sgiacomo.travaglini@arm.com    uint8_t aff2 = bits(val, 39, 32);
176514227Sgiacomo.travaglini@arm.com    uint8_t aff1 = bits(val, 23, 16);;
176614227Sgiacomo.travaglini@arm.com    uint16_t target_list = bits(val, 15, 0);
176714227Sgiacomo.travaglini@arm.com    uint32_t int_id = bits(val, 27, 24);
176814227Sgiacomo.travaglini@arm.com    bool irm = bits(val, 40, 40);
176914227Sgiacomo.travaglini@arm.com    uint8_t rs = bits(val, 47, 44);
177014227Sgiacomo.travaglini@arm.com
177114227Sgiacomo.travaglini@arm.com    bool ns = !inSecureState();
177214227Sgiacomo.travaglini@arm.com
177314227Sgiacomo.travaglini@arm.com    for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
177414227Sgiacomo.travaglini@arm.com        Gicv3Redistributor * redistributor_i =
177514227Sgiacomo.travaglini@arm.com            gic->getRedistributor(i);
177614227Sgiacomo.travaglini@arm.com        uint32_t affinity_i = redistributor_i->getAffinity();
177714227Sgiacomo.travaglini@arm.com
177814227Sgiacomo.travaglini@arm.com        if (irm) {
177914227Sgiacomo.travaglini@arm.com            // Interrupts routed to all PEs in the system,
178014227Sgiacomo.travaglini@arm.com            // excluding "self"
178114227Sgiacomo.travaglini@arm.com            if (affinity_i == redistributor->getAffinity()) {
178214227Sgiacomo.travaglini@arm.com                continue;
178314227Sgiacomo.travaglini@arm.com            }
178414227Sgiacomo.travaglini@arm.com        } else {
178514227Sgiacomo.travaglini@arm.com            // Interrupts routed to the PEs specified by
178614227Sgiacomo.travaglini@arm.com            // Aff3.Aff2.Aff1.<target list>
178714227Sgiacomo.travaglini@arm.com            if ((affinity_i >> 8) !=
178814227Sgiacomo.travaglini@arm.com                ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
178914227Sgiacomo.travaglini@arm.com                continue;
179014227Sgiacomo.travaglini@arm.com            }
179114227Sgiacomo.travaglini@arm.com
179214227Sgiacomo.travaglini@arm.com            uint8_t aff0_i = bits(affinity_i, 7, 0);
179314227Sgiacomo.travaglini@arm.com
179414227Sgiacomo.travaglini@arm.com            if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
179514227Sgiacomo.travaglini@arm.com                ((0x1 << (aff0_i - rs * 16)) & target_list))) {
179614227Sgiacomo.travaglini@arm.com                continue;
179714227Sgiacomo.travaglini@arm.com            }
179814227Sgiacomo.travaglini@arm.com        }
179914227Sgiacomo.travaglini@arm.com
180014227Sgiacomo.travaglini@arm.com        redistributor_i->sendSGI(int_id, group, ns);
180114227Sgiacomo.travaglini@arm.com    }
180214227Sgiacomo.travaglini@arm.com}
180314227Sgiacomo.travaglini@arm.com
180414227Sgiacomo.travaglini@arm.comvoid
180513531Sjairo.balart@metempsy.comGicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
180613531Sjairo.balart@metempsy.com{
180713531Sjairo.balart@metempsy.com    // Update active priority registers.
180813531Sjairo.balart@metempsy.com    uint32_t prio = hppi.prio & 0xf8;
180913531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - PRIORITY_BITS);
181013531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
181114246Sgiacomo.travaglini@arm.com
181214246Sgiacomo.travaglini@arm.com    int apr_idx = 0;
181314246Sgiacomo.travaglini@arm.com    switch (group) {
181414246Sgiacomo.travaglini@arm.com      case Gicv3::G0S:
181514246Sgiacomo.travaglini@arm.com        apr_idx = MISCREG_ICC_AP0R0_EL1;
181614246Sgiacomo.travaglini@arm.com        break;
181714246Sgiacomo.travaglini@arm.com      case Gicv3::G1S:
181814246Sgiacomo.travaglini@arm.com        apr_idx = MISCREG_ICC_AP1R0_EL1_S;
181914246Sgiacomo.travaglini@arm.com        break;
182014246Sgiacomo.travaglini@arm.com      case Gicv3::G1NS:
182114246Sgiacomo.travaglini@arm.com        apr_idx = MISCREG_ICC_AP1R0_EL1_NS;
182214246Sgiacomo.travaglini@arm.com        break;
182314246Sgiacomo.travaglini@arm.com      default:
182414246Sgiacomo.travaglini@arm.com        panic("Invalid Gicv3::GroupId");
182514246Sgiacomo.travaglini@arm.com    }
182614246Sgiacomo.travaglini@arm.com
182713580Sgabeblack@google.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
182813531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
182913531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
183013531Sjairo.balart@metempsy.com
183113531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
183213531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
183313531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
183413531Sjairo.balart@metempsy.com        redistributor->activateIRQ(int_id);
183513531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
183613531Sjairo.balart@metempsy.com        // SPI, distributor
183713531Sjairo.balart@metempsy.com        distributor->activateIRQ(int_id);
183813923Sgiacomo.travaglini@arm.com    } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
183913923Sgiacomo.travaglini@arm.com        // LPI, Redistributor
184013923Sgiacomo.travaglini@arm.com        redistributor->setClrLPI(int_id, false);
184113531Sjairo.balart@metempsy.com    }
184214231Sgiacomo.travaglini@arm.com
184314231Sgiacomo.travaglini@arm.com    // By setting the priority to 0xff we are effectively
184414231Sgiacomo.travaglini@arm.com    // making the int_id not pending anymore at the cpu
184514231Sgiacomo.travaglini@arm.com    // interface.
184614231Sgiacomo.travaglini@arm.com    hppi.prio = 0xff;
184714231Sgiacomo.travaglini@arm.com    updateDistributor();
184813531Sjairo.balart@metempsy.com}
184913531Sjairo.balart@metempsy.com
185013531Sjairo.balart@metempsy.comvoid
185113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
185213531Sjairo.balart@metempsy.com{
185313531Sjairo.balart@metempsy.com    // Update active priority registers.
185413760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
185513531Sjairo.balart@metempsy.com            lr_idx);
185613760Sjairo.balart@metempsy.com    Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
185713760Sjairo.balart@metempsy.com    uint8_t prio = ich_lr_el.Priority & 0xf8;
185813531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
185913531Sjairo.balart@metempsy.com    int reg_no = apr_bit / 32;
186013531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
186113531Sjairo.balart@metempsy.com    int apr_idx = group == Gicv3::G0S ?
186213531Sjairo.balart@metempsy.com        MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
186313580Sgabeblack@google.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
186413531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
186513531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
186613531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
186713760Sjairo.balart@metempsy.com    ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
186813760Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
186913531Sjairo.balart@metempsy.com}
187013531Sjairo.balart@metempsy.com
187113531Sjairo.balart@metempsy.comvoid
187213531Sjairo.balart@metempsy.comGicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
187313531Sjairo.balart@metempsy.com{
187413531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
187513531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
187613531Sjairo.balart@metempsy.com        redistributor->deactivateIRQ(int_id);
187713531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
187813531Sjairo.balart@metempsy.com        // SPI, distributor
187913531Sjairo.balart@metempsy.com        distributor->deactivateIRQ(int_id);
188013531Sjairo.balart@metempsy.com    }
188114231Sgiacomo.travaglini@arm.com
188214231Sgiacomo.travaglini@arm.com    updateDistributor();
188313531Sjairo.balart@metempsy.com}
188413531Sjairo.balart@metempsy.com
188513531Sjairo.balart@metempsy.comvoid
188613531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
188713531Sjairo.balart@metempsy.com{
188813760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
188913531Sjairo.balart@metempsy.com            lr_idx);
189013531Sjairo.balart@metempsy.com
189113760Sjairo.balart@metempsy.com    if (ich_lr_el2.HW) {
189213531Sjairo.balart@metempsy.com        // Deactivate the associated physical interrupt
189313760Sjairo.balart@metempsy.com        if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
189413760Sjairo.balart@metempsy.com            Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
189513760Sjairo.balart@metempsy.com                distributor->getIntGroup(ich_lr_el2.pINTID) :
189613760Sjairo.balart@metempsy.com                redistributor->getIntGroup(ich_lr_el2.pINTID);
189713760Sjairo.balart@metempsy.com            deactivateIRQ(ich_lr_el2.pINTID, group);
189813531Sjairo.balart@metempsy.com        }
189913531Sjairo.balart@metempsy.com    }
190013531Sjairo.balart@metempsy.com
190113531Sjairo.balart@metempsy.com    //  Remove the active bit
190213760Sjairo.balart@metempsy.com    ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
190313760Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
190413531Sjairo.balart@metempsy.com}
190513531Sjairo.balart@metempsy.com
190613531Sjairo.balart@metempsy.com/*
190713760Sjairo.balart@metempsy.com * Returns the priority group field for the current BPR value for the group.
190813760Sjairo.balart@metempsy.com * GroupBits() Pseudocode from spec.
190913531Sjairo.balart@metempsy.com */
191013531Sjairo.balart@metempsy.comuint32_t
191113926Sgiacomo.travaglini@arm.comGicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
191213531Sjairo.balart@metempsy.com{
191313760Sjairo.balart@metempsy.com    ICC_CTLR_EL1 icc_ctlr_el1_s =
191413760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
191513760Sjairo.balart@metempsy.com    ICC_CTLR_EL1 icc_ctlr_el1_ns =
191613760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
191713760Sjairo.balart@metempsy.com
191813760Sjairo.balart@metempsy.com    if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
191913760Sjairo.balart@metempsy.com        (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
192013531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
192113531Sjairo.balart@metempsy.com    }
192213531Sjairo.balart@metempsy.com
192313531Sjairo.balart@metempsy.com    int bpr;
192413531Sjairo.balart@metempsy.com
192513531Sjairo.balart@metempsy.com    if (group == Gicv3::G0S) {
192613926Sgiacomo.travaglini@arm.com        bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
192714237Sgiacomo.travaglini@arm.com    } else if (group == Gicv3::G1S) {
192814237Sgiacomo.travaglini@arm.com        bpr = bpr1(Gicv3::G1S) & 0x7;
192913531Sjairo.balart@metempsy.com    } else {
193014237Sgiacomo.travaglini@arm.com        bpr = bpr1(Gicv3::G1NS) & 0x7;
193113531Sjairo.balart@metempsy.com    }
193213531Sjairo.balart@metempsy.com
193313531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS) {
193413531Sjairo.balart@metempsy.com        assert(bpr > 0);
193513531Sjairo.balart@metempsy.com        bpr--;
193613531Sjairo.balart@metempsy.com    }
193713531Sjairo.balart@metempsy.com
193813531Sjairo.balart@metempsy.com    return ~0U << (bpr + 1);
193913531Sjairo.balart@metempsy.com}
194013531Sjairo.balart@metempsy.com
194113531Sjairo.balart@metempsy.comuint32_t
194213760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
194313531Sjairo.balart@metempsy.com{
194413760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 =
194513531Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
194613531Sjairo.balart@metempsy.com
194713760Sjairo.balart@metempsy.com    if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
194813531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
194913531Sjairo.balart@metempsy.com    }
195013531Sjairo.balart@metempsy.com
195113531Sjairo.balart@metempsy.com    int bpr;
195213531Sjairo.balart@metempsy.com
195313531Sjairo.balart@metempsy.com    if (group == Gicv3::G0S) {
195413760Sjairo.balart@metempsy.com        bpr = ich_vmcr_el2.VBPR0;
195513531Sjairo.balart@metempsy.com    } else {
195613760Sjairo.balart@metempsy.com        bpr = ich_vmcr_el2.VBPR1;
195713531Sjairo.balart@metempsy.com    }
195813531Sjairo.balart@metempsy.com
195913531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS) {
196013531Sjairo.balart@metempsy.com        assert(bpr > 0);
196113531Sjairo.balart@metempsy.com        bpr--;
196213531Sjairo.balart@metempsy.com    }
196313531Sjairo.balart@metempsy.com
196413531Sjairo.balart@metempsy.com    return ~0U << (bpr + 1);
196513531Sjairo.balart@metempsy.com}
196613531Sjairo.balart@metempsy.com
196713531Sjairo.balart@metempsy.combool
196813760Sjairo.balart@metempsy.comGicv3CPUInterface::isEOISplitMode() const
196913531Sjairo.balart@metempsy.com{
197013531Sjairo.balart@metempsy.com    if (isEL3OrMon()) {
197113760Sjairo.balart@metempsy.com        ICC_CTLR_EL3 icc_ctlr_el3 =
197213760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
197313760Sjairo.balart@metempsy.com        return icc_ctlr_el3.EOImode_EL3;
197413531Sjairo.balart@metempsy.com    } else {
197514245Sgiacomo.travaglini@arm.com        ICC_CTLR_EL1 icc_ctlr_el1 = 0;
197614245Sgiacomo.travaglini@arm.com        if (inSecureState())
197714245Sgiacomo.travaglini@arm.com            icc_ctlr_el1 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
197814245Sgiacomo.travaglini@arm.com        else
197914245Sgiacomo.travaglini@arm.com            icc_ctlr_el1 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
198013760Sjairo.balart@metempsy.com        return icc_ctlr_el1.EOImode;
198113531Sjairo.balart@metempsy.com    }
198213531Sjairo.balart@metempsy.com}
198313531Sjairo.balart@metempsy.com
198413531Sjairo.balart@metempsy.combool
198513760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIsEOISplitMode() const
198613531Sjairo.balart@metempsy.com{
198713760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
198813760Sjairo.balart@metempsy.com    return ich_vmcr_el2.VEOIM;
198913531Sjairo.balart@metempsy.com}
199013531Sjairo.balart@metempsy.com
199113531Sjairo.balart@metempsy.comint
199213760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActiveGroup() const
199313531Sjairo.balart@metempsy.com{
199413531Sjairo.balart@metempsy.com    int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
199513531Sjairo.balart@metempsy.com    int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
199613531Sjairo.balart@metempsy.com    int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));
199713531Sjairo.balart@metempsy.com
199813531Sjairo.balart@metempsy.com    if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
199913531Sjairo.balart@metempsy.com        return Gicv3::G1NS;
200013531Sjairo.balart@metempsy.com    }
200113531Sjairo.balart@metempsy.com
200213531Sjairo.balart@metempsy.com    if (gq_ctz < g0_ctz) {
200313531Sjairo.balart@metempsy.com        return Gicv3::G1S;
200413531Sjairo.balart@metempsy.com    }
200513531Sjairo.balart@metempsy.com
200613531Sjairo.balart@metempsy.com    if (g0_ctz < 32) {
200713531Sjairo.balart@metempsy.com        return Gicv3::G0S;
200813531Sjairo.balart@metempsy.com    }
200913531Sjairo.balart@metempsy.com
201013531Sjairo.balart@metempsy.com    return -1;
201113531Sjairo.balart@metempsy.com}
201213531Sjairo.balart@metempsy.com
201313531Sjairo.balart@metempsy.comvoid
201414231Sgiacomo.travaglini@arm.comGicv3CPUInterface::updateDistributor()
201514231Sgiacomo.travaglini@arm.com{
201614231Sgiacomo.travaglini@arm.com    distributor->update();
201714231Sgiacomo.travaglini@arm.com}
201814231Sgiacomo.travaglini@arm.com
201914231Sgiacomo.travaglini@arm.comvoid
202013531Sjairo.balart@metempsy.comGicv3CPUInterface::update()
202113531Sjairo.balart@metempsy.com{
202213531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
202313531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
202413531Sjairo.balart@metempsy.com
202513531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
202613531Sjairo.balart@metempsy.com        /*
202713531Sjairo.balart@metempsy.com         * Secure enabled GIC sending a G1S IRQ to a secure disabled
202813531Sjairo.balart@metempsy.com         * CPU -> send G0 IRQ
202913531Sjairo.balart@metempsy.com         */
203013531Sjairo.balart@metempsy.com        hppi.group = Gicv3::G0S;
203113531Sjairo.balart@metempsy.com    }
203213531Sjairo.balart@metempsy.com
203313531Sjairo.balart@metempsy.com    if (hppiCanPreempt()) {
203413531Sjairo.balart@metempsy.com        ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
203513531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::update(): "
203613531Sjairo.balart@metempsy.com                "posting int as %d!\n", int_type);
203713531Sjairo.balart@metempsy.com        int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
203813531Sjairo.balart@metempsy.com    }
203913531Sjairo.balart@metempsy.com
204013531Sjairo.balart@metempsy.com    if (signal_IRQ) {
204113531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_IRQ);
204213531Sjairo.balart@metempsy.com    } else {
204313531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_IRQ);
204413531Sjairo.balart@metempsy.com    }
204513531Sjairo.balart@metempsy.com
204613531Sjairo.balart@metempsy.com    if (signal_FIQ) {
204713531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_FIQ);
204813531Sjairo.balart@metempsy.com    } else {
204913531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_FIQ);
205013531Sjairo.balart@metempsy.com    }
205113531Sjairo.balart@metempsy.com}
205213531Sjairo.balart@metempsy.com
205313531Sjairo.balart@metempsy.comvoid
205413531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualUpdate()
205513531Sjairo.balart@metempsy.com{
205613531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
205713531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
205813531Sjairo.balart@metempsy.com    int lr_idx = getHPPVILR();
205913531Sjairo.balart@metempsy.com
206013531Sjairo.balart@metempsy.com    if (lr_idx >= 0) {
206113760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
206213531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
206313531Sjairo.balart@metempsy.com
206413531Sjairo.balart@metempsy.com        if (hppviCanPreempt(lr_idx)) {
206513760Sjairo.balart@metempsy.com            if (ich_lr_el2.Group) {
206613531Sjairo.balart@metempsy.com                signal_IRQ = true;
206713531Sjairo.balart@metempsy.com            } else {
206813531Sjairo.balart@metempsy.com                signal_FIQ = true;
206913531Sjairo.balart@metempsy.com            }
207013531Sjairo.balart@metempsy.com        }
207113531Sjairo.balart@metempsy.com    }
207213531Sjairo.balart@metempsy.com
207313760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
207413760Sjairo.balart@metempsy.com
207513760Sjairo.balart@metempsy.com    if (ich_hcr_el2.En) {
207613531Sjairo.balart@metempsy.com        if (maintenanceInterruptStatus()) {
207713826Sgiacomo.travaglini@arm.com            maintenanceInterrupt->raise();
207813531Sjairo.balart@metempsy.com        }
207913531Sjairo.balart@metempsy.com    }
208013531Sjairo.balart@metempsy.com
208113531Sjairo.balart@metempsy.com    if (signal_IRQ) {
208213531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
208313531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
208413531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ);
208513531Sjairo.balart@metempsy.com    } else {
208613531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ);
208713531Sjairo.balart@metempsy.com    }
208813531Sjairo.balart@metempsy.com
208913531Sjairo.balart@metempsy.com    if (signal_FIQ) {
209013531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
209113531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
209213531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ);
209313531Sjairo.balart@metempsy.com    } else {
209413531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ);
209513531Sjairo.balart@metempsy.com    }
209613531Sjairo.balart@metempsy.com}
209713531Sjairo.balart@metempsy.com
209813760Sjairo.balart@metempsy.com// Returns the index of the LR with the HPPI
209913531Sjairo.balart@metempsy.comint
210013760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPVILR() const
210113531Sjairo.balart@metempsy.com{
210213531Sjairo.balart@metempsy.com    int idx = -1;
210313760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
210413760Sjairo.balart@metempsy.com
210513760Sjairo.balart@metempsy.com    if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
210613531Sjairo.balart@metempsy.com        // VG0 and VG1 disabled...
210713531Sjairo.balart@metempsy.com        return idx;
210813531Sjairo.balart@metempsy.com    }
210913531Sjairo.balart@metempsy.com
211013531Sjairo.balart@metempsy.com    uint8_t highest_prio = 0xff;
211113531Sjairo.balart@metempsy.com
211213531Sjairo.balart@metempsy.com    for (int i = 0; i < 16; i++) {
211313760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
211413531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
211513760Sjairo.balart@metempsy.com
211613760Sjairo.balart@metempsy.com        if (ich_lr_el2.State != Gicv3::INT_PENDING) {
211713531Sjairo.balart@metempsy.com            continue;
211813531Sjairo.balart@metempsy.com        }
211913531Sjairo.balart@metempsy.com
212013760Sjairo.balart@metempsy.com        if (ich_lr_el2.Group) {
212113531Sjairo.balart@metempsy.com            // VG1
212213760Sjairo.balart@metempsy.com            if (!ich_vmcr_el2.VENG1) {
212313531Sjairo.balart@metempsy.com                continue;
212413531Sjairo.balart@metempsy.com            }
212513531Sjairo.balart@metempsy.com        } else {
212613531Sjairo.balart@metempsy.com            // VG0
212713760Sjairo.balart@metempsy.com            if (!ich_vmcr_el2.VENG0) {
212813531Sjairo.balart@metempsy.com                continue;
212913531Sjairo.balart@metempsy.com            }
213013531Sjairo.balart@metempsy.com        }
213113531Sjairo.balart@metempsy.com
213213760Sjairo.balart@metempsy.com        uint8_t prio = ich_lr_el2.Priority;
213313531Sjairo.balart@metempsy.com
213413531Sjairo.balart@metempsy.com        if (prio < highest_prio) {
213513531Sjairo.balart@metempsy.com            highest_prio = prio;
213613531Sjairo.balart@metempsy.com            idx = i;
213713531Sjairo.balart@metempsy.com        }
213813531Sjairo.balart@metempsy.com    }
213913531Sjairo.balart@metempsy.com
214013531Sjairo.balart@metempsy.com    return idx;
214113531Sjairo.balart@metempsy.com}
214213531Sjairo.balart@metempsy.com
214313531Sjairo.balart@metempsy.combool
214413760Sjairo.balart@metempsy.comGicv3CPUInterface::hppviCanPreempt(int lr_idx) const
214513531Sjairo.balart@metempsy.com{
214613760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
214713760Sjairo.balart@metempsy.com    if (!ich_hcr_el2.En) {
214813531Sjairo.balart@metempsy.com        // virtual interface is disabled
214913531Sjairo.balart@metempsy.com        return false;
215013531Sjairo.balart@metempsy.com    }
215113531Sjairo.balart@metempsy.com
215213760Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el2 =
215313760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
215413760Sjairo.balart@metempsy.com    uint8_t prio = ich_lr_el2.Priority;
215513531Sjairo.balart@metempsy.com    uint8_t vpmr =
215613531Sjairo.balart@metempsy.com        bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);
215713531Sjairo.balart@metempsy.com
215813531Sjairo.balart@metempsy.com    if (prio >= vpmr) {
215913531Sjairo.balart@metempsy.com        // prioriry masked
216013531Sjairo.balart@metempsy.com        return false;
216113531Sjairo.balart@metempsy.com    }
216213531Sjairo.balart@metempsy.com
216313531Sjairo.balart@metempsy.com    uint8_t rprio = virtualHighestActivePriority();
216413531Sjairo.balart@metempsy.com
216513531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
216613531Sjairo.balart@metempsy.com        return true;
216713531Sjairo.balart@metempsy.com    }
216813531Sjairo.balart@metempsy.com
216913760Sjairo.balart@metempsy.com    Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
217013531Sjairo.balart@metempsy.com    uint32_t prio_mask = virtualGroupPriorityMask(group);
217113531Sjairo.balart@metempsy.com
217213531Sjairo.balart@metempsy.com    if ((prio & prio_mask) < (rprio & prio_mask)) {
217313531Sjairo.balart@metempsy.com        return true;
217413531Sjairo.balart@metempsy.com    }
217513531Sjairo.balart@metempsy.com
217613531Sjairo.balart@metempsy.com    return false;
217713531Sjairo.balart@metempsy.com}
217813531Sjairo.balart@metempsy.com
217913531Sjairo.balart@metempsy.comuint8_t
218013760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualHighestActivePriority() const
218113531Sjairo.balart@metempsy.com{
218213531Sjairo.balart@metempsy.com    uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
218313531Sjairo.balart@metempsy.com
218413531Sjairo.balart@metempsy.com    for (int i = 0; i < num_aprs; i++) {
218513580Sgabeblack@google.com        RegVal vapr =
218613531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
218713531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
218813531Sjairo.balart@metempsy.com
218913531Sjairo.balart@metempsy.com        if (!vapr) {
219013531Sjairo.balart@metempsy.com            continue;
219113531Sjairo.balart@metempsy.com        }
219213531Sjairo.balart@metempsy.com
219313531Sjairo.balart@metempsy.com        return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
219413531Sjairo.balart@metempsy.com    }
219513531Sjairo.balart@metempsy.com
219613531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
219713531Sjairo.balart@metempsy.com    return 0xff;
219813531Sjairo.balart@metempsy.com}
219913531Sjairo.balart@metempsy.com
220013531Sjairo.balart@metempsy.comvoid
220113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIncrementEOICount()
220213531Sjairo.balart@metempsy.com{
220313531Sjairo.balart@metempsy.com    // Increment the EOICOUNT field in ICH_HCR_EL2
220413580Sgabeblack@google.com    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
220513531Sjairo.balart@metempsy.com    uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
220613531Sjairo.balart@metempsy.com    EOI_cout++;
220713531Sjairo.balart@metempsy.com    ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
220813531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
220913531Sjairo.balart@metempsy.com}
221013531Sjairo.balart@metempsy.com
221113760Sjairo.balart@metempsy.com// spec section 4.6.2
221213531Sjairo.balart@metempsy.comArmISA::InterruptTypes
221313760Sjairo.balart@metempsy.comGicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
221413531Sjairo.balart@metempsy.com{
221513531Sjairo.balart@metempsy.com    bool is_fiq = false;
221613531Sjairo.balart@metempsy.com
221713531Sjairo.balart@metempsy.com    switch (group) {
221813531Sjairo.balart@metempsy.com      case Gicv3::G0S:
221913531Sjairo.balart@metempsy.com        is_fiq = true;
222013531Sjairo.balart@metempsy.com        break;
222113531Sjairo.balart@metempsy.com
222213531Sjairo.balart@metempsy.com      case Gicv3::G1S:
222313531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) &&
222413531Sjairo.balart@metempsy.com            (!inSecureState() || ((currEL() == EL3) && isAA64()));
222513531Sjairo.balart@metempsy.com        break;
222613531Sjairo.balart@metempsy.com
222713531Sjairo.balart@metempsy.com      case Gicv3::G1NS:
222813531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) && inSecureState();
222913531Sjairo.balart@metempsy.com        break;
223013531Sjairo.balart@metempsy.com
223113531Sjairo.balart@metempsy.com      default:
223213531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::intSignalType(): invalid group!");
223313531Sjairo.balart@metempsy.com    }
223413531Sjairo.balart@metempsy.com
223513531Sjairo.balart@metempsy.com    if (is_fiq) {
223613531Sjairo.balart@metempsy.com        return ArmISA::INT_FIQ;
223713531Sjairo.balart@metempsy.com    } else {
223813531Sjairo.balart@metempsy.com        return ArmISA::INT_IRQ;
223913531Sjairo.balart@metempsy.com    }
224013531Sjairo.balart@metempsy.com}
224113531Sjairo.balart@metempsy.com
224213531Sjairo.balart@metempsy.combool
224313926Sgiacomo.travaglini@arm.comGicv3CPUInterface::hppiCanPreempt()
224413531Sjairo.balart@metempsy.com{
224513531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff) {
224613531Sjairo.balart@metempsy.com        // there is no pending interrupt
224713531Sjairo.balart@metempsy.com        return false;
224813531Sjairo.balart@metempsy.com    }
224913531Sjairo.balart@metempsy.com
225013531Sjairo.balart@metempsy.com    if (!groupEnabled(hppi.group)) {
225113531Sjairo.balart@metempsy.com        // group disabled at CPU interface
225213531Sjairo.balart@metempsy.com        return false;
225313531Sjairo.balart@metempsy.com    }
225413531Sjairo.balart@metempsy.com
225513531Sjairo.balart@metempsy.com    if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
225613531Sjairo.balart@metempsy.com        // priority masked
225713531Sjairo.balart@metempsy.com        return false;
225813531Sjairo.balart@metempsy.com    }
225913531Sjairo.balart@metempsy.com
226013531Sjairo.balart@metempsy.com    uint8_t rprio = highestActivePriority();
226113531Sjairo.balart@metempsy.com
226213531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
226313531Sjairo.balart@metempsy.com        return true;
226413531Sjairo.balart@metempsy.com    }
226513531Sjairo.balart@metempsy.com
226613531Sjairo.balart@metempsy.com    uint32_t prio_mask = groupPriorityMask(hppi.group);
226713531Sjairo.balart@metempsy.com
226813531Sjairo.balart@metempsy.com    if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
226913531Sjairo.balart@metempsy.com        return true;
227013531Sjairo.balart@metempsy.com    }
227113531Sjairo.balart@metempsy.com
227213531Sjairo.balart@metempsy.com    return false;
227313531Sjairo.balart@metempsy.com}
227413531Sjairo.balart@metempsy.com
227513531Sjairo.balart@metempsy.comuint8_t
227613760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActivePriority() const
227713531Sjairo.balart@metempsy.com{
227813531Sjairo.balart@metempsy.com    uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
227913531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
228013531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);
228113531Sjairo.balart@metempsy.com
228213531Sjairo.balart@metempsy.com    if (apr) {
228313531Sjairo.balart@metempsy.com        return ctz32(apr) << (GIC_MIN_BPR + 1);
228413531Sjairo.balart@metempsy.com    }
228513531Sjairo.balart@metempsy.com
228613531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
228713531Sjairo.balart@metempsy.com    return 0xff;
228813531Sjairo.balart@metempsy.com}
228913531Sjairo.balart@metempsy.com
229013531Sjairo.balart@metempsy.combool
229113760Sjairo.balart@metempsy.comGicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
229213531Sjairo.balart@metempsy.com{
229313531Sjairo.balart@metempsy.com    switch (group) {
229413760Sjairo.balart@metempsy.com      case Gicv3::G0S: {
229513760Sjairo.balart@metempsy.com        ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
229613760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
229714234Sgiacomo.travaglini@arm.com        return icc_igrpen0_el1.Enable && distributor->EnableGrp0;
229813760Sjairo.balart@metempsy.com      }
229913760Sjairo.balart@metempsy.com
230013760Sjairo.balart@metempsy.com      case Gicv3::G1S: {
230113760Sjairo.balart@metempsy.com        ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
230213760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
230314234Sgiacomo.travaglini@arm.com        return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
230413760Sjairo.balart@metempsy.com      }
230513760Sjairo.balart@metempsy.com
230613760Sjairo.balart@metempsy.com      case Gicv3::G1NS: {
230713760Sjairo.balart@metempsy.com        ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
230813760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
230914234Sgiacomo.travaglini@arm.com        return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS;
231013760Sjairo.balart@metempsy.com      }
231113531Sjairo.balart@metempsy.com
231213531Sjairo.balart@metempsy.com      default:
231313531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
231413531Sjairo.balart@metempsy.com    }
231513531Sjairo.balart@metempsy.com}
231613531Sjairo.balart@metempsy.com
231713531Sjairo.balart@metempsy.combool
231813760Sjairo.balart@metempsy.comGicv3CPUInterface::inSecureState() const
231913531Sjairo.balart@metempsy.com{
232013531Sjairo.balart@metempsy.com    if (!gic->getSystem()->haveSecurity()) {
232113531Sjairo.balart@metempsy.com        return false;
232213531Sjairo.balart@metempsy.com    }
232313531Sjairo.balart@metempsy.com
232413531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
232513531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
232613531Sjairo.balart@metempsy.com    return ArmISA::inSecureState(scr, cpsr);
232713531Sjairo.balart@metempsy.com}
232813531Sjairo.balart@metempsy.com
232913531Sjairo.balart@metempsy.comint
233013760Sjairo.balart@metempsy.comGicv3CPUInterface::currEL() const
233113531Sjairo.balart@metempsy.com{
233213531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
233313531Sjairo.balart@metempsy.com    bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
233413531Sjairo.balart@metempsy.com
233513531Sjairo.balart@metempsy.com    if (is_64) {
233613531Sjairo.balart@metempsy.com        return (ExceptionLevel)(uint8_t) cpsr.el;
233713531Sjairo.balart@metempsy.com    } else {
233813531Sjairo.balart@metempsy.com        switch (cpsr.mode) {
233913531Sjairo.balart@metempsy.com          case MODE_USER:
234013531Sjairo.balart@metempsy.com            return 0;
234113531Sjairo.balart@metempsy.com
234213531Sjairo.balart@metempsy.com          case MODE_HYP:
234313531Sjairo.balart@metempsy.com            return 2;
234413531Sjairo.balart@metempsy.com
234513531Sjairo.balart@metempsy.com          case MODE_MON:
234613531Sjairo.balart@metempsy.com            return 3;
234713531Sjairo.balart@metempsy.com
234813531Sjairo.balart@metempsy.com          default:
234913531Sjairo.balart@metempsy.com            return 1;
235013531Sjairo.balart@metempsy.com        }
235113531Sjairo.balart@metempsy.com    }
235213531Sjairo.balart@metempsy.com}
235313531Sjairo.balart@metempsy.com
235413531Sjairo.balart@metempsy.combool
235513760Sjairo.balart@metempsy.comGicv3CPUInterface::haveEL(ExceptionLevel el) const
235613531Sjairo.balart@metempsy.com{
235713531Sjairo.balart@metempsy.com    switch (el) {
235813531Sjairo.balart@metempsy.com      case EL0:
235913531Sjairo.balart@metempsy.com      case EL1:
236013531Sjairo.balart@metempsy.com        return true;
236113531Sjairo.balart@metempsy.com
236213531Sjairo.balart@metempsy.com      case EL2:
236313531Sjairo.balart@metempsy.com        return gic->getSystem()->haveVirtualization();
236413531Sjairo.balart@metempsy.com
236513531Sjairo.balart@metempsy.com      case EL3:
236613531Sjairo.balart@metempsy.com        return gic->getSystem()->haveSecurity();
236713531Sjairo.balart@metempsy.com
236813531Sjairo.balart@metempsy.com      default:
236913531Sjairo.balart@metempsy.com        warn("Unimplemented Exception Level\n");
237013531Sjairo.balart@metempsy.com        return false;
237113531Sjairo.balart@metempsy.com    }
237213531Sjairo.balart@metempsy.com}
237313531Sjairo.balart@metempsy.com
237413531Sjairo.balart@metempsy.combool
237513760Sjairo.balart@metempsy.comGicv3CPUInterface::isSecureBelowEL3() const
237613531Sjairo.balart@metempsy.com{
237713531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
237813531Sjairo.balart@metempsy.com    return haveEL(EL3) && scr.ns == 0;
237913531Sjairo.balart@metempsy.com}
238013531Sjairo.balart@metempsy.com
238113531Sjairo.balart@metempsy.combool
238213760Sjairo.balart@metempsy.comGicv3CPUInterface::isAA64() const
238313531Sjairo.balart@metempsy.com{
238413531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
238513531Sjairo.balart@metempsy.com    return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
238613531Sjairo.balart@metempsy.com}
238713531Sjairo.balart@metempsy.com
238813531Sjairo.balart@metempsy.combool
238913760Sjairo.balart@metempsy.comGicv3CPUInterface::isEL3OrMon() const
239013531Sjairo.balart@metempsy.com{
239113531Sjairo.balart@metempsy.com    if (haveEL(EL3)) {
239213531Sjairo.balart@metempsy.com        CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
239313531Sjairo.balart@metempsy.com        bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
239413531Sjairo.balart@metempsy.com
239513531Sjairo.balart@metempsy.com        if (is_64 && (cpsr.el == EL3)) {
239613531Sjairo.balart@metempsy.com            return true;
239713531Sjairo.balart@metempsy.com        } else if (!is_64 && (cpsr.mode == MODE_MON)) {
239813531Sjairo.balart@metempsy.com            return true;
239913531Sjairo.balart@metempsy.com        }
240013531Sjairo.balart@metempsy.com    }
240113531Sjairo.balart@metempsy.com
240213531Sjairo.balart@metempsy.com    return false;
240313531Sjairo.balart@metempsy.com}
240413531Sjairo.balart@metempsy.com
240513760Sjairo.balart@metempsy.com// Computes ICH_EISR_EL2
240613760Sjairo.balart@metempsy.comuint64_t
240713760Sjairo.balart@metempsy.comGicv3CPUInterface::eoiMaintenanceInterruptStatus() const
240813531Sjairo.balart@metempsy.com{
240913760Sjairo.balart@metempsy.com    // ICH_EISR_EL2
241013760Sjairo.balart@metempsy.com    // Bits [63:16] - RES0
241113760Sjairo.balart@metempsy.com    // Status<n>, bit [n], for n = 0 to 15
241213760Sjairo.balart@metempsy.com    //   EOI maintenance interrupt status bit for List register <n>:
241313760Sjairo.balart@metempsy.com    //     0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
241413760Sjairo.balart@metempsy.com    //     maintenance interrupt.
241513760Sjairo.balart@metempsy.com    //     1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
241613760Sjairo.balart@metempsy.com    //     interrupt that has not been handled.
241713760Sjairo.balart@metempsy.com    //
241813760Sjairo.balart@metempsy.com    // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
241913760Sjairo.balart@metempsy.com    // of the following are true:
242013760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
242113760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.HW is 0.
242213760Sjairo.balart@metempsy.com    // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
242313760Sjairo.balart@metempsy.com
242413760Sjairo.balart@metempsy.com    uint64_t value = 0;
242513531Sjairo.balart@metempsy.com
242613531Sjairo.balart@metempsy.com    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
242713760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
242813760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
242913760Sjairo.balart@metempsy.com
243013760Sjairo.balart@metempsy.com        if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
243113760Sjairo.balart@metempsy.com            !ich_lr_el2.HW && ich_lr_el2.EOI) {
243213531Sjairo.balart@metempsy.com            value |= (1 << lr_idx);
243313531Sjairo.balart@metempsy.com        }
243413760Sjairo.balart@metempsy.com    }
243513760Sjairo.balart@metempsy.com
243613760Sjairo.balart@metempsy.com    return value;
243713760Sjairo.balart@metempsy.com}
243813760Sjairo.balart@metempsy.com
243913760Sjairo.balart@metempsy.comGicv3CPUInterface::ICH_MISR_EL2
244013760Sjairo.balart@metempsy.comGicv3CPUInterface::maintenanceInterruptStatus() const
244113760Sjairo.balart@metempsy.com{
244213760Sjairo.balart@metempsy.com    // Comments are copied from SPEC section 9.4.7 (ID012119)
244313760Sjairo.balart@metempsy.com    ICH_MISR_EL2 ich_misr_el2 = 0;
244413760Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 =
244513760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
244613760Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 =
244713760Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
244813760Sjairo.balart@metempsy.com
244913760Sjairo.balart@metempsy.com    // End Of Interrupt. [bit 0]
245013760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when at least one bit in
245113760Sjairo.balart@metempsy.com    // ICH_EISR_EL2 is 1.
245213760Sjairo.balart@metempsy.com
245313760Sjairo.balart@metempsy.com    if (eoiMaintenanceInterruptStatus()) {
245413760Sjairo.balart@metempsy.com        ich_misr_el2.EOI = 1;
245513760Sjairo.balart@metempsy.com    }
245613760Sjairo.balart@metempsy.com
245713760Sjairo.balart@metempsy.com    // Underflow. [bit 1]
245813760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
245913760Sjairo.balart@metempsy.com    // zero or one of the List register entries are marked as a valid
246013760Sjairo.balart@metempsy.com    // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
246113760Sjairo.balart@metempsy.com    // do not equal 0x0.
246213760Sjairo.balart@metempsy.com    uint32_t num_valid_interrupts = 0;
246313760Sjairo.balart@metempsy.com    uint32_t num_pending_interrupts = 0;
246413760Sjairo.balart@metempsy.com
246513760Sjairo.balart@metempsy.com    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
246613760Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
246713760Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
246813760Sjairo.balart@metempsy.com
246913760Sjairo.balart@metempsy.com        if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
247013760Sjairo.balart@metempsy.com            num_valid_interrupts++;
247113531Sjairo.balart@metempsy.com        }
247213531Sjairo.balart@metempsy.com
247313760Sjairo.balart@metempsy.com        if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
247413760Sjairo.balart@metempsy.com            num_pending_interrupts++;
247513531Sjairo.balart@metempsy.com        }
247613531Sjairo.balart@metempsy.com    }
247713531Sjairo.balart@metempsy.com
247813760Sjairo.balart@metempsy.com    if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
247913760Sjairo.balart@metempsy.com        ich_misr_el2.U = 1;
248013531Sjairo.balart@metempsy.com    }
248113531Sjairo.balart@metempsy.com
248213760Sjairo.balart@metempsy.com    // List Register Entry Not Present. [bit 2]
248313760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
248413760Sjairo.balart@metempsy.com    // and ICH_HCR_EL2.EOIcount is non-zero.
248513760Sjairo.balart@metempsy.com    if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
248613760Sjairo.balart@metempsy.com        ich_misr_el2.LRENP = 1;
248713531Sjairo.balart@metempsy.com    }
248813531Sjairo.balart@metempsy.com
248913760Sjairo.balart@metempsy.com    // No Pending. [bit 3]
249013760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
249113760Sjairo.balart@metempsy.com    // no List register is in pending state.
249213760Sjairo.balart@metempsy.com    if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
249313760Sjairo.balart@metempsy.com        ich_misr_el2.NP = 1;
249413531Sjairo.balart@metempsy.com    }
249513531Sjairo.balart@metempsy.com
249613760Sjairo.balart@metempsy.com    // vPE Group 0 Enabled. [bit 4]
249713760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
249813760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
249913760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
250013760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp0E = 1;
250113531Sjairo.balart@metempsy.com    }
250213531Sjairo.balart@metempsy.com
250313760Sjairo.balart@metempsy.com    // vPE Group 0 Disabled. [bit 5]
250413760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
250513760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
250613760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
250713760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp0D = 1;
250813531Sjairo.balart@metempsy.com    }
250913531Sjairo.balart@metempsy.com
251013760Sjairo.balart@metempsy.com    // vPE Group 1 Enabled. [bit 6]
251113760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
251213760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
251313760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
251413760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp1E = 1;
251513531Sjairo.balart@metempsy.com    }
251613531Sjairo.balart@metempsy.com
251713760Sjairo.balart@metempsy.com    // vPE Group 1 Disabled. [bit 7]
251813760Sjairo.balart@metempsy.com    // This maintenance interrupt is asserted when
251913760Sjairo.balart@metempsy.com    // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
252013760Sjairo.balart@metempsy.com    if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
252113760Sjairo.balart@metempsy.com        ich_misr_el2.VGrp1D = 1;
252213760Sjairo.balart@metempsy.com    }
252313760Sjairo.balart@metempsy.com
252413760Sjairo.balart@metempsy.com    return ich_misr_el2;
252513531Sjairo.balart@metempsy.com}
252613531Sjairo.balart@metempsy.com
252714237Sgiacomo.travaglini@arm.comRegVal
252814237Sgiacomo.travaglini@arm.comGicv3CPUInterface::bpr1(Gicv3::GroupId group)
252914237Sgiacomo.travaglini@arm.com{
253014237Sgiacomo.travaglini@arm.com    bool hcr_imo = getHCREL2IMO();
253114237Sgiacomo.travaglini@arm.com    if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
253214237Sgiacomo.travaglini@arm.com        return readMiscReg(MISCREG_ICV_BPR1_EL1);
253314237Sgiacomo.travaglini@arm.com    }
253414237Sgiacomo.travaglini@arm.com
253514237Sgiacomo.travaglini@arm.com    RegVal bpr = 0;
253614237Sgiacomo.travaglini@arm.com
253714237Sgiacomo.travaglini@arm.com    if (group == Gicv3::G1S) {
253814237Sgiacomo.travaglini@arm.com        ICC_CTLR_EL1 icc_ctlr_el1_s =
253914237Sgiacomo.travaglini@arm.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
254014237Sgiacomo.travaglini@arm.com
254114237Sgiacomo.travaglini@arm.com        if (!isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
254214237Sgiacomo.travaglini@arm.com            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
254314237Sgiacomo.travaglini@arm.com        } else {
254414237Sgiacomo.travaglini@arm.com            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S);
254514237Sgiacomo.travaglini@arm.com            bpr = bpr > GIC_MIN_BPR ? bpr : GIC_MIN_BPR;
254614237Sgiacomo.travaglini@arm.com        }
254714237Sgiacomo.travaglini@arm.com    } else if (group == Gicv3::G1NS) {
254814237Sgiacomo.travaglini@arm.com        ICC_CTLR_EL1 icc_ctlr_el1_ns =
254914237Sgiacomo.travaglini@arm.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
255014237Sgiacomo.travaglini@arm.com
255114237Sgiacomo.travaglini@arm.com        // Check if EL3 is implemented and this is a non secure accesses at
255214237Sgiacomo.travaglini@arm.com        // EL1 and EL2
255314237Sgiacomo.travaglini@arm.com        if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
255414237Sgiacomo.travaglini@arm.com            // Reads return BPR0 + 1 saturated to 7, WI
255514237Sgiacomo.travaglini@arm.com            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1) + 1;
255614237Sgiacomo.travaglini@arm.com            bpr = bpr < 7 ? bpr : 7;
255714237Sgiacomo.travaglini@arm.com        } else {
255814237Sgiacomo.travaglini@arm.com            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS);
255914237Sgiacomo.travaglini@arm.com            bpr = bpr > GIC_MIN_BPR_NS ? bpr : GIC_MIN_BPR_NS;
256014237Sgiacomo.travaglini@arm.com        }
256114237Sgiacomo.travaglini@arm.com    } else {
256214237Sgiacomo.travaglini@arm.com        panic("Should be used with G1S and G1NS only\n");
256314237Sgiacomo.travaglini@arm.com    }
256414237Sgiacomo.travaglini@arm.com
256514237Sgiacomo.travaglini@arm.com    return bpr;
256614237Sgiacomo.travaglini@arm.com}
256714237Sgiacomo.travaglini@arm.com
256813531Sjairo.balart@metempsy.comvoid
256913531Sjairo.balart@metempsy.comGicv3CPUInterface::serialize(CheckpointOut & cp) const
257013531Sjairo.balart@metempsy.com{
257113531Sjairo.balart@metempsy.com    SERIALIZE_SCALAR(hppi.intid);
257213531Sjairo.balart@metempsy.com    SERIALIZE_SCALAR(hppi.prio);
257313531Sjairo.balart@metempsy.com    SERIALIZE_ENUM(hppi.group);
257413531Sjairo.balart@metempsy.com}
257513531Sjairo.balart@metempsy.com
257613531Sjairo.balart@metempsy.comvoid
257713531Sjairo.balart@metempsy.comGicv3CPUInterface::unserialize(CheckpointIn & cp)
257813531Sjairo.balart@metempsy.com{
257913531Sjairo.balart@metempsy.com    UNSERIALIZE_SCALAR(hppi.intid);
258013531Sjairo.balart@metempsy.com    UNSERIALIZE_SCALAR(hppi.prio);
258113531Sjairo.balart@metempsy.com    UNSERIALIZE_ENUM(hppi.group);
258213531Sjairo.balart@metempsy.com}
2583