gic_v3_cpu_interface.cc revision 14236
113531Sjairo.balart@metempsy.com/* 214227Sgiacomo.travaglini@arm.com * Copyright (c) 2019 ARM Limited 314227Sgiacomo.travaglini@arm.com * All rights reserved 414227Sgiacomo.travaglini@arm.com * 514227Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall 614227Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual 714227Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating 814227Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software 914227Sgiacomo.travaglini@arm.com * licensed hereunder. You may use the software subject to the license 1014227Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated 1114227Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software, 1214227Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form. 1314227Sgiacomo.travaglini@arm.com * 1413531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting 1513531Sjairo.balart@metempsy.com * All rights reserved. 1613531Sjairo.balart@metempsy.com * 1713531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without 1813531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are 1913531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright 2013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer; 2113531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright 2213531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the 2313531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution; 2413531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its 2513531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from 2613531Sjairo.balart@metempsy.com * this software without specific prior written permission. 2713531Sjairo.balart@metempsy.com * 2813531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2913531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3013531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3113531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3213531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3313531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3413531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3513531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3613531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3713531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3813531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3913531Sjairo.balart@metempsy.com * 4013531Sjairo.balart@metempsy.com * Authors: Jairo Balart 4113531Sjairo.balart@metempsy.com */ 4213531Sjairo.balart@metempsy.com 4313531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh" 4413531Sjairo.balart@metempsy.com 4513531Sjairo.balart@metempsy.com#include "arch/arm/isa.hh" 4613531Sjairo.balart@metempsy.com#include "debug/GIC.hh" 4713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh" 4813531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh" 4913531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_redistributor.hh" 5013531Sjairo.balart@metempsy.com 5113926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR; 5213926Sgiacomo.travaglini@arm.comconst uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS; 5313926Sgiacomo.travaglini@arm.com 5413531Sjairo.balart@metempsy.comGicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id) 5513531Sjairo.balart@metempsy.com : BaseISADevice(), 5613531Sjairo.balart@metempsy.com gic(gic), 5713531Sjairo.balart@metempsy.com redistributor(nullptr), 5813531Sjairo.balart@metempsy.com distributor(nullptr), 5913531Sjairo.balart@metempsy.com cpuId(cpu_id) 6013531Sjairo.balart@metempsy.com{ 6113531Sjairo.balart@metempsy.com} 6213531Sjairo.balart@metempsy.com 6313531Sjairo.balart@metempsy.comvoid 6413531Sjairo.balart@metempsy.comGicv3CPUInterface::init() 6513531Sjairo.balart@metempsy.com{ 6613531Sjairo.balart@metempsy.com redistributor = gic->getRedistributor(cpuId); 6713531Sjairo.balart@metempsy.com distributor = gic->getDistributor(); 6813531Sjairo.balart@metempsy.com} 6913531Sjairo.balart@metempsy.com 7013531Sjairo.balart@metempsy.comvoid 7113531Sjairo.balart@metempsy.comGicv3CPUInterface::initState() 7213531Sjairo.balart@metempsy.com{ 7313531Sjairo.balart@metempsy.com reset(); 7413531Sjairo.balart@metempsy.com} 7513531Sjairo.balart@metempsy.com 7613531Sjairo.balart@metempsy.comvoid 7713531Sjairo.balart@metempsy.comGicv3CPUInterface::reset() 7813531Sjairo.balart@metempsy.com{ 7913531Sjairo.balart@metempsy.com hppi.prio = 0xff; 8013531Sjairo.balart@metempsy.com} 8113531Sjairo.balart@metempsy.com 8213826Sgiacomo.travaglini@arm.comvoid 8313826Sgiacomo.travaglini@arm.comGicv3CPUInterface::setThreadContext(ThreadContext *tc) 8413826Sgiacomo.travaglini@arm.com{ 8513826Sgiacomo.travaglini@arm.com maintenanceInterrupt = gic->params()->maint_int->get(tc); 8613826Sgiacomo.travaglini@arm.com} 8713826Sgiacomo.travaglini@arm.com 8813531Sjairo.balart@metempsy.combool 8913760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2FMO() const 9013531Sjairo.balart@metempsy.com{ 9113531Sjairo.balart@metempsy.com HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2); 9213531Sjairo.balart@metempsy.com 9313531Sjairo.balart@metempsy.com if (hcr.tge && hcr.e2h) { 9413531Sjairo.balart@metempsy.com return false; 9513531Sjairo.balart@metempsy.com } else if (hcr.tge) { 9613531Sjairo.balart@metempsy.com return true; 9713531Sjairo.balart@metempsy.com } else { 9813531Sjairo.balart@metempsy.com return hcr.fmo; 9913531Sjairo.balart@metempsy.com } 10013531Sjairo.balart@metempsy.com} 10113531Sjairo.balart@metempsy.com 10213531Sjairo.balart@metempsy.combool 10313760Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2IMO() const 10413531Sjairo.balart@metempsy.com{ 10513531Sjairo.balart@metempsy.com HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2); 10613531Sjairo.balart@metempsy.com 10713531Sjairo.balart@metempsy.com if (hcr.tge && hcr.e2h) { 10813531Sjairo.balart@metempsy.com return false; 10913531Sjairo.balart@metempsy.com } else if (hcr.tge) { 11013531Sjairo.balart@metempsy.com return true; 11113531Sjairo.balart@metempsy.com } else { 11213531Sjairo.balart@metempsy.com return hcr.imo; 11313531Sjairo.balart@metempsy.com } 11413531Sjairo.balart@metempsy.com} 11513531Sjairo.balart@metempsy.com 11613580Sgabeblack@google.comRegVal 11713531Sjairo.balart@metempsy.comGicv3CPUInterface::readMiscReg(int misc_reg) 11813531Sjairo.balart@metempsy.com{ 11913580Sgabeblack@google.com RegVal value = isa->readMiscRegNoEffect(misc_reg); 12013531Sjairo.balart@metempsy.com bool hcr_fmo = getHCREL2FMO(); 12113531Sjairo.balart@metempsy.com bool hcr_imo = getHCREL2IMO(); 12213531Sjairo.balart@metempsy.com 12313531Sjairo.balart@metempsy.com switch (misc_reg) { 12413760Sjairo.balart@metempsy.com // Active Priorities Group 1 Registers 12513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0: 12613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0_EL1: { 12713531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 12813531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1); 12913531Sjairo.balart@metempsy.com } 13013531Sjairo.balart@metempsy.com 13113531Sjairo.balart@metempsy.com break; 13213531Sjairo.balart@metempsy.com } 13313531Sjairo.balart@metempsy.com 13413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1: 13513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1_EL1: 13613531Sjairo.balart@metempsy.com 13713531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 13813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2: 13913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2_EL1: 14013531Sjairo.balart@metempsy.com 14113531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 14213531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3: 14313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3_EL1: 14413531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 14513531Sjairo.balart@metempsy.com return 0; 14613531Sjairo.balart@metempsy.com 14713760Sjairo.balart@metempsy.com // Active Priorities Group 0 Registers 14813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0: 14913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0_EL1: { 15013531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 15113531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1); 15213531Sjairo.balart@metempsy.com } 15313531Sjairo.balart@metempsy.com 15413531Sjairo.balart@metempsy.com break; 15513531Sjairo.balart@metempsy.com } 15613531Sjairo.balart@metempsy.com 15713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1: 15813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1_EL1: 15913531Sjairo.balart@metempsy.com 16013531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 16113531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2: 16213531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2_EL1: 16313531Sjairo.balart@metempsy.com 16413531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 16513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3: 16613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3_EL1: 16713531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 16813531Sjairo.balart@metempsy.com return 0; 16913531Sjairo.balart@metempsy.com 17013760Sjairo.balart@metempsy.com // Interrupt Group 0 Enable register EL1 17113531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0: 17213531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0_EL1: { 17313531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 17414057Sgiacomo.travaglini@arm.com return readMiscReg(MISCREG_ICV_IGRPEN0_EL1); 17513531Sjairo.balart@metempsy.com } 17613531Sjairo.balart@metempsy.com 17713531Sjairo.balart@metempsy.com break; 17813531Sjairo.balart@metempsy.com } 17913531Sjairo.balart@metempsy.com 18014057Sgiacomo.travaglini@arm.com case MISCREG_ICV_IGRPEN0_EL1: { 18114057Sgiacomo.travaglini@arm.com ICH_VMCR_EL2 ich_vmcr_el2 = 18214057Sgiacomo.travaglini@arm.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 18314057Sgiacomo.travaglini@arm.com value = ich_vmcr_el2.VENG0; 18414057Sgiacomo.travaglini@arm.com break; 18514057Sgiacomo.travaglini@arm.com } 18614057Sgiacomo.travaglini@arm.com 18713760Sjairo.balart@metempsy.com // Interrupt Group 1 Enable register EL1 18813531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1: 18913531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL1: { 19013531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 19114057Sgiacomo.travaglini@arm.com return readMiscReg(MISCREG_ICV_IGRPEN1_EL1); 19213531Sjairo.balart@metempsy.com } 19313531Sjairo.balart@metempsy.com 19413531Sjairo.balart@metempsy.com break; 19513531Sjairo.balart@metempsy.com } 19613531Sjairo.balart@metempsy.com 19714057Sgiacomo.travaglini@arm.com case MISCREG_ICV_IGRPEN1_EL1: { 19814057Sgiacomo.travaglini@arm.com ICH_VMCR_EL2 ich_vmcr_el2 = 19914057Sgiacomo.travaglini@arm.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 20014057Sgiacomo.travaglini@arm.com value = ich_vmcr_el2.VENG1; 20114057Sgiacomo.travaglini@arm.com break; 20214057Sgiacomo.travaglini@arm.com } 20314057Sgiacomo.travaglini@arm.com 20413760Sjairo.balart@metempsy.com // Interrupt Group 1 Enable register EL3 20513760Sjairo.balart@metempsy.com case MISCREG_ICC_MGRPEN1: 20613760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL3: 20713739Sgiacomo.travaglini@arm.com break; 20813760Sjairo.balart@metempsy.com 20913760Sjairo.balart@metempsy.com // Running Priority Register 21013531Sjairo.balart@metempsy.com case MISCREG_ICC_RPR: 21113531Sjairo.balart@metempsy.com case MISCREG_ICC_RPR_EL1: { 21213531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 21313760Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 21413531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_RPR_EL1); 21513531Sjairo.balart@metempsy.com } 21613531Sjairo.balart@metempsy.com 21713531Sjairo.balart@metempsy.com uint8_t rprio = highestActivePriority(); 21813531Sjairo.balart@metempsy.com 21913531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && 22013760Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) { 22113760Sjairo.balart@metempsy.com // Spec section 4.8.1 22213760Sjairo.balart@metempsy.com // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1 22313531Sjairo.balart@metempsy.com if ((rprio & 0x80) == 0) { 22413760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 22513760Sjairo.balart@metempsy.com // 0x00-0x7F a read access returns the value 0x0 22613531Sjairo.balart@metempsy.com rprio = 0; 22713531Sjairo.balart@metempsy.com } else if (rprio != 0xff) { 22813760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 22913760Sjairo.balart@metempsy.com // 0x80-0xFF a read access returns the Non-secure read of 23013760Sjairo.balart@metempsy.com // the current value 23113531Sjairo.balart@metempsy.com rprio = (rprio << 1) & 0xff; 23213531Sjairo.balart@metempsy.com } 23313531Sjairo.balart@metempsy.com } 23413531Sjairo.balart@metempsy.com 23513531Sjairo.balart@metempsy.com value = rprio; 23613531Sjairo.balart@metempsy.com break; 23713531Sjairo.balart@metempsy.com } 23813531Sjairo.balart@metempsy.com 23913760Sjairo.balart@metempsy.com // Virtual Running Priority Register 24013531Sjairo.balart@metempsy.com case MISCREG_ICV_RPR_EL1: { 24113531Sjairo.balart@metempsy.com value = virtualHighestActivePriority(); 24213531Sjairo.balart@metempsy.com break; 24313531Sjairo.balart@metempsy.com } 24413531Sjairo.balart@metempsy.com 24513760Sjairo.balart@metempsy.com // Highest Priority Pending Interrupt Register 0 24613531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR0: 24713531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR0_EL1: { 24813531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 24913531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_HPPIR0_EL1); 25013531Sjairo.balart@metempsy.com } 25113531Sjairo.balart@metempsy.com 25213531Sjairo.balart@metempsy.com value = getHPPIR0(); 25313531Sjairo.balart@metempsy.com break; 25413531Sjairo.balart@metempsy.com } 25513531Sjairo.balart@metempsy.com 25613760Sjairo.balart@metempsy.com // Virtual Highest Priority Pending Interrupt Register 0 25713531Sjairo.balart@metempsy.com case MISCREG_ICV_HPPIR0_EL1: { 25813531Sjairo.balart@metempsy.com value = Gicv3::INTID_SPURIOUS; 25913531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 26013531Sjairo.balart@metempsy.com 26113531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 26213760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 26313531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 26413531Sjairo.balart@metempsy.com Gicv3::GroupId group = 26513760Sjairo.balart@metempsy.com ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 26613531Sjairo.balart@metempsy.com 26713531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 26813760Sjairo.balart@metempsy.com value = ich_lr_el2.vINTID; 26913531Sjairo.balart@metempsy.com } 27013531Sjairo.balart@metempsy.com } 27113531Sjairo.balart@metempsy.com 27213531Sjairo.balart@metempsy.com break; 27313531Sjairo.balart@metempsy.com } 27413531Sjairo.balart@metempsy.com 27513760Sjairo.balart@metempsy.com // Highest Priority Pending Interrupt Register 1 27613531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR1: 27713531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR1_EL1: { 27813531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 27913531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_HPPIR1_EL1); 28013531Sjairo.balart@metempsy.com } 28113531Sjairo.balart@metempsy.com 28213531Sjairo.balart@metempsy.com value = getHPPIR1(); 28313531Sjairo.balart@metempsy.com break; 28413531Sjairo.balart@metempsy.com } 28513531Sjairo.balart@metempsy.com 28613760Sjairo.balart@metempsy.com // Virtual Highest Priority Pending Interrupt Register 1 28713531Sjairo.balart@metempsy.com case MISCREG_ICV_HPPIR1_EL1: { 28813531Sjairo.balart@metempsy.com value = Gicv3::INTID_SPURIOUS; 28913531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 29013531Sjairo.balart@metempsy.com 29113531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 29213760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 29313531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 29413531Sjairo.balart@metempsy.com Gicv3::GroupId group = 29513760Sjairo.balart@metempsy.com ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 29613531Sjairo.balart@metempsy.com 29713531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 29813760Sjairo.balart@metempsy.com value = ich_lr_el2.vINTID; 29913531Sjairo.balart@metempsy.com } 30013531Sjairo.balart@metempsy.com } 30113531Sjairo.balart@metempsy.com 30213531Sjairo.balart@metempsy.com break; 30313531Sjairo.balart@metempsy.com } 30413531Sjairo.balart@metempsy.com 30513760Sjairo.balart@metempsy.com // Binary Point Register 0 30613531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0: 30713531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0_EL1: 30813531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 30913531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_BPR0_EL1); 31013531Sjairo.balart@metempsy.com } 31113531Sjairo.balart@metempsy.com 31213531Sjairo.balart@metempsy.com M5_FALLTHROUGH; 31313531Sjairo.balart@metempsy.com 31413760Sjairo.balart@metempsy.com // Binary Point Register 1 31513531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1: 31613760Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1_EL1: { 31713760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 31813760Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_BPR1_EL1); 31913760Sjairo.balart@metempsy.com } 32013760Sjairo.balart@metempsy.com 32113531Sjairo.balart@metempsy.com Gicv3::GroupId group = 32213531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S; 32313531Sjairo.balart@metempsy.com 32413531Sjairo.balart@metempsy.com if (group == Gicv3::G1S && !inSecureState()) { 32513531Sjairo.balart@metempsy.com group = Gicv3::G1NS; 32613531Sjairo.balart@metempsy.com } 32713531Sjairo.balart@metempsy.com 32813760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_s = 32913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 33013760Sjairo.balart@metempsy.com 33113760Sjairo.balart@metempsy.com if ((group == Gicv3::G1S) && !isEL3OrMon() && 33213760Sjairo.balart@metempsy.com icc_ctlr_el1_s.CBPR) { 33313531Sjairo.balart@metempsy.com group = Gicv3::G0S; 33413531Sjairo.balart@metempsy.com } 33513531Sjairo.balart@metempsy.com 33613531Sjairo.balart@metempsy.com bool sat_inc = false; 33713531Sjairo.balart@metempsy.com 33813760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_ns = 33913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 34013760Sjairo.balart@metempsy.com 34113760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && (currEL() < EL3) && 34213760Sjairo.balart@metempsy.com icc_ctlr_el1_ns.CBPR) { 34313531Sjairo.balart@metempsy.com // Reads return BPR0 + 1 saturated to 7, WI 34413531Sjairo.balart@metempsy.com group = Gicv3::G0S; 34513531Sjairo.balart@metempsy.com sat_inc = true; 34613531Sjairo.balart@metempsy.com } 34713531Sjairo.balart@metempsy.com 34813531Sjairo.balart@metempsy.com uint8_t bpr; 34913531Sjairo.balart@metempsy.com 35013531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 35113531Sjairo.balart@metempsy.com bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1); 35213531Sjairo.balart@metempsy.com } else { 35313531Sjairo.balart@metempsy.com bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1); 35413926Sgiacomo.travaglini@arm.com bpr = std::max(bpr, group == Gicv3::G1S ? 35513926Sgiacomo.travaglini@arm.com GIC_MIN_BPR : GIC_MIN_BPR_NS); 35613531Sjairo.balart@metempsy.com } 35713531Sjairo.balart@metempsy.com 35813531Sjairo.balart@metempsy.com if (sat_inc) { 35913531Sjairo.balart@metempsy.com bpr++; 36013531Sjairo.balart@metempsy.com 36113531Sjairo.balart@metempsy.com if (bpr > 7) { 36213531Sjairo.balart@metempsy.com bpr = 7; 36313531Sjairo.balart@metempsy.com } 36413531Sjairo.balart@metempsy.com } 36513531Sjairo.balart@metempsy.com 36613531Sjairo.balart@metempsy.com value = bpr; 36713531Sjairo.balart@metempsy.com break; 36813760Sjairo.balart@metempsy.com } 36913760Sjairo.balart@metempsy.com 37013760Sjairo.balart@metempsy.com // Virtual Binary Point Register 1 37113531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR0_EL1: 37213531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR1_EL1: { 37313531Sjairo.balart@metempsy.com Gicv3::GroupId group = 37413531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS; 37513760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 37613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 37713531Sjairo.balart@metempsy.com bool sat_inc = false; 37813531Sjairo.balart@metempsy.com 37913760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) { 38013760Sjairo.balart@metempsy.com // bpr0 + 1 saturated to 7, WI 38113531Sjairo.balart@metempsy.com group = Gicv3::G0S; 38213531Sjairo.balart@metempsy.com sat_inc = true; 38313531Sjairo.balart@metempsy.com } 38413531Sjairo.balart@metempsy.com 38513531Sjairo.balart@metempsy.com uint8_t vbpr; 38613531Sjairo.balart@metempsy.com 38713531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 38813760Sjairo.balart@metempsy.com vbpr = ich_vmcr_el2.VBPR0; 38913531Sjairo.balart@metempsy.com } else { 39013760Sjairo.balart@metempsy.com vbpr = ich_vmcr_el2.VBPR1; 39113531Sjairo.balart@metempsy.com } 39213531Sjairo.balart@metempsy.com 39313531Sjairo.balart@metempsy.com if (sat_inc) { 39413531Sjairo.balart@metempsy.com vbpr++; 39513531Sjairo.balart@metempsy.com 39613531Sjairo.balart@metempsy.com if (vbpr > 7) { 39713531Sjairo.balart@metempsy.com vbpr = 7; 39813531Sjairo.balart@metempsy.com } 39913531Sjairo.balart@metempsy.com } 40013531Sjairo.balart@metempsy.com 40113531Sjairo.balart@metempsy.com value = vbpr; 40213531Sjairo.balart@metempsy.com break; 40313531Sjairo.balart@metempsy.com } 40413531Sjairo.balart@metempsy.com 40513760Sjairo.balart@metempsy.com // Interrupt Priority Mask Register 40613531Sjairo.balart@metempsy.com case MISCREG_ICC_PMR: 40713760Sjairo.balart@metempsy.com case MISCREG_ICC_PMR_EL1: 40813760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) { 40914057Sgiacomo.travaglini@arm.com return readMiscReg(MISCREG_ICV_PMR_EL1); 41013531Sjairo.balart@metempsy.com } 41113531Sjairo.balart@metempsy.com 41213531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && 41313760Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) { 41413760Sjairo.balart@metempsy.com // Spec section 4.8.1 41513760Sjairo.balart@metempsy.com // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1: 41613531Sjairo.balart@metempsy.com if ((value & 0x80) == 0) { 41713760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 41813760Sjairo.balart@metempsy.com // 0x00-0x7F a read access returns the value 0x00. 41913531Sjairo.balart@metempsy.com value = 0; 42013531Sjairo.balart@metempsy.com } else if (value != 0xff) { 42113760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 42213760Sjairo.balart@metempsy.com // 0x80-0xFF a read access returns the Non-secure read of the 42313760Sjairo.balart@metempsy.com // current value. 42413531Sjairo.balart@metempsy.com value = (value << 1) & 0xff; 42513531Sjairo.balart@metempsy.com } 42613531Sjairo.balart@metempsy.com } 42713531Sjairo.balart@metempsy.com 42813531Sjairo.balart@metempsy.com break; 42913531Sjairo.balart@metempsy.com 43014057Sgiacomo.travaglini@arm.com case MISCREG_ICV_PMR_EL1: { // Priority Mask Register 43114057Sgiacomo.travaglini@arm.com ICH_VMCR_EL2 ich_vmcr_el2 = 43214057Sgiacomo.travaglini@arm.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 43314057Sgiacomo.travaglini@arm.com 43414057Sgiacomo.travaglini@arm.com value = ich_vmcr_el2.VPMR; 43514057Sgiacomo.travaglini@arm.com break; 43614057Sgiacomo.travaglini@arm.com } 43714057Sgiacomo.travaglini@arm.com 43813760Sjairo.balart@metempsy.com // Interrupt Acknowledge Register 0 43913531Sjairo.balart@metempsy.com case MISCREG_ICC_IAR0: 44013760Sjairo.balart@metempsy.com case MISCREG_ICC_IAR0_EL1: { 44113531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 44213531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_IAR0_EL1); 44313531Sjairo.balart@metempsy.com } 44413531Sjairo.balart@metempsy.com 44513531Sjairo.balart@metempsy.com uint32_t int_id; 44613531Sjairo.balart@metempsy.com 44713531Sjairo.balart@metempsy.com if (hppiCanPreempt()) { 44813531Sjairo.balart@metempsy.com int_id = getHPPIR0(); 44913531Sjairo.balart@metempsy.com 45013531Sjairo.balart@metempsy.com // avoid activation for special interrupts 45113923Sgiacomo.travaglini@arm.com if (int_id < Gicv3::INTID_SECURE || 45213923Sgiacomo.travaglini@arm.com int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) { 45313531Sjairo.balart@metempsy.com activateIRQ(int_id, hppi.group); 45413531Sjairo.balart@metempsy.com } 45513531Sjairo.balart@metempsy.com } else { 45613531Sjairo.balart@metempsy.com int_id = Gicv3::INTID_SPURIOUS; 45713531Sjairo.balart@metempsy.com } 45813531Sjairo.balart@metempsy.com 45913531Sjairo.balart@metempsy.com value = int_id; 46013531Sjairo.balart@metempsy.com break; 46113531Sjairo.balart@metempsy.com } 46213531Sjairo.balart@metempsy.com 46313760Sjairo.balart@metempsy.com // Virtual Interrupt Acknowledge Register 0 46413531Sjairo.balart@metempsy.com case MISCREG_ICV_IAR0_EL1: { 46513531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 46613531Sjairo.balart@metempsy.com uint32_t int_id = Gicv3::INTID_SPURIOUS; 46713531Sjairo.balart@metempsy.com 46813531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 46913760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 47013531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 47113531Sjairo.balart@metempsy.com 47213760Sjairo.balart@metempsy.com if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) { 47313760Sjairo.balart@metempsy.com int_id = ich_lr_el2.vINTID; 47413531Sjairo.balart@metempsy.com 47513531Sjairo.balart@metempsy.com if (int_id < Gicv3::INTID_SECURE || 47613760Sjairo.balart@metempsy.com int_id > Gicv3::INTID_SPURIOUS) { 47713531Sjairo.balart@metempsy.com virtualActivateIRQ(lr_idx); 47813531Sjairo.balart@metempsy.com } else { 47913531Sjairo.balart@metempsy.com // Bogus... Pseudocode says: 48013531Sjairo.balart@metempsy.com // - Move from pending to invalid... 48113531Sjairo.balart@metempsy.com // - Return de bogus id... 48213760Sjairo.balart@metempsy.com ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID; 48313531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, 48413760Sjairo.balart@metempsy.com ich_lr_el2); 48513531Sjairo.balart@metempsy.com } 48613531Sjairo.balart@metempsy.com } 48713531Sjairo.balart@metempsy.com } 48813531Sjairo.balart@metempsy.com 48913531Sjairo.balart@metempsy.com value = int_id; 49013531Sjairo.balart@metempsy.com virtualUpdate(); 49113531Sjairo.balart@metempsy.com break; 49213531Sjairo.balart@metempsy.com } 49313531Sjairo.balart@metempsy.com 49413760Sjairo.balart@metempsy.com // Interrupt Acknowledge Register 1 49513531Sjairo.balart@metempsy.com case MISCREG_ICC_IAR1: 49613760Sjairo.balart@metempsy.com case MISCREG_ICC_IAR1_EL1: { 49713531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 49813531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_IAR1_EL1); 49913531Sjairo.balart@metempsy.com } 50013531Sjairo.balart@metempsy.com 50113531Sjairo.balart@metempsy.com uint32_t int_id; 50213531Sjairo.balart@metempsy.com 50313531Sjairo.balart@metempsy.com if (hppiCanPreempt()) { 50413531Sjairo.balart@metempsy.com int_id = getHPPIR1(); 50513531Sjairo.balart@metempsy.com 50613531Sjairo.balart@metempsy.com // avoid activation for special interrupts 50713923Sgiacomo.travaglini@arm.com if (int_id < Gicv3::INTID_SECURE || 50813923Sgiacomo.travaglini@arm.com int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) { 50913531Sjairo.balart@metempsy.com activateIRQ(int_id, hppi.group); 51013531Sjairo.balart@metempsy.com } 51113531Sjairo.balart@metempsy.com } else { 51213531Sjairo.balart@metempsy.com int_id = Gicv3::INTID_SPURIOUS; 51313531Sjairo.balart@metempsy.com } 51413531Sjairo.balart@metempsy.com 51513531Sjairo.balart@metempsy.com value = int_id; 51613531Sjairo.balart@metempsy.com break; 51713531Sjairo.balart@metempsy.com } 51813531Sjairo.balart@metempsy.com 51913760Sjairo.balart@metempsy.com // Virtual Interrupt Acknowledge Register 1 52013531Sjairo.balart@metempsy.com case MISCREG_ICV_IAR1_EL1: { 52113531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 52213531Sjairo.balart@metempsy.com uint32_t int_id = Gicv3::INTID_SPURIOUS; 52313531Sjairo.balart@metempsy.com 52413531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 52513760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 52613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 52713531Sjairo.balart@metempsy.com 52813760Sjairo.balart@metempsy.com if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) { 52913760Sjairo.balart@metempsy.com int_id = ich_lr_el2.vINTID; 53013531Sjairo.balart@metempsy.com 53113531Sjairo.balart@metempsy.com if (int_id < Gicv3::INTID_SECURE || 53213760Sjairo.balart@metempsy.com int_id > Gicv3::INTID_SPURIOUS) { 53313531Sjairo.balart@metempsy.com virtualActivateIRQ(lr_idx); 53413531Sjairo.balart@metempsy.com } else { 53513531Sjairo.balart@metempsy.com // Bogus... Pseudocode says: 53613531Sjairo.balart@metempsy.com // - Move from pending to invalid... 53713531Sjairo.balart@metempsy.com // - Return de bogus id... 53813760Sjairo.balart@metempsy.com ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID; 53913531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, 54013760Sjairo.balart@metempsy.com ich_lr_el2); 54113531Sjairo.balart@metempsy.com } 54213531Sjairo.balart@metempsy.com } 54313531Sjairo.balart@metempsy.com } 54413531Sjairo.balart@metempsy.com 54513531Sjairo.balart@metempsy.com value = int_id; 54613531Sjairo.balart@metempsy.com virtualUpdate(); 54713531Sjairo.balart@metempsy.com break; 54813531Sjairo.balart@metempsy.com } 54913531Sjairo.balart@metempsy.com 55013760Sjairo.balart@metempsy.com // System Register Enable Register EL1 55113531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE: 55213760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL1: { 55313531Sjairo.balart@metempsy.com /* 55413531Sjairo.balart@metempsy.com * DIB [2] == 1 (IRQ bypass not supported, RAO/WI) 55513531Sjairo.balart@metempsy.com * DFB [1] == 1 (FIQ bypass not supported, RAO/WI) 55613531Sjairo.balart@metempsy.com * SRE [0] == 1 (Only system register interface supported, RAO/WI) 55713531Sjairo.balart@metempsy.com */ 55813760Sjairo.balart@metempsy.com ICC_SRE_EL1 icc_sre_el1 = 0; 55913760Sjairo.balart@metempsy.com icc_sre_el1.SRE = 1; 56013760Sjairo.balart@metempsy.com icc_sre_el1.DIB = 1; 56113760Sjairo.balart@metempsy.com icc_sre_el1.DFB = 1; 56213760Sjairo.balart@metempsy.com value = icc_sre_el1; 56313760Sjairo.balart@metempsy.com break; 56413760Sjairo.balart@metempsy.com } 56513760Sjairo.balart@metempsy.com 56613760Sjairo.balart@metempsy.com // System Register Enable Register EL2 56713760Sjairo.balart@metempsy.com case MISCREG_ICC_HSRE: 56813760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL2: { 56913531Sjairo.balart@metempsy.com /* 57013531Sjairo.balart@metempsy.com * Enable [3] == 1 57113760Sjairo.balart@metempsy.com * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI) 57213531Sjairo.balart@metempsy.com * DIB [2] == 1 (IRQ bypass not supported, RAO/WI) 57313531Sjairo.balart@metempsy.com * DFB [1] == 1 (FIQ bypass not supported, RAO/WI) 57413531Sjairo.balart@metempsy.com * SRE [0] == 1 (Only system register interface supported, RAO/WI) 57513531Sjairo.balart@metempsy.com */ 57613760Sjairo.balart@metempsy.com ICC_SRE_EL2 icc_sre_el2 = 0; 57713760Sjairo.balart@metempsy.com icc_sre_el2.SRE = 1; 57813760Sjairo.balart@metempsy.com icc_sre_el2.DIB = 1; 57913760Sjairo.balart@metempsy.com icc_sre_el2.DFB = 1; 58013760Sjairo.balart@metempsy.com icc_sre_el2.Enable = 1; 58113760Sjairo.balart@metempsy.com value = icc_sre_el2; 58213531Sjairo.balart@metempsy.com break; 58313760Sjairo.balart@metempsy.com } 58413760Sjairo.balart@metempsy.com 58513760Sjairo.balart@metempsy.com // System Register Enable Register EL3 58613760Sjairo.balart@metempsy.com case MISCREG_ICC_MSRE: 58713760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL3: { 58813760Sjairo.balart@metempsy.com /* 58913760Sjairo.balart@metempsy.com * Enable [3] == 1 59013760Sjairo.balart@metempsy.com * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3. 59113760Sjairo.balart@metempsy.com * EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3. 59213760Sjairo.balart@metempsy.com * RAO/WI) 59313760Sjairo.balart@metempsy.com * DIB [2] == 1 (IRQ bypass not supported, RAO/WI) 59413760Sjairo.balart@metempsy.com * DFB [1] == 1 (FIQ bypass not supported, RAO/WI) 59513760Sjairo.balart@metempsy.com * SRE [0] == 1 (Only system register interface supported, RAO/WI) 59613760Sjairo.balart@metempsy.com */ 59713760Sjairo.balart@metempsy.com ICC_SRE_EL3 icc_sre_el3 = 0; 59813760Sjairo.balart@metempsy.com icc_sre_el3.SRE = 1; 59913760Sjairo.balart@metempsy.com icc_sre_el3.DIB = 1; 60013760Sjairo.balart@metempsy.com icc_sre_el3.DFB = 1; 60113760Sjairo.balart@metempsy.com icc_sre_el3.Enable = 1; 60213760Sjairo.balart@metempsy.com value = icc_sre_el3; 60313760Sjairo.balart@metempsy.com break; 60413760Sjairo.balart@metempsy.com } 60513760Sjairo.balart@metempsy.com 60613760Sjairo.balart@metempsy.com // Control Register 60713531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR: 60813760Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL1: { 60913760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) { 61013531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_CTLR_EL1); 61113531Sjairo.balart@metempsy.com } 61213531Sjairo.balart@metempsy.com 61313760Sjairo.balart@metempsy.com // Enforce value for RO bits 61413760Sjairo.balart@metempsy.com // ExtRange [19], INTIDs in the range 1024..8191 not supported 61513760Sjairo.balart@metempsy.com // RSS [18], SGIs with affinity level 0 values of 0-255 are supported 61613760Sjairo.balart@metempsy.com // A3V [15], supports non-zero values of the Aff3 field in SGI 61713760Sjairo.balart@metempsy.com // generation System registers 61813760Sjairo.balart@metempsy.com // SEIS [14], does not support generation of SEIs (deprecated) 61913531Sjairo.balart@metempsy.com // IDbits [13:11], 001 = 24 bits | 000 = 16 bits 62013531Sjairo.balart@metempsy.com // PRIbits [10:8], number of priority bits implemented, minus one 62113760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1 = value; 62213760Sjairo.balart@metempsy.com icc_ctlr_el1.ExtRange = 0; 62313760Sjairo.balart@metempsy.com icc_ctlr_el1.RSS = 1; 62413760Sjairo.balart@metempsy.com icc_ctlr_el1.A3V = 1; 62513760Sjairo.balart@metempsy.com icc_ctlr_el1.SEIS = 0; 62613760Sjairo.balart@metempsy.com icc_ctlr_el1.IDbits = 1; 62713760Sjairo.balart@metempsy.com icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1; 62813760Sjairo.balart@metempsy.com value = icc_ctlr_el1; 62913531Sjairo.balart@metempsy.com break; 63013531Sjairo.balart@metempsy.com } 63113531Sjairo.balart@metempsy.com 63213760Sjairo.balart@metempsy.com // Virtual Control Register 63313531Sjairo.balart@metempsy.com case MISCREG_ICV_CTLR_EL1: { 63413760Sjairo.balart@metempsy.com ICV_CTLR_EL1 icv_ctlr_el1 = value; 63513760Sjairo.balart@metempsy.com icv_ctlr_el1.RSS = 0; 63613760Sjairo.balart@metempsy.com icv_ctlr_el1.A3V = 1; 63713760Sjairo.balart@metempsy.com icv_ctlr_el1.SEIS = 0; 63813760Sjairo.balart@metempsy.com icv_ctlr_el1.IDbits = 1; 63913760Sjairo.balart@metempsy.com icv_ctlr_el1.PRIbits = 7; 64013760Sjairo.balart@metempsy.com value = icv_ctlr_el1; 64113531Sjairo.balart@metempsy.com break; 64213531Sjairo.balart@metempsy.com } 64313531Sjairo.balart@metempsy.com 64413760Sjairo.balart@metempsy.com // Control Register 64513531Sjairo.balart@metempsy.com case MISCREG_ICC_MCTLR: 64613531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL3: { 64713760Sjairo.balart@metempsy.com // Enforce value for RO bits 64813760Sjairo.balart@metempsy.com // ExtRange [19], INTIDs in the range 1024..8191 not supported 64913760Sjairo.balart@metempsy.com // RSS [18], SGIs with affinity level 0 values of 0-255 are supported 65013760Sjairo.balart@metempsy.com // nDS [17], supports disabling of security 65113760Sjairo.balart@metempsy.com // A3V [15], supports non-zero values of the Aff3 field in SGI 65213760Sjairo.balart@metempsy.com // generation System registers 65313760Sjairo.balart@metempsy.com // SEIS [14], does not support generation of SEIs (deprecated) 65413531Sjairo.balart@metempsy.com // IDbits [13:11], 001 = 24 bits | 000 = 16 bits 65513531Sjairo.balart@metempsy.com // PRIbits [10:8], number of priority bits implemented, minus one 65613760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = value; 65713760Sjairo.balart@metempsy.com icc_ctlr_el3.ExtRange = 0; 65813760Sjairo.balart@metempsy.com icc_ctlr_el3.RSS = 1; 65913760Sjairo.balart@metempsy.com icc_ctlr_el3.nDS = 0; 66013760Sjairo.balart@metempsy.com icc_ctlr_el3.A3V = 1; 66113760Sjairo.balart@metempsy.com icc_ctlr_el3.SEIS = 0; 66213760Sjairo.balart@metempsy.com icc_ctlr_el3.IDbits = 0; 66313760Sjairo.balart@metempsy.com icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1; 66413760Sjairo.balart@metempsy.com value = icc_ctlr_el3; 66513531Sjairo.balart@metempsy.com break; 66613531Sjairo.balart@metempsy.com } 66713531Sjairo.balart@metempsy.com 66813760Sjairo.balart@metempsy.com // Hyp Control Register 66913531Sjairo.balart@metempsy.com case MISCREG_ICH_HCR: 67013531Sjairo.balart@metempsy.com case MISCREG_ICH_HCR_EL2: 67113531Sjairo.balart@metempsy.com break; 67213531Sjairo.balart@metempsy.com 67313760Sjairo.balart@metempsy.com // Hyp Active Priorities Group 0 Registers 67413531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0: 67513531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0_EL2: 67613531Sjairo.balart@metempsy.com break; 67713531Sjairo.balart@metempsy.com 67814236Sgiacomo.travaglini@arm.com // only implemented if supporting 6 or more bits of priority 67914236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R1: 68014236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R1_EL2: 68114236Sgiacomo.travaglini@arm.com // only implemented if supporting 7 or more bits of priority 68214236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R2: 68314236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R2_EL2: 68414236Sgiacomo.travaglini@arm.com // only implemented if supporting 7 or more bits of priority 68514236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R3: 68614236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R3_EL2: 68714236Sgiacomo.travaglini@arm.com // Unimplemented registers are RAZ/WI 68814236Sgiacomo.travaglini@arm.com return 0; 68914236Sgiacomo.travaglini@arm.com 69013760Sjairo.balart@metempsy.com // Hyp Active Priorities Group 1 Registers 69113531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0: 69213531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0_EL2: 69313531Sjairo.balart@metempsy.com break; 69413531Sjairo.balart@metempsy.com 69514236Sgiacomo.travaglini@arm.com // only implemented if supporting 6 or more bits of priority 69614236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R1: 69714236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R1_EL2: 69814236Sgiacomo.travaglini@arm.com // only implemented if supporting 7 or more bits of priority 69914236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R2: 70014236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R2_EL2: 70114236Sgiacomo.travaglini@arm.com // only implemented if supporting 7 or more bits of priority 70214236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R3: 70314236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R3_EL2: 70414236Sgiacomo.travaglini@arm.com // Unimplemented registers are RAZ/WI 70514236Sgiacomo.travaglini@arm.com return 0; 70614236Sgiacomo.travaglini@arm.com 70713760Sjairo.balart@metempsy.com // Maintenance Interrupt State Register 70813531Sjairo.balart@metempsy.com case MISCREG_ICH_MISR: 70913760Sjairo.balart@metempsy.com case MISCREG_ICH_MISR_EL2: 71013760Sjairo.balart@metempsy.com value = maintenanceInterruptStatus(); 71113760Sjairo.balart@metempsy.com break; 71213760Sjairo.balart@metempsy.com 71313760Sjairo.balart@metempsy.com // VGIC Type Register 71413760Sjairo.balart@metempsy.com case MISCREG_ICH_VTR: 71513760Sjairo.balart@metempsy.com case MISCREG_ICH_VTR_EL2: { 71613760Sjairo.balart@metempsy.com ICH_VTR_EL2 ich_vtr_el2 = value; 71713760Sjairo.balart@metempsy.com 71813760Sjairo.balart@metempsy.com ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1; 71913760Sjairo.balart@metempsy.com ich_vtr_el2.A3V = 1; 72013760Sjairo.balart@metempsy.com ich_vtr_el2.IDbits = 1; 72113760Sjairo.balart@metempsy.com ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1; 72213760Sjairo.balart@metempsy.com ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1; 72313760Sjairo.balart@metempsy.com 72413760Sjairo.balart@metempsy.com value = ich_vtr_el2; 72513760Sjairo.balart@metempsy.com break; 72613531Sjairo.balart@metempsy.com } 72713531Sjairo.balart@metempsy.com 72813760Sjairo.balart@metempsy.com // End of Interrupt Status Register 72913531Sjairo.balart@metempsy.com case MISCREG_ICH_EISR: 73013531Sjairo.balart@metempsy.com case MISCREG_ICH_EISR_EL2: 73113760Sjairo.balart@metempsy.com value = eoiMaintenanceInterruptStatus(); 73213531Sjairo.balart@metempsy.com break; 73313531Sjairo.balart@metempsy.com 73413760Sjairo.balart@metempsy.com // Empty List Register Status Register 73513531Sjairo.balart@metempsy.com case MISCREG_ICH_ELRSR: 73613531Sjairo.balart@metempsy.com case MISCREG_ICH_ELRSR_EL2: 73713531Sjairo.balart@metempsy.com value = 0; 73813531Sjairo.balart@metempsy.com 73913531Sjairo.balart@metempsy.com for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 74013760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 74113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 74213531Sjairo.balart@metempsy.com 74313760Sjairo.balart@metempsy.com if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) && 74413760Sjairo.balart@metempsy.com (ich_lr_el2.HW || !ich_lr_el2.EOI)) { 74513531Sjairo.balart@metempsy.com value |= (1 << lr_idx); 74613531Sjairo.balart@metempsy.com } 74713531Sjairo.balart@metempsy.com } 74813531Sjairo.balart@metempsy.com 74913531Sjairo.balart@metempsy.com break; 75013531Sjairo.balart@metempsy.com 75113760Sjairo.balart@metempsy.com // List Registers 75213531Sjairo.balart@metempsy.com case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: 75313531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part) 75413531Sjairo.balart@metempsy.com value = value >> 32; 75513531Sjairo.balart@metempsy.com break; 75613531Sjairo.balart@metempsy.com 75713760Sjairo.balart@metempsy.com // List Registers 75813531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: 75913531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part) 76013531Sjairo.balart@metempsy.com value = value & 0xffffffff; 76113531Sjairo.balart@metempsy.com break; 76213531Sjairo.balart@metempsy.com 76313760Sjairo.balart@metempsy.com // List Registers 76413531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: 76513531Sjairo.balart@metempsy.com break; 76613531Sjairo.balart@metempsy.com 76713760Sjairo.balart@metempsy.com // Virtual Machine Control Register 76813531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR: 76913531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR_EL2: 77013531Sjairo.balart@metempsy.com break; 77113531Sjairo.balart@metempsy.com 77213531Sjairo.balart@metempsy.com default: 77313760Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)", 77413760Sjairo.balart@metempsy.com misc_reg, miscRegName[misc_reg]); 77513531Sjairo.balart@metempsy.com } 77613531Sjairo.balart@metempsy.com 77713760Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n", 77813760Sjairo.balart@metempsy.com miscRegName[misc_reg], value); 77913531Sjairo.balart@metempsy.com return value; 78013531Sjairo.balart@metempsy.com} 78113531Sjairo.balart@metempsy.com 78213531Sjairo.balart@metempsy.comvoid 78313580Sgabeblack@google.comGicv3CPUInterface::setMiscReg(int misc_reg, RegVal val) 78413531Sjairo.balart@metempsy.com{ 78513531Sjairo.balart@metempsy.com bool do_virtual_update = false; 78613760Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n", 78713760Sjairo.balart@metempsy.com miscRegName[misc_reg], val); 78813531Sjairo.balart@metempsy.com bool hcr_fmo = getHCREL2FMO(); 78913531Sjairo.balart@metempsy.com bool hcr_imo = getHCREL2IMO(); 79013531Sjairo.balart@metempsy.com 79113531Sjairo.balart@metempsy.com switch (misc_reg) { 79213760Sjairo.balart@metempsy.com // Active Priorities Group 1 Registers 79313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0: 79413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0_EL1: 79513531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 79613531Sjairo.balart@metempsy.com return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val); 79713531Sjairo.balart@metempsy.com } 79813531Sjairo.balart@metempsy.com 79913531Sjairo.balart@metempsy.com break; 80013531Sjairo.balart@metempsy.com 80113531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1: 80213531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1_EL1: 80313531Sjairo.balart@metempsy.com 80413531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 80513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2: 80613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2_EL1: 80713531Sjairo.balart@metempsy.com 80813531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 80913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3: 81013531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3_EL1: 81113531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 81213531Sjairo.balart@metempsy.com break; 81313531Sjairo.balart@metempsy.com 81413760Sjairo.balart@metempsy.com // Active Priorities Group 0 Registers 81513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0: 81613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0_EL1: 81713531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 81813531Sjairo.balart@metempsy.com return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val); 81913531Sjairo.balart@metempsy.com } 82013531Sjairo.balart@metempsy.com 82113531Sjairo.balart@metempsy.com break; 82213531Sjairo.balart@metempsy.com 82313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1: 82413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1_EL1: 82513531Sjairo.balart@metempsy.com 82613531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 82713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2: 82813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2_EL1: 82913531Sjairo.balart@metempsy.com 83013531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 83113531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3: 83213531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3_EL1: 83313531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 83413531Sjairo.balart@metempsy.com break; 83513531Sjairo.balart@metempsy.com 83613760Sjairo.balart@metempsy.com // End Of Interrupt Register 0 83713531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR0: 83813531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0 83913531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 84013531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_EOIR0_EL1, val); 84113531Sjairo.balart@metempsy.com } 84213531Sjairo.balart@metempsy.com 84313531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 84413531Sjairo.balart@metempsy.com 84513531Sjairo.balart@metempsy.com // avoid activation for special interrupts 84613923Sgiacomo.travaglini@arm.com if (int_id >= Gicv3::INTID_SECURE && 84713923Sgiacomo.travaglini@arm.com int_id <= Gicv3::INTID_SPURIOUS) { 84813531Sjairo.balart@metempsy.com return; 84913531Sjairo.balart@metempsy.com } 85013531Sjairo.balart@metempsy.com 85113531Sjairo.balart@metempsy.com Gicv3::GroupId group = Gicv3::G0S; 85213531Sjairo.balart@metempsy.com 85313531Sjairo.balart@metempsy.com if (highestActiveGroup() != group) { 85413531Sjairo.balart@metempsy.com return; 85513531Sjairo.balart@metempsy.com } 85613531Sjairo.balart@metempsy.com 85713531Sjairo.balart@metempsy.com dropPriority(group); 85813531Sjairo.balart@metempsy.com 85913531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 86013531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 86113531Sjairo.balart@metempsy.com } 86213531Sjairo.balart@metempsy.com 86313531Sjairo.balart@metempsy.com break; 86413531Sjairo.balart@metempsy.com } 86513531Sjairo.balart@metempsy.com 86613760Sjairo.balart@metempsy.com // Virtual End Of Interrupt Register 0 86713531Sjairo.balart@metempsy.com case MISCREG_ICV_EOIR0_EL1: { 86813531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 86913531Sjairo.balart@metempsy.com 87013531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 87113531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 87213531Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 87313531Sjairo.balart@metempsy.com return; 87413531Sjairo.balart@metempsy.com } 87513531Sjairo.balart@metempsy.com 87613531Sjairo.balart@metempsy.com uint8_t drop_prio = virtualDropPriority(); 87713531Sjairo.balart@metempsy.com 87813531Sjairo.balart@metempsy.com if (drop_prio == 0xff) { 87913531Sjairo.balart@metempsy.com return; 88013531Sjairo.balart@metempsy.com } 88113531Sjairo.balart@metempsy.com 88213531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 88313531Sjairo.balart@metempsy.com 88413531Sjairo.balart@metempsy.com if (lr_idx < 0) { 88513531Sjairo.balart@metempsy.com // No LR found matching 88613531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 88713531Sjairo.balart@metempsy.com } else { 88813760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 88913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 89013531Sjairo.balart@metempsy.com Gicv3::GroupId lr_group = 89113760Sjairo.balart@metempsy.com ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 89213760Sjairo.balart@metempsy.com uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8; 89313531Sjairo.balart@metempsy.com 89413531Sjairo.balart@metempsy.com if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) { 89513760Sjairo.balart@metempsy.com //if (!virtualIsEOISplitMode()) 89613531Sjairo.balart@metempsy.com { 89713531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 89813531Sjairo.balart@metempsy.com } 89913531Sjairo.balart@metempsy.com } 90013531Sjairo.balart@metempsy.com } 90113531Sjairo.balart@metempsy.com 90213531Sjairo.balart@metempsy.com virtualUpdate(); 90313531Sjairo.balart@metempsy.com break; 90413531Sjairo.balart@metempsy.com } 90513531Sjairo.balart@metempsy.com 90613760Sjairo.balart@metempsy.com // End Of Interrupt Register 1 90713531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR1: 90813760Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR1_EL1: { 90913531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 91013531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_EOIR1_EL1, val); 91113531Sjairo.balart@metempsy.com } 91213531Sjairo.balart@metempsy.com 91313531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 91413531Sjairo.balart@metempsy.com 91513531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 91613923Sgiacomo.travaglini@arm.com if (int_id >= Gicv3::INTID_SECURE && 91713923Sgiacomo.travaglini@arm.com int_id <= Gicv3::INTID_SPURIOUS) { 91813531Sjairo.balart@metempsy.com return; 91913531Sjairo.balart@metempsy.com } 92013531Sjairo.balart@metempsy.com 92113760Sjairo.balart@metempsy.com Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS; 92213531Sjairo.balart@metempsy.com 92313531Sjairo.balart@metempsy.com if (highestActiveGroup() == Gicv3::G0S) { 92413531Sjairo.balart@metempsy.com return; 92513531Sjairo.balart@metempsy.com } 92613531Sjairo.balart@metempsy.com 92713531Sjairo.balart@metempsy.com if (distributor->DS == 0) { 92813531Sjairo.balart@metempsy.com if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) { 92913531Sjairo.balart@metempsy.com return; 93013531Sjairo.balart@metempsy.com } else if (highestActiveGroup() == Gicv3::G1NS && 93113760Sjairo.balart@metempsy.com !(!inSecureState() or (currEL() == EL3))) { 93213531Sjairo.balart@metempsy.com return; 93313531Sjairo.balart@metempsy.com } 93413531Sjairo.balart@metempsy.com } 93513531Sjairo.balart@metempsy.com 93613531Sjairo.balart@metempsy.com dropPriority(group); 93713531Sjairo.balart@metempsy.com 93813531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 93913531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 94013531Sjairo.balart@metempsy.com } 94113531Sjairo.balart@metempsy.com 94213531Sjairo.balart@metempsy.com break; 94313531Sjairo.balart@metempsy.com } 94413531Sjairo.balart@metempsy.com 94513760Sjairo.balart@metempsy.com // Virtual End Of Interrupt Register 1 94613531Sjairo.balart@metempsy.com case MISCREG_ICV_EOIR1_EL1: { 94713531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 94813531Sjairo.balart@metempsy.com 94913531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 95013531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 95113760Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 95213531Sjairo.balart@metempsy.com return; 95313531Sjairo.balart@metempsy.com } 95413531Sjairo.balart@metempsy.com 95513531Sjairo.balart@metempsy.com uint8_t drop_prio = virtualDropPriority(); 95613531Sjairo.balart@metempsy.com 95713531Sjairo.balart@metempsy.com if (drop_prio == 0xff) { 95813531Sjairo.balart@metempsy.com return; 95913531Sjairo.balart@metempsy.com } 96013531Sjairo.balart@metempsy.com 96113531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 96213531Sjairo.balart@metempsy.com 96313531Sjairo.balart@metempsy.com if (lr_idx < 0) { 96413760Sjairo.balart@metempsy.com // No matching LR found 96513531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 96613531Sjairo.balart@metempsy.com } else { 96713760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 96813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 96913531Sjairo.balart@metempsy.com Gicv3::GroupId lr_group = 97013760Sjairo.balart@metempsy.com ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 97113760Sjairo.balart@metempsy.com uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8; 97213531Sjairo.balart@metempsy.com 97313531Sjairo.balart@metempsy.com if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) { 97413531Sjairo.balart@metempsy.com if (!virtualIsEOISplitMode()) { 97513531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 97613531Sjairo.balart@metempsy.com } 97713531Sjairo.balart@metempsy.com } 97813531Sjairo.balart@metempsy.com } 97913531Sjairo.balart@metempsy.com 98013531Sjairo.balart@metempsy.com virtualUpdate(); 98113531Sjairo.balart@metempsy.com break; 98213531Sjairo.balart@metempsy.com } 98313531Sjairo.balart@metempsy.com 98413760Sjairo.balart@metempsy.com // Deactivate Interrupt Register 98513531Sjairo.balart@metempsy.com case MISCREG_ICC_DIR: 98613760Sjairo.balart@metempsy.com case MISCREG_ICC_DIR_EL1: { 98713531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 98813760Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 98913531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_DIR_EL1, val); 99013531Sjairo.balart@metempsy.com } 99113531Sjairo.balart@metempsy.com 99213531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 99313531Sjairo.balart@metempsy.com 99413760Sjairo.balart@metempsy.com // The following checks are as per spec pseudocode 99513760Sjairo.balart@metempsy.com // aarch64/support/ICC_DIR_EL1 99613760Sjairo.balart@metempsy.com 99713760Sjairo.balart@metempsy.com // Check for spurious ID 99813531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE) { 99913531Sjairo.balart@metempsy.com return; 100013531Sjairo.balart@metempsy.com } 100113531Sjairo.balart@metempsy.com 100213760Sjairo.balart@metempsy.com // EOI mode is not set, so don't deactivate 100313531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 100413531Sjairo.balart@metempsy.com return; 100513531Sjairo.balart@metempsy.com } 100613531Sjairo.balart@metempsy.com 100713531Sjairo.balart@metempsy.com Gicv3::GroupId group = 100813531Sjairo.balart@metempsy.com int_id >= 32 ? distributor->getIntGroup(int_id) : 100913531Sjairo.balart@metempsy.com redistributor->getIntGroup(int_id); 101013531Sjairo.balart@metempsy.com bool irq_is_grp0 = group == Gicv3::G0S; 101113531Sjairo.balart@metempsy.com bool single_sec_state = distributor->DS; 101213531Sjairo.balart@metempsy.com bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS); 101313531Sjairo.balart@metempsy.com SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 101413531Sjairo.balart@metempsy.com bool route_fiq_to_el3 = scr_el3.fiq; 101513531Sjairo.balart@metempsy.com bool route_irq_to_el3 = scr_el3.irq; 101613531Sjairo.balart@metempsy.com bool route_fiq_to_el2 = hcr_fmo; 101713531Sjairo.balart@metempsy.com bool route_irq_to_el2 = hcr_imo; 101813531Sjairo.balart@metempsy.com 101913531Sjairo.balart@metempsy.com switch (currEL()) { 102013531Sjairo.balart@metempsy.com case EL3: 102113531Sjairo.balart@metempsy.com break; 102213531Sjairo.balart@metempsy.com 102313531Sjairo.balart@metempsy.com case EL2: 102413531Sjairo.balart@metempsy.com if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) { 102513531Sjairo.balart@metempsy.com break; 102613531Sjairo.balart@metempsy.com } 102713531Sjairo.balart@metempsy.com 102813531Sjairo.balart@metempsy.com if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) { 102913531Sjairo.balart@metempsy.com break; 103013531Sjairo.balart@metempsy.com } 103113531Sjairo.balart@metempsy.com 103213531Sjairo.balart@metempsy.com return; 103313531Sjairo.balart@metempsy.com 103413531Sjairo.balart@metempsy.com case EL1: 103513531Sjairo.balart@metempsy.com if (!isSecureBelowEL3()) { 103613531Sjairo.balart@metempsy.com if (single_sec_state && irq_is_grp0 && 103713760Sjairo.balart@metempsy.com !route_fiq_to_el3 && !route_fiq_to_el2) { 103813531Sjairo.balart@metempsy.com break; 103913531Sjairo.balart@metempsy.com } 104013531Sjairo.balart@metempsy.com 104113531Sjairo.balart@metempsy.com if (!irq_is_secure && !irq_is_grp0 && 104213760Sjairo.balart@metempsy.com !route_irq_to_el3 && !route_irq_to_el2) { 104313531Sjairo.balart@metempsy.com break; 104413531Sjairo.balart@metempsy.com } 104513531Sjairo.balart@metempsy.com } else { 104613531Sjairo.balart@metempsy.com if (irq_is_grp0 && !route_fiq_to_el3) { 104713531Sjairo.balart@metempsy.com break; 104813531Sjairo.balart@metempsy.com } 104913531Sjairo.balart@metempsy.com 105013531Sjairo.balart@metempsy.com if (!irq_is_grp0 && 105113760Sjairo.balart@metempsy.com (!irq_is_secure || !single_sec_state) && 105213760Sjairo.balart@metempsy.com !route_irq_to_el3) { 105313531Sjairo.balart@metempsy.com break; 105413531Sjairo.balart@metempsy.com } 105513531Sjairo.balart@metempsy.com } 105613531Sjairo.balart@metempsy.com 105713531Sjairo.balart@metempsy.com return; 105813531Sjairo.balart@metempsy.com 105913531Sjairo.balart@metempsy.com default: 106013531Sjairo.balart@metempsy.com break; 106113531Sjairo.balart@metempsy.com } 106213531Sjairo.balart@metempsy.com 106313531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 106413531Sjairo.balart@metempsy.com break; 106513531Sjairo.balart@metempsy.com } 106613531Sjairo.balart@metempsy.com 106713760Sjairo.balart@metempsy.com // Deactivate Virtual Interrupt Register 106813531Sjairo.balart@metempsy.com case MISCREG_ICV_DIR_EL1: { 106913531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 107013531Sjairo.balart@metempsy.com 107113531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 107213531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 107313760Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 107413531Sjairo.balart@metempsy.com return; 107513531Sjairo.balart@metempsy.com } 107613531Sjairo.balart@metempsy.com 107713531Sjairo.balart@metempsy.com if (!virtualIsEOISplitMode()) { 107813531Sjairo.balart@metempsy.com return; 107913531Sjairo.balart@metempsy.com } 108013531Sjairo.balart@metempsy.com 108113531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 108213531Sjairo.balart@metempsy.com 108313531Sjairo.balart@metempsy.com if (lr_idx < 0) { 108413760Sjairo.balart@metempsy.com // No matching LR found 108513531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 108613531Sjairo.balart@metempsy.com } else { 108713531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 108813531Sjairo.balart@metempsy.com } 108913531Sjairo.balart@metempsy.com 109013531Sjairo.balart@metempsy.com virtualUpdate(); 109113531Sjairo.balart@metempsy.com break; 109213531Sjairo.balart@metempsy.com } 109313531Sjairo.balart@metempsy.com 109413760Sjairo.balart@metempsy.com // Binary Point Register 0 109513531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0: 109613760Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0_EL1: 109713760Sjairo.balart@metempsy.com // Binary Point Register 1 109813531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1: 109913760Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1_EL1: { 110013531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState()) { 110113531Sjairo.balart@metempsy.com if (misc_reg == MISCREG_ICC_BPR0_EL1 && hcr_fmo) { 110213531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_BPR0_EL1, val); 110313531Sjairo.balart@metempsy.com } else if (misc_reg == MISCREG_ICC_BPR1_EL1 && hcr_imo) { 110413531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_BPR1_EL1, val); 110513531Sjairo.balart@metempsy.com } 110613531Sjairo.balart@metempsy.com } 110713531Sjairo.balart@metempsy.com 110813531Sjairo.balart@metempsy.com Gicv3::GroupId group = 110913531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S; 111013531Sjairo.balart@metempsy.com 111113531Sjairo.balart@metempsy.com if (group == Gicv3::G1S && !inSecureState()) { 111213531Sjairo.balart@metempsy.com group = Gicv3::G1NS; 111313531Sjairo.balart@metempsy.com } 111413531Sjairo.balart@metempsy.com 111513760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_s = 111613760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 111713760Sjairo.balart@metempsy.com 111813760Sjairo.balart@metempsy.com if ((group == Gicv3::G1S) && !isEL3OrMon() && 111913760Sjairo.balart@metempsy.com icc_ctlr_el1_s.CBPR) { 112013531Sjairo.balart@metempsy.com group = Gicv3::G0S; 112113531Sjairo.balart@metempsy.com } 112213531Sjairo.balart@metempsy.com 112313760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_ns = 112413760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 112513760Sjairo.balart@metempsy.com 112613760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && (currEL() < EL3) && 112713760Sjairo.balart@metempsy.com icc_ctlr_el1_ns.CBPR) { 112813760Sjairo.balart@metempsy.com // BPR0 + 1 saturated to 7, WI 112913531Sjairo.balart@metempsy.com return; 113013531Sjairo.balart@metempsy.com } 113113531Sjairo.balart@metempsy.com 113213531Sjairo.balart@metempsy.com uint8_t min_val = (group == Gicv3::G1NS) ? 113313531Sjairo.balart@metempsy.com GIC_MIN_BPR_NS : GIC_MIN_BPR; 113413531Sjairo.balart@metempsy.com val &= 0x7; 113513531Sjairo.balart@metempsy.com 113613531Sjairo.balart@metempsy.com if (val < min_val) { 113713531Sjairo.balart@metempsy.com val = min_val; 113813531Sjairo.balart@metempsy.com } 113913531Sjairo.balart@metempsy.com 114013531Sjairo.balart@metempsy.com break; 114113531Sjairo.balart@metempsy.com } 114213531Sjairo.balart@metempsy.com 114313760Sjairo.balart@metempsy.com // Virtual Binary Point Register 0 114413531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR0_EL1: 114513760Sjairo.balart@metempsy.com // Virtual Binary Point Register 1 114613531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR1_EL1: { 114713531Sjairo.balart@metempsy.com Gicv3::GroupId group = 114813531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS; 114913760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 115013531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 115113531Sjairo.balart@metempsy.com 115213760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) { 115313760Sjairo.balart@metempsy.com // BPR0 + 1 saturated to 7, WI 115413531Sjairo.balart@metempsy.com return; 115513531Sjairo.balart@metempsy.com } 115613531Sjairo.balart@metempsy.com 115713531Sjairo.balart@metempsy.com uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS; 115813531Sjairo.balart@metempsy.com 115913531Sjairo.balart@metempsy.com if (group != Gicv3::G0S) { 116013531Sjairo.balart@metempsy.com min_VPBR++; 116113531Sjairo.balart@metempsy.com } 116213531Sjairo.balart@metempsy.com 116313531Sjairo.balart@metempsy.com if (val < min_VPBR) { 116413531Sjairo.balart@metempsy.com val = min_VPBR; 116513531Sjairo.balart@metempsy.com } 116613531Sjairo.balart@metempsy.com 116713531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 116813760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR0 = val; 116913531Sjairo.balart@metempsy.com } else { 117013760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR1 = val; 117113531Sjairo.balart@metempsy.com } 117213531Sjairo.balart@metempsy.com 117313531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 117413531Sjairo.balart@metempsy.com do_virtual_update = true; 117513531Sjairo.balart@metempsy.com break; 117613531Sjairo.balart@metempsy.com } 117713531Sjairo.balart@metempsy.com 117813760Sjairo.balart@metempsy.com // Control Register EL1 117913531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR: 118013760Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL1: { 118113760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) { 118213531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_CTLR_EL1, val); 118313531Sjairo.balart@metempsy.com } 118413531Sjairo.balart@metempsy.com 118513531Sjairo.balart@metempsy.com /* 118613760Sjairo.balart@metempsy.com * ExtRange is RO. 118713531Sjairo.balart@metempsy.com * RSS is RO. 118813531Sjairo.balart@metempsy.com * A3V is RO. 118913531Sjairo.balart@metempsy.com * SEIS is RO. 119013531Sjairo.balart@metempsy.com * IDbits is RO. 119113531Sjairo.balart@metempsy.com * PRIbits is RO. 119213531Sjairo.balart@metempsy.com */ 119313760Sjairo.balart@metempsy.com ICC_CTLR_EL1 requested_icc_ctlr_el1 = val; 119413760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1 = 119513760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1); 119613760Sjairo.balart@metempsy.com 119713760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = 119813760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 119913760Sjairo.balart@metempsy.com 120013760Sjairo.balart@metempsy.com // The following could be refactored but it is following 120113760Sjairo.balart@metempsy.com // spec description section 9.2.6 point by point. 120213760Sjairo.balart@metempsy.com 120313760Sjairo.balart@metempsy.com // PMHE 120413760Sjairo.balart@metempsy.com if (haveEL(EL3)) { 120513760Sjairo.balart@metempsy.com // PMHE is alias of ICC_CTLR_EL3.PMHE 120613760Sjairo.balart@metempsy.com 120713760Sjairo.balart@metempsy.com if (distributor->DS == 0) { 120813760Sjairo.balart@metempsy.com // PMHE is RO 120913760Sjairo.balart@metempsy.com } else if (distributor->DS == 1) { 121013760Sjairo.balart@metempsy.com // PMHE is RW 121113760Sjairo.balart@metempsy.com icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE; 121213760Sjairo.balart@metempsy.com icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE; 121313760Sjairo.balart@metempsy.com } 121413531Sjairo.balart@metempsy.com } else { 121513760Sjairo.balart@metempsy.com // PMHE is RW (by implementation choice) 121613760Sjairo.balart@metempsy.com icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE; 121713531Sjairo.balart@metempsy.com } 121813531Sjairo.balart@metempsy.com 121913760Sjairo.balart@metempsy.com // EOImode 122013760Sjairo.balart@metempsy.com icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode; 122113760Sjairo.balart@metempsy.com 122213760Sjairo.balart@metempsy.com if (inSecureState()) { 122313760Sjairo.balart@metempsy.com // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S 122413760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode; 122513760Sjairo.balart@metempsy.com } else { 122613760Sjairo.balart@metempsy.com // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS 122713760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode; 122813760Sjairo.balart@metempsy.com } 122913760Sjairo.balart@metempsy.com 123013760Sjairo.balart@metempsy.com // CBPR 123113760Sjairo.balart@metempsy.com if (haveEL(EL3)) { 123213760Sjairo.balart@metempsy.com // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS} 123313760Sjairo.balart@metempsy.com 123413760Sjairo.balart@metempsy.com if (distributor->DS == 0) { 123513760Sjairo.balart@metempsy.com // CBPR is RO 123613760Sjairo.balart@metempsy.com } else { 123713760Sjairo.balart@metempsy.com // CBPR is RW 123813760Sjairo.balart@metempsy.com icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR; 123913760Sjairo.balart@metempsy.com 124013760Sjairo.balart@metempsy.com if (inSecureState()) { 124113760Sjairo.balart@metempsy.com icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR; 124213760Sjairo.balart@metempsy.com } else { 124313760Sjairo.balart@metempsy.com icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR; 124413760Sjairo.balart@metempsy.com } 124513760Sjairo.balart@metempsy.com } 124613760Sjairo.balart@metempsy.com } else { 124713760Sjairo.balart@metempsy.com // CBPR is RW 124813760Sjairo.balart@metempsy.com icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR; 124913760Sjairo.balart@metempsy.com } 125013760Sjairo.balart@metempsy.com 125113760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3); 125213760Sjairo.balart@metempsy.com 125313760Sjairo.balart@metempsy.com val = icc_ctlr_el1; 125413531Sjairo.balart@metempsy.com break; 125513531Sjairo.balart@metempsy.com } 125613531Sjairo.balart@metempsy.com 125713760Sjairo.balart@metempsy.com // Virtual Control Register 125813531Sjairo.balart@metempsy.com case MISCREG_ICV_CTLR_EL1: { 125913760Sjairo.balart@metempsy.com ICV_CTLR_EL1 requested_icv_ctlr_el1 = val; 126013760Sjairo.balart@metempsy.com ICV_CTLR_EL1 icv_ctlr_el1 = 126113760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1); 126213760Sjairo.balart@metempsy.com icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode; 126313760Sjairo.balart@metempsy.com icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR; 126413760Sjairo.balart@metempsy.com val = icv_ctlr_el1; 126513760Sjairo.balart@metempsy.com 126613760Sjairo.balart@metempsy.com // Aliases 126713760Sjairo.balart@metempsy.com // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR. 126813760Sjairo.balart@metempsy.com // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM. 126913760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 127013760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 127113760Sjairo.balart@metempsy.com ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR; 127213760Sjairo.balart@metempsy.com ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode; 127313760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 127413760Sjairo.balart@metempsy.com break; 127513760Sjairo.balart@metempsy.com } 127613760Sjairo.balart@metempsy.com 127713760Sjairo.balart@metempsy.com // Control Register EL3 127813760Sjairo.balart@metempsy.com case MISCREG_ICC_MCTLR: 127913760Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL3: { 128013760Sjairo.balart@metempsy.com /* 128113760Sjairo.balart@metempsy.com * ExtRange is RO. 128213760Sjairo.balart@metempsy.com * RSS is RO. 128313760Sjairo.balart@metempsy.com * nDS is RO. 128413760Sjairo.balart@metempsy.com * A3V is RO. 128513760Sjairo.balart@metempsy.com * SEIS is RO. 128613760Sjairo.balart@metempsy.com * IDbits is RO. 128713760Sjairo.balart@metempsy.com * PRIbits is RO. 128813760Sjairo.balart@metempsy.com * PMHE is RAO/WI, priority-based routing is always used. 128913760Sjairo.balart@metempsy.com */ 129013760Sjairo.balart@metempsy.com ICC_CTLR_EL3 requested_icc_ctlr_el3 = val; 129113760Sjairo.balart@metempsy.com 129213760Sjairo.balart@metempsy.com // Aliases 129313760Sjairo.balart@metempsy.com if (haveEL(EL3)) 129413760Sjairo.balart@metempsy.com { 129513760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_s = 129613760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 129713760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_ns = 129813760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 129913760Sjairo.balart@metempsy.com 130013760Sjairo.balart@metempsy.com // ICC_CTLR_EL1(NS).EOImode is an alias of 130113760Sjairo.balart@metempsy.com // ICC_CTLR_EL3.EOImode_EL1NS 130213760Sjairo.balart@metempsy.com icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS; 130313760Sjairo.balart@metempsy.com // ICC_CTLR_EL1(S).EOImode is an alias of 130413760Sjairo.balart@metempsy.com // ICC_CTLR_EL3.EOImode_EL1S 130513760Sjairo.balart@metempsy.com icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S; 130613760Sjairo.balart@metempsy.com // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS 130713760Sjairo.balart@metempsy.com icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS; 130813760Sjairo.balart@metempsy.com // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S 130913760Sjairo.balart@metempsy.com icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S; 131013760Sjairo.balart@metempsy.com 131113760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s); 131213760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS, 131313760Sjairo.balart@metempsy.com icc_ctlr_el1_ns); 131413760Sjairo.balart@metempsy.com } 131513760Sjairo.balart@metempsy.com 131613760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = 131713760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 131813760Sjairo.balart@metempsy.com 131913760Sjairo.balart@metempsy.com icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM; 132013760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS; 132113760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S; 132213760Sjairo.balart@metempsy.com icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3; 132313760Sjairo.balart@metempsy.com icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS; 132413760Sjairo.balart@metempsy.com icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S; 132513760Sjairo.balart@metempsy.com 132613760Sjairo.balart@metempsy.com val = icc_ctlr_el3; 132713531Sjairo.balart@metempsy.com break; 132813531Sjairo.balart@metempsy.com } 132913531Sjairo.balart@metempsy.com 133013760Sjairo.balart@metempsy.com // Priority Mask Register 133113531Sjairo.balart@metempsy.com case MISCREG_ICC_PMR: 133213760Sjairo.balart@metempsy.com case MISCREG_ICC_PMR_EL1: { 133313760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) { 133414057Sgiacomo.travaglini@arm.com return setMiscReg(MISCREG_ICV_PMR_EL1, val); 133513531Sjairo.balart@metempsy.com } 133613531Sjairo.balart@metempsy.com 133713531Sjairo.balart@metempsy.com val &= 0xff; 133813531Sjairo.balart@metempsy.com SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 133913531Sjairo.balart@metempsy.com 134013531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) { 134113760Sjairo.balart@metempsy.com // Spec section 4.8.1 134213760Sjairo.balart@metempsy.com // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1: 134313580Sgabeblack@google.com RegVal old_icc_pmr_el1 = 134413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1); 134513531Sjairo.balart@metempsy.com 134613531Sjairo.balart@metempsy.com if (!(old_icc_pmr_el1 & 0x80)) { 134713760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 134813760Sjairo.balart@metempsy.com // 0x00-0x7F then WI 134913531Sjairo.balart@metempsy.com return; 135013531Sjairo.balart@metempsy.com } 135113531Sjairo.balart@metempsy.com 135213760Sjairo.balart@metempsy.com // If the current priority mask value is in the range of 135313760Sjairo.balart@metempsy.com // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds, 135413760Sjairo.balart@metempsy.com // based on the Non-secure read of the priority mask value 135513760Sjairo.balart@metempsy.com // written to the register. 135613760Sjairo.balart@metempsy.com 135713531Sjairo.balart@metempsy.com val = (val >> 1) | 0x80; 135813531Sjairo.balart@metempsy.com } 135913531Sjairo.balart@metempsy.com 136013531Sjairo.balart@metempsy.com val &= ~0U << (8 - PRIORITY_BITS); 136113531Sjairo.balart@metempsy.com break; 136213531Sjairo.balart@metempsy.com } 136313531Sjairo.balart@metempsy.com 136414057Sgiacomo.travaglini@arm.com case MISCREG_ICV_PMR_EL1: { // Priority Mask Register 136514057Sgiacomo.travaglini@arm.com ICH_VMCR_EL2 ich_vmcr_el2 = 136614057Sgiacomo.travaglini@arm.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 136714057Sgiacomo.travaglini@arm.com ich_vmcr_el2.VPMR = val & 0xff; 136814057Sgiacomo.travaglini@arm.com 136914057Sgiacomo.travaglini@arm.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 137014057Sgiacomo.travaglini@arm.com virtualUpdate(); 137114057Sgiacomo.travaglini@arm.com return; 137214057Sgiacomo.travaglini@arm.com } 137314057Sgiacomo.travaglini@arm.com 137413760Sjairo.balart@metempsy.com // Interrupt Group 0 Enable Register EL1 137513760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0: 137613760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0_EL1: { 137713760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 137813760Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val); 137913760Sjairo.balart@metempsy.com } 138013760Sjairo.balart@metempsy.com 138113760Sjairo.balart@metempsy.com break; 138213760Sjairo.balart@metempsy.com } 138313760Sjairo.balart@metempsy.com 138413760Sjairo.balart@metempsy.com // Virtual Interrupt Group 0 Enable register 138513760Sjairo.balart@metempsy.com case MISCREG_ICV_IGRPEN0_EL1: { 138613760Sjairo.balart@metempsy.com bool enable = val & 0x1; 138713760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 138813760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 138913760Sjairo.balart@metempsy.com ich_vmcr_el2.VENG0 = enable; 139013740Sgiacomo.travaglini@arm.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 139113740Sgiacomo.travaglini@arm.com virtualUpdate(); 139213740Sgiacomo.travaglini@arm.com return; 139313740Sgiacomo.travaglini@arm.com } 139413740Sgiacomo.travaglini@arm.com 139513760Sjairo.balart@metempsy.com // Interrupt Group 1 Enable register EL1 139613760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1: 139713760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL1: { 139813760Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 139913760Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val); 140013760Sjairo.balart@metempsy.com } 140113760Sjairo.balart@metempsy.com 140213760Sjairo.balart@metempsy.com if (haveEL(EL3)) { 140313760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1 icc_igrpen1_el1 = val; 140413760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL3 icc_igrpen1_el3 = 140513760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3); 140613760Sjairo.balart@metempsy.com 140713760Sjairo.balart@metempsy.com if (inSecureState()) { 140813760Sjairo.balart@metempsy.com // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1S 140913760Sjairo.balart@metempsy.com icc_igrpen1_el3.EnableGrp1S = icc_igrpen1_el1.Enable; 141013760Sjairo.balart@metempsy.com } else { 141113760Sjairo.balart@metempsy.com // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1NS 141213760Sjairo.balart@metempsy.com icc_igrpen1_el3.EnableGrp1NS = icc_igrpen1_el1.Enable; 141313760Sjairo.balart@metempsy.com } 141413760Sjairo.balart@metempsy.com 141513760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3, 141613760Sjairo.balart@metempsy.com icc_igrpen1_el3); 141713531Sjairo.balart@metempsy.com } 141813531Sjairo.balart@metempsy.com 141913531Sjairo.balart@metempsy.com break; 142013531Sjairo.balart@metempsy.com } 142113531Sjairo.balart@metempsy.com 142213760Sjairo.balart@metempsy.com // Virtual Interrupt Group 1 Enable register 142313760Sjairo.balart@metempsy.com case MISCREG_ICV_IGRPEN1_EL1: { 142413531Sjairo.balart@metempsy.com bool enable = val & 0x1; 142513760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 142613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 142713760Sjairo.balart@metempsy.com ich_vmcr_el2.VENG1 = enable; 142813531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 142913531Sjairo.balart@metempsy.com virtualUpdate(); 143013531Sjairo.balart@metempsy.com return; 143113531Sjairo.balart@metempsy.com } 143213531Sjairo.balart@metempsy.com 143313760Sjairo.balart@metempsy.com // Interrupt Group 1 Enable register 143413760Sjairo.balart@metempsy.com case MISCREG_ICC_MGRPEN1: 143513760Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL3: { 143613760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val; 143713760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1 icc_igrpen1_el1 = 143813760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1); 143913760Sjairo.balart@metempsy.com 144013760Sjairo.balart@metempsy.com if (inSecureState()) { 144113760Sjairo.balart@metempsy.com // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1S 144213760Sjairo.balart@metempsy.com icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1S; 144313760Sjairo.balart@metempsy.com } else { 144413760Sjairo.balart@metempsy.com // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1NS 144513760Sjairo.balart@metempsy.com icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1NS; 144613531Sjairo.balart@metempsy.com } 144713531Sjairo.balart@metempsy.com 144813760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1, icc_igrpen1_el1); 144913531Sjairo.balart@metempsy.com break; 145013531Sjairo.balart@metempsy.com } 145113531Sjairo.balart@metempsy.com 145213760Sjairo.balart@metempsy.com // Software Generated Interrupt Group 0 Register 145313531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI0R: 145413531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI0R_EL1: 145514227Sgiacomo.travaglini@arm.com generateSGI(val, Gicv3::G0S); 145614227Sgiacomo.travaglini@arm.com break; 145713531Sjairo.balart@metempsy.com 145813760Sjairo.balart@metempsy.com // Software Generated Interrupt Group 1 Register 145913531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI1R: 146014227Sgiacomo.travaglini@arm.com case MISCREG_ICC_SGI1R_EL1: { 146114227Sgiacomo.travaglini@arm.com Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS; 146214227Sgiacomo.travaglini@arm.com 146314227Sgiacomo.travaglini@arm.com generateSGI(val, group); 146414227Sgiacomo.travaglini@arm.com break; 146514227Sgiacomo.travaglini@arm.com } 146613531Sjairo.balart@metempsy.com 146713760Sjairo.balart@metempsy.com // Alias Software Generated Interrupt Group 1 Register 146813531Sjairo.balart@metempsy.com case MISCREG_ICC_ASGI1R: 146913531Sjairo.balart@metempsy.com case MISCREG_ICC_ASGI1R_EL1: { 147014227Sgiacomo.travaglini@arm.com Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S; 147114227Sgiacomo.travaglini@arm.com 147214227Sgiacomo.travaglini@arm.com generateSGI(val, group); 147314227Sgiacomo.travaglini@arm.com break; 147413531Sjairo.balart@metempsy.com } 147513531Sjairo.balart@metempsy.com 147613760Sjairo.balart@metempsy.com // System Register Enable Register EL1 147713531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE: 147813760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL1: 147913760Sjairo.balart@metempsy.com // System Register Enable Register EL2 148013531Sjairo.balart@metempsy.com case MISCREG_ICC_HSRE: 148113760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL2: 148213760Sjairo.balart@metempsy.com // System Register Enable Register EL3 148313531Sjairo.balart@metempsy.com case MISCREG_ICC_MSRE: 148413760Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL3: 148513760Sjairo.balart@metempsy.com // All bits are RAO/WI 148613760Sjairo.balart@metempsy.com return; 148713760Sjairo.balart@metempsy.com 148813760Sjairo.balart@metempsy.com // Hyp Control Register 148913760Sjairo.balart@metempsy.com case MISCREG_ICH_HCR: 149013760Sjairo.balart@metempsy.com case MISCREG_ICH_HCR_EL2: { 149113760Sjairo.balart@metempsy.com ICH_HCR_EL2 requested_ich_hcr_el2 = val; 149213760Sjairo.balart@metempsy.com ICH_HCR_EL2 ich_hcr_el2 = 149313760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 149413760Sjairo.balart@metempsy.com 149513760Sjairo.balart@metempsy.com if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount) 149613760Sjairo.balart@metempsy.com { 149713760Sjairo.balart@metempsy.com // EOIcount - Permitted behaviors are: 149813760Sjairo.balart@metempsy.com // - Increment EOIcount. 149913760Sjairo.balart@metempsy.com // - Leave EOIcount unchanged. 150013760Sjairo.balart@metempsy.com ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount; 150113531Sjairo.balart@metempsy.com } 150213531Sjairo.balart@metempsy.com 150313760Sjairo.balart@metempsy.com ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR; 150413760Sjairo.balart@metempsy.com ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI; 150513760Sjairo.balart@metempsy.com ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;; 150613760Sjairo.balart@metempsy.com ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;; 150713760Sjairo.balart@metempsy.com ich_hcr_el2.TC = requested_ich_hcr_el2.TC; 150813760Sjairo.balart@metempsy.com ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE; 150913760Sjairo.balart@metempsy.com ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE; 151013760Sjairo.balart@metempsy.com ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE; 151113760Sjairo.balart@metempsy.com ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE; 151213760Sjairo.balart@metempsy.com ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE; 151313760Sjairo.balart@metempsy.com ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE; 151413760Sjairo.balart@metempsy.com ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE; 151513760Sjairo.balart@metempsy.com ich_hcr_el2.En = requested_ich_hcr_el2.En; 151613760Sjairo.balart@metempsy.com val = ich_hcr_el2; 151713531Sjairo.balart@metempsy.com do_virtual_update = true; 151813531Sjairo.balart@metempsy.com break; 151913760Sjairo.balart@metempsy.com } 152013760Sjairo.balart@metempsy.com 152113760Sjairo.balart@metempsy.com // List Registers 152213760Sjairo.balart@metempsy.com case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: { 152313531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part) 152413760Sjairo.balart@metempsy.com ICH_LRC requested_ich_lrc = val; 152513760Sjairo.balart@metempsy.com ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg); 152613760Sjairo.balart@metempsy.com 152713760Sjairo.balart@metempsy.com ich_lrc.State = requested_ich_lrc.State; 152813760Sjairo.balart@metempsy.com ich_lrc.HW = requested_ich_lrc.HW; 152913760Sjairo.balart@metempsy.com ich_lrc.Group = requested_ich_lrc.Group; 153013760Sjairo.balart@metempsy.com 153113760Sjairo.balart@metempsy.com // Priority, bits [23:16] 153213760Sjairo.balart@metempsy.com // At least five bits must be implemented. 153313760Sjairo.balart@metempsy.com // Unimplemented bits are RES0 and start from bit[16] up to bit[18]. 153413760Sjairo.balart@metempsy.com // We implement 5 bits. 153513760Sjairo.balart@metempsy.com ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) | 153613760Sjairo.balart@metempsy.com (ich_lrc.Priority & 0x07); 153713760Sjairo.balart@metempsy.com 153813760Sjairo.balart@metempsy.com // pINTID, bits [12:0] 153913760Sjairo.balart@metempsy.com // When ICH_LR<n>.HW is 0 this field has the following meaning: 154013760Sjairo.balart@metempsy.com // - Bits[12:10] : RES0. 154113760Sjairo.balart@metempsy.com // - Bit[9] : EOI. 154213760Sjairo.balart@metempsy.com // - Bits[8:0] : RES0. 154313760Sjairo.balart@metempsy.com // When ICH_LR<n>.HW is 1: 154413760Sjairo.balart@metempsy.com // - This field is only required to implement enough bits to hold a 154513760Sjairo.balart@metempsy.com // valid value for the implemented INTID size. Any unused higher 154613760Sjairo.balart@metempsy.com // order bits are RES0. 154713760Sjairo.balart@metempsy.com if (requested_ich_lrc.HW == 0) { 154813760Sjairo.balart@metempsy.com ich_lrc.EOI = requested_ich_lrc.EOI; 154913760Sjairo.balart@metempsy.com } else { 155013760Sjairo.balart@metempsy.com ich_lrc.pINTID = requested_ich_lrc.pINTID; 155113531Sjairo.balart@metempsy.com } 155213531Sjairo.balart@metempsy.com 155313760Sjairo.balart@metempsy.com val = ich_lrc; 155413760Sjairo.balart@metempsy.com do_virtual_update = true; 155513760Sjairo.balart@metempsy.com break; 155613760Sjairo.balart@metempsy.com } 155713760Sjairo.balart@metempsy.com 155813760Sjairo.balart@metempsy.com // List Registers 155913531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: { 156013531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part) 156113580Sgabeblack@google.com RegVal old_val = isa->readMiscRegNoEffect(misc_reg); 156213531Sjairo.balart@metempsy.com val = (old_val & 0xffffffff00000000) | (val & 0xffffffff); 156313531Sjairo.balart@metempsy.com do_virtual_update = true; 156413531Sjairo.balart@metempsy.com break; 156513531Sjairo.balart@metempsy.com } 156613531Sjairo.balart@metempsy.com 156713760Sjairo.balart@metempsy.com // List Registers 156813531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64 156913760Sjairo.balart@metempsy.com ICH_LR_EL2 requested_ich_lr_el2 = val; 157013760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg); 157113760Sjairo.balart@metempsy.com 157213760Sjairo.balart@metempsy.com ich_lr_el2.State = requested_ich_lr_el2.State; 157313760Sjairo.balart@metempsy.com ich_lr_el2.HW = requested_ich_lr_el2.HW; 157413760Sjairo.balart@metempsy.com ich_lr_el2.Group = requested_ich_lr_el2.Group; 157513760Sjairo.balart@metempsy.com 157613760Sjairo.balart@metempsy.com // Priority, bits [55:48] 157713760Sjairo.balart@metempsy.com // At least five bits must be implemented. 157813760Sjairo.balart@metempsy.com // Unimplemented bits are RES0 and start from bit[48] up to bit[50]. 157913760Sjairo.balart@metempsy.com // We implement 5 bits. 158013760Sjairo.balart@metempsy.com ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) | 158113760Sjairo.balart@metempsy.com (ich_lr_el2.Priority & 0x07); 158213760Sjairo.balart@metempsy.com 158313760Sjairo.balart@metempsy.com // pINTID, bits [44:32] 158413760Sjairo.balart@metempsy.com // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning: 158513760Sjairo.balart@metempsy.com // - Bits[44:42] : RES0. 158613760Sjairo.balart@metempsy.com // - Bit[41] : EOI. 158713760Sjairo.balart@metempsy.com // - Bits[40:32] : RES0. 158813760Sjairo.balart@metempsy.com // When ICH_LR<n>_EL2.HW is 1: 158913760Sjairo.balart@metempsy.com // - This field is only required to implement enough bits to hold a 159013760Sjairo.balart@metempsy.com // valid value for the implemented INTID size. Any unused higher 159113760Sjairo.balart@metempsy.com // order bits are RES0. 159213760Sjairo.balart@metempsy.com if (requested_ich_lr_el2.HW == 0) { 159313760Sjairo.balart@metempsy.com ich_lr_el2.EOI = requested_ich_lr_el2.EOI; 159413760Sjairo.balart@metempsy.com } else { 159513760Sjairo.balart@metempsy.com ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID; 159613760Sjairo.balart@metempsy.com } 159713760Sjairo.balart@metempsy.com 159813760Sjairo.balart@metempsy.com // vINTID, bits [31:0] 159913760Sjairo.balart@metempsy.com // It is IMPLEMENTATION DEFINED how many bits are implemented, 160013760Sjairo.balart@metempsy.com // though at least 16 bits must be implemented. 160113760Sjairo.balart@metempsy.com // Unimplemented bits are RES0. 160213760Sjairo.balart@metempsy.com ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID; 160313760Sjairo.balart@metempsy.com 160413760Sjairo.balart@metempsy.com val = ich_lr_el2; 160513531Sjairo.balart@metempsy.com do_virtual_update = true; 160613531Sjairo.balart@metempsy.com break; 160713531Sjairo.balart@metempsy.com } 160813531Sjairo.balart@metempsy.com 160913760Sjairo.balart@metempsy.com // Virtual Machine Control Register 161013531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR: 161113531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR_EL2: { 161213760Sjairo.balart@metempsy.com ICH_VMCR_EL2 requested_ich_vmcr_el2 = val; 161313760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 161413760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 161513760Sjairo.balart@metempsy.com ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR; 161613531Sjairo.balart@metempsy.com uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS; 161713760Sjairo.balart@metempsy.com 161813760Sjairo.balart@metempsy.com if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) { 161913760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR0 = min_vpr0; 162013760Sjairo.balart@metempsy.com } else { 162113760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0; 162213760Sjairo.balart@metempsy.com } 162313760Sjairo.balart@metempsy.com 162413531Sjairo.balart@metempsy.com uint8_t min_vpr1 = min_vpr0 + 1; 162513760Sjairo.balart@metempsy.com 162613760Sjairo.balart@metempsy.com if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) { 162713760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR1 = min_vpr1; 162813760Sjairo.balart@metempsy.com } else { 162913760Sjairo.balart@metempsy.com ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1; 163013760Sjairo.balart@metempsy.com } 163113760Sjairo.balart@metempsy.com 163213760Sjairo.balart@metempsy.com ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM; 163313760Sjairo.balart@metempsy.com ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR; 163413760Sjairo.balart@metempsy.com ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1; 163513760Sjairo.balart@metempsy.com ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0; 163613760Sjairo.balart@metempsy.com val = ich_vmcr_el2; 163713531Sjairo.balart@metempsy.com break; 163813531Sjairo.balart@metempsy.com } 163913531Sjairo.balart@metempsy.com 164013760Sjairo.balart@metempsy.com // Hyp Active Priorities Group 0 Registers 164114236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R0: 164214236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R0_EL2: 164314236Sgiacomo.travaglini@arm.com break; 164414236Sgiacomo.travaglini@arm.com 164514236Sgiacomo.travaglini@arm.com // only implemented if supporting 6 or more bits of priority 164614236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R1: 164714236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R1_EL2: 164814236Sgiacomo.travaglini@arm.com // only implemented if supporting 7 or more bits of priority 164914236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R2: 165014236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R2_EL2: 165114236Sgiacomo.travaglini@arm.com // only implemented if supporting 7 or more bits of priority 165214236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R3: 165314236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP0R3_EL2: 165414236Sgiacomo.travaglini@arm.com // Unimplemented registers are RAZ/WI 165514236Sgiacomo.travaglini@arm.com return; 165614236Sgiacomo.travaglini@arm.com 165713760Sjairo.balart@metempsy.com // Hyp Active Priorities Group 1 Registers 165814236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R0: 165914236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R0_EL2: 166013531Sjairo.balart@metempsy.com break; 166113531Sjairo.balart@metempsy.com 166214236Sgiacomo.travaglini@arm.com // only implemented if supporting 6 or more bits of priority 166314236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R1: 166414236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R1_EL2: 166514236Sgiacomo.travaglini@arm.com // only implemented if supporting 7 or more bits of priority 166614236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R2: 166714236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R2_EL2: 166814236Sgiacomo.travaglini@arm.com // only implemented if supporting 7 or more bits of priority 166914236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R3: 167014236Sgiacomo.travaglini@arm.com case MISCREG_ICH_AP1R3_EL2: 167114236Sgiacomo.travaglini@arm.com // Unimplemented registers are RAZ/WI 167214236Sgiacomo.travaglini@arm.com return; 167314236Sgiacomo.travaglini@arm.com 167413531Sjairo.balart@metempsy.com default: 167513760Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)", 167613760Sjairo.balart@metempsy.com misc_reg, miscRegName[misc_reg]); 167713531Sjairo.balart@metempsy.com } 167813531Sjairo.balart@metempsy.com 167913531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(misc_reg, val); 168013531Sjairo.balart@metempsy.com 168113531Sjairo.balart@metempsy.com if (do_virtual_update) { 168213531Sjairo.balart@metempsy.com virtualUpdate(); 168313531Sjairo.balart@metempsy.com } 168413531Sjairo.balart@metempsy.com} 168513531Sjairo.balart@metempsy.com 168613531Sjairo.balart@metempsy.comint 168713760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualFindActive(uint32_t int_id) const 168813531Sjairo.balart@metempsy.com{ 168913531Sjairo.balart@metempsy.com for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 169013760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 169113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 169213760Sjairo.balart@metempsy.com 169313760Sjairo.balart@metempsy.com if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) || 169413760Sjairo.balart@metempsy.com (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) && 169513760Sjairo.balart@metempsy.com (ich_lr_el2.vINTID == int_id)) { 169613531Sjairo.balart@metempsy.com return lr_idx; 169713531Sjairo.balart@metempsy.com } 169813531Sjairo.balart@metempsy.com } 169913531Sjairo.balart@metempsy.com 170013531Sjairo.balart@metempsy.com return -1; 170113531Sjairo.balart@metempsy.com} 170213531Sjairo.balart@metempsy.com 170313531Sjairo.balart@metempsy.comuint32_t 170413760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR0() const 170513531Sjairo.balart@metempsy.com{ 170614233Sgiacomo.travaglini@arm.com if (hppi.prio == 0xff || !groupEnabled(hppi.group)) { 170713531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 170813531Sjairo.balart@metempsy.com } 170913531Sjairo.balart@metempsy.com 171013531Sjairo.balart@metempsy.com bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS; 171113531Sjairo.balart@metempsy.com 171213531Sjairo.balart@metempsy.com if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) { 171313760Sjairo.balart@metempsy.com // interrupt for the other state pending 171413531Sjairo.balart@metempsy.com return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE; 171513531Sjairo.balart@metempsy.com } 171613531Sjairo.balart@metempsy.com 171713531Sjairo.balart@metempsy.com if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon()) 171813531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 171913531Sjairo.balart@metempsy.com } 172013531Sjairo.balart@metempsy.com 172113531Sjairo.balart@metempsy.com if (irq_is_secure && !inSecureState()) { 172213531Sjairo.balart@metempsy.com // Secure interrupts not visible in Non-secure 172313531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 172413531Sjairo.balart@metempsy.com } 172513531Sjairo.balart@metempsy.com 172613531Sjairo.balart@metempsy.com return hppi.intid; 172713531Sjairo.balart@metempsy.com} 172813531Sjairo.balart@metempsy.com 172913531Sjairo.balart@metempsy.comuint32_t 173013760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR1() const 173113531Sjairo.balart@metempsy.com{ 173214233Sgiacomo.travaglini@arm.com if (hppi.prio == 0xff || !groupEnabled(hppi.group)) { 173313531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 173413531Sjairo.balart@metempsy.com } 173513531Sjairo.balart@metempsy.com 173613760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 173713760Sjairo.balart@metempsy.com if ((currEL() == EL3) && icc_ctlr_el3.RM) { 173813531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G0S) { 173913531Sjairo.balart@metempsy.com return Gicv3::INTID_SECURE; 174013531Sjairo.balart@metempsy.com } else if (hppi.group == Gicv3::G1NS) { 174113531Sjairo.balart@metempsy.com return Gicv3::INTID_NONSECURE; 174213531Sjairo.balart@metempsy.com } 174313531Sjairo.balart@metempsy.com } 174413531Sjairo.balart@metempsy.com 174513531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G0S) { 174613531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 174713531Sjairo.balart@metempsy.com } 174813531Sjairo.balart@metempsy.com 174913531Sjairo.balart@metempsy.com bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS); 175013531Sjairo.balart@metempsy.com 175113531Sjairo.balart@metempsy.com if (irq_is_secure) { 175213531Sjairo.balart@metempsy.com if (!inSecureState()) { 175313531Sjairo.balart@metempsy.com // Secure interrupts not visible in Non-secure 175413531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 175513531Sjairo.balart@metempsy.com } 175613531Sjairo.balart@metempsy.com } else if (!isEL3OrMon() && inSecureState()) { 175713531Sjairo.balart@metempsy.com // Group 1 non-secure interrupts not visible in Secure EL1 175813531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 175913531Sjairo.balart@metempsy.com } 176013531Sjairo.balart@metempsy.com 176113531Sjairo.balart@metempsy.com return hppi.intid; 176213531Sjairo.balart@metempsy.com} 176313531Sjairo.balart@metempsy.com 176413531Sjairo.balart@metempsy.comvoid 176513531Sjairo.balart@metempsy.comGicv3CPUInterface::dropPriority(Gicv3::GroupId group) 176613531Sjairo.balart@metempsy.com{ 176713531Sjairo.balart@metempsy.com int apr_misc_reg; 176813580Sgabeblack@google.com RegVal apr; 176913531Sjairo.balart@metempsy.com apr_misc_reg = group == Gicv3::G0S ? 177013531Sjairo.balart@metempsy.com MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1; 177113531Sjairo.balart@metempsy.com apr = isa->readMiscRegNoEffect(apr_misc_reg); 177213531Sjairo.balart@metempsy.com 177313531Sjairo.balart@metempsy.com if (apr) { 177413531Sjairo.balart@metempsy.com apr &= apr - 1; 177513531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_misc_reg, apr); 177613531Sjairo.balart@metempsy.com } 177713531Sjairo.balart@metempsy.com 177813531Sjairo.balart@metempsy.com update(); 177913531Sjairo.balart@metempsy.com} 178013531Sjairo.balart@metempsy.com 178113531Sjairo.balart@metempsy.comuint8_t 178213531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDropPriority() 178313531Sjairo.balart@metempsy.com{ 178413531Sjairo.balart@metempsy.com int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5); 178513531Sjairo.balart@metempsy.com 178613531Sjairo.balart@metempsy.com for (int i = 0; i < apr_max; i++) { 178713580Sgabeblack@google.com RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i); 178813580Sgabeblack@google.com RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i); 178913531Sjairo.balart@metempsy.com 179013531Sjairo.balart@metempsy.com if (!vapr0 && !vapr1) { 179113531Sjairo.balart@metempsy.com continue; 179213531Sjairo.balart@metempsy.com } 179313531Sjairo.balart@metempsy.com 179413531Sjairo.balart@metempsy.com int vapr0_count = ctz32(vapr0); 179513531Sjairo.balart@metempsy.com int vapr1_count = ctz32(vapr1); 179613531Sjairo.balart@metempsy.com 179713531Sjairo.balart@metempsy.com if (vapr0_count <= vapr1_count) { 179813531Sjairo.balart@metempsy.com vapr0 &= vapr0 - 1; 179913531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0); 180013531Sjairo.balart@metempsy.com return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1); 180113531Sjairo.balart@metempsy.com } else { 180213531Sjairo.balart@metempsy.com vapr1 &= vapr1 - 1; 180313531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1); 180413531Sjairo.balart@metempsy.com return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1); 180513531Sjairo.balart@metempsy.com } 180613531Sjairo.balart@metempsy.com } 180713531Sjairo.balart@metempsy.com 180813531Sjairo.balart@metempsy.com return 0xff; 180913531Sjairo.balart@metempsy.com} 181013531Sjairo.balart@metempsy.com 181113531Sjairo.balart@metempsy.comvoid 181214227Sgiacomo.travaglini@arm.comGicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group) 181314227Sgiacomo.travaglini@arm.com{ 181414227Sgiacomo.travaglini@arm.com uint8_t aff3 = bits(val, 55, 48); 181514227Sgiacomo.travaglini@arm.com uint8_t aff2 = bits(val, 39, 32); 181614227Sgiacomo.travaglini@arm.com uint8_t aff1 = bits(val, 23, 16);; 181714227Sgiacomo.travaglini@arm.com uint16_t target_list = bits(val, 15, 0); 181814227Sgiacomo.travaglini@arm.com uint32_t int_id = bits(val, 27, 24); 181914227Sgiacomo.travaglini@arm.com bool irm = bits(val, 40, 40); 182014227Sgiacomo.travaglini@arm.com uint8_t rs = bits(val, 47, 44); 182114227Sgiacomo.travaglini@arm.com 182214227Sgiacomo.travaglini@arm.com bool ns = !inSecureState(); 182314227Sgiacomo.travaglini@arm.com 182414227Sgiacomo.travaglini@arm.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 182514227Sgiacomo.travaglini@arm.com Gicv3Redistributor * redistributor_i = 182614227Sgiacomo.travaglini@arm.com gic->getRedistributor(i); 182714227Sgiacomo.travaglini@arm.com uint32_t affinity_i = redistributor_i->getAffinity(); 182814227Sgiacomo.travaglini@arm.com 182914227Sgiacomo.travaglini@arm.com if (irm) { 183014227Sgiacomo.travaglini@arm.com // Interrupts routed to all PEs in the system, 183114227Sgiacomo.travaglini@arm.com // excluding "self" 183214227Sgiacomo.travaglini@arm.com if (affinity_i == redistributor->getAffinity()) { 183314227Sgiacomo.travaglini@arm.com continue; 183414227Sgiacomo.travaglini@arm.com } 183514227Sgiacomo.travaglini@arm.com } else { 183614227Sgiacomo.travaglini@arm.com // Interrupts routed to the PEs specified by 183714227Sgiacomo.travaglini@arm.com // Aff3.Aff2.Aff1.<target list> 183814227Sgiacomo.travaglini@arm.com if ((affinity_i >> 8) != 183914227Sgiacomo.travaglini@arm.com ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) { 184014227Sgiacomo.travaglini@arm.com continue; 184114227Sgiacomo.travaglini@arm.com } 184214227Sgiacomo.travaglini@arm.com 184314227Sgiacomo.travaglini@arm.com uint8_t aff0_i = bits(affinity_i, 7, 0); 184414227Sgiacomo.travaglini@arm.com 184514227Sgiacomo.travaglini@arm.com if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 && 184614227Sgiacomo.travaglini@arm.com ((0x1 << (aff0_i - rs * 16)) & target_list))) { 184714227Sgiacomo.travaglini@arm.com continue; 184814227Sgiacomo.travaglini@arm.com } 184914227Sgiacomo.travaglini@arm.com } 185014227Sgiacomo.travaglini@arm.com 185114227Sgiacomo.travaglini@arm.com redistributor_i->sendSGI(int_id, group, ns); 185214227Sgiacomo.travaglini@arm.com } 185314227Sgiacomo.travaglini@arm.com} 185414227Sgiacomo.travaglini@arm.com 185514227Sgiacomo.travaglini@arm.comvoid 185613531Sjairo.balart@metempsy.comGicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group) 185713531Sjairo.balart@metempsy.com{ 185813531Sjairo.balart@metempsy.com // Update active priority registers. 185913531Sjairo.balart@metempsy.com uint32_t prio = hppi.prio & 0xf8; 186013531Sjairo.balart@metempsy.com int apr_bit = prio >> (8 - PRIORITY_BITS); 186113531Sjairo.balart@metempsy.com int reg_bit = apr_bit % 32; 186213531Sjairo.balart@metempsy.com int apr_idx = group == Gicv3::G0S ? 186313531Sjairo.balart@metempsy.com MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1; 186413580Sgabeblack@google.com RegVal apr = isa->readMiscRegNoEffect(apr_idx); 186513531Sjairo.balart@metempsy.com apr |= (1 << reg_bit); 186613531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_idx, apr); 186713531Sjairo.balart@metempsy.com 186813531Sjairo.balart@metempsy.com // Move interrupt state from pending to active. 186913531Sjairo.balart@metempsy.com if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) { 187013531Sjairo.balart@metempsy.com // SGI or PPI, redistributor 187113531Sjairo.balart@metempsy.com redistributor->activateIRQ(int_id); 187213531Sjairo.balart@metempsy.com } else if (int_id < Gicv3::INTID_SECURE) { 187313531Sjairo.balart@metempsy.com // SPI, distributor 187413531Sjairo.balart@metempsy.com distributor->activateIRQ(int_id); 187513923Sgiacomo.travaglini@arm.com } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) { 187613923Sgiacomo.travaglini@arm.com // LPI, Redistributor 187713923Sgiacomo.travaglini@arm.com redistributor->setClrLPI(int_id, false); 187813531Sjairo.balart@metempsy.com } 187914231Sgiacomo.travaglini@arm.com 188014231Sgiacomo.travaglini@arm.com // By setting the priority to 0xff we are effectively 188114231Sgiacomo.travaglini@arm.com // making the int_id not pending anymore at the cpu 188214231Sgiacomo.travaglini@arm.com // interface. 188314231Sgiacomo.travaglini@arm.com hppi.prio = 0xff; 188414231Sgiacomo.travaglini@arm.com updateDistributor(); 188513531Sjairo.balart@metempsy.com} 188613531Sjairo.balart@metempsy.com 188713531Sjairo.balart@metempsy.comvoid 188813531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx) 188913531Sjairo.balart@metempsy.com{ 189013531Sjairo.balart@metempsy.com // Update active priority registers. 189113760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + 189213531Sjairo.balart@metempsy.com lr_idx); 189313760Sjairo.balart@metempsy.com Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S; 189413760Sjairo.balart@metempsy.com uint8_t prio = ich_lr_el.Priority & 0xf8; 189513531Sjairo.balart@metempsy.com int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS); 189613531Sjairo.balart@metempsy.com int reg_no = apr_bit / 32; 189713531Sjairo.balart@metempsy.com int reg_bit = apr_bit % 32; 189813531Sjairo.balart@metempsy.com int apr_idx = group == Gicv3::G0S ? 189913531Sjairo.balart@metempsy.com MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no; 190013580Sgabeblack@google.com RegVal apr = isa->readMiscRegNoEffect(apr_idx); 190113531Sjairo.balart@metempsy.com apr |= (1 << reg_bit); 190213531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_idx, apr); 190313531Sjairo.balart@metempsy.com // Move interrupt state from pending to active. 190413760Sjairo.balart@metempsy.com ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE; 190513760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el); 190613531Sjairo.balart@metempsy.com} 190713531Sjairo.balart@metempsy.com 190813531Sjairo.balart@metempsy.comvoid 190913531Sjairo.balart@metempsy.comGicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group) 191013531Sjairo.balart@metempsy.com{ 191113531Sjairo.balart@metempsy.com if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) { 191213531Sjairo.balart@metempsy.com // SGI or PPI, redistributor 191313531Sjairo.balart@metempsy.com redistributor->deactivateIRQ(int_id); 191413531Sjairo.balart@metempsy.com } else if (int_id < Gicv3::INTID_SECURE) { 191513531Sjairo.balart@metempsy.com // SPI, distributor 191613531Sjairo.balart@metempsy.com distributor->deactivateIRQ(int_id); 191713531Sjairo.balart@metempsy.com } 191814231Sgiacomo.travaglini@arm.com 191914231Sgiacomo.travaglini@arm.com updateDistributor(); 192013531Sjairo.balart@metempsy.com} 192113531Sjairo.balart@metempsy.com 192213531Sjairo.balart@metempsy.comvoid 192313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDeactivateIRQ(int lr_idx) 192413531Sjairo.balart@metempsy.com{ 192513760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + 192613531Sjairo.balart@metempsy.com lr_idx); 192713531Sjairo.balart@metempsy.com 192813760Sjairo.balart@metempsy.com if (ich_lr_el2.HW) { 192913531Sjairo.balart@metempsy.com // Deactivate the associated physical interrupt 193013760Sjairo.balart@metempsy.com if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) { 193113760Sjairo.balart@metempsy.com Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ? 193213760Sjairo.balart@metempsy.com distributor->getIntGroup(ich_lr_el2.pINTID) : 193313760Sjairo.balart@metempsy.com redistributor->getIntGroup(ich_lr_el2.pINTID); 193413760Sjairo.balart@metempsy.com deactivateIRQ(ich_lr_el2.pINTID, group); 193513531Sjairo.balart@metempsy.com } 193613531Sjairo.balart@metempsy.com } 193713531Sjairo.balart@metempsy.com 193813531Sjairo.balart@metempsy.com // Remove the active bit 193913760Sjairo.balart@metempsy.com ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE; 194013760Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2); 194113531Sjairo.balart@metempsy.com} 194213531Sjairo.balart@metempsy.com 194313531Sjairo.balart@metempsy.com/* 194413760Sjairo.balart@metempsy.com * Returns the priority group field for the current BPR value for the group. 194513760Sjairo.balart@metempsy.com * GroupBits() Pseudocode from spec. 194613531Sjairo.balart@metempsy.com */ 194713531Sjairo.balart@metempsy.comuint32_t 194813926Sgiacomo.travaglini@arm.comGicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group) 194913531Sjairo.balart@metempsy.com{ 195013760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_s = 195113760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 195213760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1_ns = 195313760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 195413760Sjairo.balart@metempsy.com 195513760Sjairo.balart@metempsy.com if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) || 195613760Sjairo.balart@metempsy.com (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) { 195713531Sjairo.balart@metempsy.com group = Gicv3::G0S; 195813531Sjairo.balart@metempsy.com } 195913531Sjairo.balart@metempsy.com 196013531Sjairo.balart@metempsy.com int bpr; 196113531Sjairo.balart@metempsy.com 196213531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 196313926Sgiacomo.travaglini@arm.com bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7; 196413531Sjairo.balart@metempsy.com } else { 196513926Sgiacomo.travaglini@arm.com bpr = readMiscReg(MISCREG_ICC_BPR1_EL1) & 0x7; 196613531Sjairo.balart@metempsy.com } 196713531Sjairo.balart@metempsy.com 196813531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 196913531Sjairo.balart@metempsy.com assert(bpr > 0); 197013531Sjairo.balart@metempsy.com bpr--; 197113531Sjairo.balart@metempsy.com } 197213531Sjairo.balart@metempsy.com 197313531Sjairo.balart@metempsy.com return ~0U << (bpr + 1); 197413531Sjairo.balart@metempsy.com} 197513531Sjairo.balart@metempsy.com 197613531Sjairo.balart@metempsy.comuint32_t 197713760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const 197813531Sjairo.balart@metempsy.com{ 197913760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 198013531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 198113531Sjairo.balart@metempsy.com 198213760Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) { 198313531Sjairo.balart@metempsy.com group = Gicv3::G0S; 198413531Sjairo.balart@metempsy.com } 198513531Sjairo.balart@metempsy.com 198613531Sjairo.balart@metempsy.com int bpr; 198713531Sjairo.balart@metempsy.com 198813531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 198913760Sjairo.balart@metempsy.com bpr = ich_vmcr_el2.VBPR0; 199013531Sjairo.balart@metempsy.com } else { 199113760Sjairo.balart@metempsy.com bpr = ich_vmcr_el2.VBPR1; 199213531Sjairo.balart@metempsy.com } 199313531Sjairo.balart@metempsy.com 199413531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 199513531Sjairo.balart@metempsy.com assert(bpr > 0); 199613531Sjairo.balart@metempsy.com bpr--; 199713531Sjairo.balart@metempsy.com } 199813531Sjairo.balart@metempsy.com 199913531Sjairo.balart@metempsy.com return ~0U << (bpr + 1); 200013531Sjairo.balart@metempsy.com} 200113531Sjairo.balart@metempsy.com 200213531Sjairo.balart@metempsy.combool 200313760Sjairo.balart@metempsy.comGicv3CPUInterface::isEOISplitMode() const 200413531Sjairo.balart@metempsy.com{ 200513531Sjairo.balart@metempsy.com if (isEL3OrMon()) { 200613760Sjairo.balart@metempsy.com ICC_CTLR_EL3 icc_ctlr_el3 = 200713760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 200813760Sjairo.balart@metempsy.com return icc_ctlr_el3.EOImode_EL3; 200913531Sjairo.balart@metempsy.com } else { 201013760Sjairo.balart@metempsy.com ICC_CTLR_EL1 icc_ctlr_el1 = 201113760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1); 201213760Sjairo.balart@metempsy.com return icc_ctlr_el1.EOImode; 201313531Sjairo.balart@metempsy.com } 201413531Sjairo.balart@metempsy.com} 201513531Sjairo.balart@metempsy.com 201613531Sjairo.balart@metempsy.combool 201713760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIsEOISplitMode() const 201813531Sjairo.balart@metempsy.com{ 201913760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 202013760Sjairo.balart@metempsy.com return ich_vmcr_el2.VEOIM; 202113531Sjairo.balart@metempsy.com} 202213531Sjairo.balart@metempsy.com 202313531Sjairo.balart@metempsy.comint 202413760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActiveGroup() const 202513531Sjairo.balart@metempsy.com{ 202613531Sjairo.balart@metempsy.com int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1)); 202713531Sjairo.balart@metempsy.com int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S)); 202813531Sjairo.balart@metempsy.com int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS)); 202913531Sjairo.balart@metempsy.com 203013531Sjairo.balart@metempsy.com if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) { 203113531Sjairo.balart@metempsy.com return Gicv3::G1NS; 203213531Sjairo.balart@metempsy.com } 203313531Sjairo.balart@metempsy.com 203413531Sjairo.balart@metempsy.com if (gq_ctz < g0_ctz) { 203513531Sjairo.balart@metempsy.com return Gicv3::G1S; 203613531Sjairo.balart@metempsy.com } 203713531Sjairo.balart@metempsy.com 203813531Sjairo.balart@metempsy.com if (g0_ctz < 32) { 203913531Sjairo.balart@metempsy.com return Gicv3::G0S; 204013531Sjairo.balart@metempsy.com } 204113531Sjairo.balart@metempsy.com 204213531Sjairo.balart@metempsy.com return -1; 204313531Sjairo.balart@metempsy.com} 204413531Sjairo.balart@metempsy.com 204513531Sjairo.balart@metempsy.comvoid 204614231Sgiacomo.travaglini@arm.comGicv3CPUInterface::updateDistributor() 204714231Sgiacomo.travaglini@arm.com{ 204814231Sgiacomo.travaglini@arm.com distributor->update(); 204914231Sgiacomo.travaglini@arm.com} 205014231Sgiacomo.travaglini@arm.com 205114231Sgiacomo.travaglini@arm.comvoid 205213531Sjairo.balart@metempsy.comGicv3CPUInterface::update() 205313531Sjairo.balart@metempsy.com{ 205413531Sjairo.balart@metempsy.com bool signal_IRQ = false; 205513531Sjairo.balart@metempsy.com bool signal_FIQ = false; 205613531Sjairo.balart@metempsy.com 205713531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G1S && !haveEL(EL3)) { 205813531Sjairo.balart@metempsy.com /* 205913531Sjairo.balart@metempsy.com * Secure enabled GIC sending a G1S IRQ to a secure disabled 206013531Sjairo.balart@metempsy.com * CPU -> send G0 IRQ 206113531Sjairo.balart@metempsy.com */ 206213531Sjairo.balart@metempsy.com hppi.group = Gicv3::G0S; 206313531Sjairo.balart@metempsy.com } 206413531Sjairo.balart@metempsy.com 206513531Sjairo.balart@metempsy.com if (hppiCanPreempt()) { 206613531Sjairo.balart@metempsy.com ArmISA::InterruptTypes int_type = intSignalType(hppi.group); 206713531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::update(): " 206813531Sjairo.balart@metempsy.com "posting int as %d!\n", int_type); 206913531Sjairo.balart@metempsy.com int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true; 207013531Sjairo.balart@metempsy.com } 207113531Sjairo.balart@metempsy.com 207213531Sjairo.balart@metempsy.com if (signal_IRQ) { 207313531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_IRQ); 207413531Sjairo.balart@metempsy.com } else { 207513531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_IRQ); 207613531Sjairo.balart@metempsy.com } 207713531Sjairo.balart@metempsy.com 207813531Sjairo.balart@metempsy.com if (signal_FIQ) { 207913531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_FIQ); 208013531Sjairo.balart@metempsy.com } else { 208113531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_FIQ); 208213531Sjairo.balart@metempsy.com } 208313531Sjairo.balart@metempsy.com} 208413531Sjairo.balart@metempsy.com 208513531Sjairo.balart@metempsy.comvoid 208613531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualUpdate() 208713531Sjairo.balart@metempsy.com{ 208813531Sjairo.balart@metempsy.com bool signal_IRQ = false; 208913531Sjairo.balart@metempsy.com bool signal_FIQ = false; 209013531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 209113531Sjairo.balart@metempsy.com 209213531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 209313760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 209413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 209513531Sjairo.balart@metempsy.com 209613531Sjairo.balart@metempsy.com if (hppviCanPreempt(lr_idx)) { 209713760Sjairo.balart@metempsy.com if (ich_lr_el2.Group) { 209813531Sjairo.balart@metempsy.com signal_IRQ = true; 209913531Sjairo.balart@metempsy.com } else { 210013531Sjairo.balart@metempsy.com signal_FIQ = true; 210113531Sjairo.balart@metempsy.com } 210213531Sjairo.balart@metempsy.com } 210313531Sjairo.balart@metempsy.com } 210413531Sjairo.balart@metempsy.com 210513760Sjairo.balart@metempsy.com ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 210613760Sjairo.balart@metempsy.com 210713760Sjairo.balart@metempsy.com if (ich_hcr_el2.En) { 210813531Sjairo.balart@metempsy.com if (maintenanceInterruptStatus()) { 210913826Sgiacomo.travaglini@arm.com maintenanceInterrupt->raise(); 211013531Sjairo.balart@metempsy.com } 211113531Sjairo.balart@metempsy.com } 211213531Sjairo.balart@metempsy.com 211313531Sjairo.balart@metempsy.com if (signal_IRQ) { 211413531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): " 211513531Sjairo.balart@metempsy.com "posting int as %d!\n", ArmISA::INT_VIRT_IRQ); 211613531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ); 211713531Sjairo.balart@metempsy.com } else { 211813531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ); 211913531Sjairo.balart@metempsy.com } 212013531Sjairo.balart@metempsy.com 212113531Sjairo.balart@metempsy.com if (signal_FIQ) { 212213531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): " 212313531Sjairo.balart@metempsy.com "posting int as %d!\n", ArmISA::INT_VIRT_FIQ); 212413531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ); 212513531Sjairo.balart@metempsy.com } else { 212613531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ); 212713531Sjairo.balart@metempsy.com } 212813531Sjairo.balart@metempsy.com} 212913531Sjairo.balart@metempsy.com 213013760Sjairo.balart@metempsy.com// Returns the index of the LR with the HPPI 213113531Sjairo.balart@metempsy.comint 213213760Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPVILR() const 213313531Sjairo.balart@metempsy.com{ 213413531Sjairo.balart@metempsy.com int idx = -1; 213513760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 213613760Sjairo.balart@metempsy.com 213713760Sjairo.balart@metempsy.com if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) { 213813531Sjairo.balart@metempsy.com // VG0 and VG1 disabled... 213913531Sjairo.balart@metempsy.com return idx; 214013531Sjairo.balart@metempsy.com } 214113531Sjairo.balart@metempsy.com 214213531Sjairo.balart@metempsy.com uint8_t highest_prio = 0xff; 214313531Sjairo.balart@metempsy.com 214413531Sjairo.balart@metempsy.com for (int i = 0; i < 16; i++) { 214513760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 214613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i); 214713760Sjairo.balart@metempsy.com 214813760Sjairo.balart@metempsy.com if (ich_lr_el2.State != Gicv3::INT_PENDING) { 214913531Sjairo.balart@metempsy.com continue; 215013531Sjairo.balart@metempsy.com } 215113531Sjairo.balart@metempsy.com 215213760Sjairo.balart@metempsy.com if (ich_lr_el2.Group) { 215313531Sjairo.balart@metempsy.com // VG1 215413760Sjairo.balart@metempsy.com if (!ich_vmcr_el2.VENG1) { 215513531Sjairo.balart@metempsy.com continue; 215613531Sjairo.balart@metempsy.com } 215713531Sjairo.balart@metempsy.com } else { 215813531Sjairo.balart@metempsy.com // VG0 215913760Sjairo.balart@metempsy.com if (!ich_vmcr_el2.VENG0) { 216013531Sjairo.balart@metempsy.com continue; 216113531Sjairo.balart@metempsy.com } 216213531Sjairo.balart@metempsy.com } 216313531Sjairo.balart@metempsy.com 216413760Sjairo.balart@metempsy.com uint8_t prio = ich_lr_el2.Priority; 216513531Sjairo.balart@metempsy.com 216613531Sjairo.balart@metempsy.com if (prio < highest_prio) { 216713531Sjairo.balart@metempsy.com highest_prio = prio; 216813531Sjairo.balart@metempsy.com idx = i; 216913531Sjairo.balart@metempsy.com } 217013531Sjairo.balart@metempsy.com } 217113531Sjairo.balart@metempsy.com 217213531Sjairo.balart@metempsy.com return idx; 217313531Sjairo.balart@metempsy.com} 217413531Sjairo.balart@metempsy.com 217513531Sjairo.balart@metempsy.combool 217613760Sjairo.balart@metempsy.comGicv3CPUInterface::hppviCanPreempt(int lr_idx) const 217713531Sjairo.balart@metempsy.com{ 217813760Sjairo.balart@metempsy.com ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 217913760Sjairo.balart@metempsy.com if (!ich_hcr_el2.En) { 218013531Sjairo.balart@metempsy.com // virtual interface is disabled 218113531Sjairo.balart@metempsy.com return false; 218213531Sjairo.balart@metempsy.com } 218313531Sjairo.balart@metempsy.com 218413760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 218513760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 218613760Sjairo.balart@metempsy.com uint8_t prio = ich_lr_el2.Priority; 218713531Sjairo.balart@metempsy.com uint8_t vpmr = 218813531Sjairo.balart@metempsy.com bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24); 218913531Sjairo.balart@metempsy.com 219013531Sjairo.balart@metempsy.com if (prio >= vpmr) { 219113531Sjairo.balart@metempsy.com // prioriry masked 219213531Sjairo.balart@metempsy.com return false; 219313531Sjairo.balart@metempsy.com } 219413531Sjairo.balart@metempsy.com 219513531Sjairo.balart@metempsy.com uint8_t rprio = virtualHighestActivePriority(); 219613531Sjairo.balart@metempsy.com 219713531Sjairo.balart@metempsy.com if (rprio == 0xff) { 219813531Sjairo.balart@metempsy.com return true; 219913531Sjairo.balart@metempsy.com } 220013531Sjairo.balart@metempsy.com 220113760Sjairo.balart@metempsy.com Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S; 220213531Sjairo.balart@metempsy.com uint32_t prio_mask = virtualGroupPriorityMask(group); 220313531Sjairo.balart@metempsy.com 220413531Sjairo.balart@metempsy.com if ((prio & prio_mask) < (rprio & prio_mask)) { 220513531Sjairo.balart@metempsy.com return true; 220613531Sjairo.balart@metempsy.com } 220713531Sjairo.balart@metempsy.com 220813531Sjairo.balart@metempsy.com return false; 220913531Sjairo.balart@metempsy.com} 221013531Sjairo.balart@metempsy.com 221113531Sjairo.balart@metempsy.comuint8_t 221213760Sjairo.balart@metempsy.comGicv3CPUInterface::virtualHighestActivePriority() const 221313531Sjairo.balart@metempsy.com{ 221413531Sjairo.balart@metempsy.com uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5); 221513531Sjairo.balart@metempsy.com 221613531Sjairo.balart@metempsy.com for (int i = 0; i < num_aprs; i++) { 221713580Sgabeblack@google.com RegVal vapr = 221813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) | 221913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i); 222013531Sjairo.balart@metempsy.com 222113531Sjairo.balart@metempsy.com if (!vapr) { 222213531Sjairo.balart@metempsy.com continue; 222313531Sjairo.balart@metempsy.com } 222413531Sjairo.balart@metempsy.com 222513531Sjairo.balart@metempsy.com return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1); 222613531Sjairo.balart@metempsy.com } 222713531Sjairo.balart@metempsy.com 222813531Sjairo.balart@metempsy.com // no active interrups, return idle priority 222913531Sjairo.balart@metempsy.com return 0xff; 223013531Sjairo.balart@metempsy.com} 223113531Sjairo.balart@metempsy.com 223213531Sjairo.balart@metempsy.comvoid 223313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIncrementEOICount() 223413531Sjairo.balart@metempsy.com{ 223513531Sjairo.balart@metempsy.com // Increment the EOICOUNT field in ICH_HCR_EL2 223613580Sgabeblack@google.com RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 223713531Sjairo.balart@metempsy.com uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27); 223813531Sjairo.balart@metempsy.com EOI_cout++; 223913531Sjairo.balart@metempsy.com ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout); 224013531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2); 224113531Sjairo.balart@metempsy.com} 224213531Sjairo.balart@metempsy.com 224313760Sjairo.balart@metempsy.com// spec section 4.6.2 224413531Sjairo.balart@metempsy.comArmISA::InterruptTypes 224513760Sjairo.balart@metempsy.comGicv3CPUInterface::intSignalType(Gicv3::GroupId group) const 224613531Sjairo.balart@metempsy.com{ 224713531Sjairo.balart@metempsy.com bool is_fiq = false; 224813531Sjairo.balart@metempsy.com 224913531Sjairo.balart@metempsy.com switch (group) { 225013531Sjairo.balart@metempsy.com case Gicv3::G0S: 225113531Sjairo.balart@metempsy.com is_fiq = true; 225213531Sjairo.balart@metempsy.com break; 225313531Sjairo.balart@metempsy.com 225413531Sjairo.balart@metempsy.com case Gicv3::G1S: 225513531Sjairo.balart@metempsy.com is_fiq = (distributor->DS == 0) && 225613531Sjairo.balart@metempsy.com (!inSecureState() || ((currEL() == EL3) && isAA64())); 225713531Sjairo.balart@metempsy.com break; 225813531Sjairo.balart@metempsy.com 225913531Sjairo.balart@metempsy.com case Gicv3::G1NS: 226013531Sjairo.balart@metempsy.com is_fiq = (distributor->DS == 0) && inSecureState(); 226113531Sjairo.balart@metempsy.com break; 226213531Sjairo.balart@metempsy.com 226313531Sjairo.balart@metempsy.com default: 226413531Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::intSignalType(): invalid group!"); 226513531Sjairo.balart@metempsy.com } 226613531Sjairo.balart@metempsy.com 226713531Sjairo.balart@metempsy.com if (is_fiq) { 226813531Sjairo.balart@metempsy.com return ArmISA::INT_FIQ; 226913531Sjairo.balart@metempsy.com } else { 227013531Sjairo.balart@metempsy.com return ArmISA::INT_IRQ; 227113531Sjairo.balart@metempsy.com } 227213531Sjairo.balart@metempsy.com} 227313531Sjairo.balart@metempsy.com 227413531Sjairo.balart@metempsy.combool 227513926Sgiacomo.travaglini@arm.comGicv3CPUInterface::hppiCanPreempt() 227613531Sjairo.balart@metempsy.com{ 227713531Sjairo.balart@metempsy.com if (hppi.prio == 0xff) { 227813531Sjairo.balart@metempsy.com // there is no pending interrupt 227913531Sjairo.balart@metempsy.com return false; 228013531Sjairo.balart@metempsy.com } 228113531Sjairo.balart@metempsy.com 228213531Sjairo.balart@metempsy.com if (!groupEnabled(hppi.group)) { 228313531Sjairo.balart@metempsy.com // group disabled at CPU interface 228413531Sjairo.balart@metempsy.com return false; 228513531Sjairo.balart@metempsy.com } 228613531Sjairo.balart@metempsy.com 228713531Sjairo.balart@metempsy.com if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) { 228813531Sjairo.balart@metempsy.com // priority masked 228913531Sjairo.balart@metempsy.com return false; 229013531Sjairo.balart@metempsy.com } 229113531Sjairo.balart@metempsy.com 229213531Sjairo.balart@metempsy.com uint8_t rprio = highestActivePriority(); 229313531Sjairo.balart@metempsy.com 229413531Sjairo.balart@metempsy.com if (rprio == 0xff) { 229513531Sjairo.balart@metempsy.com return true; 229613531Sjairo.balart@metempsy.com } 229713531Sjairo.balart@metempsy.com 229813531Sjairo.balart@metempsy.com uint32_t prio_mask = groupPriorityMask(hppi.group); 229913531Sjairo.balart@metempsy.com 230013531Sjairo.balart@metempsy.com if ((hppi.prio & prio_mask) < (rprio & prio_mask)) { 230113531Sjairo.balart@metempsy.com return true; 230213531Sjairo.balart@metempsy.com } 230313531Sjairo.balart@metempsy.com 230413531Sjairo.balart@metempsy.com return false; 230513531Sjairo.balart@metempsy.com} 230613531Sjairo.balart@metempsy.com 230713531Sjairo.balart@metempsy.comuint8_t 230813760Sjairo.balart@metempsy.comGicv3CPUInterface::highestActivePriority() const 230913531Sjairo.balart@metempsy.com{ 231013531Sjairo.balart@metempsy.com uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) | 231113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) | 231213531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S); 231313531Sjairo.balart@metempsy.com 231413531Sjairo.balart@metempsy.com if (apr) { 231513531Sjairo.balart@metempsy.com return ctz32(apr) << (GIC_MIN_BPR + 1); 231613531Sjairo.balart@metempsy.com } 231713531Sjairo.balart@metempsy.com 231813531Sjairo.balart@metempsy.com // no active interrups, return idle priority 231913531Sjairo.balart@metempsy.com return 0xff; 232013531Sjairo.balart@metempsy.com} 232113531Sjairo.balart@metempsy.com 232213531Sjairo.balart@metempsy.combool 232313760Sjairo.balart@metempsy.comGicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const 232413531Sjairo.balart@metempsy.com{ 232513531Sjairo.balart@metempsy.com switch (group) { 232613760Sjairo.balart@metempsy.com case Gicv3::G0S: { 232713760Sjairo.balart@metempsy.com ICC_IGRPEN0_EL1 icc_igrpen0_el1 = 232813760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1); 232914234Sgiacomo.travaglini@arm.com return icc_igrpen0_el1.Enable && distributor->EnableGrp0; 233013760Sjairo.balart@metempsy.com } 233113760Sjairo.balart@metempsy.com 233213760Sjairo.balart@metempsy.com case Gicv3::G1S: { 233313760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1 icc_igrpen1_el1_s = 233413760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S); 233514234Sgiacomo.travaglini@arm.com return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S; 233613760Sjairo.balart@metempsy.com } 233713760Sjairo.balart@metempsy.com 233813760Sjairo.balart@metempsy.com case Gicv3::G1NS: { 233913760Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns = 234013760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS); 234114234Sgiacomo.travaglini@arm.com return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS; 234213760Sjairo.balart@metempsy.com } 234313531Sjairo.balart@metempsy.com 234413531Sjairo.balart@metempsy.com default: 234513531Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::groupEnable(): invalid group!\n"); 234613531Sjairo.balart@metempsy.com } 234713531Sjairo.balart@metempsy.com} 234813531Sjairo.balart@metempsy.com 234913531Sjairo.balart@metempsy.combool 235013760Sjairo.balart@metempsy.comGicv3CPUInterface::inSecureState() const 235113531Sjairo.balart@metempsy.com{ 235213531Sjairo.balart@metempsy.com if (!gic->getSystem()->haveSecurity()) { 235313531Sjairo.balart@metempsy.com return false; 235413531Sjairo.balart@metempsy.com } 235513531Sjairo.balart@metempsy.com 235613531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 235713531Sjairo.balart@metempsy.com SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR); 235813531Sjairo.balart@metempsy.com return ArmISA::inSecureState(scr, cpsr); 235913531Sjairo.balart@metempsy.com} 236013531Sjairo.balart@metempsy.com 236113531Sjairo.balart@metempsy.comint 236213760Sjairo.balart@metempsy.comGicv3CPUInterface::currEL() const 236313531Sjairo.balart@metempsy.com{ 236413531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 236513531Sjairo.balart@metempsy.com bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 236613531Sjairo.balart@metempsy.com 236713531Sjairo.balart@metempsy.com if (is_64) { 236813531Sjairo.balart@metempsy.com return (ExceptionLevel)(uint8_t) cpsr.el; 236913531Sjairo.balart@metempsy.com } else { 237013531Sjairo.balart@metempsy.com switch (cpsr.mode) { 237113531Sjairo.balart@metempsy.com case MODE_USER: 237213531Sjairo.balart@metempsy.com return 0; 237313531Sjairo.balart@metempsy.com 237413531Sjairo.balart@metempsy.com case MODE_HYP: 237513531Sjairo.balart@metempsy.com return 2; 237613531Sjairo.balart@metempsy.com 237713531Sjairo.balart@metempsy.com case MODE_MON: 237813531Sjairo.balart@metempsy.com return 3; 237913531Sjairo.balart@metempsy.com 238013531Sjairo.balart@metempsy.com default: 238113531Sjairo.balart@metempsy.com return 1; 238213531Sjairo.balart@metempsy.com } 238313531Sjairo.balart@metempsy.com } 238413531Sjairo.balart@metempsy.com} 238513531Sjairo.balart@metempsy.com 238613531Sjairo.balart@metempsy.combool 238713760Sjairo.balart@metempsy.comGicv3CPUInterface::haveEL(ExceptionLevel el) const 238813531Sjairo.balart@metempsy.com{ 238913531Sjairo.balart@metempsy.com switch (el) { 239013531Sjairo.balart@metempsy.com case EL0: 239113531Sjairo.balart@metempsy.com case EL1: 239213531Sjairo.balart@metempsy.com return true; 239313531Sjairo.balart@metempsy.com 239413531Sjairo.balart@metempsy.com case EL2: 239513531Sjairo.balart@metempsy.com return gic->getSystem()->haveVirtualization(); 239613531Sjairo.balart@metempsy.com 239713531Sjairo.balart@metempsy.com case EL3: 239813531Sjairo.balart@metempsy.com return gic->getSystem()->haveSecurity(); 239913531Sjairo.balart@metempsy.com 240013531Sjairo.balart@metempsy.com default: 240113531Sjairo.balart@metempsy.com warn("Unimplemented Exception Level\n"); 240213531Sjairo.balart@metempsy.com return false; 240313531Sjairo.balart@metempsy.com } 240413531Sjairo.balart@metempsy.com} 240513531Sjairo.balart@metempsy.com 240613531Sjairo.balart@metempsy.combool 240713760Sjairo.balart@metempsy.comGicv3CPUInterface::isSecureBelowEL3() const 240813531Sjairo.balart@metempsy.com{ 240913531Sjairo.balart@metempsy.com SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 241013531Sjairo.balart@metempsy.com return haveEL(EL3) && scr.ns == 0; 241113531Sjairo.balart@metempsy.com} 241213531Sjairo.balart@metempsy.com 241313531Sjairo.balart@metempsy.combool 241413760Sjairo.balart@metempsy.comGicv3CPUInterface::isAA64() const 241513531Sjairo.balart@metempsy.com{ 241613531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 241713531Sjairo.balart@metempsy.com return opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 241813531Sjairo.balart@metempsy.com} 241913531Sjairo.balart@metempsy.com 242013531Sjairo.balart@metempsy.combool 242113760Sjairo.balart@metempsy.comGicv3CPUInterface::isEL3OrMon() const 242213531Sjairo.balart@metempsy.com{ 242313531Sjairo.balart@metempsy.com if (haveEL(EL3)) { 242413531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 242513531Sjairo.balart@metempsy.com bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 242613531Sjairo.balart@metempsy.com 242713531Sjairo.balart@metempsy.com if (is_64 && (cpsr.el == EL3)) { 242813531Sjairo.balart@metempsy.com return true; 242913531Sjairo.balart@metempsy.com } else if (!is_64 && (cpsr.mode == MODE_MON)) { 243013531Sjairo.balart@metempsy.com return true; 243113531Sjairo.balart@metempsy.com } 243213531Sjairo.balart@metempsy.com } 243313531Sjairo.balart@metempsy.com 243413531Sjairo.balart@metempsy.com return false; 243513531Sjairo.balart@metempsy.com} 243613531Sjairo.balart@metempsy.com 243713760Sjairo.balart@metempsy.com// Computes ICH_EISR_EL2 243813760Sjairo.balart@metempsy.comuint64_t 243913760Sjairo.balart@metempsy.comGicv3CPUInterface::eoiMaintenanceInterruptStatus() const 244013531Sjairo.balart@metempsy.com{ 244113760Sjairo.balart@metempsy.com // ICH_EISR_EL2 244213760Sjairo.balart@metempsy.com // Bits [63:16] - RES0 244313760Sjairo.balart@metempsy.com // Status<n>, bit [n], for n = 0 to 15 244413760Sjairo.balart@metempsy.com // EOI maintenance interrupt status bit for List register <n>: 244513760Sjairo.balart@metempsy.com // 0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI 244613760Sjairo.balart@metempsy.com // maintenance interrupt. 244713760Sjairo.balart@metempsy.com // 1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance 244813760Sjairo.balart@metempsy.com // interrupt that has not been handled. 244913760Sjairo.balart@metempsy.com // 245013760Sjairo.balart@metempsy.com // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all 245113760Sjairo.balart@metempsy.com // of the following are true: 245213760Sjairo.balart@metempsy.com // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID). 245313760Sjairo.balart@metempsy.com // - ICH_LR<n>_EL2.HW is 0. 245413760Sjairo.balart@metempsy.com // - ICH_LR<n>_EL2.EOI (bit [41]) is 1. 245513760Sjairo.balart@metempsy.com 245613760Sjairo.balart@metempsy.com uint64_t value = 0; 245713531Sjairo.balart@metempsy.com 245813531Sjairo.balart@metempsy.com for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 245913760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 246013760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 246113760Sjairo.balart@metempsy.com 246213760Sjairo.balart@metempsy.com if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) && 246313760Sjairo.balart@metempsy.com !ich_lr_el2.HW && ich_lr_el2.EOI) { 246413531Sjairo.balart@metempsy.com value |= (1 << lr_idx); 246513531Sjairo.balart@metempsy.com } 246613760Sjairo.balart@metempsy.com } 246713760Sjairo.balart@metempsy.com 246813760Sjairo.balart@metempsy.com return value; 246913760Sjairo.balart@metempsy.com} 247013760Sjairo.balart@metempsy.com 247113760Sjairo.balart@metempsy.comGicv3CPUInterface::ICH_MISR_EL2 247213760Sjairo.balart@metempsy.comGicv3CPUInterface::maintenanceInterruptStatus() const 247313760Sjairo.balart@metempsy.com{ 247413760Sjairo.balart@metempsy.com // Comments are copied from SPEC section 9.4.7 (ID012119) 247513760Sjairo.balart@metempsy.com ICH_MISR_EL2 ich_misr_el2 = 0; 247613760Sjairo.balart@metempsy.com ICH_HCR_EL2 ich_hcr_el2 = 247713760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 247813760Sjairo.balart@metempsy.com ICH_VMCR_EL2 ich_vmcr_el2 = 247913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 248013760Sjairo.balart@metempsy.com 248113760Sjairo.balart@metempsy.com // End Of Interrupt. [bit 0] 248213760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when at least one bit in 248313760Sjairo.balart@metempsy.com // ICH_EISR_EL2 is 1. 248413760Sjairo.balart@metempsy.com 248513760Sjairo.balart@metempsy.com if (eoiMaintenanceInterruptStatus()) { 248613760Sjairo.balart@metempsy.com ich_misr_el2.EOI = 1; 248713760Sjairo.balart@metempsy.com } 248813760Sjairo.balart@metempsy.com 248913760Sjairo.balart@metempsy.com // Underflow. [bit 1] 249013760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and 249113760Sjairo.balart@metempsy.com // zero or one of the List register entries are marked as a valid 249213760Sjairo.balart@metempsy.com // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits 249313760Sjairo.balart@metempsy.com // do not equal 0x0. 249413760Sjairo.balart@metempsy.com uint32_t num_valid_interrupts = 0; 249513760Sjairo.balart@metempsy.com uint32_t num_pending_interrupts = 0; 249613760Sjairo.balart@metempsy.com 249713760Sjairo.balart@metempsy.com for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 249813760Sjairo.balart@metempsy.com ICH_LR_EL2 ich_lr_el2 = 249913760Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 250013760Sjairo.balart@metempsy.com 250113760Sjairo.balart@metempsy.com if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) { 250213760Sjairo.balart@metempsy.com num_valid_interrupts++; 250313531Sjairo.balart@metempsy.com } 250413531Sjairo.balart@metempsy.com 250513760Sjairo.balart@metempsy.com if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) { 250613760Sjairo.balart@metempsy.com num_pending_interrupts++; 250713531Sjairo.balart@metempsy.com } 250813531Sjairo.balart@metempsy.com } 250913531Sjairo.balart@metempsy.com 251013760Sjairo.balart@metempsy.com if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) { 251113760Sjairo.balart@metempsy.com ich_misr_el2.U = 1; 251213531Sjairo.balart@metempsy.com } 251313531Sjairo.balart@metempsy.com 251413760Sjairo.balart@metempsy.com // List Register Entry Not Present. [bit 2] 251513760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1 251613760Sjairo.balart@metempsy.com // and ICH_HCR_EL2.EOIcount is non-zero. 251713760Sjairo.balart@metempsy.com if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) { 251813760Sjairo.balart@metempsy.com ich_misr_el2.LRENP = 1; 251913531Sjairo.balart@metempsy.com } 252013531Sjairo.balart@metempsy.com 252113760Sjairo.balart@metempsy.com // No Pending. [bit 3] 252213760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and 252313760Sjairo.balart@metempsy.com // no List register is in pending state. 252413760Sjairo.balart@metempsy.com if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) { 252513760Sjairo.balart@metempsy.com ich_misr_el2.NP = 1; 252613531Sjairo.balart@metempsy.com } 252713531Sjairo.balart@metempsy.com 252813760Sjairo.balart@metempsy.com // vPE Group 0 Enabled. [bit 4] 252913760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when 253013760Sjairo.balart@metempsy.com // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1. 253113760Sjairo.balart@metempsy.com if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) { 253213760Sjairo.balart@metempsy.com ich_misr_el2.VGrp0E = 1; 253313531Sjairo.balart@metempsy.com } 253413531Sjairo.balart@metempsy.com 253513760Sjairo.balart@metempsy.com // vPE Group 0 Disabled. [bit 5] 253613760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when 253713760Sjairo.balart@metempsy.com // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0. 253813760Sjairo.balart@metempsy.com if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) { 253913760Sjairo.balart@metempsy.com ich_misr_el2.VGrp0D = 1; 254013531Sjairo.balart@metempsy.com } 254113531Sjairo.balart@metempsy.com 254213760Sjairo.balart@metempsy.com // vPE Group 1 Enabled. [bit 6] 254313760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when 254413760Sjairo.balart@metempsy.com // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1. 254513760Sjairo.balart@metempsy.com if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) { 254613760Sjairo.balart@metempsy.com ich_misr_el2.VGrp1E = 1; 254713531Sjairo.balart@metempsy.com } 254813531Sjairo.balart@metempsy.com 254913760Sjairo.balart@metempsy.com // vPE Group 1 Disabled. [bit 7] 255013760Sjairo.balart@metempsy.com // This maintenance interrupt is asserted when 255113760Sjairo.balart@metempsy.com // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0. 255213760Sjairo.balart@metempsy.com if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) { 255313760Sjairo.balart@metempsy.com ich_misr_el2.VGrp1D = 1; 255413760Sjairo.balart@metempsy.com } 255513760Sjairo.balart@metempsy.com 255613760Sjairo.balart@metempsy.com return ich_misr_el2; 255713531Sjairo.balart@metempsy.com} 255813531Sjairo.balart@metempsy.com 255913531Sjairo.balart@metempsy.comvoid 256013531Sjairo.balart@metempsy.comGicv3CPUInterface::serialize(CheckpointOut & cp) const 256113531Sjairo.balart@metempsy.com{ 256213531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(hppi.intid); 256313531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(hppi.prio); 256413531Sjairo.balart@metempsy.com SERIALIZE_ENUM(hppi.group); 256513531Sjairo.balart@metempsy.com} 256613531Sjairo.balart@metempsy.com 256713531Sjairo.balart@metempsy.comvoid 256813531Sjairo.balart@metempsy.comGicv3CPUInterface::unserialize(CheckpointIn & cp) 256913531Sjairo.balart@metempsy.com{ 257013531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(hppi.intid); 257113531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(hppi.prio); 257213531Sjairo.balart@metempsy.com UNSERIALIZE_ENUM(hppi.group); 257313531Sjairo.balart@metempsy.com} 2574