gic_v3_cpu_interface.cc revision 14256
113531Sjairo.balart@metempsy.com/*
213531Sjairo.balart@metempsy.com * Copyright (c) 2019 ARM Limited
313531Sjairo.balart@metempsy.com * All rights reserved
413531Sjairo.balart@metempsy.com *
513531Sjairo.balart@metempsy.com * The license below extends only to copyright in the software and shall
613531Sjairo.balart@metempsy.com * not be construed as granting a license to any other intellectual
713531Sjairo.balart@metempsy.com * property including but not limited to intellectual property relating
813531Sjairo.balart@metempsy.com * to a hardware implementation of the functionality of the software
913531Sjairo.balart@metempsy.com * licensed hereunder.  You may use the software subject to the license
1013531Sjairo.balart@metempsy.com * terms below provided that you ensure that this notice is replicated
1113531Sjairo.balart@metempsy.com * unmodified and in its entirety in all distributions of the software,
1213531Sjairo.balart@metempsy.com * modified or unmodified, in source code or in binary form.
1313531Sjairo.balart@metempsy.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
5113531Sjairo.balart@metempsy.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
5213531Sjairo.balart@metempsy.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;
5313531Sjairo.balart@metempsy.com
5413531Sjairo.balart@metempsy.comGicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
5513531Sjairo.balart@metempsy.com    : BaseISADevice(),
5613531Sjairo.balart@metempsy.com      gic(gic),
5713531Sjairo.balart@metempsy.com      redistributor(nullptr),
5813531Sjairo.balart@metempsy.com      distributor(nullptr),
5913531Sjairo.balart@metempsy.com      cpuId(cpu_id)
6013531Sjairo.balart@metempsy.com{
6113531Sjairo.balart@metempsy.com}
6213531Sjairo.balart@metempsy.com
6313531Sjairo.balart@metempsy.comvoid
6413531Sjairo.balart@metempsy.comGicv3CPUInterface::init()
6513531Sjairo.balart@metempsy.com{
6613531Sjairo.balart@metempsy.com    redistributor = gic->getRedistributor(cpuId);
6713531Sjairo.balart@metempsy.com    distributor = gic->getDistributor();
6813531Sjairo.balart@metempsy.com}
6913531Sjairo.balart@metempsy.com
7013531Sjairo.balart@metempsy.comvoid
7113531Sjairo.balart@metempsy.comGicv3CPUInterface::initState()
7213531Sjairo.balart@metempsy.com{
7313531Sjairo.balart@metempsy.com    reset();
7413531Sjairo.balart@metempsy.com}
7513531Sjairo.balart@metempsy.com
7613531Sjairo.balart@metempsy.comvoid
7713531Sjairo.balart@metempsy.comGicv3CPUInterface::reset()
7813531Sjairo.balart@metempsy.com{
7913531Sjairo.balart@metempsy.com    hppi.prio = 0xff;
8013531Sjairo.balart@metempsy.com}
8113531Sjairo.balart@metempsy.com
8213531Sjairo.balart@metempsy.comvoid
8313531Sjairo.balart@metempsy.comGicv3CPUInterface::setThreadContext(ThreadContext *tc)
8413531Sjairo.balart@metempsy.com{
8513531Sjairo.balart@metempsy.com    maintenanceInterrupt = gic->params()->maint_int->get(tc);
8613531Sjairo.balart@metempsy.com}
8713531Sjairo.balart@metempsy.com
8813531Sjairo.balart@metempsy.combool
8913531Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2FMO() const
9013531Sjairo.balart@metempsy.com{
9113531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
9213531Sjairo.balart@metempsy.com
9313531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
9413531Sjairo.balart@metempsy.com        return false;
9513531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
9613531Sjairo.balart@metempsy.com        return true;
9713531Sjairo.balart@metempsy.com    } else {
9813531Sjairo.balart@metempsy.com        return hcr.fmo;
9913580Sgabeblack@google.com    }
10013531Sjairo.balart@metempsy.com}
10113531Sjairo.balart@metempsy.com
10213580Sgabeblack@google.combool
10313531Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2IMO() const
10413531Sjairo.balart@metempsy.com{
10513531Sjairo.balart@metempsy.com    HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
10613531Sjairo.balart@metempsy.com
10713531Sjairo.balart@metempsy.com    if (hcr.tge && hcr.e2h) {
10813531Sjairo.balart@metempsy.com        return false;
10913531Sjairo.balart@metempsy.com    } else if (hcr.tge) {
11013531Sjairo.balart@metempsy.com        return true;
11113531Sjairo.balart@metempsy.com    } else {
11213531Sjairo.balart@metempsy.com        return hcr.imo;
11313531Sjairo.balart@metempsy.com    }
11413531Sjairo.balart@metempsy.com}
11513531Sjairo.balart@metempsy.com
11613531Sjairo.balart@metempsy.comRegVal
11713531Sjairo.balart@metempsy.comGicv3CPUInterface::readMiscReg(int misc_reg)
11813531Sjairo.balart@metempsy.com{
11913531Sjairo.balart@metempsy.com    RegVal value = isa->readMiscRegNoEffect(misc_reg);
12013531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
12113531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
12213531Sjairo.balart@metempsy.com
12313531Sjairo.balart@metempsy.com    switch (misc_reg) {
12413531Sjairo.balart@metempsy.com      // Active Priorities Group 1 Registers
12513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
12613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0_EL1: {
12713531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
12813531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
12913531Sjairo.balart@metempsy.com          }
13013531Sjairo.balart@metempsy.com
13113531Sjairo.balart@metempsy.com          return readBankedMiscReg(MISCREG_ICC_AP1R0_EL1);
13213531Sjairo.balart@metempsy.com      }
13313531Sjairo.balart@metempsy.com
13413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
13513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
13613531Sjairo.balart@metempsy.com
13713531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
13813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
13913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
14013531Sjairo.balart@metempsy.com
14113531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
14213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
14313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
14413531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
14513531Sjairo.balart@metempsy.com        return 0;
14613531Sjairo.balart@metempsy.com
14713531Sjairo.balart@metempsy.com      // Active Priorities Group 0 Registers
14813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
14913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1: {
15013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
15113531Sjairo.balart@metempsy.com              return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
15213531Sjairo.balart@metempsy.com          }
15313531Sjairo.balart@metempsy.com
15413739Sgiacomo.travaglini@arm.com          break;
15513531Sjairo.balart@metempsy.com      }
15613531Sjairo.balart@metempsy.com
15713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
15813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
15913531Sjairo.balart@metempsy.com
16013739Sgiacomo.travaglini@arm.com        // only implemented if supporting 6 or more bits of priority
16113739Sgiacomo.travaglini@arm.com      case MISCREG_ICC_AP0R2:
16213739Sgiacomo.travaglini@arm.com      case MISCREG_ICC_AP0R2_EL1:
16313739Sgiacomo.travaglini@arm.com
16413739Sgiacomo.travaglini@arm.com        // only implemented if supporting 7 or more bits of priority
16513739Sgiacomo.travaglini@arm.com      case MISCREG_ICC_AP0R3:
16613739Sgiacomo.travaglini@arm.com      case MISCREG_ICC_AP0R3_EL1:
16713531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
16813531Sjairo.balart@metempsy.com        return 0;
16913531Sjairo.balart@metempsy.com
17013739Sgiacomo.travaglini@arm.com      // Interrupt Group 0 Enable register EL1
17113531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
17213531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
17313531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
17413531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
17513531Sjairo.balart@metempsy.com          }
17613739Sgiacomo.travaglini@arm.com
17713739Sgiacomo.travaglini@arm.com          break;
17813739Sgiacomo.travaglini@arm.com      }
17913739Sgiacomo.travaglini@arm.com
18013739Sgiacomo.travaglini@arm.com      case MISCREG_ICV_IGRPEN0_EL1: {
18113739Sgiacomo.travaglini@arm.com          ICH_VMCR_EL2 ich_vmcr_el2 =
18213739Sgiacomo.travaglini@arm.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
18313531Sjairo.balart@metempsy.com          value = ich_vmcr_el2.VENG0;
18413531Sjairo.balart@metempsy.com          break;
18513531Sjairo.balart@metempsy.com      }
18613531Sjairo.balart@metempsy.com
18713531Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL1
18813531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
18913531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
19013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
19113531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
19213531Sjairo.balart@metempsy.com          }
19313531Sjairo.balart@metempsy.com
19413531Sjairo.balart@metempsy.com          value = readBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1);
19513531Sjairo.balart@metempsy.com          break;
19613531Sjairo.balart@metempsy.com      }
19713531Sjairo.balart@metempsy.com
19813531Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN1_EL1: {
19913531Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
20013531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
20113531Sjairo.balart@metempsy.com          value = ich_vmcr_el2.VENG1;
20213531Sjairo.balart@metempsy.com          break;
20313531Sjairo.balart@metempsy.com      }
20413531Sjairo.balart@metempsy.com
20513531Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL3
20613531Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
20713531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL3: {
20813531Sjairo.balart@metempsy.com          ICC_IGRPEN1_EL3 igrp_el3 = 0;
20913531Sjairo.balart@metempsy.com          igrp_el3.EnableGrp1S = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
21013531Sjairo.balart@metempsy.com              MISCREG_ICC_IGRPEN1_EL1_S)).Enable;
21113531Sjairo.balart@metempsy.com
21213531Sjairo.balart@metempsy.com          igrp_el3.EnableGrp1NS = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
21313531Sjairo.balart@metempsy.com              MISCREG_ICC_IGRPEN1_EL1_NS)).Enable;
21413531Sjairo.balart@metempsy.com
21513531Sjairo.balart@metempsy.com          value = igrp_el3;
21613531Sjairo.balart@metempsy.com          break;
21713531Sjairo.balart@metempsy.com      }
21813531Sjairo.balart@metempsy.com
21913531Sjairo.balart@metempsy.com      // Running Priority Register
22013531Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR:
22113531Sjairo.balart@metempsy.com      case MISCREG_ICC_RPR_EL1: {
22213531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
22313531Sjairo.balart@metempsy.com              (hcr_imo || hcr_fmo)) {
22413531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_RPR_EL1);
22513531Sjairo.balart@metempsy.com          }
22613531Sjairo.balart@metempsy.com
22713531Sjairo.balart@metempsy.com          uint8_t rprio = highestActivePriority();
22813531Sjairo.balart@metempsy.com
22913531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() &&
23013531Sjairo.balart@metempsy.com              (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
23113531Sjairo.balart@metempsy.com              // Spec section 4.8.1
23213531Sjairo.balart@metempsy.com              // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
23313531Sjairo.balart@metempsy.com              if ((rprio & 0x80) == 0) {
23413531Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
23513531Sjairo.balart@metempsy.com                  // 0x00-0x7F a read access returns the value 0x0
23613531Sjairo.balart@metempsy.com                  rprio = 0;
23713531Sjairo.balart@metempsy.com              } else if (rprio != 0xff) {
23813531Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
23913531Sjairo.balart@metempsy.com                  // 0x80-0xFF a read access returns the Non-secure read of
24013531Sjairo.balart@metempsy.com                  // the current value
24113531Sjairo.balart@metempsy.com                  rprio = (rprio << 1) & 0xff;
24213531Sjairo.balart@metempsy.com              }
24313531Sjairo.balart@metempsy.com          }
24413531Sjairo.balart@metempsy.com
24513531Sjairo.balart@metempsy.com          value = rprio;
24613531Sjairo.balart@metempsy.com          break;
24713531Sjairo.balart@metempsy.com      }
24813531Sjairo.balart@metempsy.com
24913531Sjairo.balart@metempsy.com      // Virtual Running Priority Register
25013531Sjairo.balart@metempsy.com      case MISCREG_ICV_RPR_EL1: {
25113531Sjairo.balart@metempsy.com          value = virtualHighestActivePriority();
25213580Sgabeblack@google.com          break;
25313531Sjairo.balart@metempsy.com      }
25413531Sjairo.balart@metempsy.com
25513531Sjairo.balart@metempsy.com      // Highest Priority Pending Interrupt Register 0
25613531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0:
25713531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR0_EL1: {
25813531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
25913531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
26013531Sjairo.balart@metempsy.com          }
26113531Sjairo.balart@metempsy.com
26213531Sjairo.balart@metempsy.com          value = getHPPIR0();
26313531Sjairo.balart@metempsy.com          break;
26413531Sjairo.balart@metempsy.com      }
26513531Sjairo.balart@metempsy.com
26613531Sjairo.balart@metempsy.com      // Virtual Highest Priority Pending Interrupt Register 0
26713531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR0_EL1: {
26813531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
26913531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
27013531Sjairo.balart@metempsy.com
27113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
27213531Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
27313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
27413531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
27513531Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
27613531Sjairo.balart@metempsy.com
27713531Sjairo.balart@metempsy.com              if (group == Gicv3::G0S) {
27813531Sjairo.balart@metempsy.com                  value = ich_lr_el2.vINTID;
27913531Sjairo.balart@metempsy.com              }
28013580Sgabeblack@google.com          }
28113531Sjairo.balart@metempsy.com
28213531Sjairo.balart@metempsy.com          break;
28313531Sjairo.balart@metempsy.com      }
28413531Sjairo.balart@metempsy.com
28513531Sjairo.balart@metempsy.com      // Highest Priority Pending Interrupt Register 1
28613531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1:
28713531Sjairo.balart@metempsy.com      case MISCREG_ICC_HPPIR1_EL1: {
28813531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
28913531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
29013531Sjairo.balart@metempsy.com          }
29113531Sjairo.balart@metempsy.com
29213531Sjairo.balart@metempsy.com          value = getHPPIR1();
29313531Sjairo.balart@metempsy.com          break;
29413531Sjairo.balart@metempsy.com      }
29513531Sjairo.balart@metempsy.com
29613531Sjairo.balart@metempsy.com      // Virtual Highest Priority Pending Interrupt Register 1
29713531Sjairo.balart@metempsy.com      case MISCREG_ICV_HPPIR1_EL1: {
29813531Sjairo.balart@metempsy.com          value = Gicv3::INTID_SPURIOUS;
29913531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
30013531Sjairo.balart@metempsy.com
30113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
30213531Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
30313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
30413531Sjairo.balart@metempsy.com              Gicv3::GroupId group =
30513531Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
30613531Sjairo.balart@metempsy.com
30713531Sjairo.balart@metempsy.com              if (group == Gicv3::G1NS) {
30813531Sjairo.balart@metempsy.com                  value = ich_lr_el2.vINTID;
30913531Sjairo.balart@metempsy.com              }
31013531Sjairo.balart@metempsy.com          }
31113531Sjairo.balart@metempsy.com
31213531Sjairo.balart@metempsy.com          break;
31313531Sjairo.balart@metempsy.com      }
31413531Sjairo.balart@metempsy.com
31513531Sjairo.balart@metempsy.com      // Binary Point Register 0
31613531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
31713531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0_EL1: {
31813531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
31913531Sjairo.balart@metempsy.com            return readMiscReg(MISCREG_ICV_BPR0_EL1);
32013531Sjairo.balart@metempsy.com        }
32113531Sjairo.balart@metempsy.com
32213531Sjairo.balart@metempsy.com        value = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
32313531Sjairo.balart@metempsy.com        break;
32413531Sjairo.balart@metempsy.com      }
32513531Sjairo.balart@metempsy.com
32613531Sjairo.balart@metempsy.com      // Binary Point Register 1
32713531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
32813531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: {
32913531Sjairo.balart@metempsy.com        value = bpr1(isSecureBelowEL3() ? Gicv3::G1S : Gicv3::G1NS);
33013531Sjairo.balart@metempsy.com        break;
33113531Sjairo.balart@metempsy.com      }
33213531Sjairo.balart@metempsy.com
33313531Sjairo.balart@metempsy.com      // Virtual Binary Point Register 0
33413531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR0_EL1: {
33513531Sjairo.balart@metempsy.com        ICH_VMCR_EL2 ich_vmcr_el2 =
33613531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
33713531Sjairo.balart@metempsy.com
33813531Sjairo.balart@metempsy.com        value = ich_vmcr_el2.VBPR0;
33913531Sjairo.balart@metempsy.com        break;
34013531Sjairo.balart@metempsy.com      }
34113531Sjairo.balart@metempsy.com
34213531Sjairo.balart@metempsy.com      // Virtual Binary Point Register 1
34313531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
34413531Sjairo.balart@metempsy.com        ICH_VMCR_EL2 ich_vmcr_el2 =
34513531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
34613531Sjairo.balart@metempsy.com
34713531Sjairo.balart@metempsy.com        if (ich_vmcr_el2.VCBPR) {
34813531Sjairo.balart@metempsy.com            // bpr0 + 1 saturated to 7, WI
34913531Sjairo.balart@metempsy.com            value = ich_vmcr_el2.VBPR0 + 1;
35013531Sjairo.balart@metempsy.com            value = value < 7 ? value : 7;
35113531Sjairo.balart@metempsy.com        } else {
35213531Sjairo.balart@metempsy.com            value = ich_vmcr_el2.VBPR1;
35313531Sjairo.balart@metempsy.com        }
35413531Sjairo.balart@metempsy.com
35513531Sjairo.balart@metempsy.com        break;
35613531Sjairo.balart@metempsy.com      }
35713580Sgabeblack@google.com
35813531Sjairo.balart@metempsy.com      // Interrupt Priority Mask Register
35913531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
36013531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1:
36113531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
36213531Sjairo.balart@metempsy.com            return readMiscReg(MISCREG_ICV_PMR_EL1);
36313531Sjairo.balart@metempsy.com        }
36413531Sjairo.balart@metempsy.com
36513531Sjairo.balart@metempsy.com        if (haveEL(EL3) && !inSecureState() &&
36613531Sjairo.balart@metempsy.com            (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
36713531Sjairo.balart@metempsy.com            // Spec section 4.8.1
36813531Sjairo.balart@metempsy.com            // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
36913531Sjairo.balart@metempsy.com            if ((value & 0x80) == 0) {
37013531Sjairo.balart@metempsy.com                // If the current priority mask value is in the range of
37113531Sjairo.balart@metempsy.com                // 0x00-0x7F a read access returns the value 0x00.
37213531Sjairo.balart@metempsy.com                value = 0;
37313531Sjairo.balart@metempsy.com            } else if (value != 0xff) {
37413531Sjairo.balart@metempsy.com                // If the current priority mask value is in the range of
37513531Sjairo.balart@metempsy.com                // 0x80-0xFF a read access returns the Non-secure read of the
37613531Sjairo.balart@metempsy.com                // current value.
37713531Sjairo.balart@metempsy.com                value = (value << 1) & 0xff;
37813531Sjairo.balart@metempsy.com            }
37913531Sjairo.balart@metempsy.com        }
38013531Sjairo.balart@metempsy.com
38113531Sjairo.balart@metempsy.com        break;
38213531Sjairo.balart@metempsy.com
38313531Sjairo.balart@metempsy.com      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
38413531Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
38513531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
38613531Sjairo.balart@metempsy.com
38713531Sjairo.balart@metempsy.com          value = ich_vmcr_el2.VPMR;
38813531Sjairo.balart@metempsy.com          break;
38913531Sjairo.balart@metempsy.com      }
39013531Sjairo.balart@metempsy.com
39113531Sjairo.balart@metempsy.com      // Interrupt Acknowledge Register 0
39213531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0:
39313531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR0_EL1: {
39413531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
39513531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR0_EL1);
39613531Sjairo.balart@metempsy.com          }
39713531Sjairo.balart@metempsy.com
39813531Sjairo.balart@metempsy.com          uint32_t int_id;
39913531Sjairo.balart@metempsy.com
40013531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
40113531Sjairo.balart@metempsy.com              int_id = getHPPIR0();
40213531Sjairo.balart@metempsy.com
40313531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
40413531Sjairo.balart@metempsy.com              if (int_id < Gicv3::INTID_SECURE ||
40513531Sjairo.balart@metempsy.com                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
40613531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
40713531Sjairo.balart@metempsy.com              }
40813531Sjairo.balart@metempsy.com          } else {
40913531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
41013531Sjairo.balart@metempsy.com          }
41113531Sjairo.balart@metempsy.com
41213531Sjairo.balart@metempsy.com          value = int_id;
41313531Sjairo.balart@metempsy.com          break;
41413531Sjairo.balart@metempsy.com      }
41513531Sjairo.balart@metempsy.com
41613531Sjairo.balart@metempsy.com      // Virtual Interrupt Acknowledge Register 0
41713531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR0_EL1: {
41813531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
41913531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
42013531Sjairo.balart@metempsy.com
42113531Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
42213531Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
42313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
42413531Sjairo.balart@metempsy.com
42513531Sjairo.balart@metempsy.com              if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
42613531Sjairo.balart@metempsy.com                  int_id = ich_lr_el2.vINTID;
42713531Sjairo.balart@metempsy.com
42813531Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
42913531Sjairo.balart@metempsy.com                      int_id > Gicv3::INTID_SPURIOUS) {
43013531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
43113531Sjairo.balart@metempsy.com                  } else {
43213531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
43313531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
43413531Sjairo.balart@metempsy.com                      // - Return de bogus id...
43513531Sjairo.balart@metempsy.com                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
43613531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
43713580Sgabeblack@google.com                                              ich_lr_el2);
43813531Sjairo.balart@metempsy.com                  }
43913531Sjairo.balart@metempsy.com              }
44013531Sjairo.balart@metempsy.com          }
44113531Sjairo.balart@metempsy.com
44213531Sjairo.balart@metempsy.com          value = int_id;
44313531Sjairo.balart@metempsy.com          virtualUpdate();
44413531Sjairo.balart@metempsy.com          break;
44513531Sjairo.balart@metempsy.com      }
44613531Sjairo.balart@metempsy.com
44713531Sjairo.balart@metempsy.com      // Interrupt Acknowledge Register 1
44813531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1:
44913531Sjairo.balart@metempsy.com      case MISCREG_ICC_IAR1_EL1: {
45013531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
45113531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_IAR1_EL1);
45213531Sjairo.balart@metempsy.com          }
45313531Sjairo.balart@metempsy.com
45413531Sjairo.balart@metempsy.com          uint32_t int_id;
45513531Sjairo.balart@metempsy.com
45613531Sjairo.balart@metempsy.com          if (hppiCanPreempt()) {
45713531Sjairo.balart@metempsy.com              int_id = getHPPIR1();
45813531Sjairo.balart@metempsy.com
45913531Sjairo.balart@metempsy.com              // avoid activation for special interrupts
46013531Sjairo.balart@metempsy.com              if (int_id < Gicv3::INTID_SECURE ||
46113531Sjairo.balart@metempsy.com                  int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
46213531Sjairo.balart@metempsy.com                  activateIRQ(int_id, hppi.group);
46313531Sjairo.balart@metempsy.com              }
46413531Sjairo.balart@metempsy.com          } else {
46513531Sjairo.balart@metempsy.com              int_id = Gicv3::INTID_SPURIOUS;
46613531Sjairo.balart@metempsy.com          }
46713531Sjairo.balart@metempsy.com
46813531Sjairo.balart@metempsy.com          value = int_id;
46913531Sjairo.balart@metempsy.com          break;
47013531Sjairo.balart@metempsy.com      }
47113531Sjairo.balart@metempsy.com
47213531Sjairo.balart@metempsy.com      // Virtual Interrupt Acknowledge Register 1
47313531Sjairo.balart@metempsy.com      case MISCREG_ICV_IAR1_EL1: {
47413531Sjairo.balart@metempsy.com          int lr_idx = getHPPVILR();
47513531Sjairo.balart@metempsy.com          uint32_t int_id = Gicv3::INTID_SPURIOUS;
47613531Sjairo.balart@metempsy.com
47713690Sjairo.balart@metempsy.com          if (lr_idx >= 0) {
47813690Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
47913690Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
48013690Sjairo.balart@metempsy.com
48113690Sjairo.balart@metempsy.com              if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
48213690Sjairo.balart@metempsy.com                  int_id = ich_lr_el2.vINTID;
48313690Sjairo.balart@metempsy.com
48413690Sjairo.balart@metempsy.com                  if (int_id < Gicv3::INTID_SECURE ||
48513531Sjairo.balart@metempsy.com                      int_id > Gicv3::INTID_SPURIOUS) {
48613531Sjairo.balart@metempsy.com                      virtualActivateIRQ(lr_idx);
48713531Sjairo.balart@metempsy.com                  } else {
48813531Sjairo.balart@metempsy.com                      // Bogus... Pseudocode says:
48913531Sjairo.balart@metempsy.com                      // - Move from pending to invalid...
49013531Sjairo.balart@metempsy.com                      // - Return de bogus id...
49113531Sjairo.balart@metempsy.com                      ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
49213531Sjairo.balart@metempsy.com                      isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
49313531Sjairo.balart@metempsy.com                                              ich_lr_el2);
49413531Sjairo.balart@metempsy.com                  }
49513531Sjairo.balart@metempsy.com              }
49613531Sjairo.balart@metempsy.com          }
49713531Sjairo.balart@metempsy.com
49813580Sgabeblack@google.com          value = int_id;
49913531Sjairo.balart@metempsy.com          virtualUpdate();
50013531Sjairo.balart@metempsy.com          break;
50113531Sjairo.balart@metempsy.com      }
50213531Sjairo.balart@metempsy.com
50313531Sjairo.balart@metempsy.com      // System Register Enable Register EL1
50413531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
50513531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1: {
50613531Sjairo.balart@metempsy.com        /*
50713531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
50813531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
50913531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
51013531Sjairo.balart@metempsy.com         */
51113531Sjairo.balart@metempsy.com          ICC_SRE_EL1 icc_sre_el1 = 0;
51213531Sjairo.balart@metempsy.com          icc_sre_el1.SRE = 1;
51313531Sjairo.balart@metempsy.com          icc_sre_el1.DIB = 1;
51413531Sjairo.balart@metempsy.com          icc_sre_el1.DFB = 1;
51513531Sjairo.balart@metempsy.com          value = icc_sre_el1;
51613531Sjairo.balart@metempsy.com          break;
51713531Sjairo.balart@metempsy.com      }
51813531Sjairo.balart@metempsy.com
51913531Sjairo.balart@metempsy.com      // System Register Enable Register EL2
52013531Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
52113531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2: {
52213531Sjairo.balart@metempsy.com        /*
52313531Sjairo.balart@metempsy.com         * Enable [3] == 1
52413531Sjairo.balart@metempsy.com         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
52513531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
52613531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
52713531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
52813531Sjairo.balart@metempsy.com         */
52913531Sjairo.balart@metempsy.com        ICC_SRE_EL2 icc_sre_el2 = 0;
53013531Sjairo.balart@metempsy.com        icc_sre_el2.SRE = 1;
53113580Sgabeblack@google.com        icc_sre_el2.DIB = 1;
53213531Sjairo.balart@metempsy.com        icc_sre_el2.DFB = 1;
53313531Sjairo.balart@metempsy.com        icc_sre_el2.Enable = 1;
53413531Sjairo.balart@metempsy.com        value = icc_sre_el2;
53513531Sjairo.balart@metempsy.com        break;
53613531Sjairo.balart@metempsy.com      }
53713531Sjairo.balart@metempsy.com
53813580Sgabeblack@google.com      // System Register Enable Register EL3
53913531Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
54013531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3: {
54113531Sjairo.balart@metempsy.com        /*
54213531Sjairo.balart@metempsy.com         * Enable [3] == 1
54313531Sjairo.balart@metempsy.com         * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
54413531Sjairo.balart@metempsy.com         *  EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
54513580Sgabeblack@google.com         *  RAO/WI)
54613531Sjairo.balart@metempsy.com         * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
54713531Sjairo.balart@metempsy.com         * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
54813531Sjairo.balart@metempsy.com         * SRE [0] == 1 (Only system register interface supported, RAO/WI)
54913531Sjairo.balart@metempsy.com         */
55013531Sjairo.balart@metempsy.com        ICC_SRE_EL3 icc_sre_el3 = 0;
55113531Sjairo.balart@metempsy.com        icc_sre_el3.SRE = 1;
55213531Sjairo.balart@metempsy.com        icc_sre_el3.DIB = 1;
55313531Sjairo.balart@metempsy.com        icc_sre_el3.DFB = 1;
55413531Sjairo.balart@metempsy.com        icc_sre_el3.Enable = 1;
55513531Sjairo.balart@metempsy.com        value = icc_sre_el3;
55613531Sjairo.balart@metempsy.com        break;
55713531Sjairo.balart@metempsy.com      }
55813531Sjairo.balart@metempsy.com
55913531Sjairo.balart@metempsy.com      // Control Register
56013531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
56113531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: {
56213531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
56313531Sjairo.balart@metempsy.com              return readMiscReg(MISCREG_ICV_CTLR_EL1);
56413531Sjairo.balart@metempsy.com          }
56513531Sjairo.balart@metempsy.com
56613531Sjairo.balart@metempsy.com          value = readBankedMiscReg(MISCREG_ICC_CTLR_EL1);
56713531Sjairo.balart@metempsy.com          // Enforce value for RO bits
56813531Sjairo.balart@metempsy.com          // ExtRange [19], INTIDs in the range 1024..8191 not supported
56913531Sjairo.balart@metempsy.com          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
57013531Sjairo.balart@metempsy.com          // A3V [15], supports non-zero values of the Aff3 field in SGI
57113531Sjairo.balart@metempsy.com          //           generation System registers
57213531Sjairo.balart@metempsy.com          // SEIS [14], does not support generation of SEIs (deprecated)
57313531Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
57413531Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
57513531Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1 = value;
57613531Sjairo.balart@metempsy.com          icc_ctlr_el1.ExtRange = 0;
57713531Sjairo.balart@metempsy.com          icc_ctlr_el1.RSS = 1;
57813531Sjairo.balart@metempsy.com          icc_ctlr_el1.A3V = 1;
57913531Sjairo.balart@metempsy.com          icc_ctlr_el1.SEIS = 0;
58013531Sjairo.balart@metempsy.com          icc_ctlr_el1.IDbits = 1;
58113531Sjairo.balart@metempsy.com          icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
58213531Sjairo.balart@metempsy.com          value = icc_ctlr_el1;
58313531Sjairo.balart@metempsy.com          break;
58413531Sjairo.balart@metempsy.com      }
58513531Sjairo.balart@metempsy.com
58613531Sjairo.balart@metempsy.com      // Virtual Control Register
58713531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
58813531Sjairo.balart@metempsy.com          ICV_CTLR_EL1 icv_ctlr_el1 = value;
58913531Sjairo.balart@metempsy.com          icv_ctlr_el1.RSS = 0;
59013531Sjairo.balart@metempsy.com          icv_ctlr_el1.A3V = 1;
59113531Sjairo.balart@metempsy.com          icv_ctlr_el1.SEIS = 0;
59213531Sjairo.balart@metempsy.com          icv_ctlr_el1.IDbits = 1;
59313531Sjairo.balart@metempsy.com          icv_ctlr_el1.PRIbits = 7;
59413531Sjairo.balart@metempsy.com          value = icv_ctlr_el1;
59513531Sjairo.balart@metempsy.com          break;
59613531Sjairo.balart@metempsy.com      }
59713531Sjairo.balart@metempsy.com
59813531Sjairo.balart@metempsy.com      // Control Register
59913531Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
60013531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
60113531Sjairo.balart@metempsy.com          // Enforce value for RO bits
60213531Sjairo.balart@metempsy.com          // ExtRange [19], INTIDs in the range 1024..8191 not supported
60313531Sjairo.balart@metempsy.com          // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
60413531Sjairo.balart@metempsy.com          // nDS [17], supports disabling of security
60513531Sjairo.balart@metempsy.com          // A3V [15], supports non-zero values of the Aff3 field in SGI
60613531Sjairo.balart@metempsy.com          //           generation System registers
60713531Sjairo.balart@metempsy.com          // SEIS [14], does not support generation of SEIs (deprecated)
60813531Sjairo.balart@metempsy.com          // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
60913531Sjairo.balart@metempsy.com          // PRIbits [10:8], number of priority bits implemented, minus one
61013531Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 = value;
61113531Sjairo.balart@metempsy.com          icc_ctlr_el3.ExtRange = 0;
61213531Sjairo.balart@metempsy.com          icc_ctlr_el3.RSS = 1;
61313580Sgabeblack@google.com          icc_ctlr_el3.nDS = 0;
61413531Sjairo.balart@metempsy.com          icc_ctlr_el3.A3V = 1;
61513531Sjairo.balart@metempsy.com          icc_ctlr_el3.SEIS = 0;
61613531Sjairo.balart@metempsy.com          icc_ctlr_el3.IDbits = 0;
61713531Sjairo.balart@metempsy.com          icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
61813531Sjairo.balart@metempsy.com          value = icc_ctlr_el3;
61913531Sjairo.balart@metempsy.com          break;
62013531Sjairo.balart@metempsy.com      }
62113531Sjairo.balart@metempsy.com
62213531Sjairo.balart@metempsy.com      // Hyp Control Register
62313531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
62413531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2:
62513531Sjairo.balart@metempsy.com        break;
62613531Sjairo.balart@metempsy.com
62713531Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 0 Registers
62813531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0:
62913531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0_EL2:
63013531Sjairo.balart@metempsy.com        break;
63113531Sjairo.balart@metempsy.com
63213531Sjairo.balart@metempsy.com      // only implemented if supporting 6 or more bits of priority
63313531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R1:
63413531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R1_EL2:
63513531Sjairo.balart@metempsy.com      // only implemented if supporting 7 or more bits of priority
63613531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R2:
63713580Sgabeblack@google.com      case MISCREG_ICH_AP0R2_EL2:
63813531Sjairo.balart@metempsy.com      // only implemented if supporting 7 or more bits of priority
63913580Sgabeblack@google.com      case MISCREG_ICH_AP0R3:
64013531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R3_EL2:
64113531Sjairo.balart@metempsy.com        // Unimplemented registers are RAZ/WI
64213531Sjairo.balart@metempsy.com        return 0;
64313531Sjairo.balart@metempsy.com
64413531Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 1 Registers
64513531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0:
64613531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0_EL2:
64713531Sjairo.balart@metempsy.com        break;
64813531Sjairo.balart@metempsy.com
64913531Sjairo.balart@metempsy.com      // only implemented if supporting 6 or more bits of priority
65013531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R1:
65113531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R1_EL2:
65213531Sjairo.balart@metempsy.com      // only implemented if supporting 7 or more bits of priority
65313531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R2:
65413531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R2_EL2:
65513531Sjairo.balart@metempsy.com      // only implemented if supporting 7 or more bits of priority
65613531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R3:
65713531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R3_EL2:
65813531Sjairo.balart@metempsy.com        // Unimplemented registers are RAZ/WI
65913531Sjairo.balart@metempsy.com        return 0;
66013531Sjairo.balart@metempsy.com
66113531Sjairo.balart@metempsy.com      // Maintenance Interrupt State Register
66213531Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR:
66313531Sjairo.balart@metempsy.com      case MISCREG_ICH_MISR_EL2:
66413531Sjairo.balart@metempsy.com        value = maintenanceInterruptStatus();
66513531Sjairo.balart@metempsy.com        break;
66613531Sjairo.balart@metempsy.com
66713531Sjairo.balart@metempsy.com      // VGIC Type Register
66813531Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR:
66913531Sjairo.balart@metempsy.com      case MISCREG_ICH_VTR_EL2: {
67013531Sjairo.balart@metempsy.com        ICH_VTR_EL2 ich_vtr_el2 = value;
67113531Sjairo.balart@metempsy.com
67213531Sjairo.balart@metempsy.com        ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
67313531Sjairo.balart@metempsy.com        ich_vtr_el2.A3V = 1;
67413531Sjairo.balart@metempsy.com        ich_vtr_el2.IDbits = 1;
67513531Sjairo.balart@metempsy.com        ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
67613531Sjairo.balart@metempsy.com        ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
67713531Sjairo.balart@metempsy.com
67813580Sgabeblack@google.com        value = ich_vtr_el2;
67913531Sjairo.balart@metempsy.com        break;
68013580Sgabeblack@google.com      }
68113531Sjairo.balart@metempsy.com
68213531Sjairo.balart@metempsy.com      // End of Interrupt Status Register
68313531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR:
68413531Sjairo.balart@metempsy.com      case MISCREG_ICH_EISR_EL2:
68513531Sjairo.balart@metempsy.com        value = eoiMaintenanceInterruptStatus();
68613531Sjairo.balart@metempsy.com        break;
68713531Sjairo.balart@metempsy.com
68813531Sjairo.balart@metempsy.com      // Empty List Register Status Register
68913531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR:
69013531Sjairo.balart@metempsy.com      case MISCREG_ICH_ELRSR_EL2:
69113531Sjairo.balart@metempsy.com        value = 0;
69213531Sjairo.balart@metempsy.com
69313531Sjairo.balart@metempsy.com        for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
69413531Sjairo.balart@metempsy.com            ICH_LR_EL2 ich_lr_el2 =
69513531Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
69613531Sjairo.balart@metempsy.com
69713531Sjairo.balart@metempsy.com            if ((ich_lr_el2.State  == ICH_LR_EL2_STATE_INVALID) &&
69813531Sjairo.balart@metempsy.com                (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
69913531Sjairo.balart@metempsy.com                value |= (1 << lr_idx);
70013531Sjairo.balart@metempsy.com            }
70113531Sjairo.balart@metempsy.com        }
70213531Sjairo.balart@metempsy.com
70313531Sjairo.balart@metempsy.com        break;
70413531Sjairo.balart@metempsy.com
70513531Sjairo.balart@metempsy.com      // List Registers
70613531Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
70713531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
70813531Sjairo.balart@metempsy.com        value = value >> 32;
70913531Sjairo.balart@metempsy.com        break;
71013531Sjairo.balart@metempsy.com
71113531Sjairo.balart@metempsy.com      // List Registers
71213531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
71313531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
71413531Sjairo.balart@metempsy.com        value = value & 0xffffffff;
71513531Sjairo.balart@metempsy.com        break;
71613531Sjairo.balart@metempsy.com
71713531Sjairo.balart@metempsy.com      // List Registers
71813531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
71913531Sjairo.balart@metempsy.com        break;
72013531Sjairo.balart@metempsy.com
72113531Sjairo.balart@metempsy.com      // Virtual Machine Control Register
72213531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
72313531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2:
72413531Sjairo.balart@metempsy.com        break;
72513531Sjairo.balart@metempsy.com
72613531Sjairo.balart@metempsy.com      default:
72713531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
72813531Sjairo.balart@metempsy.com              misc_reg, miscRegName[misc_reg]);
72913531Sjairo.balart@metempsy.com    }
73013531Sjairo.balart@metempsy.com
73113531Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
73213531Sjairo.balart@metempsy.com            miscRegName[misc_reg], value);
73313531Sjairo.balart@metempsy.com    return value;
73413531Sjairo.balart@metempsy.com}
73513531Sjairo.balart@metempsy.com
73613531Sjairo.balart@metempsy.comvoid
73713531Sjairo.balart@metempsy.comGicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
73813531Sjairo.balart@metempsy.com{
73913531Sjairo.balart@metempsy.com    bool do_virtual_update = false;
74013531Sjairo.balart@metempsy.com    DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
74113531Sjairo.balart@metempsy.com            miscRegName[misc_reg], val);
74213531Sjairo.balart@metempsy.com    bool hcr_fmo = getHCREL2FMO();
74313531Sjairo.balart@metempsy.com    bool hcr_imo = getHCREL2IMO();
74413531Sjairo.balart@metempsy.com
74513531Sjairo.balart@metempsy.com    switch (misc_reg) {
74613531Sjairo.balart@metempsy.com      // Active Priorities Group 1 Registers
74713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R0:
74813580Sgabeblack@google.com      case MISCREG_ICC_AP1R0_EL1:
74913531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
75013531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
75113531Sjairo.balart@metempsy.com        }
75213531Sjairo.balart@metempsy.com
75313531Sjairo.balart@metempsy.com        setBankedMiscReg(MISCREG_ICC_AP1R0_EL1, val);
75413531Sjairo.balart@metempsy.com        return;
75513531Sjairo.balart@metempsy.com
75613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1:
75713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R1_EL1:
75813531Sjairo.balart@metempsy.com
75913531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
76013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2:
76113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R2_EL1:
76213531Sjairo.balart@metempsy.com
76313531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
76413531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3:
76513531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP1R3_EL1:
76613531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
76713531Sjairo.balart@metempsy.com        break;
76813531Sjairo.balart@metempsy.com
76913531Sjairo.balart@metempsy.com      // Active Priorities Group 0 Registers
77013531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0:
77113531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R0_EL1:
77213531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
77313531Sjairo.balart@metempsy.com            return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
77413531Sjairo.balart@metempsy.com        }
77513531Sjairo.balart@metempsy.com
77613531Sjairo.balart@metempsy.com        break;
77713531Sjairo.balart@metempsy.com
77813531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1:
77913531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R1_EL1:
78013531Sjairo.balart@metempsy.com
78113531Sjairo.balart@metempsy.com        // only implemented if supporting 6 or more bits of priority
78213531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2:
78313531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R2_EL1:
78413531Sjairo.balart@metempsy.com
78513531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
78613531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3:
78713531Sjairo.balart@metempsy.com      case MISCREG_ICC_AP0R3_EL1:
78813531Sjairo.balart@metempsy.com        // only implemented if supporting 7 or more bits of priority
78913580Sgabeblack@google.com        break;
79013531Sjairo.balart@metempsy.com
79113531Sjairo.balart@metempsy.com      // End Of Interrupt Register 0
79213531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0:
79313531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
79413531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
79513531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
79613531Sjairo.balart@metempsy.com          }
79713531Sjairo.balart@metempsy.com
79813531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
79913531Sjairo.balart@metempsy.com
80013531Sjairo.balart@metempsy.com          // avoid activation for special interrupts
80113531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
80213531Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
80313531Sjairo.balart@metempsy.com              return;
80413531Sjairo.balart@metempsy.com          }
80513531Sjairo.balart@metempsy.com
80613531Sjairo.balart@metempsy.com          Gicv3::GroupId group = Gicv3::G0S;
80713531Sjairo.balart@metempsy.com
80813531Sjairo.balart@metempsy.com          if (highestActiveGroup() != group) {
80913531Sjairo.balart@metempsy.com              return;
81013531Sjairo.balart@metempsy.com          }
81113531Sjairo.balart@metempsy.com
81213531Sjairo.balart@metempsy.com          dropPriority(group);
81313531Sjairo.balart@metempsy.com
81413531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
81513531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
81613531Sjairo.balart@metempsy.com          }
81713531Sjairo.balart@metempsy.com
81813531Sjairo.balart@metempsy.com          break;
81913531Sjairo.balart@metempsy.com      }
82013531Sjairo.balart@metempsy.com
82113531Sjairo.balart@metempsy.com      // Virtual End Of Interrupt Register 0
82213531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR0_EL1: {
82313531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
82413531Sjairo.balart@metempsy.com
82513531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
82613531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
82713531Sjairo.balart@metempsy.com                  int_id <= Gicv3::INTID_SPURIOUS) {
82813531Sjairo.balart@metempsy.com              return;
82913531Sjairo.balart@metempsy.com          }
83013531Sjairo.balart@metempsy.com
83113531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
83213531Sjairo.balart@metempsy.com
83313531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
83413531Sjairo.balart@metempsy.com              return;
83513531Sjairo.balart@metempsy.com          }
83613531Sjairo.balart@metempsy.com
83713531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
83813531Sjairo.balart@metempsy.com
83913531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
84013531Sjairo.balart@metempsy.com              // No LR found matching
84113531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
84213531Sjairo.balart@metempsy.com          } else {
84313531Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
84413531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
84513531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
84613531Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
84713531Sjairo.balart@metempsy.com              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
84813531Sjairo.balart@metempsy.com
84913531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
85013531Sjairo.balart@metempsy.com                  //if (!virtualIsEOISplitMode())
85113531Sjairo.balart@metempsy.com                  {
85213531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
85313531Sjairo.balart@metempsy.com                  }
85413531Sjairo.balart@metempsy.com              }
85513531Sjairo.balart@metempsy.com          }
85613531Sjairo.balart@metempsy.com
85713531Sjairo.balart@metempsy.com          virtualUpdate();
85813531Sjairo.balart@metempsy.com          break;
85913531Sjairo.balart@metempsy.com      }
86013531Sjairo.balart@metempsy.com
86113531Sjairo.balart@metempsy.com      // End Of Interrupt Register 1
86213531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1:
86313531Sjairo.balart@metempsy.com      case MISCREG_ICC_EOIR1_EL1: {
86413531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
86513531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_EOIR1_EL1, val);
86613531Sjairo.balart@metempsy.com          }
86713531Sjairo.balart@metempsy.com
86813531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
86913531Sjairo.balart@metempsy.com
87013531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
87113531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
87213531Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
87313531Sjairo.balart@metempsy.com              return;
87413531Sjairo.balart@metempsy.com          }
87513531Sjairo.balart@metempsy.com
87613531Sjairo.balart@metempsy.com          Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
87713531Sjairo.balart@metempsy.com
87813531Sjairo.balart@metempsy.com          if (highestActiveGroup() == Gicv3::G0S) {
87913531Sjairo.balart@metempsy.com              return;
88013531Sjairo.balart@metempsy.com          }
88113531Sjairo.balart@metempsy.com
88213531Sjairo.balart@metempsy.com          if (distributor->DS == 0) {
88313531Sjairo.balart@metempsy.com              if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) {
88413531Sjairo.balart@metempsy.com                  return;
88513531Sjairo.balart@metempsy.com              } else if (highestActiveGroup() == Gicv3::G1NS &&
88613531Sjairo.balart@metempsy.com                         !(!inSecureState() or (currEL() == EL3))) {
88713531Sjairo.balart@metempsy.com                  return;
88813531Sjairo.balart@metempsy.com              }
88913580Sgabeblack@google.com          }
89013531Sjairo.balart@metempsy.com
89113531Sjairo.balart@metempsy.com          dropPriority(group);
89213531Sjairo.balart@metempsy.com
89313531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
89413531Sjairo.balart@metempsy.com              deactivateIRQ(int_id, group);
89513531Sjairo.balart@metempsy.com          }
89613531Sjairo.balart@metempsy.com
89713531Sjairo.balart@metempsy.com          break;
89813531Sjairo.balart@metempsy.com      }
89913531Sjairo.balart@metempsy.com
90013531Sjairo.balart@metempsy.com      // Virtual End Of Interrupt Register 1
90113531Sjairo.balart@metempsy.com      case MISCREG_ICV_EOIR1_EL1: {
90213531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
90313531Sjairo.balart@metempsy.com
90413531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
90513531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
90613531Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
90713531Sjairo.balart@metempsy.com              return;
90813531Sjairo.balart@metempsy.com          }
90913531Sjairo.balart@metempsy.com
91013531Sjairo.balart@metempsy.com          uint8_t drop_prio = virtualDropPriority();
91113531Sjairo.balart@metempsy.com
91213531Sjairo.balart@metempsy.com          if (drop_prio == 0xff) {
91313531Sjairo.balart@metempsy.com              return;
91413531Sjairo.balart@metempsy.com          }
91513531Sjairo.balart@metempsy.com
91613531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
91713531Sjairo.balart@metempsy.com
91813531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
91913531Sjairo.balart@metempsy.com              // No matching LR found
92013531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
92113531Sjairo.balart@metempsy.com          } else {
92213531Sjairo.balart@metempsy.com              ICH_LR_EL2 ich_lr_el2 =
92313531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
92413531Sjairo.balart@metempsy.com              Gicv3::GroupId lr_group =
92513531Sjairo.balart@metempsy.com                  ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
92613531Sjairo.balart@metempsy.com              uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
92713531Sjairo.balart@metempsy.com
92813531Sjairo.balart@metempsy.com              if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
92913531Sjairo.balart@metempsy.com                  if (!virtualIsEOISplitMode()) {
93013531Sjairo.balart@metempsy.com                      virtualDeactivateIRQ(lr_idx);
93113531Sjairo.balart@metempsy.com                  }
93213531Sjairo.balart@metempsy.com              }
93313531Sjairo.balart@metempsy.com          }
93413531Sjairo.balart@metempsy.com
93513531Sjairo.balart@metempsy.com          virtualUpdate();
93613531Sjairo.balart@metempsy.com          break;
93713531Sjairo.balart@metempsy.com      }
93813531Sjairo.balart@metempsy.com
93913531Sjairo.balart@metempsy.com      // Deactivate Interrupt Register
94013531Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR:
94113531Sjairo.balart@metempsy.com      case MISCREG_ICC_DIR_EL1: {
94213531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() &&
94313531Sjairo.balart@metempsy.com              (hcr_imo || hcr_fmo)) {
94413531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_DIR_EL1, val);
94513531Sjairo.balart@metempsy.com          }
94613531Sjairo.balart@metempsy.com
94713531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
94813531Sjairo.balart@metempsy.com
94913531Sjairo.balart@metempsy.com          // The following checks are as per spec pseudocode
95013531Sjairo.balart@metempsy.com          // aarch64/support/ICC_DIR_EL1
95113531Sjairo.balart@metempsy.com
95213531Sjairo.balart@metempsy.com          // Check for spurious ID
95313531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE) {
95413531Sjairo.balart@metempsy.com              return;
95513531Sjairo.balart@metempsy.com          }
95613531Sjairo.balart@metempsy.com
95713531Sjairo.balart@metempsy.com          // EOI mode is not set, so don't deactivate
95813531Sjairo.balart@metempsy.com          if (!isEOISplitMode()) {
95913531Sjairo.balart@metempsy.com              return;
96013531Sjairo.balart@metempsy.com          }
96113531Sjairo.balart@metempsy.com
96213531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
96313531Sjairo.balart@metempsy.com              int_id >= 32 ? distributor->getIntGroup(int_id) :
96413531Sjairo.balart@metempsy.com              redistributor->getIntGroup(int_id);
96513531Sjairo.balart@metempsy.com          bool irq_is_grp0 = group == Gicv3::G0S;
96613580Sgabeblack@google.com          bool single_sec_state = distributor->DS;
96713531Sjairo.balart@metempsy.com          bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
96813531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
96913531Sjairo.balart@metempsy.com          bool route_fiq_to_el3 = scr_el3.fiq;
97013531Sjairo.balart@metempsy.com          bool route_irq_to_el3 = scr_el3.irq;
97113531Sjairo.balart@metempsy.com          bool route_fiq_to_el2 = hcr_fmo;
97213531Sjairo.balart@metempsy.com          bool route_irq_to_el2 = hcr_imo;
97313531Sjairo.balart@metempsy.com
97413531Sjairo.balart@metempsy.com          switch (currEL()) {
97513531Sjairo.balart@metempsy.com            case EL3:
97613531Sjairo.balart@metempsy.com              break;
97713531Sjairo.balart@metempsy.com
97813531Sjairo.balart@metempsy.com            case EL2:
97913531Sjairo.balart@metempsy.com              if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
98013531Sjairo.balart@metempsy.com                  break;
98113531Sjairo.balart@metempsy.com              }
98213531Sjairo.balart@metempsy.com
98313531Sjairo.balart@metempsy.com              if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
98413531Sjairo.balart@metempsy.com                  break;
98513531Sjairo.balart@metempsy.com              }
98613531Sjairo.balart@metempsy.com
98713531Sjairo.balart@metempsy.com              return;
98813531Sjairo.balart@metempsy.com
98913531Sjairo.balart@metempsy.com            case EL1:
99013531Sjairo.balart@metempsy.com              if (!isSecureBelowEL3()) {
99113531Sjairo.balart@metempsy.com                  if (single_sec_state && irq_is_grp0 &&
99213531Sjairo.balart@metempsy.com                      !route_fiq_to_el3 && !route_fiq_to_el2) {
99313531Sjairo.balart@metempsy.com                      break;
99413531Sjairo.balart@metempsy.com                  }
99513531Sjairo.balart@metempsy.com
99613531Sjairo.balart@metempsy.com                  if (!irq_is_secure && !irq_is_grp0 &&
99713531Sjairo.balart@metempsy.com                      !route_irq_to_el3 && !route_irq_to_el2) {
99813531Sjairo.balart@metempsy.com                      break;
99913531Sjairo.balart@metempsy.com                  }
100013531Sjairo.balart@metempsy.com              } else {
100113531Sjairo.balart@metempsy.com                  if (irq_is_grp0 && !route_fiq_to_el3) {
100213531Sjairo.balart@metempsy.com                      break;
100313531Sjairo.balart@metempsy.com                  }
100413531Sjairo.balart@metempsy.com
100513531Sjairo.balart@metempsy.com                  if (!irq_is_grp0 &&
100613531Sjairo.balart@metempsy.com                      (!irq_is_secure || !single_sec_state) &&
100713531Sjairo.balart@metempsy.com                      !route_irq_to_el3) {
100813531Sjairo.balart@metempsy.com                      break;
100913531Sjairo.balart@metempsy.com                  }
101013531Sjairo.balart@metempsy.com              }
101113531Sjairo.balart@metempsy.com
101213531Sjairo.balart@metempsy.com              return;
101313531Sjairo.balart@metempsy.com
101413531Sjairo.balart@metempsy.com            default:
101513531Sjairo.balart@metempsy.com              break;
101613531Sjairo.balart@metempsy.com          }
101713531Sjairo.balart@metempsy.com
101813531Sjairo.balart@metempsy.com          deactivateIRQ(int_id, group);
101913531Sjairo.balart@metempsy.com          break;
102013531Sjairo.balart@metempsy.com      }
102113531Sjairo.balart@metempsy.com
102213531Sjairo.balart@metempsy.com      // Deactivate Virtual Interrupt Register
102313531Sjairo.balart@metempsy.com      case MISCREG_ICV_DIR_EL1: {
102413531Sjairo.balart@metempsy.com          int int_id = val & 0xffffff;
102513531Sjairo.balart@metempsy.com
102613531Sjairo.balart@metempsy.com          // avoid deactivation for special interrupts
102713531Sjairo.balart@metempsy.com          if (int_id >= Gicv3::INTID_SECURE &&
102813531Sjairo.balart@metempsy.com              int_id <= Gicv3::INTID_SPURIOUS) {
102913531Sjairo.balart@metempsy.com              return;
103013531Sjairo.balart@metempsy.com          }
103113531Sjairo.balart@metempsy.com
103213531Sjairo.balart@metempsy.com          if (!virtualIsEOISplitMode()) {
103313531Sjairo.balart@metempsy.com              return;
103413531Sjairo.balart@metempsy.com          }
103513531Sjairo.balart@metempsy.com
103613531Sjairo.balart@metempsy.com          int lr_idx = virtualFindActive(int_id);
103713531Sjairo.balart@metempsy.com
103813531Sjairo.balart@metempsy.com          if (lr_idx < 0) {
103913531Sjairo.balart@metempsy.com              // No matching LR found
104013531Sjairo.balart@metempsy.com              virtualIncrementEOICount();
104113531Sjairo.balart@metempsy.com          } else {
104213531Sjairo.balart@metempsy.com              virtualDeactivateIRQ(lr_idx);
104313531Sjairo.balart@metempsy.com          }
104413531Sjairo.balart@metempsy.com
104513531Sjairo.balart@metempsy.com          virtualUpdate();
104613531Sjairo.balart@metempsy.com          break;
104713531Sjairo.balart@metempsy.com      }
104813531Sjairo.balart@metempsy.com
104913531Sjairo.balart@metempsy.com      // Binary Point Register 0
105013531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0:
105113531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR0_EL1: {
105213531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
105313531Sjairo.balart@metempsy.com            return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
105413531Sjairo.balart@metempsy.com        }
105513531Sjairo.balart@metempsy.com        break;
105613531Sjairo.balart@metempsy.com      }
105713531Sjairo.balart@metempsy.com      // Binary Point Register 1
105813531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1:
105913531Sjairo.balart@metempsy.com      case MISCREG_ICC_BPR1_EL1: {
106013531Sjairo.balart@metempsy.com        if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
106113531Sjairo.balart@metempsy.com            return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
106213531Sjairo.balart@metempsy.com        }
106313531Sjairo.balart@metempsy.com
106413531Sjairo.balart@metempsy.com        val &= 0x7;
106513531Sjairo.balart@metempsy.com
106613531Sjairo.balart@metempsy.com        if (isSecureBelowEL3()) {
106713531Sjairo.balart@metempsy.com            // group == Gicv3::G1S
106813531Sjairo.balart@metempsy.com            ICC_CTLR_EL1 icc_ctlr_el1_s =
106913531Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
107013531Sjairo.balart@metempsy.com
107113531Sjairo.balart@metempsy.com            val = val > GIC_MIN_BPR ? val : GIC_MIN_BPR;
107213531Sjairo.balart@metempsy.com            if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
107313531Sjairo.balart@metempsy.com                isa->setMiscRegNoEffect(MISCREG_ICC_BPR0_EL1, val);
107413531Sjairo.balart@metempsy.com            } else {
107513531Sjairo.balart@metempsy.com                isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S, val);
107613531Sjairo.balart@metempsy.com            }
107713531Sjairo.balart@metempsy.com            return;
107813531Sjairo.balart@metempsy.com        } else {
107913531Sjairo.balart@metempsy.com            // group == Gicv3::G1NS
108013531Sjairo.balart@metempsy.com            ICC_CTLR_EL1 icc_ctlr_el1_ns =
108113531Sjairo.balart@metempsy.com                isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
108213531Sjairo.balart@metempsy.com
108313531Sjairo.balart@metempsy.com            val = val > GIC_MIN_BPR_NS ? val : GIC_MIN_BPR_NS;
108413531Sjairo.balart@metempsy.com            if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
108513531Sjairo.balart@metempsy.com                // Non secure writes from EL1 and EL2 are ignored
108613531Sjairo.balart@metempsy.com            } else {
108713531Sjairo.balart@metempsy.com                isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS, val);
108813531Sjairo.balart@metempsy.com            }
108913531Sjairo.balart@metempsy.com            return;
109013531Sjairo.balart@metempsy.com        }
109113531Sjairo.balart@metempsy.com
109213531Sjairo.balart@metempsy.com        break;
109313531Sjairo.balart@metempsy.com      }
109413531Sjairo.balart@metempsy.com
109513531Sjairo.balart@metempsy.com      // Virtual Binary Point Register 0
109613531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR0_EL1:
109713531Sjairo.balart@metempsy.com      // Virtual Binary Point Register 1
109813531Sjairo.balart@metempsy.com      case MISCREG_ICV_BPR1_EL1: {
109913531Sjairo.balart@metempsy.com          Gicv3::GroupId group =
110013531Sjairo.balart@metempsy.com              misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
110113531Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
110213531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
110313531Sjairo.balart@metempsy.com
110413531Sjairo.balart@metempsy.com          if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
110513531Sjairo.balart@metempsy.com              // BPR0 + 1 saturated to 7, WI
110613531Sjairo.balart@metempsy.com              return;
110713531Sjairo.balart@metempsy.com          }
110813531Sjairo.balart@metempsy.com
110913531Sjairo.balart@metempsy.com          uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
111013531Sjairo.balart@metempsy.com
111113531Sjairo.balart@metempsy.com          if (group != Gicv3::G0S) {
111213531Sjairo.balart@metempsy.com              min_VPBR++;
111313531Sjairo.balart@metempsy.com          }
111413531Sjairo.balart@metempsy.com
111513531Sjairo.balart@metempsy.com          if (val < min_VPBR) {
111613531Sjairo.balart@metempsy.com              val = min_VPBR;
111713531Sjairo.balart@metempsy.com          }
111813531Sjairo.balart@metempsy.com
111913531Sjairo.balart@metempsy.com          if (group == Gicv3::G0S) {
112013531Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = val;
112113531Sjairo.balart@metempsy.com          } else {
112213531Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = val;
112313531Sjairo.balart@metempsy.com          }
112413531Sjairo.balart@metempsy.com
112513531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
112613531Sjairo.balart@metempsy.com          do_virtual_update = true;
112713531Sjairo.balart@metempsy.com          break;
112813531Sjairo.balart@metempsy.com      }
112913531Sjairo.balart@metempsy.com
113013531Sjairo.balart@metempsy.com      // Control Register EL1
113113531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR:
113213531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL1: {
113313531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
113413531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
113513531Sjairo.balart@metempsy.com          }
113613531Sjairo.balart@metempsy.com
113713531Sjairo.balart@metempsy.com          /*
113813531Sjairo.balart@metempsy.com           * ExtRange is RO.
113913531Sjairo.balart@metempsy.com           * RSS is RO.
114013580Sgabeblack@google.com           * A3V is RO.
114113531Sjairo.balart@metempsy.com           * SEIS is RO.
114213531Sjairo.balart@metempsy.com           * IDbits is RO.
114313531Sjairo.balart@metempsy.com           * PRIbits is RO.
114413531Sjairo.balart@metempsy.com           */
114513531Sjairo.balart@metempsy.com          ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
114613531Sjairo.balart@metempsy.com          ICC_CTLR_EL1 icc_ctlr_el1 =
114713531Sjairo.balart@metempsy.com              readBankedMiscReg(MISCREG_ICC_CTLR_EL1);
114813531Sjairo.balart@metempsy.com
114913531Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 =
115013531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
115113531Sjairo.balart@metempsy.com
115213531Sjairo.balart@metempsy.com          // The following could be refactored but it is following
115313531Sjairo.balart@metempsy.com          // spec description section 9.2.6 point by point.
115413531Sjairo.balart@metempsy.com
115513531Sjairo.balart@metempsy.com          // PMHE
115613531Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
115713531Sjairo.balart@metempsy.com              // PMHE is alias of ICC_CTLR_EL3.PMHE
115813531Sjairo.balart@metempsy.com
115913531Sjairo.balart@metempsy.com              if (distributor->DS == 0) {
116013531Sjairo.balart@metempsy.com                  // PMHE is RO
116113531Sjairo.balart@metempsy.com              } else if (distributor->DS == 1) {
116213531Sjairo.balart@metempsy.com                  // PMHE is RW
116313531Sjairo.balart@metempsy.com                  icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
116413531Sjairo.balart@metempsy.com                  icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
116513531Sjairo.balart@metempsy.com              }
116613531Sjairo.balart@metempsy.com          } else {
116713531Sjairo.balart@metempsy.com              // PMHE is RW (by implementation choice)
116813531Sjairo.balart@metempsy.com              icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
116913531Sjairo.balart@metempsy.com          }
117013531Sjairo.balart@metempsy.com
117113531Sjairo.balart@metempsy.com          // EOImode
117213531Sjairo.balart@metempsy.com          icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
117313531Sjairo.balart@metempsy.com
117413531Sjairo.balart@metempsy.com          if (inSecureState()) {
117513531Sjairo.balart@metempsy.com              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
117613531Sjairo.balart@metempsy.com              icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
117713531Sjairo.balart@metempsy.com          } else {
117813531Sjairo.balart@metempsy.com              // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
117913531Sjairo.balart@metempsy.com              icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
118013531Sjairo.balart@metempsy.com          }
118113531Sjairo.balart@metempsy.com
118213531Sjairo.balart@metempsy.com          // CBPR
118313531Sjairo.balart@metempsy.com          if (haveEL(EL3)) {
118413531Sjairo.balart@metempsy.com              // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
118513531Sjairo.balart@metempsy.com
118613531Sjairo.balart@metempsy.com              if (distributor->DS == 0) {
118713531Sjairo.balart@metempsy.com                  // CBPR is RO
118813531Sjairo.balart@metempsy.com              } else {
118913531Sjairo.balart@metempsy.com                  // CBPR is RW
119013531Sjairo.balart@metempsy.com                  icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
119113531Sjairo.balart@metempsy.com
119213531Sjairo.balart@metempsy.com                  if (inSecureState()) {
119313531Sjairo.balart@metempsy.com                      icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
119413531Sjairo.balart@metempsy.com                  } else {
119513531Sjairo.balart@metempsy.com                      icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
119613531Sjairo.balart@metempsy.com                  }
119713531Sjairo.balart@metempsy.com              }
119813531Sjairo.balart@metempsy.com          } else {
119913531Sjairo.balart@metempsy.com              // CBPR is RW
120013531Sjairo.balart@metempsy.com              icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
120113580Sgabeblack@google.com          }
120213531Sjairo.balart@metempsy.com
120313531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);
120413531Sjairo.balart@metempsy.com
120513531Sjairo.balart@metempsy.com          setBankedMiscReg(MISCREG_ICC_CTLR_EL1, icc_ctlr_el1);
120613531Sjairo.balart@metempsy.com          return;
120713531Sjairo.balart@metempsy.com      }
120813531Sjairo.balart@metempsy.com
120913580Sgabeblack@google.com      // Virtual Control Register
121013531Sjairo.balart@metempsy.com      case MISCREG_ICV_CTLR_EL1: {
121113531Sjairo.balart@metempsy.com         ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
121213531Sjairo.balart@metempsy.com         ICV_CTLR_EL1 icv_ctlr_el1 =
121313531Sjairo.balart@metempsy.com             isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
121413531Sjairo.balart@metempsy.com         icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
121513531Sjairo.balart@metempsy.com         icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
121613531Sjairo.balart@metempsy.com         val = icv_ctlr_el1;
121713531Sjairo.balart@metempsy.com
121813531Sjairo.balart@metempsy.com         // Aliases
121913531Sjairo.balart@metempsy.com         // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
122013531Sjairo.balart@metempsy.com         // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
122113531Sjairo.balart@metempsy.com         ICH_VMCR_EL2 ich_vmcr_el2 =
122213580Sgabeblack@google.com             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
122313531Sjairo.balart@metempsy.com         ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
122413580Sgabeblack@google.com         ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
122513531Sjairo.balart@metempsy.com         isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
122613531Sjairo.balart@metempsy.com         break;
122713531Sjairo.balart@metempsy.com      }
122813531Sjairo.balart@metempsy.com
122913531Sjairo.balart@metempsy.com      // Control Register EL3
123013531Sjairo.balart@metempsy.com      case MISCREG_ICC_MCTLR:
123113531Sjairo.balart@metempsy.com      case MISCREG_ICC_CTLR_EL3: {
123213531Sjairo.balart@metempsy.com          /*
123313531Sjairo.balart@metempsy.com           * ExtRange is RO.
123413531Sjairo.balart@metempsy.com           * RSS is RO.
123513531Sjairo.balart@metempsy.com           * nDS is RO.
123613531Sjairo.balart@metempsy.com           * A3V is RO.
123713531Sjairo.balart@metempsy.com           * SEIS is RO.
123813531Sjairo.balart@metempsy.com           * IDbits is RO.
123913531Sjairo.balart@metempsy.com           * PRIbits is RO.
124013531Sjairo.balart@metempsy.com           * PMHE is RAO/WI, priority-based routing is always used.
124113531Sjairo.balart@metempsy.com           */
124213531Sjairo.balart@metempsy.com          ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
124313531Sjairo.balart@metempsy.com
124413531Sjairo.balart@metempsy.com          // Aliases
124513531Sjairo.balart@metempsy.com          if (haveEL(EL3))
124613531Sjairo.balart@metempsy.com          {
124713531Sjairo.balart@metempsy.com              ICC_CTLR_EL1 icc_ctlr_el1_s =
124813531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
124913531Sjairo.balart@metempsy.com              ICC_CTLR_EL1 icc_ctlr_el1_ns =
125013531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
125113531Sjairo.balart@metempsy.com
125213531Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(NS).EOImode is an alias of
125313531Sjairo.balart@metempsy.com              // ICC_CTLR_EL3.EOImode_EL1NS
125413531Sjairo.balart@metempsy.com              icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
125513531Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(S).EOImode is an alias of
125613531Sjairo.balart@metempsy.com              // ICC_CTLR_EL3.EOImode_EL1S
125713531Sjairo.balart@metempsy.com              icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
125813531Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
125913580Sgabeblack@google.com              icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
126013531Sjairo.balart@metempsy.com              // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
126113531Sjairo.balart@metempsy.com              icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
126213531Sjairo.balart@metempsy.com
126313531Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
126413531Sjairo.balart@metempsy.com              isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
126513531Sjairo.balart@metempsy.com                                      icc_ctlr_el1_ns);
126613531Sjairo.balart@metempsy.com          }
126713531Sjairo.balart@metempsy.com
126813531Sjairo.balart@metempsy.com          ICC_CTLR_EL3 icc_ctlr_el3 =
126913531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
127013531Sjairo.balart@metempsy.com
127113531Sjairo.balart@metempsy.com          icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
127213531Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
127313531Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
127413531Sjairo.balart@metempsy.com          icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
127513531Sjairo.balart@metempsy.com          icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
127613531Sjairo.balart@metempsy.com          icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
127713531Sjairo.balart@metempsy.com
127813531Sjairo.balart@metempsy.com          val = icc_ctlr_el3;
127913531Sjairo.balart@metempsy.com          break;
128013531Sjairo.balart@metempsy.com      }
128113531Sjairo.balart@metempsy.com
128213580Sgabeblack@google.com      // Priority Mask Register
128313531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR:
128413531Sjairo.balart@metempsy.com      case MISCREG_ICC_PMR_EL1: {
128513531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
128613531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_PMR_EL1, val);
128713531Sjairo.balart@metempsy.com          }
128813531Sjairo.balart@metempsy.com
128913531Sjairo.balart@metempsy.com          val &= 0xff;
129013531Sjairo.balart@metempsy.com          SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
129113531Sjairo.balart@metempsy.com
129213531Sjairo.balart@metempsy.com          if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
129313531Sjairo.balart@metempsy.com              // Spec section 4.8.1
129413531Sjairo.balart@metempsy.com              // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
129513531Sjairo.balart@metempsy.com              RegVal old_icc_pmr_el1 =
129613531Sjairo.balart@metempsy.com                  isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);
129713531Sjairo.balart@metempsy.com
129813531Sjairo.balart@metempsy.com              if (!(old_icc_pmr_el1 & 0x80)) {
129913531Sjairo.balart@metempsy.com                  // If the current priority mask value is in the range of
130013531Sjairo.balart@metempsy.com                  // 0x00-0x7F then WI
130113531Sjairo.balart@metempsy.com                  return;
130213531Sjairo.balart@metempsy.com              }
130313531Sjairo.balart@metempsy.com
130413531Sjairo.balart@metempsy.com              // If the current priority mask value is in the range of
130513531Sjairo.balart@metempsy.com              // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
130613531Sjairo.balart@metempsy.com              // based on the Non-secure read of the priority mask value
130713531Sjairo.balart@metempsy.com              // written to the register.
130813531Sjairo.balart@metempsy.com
130913580Sgabeblack@google.com              val = (val >> 1) | 0x80;
131013531Sjairo.balart@metempsy.com          }
131113531Sjairo.balart@metempsy.com
131213531Sjairo.balart@metempsy.com          val &= ~0U << (8 - PRIORITY_BITS);
131313531Sjairo.balart@metempsy.com          break;
131413531Sjairo.balart@metempsy.com      }
131513531Sjairo.balart@metempsy.com
131613531Sjairo.balart@metempsy.com      case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
131713531Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
131813531Sjairo.balart@metempsy.com             isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
131913531Sjairo.balart@metempsy.com          ich_vmcr_el2.VPMR = val & 0xff;
132013531Sjairo.balart@metempsy.com
132113531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
132213531Sjairo.balart@metempsy.com          virtualUpdate();
132313531Sjairo.balart@metempsy.com          return;
132413531Sjairo.balart@metempsy.com      }
132513531Sjairo.balart@metempsy.com
132613531Sjairo.balart@metempsy.com      // Interrupt Group 0 Enable Register EL1
132713531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0:
132813531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN0_EL1: {
132913580Sgabeblack@google.com          if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
133013531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
133113531Sjairo.balart@metempsy.com          }
133213531Sjairo.balart@metempsy.com
133313531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1, val);
133413531Sjairo.balart@metempsy.com          updateDistributor();
133513531Sjairo.balart@metempsy.com          return;
133613531Sjairo.balart@metempsy.com      }
133713531Sjairo.balart@metempsy.com
133813531Sjairo.balart@metempsy.com      // Virtual Interrupt Group 0 Enable register
133913531Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN0_EL1: {
134013531Sjairo.balart@metempsy.com          bool enable = val & 0x1;
134113531Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
134213531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
134313531Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG0 = enable;
134413531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
134513531Sjairo.balart@metempsy.com          virtualUpdate();
134613531Sjairo.balart@metempsy.com          return;
134713531Sjairo.balart@metempsy.com      }
134813531Sjairo.balart@metempsy.com
134913531Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register EL1
135013531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1:
135113531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL1: {
135213531Sjairo.balart@metempsy.com          if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
135313531Sjairo.balart@metempsy.com              return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
135413531Sjairo.balart@metempsy.com          }
135513531Sjairo.balart@metempsy.com
135613531Sjairo.balart@metempsy.com          setBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1, val);
135713531Sjairo.balart@metempsy.com          updateDistributor();
135813531Sjairo.balart@metempsy.com          return;
135913531Sjairo.balart@metempsy.com      }
136013531Sjairo.balart@metempsy.com
136113531Sjairo.balart@metempsy.com      // Virtual Interrupt Group 1 Enable register
136213531Sjairo.balart@metempsy.com      case MISCREG_ICV_IGRPEN1_EL1: {
136313531Sjairo.balart@metempsy.com          bool enable = val & 0x1;
136413531Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
136513531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
136613531Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG1 = enable;
136713531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
136813531Sjairo.balart@metempsy.com          virtualUpdate();
136913531Sjairo.balart@metempsy.com          return;
137013531Sjairo.balart@metempsy.com      }
137113531Sjairo.balart@metempsy.com
137213531Sjairo.balart@metempsy.com      // Interrupt Group 1 Enable register
137313531Sjairo.balart@metempsy.com      case MISCREG_ICC_MGRPEN1:
137413531Sjairo.balart@metempsy.com      case MISCREG_ICC_IGRPEN1_EL3: {
137513531Sjairo.balart@metempsy.com          ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
137613531Sjairo.balart@metempsy.com
137713531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(
137813531Sjairo.balart@metempsy.com              MISCREG_ICC_IGRPEN1_EL1_S, icc_igrpen1_el3.EnableGrp1S);
137913531Sjairo.balart@metempsy.com          isa->setMiscRegNoEffect(
138013531Sjairo.balart@metempsy.com              MISCREG_ICC_IGRPEN1_EL1_NS, icc_igrpen1_el3.EnableGrp1NS);
138113531Sjairo.balart@metempsy.com          updateDistributor();
138213531Sjairo.balart@metempsy.com          return;
138313531Sjairo.balart@metempsy.com      }
138413531Sjairo.balart@metempsy.com
138513531Sjairo.balart@metempsy.com      // Software Generated Interrupt Group 0 Register
138613531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R:
138713531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI0R_EL1:
138813531Sjairo.balart@metempsy.com        generateSGI(val, Gicv3::G0S);
138913531Sjairo.balart@metempsy.com        break;
139013531Sjairo.balart@metempsy.com
139113531Sjairo.balart@metempsy.com      // Software Generated Interrupt Group 1 Register
139213531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI1R:
139313531Sjairo.balart@metempsy.com      case MISCREG_ICC_SGI1R_EL1: {
139413531Sjairo.balart@metempsy.com        Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
139513531Sjairo.balart@metempsy.com
139613531Sjairo.balart@metempsy.com        generateSGI(val, group);
139713531Sjairo.balart@metempsy.com        break;
139813531Sjairo.balart@metempsy.com      }
139913531Sjairo.balart@metempsy.com
140013531Sjairo.balart@metempsy.com      // Alias Software Generated Interrupt Group 1 Register
140113531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R:
140213531Sjairo.balart@metempsy.com      case MISCREG_ICC_ASGI1R_EL1: {
140313531Sjairo.balart@metempsy.com        Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S;
140413531Sjairo.balart@metempsy.com
140513531Sjairo.balart@metempsy.com        generateSGI(val, group);
140613531Sjairo.balart@metempsy.com        break;
140713531Sjairo.balart@metempsy.com      }
140813531Sjairo.balart@metempsy.com
140913531Sjairo.balart@metempsy.com      // System Register Enable Register EL1
141013531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE:
141113531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL1:
141213531Sjairo.balart@metempsy.com      // System Register Enable Register EL2
141313531Sjairo.balart@metempsy.com      case MISCREG_ICC_HSRE:
141413531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL2:
141513531Sjairo.balart@metempsy.com      // System Register Enable Register EL3
141613531Sjairo.balart@metempsy.com      case MISCREG_ICC_MSRE:
141713531Sjairo.balart@metempsy.com      case MISCREG_ICC_SRE_EL3:
141813531Sjairo.balart@metempsy.com        // All bits are RAO/WI
141913531Sjairo.balart@metempsy.com        return;
142013531Sjairo.balart@metempsy.com
142113531Sjairo.balart@metempsy.com      // Hyp Control Register
142213531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR:
142313531Sjairo.balart@metempsy.com      case MISCREG_ICH_HCR_EL2: {
142413531Sjairo.balart@metempsy.com        ICH_HCR_EL2 requested_ich_hcr_el2 = val;
142513531Sjairo.balart@metempsy.com        ICH_HCR_EL2 ich_hcr_el2 =
142613531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
142713531Sjairo.balart@metempsy.com
142813531Sjairo.balart@metempsy.com        if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
142913531Sjairo.balart@metempsy.com        {
143013531Sjairo.balart@metempsy.com            // EOIcount - Permitted behaviors are:
143113531Sjairo.balart@metempsy.com            // - Increment EOIcount.
143213580Sgabeblack@google.com            // - Leave EOIcount unchanged.
143313531Sjairo.balart@metempsy.com            ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
143413531Sjairo.balart@metempsy.com        }
143513531Sjairo.balart@metempsy.com
143613531Sjairo.balart@metempsy.com        ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
143713531Sjairo.balart@metempsy.com        ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
143813531Sjairo.balart@metempsy.com        ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
143913531Sjairo.balart@metempsy.com        ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
144013531Sjairo.balart@metempsy.com        ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
144113531Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
144213531Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
144313531Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
144413531Sjairo.balart@metempsy.com        ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
144513531Sjairo.balart@metempsy.com        ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
144613531Sjairo.balart@metempsy.com        ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
144713531Sjairo.balart@metempsy.com        ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
144813531Sjairo.balart@metempsy.com        ich_hcr_el2.En = requested_ich_hcr_el2.En;
144913531Sjairo.balart@metempsy.com        val = ich_hcr_el2;
145013531Sjairo.balart@metempsy.com        do_virtual_update = true;
145113531Sjairo.balart@metempsy.com        break;
145213531Sjairo.balart@metempsy.com      }
145313531Sjairo.balart@metempsy.com
145413531Sjairo.balart@metempsy.com      // List Registers
145513531Sjairo.balart@metempsy.com      case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
145613531Sjairo.balart@metempsy.com        // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
145713531Sjairo.balart@metempsy.com        ICH_LRC requested_ich_lrc = val;
145813531Sjairo.balart@metempsy.com        ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
145913531Sjairo.balart@metempsy.com
146013531Sjairo.balart@metempsy.com        ich_lrc.State = requested_ich_lrc.State;
146113531Sjairo.balart@metempsy.com        ich_lrc.HW = requested_ich_lrc.HW;
146213531Sjairo.balart@metempsy.com        ich_lrc.Group = requested_ich_lrc.Group;
146313531Sjairo.balart@metempsy.com
146413531Sjairo.balart@metempsy.com        // Priority, bits [23:16]
146513531Sjairo.balart@metempsy.com        // At least five bits must be implemented.
146613531Sjairo.balart@metempsy.com        // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
146713531Sjairo.balart@metempsy.com        // We implement 5 bits.
146813531Sjairo.balart@metempsy.com        ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
146913531Sjairo.balart@metempsy.com                           (ich_lrc.Priority & 0x07);
147013531Sjairo.balart@metempsy.com
147113531Sjairo.balart@metempsy.com        // pINTID, bits [12:0]
147213531Sjairo.balart@metempsy.com        // When ICH_LR<n>.HW is 0 this field has the following meaning:
147313531Sjairo.balart@metempsy.com        // - Bits[12:10] : RES0.
147413531Sjairo.balart@metempsy.com        // - Bit[9] : EOI.
147513531Sjairo.balart@metempsy.com        // - Bits[8:0] : RES0.
147613580Sgabeblack@google.com        // When ICH_LR<n>.HW is 1:
147713531Sjairo.balart@metempsy.com        // - This field is only required to implement enough bits to hold a
147813531Sjairo.balart@metempsy.com        // valid value for the implemented INTID size. Any unused higher
147913531Sjairo.balart@metempsy.com        // order bits are RES0.
148013531Sjairo.balart@metempsy.com        if (requested_ich_lrc.HW == 0) {
148113531Sjairo.balart@metempsy.com            ich_lrc.EOI = requested_ich_lrc.EOI;
148213531Sjairo.balart@metempsy.com        } else {
148313531Sjairo.balart@metempsy.com            ich_lrc.pINTID = requested_ich_lrc.pINTID;
148413580Sgabeblack@google.com        }
148513531Sjairo.balart@metempsy.com
148613531Sjairo.balart@metempsy.com        val = ich_lrc;
148713531Sjairo.balart@metempsy.com        do_virtual_update = true;
148813531Sjairo.balart@metempsy.com        break;
148913531Sjairo.balart@metempsy.com      }
149013531Sjairo.balart@metempsy.com
149113531Sjairo.balart@metempsy.com      // List Registers
149213531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
149313531Sjairo.balart@metempsy.com          // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
149413531Sjairo.balart@metempsy.com          RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
149513531Sjairo.balart@metempsy.com          val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
149613531Sjairo.balart@metempsy.com          do_virtual_update = true;
149713531Sjairo.balart@metempsy.com          break;
149813531Sjairo.balart@metempsy.com      }
149913531Sjairo.balart@metempsy.com
150013531Sjairo.balart@metempsy.com      // List Registers
150113531Sjairo.balart@metempsy.com      case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
150213531Sjairo.balart@metempsy.com          ICH_LR_EL2 requested_ich_lr_el2 = val;
150313531Sjairo.balart@metempsy.com          ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
150413531Sjairo.balart@metempsy.com
150513531Sjairo.balart@metempsy.com          ich_lr_el2.State = requested_ich_lr_el2.State;
150613531Sjairo.balart@metempsy.com          ich_lr_el2.HW = requested_ich_lr_el2.HW;
150713531Sjairo.balart@metempsy.com          ich_lr_el2.Group = requested_ich_lr_el2.Group;
150813531Sjairo.balart@metempsy.com
150913531Sjairo.balart@metempsy.com          // Priority, bits [55:48]
151013531Sjairo.balart@metempsy.com          // At least five bits must be implemented.
151113531Sjairo.balart@metempsy.com          // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
151213531Sjairo.balart@metempsy.com          // We implement 5 bits.
151313531Sjairo.balart@metempsy.com          ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
151413531Sjairo.balart@metempsy.com                                (ich_lr_el2.Priority & 0x07);
151513531Sjairo.balart@metempsy.com
151613531Sjairo.balart@metempsy.com          // pINTID, bits [44:32]
151713531Sjairo.balart@metempsy.com          // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
151813531Sjairo.balart@metempsy.com          // - Bits[44:42] : RES0.
151913531Sjairo.balart@metempsy.com          // - Bit[41] : EOI.
152013531Sjairo.balart@metempsy.com          // - Bits[40:32] : RES0.
152113531Sjairo.balart@metempsy.com          // When ICH_LR<n>_EL2.HW is 1:
152213531Sjairo.balart@metempsy.com          // - This field is only required to implement enough bits to hold a
152313531Sjairo.balart@metempsy.com          // valid value for the implemented INTID size. Any unused higher
152413531Sjairo.balart@metempsy.com          // order bits are RES0.
152513531Sjairo.balart@metempsy.com          if (requested_ich_lr_el2.HW == 0) {
152613531Sjairo.balart@metempsy.com              ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
152713531Sjairo.balart@metempsy.com          } else {
152813531Sjairo.balart@metempsy.com              ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
152913531Sjairo.balart@metempsy.com          }
153013531Sjairo.balart@metempsy.com
153113531Sjairo.balart@metempsy.com          // vINTID, bits [31:0]
153213531Sjairo.balart@metempsy.com          // It is IMPLEMENTATION DEFINED how many bits are implemented,
153313531Sjairo.balart@metempsy.com          // though at least 16 bits must be implemented.
153413531Sjairo.balart@metempsy.com          // Unimplemented bits are RES0.
153513531Sjairo.balart@metempsy.com          ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
153613531Sjairo.balart@metempsy.com
153713531Sjairo.balart@metempsy.com          val = ich_lr_el2;
153813531Sjairo.balart@metempsy.com          do_virtual_update = true;
153913531Sjairo.balart@metempsy.com          break;
154013531Sjairo.balart@metempsy.com      }
154113531Sjairo.balart@metempsy.com
154213580Sgabeblack@google.com      // Virtual Machine Control Register
154313531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR:
154413531Sjairo.balart@metempsy.com      case MISCREG_ICH_VMCR_EL2: {
154513531Sjairo.balart@metempsy.com          ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
154613531Sjairo.balart@metempsy.com          ICH_VMCR_EL2 ich_vmcr_el2 =
154713531Sjairo.balart@metempsy.com              isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
154813531Sjairo.balart@metempsy.com          ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
154913531Sjairo.balart@metempsy.com          uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
155013531Sjairo.balart@metempsy.com
155113531Sjairo.balart@metempsy.com          if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
155213531Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = min_vpr0;
155313531Sjairo.balart@metempsy.com          } else {
155413531Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
155513531Sjairo.balart@metempsy.com          }
155613531Sjairo.balart@metempsy.com
155713531Sjairo.balart@metempsy.com          uint8_t min_vpr1 = min_vpr0 + 1;
155813531Sjairo.balart@metempsy.com
155913531Sjairo.balart@metempsy.com          if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
156013531Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = min_vpr1;
156113531Sjairo.balart@metempsy.com          } else {
156213531Sjairo.balart@metempsy.com              ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
156313531Sjairo.balart@metempsy.com          }
156413531Sjairo.balart@metempsy.com
156513531Sjairo.balart@metempsy.com          ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
156613531Sjairo.balart@metempsy.com          ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
156713531Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
156813531Sjairo.balart@metempsy.com          ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
156913531Sjairo.balart@metempsy.com          val = ich_vmcr_el2;
157013531Sjairo.balart@metempsy.com          break;
157113531Sjairo.balart@metempsy.com      }
157213531Sjairo.balart@metempsy.com
157313531Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 0 Registers
157413531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0:
157513531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R0_EL2:
157613531Sjairo.balart@metempsy.com        break;
157713531Sjairo.balart@metempsy.com
157813531Sjairo.balart@metempsy.com      // only implemented if supporting 6 or more bits of priority
157913531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R1:
158013531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R1_EL2:
158113531Sjairo.balart@metempsy.com      // only implemented if supporting 7 or more bits of priority
158213531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R2:
158313531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R2_EL2:
158413531Sjairo.balart@metempsy.com      // only implemented if supporting 7 or more bits of priority
158513531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R3:
158613531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP0R3_EL2:
158713531Sjairo.balart@metempsy.com        // Unimplemented registers are RAZ/WI
158813531Sjairo.balart@metempsy.com        return;
158913531Sjairo.balart@metempsy.com
159013531Sjairo.balart@metempsy.com      // Hyp Active Priorities Group 1 Registers
159113531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0:
159213531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R0_EL2:
159313531Sjairo.balart@metempsy.com        break;
159413531Sjairo.balart@metempsy.com
159513531Sjairo.balart@metempsy.com      // only implemented if supporting 6 or more bits of priority
159613531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R1:
159713531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R1_EL2:
159813531Sjairo.balart@metempsy.com      // only implemented if supporting 7 or more bits of priority
159913531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R2:
160013531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R2_EL2:
160113531Sjairo.balart@metempsy.com      // only implemented if supporting 7 or more bits of priority
160213531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R3:
160313531Sjairo.balart@metempsy.com      case MISCREG_ICH_AP1R3_EL2:
160413531Sjairo.balart@metempsy.com        // Unimplemented registers are RAZ/WI
160513531Sjairo.balart@metempsy.com        return;
160613531Sjairo.balart@metempsy.com
160713531Sjairo.balart@metempsy.com      default:
160813531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
160913531Sjairo.balart@metempsy.com              misc_reg, miscRegName[misc_reg]);
161013531Sjairo.balart@metempsy.com    }
161113531Sjairo.balart@metempsy.com
161213531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(misc_reg, val);
161313531Sjairo.balart@metempsy.com
161413531Sjairo.balart@metempsy.com    if (do_virtual_update) {
161513531Sjairo.balart@metempsy.com        virtualUpdate();
161613531Sjairo.balart@metempsy.com    }
161713531Sjairo.balart@metempsy.com}
161813531Sjairo.balart@metempsy.com
161913531Sjairo.balart@metempsy.comRegVal
162013531Sjairo.balart@metempsy.comGicv3CPUInterface::readBankedMiscReg(MiscRegIndex misc_reg) const
162113531Sjairo.balart@metempsy.com{
162213580Sgabeblack@google.com    return isa->readMiscRegNoEffect(
162313531Sjairo.balart@metempsy.com        isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()));
162413531Sjairo.balart@metempsy.com}
162513531Sjairo.balart@metempsy.com
162613531Sjairo.balart@metempsy.comvoid
162713531Sjairo.balart@metempsy.comGicv3CPUInterface::setBankedMiscReg(MiscRegIndex misc_reg, RegVal val) const
162813531Sjairo.balart@metempsy.com{
162913531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(
163013531Sjairo.balart@metempsy.com        isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()), val);
163113531Sjairo.balart@metempsy.com}
163213531Sjairo.balart@metempsy.com
163313531Sjairo.balart@metempsy.comint
163413531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualFindActive(uint32_t int_id) const
163513531Sjairo.balart@metempsy.com{
163613531Sjairo.balart@metempsy.com    for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
163713531Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
163813531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
163913531Sjairo.balart@metempsy.com
164013531Sjairo.balart@metempsy.com        if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
164113531Sjairo.balart@metempsy.com             (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
164213531Sjairo.balart@metempsy.com            (ich_lr_el2.vINTID == int_id)) {
164313531Sjairo.balart@metempsy.com            return lr_idx;
164413531Sjairo.balart@metempsy.com        }
164513531Sjairo.balart@metempsy.com    }
164613531Sjairo.balart@metempsy.com
164713531Sjairo.balart@metempsy.com    return -1;
164813531Sjairo.balart@metempsy.com}
164913531Sjairo.balart@metempsy.com
165013580Sgabeblack@google.comuint32_t
165113580Sgabeblack@google.comGicv3CPUInterface::getHPPIR0() const
165213531Sjairo.balart@metempsy.com{
165313531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
165413531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
165513531Sjairo.balart@metempsy.com    }
165613531Sjairo.balart@metempsy.com
165713531Sjairo.balart@metempsy.com    bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
165813531Sjairo.balart@metempsy.com
165913531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
166013531Sjairo.balart@metempsy.com        // interrupt for the other state pending
166113531Sjairo.balart@metempsy.com        return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
166213531Sjairo.balart@metempsy.com    }
166313531Sjairo.balart@metempsy.com
166413531Sjairo.balart@metempsy.com    if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
166513531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
166613531Sjairo.balart@metempsy.com    }
166713531Sjairo.balart@metempsy.com
166813531Sjairo.balart@metempsy.com    if (irq_is_secure && !inSecureState()) {
166913531Sjairo.balart@metempsy.com        // Secure interrupts not visible in Non-secure
167013531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
167113531Sjairo.balart@metempsy.com    }
167213531Sjairo.balart@metempsy.com
167313531Sjairo.balart@metempsy.com    return hppi.intid;
167413531Sjairo.balart@metempsy.com}
167513531Sjairo.balart@metempsy.com
167613531Sjairo.balart@metempsy.comuint32_t
167713531Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR1() const
167813531Sjairo.balart@metempsy.com{
167913531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
168013531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
168113531Sjairo.balart@metempsy.com    }
168213531Sjairo.balart@metempsy.com
168313531Sjairo.balart@metempsy.com    ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
168413531Sjairo.balart@metempsy.com    if ((currEL() == EL3) && icc_ctlr_el3.RM) {
168513580Sgabeblack@google.com        if (hppi.group == Gicv3::G0S) {
168613531Sjairo.balart@metempsy.com            return Gicv3::INTID_SECURE;
168713531Sjairo.balart@metempsy.com        } else if (hppi.group == Gicv3::G1NS) {
168813531Sjairo.balart@metempsy.com            return Gicv3::INTID_NONSECURE;
168913531Sjairo.balart@metempsy.com        }
169013531Sjairo.balart@metempsy.com    }
169113531Sjairo.balart@metempsy.com
169213531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G0S) {
169313531Sjairo.balart@metempsy.com        return Gicv3::INTID_SPURIOUS;
169413531Sjairo.balart@metempsy.com    }
169513531Sjairo.balart@metempsy.com
169613531Sjairo.balart@metempsy.com    bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
169713531Sjairo.balart@metempsy.com
169813531Sjairo.balart@metempsy.com    if (irq_is_secure) {
169913531Sjairo.balart@metempsy.com        if (!inSecureState()) {
170013531Sjairo.balart@metempsy.com            // Secure interrupts not visible in Non-secure
170113531Sjairo.balart@metempsy.com            return Gicv3::INTID_SPURIOUS;
170213531Sjairo.balart@metempsy.com        }
170313531Sjairo.balart@metempsy.com    } else if (!isEL3OrMon() && inSecureState()) {
170413531Sjairo.balart@metempsy.com        // Group 1 non-secure interrupts not visible in Secure EL1
170513580Sgabeblack@google.com        return Gicv3::INTID_SPURIOUS;
170613531Sjairo.balart@metempsy.com    }
170713531Sjairo.balart@metempsy.com
170813531Sjairo.balart@metempsy.com    return hppi.intid;
170913531Sjairo.balart@metempsy.com}
171013531Sjairo.balart@metempsy.com
171113531Sjairo.balart@metempsy.comvoid
171213531Sjairo.balart@metempsy.comGicv3CPUInterface::dropPriority(Gicv3::GroupId group)
171313531Sjairo.balart@metempsy.com{
171413580Sgabeblack@google.com    int apr_misc_reg = 0;
171513531Sjairo.balart@metempsy.com
171613531Sjairo.balart@metempsy.com    switch (group) {
171713531Sjairo.balart@metempsy.com      case Gicv3::G0S:
171813531Sjairo.balart@metempsy.com        apr_misc_reg = MISCREG_ICC_AP0R0_EL1;
171913531Sjairo.balart@metempsy.com        break;
172013531Sjairo.balart@metempsy.com      case Gicv3::G1S:
172113531Sjairo.balart@metempsy.com        apr_misc_reg = MISCREG_ICC_AP1R0_EL1_S;
172213531Sjairo.balart@metempsy.com        break;
172313531Sjairo.balart@metempsy.com      case Gicv3::G1NS:
172413531Sjairo.balart@metempsy.com        apr_misc_reg = MISCREG_ICC_AP1R0_EL1_NS;
172513531Sjairo.balart@metempsy.com        break;
172613531Sjairo.balart@metempsy.com      default:
172713531Sjairo.balart@metempsy.com        panic("Invalid Gicv3::GroupId");
172813531Sjairo.balart@metempsy.com    }
172913531Sjairo.balart@metempsy.com
173013531Sjairo.balart@metempsy.com    RegVal apr = isa->readMiscRegNoEffect(apr_misc_reg);
173113531Sjairo.balart@metempsy.com
173213531Sjairo.balart@metempsy.com    if (apr) {
173313531Sjairo.balart@metempsy.com        apr &= apr - 1;
173413531Sjairo.balart@metempsy.com        isa->setMiscRegNoEffect(apr_misc_reg, apr);
173513531Sjairo.balart@metempsy.com    }
173613531Sjairo.balart@metempsy.com
173713531Sjairo.balart@metempsy.com    update();
173813531Sjairo.balart@metempsy.com}
173913531Sjairo.balart@metempsy.com
174013531Sjairo.balart@metempsy.comuint8_t
174113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDropPriority()
174213580Sgabeblack@google.com{
174313531Sjairo.balart@metempsy.com    int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
174413531Sjairo.balart@metempsy.com
174513531Sjairo.balart@metempsy.com    for (int i = 0; i < apr_max; i++) {
174613531Sjairo.balart@metempsy.com        RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
174713531Sjairo.balart@metempsy.com        RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
174813531Sjairo.balart@metempsy.com
174913531Sjairo.balart@metempsy.com        if (!vapr0 && !vapr1) {
175013531Sjairo.balart@metempsy.com            continue;
175113531Sjairo.balart@metempsy.com        }
175213531Sjairo.balart@metempsy.com
175313531Sjairo.balart@metempsy.com        int vapr0_count = ctz32(vapr0);
175413531Sjairo.balart@metempsy.com        int vapr1_count = ctz32(vapr1);
175513531Sjairo.balart@metempsy.com
175613531Sjairo.balart@metempsy.com        if (vapr0_count <= vapr1_count) {
175713531Sjairo.balart@metempsy.com            vapr0 &= vapr0 - 1;
175813531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
175913531Sjairo.balart@metempsy.com            return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
176013531Sjairo.balart@metempsy.com        } else {
176113531Sjairo.balart@metempsy.com            vapr1 &= vapr1 - 1;
176213531Sjairo.balart@metempsy.com            isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
176313531Sjairo.balart@metempsy.com            return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
176413531Sjairo.balart@metempsy.com        }
176513531Sjairo.balart@metempsy.com    }
176613531Sjairo.balart@metempsy.com
176713531Sjairo.balart@metempsy.com    return 0xff;
176813531Sjairo.balart@metempsy.com}
176913531Sjairo.balart@metempsy.com
177013531Sjairo.balart@metempsy.comvoid
177113531Sjairo.balart@metempsy.comGicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
177213531Sjairo.balart@metempsy.com{
177313531Sjairo.balart@metempsy.com    uint8_t aff3 = bits(val, 55, 48);
177413531Sjairo.balart@metempsy.com    uint8_t aff2 = bits(val, 39, 32);
177513531Sjairo.balart@metempsy.com    uint8_t aff1 = bits(val, 23, 16);;
177613531Sjairo.balart@metempsy.com    uint16_t target_list = bits(val, 15, 0);
177713531Sjairo.balart@metempsy.com    uint32_t int_id = bits(val, 27, 24);
177813531Sjairo.balart@metempsy.com    bool irm = bits(val, 40, 40);
177913531Sjairo.balart@metempsy.com    uint8_t rs = bits(val, 47, 44);
178013531Sjairo.balart@metempsy.com
178113531Sjairo.balart@metempsy.com    bool ns = !inSecureState();
178213531Sjairo.balart@metempsy.com
178313531Sjairo.balart@metempsy.com    for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
178413531Sjairo.balart@metempsy.com        Gicv3Redistributor * redistributor_i =
178513531Sjairo.balart@metempsy.com            gic->getRedistributor(i);
178613531Sjairo.balart@metempsy.com        uint32_t affinity_i = redistributor_i->getAffinity();
178713531Sjairo.balart@metempsy.com
178813531Sjairo.balart@metempsy.com        if (irm) {
178913531Sjairo.balart@metempsy.com            // Interrupts routed to all PEs in the system,
179013531Sjairo.balart@metempsy.com            // excluding "self"
179113531Sjairo.balart@metempsy.com            if (affinity_i == redistributor->getAffinity()) {
179213531Sjairo.balart@metempsy.com                continue;
179313531Sjairo.balart@metempsy.com            }
179413531Sjairo.balart@metempsy.com        } else {
179513531Sjairo.balart@metempsy.com            // Interrupts routed to the PEs specified by
179613531Sjairo.balart@metempsy.com            // Aff3.Aff2.Aff1.<target list>
179713531Sjairo.balart@metempsy.com            if ((affinity_i >> 8) !=
179813531Sjairo.balart@metempsy.com                ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
179913531Sjairo.balart@metempsy.com                continue;
180013531Sjairo.balart@metempsy.com            }
180113531Sjairo.balart@metempsy.com
180213531Sjairo.balart@metempsy.com            uint8_t aff0_i = bits(affinity_i, 7, 0);
180313531Sjairo.balart@metempsy.com
180413531Sjairo.balart@metempsy.com            if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
180513531Sjairo.balart@metempsy.com                ((0x1 << (aff0_i - rs * 16)) & target_list))) {
180613531Sjairo.balart@metempsy.com                continue;
180713531Sjairo.balart@metempsy.com            }
180813531Sjairo.balart@metempsy.com        }
180913531Sjairo.balart@metempsy.com
181013531Sjairo.balart@metempsy.com        redistributor_i->sendSGI(int_id, group, ns);
181113531Sjairo.balart@metempsy.com    }
181213531Sjairo.balart@metempsy.com}
181313580Sgabeblack@google.com
181413531Sjairo.balart@metempsy.comvoid
181513531Sjairo.balart@metempsy.comGicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
181613531Sjairo.balart@metempsy.com{
181713531Sjairo.balart@metempsy.com    // Update active priority registers.
181813531Sjairo.balart@metempsy.com    uint32_t prio = hppi.prio & 0xf8;
181913531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - PRIORITY_BITS);
182013531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
182113531Sjairo.balart@metempsy.com
182213531Sjairo.balart@metempsy.com    int apr_idx = 0;
182313531Sjairo.balart@metempsy.com    switch (group) {
182413531Sjairo.balart@metempsy.com      case Gicv3::G0S:
182513531Sjairo.balart@metempsy.com        apr_idx = MISCREG_ICC_AP0R0_EL1;
182613531Sjairo.balart@metempsy.com        break;
182713531Sjairo.balart@metempsy.com      case Gicv3::G1S:
182813531Sjairo.balart@metempsy.com        apr_idx = MISCREG_ICC_AP1R0_EL1_S;
182913531Sjairo.balart@metempsy.com        break;
183013531Sjairo.balart@metempsy.com      case Gicv3::G1NS:
183113531Sjairo.balart@metempsy.com        apr_idx = MISCREG_ICC_AP1R0_EL1_NS;
183213531Sjairo.balart@metempsy.com        break;
183313531Sjairo.balart@metempsy.com      default:
183413531Sjairo.balart@metempsy.com        panic("Invalid Gicv3::GroupId");
183513531Sjairo.balart@metempsy.com    }
183613531Sjairo.balart@metempsy.com
183713531Sjairo.balart@metempsy.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
183813531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
183913531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
184013531Sjairo.balart@metempsy.com
184113531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
184213531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
184313531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
184413531Sjairo.balart@metempsy.com        redistributor->activateIRQ(int_id);
184513531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
184613531Sjairo.balart@metempsy.com        // SPI, distributor
184713531Sjairo.balart@metempsy.com        distributor->activateIRQ(int_id);
184813531Sjairo.balart@metempsy.com    } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
184913531Sjairo.balart@metempsy.com        // LPI, Redistributor
185013531Sjairo.balart@metempsy.com        redistributor->setClrLPI(int_id, false);
185113580Sgabeblack@google.com    }
185213531Sjairo.balart@metempsy.com
185313531Sjairo.balart@metempsy.com    // By setting the priority to 0xff we are effectively
185413531Sjairo.balart@metempsy.com    // making the int_id not pending anymore at the cpu
185513531Sjairo.balart@metempsy.com    // interface.
185613531Sjairo.balart@metempsy.com    hppi.prio = 0xff;
185713531Sjairo.balart@metempsy.com    updateDistributor();
185813531Sjairo.balart@metempsy.com}
185913531Sjairo.balart@metempsy.com
186013531Sjairo.balart@metempsy.comvoid
186113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
186213531Sjairo.balart@metempsy.com{
186313531Sjairo.balart@metempsy.com    // Update active priority registers.
186413531Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
186513531Sjairo.balart@metempsy.com            lr_idx);
186613531Sjairo.balart@metempsy.com    Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
186713531Sjairo.balart@metempsy.com    uint8_t prio = ich_lr_el.Priority & 0xf8;
186813531Sjairo.balart@metempsy.com    int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
186913531Sjairo.balart@metempsy.com    int reg_no = apr_bit / 32;
187013531Sjairo.balart@metempsy.com    int reg_bit = apr_bit % 32;
187113531Sjairo.balart@metempsy.com    int apr_idx = group == Gicv3::G0S ?
187213531Sjairo.balart@metempsy.com        MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
187313531Sjairo.balart@metempsy.com    RegVal apr = isa->readMiscRegNoEffect(apr_idx);
187413531Sjairo.balart@metempsy.com    apr |= (1 << reg_bit);
187513531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(apr_idx, apr);
187613531Sjairo.balart@metempsy.com    // Move interrupt state from pending to active.
187713531Sjairo.balart@metempsy.com    ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
187813531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
187913531Sjairo.balart@metempsy.com}
188013531Sjairo.balart@metempsy.com
188113531Sjairo.balart@metempsy.comvoid
188213531Sjairo.balart@metempsy.comGicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
188313531Sjairo.balart@metempsy.com{
188413531Sjairo.balart@metempsy.com    if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
188513531Sjairo.balart@metempsy.com        // SGI or PPI, redistributor
188613531Sjairo.balart@metempsy.com        redistributor->deactivateIRQ(int_id);
188713531Sjairo.balart@metempsy.com    } else if (int_id < Gicv3::INTID_SECURE) {
188813531Sjairo.balart@metempsy.com        // SPI, distributor
188913531Sjairo.balart@metempsy.com        distributor->deactivateIRQ(int_id);
189013531Sjairo.balart@metempsy.com    }
189113531Sjairo.balart@metempsy.com
189213531Sjairo.balart@metempsy.com    updateDistributor();
189313531Sjairo.balart@metempsy.com}
189413531Sjairo.balart@metempsy.com
189513531Sjairo.balart@metempsy.comvoid
189613531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
189713531Sjairo.balart@metempsy.com{
189813531Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
189913531Sjairo.balart@metempsy.com            lr_idx);
190013531Sjairo.balart@metempsy.com
190113531Sjairo.balart@metempsy.com    if (ich_lr_el2.HW) {
190213531Sjairo.balart@metempsy.com        // Deactivate the associated physical interrupt
190313531Sjairo.balart@metempsy.com        if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
190413531Sjairo.balart@metempsy.com            Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
190513531Sjairo.balart@metempsy.com                distributor->getIntGroup(ich_lr_el2.pINTID) :
190613531Sjairo.balart@metempsy.com                redistributor->getIntGroup(ich_lr_el2.pINTID);
190713531Sjairo.balart@metempsy.com            deactivateIRQ(ich_lr_el2.pINTID, group);
190813531Sjairo.balart@metempsy.com        }
190913531Sjairo.balart@metempsy.com    }
191013531Sjairo.balart@metempsy.com
191113531Sjairo.balart@metempsy.com    //  Remove the active bit
191213531Sjairo.balart@metempsy.com    ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
191313531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
191413531Sjairo.balart@metempsy.com}
191513531Sjairo.balart@metempsy.com
191613531Sjairo.balart@metempsy.com/*
191713531Sjairo.balart@metempsy.com * Returns the priority group field for the current BPR value for the group.
191813531Sjairo.balart@metempsy.com * GroupBits() Pseudocode from spec.
191913580Sgabeblack@google.com */
192013531Sjairo.balart@metempsy.comuint32_t
192113531Sjairo.balart@metempsy.comGicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
192213531Sjairo.balart@metempsy.com{
192313531Sjairo.balart@metempsy.com    ICC_CTLR_EL1 icc_ctlr_el1_s =
192413531Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
192513531Sjairo.balart@metempsy.com    ICC_CTLR_EL1 icc_ctlr_el1_ns =
192613531Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
192713531Sjairo.balart@metempsy.com
192813531Sjairo.balart@metempsy.com    if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
192913531Sjairo.balart@metempsy.com        (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
193013531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
193113580Sgabeblack@google.com    }
193213531Sjairo.balart@metempsy.com
193313531Sjairo.balart@metempsy.com    int bpr;
193413531Sjairo.balart@metempsy.com
193513531Sjairo.balart@metempsy.com    if (group == Gicv3::G0S) {
193613531Sjairo.balart@metempsy.com        bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
193713531Sjairo.balart@metempsy.com    } else if (group == Gicv3::G1S) {
193813531Sjairo.balart@metempsy.com        bpr = bpr1(Gicv3::G1S) & 0x7;
193913531Sjairo.balart@metempsy.com    } else {
194013531Sjairo.balart@metempsy.com        bpr = bpr1(Gicv3::G1NS) & 0x7;
194113531Sjairo.balart@metempsy.com    }
194213531Sjairo.balart@metempsy.com
194313531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS) {
194413531Sjairo.balart@metempsy.com        assert(bpr > 0);
194513531Sjairo.balart@metempsy.com        bpr--;
194613531Sjairo.balart@metempsy.com    }
194713531Sjairo.balart@metempsy.com
194813531Sjairo.balart@metempsy.com    return ~0U << (bpr + 1);
194913531Sjairo.balart@metempsy.com}
195013531Sjairo.balart@metempsy.com
195113531Sjairo.balart@metempsy.comuint32_t
195213531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
195313531Sjairo.balart@metempsy.com{
195413531Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 =
195513531Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
195613531Sjairo.balart@metempsy.com
195713531Sjairo.balart@metempsy.com    if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
195813531Sjairo.balart@metempsy.com        group = Gicv3::G0S;
195913531Sjairo.balart@metempsy.com    }
196013531Sjairo.balart@metempsy.com
196113580Sgabeblack@google.com    int bpr;
196213531Sjairo.balart@metempsy.com
196313531Sjairo.balart@metempsy.com    if (group == Gicv3::G0S) {
196413531Sjairo.balart@metempsy.com        bpr = ich_vmcr_el2.VBPR0;
196513531Sjairo.balart@metempsy.com    } else {
196613531Sjairo.balart@metempsy.com        bpr = ich_vmcr_el2.VBPR1;
196713531Sjairo.balart@metempsy.com    }
196813531Sjairo.balart@metempsy.com
196913531Sjairo.balart@metempsy.com    if (group == Gicv3::G1NS) {
197013531Sjairo.balart@metempsy.com        assert(bpr > 0);
197113580Sgabeblack@google.com        bpr--;
197213531Sjairo.balart@metempsy.com    }
197313531Sjairo.balart@metempsy.com
197413531Sjairo.balart@metempsy.com    return ~0U << (bpr + 1);
197513531Sjairo.balart@metempsy.com}
197613531Sjairo.balart@metempsy.com
197713531Sjairo.balart@metempsy.combool
197813531Sjairo.balart@metempsy.comGicv3CPUInterface::isEOISplitMode() const
197913531Sjairo.balart@metempsy.com{
198013531Sjairo.balart@metempsy.com    if (isEL3OrMon()) {
198113531Sjairo.balart@metempsy.com        ICC_CTLR_EL3 icc_ctlr_el3 =
198213531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
198313531Sjairo.balart@metempsy.com        return icc_ctlr_el3.EOImode_EL3;
198413531Sjairo.balart@metempsy.com    } else {
198513531Sjairo.balart@metempsy.com        ICC_CTLR_EL1 icc_ctlr_el1 = 0;
198613531Sjairo.balart@metempsy.com        if (inSecureState())
198713531Sjairo.balart@metempsy.com            icc_ctlr_el1 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
198813531Sjairo.balart@metempsy.com        else
198913531Sjairo.balart@metempsy.com            icc_ctlr_el1 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
199013531Sjairo.balart@metempsy.com        return icc_ctlr_el1.EOImode;
199113531Sjairo.balart@metempsy.com    }
199213531Sjairo.balart@metempsy.com}
199313531Sjairo.balart@metempsy.com
199413531Sjairo.balart@metempsy.combool
199513531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIsEOISplitMode() const
199613531Sjairo.balart@metempsy.com{
199713531Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
199813531Sjairo.balart@metempsy.com    return ich_vmcr_el2.VEOIM;
199913531Sjairo.balart@metempsy.com}
200013531Sjairo.balart@metempsy.com
200113531Sjairo.balart@metempsy.comint
200213531Sjairo.balart@metempsy.comGicv3CPUInterface::highestActiveGroup() const
200313531Sjairo.balart@metempsy.com{
200413531Sjairo.balart@metempsy.com    int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
200513580Sgabeblack@google.com    int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
200613531Sjairo.balart@metempsy.com    int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));
200713531Sjairo.balart@metempsy.com
200813531Sjairo.balart@metempsy.com    if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
200913531Sjairo.balart@metempsy.com        return Gicv3::G1NS;
201013531Sjairo.balart@metempsy.com    }
201113531Sjairo.balart@metempsy.com
201213531Sjairo.balart@metempsy.com    if (gq_ctz < g0_ctz) {
201313531Sjairo.balart@metempsy.com        return Gicv3::G1S;
201413531Sjairo.balart@metempsy.com    }
201513531Sjairo.balart@metempsy.com
201613531Sjairo.balart@metempsy.com    if (g0_ctz < 32) {
201713531Sjairo.balart@metempsy.com        return Gicv3::G0S;
201813531Sjairo.balart@metempsy.com    }
201913531Sjairo.balart@metempsy.com
202013531Sjairo.balart@metempsy.com    return -1;
202113531Sjairo.balart@metempsy.com}
202213531Sjairo.balart@metempsy.com
202313531Sjairo.balart@metempsy.comvoid
202413531Sjairo.balart@metempsy.comGicv3CPUInterface::updateDistributor()
202513531Sjairo.balart@metempsy.com{
202613531Sjairo.balart@metempsy.com    distributor->update();
202713531Sjairo.balart@metempsy.com}
202813531Sjairo.balart@metempsy.com
202913531Sjairo.balart@metempsy.comvoid
203013531Sjairo.balart@metempsy.comGicv3CPUInterface::update()
203113531Sjairo.balart@metempsy.com{
203213531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
203313531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
203413531Sjairo.balart@metempsy.com
203513531Sjairo.balart@metempsy.com    if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
203613531Sjairo.balart@metempsy.com        /*
203713531Sjairo.balart@metempsy.com         * Secure enabled GIC sending a G1S IRQ to a secure disabled
203813531Sjairo.balart@metempsy.com         * CPU -> send G0 IRQ
203913531Sjairo.balart@metempsy.com         */
204013531Sjairo.balart@metempsy.com        hppi.group = Gicv3::G0S;
204113531Sjairo.balart@metempsy.com    }
204213531Sjairo.balart@metempsy.com
204313580Sgabeblack@google.com    if (hppiCanPreempt()) {
204413531Sjairo.balart@metempsy.com        ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
204513531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::update(): "
204613531Sjairo.balart@metempsy.com                "posting int as %d!\n", int_type);
204713531Sjairo.balart@metempsy.com        int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
204813531Sjairo.balart@metempsy.com    }
204913531Sjairo.balart@metempsy.com
205013531Sjairo.balart@metempsy.com    if (signal_IRQ) {
205113531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_IRQ);
205213531Sjairo.balart@metempsy.com    } else {
205313531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_IRQ);
205413531Sjairo.balart@metempsy.com    }
205513531Sjairo.balart@metempsy.com
205613531Sjairo.balart@metempsy.com    if (signal_FIQ) {
205713531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_FIQ);
205813531Sjairo.balart@metempsy.com    } else {
205913531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_FIQ);
206013531Sjairo.balart@metempsy.com    }
206113531Sjairo.balart@metempsy.com}
206213580Sgabeblack@google.com
206313531Sjairo.balart@metempsy.comvoid
206413531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualUpdate()
206513531Sjairo.balart@metempsy.com{
206613531Sjairo.balart@metempsy.com    bool signal_IRQ = false;
206713531Sjairo.balart@metempsy.com    bool signal_FIQ = false;
206813531Sjairo.balart@metempsy.com    int lr_idx = getHPPVILR();
206913531Sjairo.balart@metempsy.com
207013531Sjairo.balart@metempsy.com    if (lr_idx >= 0) {
207113531Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
207213531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
207313531Sjairo.balart@metempsy.com
207413531Sjairo.balart@metempsy.com        if (hppviCanPreempt(lr_idx)) {
207513531Sjairo.balart@metempsy.com            if (ich_lr_el2.Group) {
207613531Sjairo.balart@metempsy.com                signal_IRQ = true;
207713531Sjairo.balart@metempsy.com            } else {
207813531Sjairo.balart@metempsy.com                signal_FIQ = true;
207913531Sjairo.balart@metempsy.com            }
208013531Sjairo.balart@metempsy.com        }
208113531Sjairo.balart@metempsy.com    }
208213531Sjairo.balart@metempsy.com
208313531Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
208413531Sjairo.balart@metempsy.com
208513531Sjairo.balart@metempsy.com    if (ich_hcr_el2.En) {
208613531Sjairo.balart@metempsy.com        if (maintenanceInterruptStatus()) {
208713531Sjairo.balart@metempsy.com            maintenanceInterrupt->raise();
208813531Sjairo.balart@metempsy.com        }
208913531Sjairo.balart@metempsy.com    }
209013531Sjairo.balart@metempsy.com
209113531Sjairo.balart@metempsy.com    if (signal_IRQ) {
209213531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
209313531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
209413531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ);
209513531Sjairo.balart@metempsy.com    } else {
209613531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ);
209713531Sjairo.balart@metempsy.com    }
209813531Sjairo.balart@metempsy.com
209913531Sjairo.balart@metempsy.com    if (signal_FIQ) {
210013531Sjairo.balart@metempsy.com        DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
210113531Sjairo.balart@metempsy.com                "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
210213531Sjairo.balart@metempsy.com        gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ);
210313531Sjairo.balart@metempsy.com    } else {
210413531Sjairo.balart@metempsy.com        gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ);
210513531Sjairo.balart@metempsy.com    }
210613531Sjairo.balart@metempsy.com}
210713531Sjairo.balart@metempsy.com
210813531Sjairo.balart@metempsy.com// Returns the index of the LR with the HPPI
210913531Sjairo.balart@metempsy.comint
211013531Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPVILR() const
211113531Sjairo.balart@metempsy.com{
211213531Sjairo.balart@metempsy.com    int idx = -1;
211313531Sjairo.balart@metempsy.com    ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
211413531Sjairo.balart@metempsy.com
211513531Sjairo.balart@metempsy.com    if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
211613531Sjairo.balart@metempsy.com        // VG0 and VG1 disabled...
211713531Sjairo.balart@metempsy.com        return idx;
211813531Sjairo.balart@metempsy.com    }
211913531Sjairo.balart@metempsy.com
212013531Sjairo.balart@metempsy.com    uint8_t highest_prio = 0xff;
212113531Sjairo.balart@metempsy.com
212213531Sjairo.balart@metempsy.com    for (int i = 0; i < 16; i++) {
212313531Sjairo.balart@metempsy.com        ICH_LR_EL2 ich_lr_el2 =
212413531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
212513531Sjairo.balart@metempsy.com
212613531Sjairo.balart@metempsy.com        if (ich_lr_el2.State != Gicv3::INT_PENDING) {
212713531Sjairo.balart@metempsy.com            continue;
212813531Sjairo.balart@metempsy.com        }
212913531Sjairo.balart@metempsy.com
213013531Sjairo.balart@metempsy.com        if (ich_lr_el2.Group) {
213113531Sjairo.balart@metempsy.com            // VG1
213213531Sjairo.balart@metempsy.com            if (!ich_vmcr_el2.VENG1) {
213313531Sjairo.balart@metempsy.com                continue;
213413531Sjairo.balart@metempsy.com            }
213513531Sjairo.balart@metempsy.com        } else {
213613531Sjairo.balart@metempsy.com            // VG0
213713531Sjairo.balart@metempsy.com            if (!ich_vmcr_el2.VENG0) {
213813531Sjairo.balart@metempsy.com                continue;
213913531Sjairo.balart@metempsy.com            }
214013531Sjairo.balart@metempsy.com        }
214113531Sjairo.balart@metempsy.com
214213531Sjairo.balart@metempsy.com        uint8_t prio = ich_lr_el2.Priority;
214313531Sjairo.balart@metempsy.com
214413531Sjairo.balart@metempsy.com        if (prio < highest_prio) {
214513531Sjairo.balart@metempsy.com            highest_prio = prio;
214613531Sjairo.balart@metempsy.com            idx = i;
214713531Sjairo.balart@metempsy.com        }
214813531Sjairo.balart@metempsy.com    }
214913531Sjairo.balart@metempsy.com
215013531Sjairo.balart@metempsy.com    return idx;
215113531Sjairo.balart@metempsy.com}
215213531Sjairo.balart@metempsy.com
215313531Sjairo.balart@metempsy.combool
215413531Sjairo.balart@metempsy.comGicv3CPUInterface::hppviCanPreempt(int lr_idx) const
215513531Sjairo.balart@metempsy.com{
215613531Sjairo.balart@metempsy.com    ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
215713531Sjairo.balart@metempsy.com    if (!ich_hcr_el2.En) {
215813531Sjairo.balart@metempsy.com        // virtual interface is disabled
215913531Sjairo.balart@metempsy.com        return false;
216013531Sjairo.balart@metempsy.com    }
216113531Sjairo.balart@metempsy.com
216213531Sjairo.balart@metempsy.com    ICH_LR_EL2 ich_lr_el2 =
216313531Sjairo.balart@metempsy.com        isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
216413531Sjairo.balart@metempsy.com    uint8_t prio = ich_lr_el2.Priority;
216513531Sjairo.balart@metempsy.com    uint8_t vpmr =
216613531Sjairo.balart@metempsy.com        bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);
216713531Sjairo.balart@metempsy.com
216813531Sjairo.balart@metempsy.com    if (prio >= vpmr) {
216913531Sjairo.balart@metempsy.com        // prioriry masked
217013531Sjairo.balart@metempsy.com        return false;
217113531Sjairo.balart@metempsy.com    }
217213531Sjairo.balart@metempsy.com
217313531Sjairo.balart@metempsy.com    uint8_t rprio = virtualHighestActivePriority();
217413531Sjairo.balart@metempsy.com
217513531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
217613531Sjairo.balart@metempsy.com        return true;
217713531Sjairo.balart@metempsy.com    }
217813531Sjairo.balart@metempsy.com
217913531Sjairo.balart@metempsy.com    Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
218013531Sjairo.balart@metempsy.com    uint32_t prio_mask = virtualGroupPriorityMask(group);
218113531Sjairo.balart@metempsy.com
218213531Sjairo.balart@metempsy.com    if ((prio & prio_mask) < (rprio & prio_mask)) {
218313531Sjairo.balart@metempsy.com        return true;
218413531Sjairo.balart@metempsy.com    }
218513531Sjairo.balart@metempsy.com
218613531Sjairo.balart@metempsy.com    return false;
218713531Sjairo.balart@metempsy.com}
218813531Sjairo.balart@metempsy.com
218913531Sjairo.balart@metempsy.comuint8_t
219013531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualHighestActivePriority() const
219113531Sjairo.balart@metempsy.com{
219213531Sjairo.balart@metempsy.com    uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
219313531Sjairo.balart@metempsy.com
219413531Sjairo.balart@metempsy.com    for (int i = 0; i < num_aprs; i++) {
219513531Sjairo.balart@metempsy.com        RegVal vapr =
219613531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
219713531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
219813531Sjairo.balart@metempsy.com
219913531Sjairo.balart@metempsy.com        if (!vapr) {
220013531Sjairo.balart@metempsy.com            continue;
220113531Sjairo.balart@metempsy.com        }
220213531Sjairo.balart@metempsy.com
220313531Sjairo.balart@metempsy.com        return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
220413531Sjairo.balart@metempsy.com    }
220513531Sjairo.balart@metempsy.com
220613531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
220713531Sjairo.balart@metempsy.com    return 0xff;
220813531Sjairo.balart@metempsy.com}
220913531Sjairo.balart@metempsy.com
221013531Sjairo.balart@metempsy.comvoid
221113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIncrementEOICount()
221213531Sjairo.balart@metempsy.com{
221313531Sjairo.balart@metempsy.com    // Increment the EOICOUNT field in ICH_HCR_EL2
221413531Sjairo.balart@metempsy.com    RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
221513531Sjairo.balart@metempsy.com    uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
221613531Sjairo.balart@metempsy.com    EOI_cout++;
221713531Sjairo.balart@metempsy.com    ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
221813531Sjairo.balart@metempsy.com    isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
221913531Sjairo.balart@metempsy.com}
222013531Sjairo.balart@metempsy.com
222113531Sjairo.balart@metempsy.com// spec section 4.6.2
222213531Sjairo.balart@metempsy.comArmISA::InterruptTypes
222313531Sjairo.balart@metempsy.comGicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
222413531Sjairo.balart@metempsy.com{
222513531Sjairo.balart@metempsy.com    bool is_fiq = false;
222613531Sjairo.balart@metempsy.com
222713531Sjairo.balart@metempsy.com    switch (group) {
222813531Sjairo.balart@metempsy.com      case Gicv3::G0S:
222913531Sjairo.balart@metempsy.com        is_fiq = true;
223013531Sjairo.balart@metempsy.com        break;
223113531Sjairo.balart@metempsy.com
223213531Sjairo.balart@metempsy.com      case Gicv3::G1S:
223313531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) &&
223413531Sjairo.balart@metempsy.com            (!inSecureState() || ((currEL() == EL3) && isAA64()));
223513531Sjairo.balart@metempsy.com        break;
223613531Sjairo.balart@metempsy.com
223713531Sjairo.balart@metempsy.com      case Gicv3::G1NS:
223813531Sjairo.balart@metempsy.com        is_fiq = (distributor->DS == 0) && inSecureState();
223913531Sjairo.balart@metempsy.com        break;
224013531Sjairo.balart@metempsy.com
224113531Sjairo.balart@metempsy.com      default:
224213531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::intSignalType(): invalid group!");
224313531Sjairo.balart@metempsy.com    }
224413531Sjairo.balart@metempsy.com
224513531Sjairo.balart@metempsy.com    if (is_fiq) {
224613531Sjairo.balart@metempsy.com        return ArmISA::INT_FIQ;
224713531Sjairo.balart@metempsy.com    } else {
224813531Sjairo.balart@metempsy.com        return ArmISA::INT_IRQ;
224913531Sjairo.balart@metempsy.com    }
225013531Sjairo.balart@metempsy.com}
225113531Sjairo.balart@metempsy.com
225213531Sjairo.balart@metempsy.combool
225313531Sjairo.balart@metempsy.comGicv3CPUInterface::hppiCanPreempt()
225413531Sjairo.balart@metempsy.com{
225513531Sjairo.balart@metempsy.com    if (hppi.prio == 0xff) {
225613531Sjairo.balart@metempsy.com        // there is no pending interrupt
225713531Sjairo.balart@metempsy.com        return false;
225813531Sjairo.balart@metempsy.com    }
225913531Sjairo.balart@metempsy.com
226013531Sjairo.balart@metempsy.com    if (!groupEnabled(hppi.group)) {
226113531Sjairo.balart@metempsy.com        // group disabled at CPU interface
226213531Sjairo.balart@metempsy.com        return false;
226313531Sjairo.balart@metempsy.com    }
226413531Sjairo.balart@metempsy.com
226513531Sjairo.balart@metempsy.com    if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
226613531Sjairo.balart@metempsy.com        // priority masked
226713531Sjairo.balart@metempsy.com        return false;
226813531Sjairo.balart@metempsy.com    }
226913531Sjairo.balart@metempsy.com
227013531Sjairo.balart@metempsy.com    uint8_t rprio = highestActivePriority();
227113531Sjairo.balart@metempsy.com
227213531Sjairo.balart@metempsy.com    if (rprio == 0xff) {
227313531Sjairo.balart@metempsy.com        return true;
227413531Sjairo.balart@metempsy.com    }
227513531Sjairo.balart@metempsy.com
227613531Sjairo.balart@metempsy.com    uint32_t prio_mask = groupPriorityMask(hppi.group);
227713531Sjairo.balart@metempsy.com
227813531Sjairo.balart@metempsy.com    if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
227913531Sjairo.balart@metempsy.com        return true;
228013531Sjairo.balart@metempsy.com    }
228113531Sjairo.balart@metempsy.com
228213531Sjairo.balart@metempsy.com    return false;
228313531Sjairo.balart@metempsy.com}
228413580Sgabeblack@google.com
228513531Sjairo.balart@metempsy.comuint8_t
228613531Sjairo.balart@metempsy.comGicv3CPUInterface::highestActivePriority() const
228713531Sjairo.balart@metempsy.com{
228813531Sjairo.balart@metempsy.com    uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
228913531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
229013531Sjairo.balart@metempsy.com                   isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);
229113531Sjairo.balart@metempsy.com
229213531Sjairo.balart@metempsy.com    if (apr) {
229313531Sjairo.balart@metempsy.com        return ctz32(apr) << (GIC_MIN_BPR + 1);
229413531Sjairo.balart@metempsy.com    }
229513531Sjairo.balart@metempsy.com
229613531Sjairo.balart@metempsy.com    // no active interrups, return idle priority
229713531Sjairo.balart@metempsy.com    return 0xff;
229813531Sjairo.balart@metempsy.com}
229913531Sjairo.balart@metempsy.com
230013531Sjairo.balart@metempsy.combool
230113531Sjairo.balart@metempsy.comGicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
230213580Sgabeblack@google.com{
230313531Sjairo.balart@metempsy.com    switch (group) {
230413531Sjairo.balart@metempsy.com      case Gicv3::G0S: {
230513531Sjairo.balart@metempsy.com        ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
230613531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
230713531Sjairo.balart@metempsy.com        return icc_igrpen0_el1.Enable && distributor->EnableGrp0;
230813531Sjairo.balart@metempsy.com      }
230913531Sjairo.balart@metempsy.com
231013531Sjairo.balart@metempsy.com      case Gicv3::G1S: {
231113531Sjairo.balart@metempsy.com        ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
231213531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
231313531Sjairo.balart@metempsy.com        return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
231413531Sjairo.balart@metempsy.com      }
231513531Sjairo.balart@metempsy.com
231613531Sjairo.balart@metempsy.com      case Gicv3::G1NS: {
231713531Sjairo.balart@metempsy.com        ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
231813531Sjairo.balart@metempsy.com            isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
231913531Sjairo.balart@metempsy.com        return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS;
232013531Sjairo.balart@metempsy.com      }
232113531Sjairo.balart@metempsy.com
232213531Sjairo.balart@metempsy.com      default:
232313531Sjairo.balart@metempsy.com        panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
232413531Sjairo.balart@metempsy.com    }
232513531Sjairo.balart@metempsy.com}
232613531Sjairo.balart@metempsy.com
232713531Sjairo.balart@metempsy.combool
232813531Sjairo.balart@metempsy.comGicv3CPUInterface::inSecureState() const
232913531Sjairo.balart@metempsy.com{
233013580Sgabeblack@google.com    if (!gic->getSystem()->haveSecurity()) {
233113580Sgabeblack@google.com        return false;
233213531Sjairo.balart@metempsy.com    }
233313531Sjairo.balart@metempsy.com
233413531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
233513531Sjairo.balart@metempsy.com    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
233613531Sjairo.balart@metempsy.com    return ArmISA::inSecureState(scr, cpsr);
233713531Sjairo.balart@metempsy.com}
233813531Sjairo.balart@metempsy.com
233913531Sjairo.balart@metempsy.comint
234013531Sjairo.balart@metempsy.comGicv3CPUInterface::currEL() const
234113531Sjairo.balart@metempsy.com{
234213531Sjairo.balart@metempsy.com    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
234313531Sjairo.balart@metempsy.com    bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
234413531Sjairo.balart@metempsy.com
234513531Sjairo.balart@metempsy.com    if (is_64) {
234613531Sjairo.balart@metempsy.com        return (ExceptionLevel)(uint8_t) cpsr.el;
234713531Sjairo.balart@metempsy.com    } else {
234813531Sjairo.balart@metempsy.com        switch (cpsr.mode) {
234913531Sjairo.balart@metempsy.com          case MODE_USER:
235013531Sjairo.balart@metempsy.com            return 0;
235113531Sjairo.balart@metempsy.com
235213531Sjairo.balart@metempsy.com          case MODE_HYP:
235313531Sjairo.balart@metempsy.com            return 2;
235413531Sjairo.balart@metempsy.com
235513531Sjairo.balart@metempsy.com          case MODE_MON:
235613531Sjairo.balart@metempsy.com            return 3;
235713531Sjairo.balart@metempsy.com
235813531Sjairo.balart@metempsy.com          default:
235913531Sjairo.balart@metempsy.com            return 1;
236013531Sjairo.balart@metempsy.com        }
236113531Sjairo.balart@metempsy.com    }
236213531Sjairo.balart@metempsy.com}
236313531Sjairo.balart@metempsy.com
236413531Sjairo.balart@metempsy.combool
236513531Sjairo.balart@metempsy.comGicv3CPUInterface::haveEL(ExceptionLevel el) const
236613531Sjairo.balart@metempsy.com{
236713531Sjairo.balart@metempsy.com    switch (el) {
236813531Sjairo.balart@metempsy.com      case EL0:
236913531Sjairo.balart@metempsy.com      case EL1:
237013531Sjairo.balart@metempsy.com        return true;
237113531Sjairo.balart@metempsy.com
237213531Sjairo.balart@metempsy.com      case EL2:
237313531Sjairo.balart@metempsy.com        return gic->getSystem()->haveVirtualization();
237413531Sjairo.balart@metempsy.com
2375      case EL3:
2376        return gic->getSystem()->haveSecurity();
2377
2378      default:
2379        warn("Unimplemented Exception Level\n");
2380        return false;
2381    }
2382}
2383
2384bool
2385Gicv3CPUInterface::isSecureBelowEL3() const
2386{
2387    SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
2388    return haveEL(EL3) && scr.ns == 0;
2389}
2390
2391bool
2392Gicv3CPUInterface::isAA64() const
2393{
2394    CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2395    return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2396}
2397
2398bool
2399Gicv3CPUInterface::isEL3OrMon() const
2400{
2401    if (haveEL(EL3)) {
2402        CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2403        bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2404
2405        if (is_64 && (cpsr.el == EL3)) {
2406            return true;
2407        } else if (!is_64 && (cpsr.mode == MODE_MON)) {
2408            return true;
2409        }
2410    }
2411
2412    return false;
2413}
2414
2415// Computes ICH_EISR_EL2
2416uint64_t
2417Gicv3CPUInterface::eoiMaintenanceInterruptStatus() const
2418{
2419    // ICH_EISR_EL2
2420    // Bits [63:16] - RES0
2421    // Status<n>, bit [n], for n = 0 to 15
2422    //   EOI maintenance interrupt status bit for List register <n>:
2423    //     0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
2424    //     maintenance interrupt.
2425    //     1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
2426    //     interrupt that has not been handled.
2427    //
2428    // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
2429    // of the following are true:
2430    // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
2431    // - ICH_LR<n>_EL2.HW is 0.
2432    // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
2433
2434    uint64_t value = 0;
2435
2436    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2437        ICH_LR_EL2 ich_lr_el2 =
2438            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2439
2440        if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
2441            !ich_lr_el2.HW && ich_lr_el2.EOI) {
2442            value |= (1 << lr_idx);
2443        }
2444    }
2445
2446    return value;
2447}
2448
2449Gicv3CPUInterface::ICH_MISR_EL2
2450Gicv3CPUInterface::maintenanceInterruptStatus() const
2451{
2452    // Comments are copied from SPEC section 9.4.7 (ID012119)
2453    ICH_MISR_EL2 ich_misr_el2 = 0;
2454    ICH_HCR_EL2 ich_hcr_el2 =
2455        isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2456    ICH_VMCR_EL2 ich_vmcr_el2 =
2457        isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2458
2459    // End Of Interrupt. [bit 0]
2460    // This maintenance interrupt is asserted when at least one bit in
2461    // ICH_EISR_EL2 is 1.
2462
2463    if (eoiMaintenanceInterruptStatus()) {
2464        ich_misr_el2.EOI = 1;
2465    }
2466
2467    // Underflow. [bit 1]
2468    // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
2469    // zero or one of the List register entries are marked as a valid
2470    // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
2471    // do not equal 0x0.
2472    uint32_t num_valid_interrupts = 0;
2473    uint32_t num_pending_interrupts = 0;
2474
2475    for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2476        ICH_LR_EL2 ich_lr_el2 =
2477            isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2478
2479        if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
2480            num_valid_interrupts++;
2481        }
2482
2483        if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
2484            num_pending_interrupts++;
2485        }
2486    }
2487
2488    if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
2489        ich_misr_el2.U = 1;
2490    }
2491
2492    // List Register Entry Not Present. [bit 2]
2493    // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
2494    // and ICH_HCR_EL2.EOIcount is non-zero.
2495    if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
2496        ich_misr_el2.LRENP = 1;
2497    }
2498
2499    // No Pending. [bit 3]
2500    // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
2501    // no List register is in pending state.
2502    if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
2503        ich_misr_el2.NP = 1;
2504    }
2505
2506    // vPE Group 0 Enabled. [bit 4]
2507    // This maintenance interrupt is asserted when
2508    // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
2509    if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
2510        ich_misr_el2.VGrp0E = 1;
2511    }
2512
2513    // vPE Group 0 Disabled. [bit 5]
2514    // This maintenance interrupt is asserted when
2515    // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
2516    if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
2517        ich_misr_el2.VGrp0D = 1;
2518    }
2519
2520    // vPE Group 1 Enabled. [bit 6]
2521    // This maintenance interrupt is asserted when
2522    // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
2523    if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
2524        ich_misr_el2.VGrp1E = 1;
2525    }
2526
2527    // vPE Group 1 Disabled. [bit 7]
2528    // This maintenance interrupt is asserted when
2529    // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
2530    if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
2531        ich_misr_el2.VGrp1D = 1;
2532    }
2533
2534    return ich_misr_el2;
2535}
2536
2537RegVal
2538Gicv3CPUInterface::bpr1(Gicv3::GroupId group)
2539{
2540    bool hcr_imo = getHCREL2IMO();
2541    if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
2542        return readMiscReg(MISCREG_ICV_BPR1_EL1);
2543    }
2544
2545    RegVal bpr = 0;
2546
2547    if (group == Gicv3::G1S) {
2548        ICC_CTLR_EL1 icc_ctlr_el1_s =
2549            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
2550
2551        if (!isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
2552            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
2553        } else {
2554            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S);
2555            bpr = bpr > GIC_MIN_BPR ? bpr : GIC_MIN_BPR;
2556        }
2557    } else if (group == Gicv3::G1NS) {
2558        ICC_CTLR_EL1 icc_ctlr_el1_ns =
2559            isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
2560
2561        // Check if EL3 is implemented and this is a non secure accesses at
2562        // EL1 and EL2
2563        if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
2564            // Reads return BPR0 + 1 saturated to 7, WI
2565            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1) + 1;
2566            bpr = bpr < 7 ? bpr : 7;
2567        } else {
2568            bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS);
2569            bpr = bpr > GIC_MIN_BPR_NS ? bpr : GIC_MIN_BPR_NS;
2570        }
2571    } else {
2572        panic("Should be used with G1S and G1NS only\n");
2573    }
2574
2575    return bpr;
2576}
2577
2578void
2579Gicv3CPUInterface::serialize(CheckpointOut & cp) const
2580{
2581    SERIALIZE_SCALAR(hppi.intid);
2582    SERIALIZE_SCALAR(hppi.prio);
2583    SERIALIZE_ENUM(hppi.group);
2584}
2585
2586void
2587Gicv3CPUInterface::unserialize(CheckpointIn & cp)
2588{
2589    UNSERIALIZE_SCALAR(hppi.intid);
2590    UNSERIALIZE_SCALAR(hppi.prio);
2591    UNSERIALIZE_ENUM(hppi.group);
2592}
2593