gic_v3_cpu_interface.cc revision 13531
113531Sjairo.balart@metempsy.com/* 213531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting 313531Sjairo.balart@metempsy.com * All rights reserved. 413531Sjairo.balart@metempsy.com * 513531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without 613531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are 713531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright 813531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer; 913531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright 1013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the 1113531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution; 1213531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its 1313531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from 1413531Sjairo.balart@metempsy.com * this software without specific prior written permission. 1513531Sjairo.balart@metempsy.com * 1613531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1713531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1813531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1913531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2013531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2113531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2213531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2313531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2413531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2513531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2613531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2713531Sjairo.balart@metempsy.com * 2813531Sjairo.balart@metempsy.com * Authors: Jairo Balart 2913531Sjairo.balart@metempsy.com */ 3013531Sjairo.balart@metempsy.com 3113531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh" 3213531Sjairo.balart@metempsy.com 3313531Sjairo.balart@metempsy.com#include "arch/arm/isa.hh" 3413531Sjairo.balart@metempsy.com#include "debug/GIC.hh" 3513531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh" 3613531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh" 3713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_redistributor.hh" 3813531Sjairo.balart@metempsy.com 3913531Sjairo.balart@metempsy.comGicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id) 4013531Sjairo.balart@metempsy.com : BaseISADevice(), 4113531Sjairo.balart@metempsy.com gic(gic), 4213531Sjairo.balart@metempsy.com redistributor(nullptr), 4313531Sjairo.balart@metempsy.com distributor(nullptr), 4413531Sjairo.balart@metempsy.com cpuId(cpu_id) 4513531Sjairo.balart@metempsy.com{ 4613531Sjairo.balart@metempsy.com} 4713531Sjairo.balart@metempsy.com 4813531Sjairo.balart@metempsy.comGicv3CPUInterface::~Gicv3CPUInterface() 4913531Sjairo.balart@metempsy.com{ 5013531Sjairo.balart@metempsy.com} 5113531Sjairo.balart@metempsy.com 5213531Sjairo.balart@metempsy.comvoid 5313531Sjairo.balart@metempsy.comGicv3CPUInterface::init() 5413531Sjairo.balart@metempsy.com{ 5513531Sjairo.balart@metempsy.com redistributor = gic->getRedistributor(cpuId); 5613531Sjairo.balart@metempsy.com distributor = gic->getDistributor(); 5713531Sjairo.balart@metempsy.com} 5813531Sjairo.balart@metempsy.com 5913531Sjairo.balart@metempsy.comvoid 6013531Sjairo.balart@metempsy.comGicv3CPUInterface::initState() 6113531Sjairo.balart@metempsy.com{ 6213531Sjairo.balart@metempsy.com reset(); 6313531Sjairo.balart@metempsy.com} 6413531Sjairo.balart@metempsy.com 6513531Sjairo.balart@metempsy.comvoid 6613531Sjairo.balart@metempsy.comGicv3CPUInterface::reset() 6713531Sjairo.balart@metempsy.com{ 6813531Sjairo.balart@metempsy.com hppi.prio = 0xff; 6913531Sjairo.balart@metempsy.com} 7013531Sjairo.balart@metempsy.com 7113531Sjairo.balart@metempsy.combool 7213531Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2FMO() 7313531Sjairo.balart@metempsy.com{ 7413531Sjairo.balart@metempsy.com HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2); 7513531Sjairo.balart@metempsy.com 7613531Sjairo.balart@metempsy.com if (hcr.tge && hcr.e2h) { 7713531Sjairo.balart@metempsy.com return false; 7813531Sjairo.balart@metempsy.com } else if (hcr.tge) { 7913531Sjairo.balart@metempsy.com return true; 8013531Sjairo.balart@metempsy.com } else { 8113531Sjairo.balart@metempsy.com return hcr.fmo; 8213531Sjairo.balart@metempsy.com } 8313531Sjairo.balart@metempsy.com} 8413531Sjairo.balart@metempsy.com 8513531Sjairo.balart@metempsy.combool 8613531Sjairo.balart@metempsy.comGicv3CPUInterface::getHCREL2IMO() 8713531Sjairo.balart@metempsy.com{ 8813531Sjairo.balart@metempsy.com HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2); 8913531Sjairo.balart@metempsy.com 9013531Sjairo.balart@metempsy.com if (hcr.tge && hcr.e2h) { 9113531Sjairo.balart@metempsy.com return false; 9213531Sjairo.balart@metempsy.com } else if (hcr.tge) { 9313531Sjairo.balart@metempsy.com return true; 9413531Sjairo.balart@metempsy.com } else { 9513531Sjairo.balart@metempsy.com return hcr.imo; 9613531Sjairo.balart@metempsy.com } 9713531Sjairo.balart@metempsy.com} 9813531Sjairo.balart@metempsy.com 9913531Sjairo.balart@metempsy.comArmISA::MiscReg 10013531Sjairo.balart@metempsy.comGicv3CPUInterface::readMiscReg(int misc_reg) 10113531Sjairo.balart@metempsy.com{ 10213531Sjairo.balart@metempsy.com ArmISA::MiscReg value = isa->readMiscRegNoEffect(misc_reg); 10313531Sjairo.balart@metempsy.com bool hcr_fmo = getHCREL2FMO(); 10413531Sjairo.balart@metempsy.com bool hcr_imo = getHCREL2IMO(); 10513531Sjairo.balart@metempsy.com 10613531Sjairo.balart@metempsy.com switch (misc_reg) { 10713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0: 10813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0_EL1: { 10913531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 11013531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1); 11113531Sjairo.balart@metempsy.com } 11213531Sjairo.balart@metempsy.com 11313531Sjairo.balart@metempsy.com break; 11413531Sjairo.balart@metempsy.com } 11513531Sjairo.balart@metempsy.com 11613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1: 11713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1_EL1: 11813531Sjairo.balart@metempsy.com 11913531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 12013531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2: 12113531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2_EL1: 12213531Sjairo.balart@metempsy.com 12313531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 12413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3: 12513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3_EL1: 12613531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 12713531Sjairo.balart@metempsy.com return 0; 12813531Sjairo.balart@metempsy.com 12913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0: 13013531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0_EL1: { 13113531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 13213531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1); 13313531Sjairo.balart@metempsy.com } 13413531Sjairo.balart@metempsy.com 13513531Sjairo.balart@metempsy.com break; 13613531Sjairo.balart@metempsy.com } 13713531Sjairo.balart@metempsy.com 13813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1: 13913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1_EL1: 14013531Sjairo.balart@metempsy.com 14113531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 14213531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2: 14313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2_EL1: 14413531Sjairo.balart@metempsy.com 14513531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 14613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3: 14713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3_EL1: 14813531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 14913531Sjairo.balart@metempsy.com return 0; 15013531Sjairo.balart@metempsy.com 15113531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0: 15213531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0_EL1: { 15313531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 15413531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_IGRPEN0_EL1); 15513531Sjairo.balart@metempsy.com } 15613531Sjairo.balart@metempsy.com 15713531Sjairo.balart@metempsy.com break; 15813531Sjairo.balart@metempsy.com } 15913531Sjairo.balart@metempsy.com 16013531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1: 16113531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL1: { 16213531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 16313531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_IGRPEN1_EL1); 16413531Sjairo.balart@metempsy.com } 16513531Sjairo.balart@metempsy.com 16613531Sjairo.balart@metempsy.com break; 16713531Sjairo.balart@metempsy.com } 16813531Sjairo.balart@metempsy.com 16913531Sjairo.balart@metempsy.com case MISCREG_ICC_MGRPEN1: 17013531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL3: { 17113531Sjairo.balart@metempsy.com // EnableGrp1S and EnableGrp1NS are aliased with 17213531Sjairo.balart@metempsy.com // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable 17313531Sjairo.balart@metempsy.com bool enable_grp_1s = 17413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S) & 17513531Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1_ENABLE; 17613531Sjairo.balart@metempsy.com bool enable_grp_1ns = 17713531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) & 17813531Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1_ENABLE; 17913531Sjairo.balart@metempsy.com value = 0; 18013531Sjairo.balart@metempsy.com 18113531Sjairo.balart@metempsy.com if (enable_grp_1s) { 18213531Sjairo.balart@metempsy.com value |= ICC_IGRPEN1_EL3_ENABLEGRP1S; 18313531Sjairo.balart@metempsy.com } 18413531Sjairo.balart@metempsy.com 18513531Sjairo.balart@metempsy.com if (enable_grp_1ns) { 18613531Sjairo.balart@metempsy.com value |= ICC_IGRPEN1_EL3_ENABLEGRP1NS; 18713531Sjairo.balart@metempsy.com } 18813531Sjairo.balart@metempsy.com 18913531Sjairo.balart@metempsy.com break; 19013531Sjairo.balart@metempsy.com } 19113531Sjairo.balart@metempsy.com 19213531Sjairo.balart@metempsy.com case MISCREG_ICC_RPR: 19313531Sjairo.balart@metempsy.com case MISCREG_ICC_RPR_EL1: { 19413531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 19513531Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 19613531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_RPR_EL1); 19713531Sjairo.balart@metempsy.com } 19813531Sjairo.balart@metempsy.com 19913531Sjairo.balart@metempsy.com uint8_t rprio = highestActivePriority(); 20013531Sjairo.balart@metempsy.com 20113531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && 20213531Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) { 20313531Sjairo.balart@metempsy.com /* NS GIC access and Group 0 is inaccessible to NS */ 20413531Sjairo.balart@metempsy.com if ((rprio & 0x80) == 0) { 20513531Sjairo.balart@metempsy.com /* NS should not see priorities in the Secure half of the 20613531Sjairo.balart@metempsy.com * range */ 20713531Sjairo.balart@metempsy.com rprio = 0; 20813531Sjairo.balart@metempsy.com } else if (rprio != 0xff) { 20913531Sjairo.balart@metempsy.com /* Non-idle priority: show the Non-secure view of it */ 21013531Sjairo.balart@metempsy.com rprio = (rprio << 1) & 0xff; 21113531Sjairo.balart@metempsy.com } 21213531Sjairo.balart@metempsy.com } 21313531Sjairo.balart@metempsy.com 21413531Sjairo.balart@metempsy.com value = rprio; 21513531Sjairo.balart@metempsy.com break; 21613531Sjairo.balart@metempsy.com } 21713531Sjairo.balart@metempsy.com 21813531Sjairo.balart@metempsy.com case MISCREG_ICV_RPR_EL1: { 21913531Sjairo.balart@metempsy.com value = virtualHighestActivePriority(); 22013531Sjairo.balart@metempsy.com break; 22113531Sjairo.balart@metempsy.com } 22213531Sjairo.balart@metempsy.com 22313531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR0: 22413531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR0_EL1: { 22513531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 22613531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_HPPIR0_EL1); 22713531Sjairo.balart@metempsy.com } 22813531Sjairo.balart@metempsy.com 22913531Sjairo.balart@metempsy.com value = getHPPIR0(); 23013531Sjairo.balart@metempsy.com break; 23113531Sjairo.balart@metempsy.com } 23213531Sjairo.balart@metempsy.com 23313531Sjairo.balart@metempsy.com case MISCREG_ICV_HPPIR0_EL1: { 23413531Sjairo.balart@metempsy.com value = Gicv3::INTID_SPURIOUS; 23513531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 23613531Sjairo.balart@metempsy.com 23713531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 23813531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 23913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 24013531Sjairo.balart@metempsy.com Gicv3::GroupId group = 24113531Sjairo.balart@metempsy.com lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S; 24213531Sjairo.balart@metempsy.com 24313531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 24413531Sjairo.balart@metempsy.com value = bits(lr, 31, 0); 24513531Sjairo.balart@metempsy.com } 24613531Sjairo.balart@metempsy.com } 24713531Sjairo.balart@metempsy.com 24813531Sjairo.balart@metempsy.com break; 24913531Sjairo.balart@metempsy.com } 25013531Sjairo.balart@metempsy.com 25113531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR1: 25213531Sjairo.balart@metempsy.com case MISCREG_ICC_HPPIR1_EL1: { 25313531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 25413531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_HPPIR1_EL1); 25513531Sjairo.balart@metempsy.com } 25613531Sjairo.balart@metempsy.com 25713531Sjairo.balart@metempsy.com value = getHPPIR1(); 25813531Sjairo.balart@metempsy.com break; 25913531Sjairo.balart@metempsy.com } 26013531Sjairo.balart@metempsy.com 26113531Sjairo.balart@metempsy.com case MISCREG_ICV_HPPIR1_EL1: { 26213531Sjairo.balart@metempsy.com value = Gicv3::INTID_SPURIOUS; 26313531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 26413531Sjairo.balart@metempsy.com 26513531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 26613531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 26713531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 26813531Sjairo.balart@metempsy.com Gicv3::GroupId group = 26913531Sjairo.balart@metempsy.com lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S; 27013531Sjairo.balart@metempsy.com 27113531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 27213531Sjairo.balart@metempsy.com value = bits(lr, 31, 0); 27313531Sjairo.balart@metempsy.com } 27413531Sjairo.balart@metempsy.com } 27513531Sjairo.balart@metempsy.com 27613531Sjairo.balart@metempsy.com break; 27713531Sjairo.balart@metempsy.com } 27813531Sjairo.balart@metempsy.com 27913531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0: 28013531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0_EL1: 28113531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 28213531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_BPR0_EL1); 28313531Sjairo.balart@metempsy.com } 28413531Sjairo.balart@metempsy.com 28513531Sjairo.balart@metempsy.com M5_FALLTHROUGH; 28613531Sjairo.balart@metempsy.com 28713531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1: 28813531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1_EL1: 28913531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 29013531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_BPR1_EL1); 29113531Sjairo.balart@metempsy.com } 29213531Sjairo.balart@metempsy.com 29313531Sjairo.balart@metempsy.com { 29413531Sjairo.balart@metempsy.com Gicv3::GroupId group = 29513531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S; 29613531Sjairo.balart@metempsy.com 29713531Sjairo.balart@metempsy.com if (group == Gicv3::G1S && !inSecureState()) { 29813531Sjairo.balart@metempsy.com group = Gicv3::G1NS; 29913531Sjairo.balart@metempsy.com } 30013531Sjairo.balart@metempsy.com 30113531Sjairo.balart@metempsy.com if ((group == Gicv3::G1S) && 30213531Sjairo.balart@metempsy.com !isEL3OrMon() && 30313531Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S) 30413531Sjairo.balart@metempsy.com & ICC_CTLR_EL1_CBPR)) { 30513531Sjairo.balart@metempsy.com group = Gicv3::G0S; 30613531Sjairo.balart@metempsy.com } 30713531Sjairo.balart@metempsy.com 30813531Sjairo.balart@metempsy.com bool sat_inc = false; 30913531Sjairo.balart@metempsy.com 31013531Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && 31113531Sjairo.balart@metempsy.com (currEL() < EL3) && 31213531Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS) 31313531Sjairo.balart@metempsy.com & ICC_CTLR_EL1_CBPR)) { 31413531Sjairo.balart@metempsy.com // Reads return BPR0 + 1 saturated to 7, WI 31513531Sjairo.balart@metempsy.com group = Gicv3::G0S; 31613531Sjairo.balart@metempsy.com sat_inc = true; 31713531Sjairo.balart@metempsy.com } 31813531Sjairo.balart@metempsy.com 31913531Sjairo.balart@metempsy.com uint8_t bpr; 32013531Sjairo.balart@metempsy.com 32113531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 32213531Sjairo.balart@metempsy.com bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1); 32313531Sjairo.balart@metempsy.com } else { 32413531Sjairo.balart@metempsy.com bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1); 32513531Sjairo.balart@metempsy.com } 32613531Sjairo.balart@metempsy.com 32713531Sjairo.balart@metempsy.com if (sat_inc) { 32813531Sjairo.balart@metempsy.com bpr++; 32913531Sjairo.balart@metempsy.com 33013531Sjairo.balart@metempsy.com if (bpr > 7) { 33113531Sjairo.balart@metempsy.com bpr = 7; 33213531Sjairo.balart@metempsy.com } 33313531Sjairo.balart@metempsy.com } 33413531Sjairo.balart@metempsy.com 33513531Sjairo.balart@metempsy.com value = bpr; 33613531Sjairo.balart@metempsy.com break; 33713531Sjairo.balart@metempsy.com } 33813531Sjairo.balart@metempsy.com 33913531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR0_EL1: 34013531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR1_EL1: { 34113531Sjairo.balart@metempsy.com Gicv3::GroupId group = 34213531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS; 34313531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 34413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 34513531Sjairo.balart@metempsy.com bool sat_inc = false; 34613531Sjairo.balart@metempsy.com 34713531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) { 34813531Sjairo.balart@metempsy.com // reads return bpr0 + 1 saturated to 7, writes ignored 34913531Sjairo.balart@metempsy.com group = Gicv3::G0S; 35013531Sjairo.balart@metempsy.com sat_inc = true; 35113531Sjairo.balart@metempsy.com } 35213531Sjairo.balart@metempsy.com 35313531Sjairo.balart@metempsy.com uint8_t vbpr; 35413531Sjairo.balart@metempsy.com 35513531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 35613531Sjairo.balart@metempsy.com vbpr = bits(ich_vmcr_el2, 23, 21); 35713531Sjairo.balart@metempsy.com } else { 35813531Sjairo.balart@metempsy.com vbpr = bits(ich_vmcr_el2, 20, 18); 35913531Sjairo.balart@metempsy.com } 36013531Sjairo.balart@metempsy.com 36113531Sjairo.balart@metempsy.com if (sat_inc) { 36213531Sjairo.balart@metempsy.com vbpr++; 36313531Sjairo.balart@metempsy.com 36413531Sjairo.balart@metempsy.com if (vbpr > 7) { 36513531Sjairo.balart@metempsy.com vbpr = 7; 36613531Sjairo.balart@metempsy.com } 36713531Sjairo.balart@metempsy.com } 36813531Sjairo.balart@metempsy.com 36913531Sjairo.balart@metempsy.com value = vbpr; 37013531Sjairo.balart@metempsy.com break; 37113531Sjairo.balart@metempsy.com } 37213531Sjairo.balart@metempsy.com 37313531Sjairo.balart@metempsy.com case MISCREG_ICC_PMR: 37413531Sjairo.balart@metempsy.com case MISCREG_ICC_PMR_EL1: // Priority Mask Register 37513531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 37613531Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 37713531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICV_PMR_EL1); 37813531Sjairo.balart@metempsy.com } 37913531Sjairo.balart@metempsy.com 38013531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && 38113531Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) { 38213531Sjairo.balart@metempsy.com /* NS GIC access and Group 0 is inaccessible to NS */ 38313531Sjairo.balart@metempsy.com if ((value & 0x80) == 0) { 38413531Sjairo.balart@metempsy.com /* NS should not see priorities in the Secure half of the 38513531Sjairo.balart@metempsy.com * range */ 38613531Sjairo.balart@metempsy.com value = 0; 38713531Sjairo.balart@metempsy.com } else if (value != 0xff) { 38813531Sjairo.balart@metempsy.com /* Non-idle priority: show the Non-secure view of it */ 38913531Sjairo.balart@metempsy.com value = (value << 1) & 0xff; 39013531Sjairo.balart@metempsy.com } 39113531Sjairo.balart@metempsy.com } 39213531Sjairo.balart@metempsy.com 39313531Sjairo.balart@metempsy.com break; 39413531Sjairo.balart@metempsy.com 39513531Sjairo.balart@metempsy.com case MISCREG_ICC_IAR0: 39613531Sjairo.balart@metempsy.com case MISCREG_ICC_IAR0_EL1: { // Interrupt Acknowledge Register 0 39713531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 39813531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_IAR0_EL1); 39913531Sjairo.balart@metempsy.com } 40013531Sjairo.balart@metempsy.com 40113531Sjairo.balart@metempsy.com uint32_t int_id; 40213531Sjairo.balart@metempsy.com 40313531Sjairo.balart@metempsy.com if (hppiCanPreempt()) { 40413531Sjairo.balart@metempsy.com int_id = getHPPIR0(); 40513531Sjairo.balart@metempsy.com 40613531Sjairo.balart@metempsy.com // avoid activation for special interrupts 40713531Sjairo.balart@metempsy.com if (int_id < Gicv3::INTID_SECURE) { 40813531Sjairo.balart@metempsy.com activateIRQ(int_id, hppi.group); 40913531Sjairo.balart@metempsy.com } 41013531Sjairo.balart@metempsy.com } else { 41113531Sjairo.balart@metempsy.com int_id = Gicv3::INTID_SPURIOUS; 41213531Sjairo.balart@metempsy.com } 41313531Sjairo.balart@metempsy.com 41413531Sjairo.balart@metempsy.com value = int_id; 41513531Sjairo.balart@metempsy.com break; 41613531Sjairo.balart@metempsy.com } 41713531Sjairo.balart@metempsy.com 41813531Sjairo.balart@metempsy.com case MISCREG_ICV_IAR0_EL1: { 41913531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 42013531Sjairo.balart@metempsy.com uint32_t int_id = Gicv3::INTID_SPURIOUS; 42113531Sjairo.balart@metempsy.com 42213531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 42313531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 42413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 42513531Sjairo.balart@metempsy.com 42613531Sjairo.balart@metempsy.com if (!(lr & ICH_LR_EL2_GROUP) && hppviCanPreempt(lr_idx)) { 42713531Sjairo.balart@metempsy.com int_id = value = bits(lr, 31, 0); 42813531Sjairo.balart@metempsy.com 42913531Sjairo.balart@metempsy.com if (int_id < Gicv3::INTID_SECURE || 43013531Sjairo.balart@metempsy.com int_id > Gicv3::INTID_SPURIOUS) { 43113531Sjairo.balart@metempsy.com virtualActivateIRQ(lr_idx); 43213531Sjairo.balart@metempsy.com } else { 43313531Sjairo.balart@metempsy.com // Bogus... Pseudocode says: 43413531Sjairo.balart@metempsy.com // - Move from pending to invalid... 43513531Sjairo.balart@metempsy.com // - Return de bogus id... 43613531Sjairo.balart@metempsy.com lr &= ~ICH_LR_EL2_STATE_PENDING_BIT; 43713531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, 43813531Sjairo.balart@metempsy.com lr); 43913531Sjairo.balart@metempsy.com } 44013531Sjairo.balart@metempsy.com } 44113531Sjairo.balart@metempsy.com } 44213531Sjairo.balart@metempsy.com 44313531Sjairo.balart@metempsy.com value = int_id; 44413531Sjairo.balart@metempsy.com virtualUpdate(); 44513531Sjairo.balart@metempsy.com break; 44613531Sjairo.balart@metempsy.com } 44713531Sjairo.balart@metempsy.com 44813531Sjairo.balart@metempsy.com case MISCREG_ICC_IAR1: 44913531Sjairo.balart@metempsy.com case MISCREG_ICC_IAR1_EL1: { // Interrupt Acknowledge Register 1 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 activateIRQ(int_id, hppi.group); 46213531Sjairo.balart@metempsy.com } 46313531Sjairo.balart@metempsy.com } else { 46413531Sjairo.balart@metempsy.com int_id = Gicv3::INTID_SPURIOUS; 46513531Sjairo.balart@metempsy.com } 46613531Sjairo.balart@metempsy.com 46713531Sjairo.balart@metempsy.com value = int_id; 46813531Sjairo.balart@metempsy.com break; 46913531Sjairo.balart@metempsy.com } 47013531Sjairo.balart@metempsy.com 47113531Sjairo.balart@metempsy.com case MISCREG_ICV_IAR1_EL1: { 47213531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 47313531Sjairo.balart@metempsy.com uint32_t int_id = Gicv3::INTID_SPURIOUS; 47413531Sjairo.balart@metempsy.com 47513531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 47613531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 47713531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 47813531Sjairo.balart@metempsy.com 47913531Sjairo.balart@metempsy.com if (lr & ICH_LR_EL2_GROUP && hppviCanPreempt(lr_idx)) { 48013531Sjairo.balart@metempsy.com int_id = value = bits(lr, 31, 0); 48113531Sjairo.balart@metempsy.com 48213531Sjairo.balart@metempsy.com if (int_id < Gicv3::INTID_SECURE || 48313531Sjairo.balart@metempsy.com int_id > Gicv3::INTID_SPURIOUS) { 48413531Sjairo.balart@metempsy.com virtualActivateIRQ(lr_idx); 48513531Sjairo.balart@metempsy.com } else { 48613531Sjairo.balart@metempsy.com // Bogus... Pseudocode says: 48713531Sjairo.balart@metempsy.com // - Move from pending to invalid... 48813531Sjairo.balart@metempsy.com // - Return de bogus id... 48913531Sjairo.balart@metempsy.com lr &= ~ICH_LR_EL2_STATE_PENDING_BIT; 49013531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, 49113531Sjairo.balart@metempsy.com lr); 49213531Sjairo.balart@metempsy.com } 49313531Sjairo.balart@metempsy.com } 49413531Sjairo.balart@metempsy.com } 49513531Sjairo.balart@metempsy.com 49613531Sjairo.balart@metempsy.com value = int_id; 49713531Sjairo.balart@metempsy.com virtualUpdate(); 49813531Sjairo.balart@metempsy.com break; 49913531Sjairo.balart@metempsy.com } 50013531Sjairo.balart@metempsy.com 50113531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE: 50213531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL1: { // System Register Enable Register 50313531Sjairo.balart@metempsy.com bool dfb; 50413531Sjairo.balart@metempsy.com bool dib; 50513531Sjairo.balart@metempsy.com 50613531Sjairo.balart@metempsy.com if (haveEL(EL3) && !distributor->DS) { 50713531Sjairo.balart@metempsy.com // DIB is RO alias of ICC_SRE_EL3.DIB 50813531Sjairo.balart@metempsy.com // DFB is RO alias of ICC_SRE_EL3.DFB 50913531Sjairo.balart@metempsy.com ArmISA::MiscReg icc_sre_el3 = 51013531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3); 51113531Sjairo.balart@metempsy.com dfb = icc_sre_el3 & ICC_SRE_EL3_DFB; 51213531Sjairo.balart@metempsy.com dib = icc_sre_el3 & ICC_SRE_EL3_DIB; 51313531Sjairo.balart@metempsy.com } else if (haveEL(EL3) && distributor->DS) { 51413531Sjairo.balart@metempsy.com // DIB is RW alias of ICC_SRE_EL3.DIB 51513531Sjairo.balart@metempsy.com // DFB is RW alias of ICC_SRE_EL3.DFB 51613531Sjairo.balart@metempsy.com ArmISA::MiscReg icc_sre_el3 = 51713531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3); 51813531Sjairo.balart@metempsy.com dfb = icc_sre_el3 & ICC_SRE_EL3_DFB; 51913531Sjairo.balart@metempsy.com dib = icc_sre_el3 & ICC_SRE_EL3_DIB; 52013531Sjairo.balart@metempsy.com } else if ((!haveEL(EL3) || distributor->DS) and haveEL(EL2)) { 52113531Sjairo.balart@metempsy.com // DIB is RO alias of ICC_SRE_EL2.DIB 52213531Sjairo.balart@metempsy.com // DFB is RO alias of ICC_SRE_EL2.DFB 52313531Sjairo.balart@metempsy.com ArmISA::MiscReg icc_sre_el2 = 52413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL2); 52513531Sjairo.balart@metempsy.com dfb = icc_sre_el2 & ICC_SRE_EL2_DFB; 52613531Sjairo.balart@metempsy.com dib = icc_sre_el2 & ICC_SRE_EL2_DIB; 52713531Sjairo.balart@metempsy.com } else { 52813531Sjairo.balart@metempsy.com dfb = value & ICC_SRE_EL1_DFB; 52913531Sjairo.balart@metempsy.com dib = value & ICC_SRE_EL1_DIB; 53013531Sjairo.balart@metempsy.com } 53113531Sjairo.balart@metempsy.com 53213531Sjairo.balart@metempsy.com value = ICC_SRE_EL1_SRE; 53313531Sjairo.balart@metempsy.com 53413531Sjairo.balart@metempsy.com if (dfb) { 53513531Sjairo.balart@metempsy.com value |= ICC_SRE_EL1_DFB; 53613531Sjairo.balart@metempsy.com } 53713531Sjairo.balart@metempsy.com 53813531Sjairo.balart@metempsy.com if (dib) { 53913531Sjairo.balart@metempsy.com value |= ICC_SRE_EL1_DIB; 54013531Sjairo.balart@metempsy.com } 54113531Sjairo.balart@metempsy.com 54213531Sjairo.balart@metempsy.com break; 54313531Sjairo.balart@metempsy.com } 54413531Sjairo.balart@metempsy.com 54513531Sjairo.balart@metempsy.com case MISCREG_ICC_HSRE: 54613531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL2: // System Register Enable Register 54713531Sjairo.balart@metempsy.com /* 54813531Sjairo.balart@metempsy.com * Enable [3] == 1 54913531Sjairo.balart@metempsy.com * (Secure EL1 accesses to Secure ICC_SRE_EL1 do not trap to EL2, 55013531Sjairo.balart@metempsy.com * RAO/WI) 55113531Sjairo.balart@metempsy.com * DIB [2] == 1 (IRQ bypass not supported, RAO/WI) 55213531Sjairo.balart@metempsy.com * DFB [1] == 1 (FIQ bypass not supported, RAO/WI) 55313531Sjairo.balart@metempsy.com * SRE [0] == 1 (Only system register interface supported, RAO/WI) 55413531Sjairo.balart@metempsy.com */ 55513531Sjairo.balart@metempsy.com value = ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_DIB | ICC_SRE_EL2_DFB | 55613531Sjairo.balart@metempsy.com ICC_SRE_EL2_SRE; 55713531Sjairo.balart@metempsy.com break; 55813531Sjairo.balart@metempsy.com 55913531Sjairo.balart@metempsy.com case MISCREG_ICC_MSRE: 56013531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL3: // System Register Enable Register 56113531Sjairo.balart@metempsy.com /* 56213531Sjairo.balart@metempsy.com * Enable [3] == 1 56313531Sjairo.balart@metempsy.com * (Secure EL1 accesses to Secure ICC_SRE_EL1 do not trap to EL3, 56413531Sjairo.balart@metempsy.com * RAO/WI) 56513531Sjairo.balart@metempsy.com * DIB [2] == 1 (IRQ bypass not supported, RAO/WI) 56613531Sjairo.balart@metempsy.com * DFB [1] == 1 (FIQ bypass not supported, RAO/WI) 56713531Sjairo.balart@metempsy.com * SRE [0] == 1 (Only system register interface supported, RAO/WI) 56813531Sjairo.balart@metempsy.com */ 56913531Sjairo.balart@metempsy.com value = ICC_SRE_EL3_ENABLE | ICC_SRE_EL3_DIB | ICC_SRE_EL3_DFB | 57013531Sjairo.balart@metempsy.com ICC_SRE_EL3_SRE; 57113531Sjairo.balart@metempsy.com break; 57213531Sjairo.balart@metempsy.com 57313531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR: 57413531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL1: { // Control Register 57513531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 57613531Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 57713531Sjairo.balart@metempsy.com return readMiscReg(MISCREG_ICV_CTLR_EL1); 57813531Sjairo.balart@metempsy.com } 57913531Sjairo.balart@metempsy.com 58013531Sjairo.balart@metempsy.com // Add value for RO bits 58113531Sjairo.balart@metempsy.com // IDbits [13:11], 001 = 24 bits | 000 = 16 bits 58213531Sjairo.balart@metempsy.com // PRIbits [10:8], number of priority bits implemented, minus one 58313531Sjairo.balart@metempsy.com value |= ICC_CTLR_EL1_RSS | ICC_CTLR_EL1_A3V | 58413531Sjairo.balart@metempsy.com (1 << 11) | ((PRIORITY_BITS - 1) << 8); 58513531Sjairo.balart@metempsy.com break; 58613531Sjairo.balart@metempsy.com } 58713531Sjairo.balart@metempsy.com 58813531Sjairo.balart@metempsy.com case MISCREG_ICV_CTLR_EL1: { 58913531Sjairo.balart@metempsy.com value = ICC_CTLR_EL1_A3V | (1 << ICC_CTLR_EL1_IDBITS_SHIFT) | 59013531Sjairo.balart@metempsy.com (7 << ICC_CTLR_EL1_PRIBITS_SHIFT); 59113531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 59213531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 59313531Sjairo.balart@metempsy.com 59413531Sjairo.balart@metempsy.com if (ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM) { 59513531Sjairo.balart@metempsy.com value |= ICC_CTLR_EL1_EOIMODE; 59613531Sjairo.balart@metempsy.com } 59713531Sjairo.balart@metempsy.com 59813531Sjairo.balart@metempsy.com if (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) { 59913531Sjairo.balart@metempsy.com value |= ICC_CTLR_EL1_CBPR; 60013531Sjairo.balart@metempsy.com } 60113531Sjairo.balart@metempsy.com 60213531Sjairo.balart@metempsy.com break; 60313531Sjairo.balart@metempsy.com } 60413531Sjairo.balart@metempsy.com 60513531Sjairo.balart@metempsy.com case MISCREG_ICC_MCTLR: 60613531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL3: { 60713531Sjairo.balart@metempsy.com // Add value for RO bits 60813531Sjairo.balart@metempsy.com // RSS [18] 60913531Sjairo.balart@metempsy.com // A3V [15] 61013531Sjairo.balart@metempsy.com // IDbits [13:11], 001 = 24 bits | 000 = 16 bits 61113531Sjairo.balart@metempsy.com // PRIbits [10:8], number of priority bits implemented, minus one 61213531Sjairo.balart@metempsy.com value |= ICC_CTLR_EL3_RSS | ICC_CTLR_EL3_A3V | (0 << 11) | 61313531Sjairo.balart@metempsy.com ((PRIORITY_BITS - 1) << 8); 61413531Sjairo.balart@metempsy.com // Aliased bits... 61513531Sjairo.balart@metempsy.com ArmISA::MiscReg icc_ctlr_el1_ns = 61613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 61713531Sjairo.balart@metempsy.com ArmISA::MiscReg icc_ctlr_el1_s = 61813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 61913531Sjairo.balart@metempsy.com 62013531Sjairo.balart@metempsy.com if (icc_ctlr_el1_ns & ICC_CTLR_EL1_EOIMODE) { 62113531Sjairo.balart@metempsy.com value |= ICC_CTLR_EL3_EOIMODE_EL1NS; 62213531Sjairo.balart@metempsy.com } 62313531Sjairo.balart@metempsy.com 62413531Sjairo.balart@metempsy.com if (icc_ctlr_el1_ns & ICC_CTLR_EL1_CBPR) { 62513531Sjairo.balart@metempsy.com value |= ICC_CTLR_EL3_CBPR_EL1NS; 62613531Sjairo.balart@metempsy.com } 62713531Sjairo.balart@metempsy.com 62813531Sjairo.balart@metempsy.com if (icc_ctlr_el1_s & ICC_CTLR_EL1_EOIMODE) { 62913531Sjairo.balart@metempsy.com value |= ICC_CTLR_EL3_EOIMODE_EL1S; 63013531Sjairo.balart@metempsy.com } 63113531Sjairo.balart@metempsy.com 63213531Sjairo.balart@metempsy.com if (icc_ctlr_el1_s & ICC_CTLR_EL1_CBPR) { 63313531Sjairo.balart@metempsy.com value |= ICC_CTLR_EL3_CBPR_EL1S; 63413531Sjairo.balart@metempsy.com } 63513531Sjairo.balart@metempsy.com 63613531Sjairo.balart@metempsy.com break; 63713531Sjairo.balart@metempsy.com } 63813531Sjairo.balart@metempsy.com 63913531Sjairo.balart@metempsy.com case MISCREG_ICH_HCR: 64013531Sjairo.balart@metempsy.com case MISCREG_ICH_HCR_EL2: 64113531Sjairo.balart@metempsy.com break; 64213531Sjairo.balart@metempsy.com 64313531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0: 64413531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0_EL2: 64513531Sjairo.balart@metempsy.com break; 64613531Sjairo.balart@metempsy.com 64713531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0: 64813531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0_EL2: 64913531Sjairo.balart@metempsy.com break; 65013531Sjairo.balart@metempsy.com 65113531Sjairo.balart@metempsy.com case MISCREG_ICH_MISR: 65213531Sjairo.balart@metempsy.com case MISCREG_ICH_MISR_EL2: { 65313531Sjairo.balart@metempsy.com value = 0; 65413531Sjairo.balart@metempsy.com // Scan list registers and fill in the U, NP and EOI bits 65513531Sjairo.balart@metempsy.com eoiMaintenanceInterruptStatus((uint32_t *) &value); 65613531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_hcr_el2 = 65713531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 65813531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 65913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 66013531Sjairo.balart@metempsy.com 66113531Sjairo.balart@metempsy.com if (ich_hcr_el2 & 66213531Sjairo.balart@metempsy.com (ICH_HCR_EL2_LRENPIE | ICH_HCR_EL2_EOICOUNT_MASK)) { 66313531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_LRENP; 66413531Sjairo.balart@metempsy.com } 66513531Sjairo.balart@metempsy.com 66613531Sjairo.balart@metempsy.com if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0EIE) && 66713531Sjairo.balart@metempsy.com (ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) { 66813531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_VGRP0E; 66913531Sjairo.balart@metempsy.com } 67013531Sjairo.balart@metempsy.com 67113531Sjairo.balart@metempsy.com if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) && 67213531Sjairo.balart@metempsy.com !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) { 67313531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_VGRP0D; 67413531Sjairo.balart@metempsy.com } 67513531Sjairo.balart@metempsy.com 67613531Sjairo.balart@metempsy.com if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) && 67713531Sjairo.balart@metempsy.com (ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) { 67813531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_VGRP1E; 67913531Sjairo.balart@metempsy.com } 68013531Sjairo.balart@metempsy.com 68113531Sjairo.balart@metempsy.com if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1DIE) && 68213531Sjairo.balart@metempsy.com !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) { 68313531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_VGRP1D; 68413531Sjairo.balart@metempsy.com } 68513531Sjairo.balart@metempsy.com 68613531Sjairo.balart@metempsy.com break; 68713531Sjairo.balart@metempsy.com } 68813531Sjairo.balart@metempsy.com 68913531Sjairo.balart@metempsy.com case MISCREG_ICH_VTR: 69013531Sjairo.balart@metempsy.com case MISCREG_ICH_VTR_EL2: 69113531Sjairo.balart@metempsy.com /* 69213531Sjairo.balart@metempsy.com * PRIbits [31:29] 69313531Sjairo.balart@metempsy.com * PREbits [28:26] 69413531Sjairo.balart@metempsy.com * IDbits [25:23] 69513531Sjairo.balart@metempsy.com * SEIS [22] == 0 (SEI Support) 69613531Sjairo.balart@metempsy.com * A3V [21] == 1 69713531Sjairo.balart@metempsy.com * (Non-zero values supported for Affinity 3 in SGI genearion) 69813531Sjairo.balart@metempsy.com * nV4 [20] == 0 69913531Sjairo.balart@metempsy.com * (Support for direct injection of virtual interrupts) 70013531Sjairo.balart@metempsy.com * TDS [19] == 0 (Implementation supports ICH_HCR_EL2.TDIR) 70113531Sjairo.balart@metempsy.com * ListRegs [4:0] 70213531Sjairo.balart@metempsy.com */ 70313531Sjairo.balart@metempsy.com value = (16 - 1) << 0 | 70413531Sjairo.balart@metempsy.com (5 - 1) << 26 | 70513531Sjairo.balart@metempsy.com (5 - 1) << 29; 70613531Sjairo.balart@metempsy.com value = 70713531Sjairo.balart@metempsy.com ((VIRTUAL_NUM_LIST_REGS - 1) << ICH_VTR_EL2_LISTREGS_SHIFT) | 70813531Sjairo.balart@metempsy.com // ICH_VTR_EL2_TDS | 70913531Sjairo.balart@metempsy.com // ICH_VTR_EL2_NV4 | 71013531Sjairo.balart@metempsy.com ICH_VTR_EL2_A3V | 71113531Sjairo.balart@metempsy.com (1 << ICH_VTR_EL2_IDBITS_SHIFT) | 71213531Sjairo.balart@metempsy.com ((VIRTUAL_PREEMPTION_BITS - 1) << ICH_VTR_EL2_PREBITS_SHIFT) | 71313531Sjairo.balart@metempsy.com ((VIRTUAL_PRIORITY_BITS - 1) << ICH_VTR_EL2_PRIBITS_SHIFT); 71413531Sjairo.balart@metempsy.com break; 71513531Sjairo.balart@metempsy.com 71613531Sjairo.balart@metempsy.com case MISCREG_ICH_EISR: 71713531Sjairo.balart@metempsy.com case MISCREG_ICH_EISR_EL2: 71813531Sjairo.balart@metempsy.com value = eoiMaintenanceInterruptStatus(nullptr); 71913531Sjairo.balart@metempsy.com break; 72013531Sjairo.balart@metempsy.com 72113531Sjairo.balart@metempsy.com case MISCREG_ICH_ELRSR: 72213531Sjairo.balart@metempsy.com case MISCREG_ICH_ELRSR_EL2: 72313531Sjairo.balart@metempsy.com value = 0; 72413531Sjairo.balart@metempsy.com 72513531Sjairo.balart@metempsy.com for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 72613531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 72713531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 72813531Sjairo.balart@metempsy.com 72913531Sjairo.balart@metempsy.com if ((lr & ICH_LR_EL2_STATE_MASK) == 0 && 73013531Sjairo.balart@metempsy.com ((lr & ICH_LR_EL2_HW) != 0 || 73113531Sjairo.balart@metempsy.com (lr & ICH_LR_EL2_EOI) == 0)) { 73213531Sjairo.balart@metempsy.com value |= (1 << lr_idx); 73313531Sjairo.balart@metempsy.com } 73413531Sjairo.balart@metempsy.com } 73513531Sjairo.balart@metempsy.com 73613531Sjairo.balart@metempsy.com break; 73713531Sjairo.balart@metempsy.com 73813531Sjairo.balart@metempsy.com case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: 73913531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part) 74013531Sjairo.balart@metempsy.com value = value >> 32; 74113531Sjairo.balart@metempsy.com break; 74213531Sjairo.balart@metempsy.com 74313531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: 74413531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part) 74513531Sjairo.balart@metempsy.com value = value & 0xffffffff; 74613531Sjairo.balart@metempsy.com break; 74713531Sjairo.balart@metempsy.com 74813531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: 74913531Sjairo.balart@metempsy.com break; 75013531Sjairo.balart@metempsy.com 75113531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR: 75213531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR_EL2: 75313531Sjairo.balart@metempsy.com break; 75413531Sjairo.balart@metempsy.com 75513531Sjairo.balart@metempsy.com default: 75613531Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::readMiscReg(): " 75713531Sjairo.balart@metempsy.com "unknown register %d (%s)", 75813531Sjairo.balart@metempsy.com misc_reg, miscRegName[misc_reg]); 75913531Sjairo.balart@metempsy.com } 76013531Sjairo.balart@metempsy.com 76113531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): " 76213531Sjairo.balart@metempsy.com "register %s value %#x\n", miscRegName[misc_reg], value); 76313531Sjairo.balart@metempsy.com return value; 76413531Sjairo.balart@metempsy.com} 76513531Sjairo.balart@metempsy.com 76613531Sjairo.balart@metempsy.comvoid 76713531Sjairo.balart@metempsy.comGicv3CPUInterface::setMiscReg(int misc_reg, ArmISA::MiscReg val) 76813531Sjairo.balart@metempsy.com{ 76913531Sjairo.balart@metempsy.com bool do_virtual_update = false; 77013531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): " 77113531Sjairo.balart@metempsy.com "register %s value %#x\n", miscRegName[misc_reg], val); 77213531Sjairo.balart@metempsy.com bool hcr_fmo = getHCREL2FMO(); 77313531Sjairo.balart@metempsy.com bool hcr_imo = getHCREL2IMO(); 77413531Sjairo.balart@metempsy.com 77513531Sjairo.balart@metempsy.com switch (misc_reg) { 77613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0: 77713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R0_EL1: 77813531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 77913531Sjairo.balart@metempsy.com return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val); 78013531Sjairo.balart@metempsy.com } 78113531Sjairo.balart@metempsy.com 78213531Sjairo.balart@metempsy.com break; 78313531Sjairo.balart@metempsy.com 78413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1: 78513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R1_EL1: 78613531Sjairo.balart@metempsy.com 78713531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 78813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2: 78913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R2_EL1: 79013531Sjairo.balart@metempsy.com 79113531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 79213531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3: 79313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP1R3_EL1: 79413531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 79513531Sjairo.balart@metempsy.com break; 79613531Sjairo.balart@metempsy.com 79713531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0: 79813531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R0_EL1: 79913531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 80013531Sjairo.balart@metempsy.com return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val); 80113531Sjairo.balart@metempsy.com } 80213531Sjairo.balart@metempsy.com 80313531Sjairo.balart@metempsy.com break; 80413531Sjairo.balart@metempsy.com 80513531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1: 80613531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R1_EL1: 80713531Sjairo.balart@metempsy.com 80813531Sjairo.balart@metempsy.com // only implemented if supporting 6 or more bits of priority 80913531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2: 81013531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R2_EL1: 81113531Sjairo.balart@metempsy.com 81213531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 81313531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3: 81413531Sjairo.balart@metempsy.com case MISCREG_ICC_AP0R3_EL1: 81513531Sjairo.balart@metempsy.com // only implemented if supporting 7 or more bits of priority 81613531Sjairo.balart@metempsy.com break; 81713531Sjairo.balart@metempsy.com 81813531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR0: 81913531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0 82013531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 82113531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_EOIR0_EL1, val); 82213531Sjairo.balart@metempsy.com } 82313531Sjairo.balart@metempsy.com 82413531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 82513531Sjairo.balart@metempsy.com 82613531Sjairo.balart@metempsy.com // avoid activation for special interrupts 82713531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE) { 82813531Sjairo.balart@metempsy.com return; 82913531Sjairo.balart@metempsy.com } 83013531Sjairo.balart@metempsy.com 83113531Sjairo.balart@metempsy.com Gicv3::GroupId group = Gicv3::G0S; 83213531Sjairo.balart@metempsy.com 83313531Sjairo.balart@metempsy.com if (highestActiveGroup() != group) { 83413531Sjairo.balart@metempsy.com return; 83513531Sjairo.balart@metempsy.com } 83613531Sjairo.balart@metempsy.com 83713531Sjairo.balart@metempsy.com dropPriority(group); 83813531Sjairo.balart@metempsy.com 83913531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 84013531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 84113531Sjairo.balart@metempsy.com } 84213531Sjairo.balart@metempsy.com 84313531Sjairo.balart@metempsy.com break; 84413531Sjairo.balart@metempsy.com } 84513531Sjairo.balart@metempsy.com 84613531Sjairo.balart@metempsy.com case MISCREG_ICV_EOIR0_EL1: { 84713531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 84813531Sjairo.balart@metempsy.com 84913531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 85013531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 85113531Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 85213531Sjairo.balart@metempsy.com return; 85313531Sjairo.balart@metempsy.com } 85413531Sjairo.balart@metempsy.com 85513531Sjairo.balart@metempsy.com uint8_t drop_prio = virtualDropPriority(); 85613531Sjairo.balart@metempsy.com 85713531Sjairo.balart@metempsy.com if (drop_prio == 0xff) { 85813531Sjairo.balart@metempsy.com return; 85913531Sjairo.balart@metempsy.com } 86013531Sjairo.balart@metempsy.com 86113531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 86213531Sjairo.balart@metempsy.com 86313531Sjairo.balart@metempsy.com if (lr_idx < 0) { 86413531Sjairo.balart@metempsy.com // No LR found matching 86513531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 86613531Sjairo.balart@metempsy.com } else { 86713531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 86813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 86913531Sjairo.balart@metempsy.com Gicv3::GroupId lr_group = 87013531Sjairo.balart@metempsy.com lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S; 87113531Sjairo.balart@metempsy.com uint8_t lr_group_prio = bits(lr, 55, 48) & 0xf8; 87213531Sjairo.balart@metempsy.com 87313531Sjairo.balart@metempsy.com if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) { 87413531Sjairo.balart@metempsy.com //JAIRO if (!virtualIsEOISplitMode()) 87513531Sjairo.balart@metempsy.com { 87613531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 87713531Sjairo.balart@metempsy.com } 87813531Sjairo.balart@metempsy.com } 87913531Sjairo.balart@metempsy.com } 88013531Sjairo.balart@metempsy.com 88113531Sjairo.balart@metempsy.com virtualUpdate(); 88213531Sjairo.balart@metempsy.com break; 88313531Sjairo.balart@metempsy.com } 88413531Sjairo.balart@metempsy.com 88513531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR1: 88613531Sjairo.balart@metempsy.com case MISCREG_ICC_EOIR1_EL1: { // End Of Interrupt Register 1 88713531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 88813531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_EOIR1_EL1, val); 88913531Sjairo.balart@metempsy.com } 89013531Sjairo.balart@metempsy.com 89113531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 89213531Sjairo.balart@metempsy.com 89313531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 89413531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE) { 89513531Sjairo.balart@metempsy.com return; 89613531Sjairo.balart@metempsy.com } 89713531Sjairo.balart@metempsy.com 89813531Sjairo.balart@metempsy.com Gicv3::GroupId group = 89913531Sjairo.balart@metempsy.com inSecureState() ? Gicv3::G1S : Gicv3::G1NS; 90013531Sjairo.balart@metempsy.com 90113531Sjairo.balart@metempsy.com if (highestActiveGroup() == Gicv3::G0S) { 90213531Sjairo.balart@metempsy.com return; 90313531Sjairo.balart@metempsy.com } 90413531Sjairo.balart@metempsy.com 90513531Sjairo.balart@metempsy.com if (distributor->DS == 0) { 90613531Sjairo.balart@metempsy.com if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) { 90713531Sjairo.balart@metempsy.com return; 90813531Sjairo.balart@metempsy.com } else if (highestActiveGroup() == Gicv3::G1NS && 90913531Sjairo.balart@metempsy.com !(!inSecureState() or (currEL() == EL3))) { 91013531Sjairo.balart@metempsy.com return; 91113531Sjairo.balart@metempsy.com } 91213531Sjairo.balart@metempsy.com } 91313531Sjairo.balart@metempsy.com 91413531Sjairo.balart@metempsy.com dropPriority(group); 91513531Sjairo.balart@metempsy.com 91613531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 91713531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 91813531Sjairo.balart@metempsy.com } 91913531Sjairo.balart@metempsy.com 92013531Sjairo.balart@metempsy.com break; 92113531Sjairo.balart@metempsy.com } 92213531Sjairo.balart@metempsy.com 92313531Sjairo.balart@metempsy.com case MISCREG_ICV_EOIR1_EL1: { 92413531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 92513531Sjairo.balart@metempsy.com 92613531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 92713531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 92813531Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 92913531Sjairo.balart@metempsy.com return; 93013531Sjairo.balart@metempsy.com } 93113531Sjairo.balart@metempsy.com 93213531Sjairo.balart@metempsy.com uint8_t drop_prio = virtualDropPriority(); 93313531Sjairo.balart@metempsy.com 93413531Sjairo.balart@metempsy.com if (drop_prio == 0xff) { 93513531Sjairo.balart@metempsy.com return; 93613531Sjairo.balart@metempsy.com } 93713531Sjairo.balart@metempsy.com 93813531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 93913531Sjairo.balart@metempsy.com 94013531Sjairo.balart@metempsy.com if (lr_idx < 0) { 94113531Sjairo.balart@metempsy.com // No LR found matching 94213531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 94313531Sjairo.balart@metempsy.com } else { 94413531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 94513531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 94613531Sjairo.balart@metempsy.com Gicv3::GroupId lr_group = 94713531Sjairo.balart@metempsy.com lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S; 94813531Sjairo.balart@metempsy.com uint8_t lr_group_prio = bits(lr, 55, 48) & 0xf8; 94913531Sjairo.balart@metempsy.com 95013531Sjairo.balart@metempsy.com if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) { 95113531Sjairo.balart@metempsy.com if (!virtualIsEOISplitMode()) { 95213531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 95313531Sjairo.balart@metempsy.com } 95413531Sjairo.balart@metempsy.com } 95513531Sjairo.balart@metempsy.com } 95613531Sjairo.balart@metempsy.com 95713531Sjairo.balart@metempsy.com virtualUpdate(); 95813531Sjairo.balart@metempsy.com break; 95913531Sjairo.balart@metempsy.com } 96013531Sjairo.balart@metempsy.com 96113531Sjairo.balart@metempsy.com case MISCREG_ICC_DIR: 96213531Sjairo.balart@metempsy.com case MISCREG_ICC_DIR_EL1: { // Deactivate Interrupt Register 96313531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 96413531Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 96513531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_DIR_EL1, val); 96613531Sjairo.balart@metempsy.com } 96713531Sjairo.balart@metempsy.com 96813531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 96913531Sjairo.balart@metempsy.com 97013531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 97113531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE) { 97213531Sjairo.balart@metempsy.com return; 97313531Sjairo.balart@metempsy.com } 97413531Sjairo.balart@metempsy.com 97513531Sjairo.balart@metempsy.com if (!isEOISplitMode()) { 97613531Sjairo.balart@metempsy.com return; 97713531Sjairo.balart@metempsy.com } 97813531Sjairo.balart@metempsy.com 97913531Sjairo.balart@metempsy.com /* 98013531Sjairo.balart@metempsy.com * Check whether we're allowed to deactivate. 98113531Sjairo.balart@metempsy.com * These checks are correspond to the spec's pseudocode. 98213531Sjairo.balart@metempsy.com */ 98313531Sjairo.balart@metempsy.com Gicv3::GroupId group = 98413531Sjairo.balart@metempsy.com int_id >= 32 ? distributor->getIntGroup(int_id) : 98513531Sjairo.balart@metempsy.com redistributor->getIntGroup(int_id); 98613531Sjairo.balart@metempsy.com bool irq_is_grp0 = group == Gicv3::G0S; 98713531Sjairo.balart@metempsy.com bool single_sec_state = distributor->DS; 98813531Sjairo.balart@metempsy.com bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS); 98913531Sjairo.balart@metempsy.com SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 99013531Sjairo.balart@metempsy.com bool route_fiq_to_el3 = scr_el3.fiq; 99113531Sjairo.balart@metempsy.com bool route_irq_to_el3 = scr_el3.irq; 99213531Sjairo.balart@metempsy.com bool route_fiq_to_el2 = hcr_fmo; 99313531Sjairo.balart@metempsy.com bool route_irq_to_el2 = hcr_imo; 99413531Sjairo.balart@metempsy.com 99513531Sjairo.balart@metempsy.com switch (currEL()) { 99613531Sjairo.balart@metempsy.com case EL3: 99713531Sjairo.balart@metempsy.com break; 99813531Sjairo.balart@metempsy.com 99913531Sjairo.balart@metempsy.com case EL2: 100013531Sjairo.balart@metempsy.com if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) { 100113531Sjairo.balart@metempsy.com break; 100213531Sjairo.balart@metempsy.com } 100313531Sjairo.balart@metempsy.com 100413531Sjairo.balart@metempsy.com if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) { 100513531Sjairo.balart@metempsy.com break; 100613531Sjairo.balart@metempsy.com } 100713531Sjairo.balart@metempsy.com 100813531Sjairo.balart@metempsy.com return; 100913531Sjairo.balart@metempsy.com 101013531Sjairo.balart@metempsy.com case EL1: 101113531Sjairo.balart@metempsy.com if (!isSecureBelowEL3()) { 101213531Sjairo.balart@metempsy.com if (single_sec_state && irq_is_grp0 && 101313531Sjairo.balart@metempsy.com !route_fiq_to_el3 && !route_fiq_to_el2) { 101413531Sjairo.balart@metempsy.com break; 101513531Sjairo.balart@metempsy.com } 101613531Sjairo.balart@metempsy.com 101713531Sjairo.balart@metempsy.com if (!irq_is_secure && !irq_is_grp0 && 101813531Sjairo.balart@metempsy.com !route_irq_to_el3 && !route_irq_to_el2) { 101913531Sjairo.balart@metempsy.com break; 102013531Sjairo.balart@metempsy.com } 102113531Sjairo.balart@metempsy.com } else { 102213531Sjairo.balart@metempsy.com if (irq_is_grp0 && !route_fiq_to_el3) { 102313531Sjairo.balart@metempsy.com break; 102413531Sjairo.balart@metempsy.com } 102513531Sjairo.balart@metempsy.com 102613531Sjairo.balart@metempsy.com if (!irq_is_grp0 && 102713531Sjairo.balart@metempsy.com (!irq_is_secure || !single_sec_state) && 102813531Sjairo.balart@metempsy.com !route_irq_to_el3) { 102913531Sjairo.balart@metempsy.com break; 103013531Sjairo.balart@metempsy.com } 103113531Sjairo.balart@metempsy.com } 103213531Sjairo.balart@metempsy.com 103313531Sjairo.balart@metempsy.com return; 103413531Sjairo.balart@metempsy.com 103513531Sjairo.balart@metempsy.com default: 103613531Sjairo.balart@metempsy.com break; 103713531Sjairo.balart@metempsy.com } 103813531Sjairo.balart@metempsy.com 103913531Sjairo.balart@metempsy.com deactivateIRQ(int_id, group); 104013531Sjairo.balart@metempsy.com break; 104113531Sjairo.balart@metempsy.com } 104213531Sjairo.balart@metempsy.com 104313531Sjairo.balart@metempsy.com case MISCREG_ICV_DIR_EL1: { 104413531Sjairo.balart@metempsy.com int int_id = val & 0xffffff; 104513531Sjairo.balart@metempsy.com 104613531Sjairo.balart@metempsy.com // avoid deactivation for special interrupts 104713531Sjairo.balart@metempsy.com if (int_id >= Gicv3::INTID_SECURE && 104813531Sjairo.balart@metempsy.com int_id <= Gicv3::INTID_SPURIOUS) { 104913531Sjairo.balart@metempsy.com return; 105013531Sjairo.balart@metempsy.com } 105113531Sjairo.balart@metempsy.com 105213531Sjairo.balart@metempsy.com if (!virtualIsEOISplitMode()) { 105313531Sjairo.balart@metempsy.com return; 105413531Sjairo.balart@metempsy.com } 105513531Sjairo.balart@metempsy.com 105613531Sjairo.balart@metempsy.com int lr_idx = virtualFindActive(int_id); 105713531Sjairo.balart@metempsy.com 105813531Sjairo.balart@metempsy.com if (lr_idx < 0) { 105913531Sjairo.balart@metempsy.com // No LR found matching 106013531Sjairo.balart@metempsy.com virtualIncrementEOICount(); 106113531Sjairo.balart@metempsy.com } else { 106213531Sjairo.balart@metempsy.com virtualDeactivateIRQ(lr_idx); 106313531Sjairo.balart@metempsy.com } 106413531Sjairo.balart@metempsy.com 106513531Sjairo.balart@metempsy.com virtualUpdate(); 106613531Sjairo.balart@metempsy.com break; 106713531Sjairo.balart@metempsy.com } 106813531Sjairo.balart@metempsy.com 106913531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0: 107013531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR0_EL1: // Binary Point Register 0 107113531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1: 107213531Sjairo.balart@metempsy.com case MISCREG_ICC_BPR1_EL1: { // Binary Point Register 1 107313531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState()) { 107413531Sjairo.balart@metempsy.com if (misc_reg == MISCREG_ICC_BPR0_EL1 && hcr_fmo) { 107513531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_BPR0_EL1, val); 107613531Sjairo.balart@metempsy.com } else if (misc_reg == MISCREG_ICC_BPR1_EL1 && hcr_imo) { 107713531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_BPR1_EL1, val); 107813531Sjairo.balart@metempsy.com } 107913531Sjairo.balart@metempsy.com } 108013531Sjairo.balart@metempsy.com 108113531Sjairo.balart@metempsy.com Gicv3::GroupId group = 108213531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S; 108313531Sjairo.balart@metempsy.com 108413531Sjairo.balart@metempsy.com if (group == Gicv3::G1S && !inSecureState()) { 108513531Sjairo.balart@metempsy.com group = Gicv3::G1NS; 108613531Sjairo.balart@metempsy.com } 108713531Sjairo.balart@metempsy.com 108813531Sjairo.balart@metempsy.com if ((group == Gicv3::G1S) && 108913531Sjairo.balart@metempsy.com !isEL3OrMon() && 109013531Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S) & 109113531Sjairo.balart@metempsy.com ICC_CTLR_EL1_CBPR)) { 109213531Sjairo.balart@metempsy.com group = Gicv3::G0S; 109313531Sjairo.balart@metempsy.com } 109413531Sjairo.balart@metempsy.com 109513531Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && 109613531Sjairo.balart@metempsy.com (currEL() < EL3) && 109713531Sjairo.balart@metempsy.com (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS) & 109813531Sjairo.balart@metempsy.com ICC_CTLR_EL1_CBPR)) { 109913531Sjairo.balart@metempsy.com // Reads return BPR0 + 1 saturated to 7, WI 110013531Sjairo.balart@metempsy.com return; 110113531Sjairo.balart@metempsy.com } 110213531Sjairo.balart@metempsy.com 110313531Sjairo.balart@metempsy.com uint8_t min_val = (group == Gicv3::G1NS) ? 110413531Sjairo.balart@metempsy.com GIC_MIN_BPR_NS : GIC_MIN_BPR; 110513531Sjairo.balart@metempsy.com val &= 0x7; 110613531Sjairo.balart@metempsy.com 110713531Sjairo.balart@metempsy.com if (val < min_val) { 110813531Sjairo.balart@metempsy.com val = min_val; 110913531Sjairo.balart@metempsy.com } 111013531Sjairo.balart@metempsy.com 111113531Sjairo.balart@metempsy.com break; 111213531Sjairo.balart@metempsy.com } 111313531Sjairo.balart@metempsy.com 111413531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR0_EL1: 111513531Sjairo.balart@metempsy.com case MISCREG_ICV_BPR1_EL1: { 111613531Sjairo.balart@metempsy.com Gicv3::GroupId group = 111713531Sjairo.balart@metempsy.com misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS; 111813531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 111913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 112013531Sjairo.balart@metempsy.com 112113531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) { 112213531Sjairo.balart@metempsy.com // reads return bpr0 + 1 saturated to 7, writes ignored 112313531Sjairo.balart@metempsy.com return; 112413531Sjairo.balart@metempsy.com } 112513531Sjairo.balart@metempsy.com 112613531Sjairo.balart@metempsy.com uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS; 112713531Sjairo.balart@metempsy.com 112813531Sjairo.balart@metempsy.com if (group != Gicv3::G0S) { 112913531Sjairo.balart@metempsy.com min_VPBR++; 113013531Sjairo.balart@metempsy.com } 113113531Sjairo.balart@metempsy.com 113213531Sjairo.balart@metempsy.com if (val < min_VPBR) { 113313531Sjairo.balart@metempsy.com val = min_VPBR; 113413531Sjairo.balart@metempsy.com } 113513531Sjairo.balart@metempsy.com 113613531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 113713531Sjairo.balart@metempsy.com ich_vmcr_el2 = insertBits(ich_vmcr_el2, 113813531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VBPR0_SHIFT + 2, ICH_VMCR_EL2_VBPR0_SHIFT, 113913531Sjairo.balart@metempsy.com val); 114013531Sjairo.balart@metempsy.com } else { 114113531Sjairo.balart@metempsy.com ich_vmcr_el2 = insertBits(ich_vmcr_el2, 114213531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VBPR1_SHIFT + 2, ICH_VMCR_EL2_VBPR1_SHIFT, 114313531Sjairo.balart@metempsy.com val); 114413531Sjairo.balart@metempsy.com } 114513531Sjairo.balart@metempsy.com 114613531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 114713531Sjairo.balart@metempsy.com do_virtual_update = true; 114813531Sjairo.balart@metempsy.com break; 114913531Sjairo.balart@metempsy.com } 115013531Sjairo.balart@metempsy.com 115113531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR: 115213531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL1: { // Control Register 115313531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 115413531Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 115513531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_CTLR_EL1, val); 115613531Sjairo.balart@metempsy.com } 115713531Sjairo.balart@metempsy.com 115813531Sjairo.balart@metempsy.com /* 115913531Sjairo.balart@metempsy.com * RSS is RO. 116013531Sjairo.balart@metempsy.com * A3V is RO. 116113531Sjairo.balart@metempsy.com * SEIS is RO. 116213531Sjairo.balart@metempsy.com * IDbits is RO. 116313531Sjairo.balart@metempsy.com * PRIbits is RO. 116413531Sjairo.balart@metempsy.com * If EL3 is implemented and GICD_CTLR.DS == 0, then PMHE is RO. 116513531Sjairo.balart@metempsy.com * So, only CBPR[0] and EOIMODE[1] are RW. 116613531Sjairo.balart@metempsy.com * If EL3 is implemented and GICD_CTLR.DS == 0, then CBPR is RO. 116713531Sjairo.balart@metempsy.com */ 116813531Sjairo.balart@metempsy.com uint64_t mask; 116913531Sjairo.balart@metempsy.com 117013531Sjairo.balart@metempsy.com if (haveEL(EL3) and distributor->DS == 0) { 117113531Sjairo.balart@metempsy.com mask = ICC_CTLR_EL1_EOIMODE; 117213531Sjairo.balart@metempsy.com } else if (haveEL(EL3) and distributor->DS == 1) { 117313531Sjairo.balart@metempsy.com mask = ICC_CTLR_EL1_PMHE | ICC_CTLR_EL1_CBPR | 117413531Sjairo.balart@metempsy.com ICC_CTLR_EL1_EOIMODE; 117513531Sjairo.balart@metempsy.com } else { 117613531Sjairo.balart@metempsy.com mask = ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE; 117713531Sjairo.balart@metempsy.com } 117813531Sjairo.balart@metempsy.com 117913531Sjairo.balart@metempsy.com ArmISA::MiscReg old_val = 118013531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1); 118113531Sjairo.balart@metempsy.com old_val &= ~mask; 118213531Sjairo.balart@metempsy.com val = old_val | (val & mask); 118313531Sjairo.balart@metempsy.com break; 118413531Sjairo.balart@metempsy.com } 118513531Sjairo.balart@metempsy.com 118613531Sjairo.balart@metempsy.com case MISCREG_ICV_CTLR_EL1: { 118713531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 118813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 118913531Sjairo.balart@metempsy.com ich_vmcr_el2 = insertBits(ich_vmcr_el2, ICH_VMCR_EL2_VCBPR_SHIFT, 119013531Sjairo.balart@metempsy.com val & ICC_CTLR_EL1_CBPR ? 1 : 0); 119113531Sjairo.balart@metempsy.com ich_vmcr_el2 = insertBits(ich_vmcr_el2, ICH_VMCR_EL2_VEOIM_SHIFT, 119213531Sjairo.balart@metempsy.com val & ICC_CTLR_EL1_EOIMODE ? 1 : 0); 119313531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 119413531Sjairo.balart@metempsy.com do_virtual_update = true; 119513531Sjairo.balart@metempsy.com break; 119613531Sjairo.balart@metempsy.com } 119713531Sjairo.balart@metempsy.com 119813531Sjairo.balart@metempsy.com case MISCREG_ICC_MCTLR: 119913531Sjairo.balart@metempsy.com case MISCREG_ICC_CTLR_EL3: { 120013531Sjairo.balart@metempsy.com ArmISA::MiscReg icc_ctlr_el1_s = 120113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S); 120213531Sjairo.balart@metempsy.com ArmISA::MiscReg icc_ctlr_el1_ns = 120313531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS); 120413531Sjairo.balart@metempsy.com 120513531Sjairo.balart@metempsy.com // ICC_CTLR_EL1(NS).EOImode is an alias of 120613531Sjairo.balart@metempsy.com // ICC_CTLR_EL3.EOImode_EL1NS 120713531Sjairo.balart@metempsy.com if (val & ICC_CTLR_EL3_EOIMODE_EL1NS) { 120813531Sjairo.balart@metempsy.com icc_ctlr_el1_ns |= ICC_CTLR_EL1_EOIMODE; 120913531Sjairo.balart@metempsy.com } else { 121013531Sjairo.balart@metempsy.com icc_ctlr_el1_ns &= ~ICC_CTLR_EL1_EOIMODE; 121113531Sjairo.balart@metempsy.com } 121213531Sjairo.balart@metempsy.com 121313531Sjairo.balart@metempsy.com // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS 121413531Sjairo.balart@metempsy.com if (val & ICC_CTLR_EL3_CBPR_EL1NS) { 121513531Sjairo.balart@metempsy.com icc_ctlr_el1_ns |= ICC_CTLR_EL1_CBPR; 121613531Sjairo.balart@metempsy.com } else { 121713531Sjairo.balart@metempsy.com icc_ctlr_el1_ns &= ~ICC_CTLR_EL1_CBPR; 121813531Sjairo.balart@metempsy.com } 121913531Sjairo.balart@metempsy.com 122013531Sjairo.balart@metempsy.com // ICC_CTLR_EL1(S).EOImode is an alias of ICC_CTLR_EL3.EOImode_EL1S 122113531Sjairo.balart@metempsy.com if (val & ICC_CTLR_EL3_EOIMODE_EL1S) { 122213531Sjairo.balart@metempsy.com icc_ctlr_el1_s |= ICC_CTLR_EL1_EOIMODE; 122313531Sjairo.balart@metempsy.com } else { 122413531Sjairo.balart@metempsy.com icc_ctlr_el1_s &= ~ICC_CTLR_EL1_EOIMODE; 122513531Sjairo.balart@metempsy.com } 122613531Sjairo.balart@metempsy.com 122713531Sjairo.balart@metempsy.com // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S 122813531Sjairo.balart@metempsy.com if (val & ICC_CTLR_EL3_CBPR_EL1S) { 122913531Sjairo.balart@metempsy.com icc_ctlr_el1_s |= ICC_CTLR_EL1_CBPR; 123013531Sjairo.balart@metempsy.com } else { 123113531Sjairo.balart@metempsy.com icc_ctlr_el1_s &= ~ICC_CTLR_EL1_CBPR; 123213531Sjairo.balart@metempsy.com } 123313531Sjairo.balart@metempsy.com 123413531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s); 123513531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS, icc_ctlr_el1_ns); 123613531Sjairo.balart@metempsy.com // Only ICC_CTLR_EL3_EOIMODE_EL3 is writable 123713531Sjairo.balart@metempsy.com ArmISA::MiscReg old_icc_ctlr_el3 = 123813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3); 123913531Sjairo.balart@metempsy.com old_icc_ctlr_el3 &= ~(ICC_CTLR_EL3_EOIMODE_EL3 | ICC_CTLR_EL3_RM); 124013531Sjairo.balart@metempsy.com val = old_icc_ctlr_el3 | 124113531Sjairo.balart@metempsy.com (val & (ICC_CTLR_EL3_EOIMODE_EL3 | ICC_CTLR_EL3_RM)); 124213531Sjairo.balart@metempsy.com break; 124313531Sjairo.balart@metempsy.com } 124413531Sjairo.balart@metempsy.com 124513531Sjairo.balart@metempsy.com case MISCREG_ICC_PMR: 124613531Sjairo.balart@metempsy.com case MISCREG_ICC_PMR_EL1: { // Priority Mask Register 124713531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && 124813531Sjairo.balart@metempsy.com (hcr_imo || hcr_fmo)) { 124913531Sjairo.balart@metempsy.com return isa->setMiscRegNoEffect(MISCREG_ICV_PMR_EL1, val); 125013531Sjairo.balart@metempsy.com } 125113531Sjairo.balart@metempsy.com 125213531Sjairo.balart@metempsy.com val &= 0xff; 125313531Sjairo.balart@metempsy.com SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 125413531Sjairo.balart@metempsy.com 125513531Sjairo.balart@metempsy.com if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) { 125613531Sjairo.balart@metempsy.com /* 125713531Sjairo.balart@metempsy.com * NS access and Group 0 is inaccessible to NS: return the 125813531Sjairo.balart@metempsy.com * NS view of the current priority 125913531Sjairo.balart@metempsy.com */ 126013531Sjairo.balart@metempsy.com ArmISA::MiscReg old_icc_pmr_el1 = 126113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1); 126213531Sjairo.balart@metempsy.com 126313531Sjairo.balart@metempsy.com if (!(old_icc_pmr_el1 & 0x80)) { 126413531Sjairo.balart@metempsy.com /* Current PMR in the secure range, don't allow NS to 126513531Sjairo.balart@metempsy.com * change it */ 126613531Sjairo.balart@metempsy.com return; 126713531Sjairo.balart@metempsy.com } 126813531Sjairo.balart@metempsy.com 126913531Sjairo.balart@metempsy.com val = (val >> 1) | 0x80; 127013531Sjairo.balart@metempsy.com } 127113531Sjairo.balart@metempsy.com 127213531Sjairo.balart@metempsy.com val &= ~0U << (8 - PRIORITY_BITS); 127313531Sjairo.balart@metempsy.com break; 127413531Sjairo.balart@metempsy.com } 127513531Sjairo.balart@metempsy.com 127613531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0: 127713531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN0_EL1: { // Interrupt Group 0 Enable Register 127813531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_fmo) { 127913531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val); 128013531Sjairo.balart@metempsy.com } 128113531Sjairo.balart@metempsy.com 128213531Sjairo.balart@metempsy.com break; 128313531Sjairo.balart@metempsy.com } 128413531Sjairo.balart@metempsy.com 128513531Sjairo.balart@metempsy.com case MISCREG_ICV_IGRPEN0_EL1: { 128613531Sjairo.balart@metempsy.com bool enable = val & 0x1; 128713531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 128813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 128913531Sjairo.balart@metempsy.com ich_vmcr_el2 = insertBits(ich_vmcr_el2, 129013531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VENG0_SHIFT, enable); 129113531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 129213531Sjairo.balart@metempsy.com virtualUpdate(); 129313531Sjairo.balart@metempsy.com return; 129413531Sjairo.balart@metempsy.com } 129513531Sjairo.balart@metempsy.com 129613531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1: 129713531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL1: { // Interrupt Group 1 Enable Register 129813531Sjairo.balart@metempsy.com if ((currEL() == EL1) && !inSecureState() && hcr_imo) { 129913531Sjairo.balart@metempsy.com return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val); 130013531Sjairo.balart@metempsy.com } 130113531Sjairo.balart@metempsy.com 130213531Sjairo.balart@metempsy.com break; 130313531Sjairo.balart@metempsy.com } 130413531Sjairo.balart@metempsy.com 130513531Sjairo.balart@metempsy.com case MISCREG_ICV_IGRPEN1_EL1: { 130613531Sjairo.balart@metempsy.com bool enable = val & 0x1; 130713531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 130813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 130913531Sjairo.balart@metempsy.com ich_vmcr_el2 = insertBits(ich_vmcr_el2, 131013531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VENG1_SHIFT, enable); 131113531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2); 131213531Sjairo.balart@metempsy.com virtualUpdate(); 131313531Sjairo.balart@metempsy.com return; 131413531Sjairo.balart@metempsy.com } 131513531Sjairo.balart@metempsy.com 131613531Sjairo.balart@metempsy.com case MISCREG_ICC_MGRPEN1: 131713531Sjairo.balart@metempsy.com case MISCREG_ICC_IGRPEN1_EL3: { 131813531Sjairo.balart@metempsy.com // EnableGrp1S and EnableGrp1NS are aliased with 131913531Sjairo.balart@metempsy.com // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable 132013531Sjairo.balart@metempsy.com bool enable_grp_1s = val & ICC_IGRPEN1_EL3_ENABLEGRP1S; 132113531Sjairo.balart@metempsy.com bool enable_grp_1ns = val & ICC_IGRPEN1_EL3_ENABLEGRP1NS; 132213531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S, enable_grp_1s); 132313531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS, enable_grp_1ns); 132413531Sjairo.balart@metempsy.com return; 132513531Sjairo.balart@metempsy.com } 132613531Sjairo.balart@metempsy.com 132713531Sjairo.balart@metempsy.com // Software Generated Interrupt Group 0 Register 132813531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI0R: 132913531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI0R_EL1: 133013531Sjairo.balart@metempsy.com 133113531Sjairo.balart@metempsy.com // Software Generated Interrupt Group 1 Register 133213531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI1R: 133313531Sjairo.balart@metempsy.com case MISCREG_ICC_SGI1R_EL1: 133413531Sjairo.balart@metempsy.com 133513531Sjairo.balart@metempsy.com // Alias Software Generated Interrupt Group 1 Register 133613531Sjairo.balart@metempsy.com case MISCREG_ICC_ASGI1R: 133713531Sjairo.balart@metempsy.com case MISCREG_ICC_ASGI1R_EL1: { 133813531Sjairo.balart@metempsy.com bool ns = !inSecureState(); 133913531Sjairo.balart@metempsy.com Gicv3::GroupId group; 134013531Sjairo.balart@metempsy.com 134113531Sjairo.balart@metempsy.com if (misc_reg == MISCREG_ICC_SGI1R_EL1) { 134213531Sjairo.balart@metempsy.com group = ns ? Gicv3::G1NS : Gicv3::G1S; 134313531Sjairo.balart@metempsy.com } else if (misc_reg == MISCREG_ICC_ASGI1R_EL1) { 134413531Sjairo.balart@metempsy.com group = ns ? Gicv3::G1S : Gicv3::G1NS; 134513531Sjairo.balart@metempsy.com } else { 134613531Sjairo.balart@metempsy.com group = Gicv3::G0S; 134713531Sjairo.balart@metempsy.com } 134813531Sjairo.balart@metempsy.com 134913531Sjairo.balart@metempsy.com if (distributor->DS && group == Gicv3::G1S) { 135013531Sjairo.balart@metempsy.com group = Gicv3::G0S; 135113531Sjairo.balart@metempsy.com } 135213531Sjairo.balart@metempsy.com 135313531Sjairo.balart@metempsy.com uint8_t aff3 = bits(val, 55, 48); 135413531Sjairo.balart@metempsy.com uint8_t aff2 = bits(val, 39, 32); 135513531Sjairo.balart@metempsy.com uint8_t aff1 = bits(val, 23, 16);; 135613531Sjairo.balart@metempsy.com uint16_t target_list = bits(val, 15, 0); 135713531Sjairo.balart@metempsy.com uint32_t int_id = bits(val, 27, 24); 135813531Sjairo.balart@metempsy.com bool irm = bits(val, 40, 40); 135913531Sjairo.balart@metempsy.com uint8_t rs = bits(val, 47, 44); 136013531Sjairo.balart@metempsy.com 136113531Sjairo.balart@metempsy.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 136213531Sjairo.balart@metempsy.com Gicv3Redistributor * redistributor_i = 136313531Sjairo.balart@metempsy.com gic->getRedistributor(i); 136413531Sjairo.balart@metempsy.com uint32_t affinity_i = redistributor_i->getAffinity(); 136513531Sjairo.balart@metempsy.com 136613531Sjairo.balart@metempsy.com if (irm) { 136713531Sjairo.balart@metempsy.com // Interrupts routed to all PEs in the system, 136813531Sjairo.balart@metempsy.com // excluding "self" 136913531Sjairo.balart@metempsy.com if (affinity_i == redistributor->getAffinity()) { 137013531Sjairo.balart@metempsy.com continue; 137113531Sjairo.balart@metempsy.com } 137213531Sjairo.balart@metempsy.com } else { 137313531Sjairo.balart@metempsy.com // Interrupts routed to the PEs specified by 137413531Sjairo.balart@metempsy.com // Aff3.Aff2.Aff1.<target list> 137513531Sjairo.balart@metempsy.com if ((affinity_i >> 8) != 137613531Sjairo.balart@metempsy.com ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) { 137713531Sjairo.balart@metempsy.com continue; 137813531Sjairo.balart@metempsy.com } 137913531Sjairo.balart@metempsy.com 138013531Sjairo.balart@metempsy.com uint8_t aff0_i = bits(affinity_i, 7, 0); 138113531Sjairo.balart@metempsy.com 138213531Sjairo.balart@metempsy.com if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 && 138313531Sjairo.balart@metempsy.com ((0x1 << (aff0_i - rs * 16)) & target_list))) { 138413531Sjairo.balart@metempsy.com continue; 138513531Sjairo.balart@metempsy.com } 138613531Sjairo.balart@metempsy.com } 138713531Sjairo.balart@metempsy.com 138813531Sjairo.balart@metempsy.com redistributor_i->sendSGI(int_id, group, ns); 138913531Sjairo.balart@metempsy.com } 139013531Sjairo.balart@metempsy.com 139113531Sjairo.balart@metempsy.com break; 139213531Sjairo.balart@metempsy.com } 139313531Sjairo.balart@metempsy.com 139413531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE: 139513531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL1: { // System Register Enable Register EL1 139613531Sjairo.balart@metempsy.com if (!(val & ICC_SRE_EL1_SRE)) { 139713531Sjairo.balart@metempsy.com warn("Gicv3CPUInterface::setMiscReg(): " 139813531Sjairo.balart@metempsy.com "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n"); 139913531Sjairo.balart@metempsy.com } 140013531Sjairo.balart@metempsy.com 140113531Sjairo.balart@metempsy.com bool dfb = val & ICC_SRE_EL1_DFB; 140213531Sjairo.balart@metempsy.com bool dib = val & ICC_SRE_EL1_DIB; 140313531Sjairo.balart@metempsy.com 140413531Sjairo.balart@metempsy.com if (haveEL(EL3) && !distributor->DS) { 140513531Sjairo.balart@metempsy.com // DIB is RO alias of ICC_SRE_EL3.DIB 140613531Sjairo.balart@metempsy.com // DFB is RO alias of ICC_SRE_EL3.DFB 140713531Sjairo.balart@metempsy.com } else if (haveEL(EL3) && distributor->DS) { 140813531Sjairo.balart@metempsy.com // DIB is RW alias of ICC_SRE_EL3.DIB 140913531Sjairo.balart@metempsy.com // DFB is RW alias of ICC_SRE_EL3.DFB 141013531Sjairo.balart@metempsy.com ArmISA::MiscReg icc_sre_el3 = 141113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3); 141213531Sjairo.balart@metempsy.com icc_sre_el3 = insertBits(icc_sre_el3, ICC_SRE_EL3_DFB, dfb); 141313531Sjairo.balart@metempsy.com icc_sre_el3 = insertBits(icc_sre_el3, ICC_SRE_EL3_DIB, dib); 141413531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICC_SRE_EL3, icc_sre_el3); 141513531Sjairo.balart@metempsy.com } else if ((!haveEL(EL3) || distributor->DS) and haveEL(EL2)) { 141613531Sjairo.balart@metempsy.com // DIB is RO alias of ICC_SRE_EL2.DIB 141713531Sjairo.balart@metempsy.com // DFB is RO alias of ICC_SRE_EL2.DFB 141813531Sjairo.balart@metempsy.com } else { 141913531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(misc_reg, val); 142013531Sjairo.balart@metempsy.com } 142113531Sjairo.balart@metempsy.com 142213531Sjairo.balart@metempsy.com return; 142313531Sjairo.balart@metempsy.com } 142413531Sjairo.balart@metempsy.com 142513531Sjairo.balart@metempsy.com case MISCREG_ICC_HSRE: 142613531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL2: // System Register Enable Register EL2 142713531Sjairo.balart@metempsy.com case MISCREG_ICC_MSRE: 142813531Sjairo.balart@metempsy.com case MISCREG_ICC_SRE_EL3: // System Register Enable Register EL3 142913531Sjairo.balart@metempsy.com if (!(val & (1 << 0))) { 143013531Sjairo.balart@metempsy.com warn("Gicv3CPUInterface::setMiscReg(): " 143113531Sjairo.balart@metempsy.com "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n"); 143213531Sjairo.balart@metempsy.com } 143313531Sjairo.balart@metempsy.com 143413531Sjairo.balart@metempsy.com // All bits are RAO/WI 143513531Sjairo.balart@metempsy.com break; 143613531Sjairo.balart@metempsy.com 143713531Sjairo.balart@metempsy.com case MISCREG_ICH_HCR: 143813531Sjairo.balart@metempsy.com case MISCREG_ICH_HCR_EL2: 143913531Sjairo.balart@metempsy.com val &= ICH_HCR_EL2_EN | ICH_HCR_EL2_UIE | ICH_HCR_EL2_LRENPIE | 144013531Sjairo.balart@metempsy.com ICH_HCR_EL2_NPIE | ICH_HCR_EL2_VGRP0EIE | 144113531Sjairo.balart@metempsy.com ICH_HCR_EL2_VGRP0DIE | ICH_HCR_EL2_VGRP1EIE | 144213531Sjairo.balart@metempsy.com ICH_HCR_EL2_VGRP1DIE | ICH_HCR_EL2_TC | ICH_HCR_EL2_TALL0 | 144313531Sjairo.balart@metempsy.com ICH_HCR_EL2_TALL1 | ICH_HCR_EL2_TDIR | 144413531Sjairo.balart@metempsy.com ICH_HCR_EL2_EOICOUNT_MASK; 144513531Sjairo.balart@metempsy.com do_virtual_update = true; 144613531Sjairo.balart@metempsy.com break; 144713531Sjairo.balart@metempsy.com 144813531Sjairo.balart@metempsy.com case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: 144913531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part) 145013531Sjairo.balart@metempsy.com { 145113531Sjairo.balart@metempsy.com // Enforce RES0 bits in priority field, 5 of 8 bits used 145213531Sjairo.balart@metempsy.com val = insertBits(val, ICH_LRC_PRIORITY_SHIFT + 2, 145313531Sjairo.balart@metempsy.com ICH_LRC_PRIORITY_SHIFT, 0); 145413531Sjairo.balart@metempsy.com ArmISA::MiscReg old_val = isa->readMiscRegNoEffect(misc_reg); 145513531Sjairo.balart@metempsy.com val = (old_val & 0xffffffff) | (val << 32); 145613531Sjairo.balart@metempsy.com do_virtual_update = true; 145713531Sjairo.balart@metempsy.com break; 145813531Sjairo.balart@metempsy.com } 145913531Sjairo.balart@metempsy.com 146013531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: { 146113531Sjairo.balart@metempsy.com // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part) 146213531Sjairo.balart@metempsy.com ArmISA::MiscReg old_val = isa->readMiscRegNoEffect(misc_reg); 146313531Sjairo.balart@metempsy.com val = (old_val & 0xffffffff00000000) | (val & 0xffffffff); 146413531Sjairo.balart@metempsy.com do_virtual_update = true; 146513531Sjairo.balart@metempsy.com break; 146613531Sjairo.balart@metempsy.com } 146713531Sjairo.balart@metempsy.com 146813531Sjairo.balart@metempsy.com case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64 146913531Sjairo.balart@metempsy.com // Enforce RES0 bits in priority field, 5 of 8 bits used 147013531Sjairo.balart@metempsy.com val = insertBits(val, ICH_LR_EL2_PRIORITY_SHIFT + 2, 147113531Sjairo.balart@metempsy.com ICH_LR_EL2_PRIORITY_SHIFT, 0); 147213531Sjairo.balart@metempsy.com do_virtual_update = true; 147313531Sjairo.balart@metempsy.com break; 147413531Sjairo.balart@metempsy.com } 147513531Sjairo.balart@metempsy.com 147613531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR: 147713531Sjairo.balart@metempsy.com case MISCREG_ICH_VMCR_EL2: { 147813531Sjairo.balart@metempsy.com val &= ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1 | 147913531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VCBPR | ICH_VMCR_EL2_VEOIM | 148013531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VBPR1_MASK | ICH_VMCR_EL2_VBPR0_MASK | 148113531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VPMR_MASK; 148213531Sjairo.balart@metempsy.com val |= ICH_VMCR_EL2_VFIQEN; // RES1 148313531Sjairo.balart@metempsy.com // Check VBPRs against minimun allowed value 148413531Sjairo.balart@metempsy.com uint8_t vbpr0 = bits(val, 23, 21); 148513531Sjairo.balart@metempsy.com uint8_t vbpr1 = bits(val, 20, 18); 148613531Sjairo.balart@metempsy.com uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS; 148713531Sjairo.balart@metempsy.com uint8_t min_vpr1 = min_vpr0 + 1; 148813531Sjairo.balart@metempsy.com vbpr0 = vbpr0 < min_vpr0 ? min_vpr0 : vbpr0; 148913531Sjairo.balart@metempsy.com vbpr1 = vbpr1 < min_vpr1 ? min_vpr1 : vbpr1; 149013531Sjairo.balart@metempsy.com val = insertBits(val, ICH_VMCR_EL2_VBPR0_SHIFT + 2, 149113531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VBPR0_SHIFT, vbpr0); 149213531Sjairo.balart@metempsy.com val = insertBits(val, ICH_VMCR_EL2_VBPR1_SHIFT + 2, 149313531Sjairo.balart@metempsy.com ICH_VMCR_EL2_VBPR1_SHIFT, vbpr1); 149413531Sjairo.balart@metempsy.com break; 149513531Sjairo.balart@metempsy.com } 149613531Sjairo.balart@metempsy.com 149713531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0 ... MISCREG_ICH_AP0R3: 149813531Sjairo.balart@metempsy.com case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_AP0R3_EL2: 149913531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0 ... MISCREG_ICH_AP1R3: 150013531Sjairo.balart@metempsy.com case MISCREG_ICH_AP1R0_EL2 ... MISCREG_ICH_AP1R3_EL2: 150113531Sjairo.balart@metempsy.com break; 150213531Sjairo.balart@metempsy.com 150313531Sjairo.balart@metempsy.com default: 150413531Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::setMiscReg(): " 150513531Sjairo.balart@metempsy.com "unknown register %d (%s)", 150613531Sjairo.balart@metempsy.com misc_reg, miscRegName[misc_reg]); 150713531Sjairo.balart@metempsy.com } 150813531Sjairo.balart@metempsy.com 150913531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(misc_reg, val); 151013531Sjairo.balart@metempsy.com 151113531Sjairo.balart@metempsy.com if (do_virtual_update) { 151213531Sjairo.balart@metempsy.com virtualUpdate(); 151313531Sjairo.balart@metempsy.com } 151413531Sjairo.balart@metempsy.com} 151513531Sjairo.balart@metempsy.com 151613531Sjairo.balart@metempsy.comint 151713531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualFindActive(uint32_t int_id) 151813531Sjairo.balart@metempsy.com{ 151913531Sjairo.balart@metempsy.com for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 152013531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 152113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 152213531Sjairo.balart@metempsy.com uint32_t lr_intid = bits(lr, 31, 0); 152313531Sjairo.balart@metempsy.com 152413531Sjairo.balart@metempsy.com if ((lr & ICH_LR_EL2_STATE_ACTIVE_BIT) && lr_intid == int_id) { 152513531Sjairo.balart@metempsy.com return lr_idx; 152613531Sjairo.balart@metempsy.com } 152713531Sjairo.balart@metempsy.com } 152813531Sjairo.balart@metempsy.com 152913531Sjairo.balart@metempsy.com return -1; 153013531Sjairo.balart@metempsy.com} 153113531Sjairo.balart@metempsy.com 153213531Sjairo.balart@metempsy.comuint32_t 153313531Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR0() 153413531Sjairo.balart@metempsy.com{ 153513531Sjairo.balart@metempsy.com if (hppi.prio == 0xff) { 153613531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 153713531Sjairo.balart@metempsy.com } 153813531Sjairo.balart@metempsy.com 153913531Sjairo.balart@metempsy.com bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS; 154013531Sjairo.balart@metempsy.com 154113531Sjairo.balart@metempsy.com if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) { 154213531Sjairo.balart@metempsy.com /* Indicate to EL3 that there's a Group 1 interrupt for the 154313531Sjairo.balart@metempsy.com * other state pending. 154413531Sjairo.balart@metempsy.com */ 154513531Sjairo.balart@metempsy.com return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE; 154613531Sjairo.balart@metempsy.com } 154713531Sjairo.balart@metempsy.com 154813531Sjairo.balart@metempsy.com if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon()) 154913531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 155013531Sjairo.balart@metempsy.com } 155113531Sjairo.balart@metempsy.com 155213531Sjairo.balart@metempsy.com if (irq_is_secure && !inSecureState()) { 155313531Sjairo.balart@metempsy.com // Secure interrupts not visible in Non-secure 155413531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 155513531Sjairo.balart@metempsy.com } 155613531Sjairo.balart@metempsy.com 155713531Sjairo.balart@metempsy.com return hppi.intid; 155813531Sjairo.balart@metempsy.com} 155913531Sjairo.balart@metempsy.com 156013531Sjairo.balart@metempsy.comuint32_t 156113531Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPIR1() 156213531Sjairo.balart@metempsy.com{ 156313531Sjairo.balart@metempsy.com if (hppi.prio == 0xff) { 156413531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 156513531Sjairo.balart@metempsy.com } 156613531Sjairo.balart@metempsy.com 156713531Sjairo.balart@metempsy.com //if ((currEL() == EL3) && ICC_CTLR_EL3_RM) 156813531Sjairo.balart@metempsy.com if ((currEL() == EL3) && 156913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3) & ICC_CTLR_EL3_RM) { 157013531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G0S) { 157113531Sjairo.balart@metempsy.com return Gicv3::INTID_SECURE; 157213531Sjairo.balart@metempsy.com } else if (hppi.group == Gicv3::G1NS) { 157313531Sjairo.balart@metempsy.com return Gicv3::INTID_NONSECURE; 157413531Sjairo.balart@metempsy.com } 157513531Sjairo.balart@metempsy.com } 157613531Sjairo.balart@metempsy.com 157713531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G0S) { 157813531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 157913531Sjairo.balart@metempsy.com } 158013531Sjairo.balart@metempsy.com 158113531Sjairo.balart@metempsy.com bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS); 158213531Sjairo.balart@metempsy.com 158313531Sjairo.balart@metempsy.com if (irq_is_secure) { 158413531Sjairo.balart@metempsy.com if (!inSecureState()) { 158513531Sjairo.balart@metempsy.com // Secure interrupts not visible in Non-secure 158613531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 158713531Sjairo.balart@metempsy.com } 158813531Sjairo.balart@metempsy.com } else if (!isEL3OrMon() && inSecureState()) { 158913531Sjairo.balart@metempsy.com // Group 1 non-secure interrupts not visible in Secure EL1 159013531Sjairo.balart@metempsy.com return Gicv3::INTID_SPURIOUS; 159113531Sjairo.balart@metempsy.com } 159213531Sjairo.balart@metempsy.com 159313531Sjairo.balart@metempsy.com return hppi.intid; 159413531Sjairo.balart@metempsy.com} 159513531Sjairo.balart@metempsy.com 159613531Sjairo.balart@metempsy.comvoid 159713531Sjairo.balart@metempsy.comGicv3CPUInterface::dropPriority(Gicv3::GroupId group) 159813531Sjairo.balart@metempsy.com{ 159913531Sjairo.balart@metempsy.com int apr_misc_reg; 160013531Sjairo.balart@metempsy.com ArmISA::MiscReg apr; 160113531Sjairo.balart@metempsy.com apr_misc_reg = group == Gicv3::G0S ? 160213531Sjairo.balart@metempsy.com MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1; 160313531Sjairo.balart@metempsy.com apr = isa->readMiscRegNoEffect(apr_misc_reg); 160413531Sjairo.balart@metempsy.com 160513531Sjairo.balart@metempsy.com if (apr) { 160613531Sjairo.balart@metempsy.com /* Clear the lowest set bit */ 160713531Sjairo.balart@metempsy.com apr &= apr - 1; 160813531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_misc_reg, apr); 160913531Sjairo.balart@metempsy.com } 161013531Sjairo.balart@metempsy.com 161113531Sjairo.balart@metempsy.com update(); 161213531Sjairo.balart@metempsy.com} 161313531Sjairo.balart@metempsy.com 161413531Sjairo.balart@metempsy.comuint8_t 161513531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDropPriority() 161613531Sjairo.balart@metempsy.com{ 161713531Sjairo.balart@metempsy.com /* Drop the priority of the currently active virtual interrupt 161813531Sjairo.balart@metempsy.com * (favouring group 0 if there is a set active bit at 161913531Sjairo.balart@metempsy.com * the same priority for both group 0 and group 1). 162013531Sjairo.balart@metempsy.com * Return the priority value for the bit we just cleared, 162113531Sjairo.balart@metempsy.com * or 0xff if no bits were set in the AP registers at all. 162213531Sjairo.balart@metempsy.com * Note that though the ich_apr[] are uint64_t only the low 162313531Sjairo.balart@metempsy.com * 32 bits are actually relevant. 162413531Sjairo.balart@metempsy.com */ 162513531Sjairo.balart@metempsy.com int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5); 162613531Sjairo.balart@metempsy.com 162713531Sjairo.balart@metempsy.com for (int i = 0; i < apr_max; i++) { 162813531Sjairo.balart@metempsy.com ArmISA::MiscReg vapr0 = 162913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i); 163013531Sjairo.balart@metempsy.com ArmISA::MiscReg vapr1 = 163113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i); 163213531Sjairo.balart@metempsy.com 163313531Sjairo.balart@metempsy.com if (!vapr0 && !vapr1) { 163413531Sjairo.balart@metempsy.com continue; 163513531Sjairo.balart@metempsy.com } 163613531Sjairo.balart@metempsy.com 163713531Sjairo.balart@metempsy.com int vapr0_count = ctz32(vapr0); 163813531Sjairo.balart@metempsy.com int vapr1_count = ctz32(vapr1); 163913531Sjairo.balart@metempsy.com 164013531Sjairo.balart@metempsy.com if (vapr0_count <= vapr1_count) { 164113531Sjairo.balart@metempsy.com /* Clear the lowest set bit */ 164213531Sjairo.balart@metempsy.com vapr0 &= vapr0 - 1; 164313531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0); 164413531Sjairo.balart@metempsy.com return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1); 164513531Sjairo.balart@metempsy.com } else { 164613531Sjairo.balart@metempsy.com /* Clear the lowest set bit */ 164713531Sjairo.balart@metempsy.com vapr1 &= vapr1 - 1; 164813531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1); 164913531Sjairo.balart@metempsy.com return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1); 165013531Sjairo.balart@metempsy.com } 165113531Sjairo.balart@metempsy.com } 165213531Sjairo.balart@metempsy.com 165313531Sjairo.balart@metempsy.com return 0xff; 165413531Sjairo.balart@metempsy.com} 165513531Sjairo.balart@metempsy.com 165613531Sjairo.balart@metempsy.comvoid 165713531Sjairo.balart@metempsy.comGicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group) 165813531Sjairo.balart@metempsy.com{ 165913531Sjairo.balart@metempsy.com // Update active priority registers. 166013531Sjairo.balart@metempsy.com uint32_t prio = hppi.prio & 0xf8; 166113531Sjairo.balart@metempsy.com int apr_bit = prio >> (8 - PRIORITY_BITS); 166213531Sjairo.balart@metempsy.com int reg_bit = apr_bit % 32; 166313531Sjairo.balart@metempsy.com int apr_idx = group == Gicv3::G0S ? 166413531Sjairo.balart@metempsy.com MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1; 166513531Sjairo.balart@metempsy.com ArmISA::MiscReg apr = isa->readMiscRegNoEffect(apr_idx); 166613531Sjairo.balart@metempsy.com apr |= (1 << reg_bit); 166713531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_idx, apr); 166813531Sjairo.balart@metempsy.com 166913531Sjairo.balart@metempsy.com // Move interrupt state from pending to active. 167013531Sjairo.balart@metempsy.com if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) { 167113531Sjairo.balart@metempsy.com // SGI or PPI, redistributor 167213531Sjairo.balart@metempsy.com redistributor->activateIRQ(int_id); 167313531Sjairo.balart@metempsy.com redistributor->updateAndInformCPUInterface(); 167413531Sjairo.balart@metempsy.com } else if (int_id < Gicv3::INTID_SECURE) { 167513531Sjairo.balart@metempsy.com // SPI, distributor 167613531Sjairo.balart@metempsy.com distributor->activateIRQ(int_id); 167713531Sjairo.balart@metempsy.com distributor->updateAndInformCPUInterfaces(); 167813531Sjairo.balart@metempsy.com } 167913531Sjairo.balart@metempsy.com} 168013531Sjairo.balart@metempsy.com 168113531Sjairo.balart@metempsy.comvoid 168213531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx) 168313531Sjairo.balart@metempsy.com{ 168413531Sjairo.balart@metempsy.com // Update active priority registers. 168513531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + 168613531Sjairo.balart@metempsy.com lr_idx); 168713531Sjairo.balart@metempsy.com Gicv3::GroupId group = lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S; 168813531Sjairo.balart@metempsy.com uint8_t prio = bits(lr, 55, 48) & 0xf8; 168913531Sjairo.balart@metempsy.com int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS); 169013531Sjairo.balart@metempsy.com int reg_no = apr_bit / 32; 169113531Sjairo.balart@metempsy.com int reg_bit = apr_bit % 32; 169213531Sjairo.balart@metempsy.com int apr_idx = group == Gicv3::G0S ? 169313531Sjairo.balart@metempsy.com MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no; 169413531Sjairo.balart@metempsy.com ArmISA::MiscReg apr = isa->readMiscRegNoEffect(apr_idx); 169513531Sjairo.balart@metempsy.com apr |= (1 << reg_bit); 169613531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(apr_idx, apr); 169713531Sjairo.balart@metempsy.com // Move interrupt state from pending to active. 169813531Sjairo.balart@metempsy.com lr &= ~ICH_LR_EL2_STATE_PENDING_BIT; 169913531Sjairo.balart@metempsy.com lr |= ICH_LR_EL2_STATE_ACTIVE_BIT; 170013531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, lr); 170113531Sjairo.balart@metempsy.com} 170213531Sjairo.balart@metempsy.com 170313531Sjairo.balart@metempsy.comvoid 170413531Sjairo.balart@metempsy.comGicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group) 170513531Sjairo.balart@metempsy.com{ 170613531Sjairo.balart@metempsy.com if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) { 170713531Sjairo.balart@metempsy.com // SGI or PPI, redistributor 170813531Sjairo.balart@metempsy.com redistributor->deactivateIRQ(int_id); 170913531Sjairo.balart@metempsy.com redistributor->updateAndInformCPUInterface(); 171013531Sjairo.balart@metempsy.com } else if (int_id < Gicv3::INTID_SECURE) { 171113531Sjairo.balart@metempsy.com // SPI, distributor 171213531Sjairo.balart@metempsy.com distributor->deactivateIRQ(int_id); 171313531Sjairo.balart@metempsy.com distributor->updateAndInformCPUInterfaces(); 171413531Sjairo.balart@metempsy.com } else { 171513531Sjairo.balart@metempsy.com return; 171613531Sjairo.balart@metempsy.com } 171713531Sjairo.balart@metempsy.com} 171813531Sjairo.balart@metempsy.com 171913531Sjairo.balart@metempsy.comvoid 172013531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualDeactivateIRQ(int lr_idx) 172113531Sjairo.balart@metempsy.com{ 172213531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + 172313531Sjairo.balart@metempsy.com lr_idx); 172413531Sjairo.balart@metempsy.com 172513531Sjairo.balart@metempsy.com if (lr & ICH_LR_EL2_HW) { 172613531Sjairo.balart@metempsy.com // Deactivate the associated physical interrupt 172713531Sjairo.balart@metempsy.com int pintid = bits(lr, 41, 32); 172813531Sjairo.balart@metempsy.com 172913531Sjairo.balart@metempsy.com if (pintid < Gicv3::INTID_SECURE) { 173013531Sjairo.balart@metempsy.com Gicv3::GroupId group = 173113531Sjairo.balart@metempsy.com pintid >= 32 ? distributor->getIntGroup(pintid) : 173213531Sjairo.balart@metempsy.com redistributor->getIntGroup(pintid); 173313531Sjairo.balart@metempsy.com deactivateIRQ(pintid, group); 173413531Sjairo.balart@metempsy.com } 173513531Sjairo.balart@metempsy.com } 173613531Sjairo.balart@metempsy.com 173713531Sjairo.balart@metempsy.com // Remove the active bit 173813531Sjairo.balart@metempsy.com lr &= ~ICH_LR_EL2_STATE_ACTIVE_BIT; 173913531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, lr); 174013531Sjairo.balart@metempsy.com} 174113531Sjairo.balart@metempsy.com 174213531Sjairo.balart@metempsy.com/* 174313531Sjairo.balart@metempsy.com * Return a mask word which clears the subpriority bits from 174413531Sjairo.balart@metempsy.com * a priority value for an interrupt in the specified group. 174513531Sjairo.balart@metempsy.com * This depends on the BPR value. For CBPR0 (S or NS): 174613531Sjairo.balart@metempsy.com * a BPR of 0 means the group priority bits are [7:1]; 174713531Sjairo.balart@metempsy.com * a BPR of 1 means they are [7:2], and so on down to 174813531Sjairo.balart@metempsy.com * ... 174913531Sjairo.balart@metempsy.com * a BPR of 7 meaning no group priority bits at all. 175013531Sjairo.balart@metempsy.com * For CBPR1 NS: 175113531Sjairo.balart@metempsy.com * a BPR of 0 is impossible (the minimum value is 1) 175213531Sjairo.balart@metempsy.com * a BPR of 1 means the group priority bits are [7:1]; 175313531Sjairo.balart@metempsy.com * a BPR of 2 means they are [7:2], and so on down to 175413531Sjairo.balart@metempsy.com * ... 175513531Sjairo.balart@metempsy.com * a BPR of 7 meaning the group priority is [7]. 175613531Sjairo.balart@metempsy.com * 175713531Sjairo.balart@metempsy.com * Which BPR to use depends on the group of the interrupt and 175813531Sjairo.balart@metempsy.com * the current ICC_CTLR.CBPR settings. 175913531Sjairo.balart@metempsy.com * 176013531Sjairo.balart@metempsy.com * This corresponds to the GroupBits() pseudocode from 4.8.2. 176113531Sjairo.balart@metempsy.com */ 176213531Sjairo.balart@metempsy.comuint32_t 176313531Sjairo.balart@metempsy.comGicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group) 176413531Sjairo.balart@metempsy.com{ 176513531Sjairo.balart@metempsy.com if ((group == Gicv3::G1S && 176613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S) 176713531Sjairo.balart@metempsy.com & ICC_CTLR_EL1_CBPR) || 176813531Sjairo.balart@metempsy.com (group == Gicv3::G1NS && 176913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS) 177013531Sjairo.balart@metempsy.com & ICC_CTLR_EL1_CBPR)) { 177113531Sjairo.balart@metempsy.com group = Gicv3::G0S; 177213531Sjairo.balart@metempsy.com } 177313531Sjairo.balart@metempsy.com 177413531Sjairo.balart@metempsy.com int bpr; 177513531Sjairo.balart@metempsy.com 177613531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 177713531Sjairo.balart@metempsy.com bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1) & 0x7; 177813531Sjairo.balart@metempsy.com } else { 177913531Sjairo.balart@metempsy.com bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1) & 0x7; 178013531Sjairo.balart@metempsy.com } 178113531Sjairo.balart@metempsy.com 178213531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 178313531Sjairo.balart@metempsy.com assert(bpr > 0); 178413531Sjairo.balart@metempsy.com bpr--; 178513531Sjairo.balart@metempsy.com } 178613531Sjairo.balart@metempsy.com 178713531Sjairo.balart@metempsy.com return ~0U << (bpr + 1); 178813531Sjairo.balart@metempsy.com} 178913531Sjairo.balart@metempsy.com 179013531Sjairo.balart@metempsy.comuint32_t 179113531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) 179213531Sjairo.balart@metempsy.com{ 179313531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 179413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 179513531Sjairo.balart@metempsy.com 179613531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) { 179713531Sjairo.balart@metempsy.com group = Gicv3::G0S; 179813531Sjairo.balart@metempsy.com } 179913531Sjairo.balart@metempsy.com 180013531Sjairo.balart@metempsy.com int bpr; 180113531Sjairo.balart@metempsy.com 180213531Sjairo.balart@metempsy.com if (group == Gicv3::G0S) { 180313531Sjairo.balart@metempsy.com bpr = bits(ich_vmcr_el2, 23, 21); 180413531Sjairo.balart@metempsy.com } else { 180513531Sjairo.balart@metempsy.com bpr = bits(ich_vmcr_el2, 20, 18); 180613531Sjairo.balart@metempsy.com } 180713531Sjairo.balart@metempsy.com 180813531Sjairo.balart@metempsy.com if (group == Gicv3::G1NS) { 180913531Sjairo.balart@metempsy.com assert(bpr > 0); 181013531Sjairo.balart@metempsy.com bpr--; 181113531Sjairo.balart@metempsy.com } 181213531Sjairo.balart@metempsy.com 181313531Sjairo.balart@metempsy.com return ~0U << (bpr + 1); 181413531Sjairo.balart@metempsy.com} 181513531Sjairo.balart@metempsy.com 181613531Sjairo.balart@metempsy.combool 181713531Sjairo.balart@metempsy.comGicv3CPUInterface::isEOISplitMode() 181813531Sjairo.balart@metempsy.com{ 181913531Sjairo.balart@metempsy.com if (isEL3OrMon()) { 182013531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3) & 182113531Sjairo.balart@metempsy.com ICC_CTLR_EL3_EOIMODE_EL3; 182213531Sjairo.balart@metempsy.com } else { 182313531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1) & 182413531Sjairo.balart@metempsy.com ICC_CTLR_EL1_EOIMODE; 182513531Sjairo.balart@metempsy.com } 182613531Sjairo.balart@metempsy.com} 182713531Sjairo.balart@metempsy.com 182813531Sjairo.balart@metempsy.combool 182913531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIsEOISplitMode() 183013531Sjairo.balart@metempsy.com{ 183113531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 183213531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 183313531Sjairo.balart@metempsy.com return ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM; 183413531Sjairo.balart@metempsy.com} 183513531Sjairo.balart@metempsy.com 183613531Sjairo.balart@metempsy.comint 183713531Sjairo.balart@metempsy.comGicv3CPUInterface::highestActiveGroup() 183813531Sjairo.balart@metempsy.com{ 183913531Sjairo.balart@metempsy.com int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1)); 184013531Sjairo.balart@metempsy.com int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S)); 184113531Sjairo.balart@metempsy.com int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS)); 184213531Sjairo.balart@metempsy.com 184313531Sjairo.balart@metempsy.com if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) { 184413531Sjairo.balart@metempsy.com return Gicv3::G1NS; 184513531Sjairo.balart@metempsy.com } 184613531Sjairo.balart@metempsy.com 184713531Sjairo.balart@metempsy.com if (gq_ctz < g0_ctz) { 184813531Sjairo.balart@metempsy.com return Gicv3::G1S; 184913531Sjairo.balart@metempsy.com } 185013531Sjairo.balart@metempsy.com 185113531Sjairo.balart@metempsy.com if (g0_ctz < 32) { 185213531Sjairo.balart@metempsy.com return Gicv3::G0S; 185313531Sjairo.balart@metempsy.com } 185413531Sjairo.balart@metempsy.com 185513531Sjairo.balart@metempsy.com return -1; 185613531Sjairo.balart@metempsy.com} 185713531Sjairo.balart@metempsy.com 185813531Sjairo.balart@metempsy.comvoid 185913531Sjairo.balart@metempsy.comGicv3CPUInterface::update() 186013531Sjairo.balart@metempsy.com{ 186113531Sjairo.balart@metempsy.com bool signal_IRQ = false; 186213531Sjairo.balart@metempsy.com bool signal_FIQ = false; 186313531Sjairo.balart@metempsy.com 186413531Sjairo.balart@metempsy.com if (hppi.group == Gicv3::G1S && !haveEL(EL3)) { 186513531Sjairo.balart@metempsy.com /* 186613531Sjairo.balart@metempsy.com * Secure enabled GIC sending a G1S IRQ to a secure disabled 186713531Sjairo.balart@metempsy.com * CPU -> send G0 IRQ 186813531Sjairo.balart@metempsy.com */ 186913531Sjairo.balart@metempsy.com hppi.group = Gicv3::G0S; 187013531Sjairo.balart@metempsy.com } 187113531Sjairo.balart@metempsy.com 187213531Sjairo.balart@metempsy.com if (hppiCanPreempt()) { 187313531Sjairo.balart@metempsy.com ArmISA::InterruptTypes int_type = intSignalType(hppi.group); 187413531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::update(): " 187513531Sjairo.balart@metempsy.com "posting int as %d!\n", int_type); 187613531Sjairo.balart@metempsy.com int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true; 187713531Sjairo.balart@metempsy.com } 187813531Sjairo.balart@metempsy.com 187913531Sjairo.balart@metempsy.com if (signal_IRQ) { 188013531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_IRQ); 188113531Sjairo.balart@metempsy.com } else { 188213531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_IRQ); 188313531Sjairo.balart@metempsy.com } 188413531Sjairo.balart@metempsy.com 188513531Sjairo.balart@metempsy.com if (signal_FIQ) { 188613531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_FIQ); 188713531Sjairo.balart@metempsy.com } else { 188813531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_FIQ); 188913531Sjairo.balart@metempsy.com } 189013531Sjairo.balart@metempsy.com} 189113531Sjairo.balart@metempsy.com 189213531Sjairo.balart@metempsy.comvoid 189313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualUpdate() 189413531Sjairo.balart@metempsy.com{ 189513531Sjairo.balart@metempsy.com bool signal_IRQ = false; 189613531Sjairo.balart@metempsy.com bool signal_FIQ = false; 189713531Sjairo.balart@metempsy.com int lr_idx = getHPPVILR(); 189813531Sjairo.balart@metempsy.com 189913531Sjairo.balart@metempsy.com if (lr_idx >= 0) { 190013531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_lr_el2 = 190113531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 190213531Sjairo.balart@metempsy.com 190313531Sjairo.balart@metempsy.com if (hppviCanPreempt(lr_idx)) { 190413531Sjairo.balart@metempsy.com if (ich_lr_el2 & ICH_LR_EL2_GROUP) { 190513531Sjairo.balart@metempsy.com signal_IRQ = true; 190613531Sjairo.balart@metempsy.com } else { 190713531Sjairo.balart@metempsy.com signal_FIQ = true; 190813531Sjairo.balart@metempsy.com } 190913531Sjairo.balart@metempsy.com } 191013531Sjairo.balart@metempsy.com } 191113531Sjairo.balart@metempsy.com 191213531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_hcr_el2 = 191313531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 191413531Sjairo.balart@metempsy.com 191513531Sjairo.balart@metempsy.com if (ich_hcr_el2 & ICH_HCR_EL2_EN) { 191613531Sjairo.balart@metempsy.com if (maintenanceInterruptStatus()) { 191713531Sjairo.balart@metempsy.com redistributor->sendPPInt(25); 191813531Sjairo.balart@metempsy.com } 191913531Sjairo.balart@metempsy.com } 192013531Sjairo.balart@metempsy.com 192113531Sjairo.balart@metempsy.com if (signal_IRQ) { 192213531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): " 192313531Sjairo.balart@metempsy.com "posting int as %d!\n", ArmISA::INT_VIRT_IRQ); 192413531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ); 192513531Sjairo.balart@metempsy.com } else { 192613531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ); 192713531Sjairo.balart@metempsy.com } 192813531Sjairo.balart@metempsy.com 192913531Sjairo.balart@metempsy.com if (signal_FIQ) { 193013531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): " 193113531Sjairo.balart@metempsy.com "posting int as %d!\n", ArmISA::INT_VIRT_FIQ); 193213531Sjairo.balart@metempsy.com gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ); 193313531Sjairo.balart@metempsy.com } else { 193413531Sjairo.balart@metempsy.com gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ); 193513531Sjairo.balart@metempsy.com } 193613531Sjairo.balart@metempsy.com} 193713531Sjairo.balart@metempsy.com 193813531Sjairo.balart@metempsy.com// Returns the intex of the LR with the HPPI 193913531Sjairo.balart@metempsy.comint 194013531Sjairo.balart@metempsy.comGicv3CPUInterface::getHPPVILR() 194113531Sjairo.balart@metempsy.com{ 194213531Sjairo.balart@metempsy.com int idx = -1; 194313531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 194413531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 194513531Sjairo.balart@metempsy.com 194613531Sjairo.balart@metempsy.com if (!(ich_vmcr_el2 & (ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1))) { 194713531Sjairo.balart@metempsy.com // VG0 and VG1 disabled... 194813531Sjairo.balart@metempsy.com return idx; 194913531Sjairo.balart@metempsy.com } 195013531Sjairo.balart@metempsy.com 195113531Sjairo.balart@metempsy.com uint8_t highest_prio = 0xff; 195213531Sjairo.balart@metempsy.com 195313531Sjairo.balart@metempsy.com for (int i = 0; i < 16; i++) { 195413531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_lri_el2 = 195513531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i); 195613531Sjairo.balart@metempsy.com uint8_t state = bits(ich_lri_el2, 63, 62); 195713531Sjairo.balart@metempsy.com 195813531Sjairo.balart@metempsy.com if (state != Gicv3::INT_PENDING) { 195913531Sjairo.balart@metempsy.com continue; 196013531Sjairo.balart@metempsy.com } 196113531Sjairo.balart@metempsy.com 196213531Sjairo.balart@metempsy.com if (ich_lri_el2 & ICH_LR_EL2_GROUP) { 196313531Sjairo.balart@metempsy.com // VG1 196413531Sjairo.balart@metempsy.com if (!(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) { 196513531Sjairo.balart@metempsy.com continue; 196613531Sjairo.balart@metempsy.com } 196713531Sjairo.balart@metempsy.com } else { 196813531Sjairo.balart@metempsy.com // VG0 196913531Sjairo.balart@metempsy.com if (!(ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) { 197013531Sjairo.balart@metempsy.com continue; 197113531Sjairo.balart@metempsy.com } 197213531Sjairo.balart@metempsy.com } 197313531Sjairo.balart@metempsy.com 197413531Sjairo.balart@metempsy.com uint8_t prio = bits(ich_lri_el2, 55, 48); 197513531Sjairo.balart@metempsy.com 197613531Sjairo.balart@metempsy.com if (prio < highest_prio) { 197713531Sjairo.balart@metempsy.com highest_prio = prio; 197813531Sjairo.balart@metempsy.com idx = i; 197913531Sjairo.balart@metempsy.com } 198013531Sjairo.balart@metempsy.com } 198113531Sjairo.balart@metempsy.com 198213531Sjairo.balart@metempsy.com return idx; 198313531Sjairo.balart@metempsy.com} 198413531Sjairo.balart@metempsy.com 198513531Sjairo.balart@metempsy.combool 198613531Sjairo.balart@metempsy.comGicv3CPUInterface::hppviCanPreempt(int lr_idx) 198713531Sjairo.balart@metempsy.com{ 198813531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + 198913531Sjairo.balart@metempsy.com lr_idx); 199013531Sjairo.balart@metempsy.com 199113531Sjairo.balart@metempsy.com if (!(isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2) & ICH_HCR_EL2_EN)) { 199213531Sjairo.balart@metempsy.com // virtual interface is disabled 199313531Sjairo.balart@metempsy.com return false; 199413531Sjairo.balart@metempsy.com } 199513531Sjairo.balart@metempsy.com 199613531Sjairo.balart@metempsy.com uint8_t prio = bits(lr, 55, 48); 199713531Sjairo.balart@metempsy.com uint8_t vpmr = 199813531Sjairo.balart@metempsy.com bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24); 199913531Sjairo.balart@metempsy.com 200013531Sjairo.balart@metempsy.com if (prio >= vpmr) { 200113531Sjairo.balart@metempsy.com // prioriry masked 200213531Sjairo.balart@metempsy.com return false; 200313531Sjairo.balart@metempsy.com } 200413531Sjairo.balart@metempsy.com 200513531Sjairo.balart@metempsy.com uint8_t rprio = virtualHighestActivePriority(); 200613531Sjairo.balart@metempsy.com 200713531Sjairo.balart@metempsy.com if (rprio == 0xff) { 200813531Sjairo.balart@metempsy.com return true; 200913531Sjairo.balart@metempsy.com } 201013531Sjairo.balart@metempsy.com 201113531Sjairo.balart@metempsy.com Gicv3::GroupId group = lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S; 201213531Sjairo.balart@metempsy.com uint32_t prio_mask = virtualGroupPriorityMask(group); 201313531Sjairo.balart@metempsy.com 201413531Sjairo.balart@metempsy.com if ((prio & prio_mask) < (rprio & prio_mask)) { 201513531Sjairo.balart@metempsy.com return true; 201613531Sjairo.balart@metempsy.com } 201713531Sjairo.balart@metempsy.com 201813531Sjairo.balart@metempsy.com return false; 201913531Sjairo.balart@metempsy.com} 202013531Sjairo.balart@metempsy.com 202113531Sjairo.balart@metempsy.comuint8_t 202213531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualHighestActivePriority() 202313531Sjairo.balart@metempsy.com{ 202413531Sjairo.balart@metempsy.com uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5); 202513531Sjairo.balart@metempsy.com 202613531Sjairo.balart@metempsy.com for (int i = 0; i < num_aprs; i++) { 202713531Sjairo.balart@metempsy.com ArmISA::MiscReg vapr = 202813531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) | 202913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i); 203013531Sjairo.balart@metempsy.com 203113531Sjairo.balart@metempsy.com if (!vapr) { 203213531Sjairo.balart@metempsy.com continue; 203313531Sjairo.balart@metempsy.com } 203413531Sjairo.balart@metempsy.com 203513531Sjairo.balart@metempsy.com return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1); 203613531Sjairo.balart@metempsy.com } 203713531Sjairo.balart@metempsy.com 203813531Sjairo.balart@metempsy.com // no active interrups, return idle priority 203913531Sjairo.balart@metempsy.com return 0xff; 204013531Sjairo.balart@metempsy.com} 204113531Sjairo.balart@metempsy.com 204213531Sjairo.balart@metempsy.comvoid 204313531Sjairo.balart@metempsy.comGicv3CPUInterface::virtualIncrementEOICount() 204413531Sjairo.balart@metempsy.com{ 204513531Sjairo.balart@metempsy.com // Increment the EOICOUNT field in ICH_HCR_EL2 204613531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_hcr_el2 = 204713531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 204813531Sjairo.balart@metempsy.com uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27); 204913531Sjairo.balart@metempsy.com EOI_cout++; 205013531Sjairo.balart@metempsy.com ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout); 205113531Sjairo.balart@metempsy.com isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2); 205213531Sjairo.balart@metempsy.com} 205313531Sjairo.balart@metempsy.com 205413531Sjairo.balart@metempsy.com/* 205513531Sjairo.balart@metempsy.com * Should we signal the interrupt as IRQ or FIQ? 205613531Sjairo.balart@metempsy.com * see spec section 4.6.2 205713531Sjairo.balart@metempsy.com */ 205813531Sjairo.balart@metempsy.comArmISA::InterruptTypes 205913531Sjairo.balart@metempsy.comGicv3CPUInterface::intSignalType(Gicv3::GroupId group) 206013531Sjairo.balart@metempsy.com{ 206113531Sjairo.balart@metempsy.com bool is_fiq = false; 206213531Sjairo.balart@metempsy.com 206313531Sjairo.balart@metempsy.com switch (group) { 206413531Sjairo.balart@metempsy.com case Gicv3::G0S: 206513531Sjairo.balart@metempsy.com is_fiq = true; 206613531Sjairo.balart@metempsy.com break; 206713531Sjairo.balart@metempsy.com 206813531Sjairo.balart@metempsy.com case Gicv3::G1S: 206913531Sjairo.balart@metempsy.com is_fiq = (distributor->DS == 0) && 207013531Sjairo.balart@metempsy.com (!inSecureState() || ((currEL() == EL3) && isAA64())); 207113531Sjairo.balart@metempsy.com break; 207213531Sjairo.balart@metempsy.com 207313531Sjairo.balart@metempsy.com case Gicv3::G1NS: 207413531Sjairo.balart@metempsy.com is_fiq = (distributor->DS == 0) && inSecureState(); 207513531Sjairo.balart@metempsy.com break; 207613531Sjairo.balart@metempsy.com 207713531Sjairo.balart@metempsy.com default: 207813531Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::intSignalType(): invalid group!"); 207913531Sjairo.balart@metempsy.com } 208013531Sjairo.balart@metempsy.com 208113531Sjairo.balart@metempsy.com if (is_fiq) { 208213531Sjairo.balart@metempsy.com return ArmISA::INT_FIQ; 208313531Sjairo.balart@metempsy.com } else { 208413531Sjairo.balart@metempsy.com return ArmISA::INT_IRQ; 208513531Sjairo.balart@metempsy.com } 208613531Sjairo.balart@metempsy.com} 208713531Sjairo.balart@metempsy.com 208813531Sjairo.balart@metempsy.combool 208913531Sjairo.balart@metempsy.comGicv3CPUInterface::hppiCanPreempt() 209013531Sjairo.balart@metempsy.com{ 209113531Sjairo.balart@metempsy.com if (hppi.prio == 0xff) { 209213531Sjairo.balart@metempsy.com // there is no pending interrupt 209313531Sjairo.balart@metempsy.com return false; 209413531Sjairo.balart@metempsy.com } 209513531Sjairo.balart@metempsy.com 209613531Sjairo.balart@metempsy.com if (!groupEnabled(hppi.group)) { 209713531Sjairo.balart@metempsy.com // group disabled at CPU interface 209813531Sjairo.balart@metempsy.com return false; 209913531Sjairo.balart@metempsy.com } 210013531Sjairo.balart@metempsy.com 210113531Sjairo.balart@metempsy.com if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) { 210213531Sjairo.balart@metempsy.com // priority masked 210313531Sjairo.balart@metempsy.com return false; 210413531Sjairo.balart@metempsy.com } 210513531Sjairo.balart@metempsy.com 210613531Sjairo.balart@metempsy.com uint8_t rprio = highestActivePriority(); 210713531Sjairo.balart@metempsy.com 210813531Sjairo.balart@metempsy.com if (rprio == 0xff) { 210913531Sjairo.balart@metempsy.com return true; 211013531Sjairo.balart@metempsy.com } 211113531Sjairo.balart@metempsy.com 211213531Sjairo.balart@metempsy.com uint32_t prio_mask = groupPriorityMask(hppi.group); 211313531Sjairo.balart@metempsy.com 211413531Sjairo.balart@metempsy.com if ((hppi.prio & prio_mask) < (rprio & prio_mask)) { 211513531Sjairo.balart@metempsy.com return true; 211613531Sjairo.balart@metempsy.com } 211713531Sjairo.balart@metempsy.com 211813531Sjairo.balart@metempsy.com return false; 211913531Sjairo.balart@metempsy.com} 212013531Sjairo.balart@metempsy.com 212113531Sjairo.balart@metempsy.comuint8_t 212213531Sjairo.balart@metempsy.comGicv3CPUInterface::highestActivePriority() 212313531Sjairo.balart@metempsy.com{ 212413531Sjairo.balart@metempsy.com uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) | 212513531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) | 212613531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S); 212713531Sjairo.balart@metempsy.com 212813531Sjairo.balart@metempsy.com if (apr) { 212913531Sjairo.balart@metempsy.com return ctz32(apr) << (GIC_MIN_BPR + 1); 213013531Sjairo.balart@metempsy.com } 213113531Sjairo.balart@metempsy.com 213213531Sjairo.balart@metempsy.com // no active interrups, return idle priority 213313531Sjairo.balart@metempsy.com return 0xff; 213413531Sjairo.balart@metempsy.com} 213513531Sjairo.balart@metempsy.com 213613531Sjairo.balart@metempsy.combool 213713531Sjairo.balart@metempsy.comGicv3CPUInterface::groupEnabled(Gicv3::GroupId group) 213813531Sjairo.balart@metempsy.com{ 213913531Sjairo.balart@metempsy.com switch (group) { 214013531Sjairo.balart@metempsy.com case Gicv3::G0S: 214113531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1) & 214213531Sjairo.balart@metempsy.com ICC_IGRPEN0_EL1_ENABLE; 214313531Sjairo.balart@metempsy.com 214413531Sjairo.balart@metempsy.com case Gicv3::G1S: 214513531Sjairo.balart@metempsy.com //if (distributor->DS) 214613531Sjairo.balart@metempsy.com //{ 214713531Sjairo.balart@metempsy.com // return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) & 214813531Sjairo.balart@metempsy.com // ICC_IGRPEN1_EL1_ENABLE; 214913531Sjairo.balart@metempsy.com //} 215013531Sjairo.balart@metempsy.com //else 215113531Sjairo.balart@metempsy.com //{ 215213531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S) & 215313531Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1_ENABLE; 215413531Sjairo.balart@metempsy.com 215513531Sjairo.balart@metempsy.com //} 215613531Sjairo.balart@metempsy.com 215713531Sjairo.balart@metempsy.com case Gicv3::G1NS: 215813531Sjairo.balart@metempsy.com return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) & 215913531Sjairo.balart@metempsy.com ICC_IGRPEN1_EL1_ENABLE; 216013531Sjairo.balart@metempsy.com 216113531Sjairo.balart@metempsy.com default: 216213531Sjairo.balart@metempsy.com panic("Gicv3CPUInterface::groupEnable(): invalid group!\n"); 216313531Sjairo.balart@metempsy.com } 216413531Sjairo.balart@metempsy.com} 216513531Sjairo.balart@metempsy.com 216613531Sjairo.balart@metempsy.combool 216713531Sjairo.balart@metempsy.comGicv3CPUInterface::inSecureState() 216813531Sjairo.balart@metempsy.com{ 216913531Sjairo.balart@metempsy.com if (!gic->getSystem()->haveSecurity()) { 217013531Sjairo.balart@metempsy.com return false; 217113531Sjairo.balart@metempsy.com } 217213531Sjairo.balart@metempsy.com 217313531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 217413531Sjairo.balart@metempsy.com SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR); 217513531Sjairo.balart@metempsy.com return ArmISA::inSecureState(scr, cpsr); 217613531Sjairo.balart@metempsy.com} 217713531Sjairo.balart@metempsy.com 217813531Sjairo.balart@metempsy.comint 217913531Sjairo.balart@metempsy.comGicv3CPUInterface::currEL() 218013531Sjairo.balart@metempsy.com{ 218113531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 218213531Sjairo.balart@metempsy.com bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 218313531Sjairo.balart@metempsy.com 218413531Sjairo.balart@metempsy.com if (is_64) { 218513531Sjairo.balart@metempsy.com return (ExceptionLevel)(uint8_t) cpsr.el; 218613531Sjairo.balart@metempsy.com } else { 218713531Sjairo.balart@metempsy.com switch (cpsr.mode) { 218813531Sjairo.balart@metempsy.com case MODE_USER: 218913531Sjairo.balart@metempsy.com return 0; 219013531Sjairo.balart@metempsy.com 219113531Sjairo.balart@metempsy.com case MODE_HYP: 219213531Sjairo.balart@metempsy.com return 2; 219313531Sjairo.balart@metempsy.com 219413531Sjairo.balart@metempsy.com case MODE_MON: 219513531Sjairo.balart@metempsy.com return 3; 219613531Sjairo.balart@metempsy.com 219713531Sjairo.balart@metempsy.com default: 219813531Sjairo.balart@metempsy.com return 1; 219913531Sjairo.balart@metempsy.com } 220013531Sjairo.balart@metempsy.com } 220113531Sjairo.balart@metempsy.com} 220213531Sjairo.balart@metempsy.com 220313531Sjairo.balart@metempsy.combool 220413531Sjairo.balart@metempsy.comGicv3CPUInterface::haveEL(ExceptionLevel el) 220513531Sjairo.balart@metempsy.com{ 220613531Sjairo.balart@metempsy.com switch (el) { 220713531Sjairo.balart@metempsy.com case EL0: 220813531Sjairo.balart@metempsy.com case EL1: 220913531Sjairo.balart@metempsy.com return true; 221013531Sjairo.balart@metempsy.com 221113531Sjairo.balart@metempsy.com case EL2: 221213531Sjairo.balart@metempsy.com return gic->getSystem()->haveVirtualization(); 221313531Sjairo.balart@metempsy.com 221413531Sjairo.balart@metempsy.com case EL3: 221513531Sjairo.balart@metempsy.com return gic->getSystem()->haveSecurity(); 221613531Sjairo.balart@metempsy.com 221713531Sjairo.balart@metempsy.com default: 221813531Sjairo.balart@metempsy.com warn("Unimplemented Exception Level\n"); 221913531Sjairo.balart@metempsy.com return false; 222013531Sjairo.balart@metempsy.com } 222113531Sjairo.balart@metempsy.com} 222213531Sjairo.balart@metempsy.com 222313531Sjairo.balart@metempsy.combool 222413531Sjairo.balart@metempsy.comGicv3CPUInterface::isSecureBelowEL3() 222513531Sjairo.balart@metempsy.com{ 222613531Sjairo.balart@metempsy.com SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3); 222713531Sjairo.balart@metempsy.com return haveEL(EL3) && scr.ns == 0; 222813531Sjairo.balart@metempsy.com} 222913531Sjairo.balart@metempsy.com 223013531Sjairo.balart@metempsy.combool 223113531Sjairo.balart@metempsy.comGicv3CPUInterface::isAA64() 223213531Sjairo.balart@metempsy.com{ 223313531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 223413531Sjairo.balart@metempsy.com return opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 223513531Sjairo.balart@metempsy.com} 223613531Sjairo.balart@metempsy.com 223713531Sjairo.balart@metempsy.combool 223813531Sjairo.balart@metempsy.comGicv3CPUInterface::isEL3OrMon() 223913531Sjairo.balart@metempsy.com{ 224013531Sjairo.balart@metempsy.com if (haveEL(EL3)) { 224113531Sjairo.balart@metempsy.com CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR); 224213531Sjairo.balart@metempsy.com bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode); 224313531Sjairo.balart@metempsy.com 224413531Sjairo.balart@metempsy.com if (is_64 && (cpsr.el == EL3)) { 224513531Sjairo.balart@metempsy.com return true; 224613531Sjairo.balart@metempsy.com } else if (!is_64 && (cpsr.mode == MODE_MON)) { 224713531Sjairo.balart@metempsy.com return true; 224813531Sjairo.balart@metempsy.com } 224913531Sjairo.balart@metempsy.com } 225013531Sjairo.balart@metempsy.com 225113531Sjairo.balart@metempsy.com return false; 225213531Sjairo.balart@metempsy.com} 225313531Sjairo.balart@metempsy.com 225413531Sjairo.balart@metempsy.comuint32_t 225513531Sjairo.balart@metempsy.comGicv3CPUInterface::eoiMaintenanceInterruptStatus(uint32_t * misr) 225613531Sjairo.balart@metempsy.com{ 225713531Sjairo.balart@metempsy.com /* Return a set of bits indicating the EOI maintenance interrupt status 225813531Sjairo.balart@metempsy.com * for each list register. The EOI maintenance interrupt status is 225913531Sjairo.balart@metempsy.com * 1 if LR.State == 0 && LR.HW == 0 && LR.EOI == 1 226013531Sjairo.balart@metempsy.com * (see the GICv3 spec for the ICH_EISR_EL2 register). 226113531Sjairo.balart@metempsy.com * If misr is not NULL then we should also collect the information 226213531Sjairo.balart@metempsy.com * about the MISR.EOI, MISR.NP and MISR.U bits. 226313531Sjairo.balart@metempsy.com */ 226413531Sjairo.balart@metempsy.com uint32_t value = 0; 226513531Sjairo.balart@metempsy.com int valid_count = 0; 226613531Sjairo.balart@metempsy.com bool seen_pending = false; 226713531Sjairo.balart@metempsy.com 226813531Sjairo.balart@metempsy.com for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) { 226913531Sjairo.balart@metempsy.com ArmISA::MiscReg lr = 227013531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx); 227113531Sjairo.balart@metempsy.com 227213531Sjairo.balart@metempsy.com if ((lr & (ICH_LR_EL2_STATE_MASK | ICH_LR_EL2_HW | ICH_LR_EL2_EOI)) == 227313531Sjairo.balart@metempsy.com ICH_LR_EL2_EOI) { 227413531Sjairo.balart@metempsy.com value |= (1 << lr_idx); 227513531Sjairo.balart@metempsy.com } 227613531Sjairo.balart@metempsy.com 227713531Sjairo.balart@metempsy.com if ((lr & ICH_LR_EL2_STATE_MASK)) { 227813531Sjairo.balart@metempsy.com valid_count++; 227913531Sjairo.balart@metempsy.com } 228013531Sjairo.balart@metempsy.com 228113531Sjairo.balart@metempsy.com if (bits(lr, ICH_LR_EL2_STATE_SHIFT + ICH_LR_EL2_STATE_LENGTH, 228213531Sjairo.balart@metempsy.com ICH_LR_EL2_STATE_SHIFT) == ICH_LR_EL2_STATE_PENDING) { 228313531Sjairo.balart@metempsy.com seen_pending = true; 228413531Sjairo.balart@metempsy.com } 228513531Sjairo.balart@metempsy.com } 228613531Sjairo.balart@metempsy.com 228713531Sjairo.balart@metempsy.com if (misr) { 228813531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_hcr_el2 = 228913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 229013531Sjairo.balart@metempsy.com 229113531Sjairo.balart@metempsy.com if (valid_count < 2 && (ich_hcr_el2 & ICH_HCR_EL2_UIE)) { 229213531Sjairo.balart@metempsy.com *misr |= ICH_MISR_EL2_U; 229313531Sjairo.balart@metempsy.com } 229413531Sjairo.balart@metempsy.com 229513531Sjairo.balart@metempsy.com if (!seen_pending && (ich_hcr_el2 & ICH_HCR_EL2_NPIE)) { 229613531Sjairo.balart@metempsy.com *misr |= ICH_MISR_EL2_NP; 229713531Sjairo.balart@metempsy.com } 229813531Sjairo.balart@metempsy.com 229913531Sjairo.balart@metempsy.com if (value) { 230013531Sjairo.balart@metempsy.com *misr |= ICH_MISR_EL2_EOI; 230113531Sjairo.balart@metempsy.com } 230213531Sjairo.balart@metempsy.com } 230313531Sjairo.balart@metempsy.com 230413531Sjairo.balart@metempsy.com return value; 230513531Sjairo.balart@metempsy.com} 230613531Sjairo.balart@metempsy.com 230713531Sjairo.balart@metempsy.comuint32_t 230813531Sjairo.balart@metempsy.comGicv3CPUInterface::maintenanceInterruptStatus() 230913531Sjairo.balart@metempsy.com{ 231013531Sjairo.balart@metempsy.com /* Return a set of bits indicating the maintenance interrupt status 231113531Sjairo.balart@metempsy.com * (as seen in the ICH_MISR_EL2 register). 231213531Sjairo.balart@metempsy.com */ 231313531Sjairo.balart@metempsy.com uint32_t value = 0; 231413531Sjairo.balart@metempsy.com /* Scan list registers and fill in the U, NP and EOI bits */ 231513531Sjairo.balart@metempsy.com eoiMaintenanceInterruptStatus(&value); 231613531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_hcr_el2 = 231713531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); 231813531Sjairo.balart@metempsy.com ArmISA::MiscReg ich_vmcr_el2 = 231913531Sjairo.balart@metempsy.com isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2); 232013531Sjairo.balart@metempsy.com 232113531Sjairo.balart@metempsy.com if (ich_hcr_el2 & (ICH_HCR_EL2_LRENPIE | ICH_HCR_EL2_EOICOUNT_MASK)) { 232213531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_LRENP; 232313531Sjairo.balart@metempsy.com } 232413531Sjairo.balart@metempsy.com 232513531Sjairo.balart@metempsy.com if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0EIE) && 232613531Sjairo.balart@metempsy.com (ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) { 232713531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_VGRP0E; 232813531Sjairo.balart@metempsy.com } 232913531Sjairo.balart@metempsy.com 233013531Sjairo.balart@metempsy.com if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) && 233113531Sjairo.balart@metempsy.com !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) { 233213531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_VGRP0D; 233313531Sjairo.balart@metempsy.com } 233413531Sjairo.balart@metempsy.com 233513531Sjairo.balart@metempsy.com if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) && 233613531Sjairo.balart@metempsy.com (ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) { 233713531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_VGRP1E; 233813531Sjairo.balart@metempsy.com } 233913531Sjairo.balart@metempsy.com 234013531Sjairo.balart@metempsy.com if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1DIE) && 234113531Sjairo.balart@metempsy.com !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) { 234213531Sjairo.balart@metempsy.com value |= ICH_MISR_EL2_VGRP1D; 234313531Sjairo.balart@metempsy.com } 234413531Sjairo.balart@metempsy.com 234513531Sjairo.balart@metempsy.com return value; 234613531Sjairo.balart@metempsy.com} 234713531Sjairo.balart@metempsy.com 234813531Sjairo.balart@metempsy.comvoid 234913531Sjairo.balart@metempsy.comGicv3CPUInterface::serialize(CheckpointOut & cp) const 235013531Sjairo.balart@metempsy.com{ 235113531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(hppi.intid); 235213531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(hppi.prio); 235313531Sjairo.balart@metempsy.com SERIALIZE_ENUM(hppi.group); 235413531Sjairo.balart@metempsy.com} 235513531Sjairo.balart@metempsy.com 235613531Sjairo.balart@metempsy.comvoid 235713531Sjairo.balart@metempsy.comGicv3CPUInterface::unserialize(CheckpointIn & cp) 235813531Sjairo.balart@metempsy.com{ 235913531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(hppi.intid); 236013531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(hppi.prio); 236113531Sjairo.balart@metempsy.com UNSERIALIZE_ENUM(hppi.group); 236213531Sjairo.balart@metempsy.com} 2363