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