gic_v3_cpu_interface.cc revision 14057
113531Sjairo.balart@metempsy.com/* 213531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting 313531Sjairo.balart@metempsy.com * All rights reserved. 413531Sjairo.balart@metempsy.com * 513531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without 613531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are 713531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright 813531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer; 913531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright 1013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the 1113531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution; 1213531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its 1313531Sjairo.balart@metempsy.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 3913926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR; 4013926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS; 4113926Sgiacomo.travaglini@arm.com 4213531Sjairo.balart@metempsy.comGicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id) 4313531Sjairo.balart@metempsy.com : BaseISADevice(), 4413531Sjairo.balart@metempsy.com gic(gic), 4513531Sjairo.balart@metempsy.com redistributor(nullptr), 4613531Sjairo.balart@metempsy.com distributor(nullptr), 4713531Sjairo.balart@metempsy.com cpuId(cpu_id) 4813531Sjairo.balart@metempsy.com{ 4913531Sjairo.balart@metempsy.com} 5013531Sjairo.balart@metempsy.com 5113531Sjairo.balart@metempsy.comvoid 5213531Sjairo.balart@metempsy.comGicv3CPUInterface::init() 5313531Sjairo.balart@metempsy.com{ 5413531Sjairo.balart@metempsy.com redistributor = gic->getRedistributor(cpuId); 5513531Sjairo.balart@metempsy.com distributor = gic->getDistributor(); 5613531Sjairo.balart@metempsy.com} 5713531Sjairo.balart@metempsy.com 5813531Sjairo.balart@metempsy.comvoid 5913531Sjairo.balart@metempsy.comGicv3CPUInterface::initState() 6013531Sjairo.balart@metempsy.com{ 6113531Sjairo.balart@metempsy.com reset(); 6213531Sjairo.balart@metempsy.com} 6313531Sjairo.balart@metempsy.com 6413531Sjairo.balart@metempsy.comvoid 6513531Sjairo.balart@metempsy.comGicv3CPUInterface::reset() 6613531Sjairo.balart@metempsy.com{ 6713531Sjairo.balart@metempsy.com hppi.prio = 0xff; 6813531Sjairo.balart@metempsy.com} 6913531Sjairo.balart@metempsy.com 7013826Sgiacomo.travaglini@arm.comvoid 7113826Sgiacomo.travaglini@arm.comGicv3CPUInterface::setThreadContext(ThreadContext *tc) 7213826Sgiacomo.travaglini@arm.com{ 7313826Sgiacomo.travaglini@arm.com maintenanceInterrupt = gic->params()->maint_int->get(tc); 7413826Sgiacomo.travaglini@arm.com} 7513826Sgiacomo.travaglini@arm.com 7613531Sjairo.balart@metempsy.combool 7713760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2FMO() const 7813531Sjairo.balart@metempsy.com{ 7913531Sjairo.balart@metempsy.com HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2); 8013531Sjairo.balart@metempsy.com 8113531Sjairo.balart@metempsy.com if (hcr.tge && hcr.e2h) { 8213531Sjairo.balart@metempsy.com return false; 8313531Sjairo.balart@metempsy.com } else if (hcr.tge) { 8413531Sjairo.balart@metempsy.com return true; 8513531Sjairo.balart@metempsy.com } else { 8613531Sjairo.balart@metempsy.com return hcr.fmo; 8713531Sjairo.balart@metempsy.com } 8813531Sjairo.balart@metempsy.com} 8913531Sjairo.balart@metempsy.com 9013531Sjairo.balart@metempsy.combool 9113760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2IMO() const 9213531Sjairo.balart@metempsy.com{ 9313531Sjairo.balart@metempsy.com HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2); 9413531Sjairo.balart@metempsy.com 9513531Sjairo.balart@metempsy.com if (hcr.tge && hcr.e2h) { 9613531Sjairo.balart@metempsy.com return false; 9713531Sjairo.balart@metempsy.com } else if (hcr.tge) { 9813531Sjairo.balart@metempsy.com return true; 9913531Sjairo.balart@metempsy.com } else { 10013531Sjairo.balart@metempsy.com return hcr.imo; 10113531Sjairo.balart@metempsy.com } 10213531Sjairo.balart@metempsy.com} 10313531Sjairo.balart@metempsy.com 10413580Sgabeblack@google.comRegVal 10513531Sjairo.balart@metempsy.comGicv3CPUInterface::readMiscReg(int misc_reg) 10613531Sjairo.balart@metempsy.com{ 10713580Sgabeblack@google.com RegVal value = isa->readMiscRegNoEffect(misc_reg); 10813531Sjairo.balart@metempsy.com bool hcr_fmo = getHCREL2FMO(); 10913531Sjairo.balart@metempsy.com bool hcr_imo = getHCREL2IMO(); 11013531Sjairo.balart@metempsy.com 11113531Sjairo.balart@metempsy.com switch (misc_reg) { 11213760Sjairo.balart@metempsy.com // Active Priorities Group 1 Registers 11313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0: 11413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0_EL1: { 11513531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 11613531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1); 11713531Sjairo.balart@metempsy.com } 11813531Sjairo.balart@metempsy.com 11913531Sjairo.balart@metempsy.com break; 12013531Sjairo.balart@metempsy.com } 12113531Sjairo.balart@metempsy.com 12213531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1: 12313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1_EL1: 12413531Sjairo.balart@metempsy.com 12513531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 12613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2: 12713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2_EL1: 12813531Sjairo.balart@metempsy.com 12913531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 13013531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3: 13113531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3_EL1: 13213531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 13313531Sjairo.balart@metempsy.com return 0; 13413531Sjairo.balart@metempsy.com 13513760Sjairo.balart@metempsy.com // Active Priorities Group 0 Registers 13613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0: 13713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0_EL1: { 13813531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 13913531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1); 14013531Sjairo.balart@metempsy.com } 14113531Sjairo.balart@metempsy.com 14213531Sjairo.balart@metempsy.com break; 14313531Sjairo.balart@metempsy.com } 14413531Sjairo.balart@metempsy.com 14513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1: 14613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1_EL1: 14713531Sjairo.balart@metempsy.com 14813531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 14913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2: 15013531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2_EL1: 15113531Sjairo.balart@metempsy.com 15213531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 15313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3: 15413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3_EL1: 15513531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 15613531Sjairo.balart@metempsy.com return 0; 15713531Sjairo.balart@metempsy.com 15813760Sjairo.balart@metempsy.com // Interrupt Group 0 Enable register EL1 15913531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0: 16013531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0_EL1: { 16113531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 16214057Sgiacomo.travaglini@arm.com return readMiscReg(MISCREG_ICV_IGRPEN0_EL1); 16313531Sjairo.balart@metempsy.com } 16413531Sjairo.balart@metempsy.com 16513531Sjairo.balart@metempsy.com break; 16613531Sjairo.balart@metempsy.com } 16713531Sjairo.balart@metempsy.com 16814057Sgiacomo.travaglini@arm.com case MISCREG_ICV_IGRPEN0_EL1: { 16914057Sgiacomo.travaglini@arm.com ICH_VMCR_EL2 ich_vmcr_el2 = 17014057Sgiacomo.travaglini@arm.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 17114057Sgiacomo.travaglini@arm.com value = ich_vmcr_el2.VENG0; 17214057Sgiacomo.travaglini@arm.com break; 17314057Sgiacomo.travaglini@arm.com } 17414057Sgiacomo.travaglini@arm.com 17513760Sjairo.balart@metempsy.com // Interrupt Group 1 Enable register EL1 17613531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1: 17713531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL1: { 17813531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 17914057Sgiacomo.travaglini@arm.com return readMiscReg(MISCREG_ICV_IGRPEN1_EL1); 18013531Sjairo.balart@metempsy.com } 18113531Sjairo.balart@metempsy.com 18213531Sjairo.balart@metempsy.com break; 18313531Sjairo.balart@metempsy.com } 18413531Sjairo.balart@metempsy.com 18514057Sgiacomo.travaglini@arm.com case MISCREG_ICV_IGRPEN1_EL1: { 18614057Sgiacomo.travaglini@arm.com ICH_VMCR_EL2 ich_vmcr_el2 = 18714057Sgiacomo.travaglini@arm.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 18814057Sgiacomo.travaglini@arm.com value = ich_vmcr_el2.VENG1; 18914057Sgiacomo.travaglini@arm.com break; 19014057Sgiacomo.travaglini@arm.com } 19114057Sgiacomo.travaglini@arm.com 19213760Sjairo.balart@metempsy.com // Interrupt Group 1 Enable register EL3 19313760Sjairo.balart@metempsy.com case MISCREG_ICC_MGRPEN1: 19413760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL3: 19513739Sgiacomo.travaglini@arm.com break; 19613760Sjairo.balart@metempsy.com 19713760Sjairo.balart@metempsy.com // Running Priority Register 19813531Sjairo.balart@metempsy.com case MISCREG_ICC_RPR: 19913531Sjairo.balart@metempsy.com case MISCREG_ICC_RPR_EL1: { 20013531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 20113760Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 20213531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_RPR_EL1); 20313531Sjairo.balart@metempsy.com } 20413531Sjairo.balart@metempsy.com 20513531Sjairo.balart@metempsy.com uint8_t rprio = highestActivePriority(); 20613531Sjairo.balart@metempsy.com 20713531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && 20813760Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) { 20913760Sjairo.balart@metempsy.com // Spec section 4.8.1 21013760Sjairo.balart@metempsy.com // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1 21113531Sjairo.balart@metempsy.com if ((rprio & 0x80) == 0) { 21213760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 21313760Sjairo.balart@metempsy.com // 0x00-0x7F a read access returns the value 0x0 21413531Sjairo.balart@metempsy.com rprio = 0; 21513531Sjairo.balart@metempsy.com } else if (rprio != 0xff) { 21613760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 21713760Sjairo.balart@metempsy.com // 0x80-0xFF a read access returns the Non-secure read of 21813760Sjairo.balart@metempsy.com // the current value 21913531Sjairo.balart@metempsy.com rprio = (rprio << 1) & 0xff; 22013531Sjairo.balart@metempsy.com } 22113531Sjairo.balart@metempsy.com } 22213531Sjairo.balart@metempsy.com 22313531Sjairo.balart@metempsy.com value = rprio; 22413531Sjairo.balart@metempsy.com break; 22513531Sjairo.balart@metempsy.com } 22613531Sjairo.balart@metempsy.com 22713760Sjairo.balart@metempsy.com // Virtual Running Priority Register 22813531Sjairo.balart@metempsy.com case MISCREG_ICV_RPR_EL1: { 22913531Sjairo.balart@metempsy.com value = virtualHighestActivePriority(); 23013531Sjairo.balart@metempsy.com break; 23113531Sjairo.balart@metempsy.com } 23213531Sjairo.balart@metempsy.com 23313760Sjairo.balart@metempsy.com // Highest Priority Pending Interrupt Register 0 23413531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR0: 23513531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR0_EL1: { 23613531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 23713531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_HPPIR0_EL1); 23813531Sjairo.balart@metempsy.com } 23913531Sjairo.balart@metempsy.com 24013531Sjairo.balart@metempsy.com value = getHPPIR0(); 24113531Sjairo.balart@metempsy.com break; 24213531Sjairo.balart@metempsy.com } 24313531Sjairo.balart@metempsy.com 24413760Sjairo.balart@metempsy.com // Virtual Highest Priority Pending Interrupt Register 0 24513531Sjairo.balart@metempsy.com case MISCREG_ICV_HPPIR0_EL1: { 24613531Sjairo.balart@metempsy.com value = Gicv3::INTID_SPURIOUS; 24713531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 24813531Sjairo.balart@metempsy.com 24913531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 25013760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 25113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 25213531Sjairo.balart@metempsy.com Gicv3::GroupId group = 25313760Sjairo.balart@metempsy.com ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 25413531Sjairo.balart@metempsy.com 25513531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 25613760Sjairo.balart@metempsy.com value = ich_lr_el2.vINTID; 25713531Sjairo.balart@metempsy.com } 25813531Sjairo.balart@metempsy.com } 25913531Sjairo.balart@metempsy.com 26013531Sjairo.balart@metempsy.com break; 26113531Sjairo.balart@metempsy.com } 26213531Sjairo.balart@metempsy.com 26313760Sjairo.balart@metempsy.com // Highest Priority Pending Interrupt Register 1 26413531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR1: 26513531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR1_EL1: { 26613531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 26713531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_HPPIR1_EL1); 26813531Sjairo.balart@metempsy.com } 26913531Sjairo.balart@metempsy.com 27013531Sjairo.balart@metempsy.com value = getHPPIR1(); 27113531Sjairo.balart@metempsy.com break; 27213531Sjairo.balart@metempsy.com } 27313531Sjairo.balart@metempsy.com 27413760Sjairo.balart@metempsy.com // Virtual Highest Priority Pending Interrupt Register 1 27513531Sjairo.balart@metempsy.com case MISCREG_ICV_HPPIR1_EL1: { 27613531Sjairo.balart@metempsy.com value = Gicv3::INTID_SPURIOUS; 27713531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 27813531Sjairo.balart@metempsy.com 27913531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 28013760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 28113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 28213531Sjairo.balart@metempsy.com Gicv3::GroupId group = 28313760Sjairo.balart@metempsy.com ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 28413531Sjairo.balart@metempsy.com 28513531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 28613760Sjairo.balart@metempsy.com value = ich_lr_el2.vINTID; 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 29313760Sjairo.balart@metempsy.com // Binary Point Register 0 29413531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0: 29513531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0_EL1: 29613531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 29713531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_BPR0_EL1); 29813531Sjairo.balart@metempsy.com } 29913531Sjairo.balart@metempsy.com 30013531Sjairo.balart@metempsy.com M5_FALLTHROUGH; 30113531Sjairo.balart@metempsy.com 30213760Sjairo.balart@metempsy.com // Binary Point Register 1 30313531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1: 30413760Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1_EL1: { 30513760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 30613760Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_BPR1_EL1); 30713760Sjairo.balart@metempsy.com } 30813760Sjairo.balart@metempsy.com 30913531Sjairo.balart@metempsy.com Gicv3::GroupId group = 31013531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S; 31113531Sjairo.balart@metempsy.com 31213531Sjairo.balart@metempsy.com if (group == Gicv3::G1S && !inSecureState()) { 31313531Sjairo.balart@metempsy.com group = Gicv3::G1NS; 31413531Sjairo.balart@metempsy.com } 31513531Sjairo.balart@metempsy.com 31613760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_s = 31713760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 31813760Sjairo.balart@metempsy.com 31913760Sjairo.balart@metempsy.com if ((group == Gicv3::G1S) && !isEL3OrMon() && 32013760Sjairo.balart@metempsy.com icc_ctlr_el1_s.CBPR) { 32113531Sjairo.balart@metempsy.com group = Gicv3::G0S; 32213531Sjairo.balart@metempsy.com } 32313531Sjairo.balart@metempsy.com 32413531Sjairo.balart@metempsy.com bool sat_inc = false; 32513531Sjairo.balart@metempsy.com 32613760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_ns = 32713760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 32813760Sjairo.balart@metempsy.com 32913760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && (currEL() < EL3) && 33013760Sjairo.balart@metempsy.com icc_ctlr_el1_ns.CBPR) { 33113531Sjairo.balart@metempsy.com // Reads return BPR0 + 1 saturated to 7, WI 33213531Sjairo.balart@metempsy.com group = Gicv3::G0S; 33313531Sjairo.balart@metempsy.com sat_inc = true; 33413531Sjairo.balart@metempsy.com } 33513531Sjairo.balart@metempsy.com 33613531Sjairo.balart@metempsy.com uint8_t bpr; 33713531Sjairo.balart@metempsy.com 33813531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 33913531Sjairo.balart@metempsy.com bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1); 34013531Sjairo.balart@metempsy.com } else { 34113531Sjairo.balart@metempsy.com bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1); 34213926Sgiacomo.travaglini@arm.com bpr = std::max(bpr, group == Gicv3::G1S ? 34313926Sgiacomo.travaglini@arm.com GIC_MIN_BPR : GIC_MIN_BPR_NS); 34413531Sjairo.balart@metempsy.com } 34513531Sjairo.balart@metempsy.com 34613531Sjairo.balart@metempsy.com if (sat_inc) { 34713531Sjairo.balart@metempsy.com bpr++; 34813531Sjairo.balart@metempsy.com 34913531Sjairo.balart@metempsy.com if (bpr > 7) { 35013531Sjairo.balart@metempsy.com bpr = 7; 35113531Sjairo.balart@metempsy.com } 35213531Sjairo.balart@metempsy.com } 35313531Sjairo.balart@metempsy.com 35413531Sjairo.balart@metempsy.com value = bpr; 35513531Sjairo.balart@metempsy.com break; 35613760Sjairo.balart@metempsy.com } 35713760Sjairo.balart@metempsy.com 35813760Sjairo.balart@metempsy.com // Virtual Binary Point Register 1 35913531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR0_EL1: 36013531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR1_EL1: { 36113531Sjairo.balart@metempsy.com Gicv3::GroupId group = 36213531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS; 36313760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 36413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 36513531Sjairo.balart@metempsy.com bool sat_inc = false; 36613531Sjairo.balart@metempsy.com 36713760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) { 36813760Sjairo.balart@metempsy.com // bpr0 + 1 saturated to 7, WI 36913531Sjairo.balart@metempsy.com group = Gicv3::G0S; 37013531Sjairo.balart@metempsy.com sat_inc = true; 37113531Sjairo.balart@metempsy.com } 37213531Sjairo.balart@metempsy.com 37313531Sjairo.balart@metempsy.com uint8_t vbpr; 37413531Sjairo.balart@metempsy.com 37513531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 37613760Sjairo.balart@metempsy.com vbpr = ich_vmcr_el2.VBPR0; 37713531Sjairo.balart@metempsy.com } else { 37813760Sjairo.balart@metempsy.com vbpr = ich_vmcr_el2.VBPR1; 37913531Sjairo.balart@metempsy.com } 38013531Sjairo.balart@metempsy.com 38113531Sjairo.balart@metempsy.com if (sat_inc) { 38213531Sjairo.balart@metempsy.com vbpr++; 38313531Sjairo.balart@metempsy.com 38413531Sjairo.balart@metempsy.com if (vbpr > 7) { 38513531Sjairo.balart@metempsy.com vbpr = 7; 38613531Sjairo.balart@metempsy.com } 38713531Sjairo.balart@metempsy.com } 38813531Sjairo.balart@metempsy.com 38913531Sjairo.balart@metempsy.com value = vbpr; 39013531Sjairo.balart@metempsy.com break; 39113531Sjairo.balart@metempsy.com } 39213531Sjairo.balart@metempsy.com 39313760Sjairo.balart@metempsy.com // Interrupt Priority Mask Register 39413531Sjairo.balart@metempsy.com case MISCREG_ICC_PMR: 39513760Sjairo.balart@metempsy.com case MISCREG_ICC_PMR_EL1: 39613760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) { 39714057Sgiacomo.travaglini@arm.com return readMiscReg(MISCREG_ICV_PMR_EL1); 39813531Sjairo.balart@metempsy.com } 39913531Sjairo.balart@metempsy.com 40013531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && 40113760Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) { 40213760Sjairo.balart@metempsy.com // Spec section 4.8.1 40313760Sjairo.balart@metempsy.com // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1: 40413531Sjairo.balart@metempsy.com if ((value & 0x80) == 0) { 40513760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 40613760Sjairo.balart@metempsy.com // 0x00-0x7F a read access returns the value 0x00. 40713531Sjairo.balart@metempsy.com value = 0; 40813531Sjairo.balart@metempsy.com } else if (value != 0xff) { 40913760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 41013760Sjairo.balart@metempsy.com // 0x80-0xFF a read access returns the Non-secure read of the 41113760Sjairo.balart@metempsy.com // current value. 41213531Sjairo.balart@metempsy.com value = (value << 1) & 0xff; 41313531Sjairo.balart@metempsy.com } 41413531Sjairo.balart@metempsy.com } 41513531Sjairo.balart@metempsy.com 41613531Sjairo.balart@metempsy.com break; 41713531Sjairo.balart@metempsy.com 41814057Sgiacomo.travaglini@arm.com case MISCREG_ICV_PMR_EL1: { // Priority Mask Register 41914057Sgiacomo.travaglini@arm.com ICH_VMCR_EL2 ich_vmcr_el2 = 42014057Sgiacomo.travaglini@arm.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 42114057Sgiacomo.travaglini@arm.com 42214057Sgiacomo.travaglini@arm.com value = ich_vmcr_el2.VPMR; 42314057Sgiacomo.travaglini@arm.com break; 42414057Sgiacomo.travaglini@arm.com } 42514057Sgiacomo.travaglini@arm.com 42613760Sjairo.balart@metempsy.com // Interrupt Acknowledge Register 0 42713531Sjairo.balart@metempsy.com case MISCREG_ICC_IAR0: 42813760Sjairo.balart@metempsy.com case MISCREG_ICC_IAR0_EL1: { 42913531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 43013531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_IAR0_EL1); 43113531Sjairo.balart@metempsy.com } 43213531Sjairo.balart@metempsy.com 43313531Sjairo.balart@metempsy.com uint32_t int_id; 43413531Sjairo.balart@metempsy.com 43513531Sjairo.balart@metempsy.com if (hppiCanPreempt()) { 43613531Sjairo.balart@metempsy.com int_id = getHPPIR0(); 43713531Sjairo.balart@metempsy.com 43813531Sjairo.balart@metempsy.com // avoid activation for special interrupts 43913923Sgiacomo.travaglini@arm.com if (int_id < Gicv3::INTID_SECURE || 44013923Sgiacomo.travaglini@arm.com int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) { 44113531Sjairo.balart@metempsy.com activateIRQ(int_id, hppi.group); 44213531Sjairo.balart@metempsy.com } 44313531Sjairo.balart@metempsy.com } else { 44413531Sjairo.balart@metempsy.com int_id = Gicv3::INTID_SPURIOUS; 44513531Sjairo.balart@metempsy.com } 44613531Sjairo.balart@metempsy.com 44713531Sjairo.balart@metempsy.com value = int_id; 44813531Sjairo.balart@metempsy.com break; 44913531Sjairo.balart@metempsy.com } 45013531Sjairo.balart@metempsy.com 45113760Sjairo.balart@metempsy.com // Virtual Interrupt Acknowledge Register 0 45213531Sjairo.balart@metempsy.com case MISCREG_ICV_IAR0_EL1: { 45313531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 45413531Sjairo.balart@metempsy.com uint32_t int_id = Gicv3::INTID_SPURIOUS; 45513531Sjairo.balart@metempsy.com 45613531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 45713760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 45813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 45913531Sjairo.balart@metempsy.com 46013760Sjairo.balart@metempsy.com if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) { 46113760Sjairo.balart@metempsy.com int_id = ich_lr_el2.vINTID; 46213531Sjairo.balart@metempsy.com 46313531Sjairo.balart@metempsy.com if (int_id < Gicv3::INTID_SECURE || 46413760Sjairo.balart@metempsy.com int_id > Gicv3::INTID_SPURIOUS) { 46513531Sjairo.balart@metempsy.com virtualActivateIRQ(lr_idx); 46613531Sjairo.balart@metempsy.com } else { 46713531Sjairo.balart@metempsy.com // Bogus... Pseudocode says: 46813531Sjairo.balart@metempsy.com // - Move from pending to invalid... 46913531Sjairo.balart@metempsy.com // - Return de bogus id... 47013760Sjairo.balart@metempsy.com ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID; 47113531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, 47213760Sjairo.balart@metempsy.com ich_lr_el2); 47313531Sjairo.balart@metempsy.com } 47413531Sjairo.balart@metempsy.com } 47513531Sjairo.balart@metempsy.com } 47613531Sjairo.balart@metempsy.com 47713531Sjairo.balart@metempsy.com value = int_id; 47813531Sjairo.balart@metempsy.com virtualUpdate(); 47913531Sjairo.balart@metempsy.com break; 48013531Sjairo.balart@metempsy.com } 48113531Sjairo.balart@metempsy.com 48213760Sjairo.balart@metempsy.com // Interrupt Acknowledge Register 1 48313531Sjairo.balart@metempsy.com case MISCREG_ICC_IAR1: 48413760Sjairo.balart@metempsy.com case MISCREG_ICC_IAR1_EL1: { 48513531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 48613531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_IAR1_EL1); 48713531Sjairo.balart@metempsy.com } 48813531Sjairo.balart@metempsy.com 48913531Sjairo.balart@metempsy.com uint32_t int_id; 49013531Sjairo.balart@metempsy.com 49113531Sjairo.balart@metempsy.com if (hppiCanPreempt()) { 49213531Sjairo.balart@metempsy.com int_id = getHPPIR1(); 49313531Sjairo.balart@metempsy.com 49413531Sjairo.balart@metempsy.com // avoid activation for special interrupts 49513923Sgiacomo.travaglini@arm.com if (int_id < Gicv3::INTID_SECURE || 49613923Sgiacomo.travaglini@arm.com int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) { 49713531Sjairo.balart@metempsy.com activateIRQ(int_id, hppi.group); 49813531Sjairo.balart@metempsy.com } 49913531Sjairo.balart@metempsy.com } else { 50013531Sjairo.balart@metempsy.com int_id = Gicv3::INTID_SPURIOUS; 50113531Sjairo.balart@metempsy.com } 50213531Sjairo.balart@metempsy.com 50313531Sjairo.balart@metempsy.com value = int_id; 50413531Sjairo.balart@metempsy.com break; 50513531Sjairo.balart@metempsy.com } 50613531Sjairo.balart@metempsy.com 50713760Sjairo.balart@metempsy.com // Virtual Interrupt Acknowledge Register 1 50813531Sjairo.balart@metempsy.com case MISCREG_ICV_IAR1_EL1: { 50913531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 51013531Sjairo.balart@metempsy.com uint32_t int_id = Gicv3::INTID_SPURIOUS; 51113531Sjairo.balart@metempsy.com 51213531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 51313760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 51413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 51513531Sjairo.balart@metempsy.com 51613760Sjairo.balart@metempsy.com if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) { 51713760Sjairo.balart@metempsy.com int_id = ich_lr_el2.vINTID; 51813531Sjairo.balart@metempsy.com 51913531Sjairo.balart@metempsy.com if (int_id < Gicv3::INTID_SECURE || 52013760Sjairo.balart@metempsy.com int_id > Gicv3::INTID_SPURIOUS) { 52113531Sjairo.balart@metempsy.com virtualActivateIRQ(lr_idx); 52213531Sjairo.balart@metempsy.com } else { 52313531Sjairo.balart@metempsy.com // Bogus... Pseudocode says: 52413531Sjairo.balart@metempsy.com // - Move from pending to invalid... 52513531Sjairo.balart@metempsy.com // - Return de bogus id... 52613760Sjairo.balart@metempsy.com ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID; 52713531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, 52813760Sjairo.balart@metempsy.com ich_lr_el2); 52913531Sjairo.balart@metempsy.com } 53013531Sjairo.balart@metempsy.com } 53113531Sjairo.balart@metempsy.com } 53213531Sjairo.balart@metempsy.com 53313531Sjairo.balart@metempsy.com value = int_id; 53413531Sjairo.balart@metempsy.com virtualUpdate(); 53513531Sjairo.balart@metempsy.com break; 53613531Sjairo.balart@metempsy.com } 53713531Sjairo.balart@metempsy.com 53813760Sjairo.balart@metempsy.com // System Register Enable Register EL1 53913531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE: 54013760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL1: { 54113531Sjairo.balart@metempsy.com /* 54213531Sjairo.balart@metempsy.com * DIB [2] == 1 (IRQ bypass not supported, RAO/WI) 54313531Sjairo.balart@metempsy.com * DFB [1] == 1 (FIQ bypass not supported, RAO/WI) 54413531Sjairo.balart@metempsy.com * SRE [0] == 1 (Only system register interface supported, RAO/WI) 54513531Sjairo.balart@metempsy.com */ 54613760Sjairo.balart@metempsy.com ICC_SRE_EL1 icc_sre_el1 = 0; 54713760Sjairo.balart@metempsy.com icc_sre_el1.SRE = 1; 54813760Sjairo.balart@metempsy.com icc_sre_el1.DIB = 1; 54913760Sjairo.balart@metempsy.com icc_sre_el1.DFB = 1; 55013760Sjairo.balart@metempsy.com value = icc_sre_el1; 55113760Sjairo.balart@metempsy.com break; 55213760Sjairo.balart@metempsy.com } 55313760Sjairo.balart@metempsy.com 55413760Sjairo.balart@metempsy.com // System Register Enable Register EL2 55513760Sjairo.balart@metempsy.com case MISCREG_ICC_HSRE: 55613760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL2: { 55713531Sjairo.balart@metempsy.com /* 55813531Sjairo.balart@metempsy.com * Enable [3] == 1 55913760Sjairo.balart@metempsy.com * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI) 56013531Sjairo.balart@metempsy.com * DIB [2] == 1 (IRQ bypass not supported, RAO/WI) 56113531Sjairo.balart@metempsy.com * DFB [1] == 1 (FIQ bypass not supported, RAO/WI) 56213531Sjairo.balart@metempsy.com * SRE [0] == 1 (Only system register interface supported, RAO/WI) 56313531Sjairo.balart@metempsy.com */ 56413760Sjairo.balart@metempsy.com ICC_SRE_EL2 icc_sre_el2 = 0; 56513760Sjairo.balart@metempsy.com icc_sre_el2.SRE = 1; 56613760Sjairo.balart@metempsy.com icc_sre_el2.DIB = 1; 56713760Sjairo.balart@metempsy.com icc_sre_el2.DFB = 1; 56813760Sjairo.balart@metempsy.com icc_sre_el2.Enable = 1; 56913760Sjairo.balart@metempsy.com value = icc_sre_el2; 57013531Sjairo.balart@metempsy.com break; 57113760Sjairo.balart@metempsy.com } 57213760Sjairo.balart@metempsy.com 57313760Sjairo.balart@metempsy.com // System Register Enable Register EL3 57413760Sjairo.balart@metempsy.com case MISCREG_ICC_MSRE: 57513760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL3: { 57613760Sjairo.balart@metempsy.com /* 57713760Sjairo.balart@metempsy.com * Enable [3] == 1 57813760Sjairo.balart@metempsy.com * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3. 57913760Sjairo.balart@metempsy.com * EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3. 58013760Sjairo.balart@metempsy.com * RAO/WI) 58113760Sjairo.balart@metempsy.com * DIB [2] == 1 (IRQ bypass not supported, RAO/WI) 58213760Sjairo.balart@metempsy.com * DFB [1] == 1 (FIQ bypass not supported, RAO/WI) 58313760Sjairo.balart@metempsy.com * SRE [0] == 1 (Only system register interface supported, RAO/WI) 58413760Sjairo.balart@metempsy.com */ 58513760Sjairo.balart@metempsy.com ICC_SRE_EL3 icc_sre_el3 = 0; 58613760Sjairo.balart@metempsy.com icc_sre_el3.SRE = 1; 58713760Sjairo.balart@metempsy.com icc_sre_el3.DIB = 1; 58813760Sjairo.balart@metempsy.com icc_sre_el3.DFB = 1; 58913760Sjairo.balart@metempsy.com icc_sre_el3.Enable = 1; 59013760Sjairo.balart@metempsy.com value = icc_sre_el3; 59113760Sjairo.balart@metempsy.com break; 59213760Sjairo.balart@metempsy.com } 59313760Sjairo.balart@metempsy.com 59413760Sjairo.balart@metempsy.com // Control Register 59513531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR: 59613760Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL1: { 59713760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) { 59813531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_CTLR_EL1); 59913531Sjairo.balart@metempsy.com } 60013531Sjairo.balart@metempsy.com 60113760Sjairo.balart@metempsy.com // Enforce value for RO bits 60213760Sjairo.balart@metempsy.com // ExtRange [19], INTIDs in the range 1024..8191 not supported 60313760Sjairo.balart@metempsy.com // RSS [18], SGIs with affinity level 0 values of 0-255 are supported 60413760Sjairo.balart@metempsy.com // A3V [15], supports non-zero values of the Aff3 field in SGI 60513760Sjairo.balart@metempsy.com // generation System registers 60613760Sjairo.balart@metempsy.com // SEIS [14], does not support generation of SEIs (deprecated) 60713531Sjairo.balart@metempsy.com // IDbits [13:11], 001 = 24 bits | 000 = 16 bits 60813531Sjairo.balart@metempsy.com // PRIbits [10:8], number of priority bits implemented, minus one 60913760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1 = value; 61013760Sjairo.balart@metempsy.com icc_ctlr_el1.ExtRange = 0; 61113760Sjairo.balart@metempsy.com icc_ctlr_el1.RSS = 1; 61213760Sjairo.balart@metempsy.com icc_ctlr_el1.A3V = 1; 61313760Sjairo.balart@metempsy.com icc_ctlr_el1.SEIS = 0; 61413760Sjairo.balart@metempsy.com icc_ctlr_el1.IDbits = 1; 61513760Sjairo.balart@metempsy.com icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1; 61613760Sjairo.balart@metempsy.com value = icc_ctlr_el1; 61713531Sjairo.balart@metempsy.com break; 61813531Sjairo.balart@metempsy.com } 61913531Sjairo.balart@metempsy.com 62013760Sjairo.balart@metempsy.com // Virtual Control Register 62113531Sjairo.balart@metempsy.com case MISCREG_ICV_CTLR_EL1: { 62213760Sjairo.balart@metempsy.com ICV_CTLR_EL1 icv_ctlr_el1 = value; 62313760Sjairo.balart@metempsy.com icv_ctlr_el1.RSS = 0; 62413760Sjairo.balart@metempsy.com icv_ctlr_el1.A3V = 1; 62513760Sjairo.balart@metempsy.com icv_ctlr_el1.SEIS = 0; 62613760Sjairo.balart@metempsy.com icv_ctlr_el1.IDbits = 1; 62713760Sjairo.balart@metempsy.com icv_ctlr_el1.PRIbits = 7; 62813760Sjairo.balart@metempsy.com value = icv_ctlr_el1; 62913531Sjairo.balart@metempsy.com break; 63013531Sjairo.balart@metempsy.com } 63113531Sjairo.balart@metempsy.com 63213760Sjairo.balart@metempsy.com // Control Register 63313531Sjairo.balart@metempsy.com case MISCREG_ICC_MCTLR: 63413531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL3: { 63513760Sjairo.balart@metempsy.com // Enforce value for RO bits 63613760Sjairo.balart@metempsy.com // ExtRange [19], INTIDs in the range 1024..8191 not supported 63713760Sjairo.balart@metempsy.com // RSS [18], SGIs with affinity level 0 values of 0-255 are supported 63813760Sjairo.balart@metempsy.com // nDS [17], supports disabling of security 63913760Sjairo.balart@metempsy.com // A3V [15], supports non-zero values of the Aff3 field in SGI 64013760Sjairo.balart@metempsy.com // generation System registers 64113760Sjairo.balart@metempsy.com // SEIS [14], does not support generation of SEIs (deprecated) 64213531Sjairo.balart@metempsy.com // IDbits [13:11], 001 = 24 bits | 000 = 16 bits 64313531Sjairo.balart@metempsy.com // PRIbits [10:8], number of priority bits implemented, minus one 64413760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = value; 64513760Sjairo.balart@metempsy.com icc_ctlr_el3.ExtRange = 0; 64613760Sjairo.balart@metempsy.com icc_ctlr_el3.RSS = 1; 64713760Sjairo.balart@metempsy.com icc_ctlr_el3.nDS = 0; 64813760Sjairo.balart@metempsy.com icc_ctlr_el3.A3V = 1; 64913760Sjairo.balart@metempsy.com icc_ctlr_el3.SEIS = 0; 65013760Sjairo.balart@metempsy.com icc_ctlr_el3.IDbits = 0; 65113760Sjairo.balart@metempsy.com icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1; 65213760Sjairo.balart@metempsy.com value = icc_ctlr_el3; 65313531Sjairo.balart@metempsy.com break; 65413531Sjairo.balart@metempsy.com } 65513531Sjairo.balart@metempsy.com 65613760Sjairo.balart@metempsy.com // Hyp Control Register 65713531Sjairo.balart@metempsy.com case MISCREG_ICH_HCR: 65813531Sjairo.balart@metempsy.com case MISCREG_ICH_HCR_EL2: 65913531Sjairo.balart@metempsy.com break; 66013531Sjairo.balart@metempsy.com 66113760Sjairo.balart@metempsy.com // Hyp Active Priorities Group 0 Registers 66213531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0: 66313531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0_EL2: 66413531Sjairo.balart@metempsy.com break; 66513531Sjairo.balart@metempsy.com 66613760Sjairo.balart@metempsy.com // Hyp Active Priorities Group 1 Registers 66713531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0: 66813531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0_EL2: 66913531Sjairo.balart@metempsy.com break; 67013531Sjairo.balart@metempsy.com 67113760Sjairo.balart@metempsy.com // Maintenance Interrupt State Register 67213531Sjairo.balart@metempsy.com case MISCREG_ICH_MISR: 67313760Sjairo.balart@metempsy.com case MISCREG_ICH_MISR_EL2: 67413760Sjairo.balart@metempsy.com value = maintenanceInterruptStatus(); 67513760Sjairo.balart@metempsy.com break; 67613760Sjairo.balart@metempsy.com 67713760Sjairo.balart@metempsy.com // VGIC Type Register 67813760Sjairo.balart@metempsy.com case MISCREG_ICH_VTR: 67913760Sjairo.balart@metempsy.com case MISCREG_ICH_VTR_EL2: { 68013760Sjairo.balart@metempsy.com ICH_VTR_EL2 ich_vtr_el2 = value; 68113760Sjairo.balart@metempsy.com 68213760Sjairo.balart@metempsy.com ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1; 68313760Sjairo.balart@metempsy.com ich_vtr_el2.A3V = 1; 68413760Sjairo.balart@metempsy.com ich_vtr_el2.IDbits = 1; 68513760Sjairo.balart@metempsy.com ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1; 68613760Sjairo.balart@metempsy.com ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1; 68713760Sjairo.balart@metempsy.com 68813760Sjairo.balart@metempsy.com value = ich_vtr_el2; 68913760Sjairo.balart@metempsy.com break; 69013531Sjairo.balart@metempsy.com } 69113531Sjairo.balart@metempsy.com 69213760Sjairo.balart@metempsy.com // End of Interrupt Status Register 69313531Sjairo.balart@metempsy.com case MISCREG_ICH_EISR: 69413531Sjairo.balart@metempsy.com case MISCREG_ICH_EISR_EL2: 69513760Sjairo.balart@metempsy.com value = eoiMaintenanceInterruptStatus(); 69613531Sjairo.balart@metempsy.com break; 69713531Sjairo.balart@metempsy.com 69813760Sjairo.balart@metempsy.com // Empty List Register Status Register 69913531Sjairo.balart@metempsy.com case MISCREG_ICH_ELRSR: 70013531Sjairo.balart@metempsy.com case MISCREG_ICH_ELRSR_EL2: 70113531Sjairo.balart@metempsy.com value = 0; 70213531Sjairo.balart@metempsy.com 70313531Sjairo.balart@metempsy.com for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 70413760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 70513531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 70613531Sjairo.balart@metempsy.com 70713760Sjairo.balart@metempsy.com if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) && 70813760Sjairo.balart@metempsy.com (ich_lr_el2.HW || !ich_lr_el2.EOI)) { 70913531Sjairo.balart@metempsy.com value |= (1 << lr_idx); 71013531Sjairo.balart@metempsy.com } 71113531Sjairo.balart@metempsy.com } 71213531Sjairo.balart@metempsy.com 71313531Sjairo.balart@metempsy.com break; 71413531Sjairo.balart@metempsy.com 71513760Sjairo.balart@metempsy.com // List Registers 71613531Sjairo.balart@metempsy.com case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: 71713531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part) 71813531Sjairo.balart@metempsy.com value = value >> 32; 71913531Sjairo.balart@metempsy.com break; 72013531Sjairo.balart@metempsy.com 72113760Sjairo.balart@metempsy.com // List Registers 72213531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: 72313531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part) 72413531Sjairo.balart@metempsy.com value = value & 0xffffffff; 72513531Sjairo.balart@metempsy.com break; 72613531Sjairo.balart@metempsy.com 72713760Sjairo.balart@metempsy.com // List Registers 72813531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: 72913531Sjairo.balart@metempsy.com break; 73013531Sjairo.balart@metempsy.com 73113760Sjairo.balart@metempsy.com // Virtual Machine Control Register 73213531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR: 73313531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR_EL2: 73413531Sjairo.balart@metempsy.com break; 73513531Sjairo.balart@metempsy.com 73613531Sjairo.balart@metempsy.com default: 73713760Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)", 73813760Sjairo.balart@metempsy.com misc_reg, miscRegName[misc_reg]); 73913531Sjairo.balart@metempsy.com } 74013531Sjairo.balart@metempsy.com 74113760Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n", 74213760Sjairo.balart@metempsy.com miscRegName[misc_reg], value); 74313531Sjairo.balart@metempsy.com return value; 74413531Sjairo.balart@metempsy.com} 74513531Sjairo.balart@metempsy.com 74613531Sjairo.balart@metempsy.comvoid 74713580Sgabeblack@google.comGicv3CPUInterface::setMiscReg(int misc_reg, RegVal val) 74813531Sjairo.balart@metempsy.com{ 74913531Sjairo.balart@metempsy.com bool do_virtual_update = false; 75013760Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n", 75113760Sjairo.balart@metempsy.com miscRegName[misc_reg], val); 75213531Sjairo.balart@metempsy.com bool hcr_fmo = getHCREL2FMO(); 75313531Sjairo.balart@metempsy.com bool hcr_imo = getHCREL2IMO(); 75413531Sjairo.balart@metempsy.com 75513531Sjairo.balart@metempsy.com switch (misc_reg) { 75613760Sjairo.balart@metempsy.com // Active Priorities Group 1 Registers 75713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0: 75813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0_EL1: 75913531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 76013531Sjairo.balart@metempsy.com return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val); 76113531Sjairo.balart@metempsy.com } 76213531Sjairo.balart@metempsy.com 76313531Sjairo.balart@metempsy.com break; 76413531Sjairo.balart@metempsy.com 76513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1: 76613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1_EL1: 76713531Sjairo.balart@metempsy.com 76813531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 76913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2: 77013531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2_EL1: 77113531Sjairo.balart@metempsy.com 77213531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 77313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3: 77413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3_EL1: 77513531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 77613531Sjairo.balart@metempsy.com break; 77713531Sjairo.balart@metempsy.com 77813760Sjairo.balart@metempsy.com // Active Priorities Group 0 Registers 77913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0: 78013531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0_EL1: 78113531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 78213531Sjairo.balart@metempsy.com return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val); 78313531Sjairo.balart@metempsy.com } 78413531Sjairo.balart@metempsy.com 78513531Sjairo.balart@metempsy.com break; 78613531Sjairo.balart@metempsy.com 78713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1: 78813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1_EL1: 78913531Sjairo.balart@metempsy.com 79013531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 79113531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2: 79213531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2_EL1: 79313531Sjairo.balart@metempsy.com 79413531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 79513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3: 79613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3_EL1: 79713531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 79813531Sjairo.balart@metempsy.com break; 79913531Sjairo.balart@metempsy.com 80013760Sjairo.balart@metempsy.com // End Of Interrupt Register 0 80113531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR0: 80213531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0 80313531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 80413531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_EOIR0_EL1, val); 80513531Sjairo.balart@metempsy.com } 80613531Sjairo.balart@metempsy.com 80713531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 80813531Sjairo.balart@metempsy.com 80913531Sjairo.balart@metempsy.com // avoid activation for special interrupts 81013923Sgiacomo.travaglini@arm.com if (int_id >= Gicv3::INTID_SECURE && 81113923Sgiacomo.travaglini@arm.com int_id <= Gicv3::INTID_SPURIOUS) { 81213531Sjairo.balart@metempsy.com return; 81313531Sjairo.balart@metempsy.com } 81413531Sjairo.balart@metempsy.com 81513531Sjairo.balart@metempsy.com Gicv3::GroupId group = Gicv3::G0S; 81613531Sjairo.balart@metempsy.com 81713531Sjairo.balart@metempsy.com if (highestActiveGroup() != group) { 81813531Sjairo.balart@metempsy.com return; 81913531Sjairo.balart@metempsy.com } 82013531Sjairo.balart@metempsy.com 82113531Sjairo.balart@metempsy.com dropPriority(group); 82213531Sjairo.balart@metempsy.com 82313531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 82413531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 82513531Sjairo.balart@metempsy.com } 82613531Sjairo.balart@metempsy.com 82713531Sjairo.balart@metempsy.com break; 82813531Sjairo.balart@metempsy.com } 82913531Sjairo.balart@metempsy.com 83013760Sjairo.balart@metempsy.com // Virtual End Of Interrupt Register 0 83113531Sjairo.balart@metempsy.com case MISCREG_ICV_EOIR0_EL1: { 83213531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 83313531Sjairo.balart@metempsy.com 83413531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 83513531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 83613531Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 83713531Sjairo.balart@metempsy.com return; 83813531Sjairo.balart@metempsy.com } 83913531Sjairo.balart@metempsy.com 84013531Sjairo.balart@metempsy.com uint8_t drop_prio = virtualDropPriority(); 84113531Sjairo.balart@metempsy.com 84213531Sjairo.balart@metempsy.com if (drop_prio == 0xff) { 84313531Sjairo.balart@metempsy.com return; 84413531Sjairo.balart@metempsy.com } 84513531Sjairo.balart@metempsy.com 84613531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 84713531Sjairo.balart@metempsy.com 84813531Sjairo.balart@metempsy.com if (lr_idx < 0) { 84913531Sjairo.balart@metempsy.com // No LR found matching 85013531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 85113531Sjairo.balart@metempsy.com } else { 85213760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 85313531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 85413531Sjairo.balart@metempsy.com Gicv3::GroupId lr_group = 85513760Sjairo.balart@metempsy.com ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 85613760Sjairo.balart@metempsy.com uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8; 85713531Sjairo.balart@metempsy.com 85813531Sjairo.balart@metempsy.com if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) { 85913760Sjairo.balart@metempsy.com //if (!virtualIsEOISplitMode()) 86013531Sjairo.balart@metempsy.com { 86113531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 86213531Sjairo.balart@metempsy.com } 86313531Sjairo.balart@metempsy.com } 86413531Sjairo.balart@metempsy.com } 86513531Sjairo.balart@metempsy.com 86613531Sjairo.balart@metempsy.com virtualUpdate(); 86713531Sjairo.balart@metempsy.com break; 86813531Sjairo.balart@metempsy.com } 86913531Sjairo.balart@metempsy.com 87013760Sjairo.balart@metempsy.com // End Of Interrupt Register 1 87113531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR1: 87213760Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR1_EL1: { 87313531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 87413531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_EOIR1_EL1, val); 87513531Sjairo.balart@metempsy.com } 87613531Sjairo.balart@metempsy.com 87713531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 87813531Sjairo.balart@metempsy.com 87913531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 88013923Sgiacomo.travaglini@arm.com if (int_id >= Gicv3::INTID_SECURE && 88113923Sgiacomo.travaglini@arm.com int_id <= Gicv3::INTID_SPURIOUS) { 88213531Sjairo.balart@metempsy.com return; 88313531Sjairo.balart@metempsy.com } 88413531Sjairo.balart@metempsy.com 88513760Sjairo.balart@metempsy.com Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS; 88613531Sjairo.balart@metempsy.com 88713531Sjairo.balart@metempsy.com if (highestActiveGroup() == Gicv3::G0S) { 88813531Sjairo.balart@metempsy.com return; 88913531Sjairo.balart@metempsy.com } 89013531Sjairo.balart@metempsy.com 89113531Sjairo.balart@metempsy.com if (distributor->DS == 0) { 89213531Sjairo.balart@metempsy.com if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) { 89313531Sjairo.balart@metempsy.com return; 89413531Sjairo.balart@metempsy.com } else if (highestActiveGroup() == Gicv3::G1NS && 89513760Sjairo.balart@metempsy.com !(!inSecureState() or (currEL() == EL3))) { 89613531Sjairo.balart@metempsy.com return; 89713531Sjairo.balart@metempsy.com } 89813531Sjairo.balart@metempsy.com } 89913531Sjairo.balart@metempsy.com 90013531Sjairo.balart@metempsy.com dropPriority(group); 90113531Sjairo.balart@metempsy.com 90213531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 90313531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 90413531Sjairo.balart@metempsy.com } 90513531Sjairo.balart@metempsy.com 90613531Sjairo.balart@metempsy.com break; 90713531Sjairo.balart@metempsy.com } 90813531Sjairo.balart@metempsy.com 90913760Sjairo.balart@metempsy.com // Virtual End Of Interrupt Register 1 91013531Sjairo.balart@metempsy.com case MISCREG_ICV_EOIR1_EL1: { 91113531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 91213531Sjairo.balart@metempsy.com 91313531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 91413531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 91513760Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 91613531Sjairo.balart@metempsy.com return; 91713531Sjairo.balart@metempsy.com } 91813531Sjairo.balart@metempsy.com 91913531Sjairo.balart@metempsy.com uint8_t drop_prio = virtualDropPriority(); 92013531Sjairo.balart@metempsy.com 92113531Sjairo.balart@metempsy.com if (drop_prio == 0xff) { 92213531Sjairo.balart@metempsy.com return; 92313531Sjairo.balart@metempsy.com } 92413531Sjairo.balart@metempsy.com 92513531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 92613531Sjairo.balart@metempsy.com 92713531Sjairo.balart@metempsy.com if (lr_idx < 0) { 92813760Sjairo.balart@metempsy.com // No matching LR found 92913531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 93013531Sjairo.balart@metempsy.com } else { 93113760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 93213531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 93313531Sjairo.balart@metempsy.com Gicv3::GroupId lr_group = 93413760Sjairo.balart@metempsy.com ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 93513760Sjairo.balart@metempsy.com uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8; 93613531Sjairo.balart@metempsy.com 93713531Sjairo.balart@metempsy.com if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) { 93813531Sjairo.balart@metempsy.com if (!virtualIsEOISplitMode()) { 93913531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 94013531Sjairo.balart@metempsy.com } 94113531Sjairo.balart@metempsy.com } 94213531Sjairo.balart@metempsy.com } 94313531Sjairo.balart@metempsy.com 94413531Sjairo.balart@metempsy.com virtualUpdate(); 94513531Sjairo.balart@metempsy.com break; 94613531Sjairo.balart@metempsy.com } 94713531Sjairo.balart@metempsy.com 94813760Sjairo.balart@metempsy.com // Deactivate Interrupt Register 94913531Sjairo.balart@metempsy.com case MISCREG_ICC_DIR: 95013760Sjairo.balart@metempsy.com case MISCREG_ICC_DIR_EL1: { 95113531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 95213760Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 95313531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_DIR_EL1, val); 95413531Sjairo.balart@metempsy.com } 95513531Sjairo.balart@metempsy.com 95613531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 95713531Sjairo.balart@metempsy.com 95813760Sjairo.balart@metempsy.com // The following checks are as per spec pseudocode 95913760Sjairo.balart@metempsy.com // aarch64/support/ICC_DIR_EL1 96013760Sjairo.balart@metempsy.com 96113760Sjairo.balart@metempsy.com // Check for spurious ID 96213531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE) { 96313531Sjairo.balart@metempsy.com return; 96413531Sjairo.balart@metempsy.com } 96513531Sjairo.balart@metempsy.com 96613760Sjairo.balart@metempsy.com // EOI mode is not set, so don't deactivate 96713531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 96813531Sjairo.balart@metempsy.com return; 96913531Sjairo.balart@metempsy.com } 97013531Sjairo.balart@metempsy.com 97113531Sjairo.balart@metempsy.com Gicv3::GroupId group = 97213531Sjairo.balart@metempsy.com int_id >= 32 ? distributor->getIntGroup(int_id) : 97313531Sjairo.balart@metempsy.com redistributor->getIntGroup(int_id); 97413531Sjairo.balart@metempsy.com bool irq_is_grp0 = group == Gicv3::G0S; 97513531Sjairo.balart@metempsy.com bool single_sec_state = distributor->DS; 97613531Sjairo.balart@metempsy.com bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS); 97713531Sjairo.balart@metempsy.com SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 97813531Sjairo.balart@metempsy.com bool route_fiq_to_el3 = scr_el3.fiq; 97913531Sjairo.balart@metempsy.com bool route_irq_to_el3 = scr_el3.irq; 98013531Sjairo.balart@metempsy.com bool route_fiq_to_el2 = hcr_fmo; 98113531Sjairo.balart@metempsy.com bool route_irq_to_el2 = hcr_imo; 98213531Sjairo.balart@metempsy.com 98313531Sjairo.balart@metempsy.com switch (currEL()) { 98413531Sjairo.balart@metempsy.com case EL3: 98513531Sjairo.balart@metempsy.com break; 98613531Sjairo.balart@metempsy.com 98713531Sjairo.balart@metempsy.com case EL2: 98813531Sjairo.balart@metempsy.com if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) { 98913531Sjairo.balart@metempsy.com break; 99013531Sjairo.balart@metempsy.com } 99113531Sjairo.balart@metempsy.com 99213531Sjairo.balart@metempsy.com if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) { 99313531Sjairo.balart@metempsy.com break; 99413531Sjairo.balart@metempsy.com } 99513531Sjairo.balart@metempsy.com 99613531Sjairo.balart@metempsy.com return; 99713531Sjairo.balart@metempsy.com 99813531Sjairo.balart@metempsy.com case EL1: 99913531Sjairo.balart@metempsy.com if (!isSecureBelowEL3()) { 100013531Sjairo.balart@metempsy.com if (single_sec_state && irq_is_grp0 && 100113760Sjairo.balart@metempsy.com !route_fiq_to_el3 && !route_fiq_to_el2) { 100213531Sjairo.balart@metempsy.com break; 100313531Sjairo.balart@metempsy.com } 100413531Sjairo.balart@metempsy.com 100513531Sjairo.balart@metempsy.com if (!irq_is_secure && !irq_is_grp0 && 100613760Sjairo.balart@metempsy.com !route_irq_to_el3 && !route_irq_to_el2) { 100713531Sjairo.balart@metempsy.com break; 100813531Sjairo.balart@metempsy.com } 100913531Sjairo.balart@metempsy.com } else { 101013531Sjairo.balart@metempsy.com if (irq_is_grp0 && !route_fiq_to_el3) { 101113531Sjairo.balart@metempsy.com break; 101213531Sjairo.balart@metempsy.com } 101313531Sjairo.balart@metempsy.com 101413531Sjairo.balart@metempsy.com if (!irq_is_grp0 && 101513760Sjairo.balart@metempsy.com (!irq_is_secure || !single_sec_state) && 101613760Sjairo.balart@metempsy.com !route_irq_to_el3) { 101713531Sjairo.balart@metempsy.com break; 101813531Sjairo.balart@metempsy.com } 101913531Sjairo.balart@metempsy.com } 102013531Sjairo.balart@metempsy.com 102113531Sjairo.balart@metempsy.com return; 102213531Sjairo.balart@metempsy.com 102313531Sjairo.balart@metempsy.com default: 102413531Sjairo.balart@metempsy.com break; 102513531Sjairo.balart@metempsy.com } 102613531Sjairo.balart@metempsy.com 102713531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 102813531Sjairo.balart@metempsy.com break; 102913531Sjairo.balart@metempsy.com } 103013531Sjairo.balart@metempsy.com 103113760Sjairo.balart@metempsy.com // Deactivate Virtual Interrupt Register 103213531Sjairo.balart@metempsy.com case MISCREG_ICV_DIR_EL1: { 103313531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 103413531Sjairo.balart@metempsy.com 103513531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 103613531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 103713760Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 103813531Sjairo.balart@metempsy.com return; 103913531Sjairo.balart@metempsy.com } 104013531Sjairo.balart@metempsy.com 104113531Sjairo.balart@metempsy.com if (!virtualIsEOISplitMode()) { 104213531Sjairo.balart@metempsy.com return; 104313531Sjairo.balart@metempsy.com } 104413531Sjairo.balart@metempsy.com 104513531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 104613531Sjairo.balart@metempsy.com 104713531Sjairo.balart@metempsy.com if (lr_idx < 0) { 104813760Sjairo.balart@metempsy.com // No matching LR found 104913531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 105013531Sjairo.balart@metempsy.com } else { 105113531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 105213531Sjairo.balart@metempsy.com } 105313531Sjairo.balart@metempsy.com 105413531Sjairo.balart@metempsy.com virtualUpdate(); 105513531Sjairo.balart@metempsy.com break; 105613531Sjairo.balart@metempsy.com } 105713531Sjairo.balart@metempsy.com 105813760Sjairo.balart@metempsy.com // Binary Point Register 0 105913531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0: 106013760Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0_EL1: 106113760Sjairo.balart@metempsy.com // Binary Point Register 1 106213531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1: 106313760Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1_EL1: { 106413531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState()) { 106513531Sjairo.balart@metempsy.com if (misc_reg == MISCREG_ICC_BPR0_EL1 && hcr_fmo) { 106613531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_BPR0_EL1, val); 106713531Sjairo.balart@metempsy.com } else if (misc_reg == MISCREG_ICC_BPR1_EL1 && hcr_imo) { 106813531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_BPR1_EL1, val); 106913531Sjairo.balart@metempsy.com } 107013531Sjairo.balart@metempsy.com } 107113531Sjairo.balart@metempsy.com 107213531Sjairo.balart@metempsy.com Gicv3::GroupId group = 107313531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S; 107413531Sjairo.balart@metempsy.com 107513531Sjairo.balart@metempsy.com if (group == Gicv3::G1S && !inSecureState()) { 107613531Sjairo.balart@metempsy.com group = Gicv3::G1NS; 107713531Sjairo.balart@metempsy.com } 107813531Sjairo.balart@metempsy.com 107913760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_s = 108013760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 108113760Sjairo.balart@metempsy.com 108213760Sjairo.balart@metempsy.com if ((group == Gicv3::G1S) && !isEL3OrMon() && 108313760Sjairo.balart@metempsy.com icc_ctlr_el1_s.CBPR) { 108413531Sjairo.balart@metempsy.com group = Gicv3::G0S; 108513531Sjairo.balart@metempsy.com } 108613531Sjairo.balart@metempsy.com 108713760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_ns = 108813760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 108913760Sjairo.balart@metempsy.com 109013760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && (currEL() < EL3) && 109113760Sjairo.balart@metempsy.com icc_ctlr_el1_ns.CBPR) { 109213760Sjairo.balart@metempsy.com // BPR0 + 1 saturated to 7, WI 109313531Sjairo.balart@metempsy.com return; 109413531Sjairo.balart@metempsy.com } 109513531Sjairo.balart@metempsy.com 109613531Sjairo.balart@metempsy.com uint8_t min_val = (group == Gicv3::G1NS) ? 109713531Sjairo.balart@metempsy.com GIC_MIN_BPR_NS : GIC_MIN_BPR; 109813531Sjairo.balart@metempsy.com val &= 0x7; 109913531Sjairo.balart@metempsy.com 110013531Sjairo.balart@metempsy.com if (val < min_val) { 110113531Sjairo.balart@metempsy.com val = min_val; 110213531Sjairo.balart@metempsy.com } 110313531Sjairo.balart@metempsy.com 110413531Sjairo.balart@metempsy.com break; 110513531Sjairo.balart@metempsy.com } 110613531Sjairo.balart@metempsy.com 110713760Sjairo.balart@metempsy.com // Virtual Binary Point Register 0 110813531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR0_EL1: 110913760Sjairo.balart@metempsy.com // Virtual Binary Point Register 1 111013531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR1_EL1: { 111113531Sjairo.balart@metempsy.com Gicv3::GroupId group = 111213531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS; 111313760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 111413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 111513531Sjairo.balart@metempsy.com 111613760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) { 111713760Sjairo.balart@metempsy.com // BPR0 + 1 saturated to 7, WI 111813531Sjairo.balart@metempsy.com return; 111913531Sjairo.balart@metempsy.com } 112013531Sjairo.balart@metempsy.com 112113531Sjairo.balart@metempsy.com uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS; 112213531Sjairo.balart@metempsy.com 112313531Sjairo.balart@metempsy.com if (group != Gicv3::G0S) { 112413531Sjairo.balart@metempsy.com min_VPBR++; 112513531Sjairo.balart@metempsy.com } 112613531Sjairo.balart@metempsy.com 112713531Sjairo.balart@metempsy.com if (val < min_VPBR) { 112813531Sjairo.balart@metempsy.com val = min_VPBR; 112913531Sjairo.balart@metempsy.com } 113013531Sjairo.balart@metempsy.com 113113531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 113213760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR0 = val; 113313531Sjairo.balart@metempsy.com } else { 113413760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR1 = val; 113513531Sjairo.balart@metempsy.com } 113613531Sjairo.balart@metempsy.com 113713531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 113813531Sjairo.balart@metempsy.com do_virtual_update = true; 113913531Sjairo.balart@metempsy.com break; 114013531Sjairo.balart@metempsy.com } 114113531Sjairo.balart@metempsy.com 114213760Sjairo.balart@metempsy.com // Control Register EL1 114313531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR: 114413760Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL1: { 114513760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) { 114613531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_CTLR_EL1, val); 114713531Sjairo.balart@metempsy.com } 114813531Sjairo.balart@metempsy.com 114913531Sjairo.balart@metempsy.com /* 115013760Sjairo.balart@metempsy.com * ExtRange is RO. 115113531Sjairo.balart@metempsy.com * RSS is RO. 115213531Sjairo.balart@metempsy.com * A3V is RO. 115313531Sjairo.balart@metempsy.com * SEIS is RO. 115413531Sjairo.balart@metempsy.com * IDbits is RO. 115513531Sjairo.balart@metempsy.com * PRIbits is RO. 115613531Sjairo.balart@metempsy.com */ 115713760Sjairo.balart@metempsy.com ICC_CTLR_EL1 requested_icc_ctlr_el1 = val; 115813760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1 = 115913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1); 116013760Sjairo.balart@metempsy.com 116113760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = 116213760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 116313760Sjairo.balart@metempsy.com 116413760Sjairo.balart@metempsy.com // The following could be refactored but it is following 116513760Sjairo.balart@metempsy.com // spec description section 9.2.6 point by point. 116613760Sjairo.balart@metempsy.com 116713760Sjairo.balart@metempsy.com // PMHE 116813760Sjairo.balart@metempsy.com if (haveEL(EL3)) { 116913760Sjairo.balart@metempsy.com // PMHE is alias of ICC_CTLR_EL3.PMHE 117013760Sjairo.balart@metempsy.com 117113760Sjairo.balart@metempsy.com if (distributor->DS == 0) { 117213760Sjairo.balart@metempsy.com // PMHE is RO 117313760Sjairo.balart@metempsy.com } else if (distributor->DS == 1) { 117413760Sjairo.balart@metempsy.com // PMHE is RW 117513760Sjairo.balart@metempsy.com icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE; 117613760Sjairo.balart@metempsy.com icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE; 117713760Sjairo.balart@metempsy.com } 117813531Sjairo.balart@metempsy.com } else { 117913760Sjairo.balart@metempsy.com // PMHE is RW (by implementation choice) 118013760Sjairo.balart@metempsy.com icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE; 118113531Sjairo.balart@metempsy.com } 118213531Sjairo.balart@metempsy.com 118313760Sjairo.balart@metempsy.com // EOImode 118413760Sjairo.balart@metempsy.com icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode; 118513760Sjairo.balart@metempsy.com 118613760Sjairo.balart@metempsy.com if (inSecureState()) { 118713760Sjairo.balart@metempsy.com // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S 118813760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode; 118913760Sjairo.balart@metempsy.com } else { 119013760Sjairo.balart@metempsy.com // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS 119113760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode; 119213760Sjairo.balart@metempsy.com } 119313760Sjairo.balart@metempsy.com 119413760Sjairo.balart@metempsy.com // CBPR 119513760Sjairo.balart@metempsy.com if (haveEL(EL3)) { 119613760Sjairo.balart@metempsy.com // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS} 119713760Sjairo.balart@metempsy.com 119813760Sjairo.balart@metempsy.com if (distributor->DS == 0) { 119913760Sjairo.balart@metempsy.com // CBPR is RO 120013760Sjairo.balart@metempsy.com } else { 120113760Sjairo.balart@metempsy.com // CBPR is RW 120213760Sjairo.balart@metempsy.com icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR; 120313760Sjairo.balart@metempsy.com 120413760Sjairo.balart@metempsy.com if (inSecureState()) { 120513760Sjairo.balart@metempsy.com icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR; 120613760Sjairo.balart@metempsy.com } else { 120713760Sjairo.balart@metempsy.com icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR; 120813760Sjairo.balart@metempsy.com } 120913760Sjairo.balart@metempsy.com } 121013760Sjairo.balart@metempsy.com } else { 121113760Sjairo.balart@metempsy.com // CBPR is RW 121213760Sjairo.balart@metempsy.com icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR; 121313760Sjairo.balart@metempsy.com } 121413760Sjairo.balart@metempsy.com 121513760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3); 121613760Sjairo.balart@metempsy.com 121713760Sjairo.balart@metempsy.com val = icc_ctlr_el1; 121813531Sjairo.balart@metempsy.com break; 121913531Sjairo.balart@metempsy.com } 122013531Sjairo.balart@metempsy.com 122113760Sjairo.balart@metempsy.com // Virtual Control Register 122213531Sjairo.balart@metempsy.com case MISCREG_ICV_CTLR_EL1: { 122313760Sjairo.balart@metempsy.com ICV_CTLR_EL1 requested_icv_ctlr_el1 = val; 122413760Sjairo.balart@metempsy.com ICV_CTLR_EL1 icv_ctlr_el1 = 122513760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1); 122613760Sjairo.balart@metempsy.com icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode; 122713760Sjairo.balart@metempsy.com icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR; 122813760Sjairo.balart@metempsy.com val = icv_ctlr_el1; 122913760Sjairo.balart@metempsy.com 123013760Sjairo.balart@metempsy.com // Aliases 123113760Sjairo.balart@metempsy.com // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR. 123213760Sjairo.balart@metempsy.com // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM. 123313760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 123413760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 123513760Sjairo.balart@metempsy.com ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR; 123613760Sjairo.balart@metempsy.com ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode; 123713760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 123813760Sjairo.balart@metempsy.com break; 123913760Sjairo.balart@metempsy.com } 124013760Sjairo.balart@metempsy.com 124113760Sjairo.balart@metempsy.com // Control Register EL3 124213760Sjairo.balart@metempsy.com case MISCREG_ICC_MCTLR: 124313760Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL3: { 124413760Sjairo.balart@metempsy.com /* 124513760Sjairo.balart@metempsy.com * ExtRange is RO. 124613760Sjairo.balart@metempsy.com * RSS is RO. 124713760Sjairo.balart@metempsy.com * nDS is RO. 124813760Sjairo.balart@metempsy.com * A3V is RO. 124913760Sjairo.balart@metempsy.com * SEIS is RO. 125013760Sjairo.balart@metempsy.com * IDbits is RO. 125113760Sjairo.balart@metempsy.com * PRIbits is RO. 125213760Sjairo.balart@metempsy.com * PMHE is RAO/WI, priority-based routing is always used. 125313760Sjairo.balart@metempsy.com */ 125413760Sjairo.balart@metempsy.com ICC_CTLR_EL3 requested_icc_ctlr_el3 = val; 125513760Sjairo.balart@metempsy.com 125613760Sjairo.balart@metempsy.com // Aliases 125713760Sjairo.balart@metempsy.com if (haveEL(EL3)) 125813760Sjairo.balart@metempsy.com { 125913760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_s = 126013760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 126113760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_ns = 126213760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 126313760Sjairo.balart@metempsy.com 126413760Sjairo.balart@metempsy.com // ICC_CTLR_EL1(NS).EOImode is an alias of 126513760Sjairo.balart@metempsy.com // ICC_CTLR_EL3.EOImode_EL1NS 126613760Sjairo.balart@metempsy.com icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS; 126713760Sjairo.balart@metempsy.com // ICC_CTLR_EL1(S).EOImode is an alias of 126813760Sjairo.balart@metempsy.com // ICC_CTLR_EL3.EOImode_EL1S 126913760Sjairo.balart@metempsy.com icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S; 127013760Sjairo.balart@metempsy.com // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS 127113760Sjairo.balart@metempsy.com icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS; 127213760Sjairo.balart@metempsy.com // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S 127313760Sjairo.balart@metempsy.com icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S; 127413760Sjairo.balart@metempsy.com 127513760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s); 127613760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS, 127713760Sjairo.balart@metempsy.com icc_ctlr_el1_ns); 127813760Sjairo.balart@metempsy.com } 127913760Sjairo.balart@metempsy.com 128013760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = 128113760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 128213760Sjairo.balart@metempsy.com 128313760Sjairo.balart@metempsy.com icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM; 128413760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS; 128513760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S; 128613760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3; 128713760Sjairo.balart@metempsy.com icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS; 128813760Sjairo.balart@metempsy.com icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S; 128913760Sjairo.balart@metempsy.com 129013760Sjairo.balart@metempsy.com val = icc_ctlr_el3; 129113531Sjairo.balart@metempsy.com break; 129213531Sjairo.balart@metempsy.com } 129313531Sjairo.balart@metempsy.com 129413760Sjairo.balart@metempsy.com // Priority Mask Register 129513531Sjairo.balart@metempsy.com case MISCREG_ICC_PMR: 129613760Sjairo.balart@metempsy.com case MISCREG_ICC_PMR_EL1: { 129713760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) { 129814057Sgiacomo.travaglini@arm.com return setMiscReg(MISCREG_ICV_PMR_EL1, val); 129913531Sjairo.balart@metempsy.com } 130013531Sjairo.balart@metempsy.com 130113531Sjairo.balart@metempsy.com val &= 0xff; 130213531Sjairo.balart@metempsy.com SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 130313531Sjairo.balart@metempsy.com 130413531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) { 130513760Sjairo.balart@metempsy.com // Spec section 4.8.1 130613760Sjairo.balart@metempsy.com // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1: 130713580Sgabeblack@google.com RegVal old_icc_pmr_el1 = 130813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1); 130913531Sjairo.balart@metempsy.com 131013531Sjairo.balart@metempsy.com if (!(old_icc_pmr_el1 & 0x80)) { 131113760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 131213760Sjairo.balart@metempsy.com // 0x00-0x7F then WI 131313531Sjairo.balart@metempsy.com return; 131413531Sjairo.balart@metempsy.com } 131513531Sjairo.balart@metempsy.com 131613760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 131713760Sjairo.balart@metempsy.com // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds, 131813760Sjairo.balart@metempsy.com // based on the Non-secure read of the priority mask value 131913760Sjairo.balart@metempsy.com // written to the register. 132013760Sjairo.balart@metempsy.com 132113531Sjairo.balart@metempsy.com val = (val >> 1) | 0x80; 132213531Sjairo.balart@metempsy.com } 132313531Sjairo.balart@metempsy.com 132413531Sjairo.balart@metempsy.com val &= ~0U << (8 - PRIORITY_BITS); 132513531Sjairo.balart@metempsy.com break; 132613531Sjairo.balart@metempsy.com } 132713531Sjairo.balart@metempsy.com 132814057Sgiacomo.travaglini@arm.com case MISCREG_ICV_PMR_EL1: { // Priority Mask Register 132914057Sgiacomo.travaglini@arm.com ICH_VMCR_EL2 ich_vmcr_el2 = 133014057Sgiacomo.travaglini@arm.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 133114057Sgiacomo.travaglini@arm.com ich_vmcr_el2.VPMR = val & 0xff; 133214057Sgiacomo.travaglini@arm.com 133314057Sgiacomo.travaglini@arm.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 133414057Sgiacomo.travaglini@arm.com virtualUpdate(); 133514057Sgiacomo.travaglini@arm.com return; 133614057Sgiacomo.travaglini@arm.com } 133714057Sgiacomo.travaglini@arm.com 133813760Sjairo.balart@metempsy.com // Interrupt Group 0 Enable Register EL1 133913760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0: 134013760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0_EL1: { 134113760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 134213760Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val); 134313760Sjairo.balart@metempsy.com } 134413760Sjairo.balart@metempsy.com 134513760Sjairo.balart@metempsy.com break; 134613760Sjairo.balart@metempsy.com } 134713760Sjairo.balart@metempsy.com 134813760Sjairo.balart@metempsy.com // Virtual Interrupt Group 0 Enable register 134913760Sjairo.balart@metempsy.com case MISCREG_ICV_IGRPEN0_EL1: { 135013760Sjairo.balart@metempsy.com bool enable = val & 0x1; 135113760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 135213760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 135313760Sjairo.balart@metempsy.com ich_vmcr_el2.VENG0 = enable; 135413740Sgiacomo.travaglini@arm.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 135513740Sgiacomo.travaglini@arm.com virtualUpdate(); 135613740Sgiacomo.travaglini@arm.com return; 135713740Sgiacomo.travaglini@arm.com } 135813740Sgiacomo.travaglini@arm.com 135913760Sjairo.balart@metempsy.com // Interrupt Group 1 Enable register EL1 136013760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1: 136113760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL1: { 136213760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 136313760Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val); 136413760Sjairo.balart@metempsy.com } 136513760Sjairo.balart@metempsy.com 136613760Sjairo.balart@metempsy.com if (haveEL(EL3)) { 136713760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1 icc_igrpen1_el1 = val; 136813760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL3 icc_igrpen1_el3 = 136913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3); 137013760Sjairo.balart@metempsy.com 137113760Sjairo.balart@metempsy.com if (inSecureState()) { 137213760Sjairo.balart@metempsy.com // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1S 137313760Sjairo.balart@metempsy.com icc_igrpen1_el3.EnableGrp1S = icc_igrpen1_el1.Enable; 137413760Sjairo.balart@metempsy.com } else { 137513760Sjairo.balart@metempsy.com // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1NS 137613760Sjairo.balart@metempsy.com icc_igrpen1_el3.EnableGrp1NS = icc_igrpen1_el1.Enable; 137713760Sjairo.balart@metempsy.com } 137813760Sjairo.balart@metempsy.com 137913760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3, 138013760Sjairo.balart@metempsy.com icc_igrpen1_el3); 138113531Sjairo.balart@metempsy.com } 138213531Sjairo.balart@metempsy.com 138313531Sjairo.balart@metempsy.com break; 138413531Sjairo.balart@metempsy.com } 138513531Sjairo.balart@metempsy.com 138613760Sjairo.balart@metempsy.com // Virtual Interrupt Group 1 Enable register 138713760Sjairo.balart@metempsy.com case MISCREG_ICV_IGRPEN1_EL1: { 138813531Sjairo.balart@metempsy.com bool enable = val & 0x1; 138913760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 139013531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 139113760Sjairo.balart@metempsy.com ich_vmcr_el2.VENG1 = enable; 139213531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 139313531Sjairo.balart@metempsy.com virtualUpdate(); 139413531Sjairo.balart@metempsy.com return; 139513531Sjairo.balart@metempsy.com } 139613531Sjairo.balart@metempsy.com 139713760Sjairo.balart@metempsy.com // Interrupt Group 1 Enable register 139813760Sjairo.balart@metempsy.com case MISCREG_ICC_MGRPEN1: 139913760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL3: { 140013760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val; 140113760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1 icc_igrpen1_el1 = 140213760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1); 140313760Sjairo.balart@metempsy.com 140413760Sjairo.balart@metempsy.com if (inSecureState()) { 140513760Sjairo.balart@metempsy.com // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1S 140613760Sjairo.balart@metempsy.com icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1S; 140713760Sjairo.balart@metempsy.com } else { 140813760Sjairo.balart@metempsy.com // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1NS 140913760Sjairo.balart@metempsy.com icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1NS; 141013531Sjairo.balart@metempsy.com } 141113531Sjairo.balart@metempsy.com 141213760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1, icc_igrpen1_el1); 141313531Sjairo.balart@metempsy.com break; 141413531Sjairo.balart@metempsy.com } 141513531Sjairo.balart@metempsy.com 141613760Sjairo.balart@metempsy.com // Software Generated Interrupt Group 0 Register 141713531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI0R: 141813531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI0R_EL1: 141913531Sjairo.balart@metempsy.com 142013760Sjairo.balart@metempsy.com // Software Generated Interrupt Group 1 Register 142113531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI1R: 142213531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI1R_EL1: 142313531Sjairo.balart@metempsy.com 142413760Sjairo.balart@metempsy.com // Alias Software Generated Interrupt Group 1 Register 142513531Sjairo.balart@metempsy.com case MISCREG_ICC_ASGI1R: 142613531Sjairo.balart@metempsy.com case MISCREG_ICC_ASGI1R_EL1: { 142713531Sjairo.balart@metempsy.com bool ns = !inSecureState(); 142813531Sjairo.balart@metempsy.com Gicv3::GroupId group; 142913531Sjairo.balart@metempsy.com 143013531Sjairo.balart@metempsy.com if (misc_reg == MISCREG_ICC_SGI1R_EL1) { 143113531Sjairo.balart@metempsy.com group = ns ? Gicv3::G1NS : Gicv3::G1S; 143213531Sjairo.balart@metempsy.com } else if (misc_reg == MISCREG_ICC_ASGI1R_EL1) { 143313531Sjairo.balart@metempsy.com group = ns ? Gicv3::G1S : Gicv3::G1NS; 143413531Sjairo.balart@metempsy.com } else { 143513531Sjairo.balart@metempsy.com group = Gicv3::G0S; 143613531Sjairo.balart@metempsy.com } 143713531Sjairo.balart@metempsy.com 143813531Sjairo.balart@metempsy.com if (distributor->DS && group == Gicv3::G1S) { 143913531Sjairo.balart@metempsy.com group = Gicv3::G0S; 144013531Sjairo.balart@metempsy.com } 144113531Sjairo.balart@metempsy.com 144213531Sjairo.balart@metempsy.com uint8_t aff3 = bits(val, 55, 48); 144313531Sjairo.balart@metempsy.com uint8_t aff2 = bits(val, 39, 32); 144413531Sjairo.balart@metempsy.com uint8_t aff1 = bits(val, 23, 16);; 144513531Sjairo.balart@metempsy.com uint16_t target_list = bits(val, 15, 0); 144613531Sjairo.balart@metempsy.com uint32_t int_id = bits(val, 27, 24); 144713531Sjairo.balart@metempsy.com bool irm = bits(val, 40, 40); 144813531Sjairo.balart@metempsy.com uint8_t rs = bits(val, 47, 44); 144913531Sjairo.balart@metempsy.com 145013531Sjairo.balart@metempsy.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 145113531Sjairo.balart@metempsy.com Gicv3Redistributor * redistributor_i = 145213531Sjairo.balart@metempsy.com gic->getRedistributor(i); 145313531Sjairo.balart@metempsy.com uint32_t affinity_i = redistributor_i->getAffinity(); 145413531Sjairo.balart@metempsy.com 145513531Sjairo.balart@metempsy.com if (irm) { 145613531Sjairo.balart@metempsy.com // Interrupts routed to all PEs in the system, 145713531Sjairo.balart@metempsy.com // excluding "self" 145813531Sjairo.balart@metempsy.com if (affinity_i == redistributor->getAffinity()) { 145913531Sjairo.balart@metempsy.com continue; 146013531Sjairo.balart@metempsy.com } 146113531Sjairo.balart@metempsy.com } else { 146213531Sjairo.balart@metempsy.com // Interrupts routed to the PEs specified by 146313531Sjairo.balart@metempsy.com // Aff3.Aff2.Aff1.<target list> 146413531Sjairo.balart@metempsy.com if ((affinity_i >> 8) != 146513760Sjairo.balart@metempsy.com ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) { 146613531Sjairo.balart@metempsy.com continue; 146713531Sjairo.balart@metempsy.com } 146813531Sjairo.balart@metempsy.com 146913531Sjairo.balart@metempsy.com uint8_t aff0_i = bits(affinity_i, 7, 0); 147013531Sjairo.balart@metempsy.com 147113531Sjairo.balart@metempsy.com if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 && 147213760Sjairo.balart@metempsy.com ((0x1 << (aff0_i - rs * 16)) & target_list))) { 147313531Sjairo.balart@metempsy.com continue; 147413531Sjairo.balart@metempsy.com } 147513531Sjairo.balart@metempsy.com } 147613531Sjairo.balart@metempsy.com 147713531Sjairo.balart@metempsy.com redistributor_i->sendSGI(int_id, group, ns); 147813531Sjairo.balart@metempsy.com } 147913531Sjairo.balart@metempsy.com 148013531Sjairo.balart@metempsy.com break; 148113531Sjairo.balart@metempsy.com } 148213531Sjairo.balart@metempsy.com 148313760Sjairo.balart@metempsy.com // System Register Enable Register EL1 148413531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE: 148513760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL1: 148613760Sjairo.balart@metempsy.com // System Register Enable Register EL2 148713531Sjairo.balart@metempsy.com case MISCREG_ICC_HSRE: 148813760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL2: 148913760Sjairo.balart@metempsy.com // System Register Enable Register EL3 149013531Sjairo.balart@metempsy.com case MISCREG_ICC_MSRE: 149113760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL3: 149213760Sjairo.balart@metempsy.com // All bits are RAO/WI 149313760Sjairo.balart@metempsy.com return; 149413760Sjairo.balart@metempsy.com 149513760Sjairo.balart@metempsy.com // Hyp Control Register 149613760Sjairo.balart@metempsy.com case MISCREG_ICH_HCR: 149713760Sjairo.balart@metempsy.com case MISCREG_ICH_HCR_EL2: { 149813760Sjairo.balart@metempsy.com ICH_HCR_EL2 requested_ich_hcr_el2 = val; 149913760Sjairo.balart@metempsy.com ICH_HCR_EL2 ich_hcr_el2 = 150013760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 150113760Sjairo.balart@metempsy.com 150213760Sjairo.balart@metempsy.com if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount) 150313760Sjairo.balart@metempsy.com { 150413760Sjairo.balart@metempsy.com // EOIcount - Permitted behaviors are: 150513760Sjairo.balart@metempsy.com // - Increment EOIcount. 150613760Sjairo.balart@metempsy.com // - Leave EOIcount unchanged. 150713760Sjairo.balart@metempsy.com ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount; 150813531Sjairo.balart@metempsy.com } 150913531Sjairo.balart@metempsy.com 151013760Sjairo.balart@metempsy.com ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR; 151113760Sjairo.balart@metempsy.com ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI; 151213760Sjairo.balart@metempsy.com ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;; 151313760Sjairo.balart@metempsy.com ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;; 151413760Sjairo.balart@metempsy.com ich_hcr_el2.TC = requested_ich_hcr_el2.TC; 151513760Sjairo.balart@metempsy.com ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE; 151613760Sjairo.balart@metempsy.com ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE; 151713760Sjairo.balart@metempsy.com ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE; 151813760Sjairo.balart@metempsy.com ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE; 151913760Sjairo.balart@metempsy.com ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE; 152013760Sjairo.balart@metempsy.com ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE; 152113760Sjairo.balart@metempsy.com ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE; 152213760Sjairo.balart@metempsy.com ich_hcr_el2.En = requested_ich_hcr_el2.En; 152313760Sjairo.balart@metempsy.com val = ich_hcr_el2; 152413531Sjairo.balart@metempsy.com do_virtual_update = true; 152513531Sjairo.balart@metempsy.com break; 152613760Sjairo.balart@metempsy.com } 152713760Sjairo.balart@metempsy.com 152813760Sjairo.balart@metempsy.com // List Registers 152913760Sjairo.balart@metempsy.com case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: { 153013531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part) 153113760Sjairo.balart@metempsy.com ICH_LRC requested_ich_lrc = val; 153213760Sjairo.balart@metempsy.com ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg); 153313760Sjairo.balart@metempsy.com 153413760Sjairo.balart@metempsy.com ich_lrc.State = requested_ich_lrc.State; 153513760Sjairo.balart@metempsy.com ich_lrc.HW = requested_ich_lrc.HW; 153613760Sjairo.balart@metempsy.com ich_lrc.Group = requested_ich_lrc.Group; 153713760Sjairo.balart@metempsy.com 153813760Sjairo.balart@metempsy.com // Priority, bits [23:16] 153913760Sjairo.balart@metempsy.com // At least five bits must be implemented. 154013760Sjairo.balart@metempsy.com // Unimplemented bits are RES0 and start from bit[16] up to bit[18]. 154113760Sjairo.balart@metempsy.com // We implement 5 bits. 154213760Sjairo.balart@metempsy.com ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) | 154313760Sjairo.balart@metempsy.com (ich_lrc.Priority & 0x07); 154413760Sjairo.balart@metempsy.com 154513760Sjairo.balart@metempsy.com // pINTID, bits [12:0] 154613760Sjairo.balart@metempsy.com // When ICH_LR<n>.HW is 0 this field has the following meaning: 154713760Sjairo.balart@metempsy.com // - Bits[12:10] : RES0. 154813760Sjairo.balart@metempsy.com // - Bit[9] : EOI. 154913760Sjairo.balart@metempsy.com // - Bits[8:0] : RES0. 155013760Sjairo.balart@metempsy.com // When ICH_LR<n>.HW is 1: 155113760Sjairo.balart@metempsy.com // - This field is only required to implement enough bits to hold a 155213760Sjairo.balart@metempsy.com // valid value for the implemented INTID size. Any unused higher 155313760Sjairo.balart@metempsy.com // order bits are RES0. 155413760Sjairo.balart@metempsy.com if (requested_ich_lrc.HW == 0) { 155513760Sjairo.balart@metempsy.com ich_lrc.EOI = requested_ich_lrc.EOI; 155613760Sjairo.balart@metempsy.com } else { 155713760Sjairo.balart@metempsy.com ich_lrc.pINTID = requested_ich_lrc.pINTID; 155813531Sjairo.balart@metempsy.com } 155913531Sjairo.balart@metempsy.com 156013760Sjairo.balart@metempsy.com val = ich_lrc; 156113760Sjairo.balart@metempsy.com do_virtual_update = true; 156213760Sjairo.balart@metempsy.com break; 156313760Sjairo.balart@metempsy.com } 156413760Sjairo.balart@metempsy.com 156513760Sjairo.balart@metempsy.com // List Registers 156613531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: { 156713531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part) 156813580Sgabeblack@google.com RegVal old_val = isa->readMiscRegNoEffect(misc_reg); 156913531Sjairo.balart@metempsy.com val = (old_val & 0xffffffff00000000) | (val & 0xffffffff); 157013531Sjairo.balart@metempsy.com do_virtual_update = true; 157113531Sjairo.balart@metempsy.com break; 157213531Sjairo.balart@metempsy.com } 157313531Sjairo.balart@metempsy.com 157413760Sjairo.balart@metempsy.com // List Registers 157513531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64 157613760Sjairo.balart@metempsy.com ICH_LR_EL2 requested_ich_lr_el2 = val; 157713760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg); 157813760Sjairo.balart@metempsy.com 157913760Sjairo.balart@metempsy.com ich_lr_el2.State = requested_ich_lr_el2.State; 158013760Sjairo.balart@metempsy.com ich_lr_el2.HW = requested_ich_lr_el2.HW; 158113760Sjairo.balart@metempsy.com ich_lr_el2.Group = requested_ich_lr_el2.Group; 158213760Sjairo.balart@metempsy.com 158313760Sjairo.balart@metempsy.com // Priority, bits [55:48] 158413760Sjairo.balart@metempsy.com // At least five bits must be implemented. 158513760Sjairo.balart@metempsy.com // Unimplemented bits are RES0 and start from bit[48] up to bit[50]. 158613760Sjairo.balart@metempsy.com // We implement 5 bits. 158713760Sjairo.balart@metempsy.com ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) | 158813760Sjairo.balart@metempsy.com (ich_lr_el2.Priority & 0x07); 158913760Sjairo.balart@metempsy.com 159013760Sjairo.balart@metempsy.com // pINTID, bits [44:32] 159113760Sjairo.balart@metempsy.com // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning: 159213760Sjairo.balart@metempsy.com // - Bits[44:42] : RES0. 159313760Sjairo.balart@metempsy.com // - Bit[41] : EOI. 159413760Sjairo.balart@metempsy.com // - Bits[40:32] : RES0. 159513760Sjairo.balart@metempsy.com // When ICH_LR<n>_EL2.HW is 1: 159613760Sjairo.balart@metempsy.com // - This field is only required to implement enough bits to hold a 159713760Sjairo.balart@metempsy.com // valid value for the implemented INTID size. Any unused higher 159813760Sjairo.balart@metempsy.com // order bits are RES0. 159913760Sjairo.balart@metempsy.com if (requested_ich_lr_el2.HW == 0) { 160013760Sjairo.balart@metempsy.com ich_lr_el2.EOI = requested_ich_lr_el2.EOI; 160113760Sjairo.balart@metempsy.com } else { 160213760Sjairo.balart@metempsy.com ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID; 160313760Sjairo.balart@metempsy.com } 160413760Sjairo.balart@metempsy.com 160513760Sjairo.balart@metempsy.com // vINTID, bits [31:0] 160613760Sjairo.balart@metempsy.com // It is IMPLEMENTATION DEFINED how many bits are implemented, 160713760Sjairo.balart@metempsy.com // though at least 16 bits must be implemented. 160813760Sjairo.balart@metempsy.com // Unimplemented bits are RES0. 160913760Sjairo.balart@metempsy.com ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID; 161013760Sjairo.balart@metempsy.com 161113760Sjairo.balart@metempsy.com val = ich_lr_el2; 161213531Sjairo.balart@metempsy.com do_virtual_update = true; 161313531Sjairo.balart@metempsy.com break; 161413531Sjairo.balart@metempsy.com } 161513531Sjairo.balart@metempsy.com 161613760Sjairo.balart@metempsy.com // Virtual Machine Control Register 161713531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR: 161813531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR_EL2: { 161913760Sjairo.balart@metempsy.com ICH_VMCR_EL2 requested_ich_vmcr_el2 = val; 162013760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 162113760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 162213760Sjairo.balart@metempsy.com ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR; 162313531Sjairo.balart@metempsy.com uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS; 162413760Sjairo.balart@metempsy.com 162513760Sjairo.balart@metempsy.com if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) { 162613760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR0 = min_vpr0; 162713760Sjairo.balart@metempsy.com } else { 162813760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0; 162913760Sjairo.balart@metempsy.com } 163013760Sjairo.balart@metempsy.com 163113531Sjairo.balart@metempsy.com uint8_t min_vpr1 = min_vpr0 + 1; 163213760Sjairo.balart@metempsy.com 163313760Sjairo.balart@metempsy.com if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) { 163413760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR1 = min_vpr1; 163513760Sjairo.balart@metempsy.com } else { 163613760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1; 163713760Sjairo.balart@metempsy.com } 163813760Sjairo.balart@metempsy.com 163913760Sjairo.balart@metempsy.com ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM; 164013760Sjairo.balart@metempsy.com ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR; 164113760Sjairo.balart@metempsy.com ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1; 164213760Sjairo.balart@metempsy.com ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0; 164313760Sjairo.balart@metempsy.com val = ich_vmcr_el2; 164413531Sjairo.balart@metempsy.com break; 164513531Sjairo.balart@metempsy.com } 164613531Sjairo.balart@metempsy.com 164713760Sjairo.balart@metempsy.com // Hyp Active Priorities Group 0 Registers 164813531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0 ... MISCREG_ICH_AP0R3: 164913531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_AP0R3_EL2: 165013760Sjairo.balart@metempsy.com // Hyp Active Priorities Group 1 Registers 165113531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0 ... MISCREG_ICH_AP1R3: 165213531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0_EL2 ... MISCREG_ICH_AP1R3_EL2: 165313531Sjairo.balart@metempsy.com break; 165413531Sjairo.balart@metempsy.com 165513531Sjairo.balart@metempsy.com default: 165613760Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)", 165713760Sjairo.balart@metempsy.com misc_reg, miscRegName[misc_reg]); 165813531Sjairo.balart@metempsy.com } 165913531Sjairo.balart@metempsy.com 166013531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(misc_reg, val); 166113531Sjairo.balart@metempsy.com 166213531Sjairo.balart@metempsy.com if (do_virtual_update) { 166313531Sjairo.balart@metempsy.com virtualUpdate(); 166413531Sjairo.balart@metempsy.com } 166513531Sjairo.balart@metempsy.com} 166613531Sjairo.balart@metempsy.com 166713531Sjairo.balart@metempsy.comint 166813760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualFindActive(uint32_t int_id) const 166913531Sjairo.balart@metempsy.com{ 167013531Sjairo.balart@metempsy.com for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 167113760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 167213531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 167313760Sjairo.balart@metempsy.com 167413760Sjairo.balart@metempsy.com if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) || 167513760Sjairo.balart@metempsy.com (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) && 167613760Sjairo.balart@metempsy.com (ich_lr_el2.vINTID == int_id)) { 167713531Sjairo.balart@metempsy.com return lr_idx; 167813531Sjairo.balart@metempsy.com } 167913531Sjairo.balart@metempsy.com } 168013531Sjairo.balart@metempsy.com 168113531Sjairo.balart@metempsy.com return -1; 168213531Sjairo.balart@metempsy.com} 168313531Sjairo.balart@metempsy.com 168413531Sjairo.balart@metempsy.comuint32_t 168513760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR0() const 168613531Sjairo.balart@metempsy.com{ 168713531Sjairo.balart@metempsy.com if (hppi.prio == 0xff) { 168813531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 168913531Sjairo.balart@metempsy.com } 169013531Sjairo.balart@metempsy.com 169113531Sjairo.balart@metempsy.com bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS; 169213531Sjairo.balart@metempsy.com 169313531Sjairo.balart@metempsy.com if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) { 169413760Sjairo.balart@metempsy.com // interrupt for the other state pending 169513531Sjairo.balart@metempsy.com return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE; 169613531Sjairo.balart@metempsy.com } 169713531Sjairo.balart@metempsy.com 169813531Sjairo.balart@metempsy.com if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon()) 169913531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 170013531Sjairo.balart@metempsy.com } 170113531Sjairo.balart@metempsy.com 170213531Sjairo.balart@metempsy.com if (irq_is_secure && !inSecureState()) { 170313531Sjairo.balart@metempsy.com // Secure interrupts not visible in Non-secure 170413531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 170513531Sjairo.balart@metempsy.com } 170613531Sjairo.balart@metempsy.com 170713531Sjairo.balart@metempsy.com return hppi.intid; 170813531Sjairo.balart@metempsy.com} 170913531Sjairo.balart@metempsy.com 171013531Sjairo.balart@metempsy.comuint32_t 171113760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR1() const 171213531Sjairo.balart@metempsy.com{ 171313531Sjairo.balart@metempsy.com if (hppi.prio == 0xff) { 171413531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 171513531Sjairo.balart@metempsy.com } 171613531Sjairo.balart@metempsy.com 171713760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 171813760Sjairo.balart@metempsy.com if ((currEL() == EL3) && icc_ctlr_el3.RM) { 171913531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G0S) { 172013531Sjairo.balart@metempsy.com return Gicv3::INTID_SECURE; 172113531Sjairo.balart@metempsy.com } else if (hppi.group == Gicv3::G1NS) { 172213531Sjairo.balart@metempsy.com return Gicv3::INTID_NONSECURE; 172313531Sjairo.balart@metempsy.com } 172413531Sjairo.balart@metempsy.com } 172513531Sjairo.balart@metempsy.com 172613531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G0S) { 172713531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 172813531Sjairo.balart@metempsy.com } 172913531Sjairo.balart@metempsy.com 173013531Sjairo.balart@metempsy.com bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS); 173113531Sjairo.balart@metempsy.com 173213531Sjairo.balart@metempsy.com if (irq_is_secure) { 173313531Sjairo.balart@metempsy.com if (!inSecureState()) { 173413531Sjairo.balart@metempsy.com // Secure interrupts not visible in Non-secure 173513531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 173613531Sjairo.balart@metempsy.com } 173713531Sjairo.balart@metempsy.com } else if (!isEL3OrMon() && inSecureState()) { 173813531Sjairo.balart@metempsy.com // Group 1 non-secure interrupts not visible in Secure EL1 173913531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 174013531Sjairo.balart@metempsy.com } 174113531Sjairo.balart@metempsy.com 174213531Sjairo.balart@metempsy.com return hppi.intid; 174313531Sjairo.balart@metempsy.com} 174413531Sjairo.balart@metempsy.com 174513531Sjairo.balart@metempsy.comvoid 174613531Sjairo.balart@metempsy.comGicv3CPUInterface::dropPriority(Gicv3::GroupId group) 174713531Sjairo.balart@metempsy.com{ 174813531Sjairo.balart@metempsy.com int apr_misc_reg; 174913580Sgabeblack@google.com RegVal apr; 175013531Sjairo.balart@metempsy.com apr_misc_reg = group == Gicv3::G0S ? 175113531Sjairo.balart@metempsy.com MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1; 175213531Sjairo.balart@metempsy.com apr = isa->readMiscRegNoEffect(apr_misc_reg); 175313531Sjairo.balart@metempsy.com 175413531Sjairo.balart@metempsy.com if (apr) { 175513531Sjairo.balart@metempsy.com apr &= apr - 1; 175613531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_misc_reg, apr); 175713531Sjairo.balart@metempsy.com } 175813531Sjairo.balart@metempsy.com 175913531Sjairo.balart@metempsy.com update(); 176013531Sjairo.balart@metempsy.com} 176113531Sjairo.balart@metempsy.com 176213531Sjairo.balart@metempsy.comuint8_t 176313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDropPriority() 176413531Sjairo.balart@metempsy.com{ 176513531Sjairo.balart@metempsy.com int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5); 176613531Sjairo.balart@metempsy.com 176713531Sjairo.balart@metempsy.com for (int i = 0; i < apr_max; i++) { 176813580Sgabeblack@google.com RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i); 176913580Sgabeblack@google.com RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i); 177013531Sjairo.balart@metempsy.com 177113531Sjairo.balart@metempsy.com if (!vapr0 && !vapr1) { 177213531Sjairo.balart@metempsy.com continue; 177313531Sjairo.balart@metempsy.com } 177413531Sjairo.balart@metempsy.com 177513531Sjairo.balart@metempsy.com int vapr0_count = ctz32(vapr0); 177613531Sjairo.balart@metempsy.com int vapr1_count = ctz32(vapr1); 177713531Sjairo.balart@metempsy.com 177813531Sjairo.balart@metempsy.com if (vapr0_count <= vapr1_count) { 177913531Sjairo.balart@metempsy.com vapr0 &= vapr0 - 1; 178013531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0); 178113531Sjairo.balart@metempsy.com return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1); 178213531Sjairo.balart@metempsy.com } else { 178313531Sjairo.balart@metempsy.com vapr1 &= vapr1 - 1; 178413531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1); 178513531Sjairo.balart@metempsy.com return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1); 178613531Sjairo.balart@metempsy.com } 178713531Sjairo.balart@metempsy.com } 178813531Sjairo.balart@metempsy.com 178913531Sjairo.balart@metempsy.com return 0xff; 179013531Sjairo.balart@metempsy.com} 179113531Sjairo.balart@metempsy.com 179213531Sjairo.balart@metempsy.comvoid 179313531Sjairo.balart@metempsy.comGicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group) 179413531Sjairo.balart@metempsy.com{ 179513531Sjairo.balart@metempsy.com // Update active priority registers. 179613531Sjairo.balart@metempsy.com uint32_t prio = hppi.prio & 0xf8; 179713531Sjairo.balart@metempsy.com int apr_bit = prio >> (8 - PRIORITY_BITS); 179813531Sjairo.balart@metempsy.com int reg_bit = apr_bit % 32; 179913531Sjairo.balart@metempsy.com int apr_idx = group == Gicv3::G0S ? 180013531Sjairo.balart@metempsy.com MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1; 180113580Sgabeblack@google.com RegVal apr = isa->readMiscRegNoEffect(apr_idx); 180213531Sjairo.balart@metempsy.com apr |= (1 << reg_bit); 180313531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_idx, apr); 180413531Sjairo.balart@metempsy.com 180513531Sjairo.balart@metempsy.com // Move interrupt state from pending to active. 180613531Sjairo.balart@metempsy.com if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) { 180713531Sjairo.balart@metempsy.com // SGI or PPI, redistributor 180813531Sjairo.balart@metempsy.com redistributor->activateIRQ(int_id); 180913531Sjairo.balart@metempsy.com redistributor->updateAndInformCPUInterface(); 181013531Sjairo.balart@metempsy.com } else if (int_id < Gicv3::INTID_SECURE) { 181113531Sjairo.balart@metempsy.com // SPI, distributor 181213531Sjairo.balart@metempsy.com distributor->activateIRQ(int_id); 181313531Sjairo.balart@metempsy.com distributor->updateAndInformCPUInterfaces(); 181413923Sgiacomo.travaglini@arm.com } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) { 181513923Sgiacomo.travaglini@arm.com // LPI, Redistributor 181613923Sgiacomo.travaglini@arm.com redistributor->setClrLPI(int_id, false); 181713531Sjairo.balart@metempsy.com } 181813531Sjairo.balart@metempsy.com} 181913531Sjairo.balart@metempsy.com 182013531Sjairo.balart@metempsy.comvoid 182113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx) 182213531Sjairo.balart@metempsy.com{ 182313531Sjairo.balart@metempsy.com // Update active priority registers. 182413760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + 182513531Sjairo.balart@metempsy.com lr_idx); 182613760Sjairo.balart@metempsy.com Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S; 182713760Sjairo.balart@metempsy.com uint8_t prio = ich_lr_el.Priority & 0xf8; 182813531Sjairo.balart@metempsy.com int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS); 182913531Sjairo.balart@metempsy.com int reg_no = apr_bit / 32; 183013531Sjairo.balart@metempsy.com int reg_bit = apr_bit % 32; 183113531Sjairo.balart@metempsy.com int apr_idx = group == Gicv3::G0S ? 183213531Sjairo.balart@metempsy.com MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no; 183313580Sgabeblack@google.com RegVal apr = isa->readMiscRegNoEffect(apr_idx); 183413531Sjairo.balart@metempsy.com apr |= (1 << reg_bit); 183513531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_idx, apr); 183613531Sjairo.balart@metempsy.com // Move interrupt state from pending to active. 183713760Sjairo.balart@metempsy.com ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE; 183813760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el); 183913531Sjairo.balart@metempsy.com} 184013531Sjairo.balart@metempsy.com 184113531Sjairo.balart@metempsy.comvoid 184213531Sjairo.balart@metempsy.comGicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group) 184313531Sjairo.balart@metempsy.com{ 184413531Sjairo.balart@metempsy.com if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) { 184513531Sjairo.balart@metempsy.com // SGI or PPI, redistributor 184613531Sjairo.balart@metempsy.com redistributor->deactivateIRQ(int_id); 184713531Sjairo.balart@metempsy.com redistributor->updateAndInformCPUInterface(); 184813531Sjairo.balart@metempsy.com } else if (int_id < Gicv3::INTID_SECURE) { 184913531Sjairo.balart@metempsy.com // SPI, distributor 185013531Sjairo.balart@metempsy.com distributor->deactivateIRQ(int_id); 185113531Sjairo.balart@metempsy.com distributor->updateAndInformCPUInterfaces(); 185213531Sjairo.balart@metempsy.com } else { 185313923Sgiacomo.travaglini@arm.com // LPI, redistributor, shouldn't deactivate 185413923Sgiacomo.travaglini@arm.com redistributor->updateAndInformCPUInterface(); 185513531Sjairo.balart@metempsy.com } 185613531Sjairo.balart@metempsy.com} 185713531Sjairo.balart@metempsy.com 185813531Sjairo.balart@metempsy.comvoid 185913531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDeactivateIRQ(int lr_idx) 186013531Sjairo.balart@metempsy.com{ 186113760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + 186213531Sjairo.balart@metempsy.com lr_idx); 186313531Sjairo.balart@metempsy.com 186413760Sjairo.balart@metempsy.com if (ich_lr_el2.HW) { 186513531Sjairo.balart@metempsy.com // Deactivate the associated physical interrupt 186613760Sjairo.balart@metempsy.com if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) { 186713760Sjairo.balart@metempsy.com Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ? 186813760Sjairo.balart@metempsy.com distributor->getIntGroup(ich_lr_el2.pINTID) : 186913760Sjairo.balart@metempsy.com redistributor->getIntGroup(ich_lr_el2.pINTID); 187013760Sjairo.balart@metempsy.com deactivateIRQ(ich_lr_el2.pINTID, group); 187113531Sjairo.balart@metempsy.com } 187213531Sjairo.balart@metempsy.com } 187313531Sjairo.balart@metempsy.com 187413531Sjairo.balart@metempsy.com // Remove the active bit 187513760Sjairo.balart@metempsy.com ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE; 187613760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2); 187713531Sjairo.balart@metempsy.com} 187813531Sjairo.balart@metempsy.com 187913531Sjairo.balart@metempsy.com/* 188013760Sjairo.balart@metempsy.com * Returns the priority group field for the current BPR value for the group. 188113760Sjairo.balart@metempsy.com * GroupBits() Pseudocode from spec. 188213531Sjairo.balart@metempsy.com */ 188313531Sjairo.balart@metempsy.comuint32_t 188413926Sgiacomo.travaglini@arm.comGicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group) 188513531Sjairo.balart@metempsy.com{ 188613760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_s = 188713760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 188813760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_ns = 188913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 189013760Sjairo.balart@metempsy.com 189113760Sjairo.balart@metempsy.com if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) || 189213760Sjairo.balart@metempsy.com (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) { 189313531Sjairo.balart@metempsy.com group = Gicv3::G0S; 189413531Sjairo.balart@metempsy.com } 189513531Sjairo.balart@metempsy.com 189613531Sjairo.balart@metempsy.com int bpr; 189713531Sjairo.balart@metempsy.com 189813531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 189913926Sgiacomo.travaglini@arm.com bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7; 190013531Sjairo.balart@metempsy.com } else { 190113926Sgiacomo.travaglini@arm.com bpr = readMiscReg(MISCREG_ICC_BPR1_EL1) & 0x7; 190213531Sjairo.balart@metempsy.com } 190313531Sjairo.balart@metempsy.com 190413531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 190513531Sjairo.balart@metempsy.com assert(bpr > 0); 190613531Sjairo.balart@metempsy.com bpr--; 190713531Sjairo.balart@metempsy.com } 190813531Sjairo.balart@metempsy.com 190913531Sjairo.balart@metempsy.com return ~0U << (bpr + 1); 191013531Sjairo.balart@metempsy.com} 191113531Sjairo.balart@metempsy.com 191213531Sjairo.balart@metempsy.comuint32_t 191313760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const 191413531Sjairo.balart@metempsy.com{ 191513760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 191613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 191713531Sjairo.balart@metempsy.com 191813760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) { 191913531Sjairo.balart@metempsy.com group = Gicv3::G0S; 192013531Sjairo.balart@metempsy.com } 192113531Sjairo.balart@metempsy.com 192213531Sjairo.balart@metempsy.com int bpr; 192313531Sjairo.balart@metempsy.com 192413531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 192513760Sjairo.balart@metempsy.com bpr = ich_vmcr_el2.VBPR0; 192613531Sjairo.balart@metempsy.com } else { 192713760Sjairo.balart@metempsy.com bpr = ich_vmcr_el2.VBPR1; 192813531Sjairo.balart@metempsy.com } 192913531Sjairo.balart@metempsy.com 193013531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 193113531Sjairo.balart@metempsy.com assert(bpr > 0); 193213531Sjairo.balart@metempsy.com bpr--; 193313531Sjairo.balart@metempsy.com } 193413531Sjairo.balart@metempsy.com 193513531Sjairo.balart@metempsy.com return ~0U << (bpr + 1); 193613531Sjairo.balart@metempsy.com} 193713531Sjairo.balart@metempsy.com 193813531Sjairo.balart@metempsy.combool 193913760Sjairo.balart@metempsy.comGicv3CPUInterface::isEOISplitMode() const 194013531Sjairo.balart@metempsy.com{ 194113531Sjairo.balart@metempsy.com if (isEL3OrMon()) { 194213760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = 194313760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 194413760Sjairo.balart@metempsy.com return icc_ctlr_el3.EOImode_EL3; 194513531Sjairo.balart@metempsy.com } else { 194613760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1 = 194713760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1); 194813760Sjairo.balart@metempsy.com return icc_ctlr_el1.EOImode; 194913531Sjairo.balart@metempsy.com } 195013531Sjairo.balart@metempsy.com} 195113531Sjairo.balart@metempsy.com 195213531Sjairo.balart@metempsy.combool 195313760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIsEOISplitMode() const 195413531Sjairo.balart@metempsy.com{ 195513760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 195613760Sjairo.balart@metempsy.com return ich_vmcr_el2.VEOIM; 195713531Sjairo.balart@metempsy.com} 195813531Sjairo.balart@metempsy.com 195913531Sjairo.balart@metempsy.comint 196013760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActiveGroup() const 196113531Sjairo.balart@metempsy.com{ 196213531Sjairo.balart@metempsy.com int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1)); 196313531Sjairo.balart@metempsy.com int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S)); 196413531Sjairo.balart@metempsy.com int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS)); 196513531Sjairo.balart@metempsy.com 196613531Sjairo.balart@metempsy.com if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) { 196713531Sjairo.balart@metempsy.com return Gicv3::G1NS; 196813531Sjairo.balart@metempsy.com } 196913531Sjairo.balart@metempsy.com 197013531Sjairo.balart@metempsy.com if (gq_ctz < g0_ctz) { 197113531Sjairo.balart@metempsy.com return Gicv3::G1S; 197213531Sjairo.balart@metempsy.com } 197313531Sjairo.balart@metempsy.com 197413531Sjairo.balart@metempsy.com if (g0_ctz < 32) { 197513531Sjairo.balart@metempsy.com return Gicv3::G0S; 197613531Sjairo.balart@metempsy.com } 197713531Sjairo.balart@metempsy.com 197813531Sjairo.balart@metempsy.com return -1; 197913531Sjairo.balart@metempsy.com} 198013531Sjairo.balart@metempsy.com 198113531Sjairo.balart@metempsy.comvoid 198213531Sjairo.balart@metempsy.comGicv3CPUInterface::update() 198313531Sjairo.balart@metempsy.com{ 198413531Sjairo.balart@metempsy.com bool signal_IRQ = false; 198513531Sjairo.balart@metempsy.com bool signal_FIQ = false; 198613531Sjairo.balart@metempsy.com 198713531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G1S && !haveEL(EL3)) { 198813531Sjairo.balart@metempsy.com /* 198913531Sjairo.balart@metempsy.com * Secure enabled GIC sending a G1S IRQ to a secure disabled 199013531Sjairo.balart@metempsy.com * CPU -> send G0 IRQ 199113531Sjairo.balart@metempsy.com */ 199213531Sjairo.balart@metempsy.com hppi.group = Gicv3::G0S; 199313531Sjairo.balart@metempsy.com } 199413531Sjairo.balart@metempsy.com 199513531Sjairo.balart@metempsy.com if (hppiCanPreempt()) { 199613531Sjairo.balart@metempsy.com ArmISA::InterruptTypes int_type = intSignalType(hppi.group); 199713531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::update(): " 199813531Sjairo.balart@metempsy.com "posting int as %d!\n", int_type); 199913531Sjairo.balart@metempsy.com int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true; 200013531Sjairo.balart@metempsy.com } 200113531Sjairo.balart@metempsy.com 200213531Sjairo.balart@metempsy.com if (signal_IRQ) { 200313531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_IRQ); 200413531Sjairo.balart@metempsy.com } else { 200513531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_IRQ); 200613531Sjairo.balart@metempsy.com } 200713531Sjairo.balart@metempsy.com 200813531Sjairo.balart@metempsy.com if (signal_FIQ) { 200913531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_FIQ); 201013531Sjairo.balart@metempsy.com } else { 201113531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_FIQ); 201213531Sjairo.balart@metempsy.com } 201313531Sjairo.balart@metempsy.com} 201413531Sjairo.balart@metempsy.com 201513531Sjairo.balart@metempsy.comvoid 201613531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualUpdate() 201713531Sjairo.balart@metempsy.com{ 201813531Sjairo.balart@metempsy.com bool signal_IRQ = false; 201913531Sjairo.balart@metempsy.com bool signal_FIQ = false; 202013531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 202113531Sjairo.balart@metempsy.com 202213531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 202313760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 202413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 202513531Sjairo.balart@metempsy.com 202613531Sjairo.balart@metempsy.com if (hppviCanPreempt(lr_idx)) { 202713760Sjairo.balart@metempsy.com if (ich_lr_el2.Group) { 202813531Sjairo.balart@metempsy.com signal_IRQ = true; 202913531Sjairo.balart@metempsy.com } else { 203013531Sjairo.balart@metempsy.com signal_FIQ = true; 203113531Sjairo.balart@metempsy.com } 203213531Sjairo.balart@metempsy.com } 203313531Sjairo.balart@metempsy.com } 203413531Sjairo.balart@metempsy.com 203513760Sjairo.balart@metempsy.com ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 203613760Sjairo.balart@metempsy.com 203713760Sjairo.balart@metempsy.com if (ich_hcr_el2.En) { 203813531Sjairo.balart@metempsy.com if (maintenanceInterruptStatus()) { 203913826Sgiacomo.travaglini@arm.com maintenanceInterrupt->raise(); 204013531Sjairo.balart@metempsy.com } 204113531Sjairo.balart@metempsy.com } 204213531Sjairo.balart@metempsy.com 204313531Sjairo.balart@metempsy.com if (signal_IRQ) { 204413531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): " 204513531Sjairo.balart@metempsy.com "posting int as %d!\n", ArmISA::INT_VIRT_IRQ); 204613531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ); 204713531Sjairo.balart@metempsy.com } else { 204813531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ); 204913531Sjairo.balart@metempsy.com } 205013531Sjairo.balart@metempsy.com 205113531Sjairo.balart@metempsy.com if (signal_FIQ) { 205213531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): " 205313531Sjairo.balart@metempsy.com "posting int as %d!\n", ArmISA::INT_VIRT_FIQ); 205413531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ); 205513531Sjairo.balart@metempsy.com } else { 205613531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ); 205713531Sjairo.balart@metempsy.com } 205813531Sjairo.balart@metempsy.com} 205913531Sjairo.balart@metempsy.com 206013760Sjairo.balart@metempsy.com// Returns the index of the LR with the HPPI 206113531Sjairo.balart@metempsy.comint 206213760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPVILR() const 206313531Sjairo.balart@metempsy.com{ 206413531Sjairo.balart@metempsy.com int idx = -1; 206513760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 206613760Sjairo.balart@metempsy.com 206713760Sjairo.balart@metempsy.com if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) { 206813531Sjairo.balart@metempsy.com // VG0 and VG1 disabled... 206913531Sjairo.balart@metempsy.com return idx; 207013531Sjairo.balart@metempsy.com } 207113531Sjairo.balart@metempsy.com 207213531Sjairo.balart@metempsy.com uint8_t highest_prio = 0xff; 207313531Sjairo.balart@metempsy.com 207413531Sjairo.balart@metempsy.com for (int i = 0; i < 16; i++) { 207513760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 207613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i); 207713760Sjairo.balart@metempsy.com 207813760Sjairo.balart@metempsy.com if (ich_lr_el2.State != Gicv3::INT_PENDING) { 207913531Sjairo.balart@metempsy.com continue; 208013531Sjairo.balart@metempsy.com } 208113531Sjairo.balart@metempsy.com 208213760Sjairo.balart@metempsy.com if (ich_lr_el2.Group) { 208313531Sjairo.balart@metempsy.com // VG1 208413760Sjairo.balart@metempsy.com if (!ich_vmcr_el2.VENG1) { 208513531Sjairo.balart@metempsy.com continue; 208613531Sjairo.balart@metempsy.com } 208713531Sjairo.balart@metempsy.com } else { 208813531Sjairo.balart@metempsy.com // VG0 208913760Sjairo.balart@metempsy.com if (!ich_vmcr_el2.VENG0) { 209013531Sjairo.balart@metempsy.com continue; 209113531Sjairo.balart@metempsy.com } 209213531Sjairo.balart@metempsy.com } 209313531Sjairo.balart@metempsy.com 209413760Sjairo.balart@metempsy.com uint8_t prio = ich_lr_el2.Priority; 209513531Sjairo.balart@metempsy.com 209613531Sjairo.balart@metempsy.com if (prio < highest_prio) { 209713531Sjairo.balart@metempsy.com highest_prio = prio; 209813531Sjairo.balart@metempsy.com idx = i; 209913531Sjairo.balart@metempsy.com } 210013531Sjairo.balart@metempsy.com } 210113531Sjairo.balart@metempsy.com 210213531Sjairo.balart@metempsy.com return idx; 210313531Sjairo.balart@metempsy.com} 210413531Sjairo.balart@metempsy.com 210513531Sjairo.balart@metempsy.combool 210613760Sjairo.balart@metempsy.comGicv3CPUInterface::hppviCanPreempt(int lr_idx) const 210713531Sjairo.balart@metempsy.com{ 210813760Sjairo.balart@metempsy.com ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 210913760Sjairo.balart@metempsy.com if (!ich_hcr_el2.En) { 211013531Sjairo.balart@metempsy.com // virtual interface is disabled 211113531Sjairo.balart@metempsy.com return false; 211213531Sjairo.balart@metempsy.com } 211313531Sjairo.balart@metempsy.com 211413760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 211513760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 211613760Sjairo.balart@metempsy.com uint8_t prio = ich_lr_el2.Priority; 211713531Sjairo.balart@metempsy.com uint8_t vpmr = 211813531Sjairo.balart@metempsy.com bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24); 211913531Sjairo.balart@metempsy.com 212013531Sjairo.balart@metempsy.com if (prio >= vpmr) { 212113531Sjairo.balart@metempsy.com // prioriry masked 212213531Sjairo.balart@metempsy.com return false; 212313531Sjairo.balart@metempsy.com } 212413531Sjairo.balart@metempsy.com 212513531Sjairo.balart@metempsy.com uint8_t rprio = virtualHighestActivePriority(); 212613531Sjairo.balart@metempsy.com 212713531Sjairo.balart@metempsy.com if (rprio == 0xff) { 212813531Sjairo.balart@metempsy.com return true; 212913531Sjairo.balart@metempsy.com } 213013531Sjairo.balart@metempsy.com 213113760Sjairo.balart@metempsy.com Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 213213531Sjairo.balart@metempsy.com uint32_t prio_mask = virtualGroupPriorityMask(group); 213313531Sjairo.balart@metempsy.com 213413531Sjairo.balart@metempsy.com if ((prio & prio_mask) < (rprio & prio_mask)) { 213513531Sjairo.balart@metempsy.com return true; 213613531Sjairo.balart@metempsy.com } 213713531Sjairo.balart@metempsy.com 213813531Sjairo.balart@metempsy.com return false; 213913531Sjairo.balart@metempsy.com} 214013531Sjairo.balart@metempsy.com 214113531Sjairo.balart@metempsy.comuint8_t 214213760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualHighestActivePriority() const 214313531Sjairo.balart@metempsy.com{ 214413531Sjairo.balart@metempsy.com uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5); 214513531Sjairo.balart@metempsy.com 214613531Sjairo.balart@metempsy.com for (int i = 0; i < num_aprs; i++) { 214713580Sgabeblack@google.com RegVal vapr = 214813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) | 214913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i); 215013531Sjairo.balart@metempsy.com 215113531Sjairo.balart@metempsy.com if (!vapr) { 215213531Sjairo.balart@metempsy.com continue; 215313531Sjairo.balart@metempsy.com } 215413531Sjairo.balart@metempsy.com 215513531Sjairo.balart@metempsy.com return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1); 215613531Sjairo.balart@metempsy.com } 215713531Sjairo.balart@metempsy.com 215813531Sjairo.balart@metempsy.com // no active interrups, return idle priority 215913531Sjairo.balart@metempsy.com return 0xff; 216013531Sjairo.balart@metempsy.com} 216113531Sjairo.balart@metempsy.com 216213531Sjairo.balart@metempsy.comvoid 216313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIncrementEOICount() 216413531Sjairo.balart@metempsy.com{ 216513531Sjairo.balart@metempsy.com // Increment the EOICOUNT field in ICH_HCR_EL2 216613580Sgabeblack@google.com RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 216713531Sjairo.balart@metempsy.com uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27); 216813531Sjairo.balart@metempsy.com EOI_cout++; 216913531Sjairo.balart@metempsy.com ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout); 217013531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2); 217113531Sjairo.balart@metempsy.com} 217213531Sjairo.balart@metempsy.com 217313760Sjairo.balart@metempsy.com// spec section 4.6.2 217413531Sjairo.balart@metempsy.comArmISA::InterruptTypes 217513760Sjairo.balart@metempsy.comGicv3CPUInterface::intSignalType(Gicv3::GroupId group) const 217613531Sjairo.balart@metempsy.com{ 217713531Sjairo.balart@metempsy.com bool is_fiq = false; 217813531Sjairo.balart@metempsy.com 217913531Sjairo.balart@metempsy.com switch (group) { 218013531Sjairo.balart@metempsy.com case Gicv3::G0S: 218113531Sjairo.balart@metempsy.com is_fiq = true; 218213531Sjairo.balart@metempsy.com break; 218313531Sjairo.balart@metempsy.com 218413531Sjairo.balart@metempsy.com case Gicv3::G1S: 218513531Sjairo.balart@metempsy.com is_fiq = (distributor->DS == 0) && 218613531Sjairo.balart@metempsy.com (!inSecureState() || ((currEL() == EL3) && isAA64())); 218713531Sjairo.balart@metempsy.com break; 218813531Sjairo.balart@metempsy.com 218913531Sjairo.balart@metempsy.com case Gicv3::G1NS: 219013531Sjairo.balart@metempsy.com is_fiq = (distributor->DS == 0) && inSecureState(); 219113531Sjairo.balart@metempsy.com break; 219213531Sjairo.balart@metempsy.com 219313531Sjairo.balart@metempsy.com default: 219413531Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::intSignalType(): invalid group!"); 219513531Sjairo.balart@metempsy.com } 219613531Sjairo.balart@metempsy.com 219713531Sjairo.balart@metempsy.com if (is_fiq) { 219813531Sjairo.balart@metempsy.com return ArmISA::INT_FIQ; 219913531Sjairo.balart@metempsy.com } else { 220013531Sjairo.balart@metempsy.com return ArmISA::INT_IRQ; 220113531Sjairo.balart@metempsy.com } 220213531Sjairo.balart@metempsy.com} 220313531Sjairo.balart@metempsy.com 220413531Sjairo.balart@metempsy.combool 220513926Sgiacomo.travaglini@arm.comGicv3CPUInterface::hppiCanPreempt() 220613531Sjairo.balart@metempsy.com{ 220713531Sjairo.balart@metempsy.com if (hppi.prio == 0xff) { 220813531Sjairo.balart@metempsy.com // there is no pending interrupt 220913531Sjairo.balart@metempsy.com return false; 221013531Sjairo.balart@metempsy.com } 221113531Sjairo.balart@metempsy.com 221213531Sjairo.balart@metempsy.com if (!groupEnabled(hppi.group)) { 221313531Sjairo.balart@metempsy.com // group disabled at CPU interface 221413531Sjairo.balart@metempsy.com return false; 221513531Sjairo.balart@metempsy.com } 221613531Sjairo.balart@metempsy.com 221713531Sjairo.balart@metempsy.com if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) { 221813531Sjairo.balart@metempsy.com // priority masked 221913531Sjairo.balart@metempsy.com return false; 222013531Sjairo.balart@metempsy.com } 222113531Sjairo.balart@metempsy.com 222213531Sjairo.balart@metempsy.com uint8_t rprio = highestActivePriority(); 222313531Sjairo.balart@metempsy.com 222413531Sjairo.balart@metempsy.com if (rprio == 0xff) { 222513531Sjairo.balart@metempsy.com return true; 222613531Sjairo.balart@metempsy.com } 222713531Sjairo.balart@metempsy.com 222813531Sjairo.balart@metempsy.com uint32_t prio_mask = groupPriorityMask(hppi.group); 222913531Sjairo.balart@metempsy.com 223013531Sjairo.balart@metempsy.com if ((hppi.prio & prio_mask) < (rprio & prio_mask)) { 223113531Sjairo.balart@metempsy.com return true; 223213531Sjairo.balart@metempsy.com } 223313531Sjairo.balart@metempsy.com 223413531Sjairo.balart@metempsy.com return false; 223513531Sjairo.balart@metempsy.com} 223613531Sjairo.balart@metempsy.com 223713531Sjairo.balart@metempsy.comuint8_t 223813760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActivePriority() const 223913531Sjairo.balart@metempsy.com{ 224013531Sjairo.balart@metempsy.com uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) | 224113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) | 224213531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S); 224313531Sjairo.balart@metempsy.com 224413531Sjairo.balart@metempsy.com if (apr) { 224513531Sjairo.balart@metempsy.com return ctz32(apr) << (GIC_MIN_BPR + 1); 224613531Sjairo.balart@metempsy.com } 224713531Sjairo.balart@metempsy.com 224813531Sjairo.balart@metempsy.com // no active interrups, return idle priority 224913531Sjairo.balart@metempsy.com return 0xff; 225013531Sjairo.balart@metempsy.com} 225113531Sjairo.balart@metempsy.com 225213531Sjairo.balart@metempsy.combool 225313760Sjairo.balart@metempsy.comGicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const 225413531Sjairo.balart@metempsy.com{ 225513531Sjairo.balart@metempsy.com switch (group) { 225613760Sjairo.balart@metempsy.com case Gicv3::G0S: { 225713760Sjairo.balart@metempsy.com ICC_IGRPEN0_EL1 icc_igrpen0_el1 = 225813760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1); 225913760Sjairo.balart@metempsy.com return icc_igrpen0_el1.Enable; 226013760Sjairo.balart@metempsy.com } 226113760Sjairo.balart@metempsy.com 226213760Sjairo.balart@metempsy.com case Gicv3::G1S: { 226313760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1 icc_igrpen1_el1_s = 226413760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S); 226513760Sjairo.balart@metempsy.com return icc_igrpen1_el1_s.Enable; 226613760Sjairo.balart@metempsy.com } 226713760Sjairo.balart@metempsy.com 226813760Sjairo.balart@metempsy.com case Gicv3::G1NS: { 226913760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns = 227013760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS); 227113760Sjairo.balart@metempsy.com return icc_igrpen1_el1_ns.Enable; 227213760Sjairo.balart@metempsy.com } 227313531Sjairo.balart@metempsy.com 227413531Sjairo.balart@metempsy.com default: 227513531Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::groupEnable(): invalid group!\n"); 227613531Sjairo.balart@metempsy.com } 227713531Sjairo.balart@metempsy.com} 227813531Sjairo.balart@metempsy.com 227913531Sjairo.balart@metempsy.combool 228013760Sjairo.balart@metempsy.comGicv3CPUInterface::inSecureState() const 228113531Sjairo.balart@metempsy.com{ 228213531Sjairo.balart@metempsy.com if (!gic->getSystem()->haveSecurity()) { 228313531Sjairo.balart@metempsy.com return false; 228413531Sjairo.balart@metempsy.com } 228513531Sjairo.balart@metempsy.com 228613531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 228713531Sjairo.balart@metempsy.com SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR); 228813531Sjairo.balart@metempsy.com return ArmISA::inSecureState(scr, cpsr); 228913531Sjairo.balart@metempsy.com} 229013531Sjairo.balart@metempsy.com 229113531Sjairo.balart@metempsy.comint 229213760Sjairo.balart@metempsy.comGicv3CPUInterface::currEL() const 229313531Sjairo.balart@metempsy.com{ 229413531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 229513531Sjairo.balart@metempsy.com bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 229613531Sjairo.balart@metempsy.com 229713531Sjairo.balart@metempsy.com if (is_64) { 229813531Sjairo.balart@metempsy.com return (ExceptionLevel)(uint8_t) cpsr.el; 229913531Sjairo.balart@metempsy.com } else { 230013531Sjairo.balart@metempsy.com switch (cpsr.mode) { 230113531Sjairo.balart@metempsy.com case MODE_USER: 230213531Sjairo.balart@metempsy.com return 0; 230313531Sjairo.balart@metempsy.com 230413531Sjairo.balart@metempsy.com case MODE_HYP: 230513531Sjairo.balart@metempsy.com return 2; 230613531Sjairo.balart@metempsy.com 230713531Sjairo.balart@metempsy.com case MODE_MON: 230813531Sjairo.balart@metempsy.com return 3; 230913531Sjairo.balart@metempsy.com 231013531Sjairo.balart@metempsy.com default: 231113531Sjairo.balart@metempsy.com return 1; 231213531Sjairo.balart@metempsy.com } 231313531Sjairo.balart@metempsy.com } 231413531Sjairo.balart@metempsy.com} 231513531Sjairo.balart@metempsy.com 231613531Sjairo.balart@metempsy.combool 231713760Sjairo.balart@metempsy.comGicv3CPUInterface::haveEL(ExceptionLevel el) const 231813531Sjairo.balart@metempsy.com{ 231913531Sjairo.balart@metempsy.com switch (el) { 232013531Sjairo.balart@metempsy.com case EL0: 232113531Sjairo.balart@metempsy.com case EL1: 232213531Sjairo.balart@metempsy.com return true; 232313531Sjairo.balart@metempsy.com 232413531Sjairo.balart@metempsy.com case EL2: 232513531Sjairo.balart@metempsy.com return gic->getSystem()->haveVirtualization(); 232613531Sjairo.balart@metempsy.com 232713531Sjairo.balart@metempsy.com case EL3: 232813531Sjairo.balart@metempsy.com return gic->getSystem()->haveSecurity(); 232913531Sjairo.balart@metempsy.com 233013531Sjairo.balart@metempsy.com default: 233113531Sjairo.balart@metempsy.com warn("Unimplemented Exception Level\n"); 233213531Sjairo.balart@metempsy.com return false; 233313531Sjairo.balart@metempsy.com } 233413531Sjairo.balart@metempsy.com} 233513531Sjairo.balart@metempsy.com 233613531Sjairo.balart@metempsy.combool 233713760Sjairo.balart@metempsy.comGicv3CPUInterface::isSecureBelowEL3() const 233813531Sjairo.balart@metempsy.com{ 233913531Sjairo.balart@metempsy.com SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 234013531Sjairo.balart@metempsy.com return haveEL(EL3) && scr.ns == 0; 234113531Sjairo.balart@metempsy.com} 234213531Sjairo.balart@metempsy.com 234313531Sjairo.balart@metempsy.combool 234413760Sjairo.balart@metempsy.comGicv3CPUInterface::isAA64() const 234513531Sjairo.balart@metempsy.com{ 234613531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 234713531Sjairo.balart@metempsy.com return opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 234813531Sjairo.balart@metempsy.com} 234913531Sjairo.balart@metempsy.com 235013531Sjairo.balart@metempsy.combool 235113760Sjairo.balart@metempsy.comGicv3CPUInterface::isEL3OrMon() const 235213531Sjairo.balart@metempsy.com{ 235313531Sjairo.balart@metempsy.com if (haveEL(EL3)) { 235413531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 235513531Sjairo.balart@metempsy.com bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 235613531Sjairo.balart@metempsy.com 235713531Sjairo.balart@metempsy.com if (is_64 && (cpsr.el == EL3)) { 235813531Sjairo.balart@metempsy.com return true; 235913531Sjairo.balart@metempsy.com } else if (!is_64 && (cpsr.mode == MODE_MON)) { 236013531Sjairo.balart@metempsy.com return true; 236113531Sjairo.balart@metempsy.com } 236213531Sjairo.balart@metempsy.com } 236313531Sjairo.balart@metempsy.com 236413531Sjairo.balart@metempsy.com return false; 236513531Sjairo.balart@metempsy.com} 236613531Sjairo.balart@metempsy.com 236713760Sjairo.balart@metempsy.com// Computes ICH_EISR_EL2 236813760Sjairo.balart@metempsy.comuint64_t 236913760Sjairo.balart@metempsy.comGicv3CPUInterface::eoiMaintenanceInterruptStatus() const 237013531Sjairo.balart@metempsy.com{ 237113760Sjairo.balart@metempsy.com // ICH_EISR_EL2 237213760Sjairo.balart@metempsy.com // Bits [63:16] - RES0 237313760Sjairo.balart@metempsy.com // Status<n>, bit [n], for n = 0 to 15 237413760Sjairo.balart@metempsy.com // EOI maintenance interrupt status bit for List register <n>: 237513760Sjairo.balart@metempsy.com // 0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI 237613760Sjairo.balart@metempsy.com // maintenance interrupt. 237713760Sjairo.balart@metempsy.com // 1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance 237813760Sjairo.balart@metempsy.com // interrupt that has not been handled. 237913760Sjairo.balart@metempsy.com // 238013760Sjairo.balart@metempsy.com // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all 238113760Sjairo.balart@metempsy.com // of the following are true: 238213760Sjairo.balart@metempsy.com // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID). 238313760Sjairo.balart@metempsy.com // - ICH_LR<n>_EL2.HW is 0. 238413760Sjairo.balart@metempsy.com // - ICH_LR<n>_EL2.EOI (bit [41]) is 1. 238513760Sjairo.balart@metempsy.com 238613760Sjairo.balart@metempsy.com uint64_t value = 0; 238713531Sjairo.balart@metempsy.com 238813531Sjairo.balart@metempsy.com for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 238913760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 239013760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 239113760Sjairo.balart@metempsy.com 239213760Sjairo.balart@metempsy.com if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) && 239313760Sjairo.balart@metempsy.com !ich_lr_el2.HW && ich_lr_el2.EOI) { 239413531Sjairo.balart@metempsy.com value |= (1 << lr_idx); 239513531Sjairo.balart@metempsy.com } 239613760Sjairo.balart@metempsy.com } 239713760Sjairo.balart@metempsy.com 239813760Sjairo.balart@metempsy.com return value; 239913760Sjairo.balart@metempsy.com} 240013760Sjairo.balart@metempsy.com 240113760Sjairo.balart@metempsy.comGicv3CPUInterface::ICH_MISR_EL2 240213760Sjairo.balart@metempsy.comGicv3CPUInterface::maintenanceInterruptStatus() const 240313760Sjairo.balart@metempsy.com{ 240413760Sjairo.balart@metempsy.com // Comments are copied from SPEC section 9.4.7 (ID012119) 240513760Sjairo.balart@metempsy.com ICH_MISR_EL2 ich_misr_el2 = 0; 240613760Sjairo.balart@metempsy.com ICH_HCR_EL2 ich_hcr_el2 = 240713760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 240813760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 240913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 241013760Sjairo.balart@metempsy.com 241113760Sjairo.balart@metempsy.com // End Of Interrupt. [bit 0] 241213760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when at least one bit in 241313760Sjairo.balart@metempsy.com // ICH_EISR_EL2 is 1. 241413760Sjairo.balart@metempsy.com 241513760Sjairo.balart@metempsy.com if (eoiMaintenanceInterruptStatus()) { 241613760Sjairo.balart@metempsy.com ich_misr_el2.EOI = 1; 241713760Sjairo.balart@metempsy.com } 241813760Sjairo.balart@metempsy.com 241913760Sjairo.balart@metempsy.com // Underflow. [bit 1] 242013760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and 242113760Sjairo.balart@metempsy.com // zero or one of the List register entries are marked as a valid 242213760Sjairo.balart@metempsy.com // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits 242313760Sjairo.balart@metempsy.com // do not equal 0x0. 242413760Sjairo.balart@metempsy.com uint32_t num_valid_interrupts = 0; 242513760Sjairo.balart@metempsy.com uint32_t num_pending_interrupts = 0; 242613760Sjairo.balart@metempsy.com 242713760Sjairo.balart@metempsy.com for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 242813760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 242913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 243013760Sjairo.balart@metempsy.com 243113760Sjairo.balart@metempsy.com if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) { 243213760Sjairo.balart@metempsy.com num_valid_interrupts++; 243313531Sjairo.balart@metempsy.com } 243413531Sjairo.balart@metempsy.com 243513760Sjairo.balart@metempsy.com if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) { 243613760Sjairo.balart@metempsy.com num_pending_interrupts++; 243713531Sjairo.balart@metempsy.com } 243813531Sjairo.balart@metempsy.com } 243913531Sjairo.balart@metempsy.com 244013760Sjairo.balart@metempsy.com if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) { 244113760Sjairo.balart@metempsy.com ich_misr_el2.U = 1; 244213531Sjairo.balart@metempsy.com } 244313531Sjairo.balart@metempsy.com 244413760Sjairo.balart@metempsy.com // List Register Entry Not Present. [bit 2] 244513760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1 244613760Sjairo.balart@metempsy.com // and ICH_HCR_EL2.EOIcount is non-zero. 244713760Sjairo.balart@metempsy.com if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) { 244813760Sjairo.balart@metempsy.com ich_misr_el2.LRENP = 1; 244913531Sjairo.balart@metempsy.com } 245013531Sjairo.balart@metempsy.com 245113760Sjairo.balart@metempsy.com // No Pending. [bit 3] 245213760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and 245313760Sjairo.balart@metempsy.com // no List register is in pending state. 245413760Sjairo.balart@metempsy.com if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) { 245513760Sjairo.balart@metempsy.com ich_misr_el2.NP = 1; 245613531Sjairo.balart@metempsy.com } 245713531Sjairo.balart@metempsy.com 245813760Sjairo.balart@metempsy.com // vPE Group 0 Enabled. [bit 4] 245913760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when 246013760Sjairo.balart@metempsy.com // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1. 246113760Sjairo.balart@metempsy.com if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) { 246213760Sjairo.balart@metempsy.com ich_misr_el2.VGrp0E = 1; 246313531Sjairo.balart@metempsy.com } 246413531Sjairo.balart@metempsy.com 246513760Sjairo.balart@metempsy.com // vPE Group 0 Disabled. [bit 5] 246613760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when 246713760Sjairo.balart@metempsy.com // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0. 246813760Sjairo.balart@metempsy.com if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) { 246913760Sjairo.balart@metempsy.com ich_misr_el2.VGrp0D = 1; 247013531Sjairo.balart@metempsy.com } 247113531Sjairo.balart@metempsy.com 247213760Sjairo.balart@metempsy.com // vPE Group 1 Enabled. [bit 6] 247313760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when 247413760Sjairo.balart@metempsy.com // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1. 247513760Sjairo.balart@metempsy.com if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) { 247613760Sjairo.balart@metempsy.com ich_misr_el2.VGrp1E = 1; 247713531Sjairo.balart@metempsy.com } 247813531Sjairo.balart@metempsy.com 247913760Sjairo.balart@metempsy.com // vPE Group 1 Disabled. [bit 7] 248013760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when 248113760Sjairo.balart@metempsy.com // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0. 248213760Sjairo.balart@metempsy.com if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) { 248313760Sjairo.balart@metempsy.com ich_misr_el2.VGrp1D = 1; 248413760Sjairo.balart@metempsy.com } 248513760Sjairo.balart@metempsy.com 248613760Sjairo.balart@metempsy.com return ich_misr_el2; 248713531Sjairo.balart@metempsy.com} 248813531Sjairo.balart@metempsy.com 248913531Sjairo.balart@metempsy.comvoid 249013531Sjairo.balart@metempsy.comGicv3CPUInterface::serialize(CheckpointOut & cp) const 249113531Sjairo.balart@metempsy.com{ 249213531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(hppi.intid); 249313531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(hppi.prio); 249413531Sjairo.balart@metempsy.com SERIALIZE_ENUM(hppi.group); 249513531Sjairo.balart@metempsy.com} 249613531Sjairo.balart@metempsy.com 249713531Sjairo.balart@metempsy.comvoid 249813531Sjairo.balart@metempsy.comGicv3CPUInterface::unserialize(CheckpointIn & cp) 249913531Sjairo.balart@metempsy.com{ 250013531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(hppi.intid); 250113531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(hppi.prio); 250213531Sjairo.balart@metempsy.com UNSERIALIZE_ENUM(hppi.group); 250313531Sjairo.balart@metempsy.com} 2504