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