gic_v3_redistributor.cc revision 13928
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_redistributor.hh" 3213531Sjairo.balart@metempsy.com 3313531Sjairo.balart@metempsy.com#include "arch/arm/utility.hh" 3413531Sjairo.balart@metempsy.com#include "debug/GIC.hh" 3513531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh" 3613531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh" 3713690Sjairo.balart@metempsy.com#include "mem/fs_translating_port_proxy.hh" 3813531Sjairo.balart@metempsy.com 3913531Sjairo.balart@metempsy.comconst AddrRange Gicv3Redistributor::GICR_IPRIORITYR(SGI_base + 0x0400, 4013756Sjairo.balart@metempsy.com SGI_base + 0x041f); 4113531Sjairo.balart@metempsy.com 4213531Sjairo.balart@metempsy.comGicv3Redistributor::Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id) 4313531Sjairo.balart@metempsy.com : gic(gic), 4413531Sjairo.balart@metempsy.com distributor(nullptr), 4513531Sjairo.balart@metempsy.com cpuInterface(nullptr), 4613531Sjairo.balart@metempsy.com cpuId(cpu_id), 4713928Sgiacomo.travaglini@arm.com memProxy(nullptr), 4813531Sjairo.balart@metempsy.com irqGroup(Gicv3::SGI_MAX + Gicv3::PPI_MAX), 4913531Sjairo.balart@metempsy.com irqEnabled(Gicv3::SGI_MAX + Gicv3::PPI_MAX), 5013531Sjairo.balart@metempsy.com irqPending(Gicv3::SGI_MAX + Gicv3::PPI_MAX), 5113531Sjairo.balart@metempsy.com irqActive(Gicv3::SGI_MAX + Gicv3::PPI_MAX), 5213531Sjairo.balart@metempsy.com irqPriority(Gicv3::SGI_MAX + Gicv3::PPI_MAX), 5313531Sjairo.balart@metempsy.com irqConfig(Gicv3::SGI_MAX + Gicv3::PPI_MAX), 5413531Sjairo.balart@metempsy.com irqGrpmod(Gicv3::SGI_MAX + Gicv3::PPI_MAX), 5513878Sgiacomo.travaglini@arm.com irqNsacr(Gicv3::SGI_MAX + Gicv3::PPI_MAX), 5613878Sgiacomo.travaglini@arm.com addrRangeSize(gic->params()->gicv4 ? 0x40000 : 0x20000) 5713531Sjairo.balart@metempsy.com{ 5813531Sjairo.balart@metempsy.com} 5913531Sjairo.balart@metempsy.com 6013531Sjairo.balart@metempsy.comvoid 6113531Sjairo.balart@metempsy.comGicv3Redistributor::init() 6213531Sjairo.balart@metempsy.com{ 6313531Sjairo.balart@metempsy.com distributor = gic->getDistributor(); 6413531Sjairo.balart@metempsy.com cpuInterface = gic->getCPUInterface(cpuId); 6513928Sgiacomo.travaglini@arm.com 6613928Sgiacomo.travaglini@arm.com memProxy = &gic->getSystem()->physProxy; 6713531Sjairo.balart@metempsy.com} 6813531Sjairo.balart@metempsy.com 6913531Sjairo.balart@metempsy.comvoid 7013531Sjairo.balart@metempsy.comGicv3Redistributor::initState() 7113531Sjairo.balart@metempsy.com{ 7213531Sjairo.balart@metempsy.com reset(); 7313531Sjairo.balart@metempsy.com} 7413531Sjairo.balart@metempsy.com 7513531Sjairo.balart@metempsy.comvoid 7613531Sjairo.balart@metempsy.comGicv3Redistributor::reset() 7713531Sjairo.balart@metempsy.com{ 7813531Sjairo.balart@metempsy.com peInLowPowerState = true; 7913531Sjairo.balart@metempsy.com std::fill(irqGroup.begin(), irqGroup.end(), 0); 8013531Sjairo.balart@metempsy.com std::fill(irqEnabled.begin(), irqEnabled.end(), false); 8113531Sjairo.balart@metempsy.com std::fill(irqPending.begin(), irqPending.end(), false); 8213531Sjairo.balart@metempsy.com std::fill(irqActive.begin(), irqActive.end(), false); 8313531Sjairo.balart@metempsy.com std::fill(irqPriority.begin(), irqPriority.end(), 0); 8413531Sjairo.balart@metempsy.com 8513531Sjairo.balart@metempsy.com // SGIs have edge-triggered behavior 8613531Sjairo.balart@metempsy.com for (uint32_t int_id = 0; int_id < Gicv3::SGI_MAX; int_id++) { 8713531Sjairo.balart@metempsy.com irqConfig[int_id] = Gicv3::INT_EDGE_TRIGGERED; 8813531Sjairo.balart@metempsy.com } 8913531Sjairo.balart@metempsy.com 9013531Sjairo.balart@metempsy.com std::fill(irqGrpmod.begin(), irqGrpmod.end(), 0); 9113531Sjairo.balart@metempsy.com std::fill(irqNsacr.begin(), irqNsacr.end(), 0); 9213531Sjairo.balart@metempsy.com DPG1S = false; 9313531Sjairo.balart@metempsy.com DPG1NS = false; 9413531Sjairo.balart@metempsy.com DPG0 = false; 9513690Sjairo.balart@metempsy.com EnableLPIs = false; 9613690Sjairo.balart@metempsy.com lpiConfigurationTablePtr = 0; 9713690Sjairo.balart@metempsy.com lpiIDBits = 0; 9813690Sjairo.balart@metempsy.com lpiPendingTablePtr = 0; 9913531Sjairo.balart@metempsy.com} 10013531Sjairo.balart@metempsy.com 10113531Sjairo.balart@metempsy.comuint64_t 10213531Sjairo.balart@metempsy.comGicv3Redistributor::read(Addr addr, size_t size, bool is_secure_access) 10313531Sjairo.balart@metempsy.com{ 10413531Sjairo.balart@metempsy.com if (GICR_IPRIORITYR.contains(addr)) { // Interrupt Priority Registers 10513531Sjairo.balart@metempsy.com uint64_t value = 0; 10613531Sjairo.balart@metempsy.com int first_intid = addr - GICR_IPRIORITYR.start(); 10713531Sjairo.balart@metempsy.com 10813531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < size; i++, int_id++) { 10913531Sjairo.balart@metempsy.com uint8_t prio = irqPriority[int_id]; 11013531Sjairo.balart@metempsy.com 11113531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 11213531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 11313531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 11413531Sjairo.balart@metempsy.com continue; 11513531Sjairo.balart@metempsy.com } else { 11613531Sjairo.balart@metempsy.com // NS view 11713531Sjairo.balart@metempsy.com prio = (prio << 1) & 0xff; 11813531Sjairo.balart@metempsy.com } 11913531Sjairo.balart@metempsy.com } 12013531Sjairo.balart@metempsy.com 12113531Sjairo.balart@metempsy.com value |= prio << (i * 8); 12213531Sjairo.balart@metempsy.com } 12313531Sjairo.balart@metempsy.com 12413531Sjairo.balart@metempsy.com return value; 12513531Sjairo.balart@metempsy.com } 12613531Sjairo.balart@metempsy.com 12713531Sjairo.balart@metempsy.com switch (addr) { 12813531Sjairo.balart@metempsy.com case GICR_CTLR: { // Control Register 12913531Sjairo.balart@metempsy.com uint64_t value = 0; 13013531Sjairo.balart@metempsy.com 13113531Sjairo.balart@metempsy.com if (DPG1S) { 13213531Sjairo.balart@metempsy.com value |= GICR_CTLR_DPG1S; 13313531Sjairo.balart@metempsy.com } 13413531Sjairo.balart@metempsy.com 13513531Sjairo.balart@metempsy.com if (DPG1NS) { 13613531Sjairo.balart@metempsy.com value |= GICR_CTLR_DPG1NS; 13713531Sjairo.balart@metempsy.com } 13813531Sjairo.balart@metempsy.com 13913531Sjairo.balart@metempsy.com if (DPG0) { 14013531Sjairo.balart@metempsy.com value |= GICR_CTLR_DPG0; 14113531Sjairo.balart@metempsy.com } 14213531Sjairo.balart@metempsy.com 14313690Sjairo.balart@metempsy.com if (EnableLPIs) { 14413690Sjairo.balart@metempsy.com value |= GICR_CTLR_ENABLE_LPIS; 14513690Sjairo.balart@metempsy.com } 14613690Sjairo.balart@metempsy.com 14713531Sjairo.balart@metempsy.com return value; 14813531Sjairo.balart@metempsy.com } 14913531Sjairo.balart@metempsy.com 15013531Sjairo.balart@metempsy.com case GICR_IIDR: // Implementer Identification Register 15113531Sjairo.balart@metempsy.com //return 0x43b; // r0p0 GIC-500 15213531Sjairo.balart@metempsy.com return 0; 15313531Sjairo.balart@metempsy.com 15413531Sjairo.balart@metempsy.com case GICR_TYPER: { // Type Register 15513531Sjairo.balart@metempsy.com /* 15613531Sjairo.balart@metempsy.com * Affinity_Value [63:32] == X 15713531Sjairo.balart@metempsy.com * (The identity of the PE associated with this Redistributor) 15813531Sjairo.balart@metempsy.com * CommonLPIAff [25:24] == 01 15913531Sjairo.balart@metempsy.com * (All Redistributors with the same Aff3 value must share an 16013531Sjairo.balart@metempsy.com * LPI Configuration table) 16113531Sjairo.balart@metempsy.com * Processor_Number [23:8] == X 16213531Sjairo.balart@metempsy.com * (A unique identifier for the PE) 16313531Sjairo.balart@metempsy.com * DPGS [5] == 1 16413531Sjairo.balart@metempsy.com * (GICR_CTLR.DPG* bits are supported) 16513531Sjairo.balart@metempsy.com * Last [4] == X 16613531Sjairo.balart@metempsy.com * (This Redistributor is the highest-numbered Redistributor in 16713531Sjairo.balart@metempsy.com * a series of contiguous Redistributor pages) 16813690Sjairo.balart@metempsy.com * DirectLPI [3] == 1 16913690Sjairo.balart@metempsy.com * (direct injection of LPIs supported) 17013531Sjairo.balart@metempsy.com * VLPIS [1] == 0 17113531Sjairo.balart@metempsy.com * (virtual LPIs not supported) 17213690Sjairo.balart@metempsy.com * PLPIS [0] == 1 17313690Sjairo.balart@metempsy.com * (physical LPIs supported) 17413531Sjairo.balart@metempsy.com */ 17513531Sjairo.balart@metempsy.com uint64_t affinity = getAffinity(); 17613531Sjairo.balart@metempsy.com int last = cpuId == (gic->getSystem()->numContexts() - 1); 17713531Sjairo.balart@metempsy.com return (affinity << 32) | (1 << 24) | (cpuId << 8) | 17813690Sjairo.balart@metempsy.com (1 << 5) | (last << 4) | (1 << 3) | (1 << 0); 17913531Sjairo.balart@metempsy.com } 18013531Sjairo.balart@metempsy.com 18113531Sjairo.balart@metempsy.com case GICR_WAKER: // Wake Register 18213531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 18313531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 18413531Sjairo.balart@metempsy.com return 0; 18513531Sjairo.balart@metempsy.com } 18613531Sjairo.balart@metempsy.com 18713531Sjairo.balart@metempsy.com if (peInLowPowerState) { 18813531Sjairo.balart@metempsy.com return GICR_WAKER_ChildrenAsleep | GICR_WAKER_ProcessorSleep; 18913531Sjairo.balart@metempsy.com } else { 19013531Sjairo.balart@metempsy.com return 0; 19113531Sjairo.balart@metempsy.com } 19213531Sjairo.balart@metempsy.com 19313531Sjairo.balart@metempsy.com case GICR_PIDR0: { // Peripheral ID0 Register 19413756Sjairo.balart@metempsy.com return 0x92; // Part number, bits[7:0] 19513531Sjairo.balart@metempsy.com } 19613531Sjairo.balart@metempsy.com 19713531Sjairo.balart@metempsy.com case GICR_PIDR1: { // Peripheral ID1 Register 19813531Sjairo.balart@metempsy.com uint8_t des_0 = 0xB; // JEP106 identification code, bits[3:0] 19913531Sjairo.balart@metempsy.com uint8_t part_1 = 0x4; // Part number, bits[11:8] 20013531Sjairo.balart@metempsy.com return (des_0 << 4) | (part_1 << 0); 20113531Sjairo.balart@metempsy.com } 20213531Sjairo.balart@metempsy.com 20313531Sjairo.balart@metempsy.com case GICR_PIDR2: { // Peripheral ID2 Register 20413531Sjairo.balart@metempsy.com uint8_t arch_rev = 0x3; // 0x3 GICv3 20513531Sjairo.balart@metempsy.com uint8_t jedec = 0x1; // JEP code 20613531Sjairo.balart@metempsy.com uint8_t des_1 = 0x3; // JEP106 identification code, bits[6:4] 20713531Sjairo.balart@metempsy.com return (arch_rev << 4) | (jedec << 3) | (des_1 << 0); 20813531Sjairo.balart@metempsy.com } 20913531Sjairo.balart@metempsy.com 21013531Sjairo.balart@metempsy.com case GICR_PIDR3: // Peripheral ID3 Register 21113531Sjairo.balart@metempsy.com return 0x0; // Implementation defined 21213531Sjairo.balart@metempsy.com 21313531Sjairo.balart@metempsy.com case GICR_PIDR4: { // Peripheral ID4 Register 21413531Sjairo.balart@metempsy.com uint8_t size = 0x4; // 64 KB software visible page 21513531Sjairo.balart@metempsy.com uint8_t des_2 = 0x4; // ARM implementation 21613531Sjairo.balart@metempsy.com return (size << 4) | (des_2 << 0); 21713531Sjairo.balart@metempsy.com } 21813531Sjairo.balart@metempsy.com 21913531Sjairo.balart@metempsy.com case GICR_PIDR5: // Peripheral ID5 Register 22013531Sjairo.balart@metempsy.com case GICR_PIDR6: // Peripheral ID6 Register 22113531Sjairo.balart@metempsy.com case GICR_PIDR7: // Peripheral ID7 Register 22213531Sjairo.balart@metempsy.com return 0; // RES0 22313531Sjairo.balart@metempsy.com 22413531Sjairo.balart@metempsy.com case GICR_IGROUPR0: { // Interrupt Group Register 0 22513531Sjairo.balart@metempsy.com uint64_t value = 0; 22613531Sjairo.balart@metempsy.com 22713531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 22813531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 22913531Sjairo.balart@metempsy.com return 0; 23013531Sjairo.balart@metempsy.com } 23113531Sjairo.balart@metempsy.com 23213531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 23313531Sjairo.balart@metempsy.com value |= (irqGroup[int_id] << int_id); 23413531Sjairo.balart@metempsy.com } 23513531Sjairo.balart@metempsy.com 23613531Sjairo.balart@metempsy.com return value; 23713531Sjairo.balart@metempsy.com } 23813531Sjairo.balart@metempsy.com 23913531Sjairo.balart@metempsy.com case GICR_ISENABLER0: // Interrupt Set-Enable Register 0 24013531Sjairo.balart@metempsy.com case GICR_ICENABLER0: { // Interrupt Clear-Enable Register 0 24113531Sjairo.balart@metempsy.com uint64_t value = 0; 24213531Sjairo.balart@metempsy.com 24313531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 24413531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 24513531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 24613531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 24713531Sjairo.balart@metempsy.com continue; 24813531Sjairo.balart@metempsy.com } 24913531Sjairo.balart@metempsy.com } 25013531Sjairo.balart@metempsy.com 25113531Sjairo.balart@metempsy.com if (irqEnabled[int_id]) { 25213531Sjairo.balart@metempsy.com value |= (1 << int_id); 25313531Sjairo.balart@metempsy.com } 25413531Sjairo.balart@metempsy.com } 25513531Sjairo.balart@metempsy.com 25613531Sjairo.balart@metempsy.com return value; 25713531Sjairo.balart@metempsy.com } 25813531Sjairo.balart@metempsy.com 25913531Sjairo.balart@metempsy.com case GICR_ISPENDR0: // Interrupt Set-Pending Register 0 26013531Sjairo.balart@metempsy.com case GICR_ICPENDR0: { // Interrupt Clear-Pending Register 0 26113531Sjairo.balart@metempsy.com uint64_t value = 0; 26213531Sjairo.balart@metempsy.com 26313531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 26413531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 26513531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 26613531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 26713531Sjairo.balart@metempsy.com continue; 26813531Sjairo.balart@metempsy.com } 26913531Sjairo.balart@metempsy.com } 27013531Sjairo.balart@metempsy.com 27113531Sjairo.balart@metempsy.com value |= (irqPending[int_id] << int_id); 27213531Sjairo.balart@metempsy.com } 27313531Sjairo.balart@metempsy.com 27413531Sjairo.balart@metempsy.com return value; 27513531Sjairo.balart@metempsy.com } 27613531Sjairo.balart@metempsy.com 27713531Sjairo.balart@metempsy.com case GICR_ISACTIVER0: // Interrupt Set-Active Register 0 27813531Sjairo.balart@metempsy.com case GICR_ICACTIVER0: { // Interrupt Clear-Active Register 0 27913531Sjairo.balart@metempsy.com uint64_t value = 0; 28013531Sjairo.balart@metempsy.com 28113531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 28213531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 28313531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 28413531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 28513531Sjairo.balart@metempsy.com continue; 28613531Sjairo.balart@metempsy.com } 28713531Sjairo.balart@metempsy.com } 28813531Sjairo.balart@metempsy.com 28913531Sjairo.balart@metempsy.com value |= irqActive[int_id] << int_id; 29013531Sjairo.balart@metempsy.com } 29113531Sjairo.balart@metempsy.com 29213531Sjairo.balart@metempsy.com return value; 29313531Sjairo.balart@metempsy.com } 29413531Sjairo.balart@metempsy.com 29513531Sjairo.balart@metempsy.com case GICR_ICFGR0: // SGI Configuration Register 29613531Sjairo.balart@metempsy.com case GICR_ICFGR1: { // PPI Configuration Register 29713531Sjairo.balart@metempsy.com uint64_t value = 0; 29813531Sjairo.balart@metempsy.com uint32_t first_int_id = addr == GICR_ICFGR0 ? 0 : Gicv3::SGI_MAX; 29913531Sjairo.balart@metempsy.com 30013531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_int_id; i < 32; 30113756Sjairo.balart@metempsy.com i = i + 2, int_id++) { 30213531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 30313531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 30413531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 30513531Sjairo.balart@metempsy.com continue; 30613531Sjairo.balart@metempsy.com } 30713531Sjairo.balart@metempsy.com } 30813531Sjairo.balart@metempsy.com 30913531Sjairo.balart@metempsy.com if (irqConfig[int_id] == Gicv3::INT_EDGE_TRIGGERED) { 31013531Sjairo.balart@metempsy.com value |= (0x2) << i; 31113531Sjairo.balart@metempsy.com } 31213531Sjairo.balart@metempsy.com } 31313531Sjairo.balart@metempsy.com 31413531Sjairo.balart@metempsy.com return value; 31513531Sjairo.balart@metempsy.com } 31613531Sjairo.balart@metempsy.com 31713531Sjairo.balart@metempsy.com case GICR_IGRPMODR0: { // Interrupt Group Modifier Register 0 31813531Sjairo.balart@metempsy.com uint64_t value = 0; 31913531Sjairo.balart@metempsy.com 32013531Sjairo.balart@metempsy.com if (distributor->DS) { 32113531Sjairo.balart@metempsy.com value = 0; 32213531Sjairo.balart@metempsy.com } else { 32313531Sjairo.balart@metempsy.com if (!is_secure_access) { 32413531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 32513531Sjairo.balart@metempsy.com value = 0; 32613531Sjairo.balart@metempsy.com } else { 32713531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 32813531Sjairo.balart@metempsy.com value |= irqGrpmod[int_id] << int_id; 32913531Sjairo.balart@metempsy.com } 33013531Sjairo.balart@metempsy.com } 33113531Sjairo.balart@metempsy.com } 33213531Sjairo.balart@metempsy.com 33313531Sjairo.balart@metempsy.com return value; 33413531Sjairo.balart@metempsy.com } 33513531Sjairo.balart@metempsy.com 33613531Sjairo.balart@metempsy.com case GICR_NSACR: { // Non-secure Access Control Register 33713531Sjairo.balart@metempsy.com uint64_t value = 0; 33813531Sjairo.balart@metempsy.com 33913531Sjairo.balart@metempsy.com if (distributor->DS) { 34013531Sjairo.balart@metempsy.com // RAZ/WI 34113531Sjairo.balart@metempsy.com value = 0; 34213531Sjairo.balart@metempsy.com } else { 34313531Sjairo.balart@metempsy.com if (!is_secure_access) { 34413531Sjairo.balart@metempsy.com // RAZ/WI 34513531Sjairo.balart@metempsy.com value = 0; 34613531Sjairo.balart@metempsy.com } else { 34713531Sjairo.balart@metempsy.com for (int i = 0, int_id = 0; i < 8 * size; 34813756Sjairo.balart@metempsy.com i = i + 2, int_id++) { 34913531Sjairo.balart@metempsy.com value |= irqNsacr[int_id] << i; 35013531Sjairo.balart@metempsy.com } 35113531Sjairo.balart@metempsy.com } 35213531Sjairo.balart@metempsy.com } 35313531Sjairo.balart@metempsy.com 35413531Sjairo.balart@metempsy.com return value; 35513531Sjairo.balart@metempsy.com } 35613531Sjairo.balart@metempsy.com 35713690Sjairo.balart@metempsy.com case GICR_PROPBASER: // Redistributor Properties Base Address Register 35813690Sjairo.balart@metempsy.com // OuterCache, bits [58:56] 35913690Sjairo.balart@metempsy.com // 000 Memory type defined in InnerCache field 36013690Sjairo.balart@metempsy.com // Physical_Address, bits [51:12] 36113690Sjairo.balart@metempsy.com // Bits [51:12] of the physical address containing the LPI 36213690Sjairo.balart@metempsy.com // Configuration table 36313690Sjairo.balart@metempsy.com // Shareability, bits [11:10] 36413690Sjairo.balart@metempsy.com // 00 Non-shareable 36513690Sjairo.balart@metempsy.com // InnerCache, bits [9:7] 36613690Sjairo.balart@metempsy.com // 000 Device-nGnRnE 36713690Sjairo.balart@metempsy.com // IDbits, bits [4:0] 36813690Sjairo.balart@metempsy.com // limited by GICD_TYPER.IDbits 36913690Sjairo.balart@metempsy.com return lpiConfigurationTablePtr | lpiIDBits; 37013690Sjairo.balart@metempsy.com 37113690Sjairo.balart@metempsy.com // Redistributor LPI Pending Table Base Address Register 37213690Sjairo.balart@metempsy.com case GICR_PENDBASER: 37313690Sjairo.balart@metempsy.com // PTZ, bit [62] 37413690Sjairo.balart@metempsy.com // Pending Table Zero 37513690Sjairo.balart@metempsy.com // OuterCache, bits [58:56] 37613690Sjairo.balart@metempsy.com // 000 Memory type defined in InnerCache field 37713690Sjairo.balart@metempsy.com // Physical_Address, bits [51:16] 37813690Sjairo.balart@metempsy.com // Bits [51:16] of the physical address containing the LPI Pending 37913690Sjairo.balart@metempsy.com // table 38013690Sjairo.balart@metempsy.com // Shareability, bits [11:10] 38113690Sjairo.balart@metempsy.com // 00 Non-shareable 38213690Sjairo.balart@metempsy.com // InnerCache, bits [9:7] 38313690Sjairo.balart@metempsy.com // 000 Device-nGnRnE 38413690Sjairo.balart@metempsy.com return lpiPendingTablePtr; 38513690Sjairo.balart@metempsy.com 38613690Sjairo.balart@metempsy.com // Redistributor Synchronize Register 38713690Sjairo.balart@metempsy.com case GICR_SYNCR: 38813690Sjairo.balart@metempsy.com return 0; 38913690Sjairo.balart@metempsy.com 39013531Sjairo.balart@metempsy.com default: 39113531Sjairo.balart@metempsy.com panic("Gicv3Redistributor::read(): invalid offset %#x\n", addr); 39213531Sjairo.balart@metempsy.com break; 39313531Sjairo.balart@metempsy.com } 39413531Sjairo.balart@metempsy.com} 39513531Sjairo.balart@metempsy.com 39613531Sjairo.balart@metempsy.comvoid 39713531Sjairo.balart@metempsy.comGicv3Redistributor::write(Addr addr, uint64_t data, size_t size, 39813531Sjairo.balart@metempsy.com bool is_secure_access) 39913531Sjairo.balart@metempsy.com{ 40013531Sjairo.balart@metempsy.com if (GICR_IPRIORITYR.contains(addr)) { // Interrupt Priority Registers 40113531Sjairo.balart@metempsy.com int first_intid = addr - GICR_IPRIORITYR.start(); 40213531Sjairo.balart@metempsy.com 40313531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < size; i++, int_id++) { 40413531Sjairo.balart@metempsy.com uint8_t prio = bits(data, (i + 1) * 8 - 1, (i * 8)); 40513531Sjairo.balart@metempsy.com 40613531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 40713531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 40813531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 40913531Sjairo.balart@metempsy.com continue; 41013531Sjairo.balart@metempsy.com } else { 41113531Sjairo.balart@metempsy.com // NS view 41213531Sjairo.balart@metempsy.com prio = 0x80 | (prio >> 1); 41313531Sjairo.balart@metempsy.com } 41413531Sjairo.balart@metempsy.com } 41513531Sjairo.balart@metempsy.com 41613531Sjairo.balart@metempsy.com irqPriority[int_id] = prio; 41713531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): " 41813531Sjairo.balart@metempsy.com "int_id %d priority %d\n", int_id, irqPriority[int_id]); 41913531Sjairo.balart@metempsy.com } 42013531Sjairo.balart@metempsy.com 42113531Sjairo.balart@metempsy.com return; 42213531Sjairo.balart@metempsy.com } 42313531Sjairo.balart@metempsy.com 42413531Sjairo.balart@metempsy.com switch (addr) { 42513531Sjairo.balart@metempsy.com case GICR_CTLR: { 42613690Sjairo.balart@metempsy.com // GICR_TYPER.LPIS is 0 so EnableLPIs is RES0 42713690Sjairo.balart@metempsy.com EnableLPIs = data & GICR_CTLR_ENABLE_LPIS; 42813531Sjairo.balart@metempsy.com DPG1S = data & GICR_CTLR_DPG1S; 42913531Sjairo.balart@metempsy.com DPG1NS = data & GICR_CTLR_DPG1NS; 43013531Sjairo.balart@metempsy.com DPG0 = data & GICR_CTLR_DPG0; 43113531Sjairo.balart@metempsy.com break; 43213531Sjairo.balart@metempsy.com } 43313531Sjairo.balart@metempsy.com 43413531Sjairo.balart@metempsy.com case GICR_WAKER: // Wake Register 43513531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 43613531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 43713531Sjairo.balart@metempsy.com return; 43813531Sjairo.balart@metempsy.com } 43913531Sjairo.balart@metempsy.com 44013531Sjairo.balart@metempsy.com if (not peInLowPowerState and 44113756Sjairo.balart@metempsy.com (data & GICR_WAKER_ProcessorSleep)) { 44213531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): " 44313531Sjairo.balart@metempsy.com "PE entering in low power state\n"); 44413531Sjairo.balart@metempsy.com } else if (peInLowPowerState and 44513756Sjairo.balart@metempsy.com not(data & GICR_WAKER_ProcessorSleep)) { 44613531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): powering up PE\n"); 44713531Sjairo.balart@metempsy.com } 44813531Sjairo.balart@metempsy.com 44913531Sjairo.balart@metempsy.com peInLowPowerState = data & GICR_WAKER_ProcessorSleep; 45013531Sjairo.balart@metempsy.com break; 45113531Sjairo.balart@metempsy.com 45213531Sjairo.balart@metempsy.com case GICR_IGROUPR0: // Interrupt Group Register 0 45313531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 45413531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 45513531Sjairo.balart@metempsy.com return; 45613531Sjairo.balart@metempsy.com } 45713531Sjairo.balart@metempsy.com 45813531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 45913531Sjairo.balart@metempsy.com irqGroup[int_id] = data & (1 << int_id) ? 1 : 0; 46013531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): " 46113531Sjairo.balart@metempsy.com "int_id %d group %d\n", int_id, irqGroup[int_id]); 46213531Sjairo.balart@metempsy.com } 46313531Sjairo.balart@metempsy.com 46413531Sjairo.balart@metempsy.com break; 46513531Sjairo.balart@metempsy.com 46613531Sjairo.balart@metempsy.com case GICR_ISENABLER0: // Interrupt Set-Enable Register 0 46713531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 46813531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 46913531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 47013531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 47113531Sjairo.balart@metempsy.com continue; 47213531Sjairo.balart@metempsy.com } 47313531Sjairo.balart@metempsy.com } 47413531Sjairo.balart@metempsy.com 47513531Sjairo.balart@metempsy.com bool enable = data & (1 << int_id) ? 1 : 0; 47613531Sjairo.balart@metempsy.com 47713531Sjairo.balart@metempsy.com if (enable) { 47813531Sjairo.balart@metempsy.com irqEnabled[int_id] = true; 47913531Sjairo.balart@metempsy.com } 48013531Sjairo.balart@metempsy.com 48113531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): " 48213531Sjairo.balart@metempsy.com "int_id %d enable %i\n", int_id, irqEnabled[int_id]); 48313531Sjairo.balart@metempsy.com } 48413531Sjairo.balart@metempsy.com 48513531Sjairo.balart@metempsy.com break; 48613531Sjairo.balart@metempsy.com 48713531Sjairo.balart@metempsy.com case GICR_ICENABLER0: // Interrupt Clear-Enable Register 0 48813531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 48913531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 49013531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 49113531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 49213531Sjairo.balart@metempsy.com continue; 49313531Sjairo.balart@metempsy.com } 49413531Sjairo.balart@metempsy.com } 49513531Sjairo.balart@metempsy.com 49613531Sjairo.balart@metempsy.com bool disable = data & (1 << int_id) ? 1 : 0; 49713531Sjairo.balart@metempsy.com 49813531Sjairo.balart@metempsy.com if (disable) { 49913531Sjairo.balart@metempsy.com irqEnabled[int_id] = false; 50013531Sjairo.balart@metempsy.com } 50113531Sjairo.balart@metempsy.com 50213531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): " 50313531Sjairo.balart@metempsy.com "int_id %d enable %i\n", int_id, irqEnabled[int_id]); 50413531Sjairo.balart@metempsy.com } 50513531Sjairo.balart@metempsy.com 50613531Sjairo.balart@metempsy.com break; 50713531Sjairo.balart@metempsy.com 50813531Sjairo.balart@metempsy.com case GICR_ISPENDR0: // Interrupt Set-Pending Register 0 50913531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 51013531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 51113531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 51213531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 51313531Sjairo.balart@metempsy.com continue; 51413531Sjairo.balart@metempsy.com } 51513531Sjairo.balart@metempsy.com } 51613531Sjairo.balart@metempsy.com 51713531Sjairo.balart@metempsy.com bool pending = data & (1 << int_id) ? 1 : 0; 51813531Sjairo.balart@metempsy.com 51913531Sjairo.balart@metempsy.com if (pending) { 52013531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write() " 52113531Sjairo.balart@metempsy.com "(GICR_ISPENDR0): int_id %d (PPI) " 52213531Sjairo.balart@metempsy.com "pending bit set\n", int_id); 52313531Sjairo.balart@metempsy.com irqPending[int_id] = true; 52413531Sjairo.balart@metempsy.com } 52513531Sjairo.balart@metempsy.com } 52613531Sjairo.balart@metempsy.com 52713531Sjairo.balart@metempsy.com updateAndInformCPUInterface(); 52813531Sjairo.balart@metempsy.com break; 52913531Sjairo.balart@metempsy.com 53013531Sjairo.balart@metempsy.com case GICR_ICPENDR0:// Interrupt Clear-Pending Register 0 53113531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 53213531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 53313531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 53413531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 53513531Sjairo.balart@metempsy.com continue; 53613531Sjairo.balart@metempsy.com } 53713531Sjairo.balart@metempsy.com } 53813531Sjairo.balart@metempsy.com 53913531Sjairo.balart@metempsy.com bool clear = data & (1 << int_id) ? 1 : 0; 54013531Sjairo.balart@metempsy.com 54113531Sjairo.balart@metempsy.com if (clear) { 54213531Sjairo.balart@metempsy.com irqPending[int_id] = false; 54313531Sjairo.balart@metempsy.com } 54413531Sjairo.balart@metempsy.com } 54513531Sjairo.balart@metempsy.com 54613531Sjairo.balart@metempsy.com break; 54713531Sjairo.balart@metempsy.com 54813531Sjairo.balart@metempsy.com case GICR_ISACTIVER0: // Interrupt Set-Active Register 0 54913531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 55013531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 55113531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 55213531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 55313531Sjairo.balart@metempsy.com continue; 55413531Sjairo.balart@metempsy.com } 55513531Sjairo.balart@metempsy.com } 55613531Sjairo.balart@metempsy.com 55713531Sjairo.balart@metempsy.com bool activate = data & (1 << int_id) ? 1 : 0; 55813531Sjairo.balart@metempsy.com 55913531Sjairo.balart@metempsy.com if (activate) { 56013531Sjairo.balart@metempsy.com if (!irqActive[int_id]) { 56113531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): " 56213531Sjairo.balart@metempsy.com "int_id %d active set\n", int_id); 56313531Sjairo.balart@metempsy.com } 56413531Sjairo.balart@metempsy.com 56513531Sjairo.balart@metempsy.com irqActive[int_id] = true; 56613531Sjairo.balart@metempsy.com } 56713531Sjairo.balart@metempsy.com } 56813531Sjairo.balart@metempsy.com 56913531Sjairo.balart@metempsy.com break; 57013531Sjairo.balart@metempsy.com 57113531Sjairo.balart@metempsy.com case GICR_ICACTIVER0: // Interrupt Clear-Active Register 0 57213531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 57313531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 57413531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 57513531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 57613531Sjairo.balart@metempsy.com continue; 57713531Sjairo.balart@metempsy.com } 57813531Sjairo.balart@metempsy.com } 57913531Sjairo.balart@metempsy.com 58013531Sjairo.balart@metempsy.com bool clear = data & (1 << int_id) ? 1 : 0; 58113531Sjairo.balart@metempsy.com 58213531Sjairo.balart@metempsy.com if (clear) { 58313531Sjairo.balart@metempsy.com if (irqActive[int_id]) { 58413531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): " 58513531Sjairo.balart@metempsy.com "int_id %d active cleared\n", int_id); 58613531Sjairo.balart@metempsy.com } 58713531Sjairo.balart@metempsy.com 58813531Sjairo.balart@metempsy.com irqActive[int_id] = false; 58913531Sjairo.balart@metempsy.com } 59013531Sjairo.balart@metempsy.com } 59113531Sjairo.balart@metempsy.com 59213531Sjairo.balart@metempsy.com break; 59313531Sjairo.balart@metempsy.com 59413531Sjairo.balart@metempsy.com case GICR_ICFGR1: { // PPI Configuration Register 59513531Sjairo.balart@metempsy.com int first_intid = Gicv3::SGI_MAX; 59613531Sjairo.balart@metempsy.com 59713531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size; 59813756Sjairo.balart@metempsy.com i = i + 2, int_id++) { 59913531Sjairo.balart@metempsy.com if (!distributor->DS && !is_secure_access) { 60013531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 60113531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 60213531Sjairo.balart@metempsy.com continue; 60313531Sjairo.balart@metempsy.com } 60413531Sjairo.balart@metempsy.com } 60513531Sjairo.balart@metempsy.com 60613756Sjairo.balart@metempsy.com irqConfig[int_id] = data & (0x2 << i) ? 60713756Sjairo.balart@metempsy.com Gicv3::INT_EDGE_TRIGGERED : 60813756Sjairo.balart@metempsy.com Gicv3::INT_LEVEL_SENSITIVE; 60913531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::write(): " 61013531Sjairo.balart@metempsy.com "int_id %d (PPI) config %d\n", 61113531Sjairo.balart@metempsy.com int_id, irqConfig[int_id]); 61213531Sjairo.balart@metempsy.com } 61313531Sjairo.balart@metempsy.com 61413531Sjairo.balart@metempsy.com break; 61513531Sjairo.balart@metempsy.com } 61613531Sjairo.balart@metempsy.com 61713531Sjairo.balart@metempsy.com case GICR_IGRPMODR0: { // Interrupt Group Modifier Register 0 61813531Sjairo.balart@metempsy.com if (distributor->DS) { 61913531Sjairo.balart@metempsy.com // RAZ/WI if secutiry disabled 62013531Sjairo.balart@metempsy.com } else { 62113531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < 8 * size; int_id++) { 62213531Sjairo.balart@metempsy.com if (!is_secure_access) { 62313531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 62413531Sjairo.balart@metempsy.com continue; 62513531Sjairo.balart@metempsy.com } 62613531Sjairo.balart@metempsy.com 62713531Sjairo.balart@metempsy.com irqGrpmod[int_id] = data & (1 << int_id); 62813531Sjairo.balart@metempsy.com } 62913531Sjairo.balart@metempsy.com } 63013531Sjairo.balart@metempsy.com 63113531Sjairo.balart@metempsy.com break; 63213531Sjairo.balart@metempsy.com } 63313531Sjairo.balart@metempsy.com 63413531Sjairo.balart@metempsy.com case GICR_NSACR: { // Non-secure Access Control Register 63513531Sjairo.balart@metempsy.com if (distributor->DS) { 63613531Sjairo.balart@metempsy.com // RAZ/WI 63713531Sjairo.balart@metempsy.com } else { 63813531Sjairo.balart@metempsy.com if (!is_secure_access) { 63913531Sjairo.balart@metempsy.com // RAZ/WI 64013531Sjairo.balart@metempsy.com } else { 64113531Sjairo.balart@metempsy.com for (int i = 0, int_id = 0; i < 8 * size; 64213756Sjairo.balart@metempsy.com i = i + 2, int_id++) { 64313531Sjairo.balart@metempsy.com irqNsacr[int_id] = (data >> i) & 0x3; 64413531Sjairo.balart@metempsy.com } 64513531Sjairo.balart@metempsy.com } 64613531Sjairo.balart@metempsy.com } 64713531Sjairo.balart@metempsy.com 64813531Sjairo.balart@metempsy.com break; 64913531Sjairo.balart@metempsy.com } 65013531Sjairo.balart@metempsy.com 65113690Sjairo.balart@metempsy.com case GICR_SETLPIR: // Set LPI Pending Register 65213690Sjairo.balart@metempsy.com setClrLPI(data, true); 65313690Sjairo.balart@metempsy.com break; 65413690Sjairo.balart@metempsy.com 65513690Sjairo.balart@metempsy.com case GICR_CLRLPIR: // Clear LPI Pending Register 65613690Sjairo.balart@metempsy.com setClrLPI(data, false); 65713690Sjairo.balart@metempsy.com break; 65813690Sjairo.balart@metempsy.com 65913690Sjairo.balart@metempsy.com case GICR_PROPBASER: { // Redistributor Properties Base Address Register 66013690Sjairo.balart@metempsy.com // OuterCache, bits [58:56] 66113690Sjairo.balart@metempsy.com // 000 Memory type defined in InnerCache field 66213690Sjairo.balart@metempsy.com // Physical_Address, bits [51:12] 66313690Sjairo.balart@metempsy.com // Bits [51:12] of the physical address containing the LPI 66413690Sjairo.balart@metempsy.com // Configuration table 66513690Sjairo.balart@metempsy.com // Shareability, bits [11:10] 66613690Sjairo.balart@metempsy.com // 00 Non-shareable 66713690Sjairo.balart@metempsy.com // InnerCache, bits [9:7] 66813690Sjairo.balart@metempsy.com // 000 Device-nGnRnE 66913690Sjairo.balart@metempsy.com // IDbits, bits [4:0] 67013690Sjairo.balart@metempsy.com // limited by GICD_TYPER.IDbits (= 0xf) 67113690Sjairo.balart@metempsy.com lpiConfigurationTablePtr = data & 0xFFFFFFFFFF000; 67213690Sjairo.balart@metempsy.com lpiIDBits = data & 0x1f; 67313690Sjairo.balart@metempsy.com 67413690Sjairo.balart@metempsy.com // 0xf here matches the value of GICD_TYPER.IDbits. 67513690Sjairo.balart@metempsy.com // TODO - make GICD_TYPER.IDbits a parameter instead of a hardcoded 67613690Sjairo.balart@metempsy.com // value 67713690Sjairo.balart@metempsy.com if (lpiIDBits > 0xf) { 67813690Sjairo.balart@metempsy.com lpiIDBits = 0xf; 67913690Sjairo.balart@metempsy.com } 68013690Sjairo.balart@metempsy.com 68113690Sjairo.balart@metempsy.com break; 68213690Sjairo.balart@metempsy.com } 68313690Sjairo.balart@metempsy.com 68413690Sjairo.balart@metempsy.com // Redistributor LPI Pending Table Base Address Register 68513690Sjairo.balart@metempsy.com case GICR_PENDBASER: 68613690Sjairo.balart@metempsy.com // PTZ, bit [62] 68713690Sjairo.balart@metempsy.com // Pending Table Zero 68813690Sjairo.balart@metempsy.com // OuterCache, bits [58:56] 68913690Sjairo.balart@metempsy.com // 000 Memory type defined in InnerCache field 69013690Sjairo.balart@metempsy.com // Physical_Address, bits [51:16] 69113690Sjairo.balart@metempsy.com // Bits [51:16] of the physical address containing the LPI Pending 69213690Sjairo.balart@metempsy.com // table 69313690Sjairo.balart@metempsy.com // Shareability, bits [11:10] 69413690Sjairo.balart@metempsy.com // 00 Non-shareable 69513690Sjairo.balart@metempsy.com // InnerCache, bits [9:7] 69613690Sjairo.balart@metempsy.com // 000 Device-nGnRnE 69713690Sjairo.balart@metempsy.com lpiPendingTablePtr = data & 0xFFFFFFFFF0000; 69813690Sjairo.balart@metempsy.com break; 69913690Sjairo.balart@metempsy.com 70013690Sjairo.balart@metempsy.com case GICR_INVLPIR: { // Redistributor Invalidate LPI Register 70113921Sgiacomo.travaglini@arm.com // Do nothing: no caching supported 70213690Sjairo.balart@metempsy.com break; 70313690Sjairo.balart@metempsy.com } 70413690Sjairo.balart@metempsy.com 70513690Sjairo.balart@metempsy.com case GICR_INVALLR: { // Redistributor Invalidate All Register 70613921Sgiacomo.travaglini@arm.com // Do nothing: no caching supported 70713690Sjairo.balart@metempsy.com break; 70813690Sjairo.balart@metempsy.com } 70913690Sjairo.balart@metempsy.com 71013531Sjairo.balart@metempsy.com default: 71113531Sjairo.balart@metempsy.com panic("Gicv3Redistributor::write(): invalid offset %#x\n", addr); 71213531Sjairo.balart@metempsy.com break; 71313531Sjairo.balart@metempsy.com } 71413531Sjairo.balart@metempsy.com} 71513531Sjairo.balart@metempsy.com 71613531Sjairo.balart@metempsy.comvoid 71713531Sjairo.balart@metempsy.comGicv3Redistributor::sendPPInt(uint32_t int_id) 71813531Sjairo.balart@metempsy.com{ 71913531Sjairo.balart@metempsy.com assert((int_id >= Gicv3::SGI_MAX) && 72013531Sjairo.balart@metempsy.com (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX)); 72113531Sjairo.balart@metempsy.com irqPending[int_id] = true; 72213531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Redistributor::sendPPInt(): " 72313531Sjairo.balart@metempsy.com "int_id %d (PPI) pending bit set\n", int_id); 72413531Sjairo.balart@metempsy.com updateAndInformCPUInterface(); 72513531Sjairo.balart@metempsy.com} 72613531Sjairo.balart@metempsy.com 72713531Sjairo.balart@metempsy.comvoid 72813531Sjairo.balart@metempsy.comGicv3Redistributor::sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns) 72913531Sjairo.balart@metempsy.com{ 73013531Sjairo.balart@metempsy.com assert(int_id < Gicv3::SGI_MAX); 73113531Sjairo.balart@metempsy.com Gicv3::GroupId int_group = getIntGroup(int_id); 73213531Sjairo.balart@metempsy.com 73313531Sjairo.balart@metempsy.com // asked for secure group 1 73413531Sjairo.balart@metempsy.com // configured as group 0 73513531Sjairo.balart@metempsy.com // send group 0 73613531Sjairo.balart@metempsy.com if (int_group == Gicv3::G0S && group == Gicv3::G1S) { 73713531Sjairo.balart@metempsy.com group = Gicv3::G0S; 73813531Sjairo.balart@metempsy.com } 73913531Sjairo.balart@metempsy.com 74013531Sjairo.balart@metempsy.com if (group == Gicv3::G0S and int_group != Gicv3::G0S) { 74113531Sjairo.balart@metempsy.com return; 74213531Sjairo.balart@metempsy.com } 74313531Sjairo.balart@metempsy.com 74413531Sjairo.balart@metempsy.com if (ns && distributor->DS == 0) { 74513531Sjairo.balart@metempsy.com int nsaccess = irqNsacr[int_id]; 74613531Sjairo.balart@metempsy.com 74713531Sjairo.balart@metempsy.com if ((int_group == Gicv3::G0S && nsaccess < 1) || 74813756Sjairo.balart@metempsy.com (int_group == Gicv3::G1S && nsaccess < 2)) { 74913531Sjairo.balart@metempsy.com return; 75013531Sjairo.balart@metempsy.com } 75113531Sjairo.balart@metempsy.com } 75213531Sjairo.balart@metempsy.com 75313531Sjairo.balart@metempsy.com irqPending[int_id] = true; 75413531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3ReDistributor::sendSGI(): " 75513531Sjairo.balart@metempsy.com "int_id %d (SGI) pending bit set\n", int_id); 75613531Sjairo.balart@metempsy.com updateAndInformCPUInterface(); 75713531Sjairo.balart@metempsy.com} 75813531Sjairo.balart@metempsy.com 75913531Sjairo.balart@metempsy.comGicv3::IntStatus 76013756Sjairo.balart@metempsy.comGicv3Redistributor::intStatus(uint32_t int_id) const 76113531Sjairo.balart@metempsy.com{ 76213531Sjairo.balart@metempsy.com assert(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX); 76313531Sjairo.balart@metempsy.com 76413531Sjairo.balart@metempsy.com if (irqPending[int_id]) { 76513531Sjairo.balart@metempsy.com if (irqActive[int_id]) { 76613531Sjairo.balart@metempsy.com return Gicv3::INT_ACTIVE_PENDING; 76713531Sjairo.balart@metempsy.com } 76813531Sjairo.balart@metempsy.com 76913531Sjairo.balart@metempsy.com return Gicv3::INT_PENDING; 77013531Sjairo.balart@metempsy.com } else if (irqActive[int_id]) { 77113531Sjairo.balart@metempsy.com return Gicv3::INT_ACTIVE; 77213531Sjairo.balart@metempsy.com } else { 77313531Sjairo.balart@metempsy.com return Gicv3::INT_INACTIVE; 77413531Sjairo.balart@metempsy.com } 77513531Sjairo.balart@metempsy.com} 77613531Sjairo.balart@metempsy.com 77713531Sjairo.balart@metempsy.com/* 77813531Sjairo.balart@metempsy.com * Recalculate the highest priority pending interrupt after a 77913531Sjairo.balart@metempsy.com * change to redistributor state. 78013531Sjairo.balart@metempsy.com */ 78113531Sjairo.balart@metempsy.comvoid 78213531Sjairo.balart@metempsy.comGicv3Redistributor::update() 78313531Sjairo.balart@metempsy.com{ 78413531Sjairo.balart@metempsy.com bool new_hppi = false; 78513531Sjairo.balart@metempsy.com 78613531Sjairo.balart@metempsy.com for (int int_id = 0; int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id++) { 78713531Sjairo.balart@metempsy.com Gicv3::GroupId int_group = getIntGroup(int_id); 78813531Sjairo.balart@metempsy.com bool group_enabled = distributor->groupEnabled(int_group); 78913531Sjairo.balart@metempsy.com 79013531Sjairo.balart@metempsy.com if (irqPending[int_id] && irqEnabled[int_id] && 79113531Sjairo.balart@metempsy.com !irqActive[int_id] && group_enabled) { 79213531Sjairo.balart@metempsy.com if ((irqPriority[int_id] < cpuInterface->hppi.prio) || 79313756Sjairo.balart@metempsy.com /* 79413756Sjairo.balart@metempsy.com * Multiple pending ints with same priority. 79513756Sjairo.balart@metempsy.com * Implementation choice which one to signal. 79613756Sjairo.balart@metempsy.com * Our implementation selects the one with the lower id. 79713756Sjairo.balart@metempsy.com */ 79813756Sjairo.balart@metempsy.com (irqPriority[int_id] == cpuInterface->hppi.prio && 79913756Sjairo.balart@metempsy.com int_id < cpuInterface->hppi.intid)) { 80013531Sjairo.balart@metempsy.com cpuInterface->hppi.intid = int_id; 80113531Sjairo.balart@metempsy.com cpuInterface->hppi.prio = irqPriority[int_id]; 80213531Sjairo.balart@metempsy.com cpuInterface->hppi.group = int_group; 80313531Sjairo.balart@metempsy.com new_hppi = true; 80413531Sjairo.balart@metempsy.com } 80513531Sjairo.balart@metempsy.com } 80613531Sjairo.balart@metempsy.com } 80713531Sjairo.balart@metempsy.com 80813690Sjairo.balart@metempsy.com // Check LPIs 80913920Sgiacomo.travaglini@arm.com if (EnableLPIs) { 81013921Sgiacomo.travaglini@arm.com 81113920Sgiacomo.travaglini@arm.com const uint32_t largest_lpi_id = 1 << (lpiIDBits + 1); 81213921Sgiacomo.travaglini@arm.com const uint32_t number_lpis = largest_lpi_id - SMALLEST_LPI_ID + 1; 81313921Sgiacomo.travaglini@arm.com 81413921Sgiacomo.travaglini@arm.com uint8_t lpi_pending_table[largest_lpi_id / 8]; 81513921Sgiacomo.travaglini@arm.com uint8_t lpi_config_table[number_lpis]; 81613921Sgiacomo.travaglini@arm.com 81713928Sgiacomo.travaglini@arm.com memProxy->readBlob(lpiPendingTablePtr, 81813928Sgiacomo.travaglini@arm.com (uint8_t *) lpi_pending_table, 81913928Sgiacomo.travaglini@arm.com sizeof(lpi_pending_table)); 82013919Sgiacomo.travaglini@arm.com 82113928Sgiacomo.travaglini@arm.com memProxy->readBlob(lpiConfigurationTablePtr, 82213928Sgiacomo.travaglini@arm.com (uint8_t*) lpi_config_table, 82313928Sgiacomo.travaglini@arm.com sizeof(lpi_config_table)); 82413921Sgiacomo.travaglini@arm.com 82513920Sgiacomo.travaglini@arm.com for (int lpi_id = SMALLEST_LPI_ID; lpi_id < largest_lpi_id; 82613920Sgiacomo.travaglini@arm.com lpi_id++) { 82713920Sgiacomo.travaglini@arm.com uint32_t lpi_pending_entry_byte = lpi_id / 8; 82813920Sgiacomo.travaglini@arm.com uint8_t lpi_pending_entry_bit_position = lpi_id % 8; 82913920Sgiacomo.travaglini@arm.com bool lpi_is_pending = lpi_pending_table[lpi_pending_entry_byte] & 83013920Sgiacomo.travaglini@arm.com 1 << lpi_pending_entry_bit_position; 83113920Sgiacomo.travaglini@arm.com uint32_t lpi_configuration_entry_index = lpi_id - SMALLEST_LPI_ID; 83213921Sgiacomo.travaglini@arm.com 83313921Sgiacomo.travaglini@arm.com LPIConfigurationTableEntry config_entry = 83413921Sgiacomo.travaglini@arm.com lpi_config_table[lpi_configuration_entry_index]; 83513921Sgiacomo.travaglini@arm.com 83613921Sgiacomo.travaglini@arm.com bool lpi_is_enable = config_entry.enable; 83713921Sgiacomo.travaglini@arm.com 83813920Sgiacomo.travaglini@arm.com // LPIs are always Non-secure Group 1 interrupts, 83913920Sgiacomo.travaglini@arm.com // in a system where two Security states are enabled. 84013920Sgiacomo.travaglini@arm.com Gicv3::GroupId lpi_group = Gicv3::G1NS; 84113920Sgiacomo.travaglini@arm.com bool group_enabled = distributor->groupEnabled(lpi_group); 84213690Sjairo.balart@metempsy.com 84313920Sgiacomo.travaglini@arm.com if (lpi_is_pending && lpi_is_enable && group_enabled) { 84413922Sgiacomo.travaglini@arm.com uint8_t lpi_priority = config_entry.priority << 2; 84513690Sjairo.balart@metempsy.com 84613920Sgiacomo.travaglini@arm.com if ((lpi_priority < cpuInterface->hppi.prio) || 84713920Sgiacomo.travaglini@arm.com (lpi_priority == cpuInterface->hppi.prio && 84813920Sgiacomo.travaglini@arm.com lpi_id < cpuInterface->hppi.intid)) { 84913920Sgiacomo.travaglini@arm.com cpuInterface->hppi.intid = lpi_id; 85013920Sgiacomo.travaglini@arm.com cpuInterface->hppi.prio = lpi_priority; 85113920Sgiacomo.travaglini@arm.com cpuInterface->hppi.group = lpi_group; 85213920Sgiacomo.travaglini@arm.com new_hppi = true; 85313920Sgiacomo.travaglini@arm.com } 85413690Sjairo.balart@metempsy.com } 85513690Sjairo.balart@metempsy.com } 85613690Sjairo.balart@metempsy.com } 85713690Sjairo.balart@metempsy.com 85813531Sjairo.balart@metempsy.com if (!new_hppi && cpuInterface->hppi.prio != 0xff && 85913923Sgiacomo.travaglini@arm.com (cpuInterface->hppi.intid < Gicv3::SGI_MAX + Gicv3::PPI_MAX || 86013923Sgiacomo.travaglini@arm.com cpuInterface->hppi.intid > SMALLEST_LPI_ID)) { 86113531Sjairo.balart@metempsy.com distributor->fullUpdate(); 86213531Sjairo.balart@metempsy.com } 86313531Sjairo.balart@metempsy.com} 86413531Sjairo.balart@metempsy.com 86513924Sgiacomo.travaglini@arm.comuint8_t 86613924Sgiacomo.travaglini@arm.comGicv3Redistributor::readEntryLPI(uint32_t lpi_id) 86713924Sgiacomo.travaglini@arm.com{ 86813924Sgiacomo.travaglini@arm.com Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8); 86913924Sgiacomo.travaglini@arm.com 87013924Sgiacomo.travaglini@arm.com uint8_t lpi_pending_entry; 87113928Sgiacomo.travaglini@arm.com memProxy->readBlob(lpi_pending_entry_ptr, 87213928Sgiacomo.travaglini@arm.com (uint8_t*) &lpi_pending_entry, 87313928Sgiacomo.travaglini@arm.com sizeof(lpi_pending_entry)); 87413924Sgiacomo.travaglini@arm.com 87513924Sgiacomo.travaglini@arm.com return lpi_pending_entry; 87613924Sgiacomo.travaglini@arm.com} 87713924Sgiacomo.travaglini@arm.com 87813924Sgiacomo.travaglini@arm.comvoid 87913924Sgiacomo.travaglini@arm.comGicv3Redistributor::writeEntryLPI(uint32_t lpi_id, uint8_t lpi_pending_entry) 88013924Sgiacomo.travaglini@arm.com{ 88113924Sgiacomo.travaglini@arm.com Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8); 88213924Sgiacomo.travaglini@arm.com 88313928Sgiacomo.travaglini@arm.com memProxy->writeBlob(lpi_pending_entry_ptr, 88413928Sgiacomo.travaglini@arm.com (uint8_t*) &lpi_pending_entry, 88513928Sgiacomo.travaglini@arm.com sizeof(lpi_pending_entry)); 88613924Sgiacomo.travaglini@arm.com} 88713924Sgiacomo.travaglini@arm.com 88813924Sgiacomo.travaglini@arm.combool 88913924Sgiacomo.travaglini@arm.comGicv3Redistributor::isPendingLPI(uint32_t lpi_id) 89013924Sgiacomo.travaglini@arm.com{ 89113924Sgiacomo.travaglini@arm.com // Fetch the LPI pending entry from memory 89213924Sgiacomo.travaglini@arm.com uint8_t lpi_pending_entry = readEntryLPI(lpi_id); 89313924Sgiacomo.travaglini@arm.com 89413924Sgiacomo.travaglini@arm.com uint8_t lpi_pending_entry_bit_position = lpi_id % 8; 89513924Sgiacomo.travaglini@arm.com bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position); 89613924Sgiacomo.travaglini@arm.com 89713924Sgiacomo.travaglini@arm.com return is_set; 89813924Sgiacomo.travaglini@arm.com} 89913924Sgiacomo.travaglini@arm.com 90013531Sjairo.balart@metempsy.comvoid 90113690Sjairo.balart@metempsy.comGicv3Redistributor::setClrLPI(uint64_t data, bool set) 90213690Sjairo.balart@metempsy.com{ 90313690Sjairo.balart@metempsy.com if (!EnableLPIs) { 90413690Sjairo.balart@metempsy.com // Writes to GICR_SETLPIR or GICR_CLRLPIR have not effect if 90513690Sjairo.balart@metempsy.com // GICR_CTLR.EnableLPIs == 0. 90613690Sjairo.balart@metempsy.com return; 90713690Sjairo.balart@metempsy.com } 90813690Sjairo.balart@metempsy.com 90913690Sjairo.balart@metempsy.com uint32_t lpi_id = data & 0xffffffff; 91013917Sgiacomo.travaglini@arm.com uint32_t largest_lpi_id = 1 << (lpiIDBits + 1); 91113690Sjairo.balart@metempsy.com 91213690Sjairo.balart@metempsy.com if (lpi_id > largest_lpi_id) { 91313690Sjairo.balart@metempsy.com // Writes to GICR_SETLPIR or GICR_CLRLPIR have not effect if 91413690Sjairo.balart@metempsy.com // pINTID value specifies an unimplemented LPI. 91513690Sjairo.balart@metempsy.com return; 91613690Sjairo.balart@metempsy.com } 91713690Sjairo.balart@metempsy.com 91813924Sgiacomo.travaglini@arm.com // Fetch the LPI pending entry from memory 91913924Sgiacomo.travaglini@arm.com uint8_t lpi_pending_entry = readEntryLPI(lpi_id); 92013924Sgiacomo.travaglini@arm.com 92113690Sjairo.balart@metempsy.com uint8_t lpi_pending_entry_bit_position = lpi_id % 8; 92213690Sjairo.balart@metempsy.com bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position); 92313690Sjairo.balart@metempsy.com 92413690Sjairo.balart@metempsy.com if (set) { 92513690Sjairo.balart@metempsy.com if (is_set) { 92613690Sjairo.balart@metempsy.com // Writes to GICR_SETLPIR have not effect if the pINTID field 92713690Sjairo.balart@metempsy.com // corresponds to an LPI that is already pending. 92813690Sjairo.balart@metempsy.com return; 92913690Sjairo.balart@metempsy.com } 93013690Sjairo.balart@metempsy.com 93113690Sjairo.balart@metempsy.com lpi_pending_entry |= 1 << (lpi_pending_entry_bit_position); 93213690Sjairo.balart@metempsy.com } else { 93313690Sjairo.balart@metempsy.com if (!is_set) { 93413690Sjairo.balart@metempsy.com // Writes to GICR_SETLPIR have not effect if the pINTID field 93513690Sjairo.balart@metempsy.com // corresponds to an LPI that is not pending. 93613690Sjairo.balart@metempsy.com return; 93713690Sjairo.balart@metempsy.com } 93813690Sjairo.balart@metempsy.com 93913690Sjairo.balart@metempsy.com lpi_pending_entry &= ~(1 << (lpi_pending_entry_bit_position)); 94013690Sjairo.balart@metempsy.com } 94113690Sjairo.balart@metempsy.com 94213924Sgiacomo.travaglini@arm.com writeEntryLPI(lpi_id, lpi_pending_entry); 94313924Sgiacomo.travaglini@arm.com 94413690Sjairo.balart@metempsy.com updateAndInformCPUInterface(); 94513690Sjairo.balart@metempsy.com} 94613690Sjairo.balart@metempsy.com 94713690Sjairo.balart@metempsy.comvoid 94813531Sjairo.balart@metempsy.comGicv3Redistributor::updateAndInformCPUInterface() 94913531Sjairo.balart@metempsy.com{ 95013531Sjairo.balart@metempsy.com update(); 95113531Sjairo.balart@metempsy.com cpuInterface->update(); 95213531Sjairo.balart@metempsy.com} 95313531Sjairo.balart@metempsy.com 95413531Sjairo.balart@metempsy.comGicv3::GroupId 95513756Sjairo.balart@metempsy.comGicv3Redistributor::getIntGroup(int int_id) const 95613531Sjairo.balart@metempsy.com{ 95713531Sjairo.balart@metempsy.com assert(int_id < (Gicv3::SGI_MAX + Gicv3::PPI_MAX)); 95813531Sjairo.balart@metempsy.com 95913531Sjairo.balart@metempsy.com if (distributor->DS) { 96013531Sjairo.balart@metempsy.com if (irqGroup[int_id] == 0) { 96113531Sjairo.balart@metempsy.com return Gicv3::G0S; 96213531Sjairo.balart@metempsy.com } else { 96313531Sjairo.balart@metempsy.com return Gicv3::G1NS; 96413531Sjairo.balart@metempsy.com } 96513531Sjairo.balart@metempsy.com } else { 96613531Sjairo.balart@metempsy.com if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 0) { 96713531Sjairo.balart@metempsy.com return Gicv3::G0S; 96813531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 1) { 96913531Sjairo.balart@metempsy.com return Gicv3::G1NS; 97013531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 0) { 97113531Sjairo.balart@metempsy.com return Gicv3::G1S; 97213531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 1) { 97313531Sjairo.balart@metempsy.com return Gicv3::G1NS; 97413531Sjairo.balart@metempsy.com } 97513531Sjairo.balart@metempsy.com } 97613531Sjairo.balart@metempsy.com 97713531Sjairo.balart@metempsy.com M5_UNREACHABLE; 97813531Sjairo.balart@metempsy.com} 97913531Sjairo.balart@metempsy.com 98013531Sjairo.balart@metempsy.comvoid 98113531Sjairo.balart@metempsy.comGicv3Redistributor::activateIRQ(uint32_t int_id) 98213531Sjairo.balart@metempsy.com{ 98313531Sjairo.balart@metempsy.com irqPending[int_id] = false; 98413531Sjairo.balart@metempsy.com irqActive[int_id] = true; 98513531Sjairo.balart@metempsy.com} 98613531Sjairo.balart@metempsy.com 98713531Sjairo.balart@metempsy.comvoid 98813531Sjairo.balart@metempsy.comGicv3Redistributor::deactivateIRQ(uint32_t int_id) 98913531Sjairo.balart@metempsy.com{ 99013531Sjairo.balart@metempsy.com irqActive[int_id] = false; 99113531Sjairo.balart@metempsy.com} 99213531Sjairo.balart@metempsy.com 99313531Sjairo.balart@metempsy.comuint32_t 99413756Sjairo.balart@metempsy.comGicv3Redistributor::getAffinity() const 99513531Sjairo.balart@metempsy.com{ 99613531Sjairo.balart@metempsy.com ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId); 99713531Sjairo.balart@metempsy.com uint64_t mpidr = getMPIDR(gic->getSystem(), tc); 99813531Sjairo.balart@metempsy.com /* 99913531Sjairo.balart@metempsy.com * Aff3 = MPIDR[39:32] 100013531Sjairo.balart@metempsy.com * (Note getMPIDR() returns uint32_t so Aff3 is always 0...) 100113531Sjairo.balart@metempsy.com * Aff2 = MPIDR[23:16] 100213531Sjairo.balart@metempsy.com * Aff1 = MPIDR[15:8] 100313531Sjairo.balart@metempsy.com * Aff0 = MPIDR[7:0] 100413531Sjairo.balart@metempsy.com * affinity = Aff3.Aff2.Aff1.Aff0 100513531Sjairo.balart@metempsy.com */ 100613531Sjairo.balart@metempsy.com uint64_t affinity = ((mpidr & 0xff00000000) >> 8) | (mpidr & (0xffffff)); 100713531Sjairo.balart@metempsy.com return affinity; 100813531Sjairo.balart@metempsy.com} 100913531Sjairo.balart@metempsy.com 101013531Sjairo.balart@metempsy.combool 101113756Sjairo.balart@metempsy.comGicv3Redistributor::canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const 101213531Sjairo.balart@metempsy.com{ 101313531Sjairo.balart@metempsy.com if (peInLowPowerState) { 101413531Sjairo.balart@metempsy.com return false; 101513531Sjairo.balart@metempsy.com } 101613531Sjairo.balart@metempsy.com 101713531Sjairo.balart@metempsy.com if (!distributor->groupEnabled(group)) { 101813531Sjairo.balart@metempsy.com return false; 101913531Sjairo.balart@metempsy.com } 102013531Sjairo.balart@metempsy.com 102113531Sjairo.balart@metempsy.com if ((group == Gicv3::G1S) && DPG1S) { 102213531Sjairo.balart@metempsy.com return false; 102313531Sjairo.balart@metempsy.com } 102413531Sjairo.balart@metempsy.com 102513531Sjairo.balart@metempsy.com if ((group == Gicv3::G1NS) && DPG1NS) { 102613531Sjairo.balart@metempsy.com return false; 102713531Sjairo.balart@metempsy.com } 102813531Sjairo.balart@metempsy.com 102913531Sjairo.balart@metempsy.com if ((group == Gicv3::G0S) && DPG0) { 103013531Sjairo.balart@metempsy.com return false; 103113531Sjairo.balart@metempsy.com } 103213531Sjairo.balart@metempsy.com 103313531Sjairo.balart@metempsy.com return true; 103413531Sjairo.balart@metempsy.com} 103513531Sjairo.balart@metempsy.com 103613531Sjairo.balart@metempsy.comvoid 103713531Sjairo.balart@metempsy.comGicv3Redistributor::serialize(CheckpointOut & cp) const 103813531Sjairo.balart@metempsy.com{ 103913531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(peInLowPowerState); 104013531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqGroup); 104113531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqEnabled); 104213531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqPending); 104313531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqActive); 104413531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqPriority); 104513531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqConfig); 104613531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqGrpmod); 104713531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqNsacr); 104813531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(DPG1S); 104913531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(DPG1NS); 105013531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(DPG0); 105113690Sjairo.balart@metempsy.com SERIALIZE_SCALAR(EnableLPIs); 105213690Sjairo.balart@metempsy.com SERIALIZE_SCALAR(lpiConfigurationTablePtr); 105313690Sjairo.balart@metempsy.com SERIALIZE_SCALAR(lpiIDBits); 105413690Sjairo.balart@metempsy.com SERIALIZE_SCALAR(lpiPendingTablePtr); 105513531Sjairo.balart@metempsy.com} 105613531Sjairo.balart@metempsy.com 105713531Sjairo.balart@metempsy.comvoid 105813531Sjairo.balart@metempsy.comGicv3Redistributor::unserialize(CheckpointIn & cp) 105913531Sjairo.balart@metempsy.com{ 106013531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(peInLowPowerState); 106113531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqGroup); 106213531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqEnabled); 106313531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqPending); 106413531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqActive); 106513531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqPriority); 106613531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqConfig); 106713531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqGrpmod); 106813531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqNsacr); 106913531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(DPG1S); 107013531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(DPG1NS); 107113531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(DPG0); 107213690Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(EnableLPIs); 107313690Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(lpiConfigurationTablePtr); 107413690Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(lpiIDBits); 107513690Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(lpiPendingTablePtr); 107613531Sjairo.balart@metempsy.com} 1077