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