gic_v3_distributor.cc revision 14258
113531Sjairo.balart@metempsy.com/* 214167Sgiacomo.travaglini@arm.com * Copyright (c) 2019 ARM Limited 314167Sgiacomo.travaglini@arm.com * All rights reserved 414167Sgiacomo.travaglini@arm.com * 514167Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall 614167Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual 714167Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating 814167Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software 914167Sgiacomo.travaglini@arm.com * licensed hereunder. You may use the software subject to the license 1014167Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated 1114167Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software, 1214167Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form. 1314167Sgiacomo.travaglini@arm.com * 1413531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting 1513531Sjairo.balart@metempsy.com * All rights reserved. 1613531Sjairo.balart@metempsy.com * 1713531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without 1813531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are 1913531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright 2013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer; 2113531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright 2213531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the 2313531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution; 2413531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its 2513531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from 2613531Sjairo.balart@metempsy.com * this software without specific prior written permission. 2713531Sjairo.balart@metempsy.com * 2813531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2913531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3013531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3113531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3213531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3313531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3413531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3513531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3613531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3713531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3813531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3913531Sjairo.balart@metempsy.com * 4013531Sjairo.balart@metempsy.com * Authors: Jairo Balart 4113531Sjairo.balart@metempsy.com */ 4213756Sjairo.balart@metempsy.com 4313531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh" 4413531Sjairo.balart@metempsy.com 4513531Sjairo.balart@metempsy.com#include <algorithm> 4613531Sjairo.balart@metempsy.com 4714257Sgiacomo.travaglini@arm.com#include "base/intmath.hh" 4813531Sjairo.balart@metempsy.com#include "debug/GIC.hh" 4913531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh" 5013531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh" 5113531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_redistributor.hh" 5213531Sjairo.balart@metempsy.com 5313756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_IGROUPR (0x0080, 0x00ff); 5413756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ISENABLER (0x0100, 0x017f); 5513756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ICENABLER (0x0180, 0x01ff); 5613756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ISPENDR (0x0200, 0x027f); 5713756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ICPENDR (0x0280, 0x02ff); 5813756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ISACTIVER (0x0300, 0x037f); 5913756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ICACTIVER (0x0380, 0x03ff); 6013531Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_IPRIORITYR(0x0400, 0x07ff); 6113756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ITARGETSR (0x0800, 0x08ff); 6213756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ICFGR (0x0c00, 0x0cff); 6313756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_IGRPMODR (0x0d00, 0x0d7f); 6413756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_NSACR (0x0e00, 0x0eff); 6513756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_CPENDSGIR (0x0f10, 0x0f1f); 6613756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_SPENDSGIR (0x0f20, 0x0f2f); 6713756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_IROUTER (0x6000, 0x7fe0); 6813531Sjairo.balart@metempsy.com 6913531Sjairo.balart@metempsy.comGicv3Distributor::Gicv3Distributor(Gicv3 * gic, uint32_t it_lines) 7013531Sjairo.balart@metempsy.com : gic(gic), 7113531Sjairo.balart@metempsy.com itLines(it_lines), 7214258Sgiacomo.travaglini@arm.com ARE(true), 7314258Sgiacomo.travaglini@arm.com EnableGrp1S(0), 7414258Sgiacomo.travaglini@arm.com EnableGrp1NS(0), 7514258Sgiacomo.travaglini@arm.com EnableGrp0(0), 7614258Sgiacomo.travaglini@arm.com irqGroup(it_lines, 0), 7714258Sgiacomo.travaglini@arm.com irqEnabled(it_lines, false), 7814258Sgiacomo.travaglini@arm.com irqPending(it_lines, false), 7914258Sgiacomo.travaglini@arm.com irqActive(it_lines, false), 8014258Sgiacomo.travaglini@arm.com irqPriority(it_lines, 0xAA), 8114258Sgiacomo.travaglini@arm.com irqConfig(it_lines, Gicv3::INT_LEVEL_SENSITIVE), 8214258Sgiacomo.travaglini@arm.com irqGrpmod(it_lines, 0), 8314258Sgiacomo.travaglini@arm.com irqNsacr(it_lines, 0), 8414258Sgiacomo.travaglini@arm.com irqAffinityRouting(it_lines, 0), 8514257Sgiacomo.travaglini@arm.com gicdTyper(0), 8614167Sgiacomo.travaglini@arm.com gicdPidr0(0x92), 8714167Sgiacomo.travaglini@arm.com gicdPidr1(0xb4), 8814167Sgiacomo.travaglini@arm.com gicdPidr2(0x3b), 8914167Sgiacomo.travaglini@arm.com gicdPidr3(0), 9014167Sgiacomo.travaglini@arm.com gicdPidr4(0x44) 9113531Sjairo.balart@metempsy.com{ 9213531Sjairo.balart@metempsy.com panic_if(it_lines > Gicv3::INTID_SECURE, "Invalid value for it_lines!"); 9314257Sgiacomo.travaglini@arm.com /* 9414257Sgiacomo.travaglini@arm.com * RSS [26] == 1 9514257Sgiacomo.travaglini@arm.com * (The implementation does supports targeted SGIs with affinity 9614257Sgiacomo.travaglini@arm.com * level 0 values of 0 - 255) 9714257Sgiacomo.travaglini@arm.com * No1N [25] == 1 9814257Sgiacomo.travaglini@arm.com * (1 of N SPI interrupts are not supported) 9914257Sgiacomo.travaglini@arm.com * A3V [24] == 1 10014257Sgiacomo.travaglini@arm.com * (Supports nonzero values of Affinity level 3) 10114257Sgiacomo.travaglini@arm.com * IDbits [23:19] == 0xf 10214257Sgiacomo.travaglini@arm.com * (The number of interrupt identifier bits supported, minus one) 10314257Sgiacomo.travaglini@arm.com * DVIS [18] == 0 10414257Sgiacomo.travaglini@arm.com * (The implementation does not support Direct Virtual LPI 10514257Sgiacomo.travaglini@arm.com * injection) 10614257Sgiacomo.travaglini@arm.com * LPIS [17] == 1 10714257Sgiacomo.travaglini@arm.com * (The implementation does not support LPIs) 10814257Sgiacomo.travaglini@arm.com * MBIS [16] == 1 10914257Sgiacomo.travaglini@arm.com * (The implementation supports message-based interrupts 11014257Sgiacomo.travaglini@arm.com * by writing to Distributor registers) 11114257Sgiacomo.travaglini@arm.com * SecurityExtn [10] == X 11214257Sgiacomo.travaglini@arm.com * (The GIC implementation supports two Security states) 11314257Sgiacomo.travaglini@arm.com * CPUNumber [7:5] == 0 11414257Sgiacomo.travaglini@arm.com * (since for us ARE is always 1 [(ARE = 0) == Gicv2 legacy]) 11514257Sgiacomo.travaglini@arm.com * ITLinesNumber [4:0] == N 11614257Sgiacomo.travaglini@arm.com * (MaxSPIIntId = 32 (N + 1) - 1) 11714257Sgiacomo.travaglini@arm.com */ 11814257Sgiacomo.travaglini@arm.com int max_spi_int_id = itLines - 1; 11914257Sgiacomo.travaglini@arm.com int it_lines_number = divCeil(max_spi_int_id + 1, 32) - 1; 12014257Sgiacomo.travaglini@arm.com gicdTyper = (1 << 26) | (1 << 25) | (1 << 24) | (IDBITS << 19) | 12114257Sgiacomo.travaglini@arm.com (1 << 17) | (1 << 16) | 12214257Sgiacomo.travaglini@arm.com ((gic->getSystem()->haveSecurity() ? 1 : 0) << 10) | 12314257Sgiacomo.travaglini@arm.com (it_lines_number << 0); 12413531Sjairo.balart@metempsy.com 12513531Sjairo.balart@metempsy.com if (gic->getSystem()->haveSecurity()) { 12613531Sjairo.balart@metempsy.com DS = false; 12713531Sjairo.balart@metempsy.com } else { 12813531Sjairo.balart@metempsy.com DS = true; 12913531Sjairo.balart@metempsy.com } 13014258Sgiacomo.travaglini@arm.com} 13113531Sjairo.balart@metempsy.com 13214258Sgiacomo.travaglini@arm.comvoid 13314258Sgiacomo.travaglini@arm.comGicv3Distributor::init() 13414258Sgiacomo.travaglini@arm.com{ 13513531Sjairo.balart@metempsy.com} 13613531Sjairo.balart@metempsy.com 13713531Sjairo.balart@metempsy.comuint64_t 13813531Sjairo.balart@metempsy.comGicv3Distributor::read(Addr addr, size_t size, bool is_secure_access) 13913531Sjairo.balart@metempsy.com{ 14013531Sjairo.balart@metempsy.com if (GICD_IGROUPR.contains(addr)) { // Interrupt Group Registers 14113531Sjairo.balart@metempsy.com uint64_t val = 0x0; 14213531Sjairo.balart@metempsy.com 14313531Sjairo.balart@metempsy.com if (!DS && !is_secure_access) { 14413531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 14513531Sjairo.balart@metempsy.com return 0; 14613531Sjairo.balart@metempsy.com } 14713531Sjairo.balart@metempsy.com 14813531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_IGROUPR.start()) * 8; 14913531Sjairo.balart@metempsy.com 15013531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 15113531Sjairo.balart@metempsy.com return 0; 15213531Sjairo.balart@metempsy.com } 15313531Sjairo.balart@metempsy.com 15413531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 15513756Sjairo.balart@metempsy.com i++, int_id++) { 15613531Sjairo.balart@metempsy.com val |= irqGroup[int_id] << i; 15713531Sjairo.balart@metempsy.com } 15813531Sjairo.balart@metempsy.com 15913531Sjairo.balart@metempsy.com return val; 16013756Sjairo.balart@metempsy.com } else if (GICD_ISENABLER.contains(addr)) { 16113531Sjairo.balart@metempsy.com // Interrupt Set-Enable Registers 16213531Sjairo.balart@metempsy.com uint64_t val = 0x0; 16313531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISENABLER.start()) * 8; 16413531Sjairo.balart@metempsy.com 16513531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 16613531Sjairo.balart@metempsy.com return 0; 16713531Sjairo.balart@metempsy.com } 16813531Sjairo.balart@metempsy.com 16913531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 17013756Sjairo.balart@metempsy.com i++, int_id++) { 17113756Sjairo.balart@metempsy.com 17213531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 17313531Sjairo.balart@metempsy.com { 17413531Sjairo.balart@metempsy.com continue; 17513531Sjairo.balart@metempsy.com } 17613531Sjairo.balart@metempsy.com 17713531Sjairo.balart@metempsy.com val |= irqEnabled[int_id] << i; 17813531Sjairo.balart@metempsy.com } 17913531Sjairo.balart@metempsy.com 18013531Sjairo.balart@metempsy.com return val; 18113531Sjairo.balart@metempsy.com } else if (GICD_ICENABLER.contains(addr)) { 18213531Sjairo.balart@metempsy.com // Interrupt Clear-Enable Registers 18313531Sjairo.balart@metempsy.com uint64_t val = 0x0; 18413531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICENABLER.start()) * 8; 18513531Sjairo.balart@metempsy.com 18613531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 18713531Sjairo.balart@metempsy.com return 0; 18813531Sjairo.balart@metempsy.com } 18913531Sjairo.balart@metempsy.com 19013531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 19113756Sjairo.balart@metempsy.com i++, int_id++) { 19213756Sjairo.balart@metempsy.com 19313531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 19413531Sjairo.balart@metempsy.com { 19513531Sjairo.balart@metempsy.com continue; 19613531Sjairo.balart@metempsy.com } 19713531Sjairo.balart@metempsy.com 19813531Sjairo.balart@metempsy.com val |= (irqEnabled[int_id] << i); 19913531Sjairo.balart@metempsy.com } 20013531Sjairo.balart@metempsy.com 20113531Sjairo.balart@metempsy.com return val; 20213531Sjairo.balart@metempsy.com } else if (GICD_ISPENDR.contains(addr)) { 20313756Sjairo.balart@metempsy.com // Interrupt Set-Pending Registers 20413531Sjairo.balart@metempsy.com uint64_t val = 0x0; 20513531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISPENDR.start()) * 8; 20613531Sjairo.balart@metempsy.com 20713531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 20813531Sjairo.balart@metempsy.com return 0; 20913531Sjairo.balart@metempsy.com } 21013531Sjairo.balart@metempsy.com 21113531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 21213756Sjairo.balart@metempsy.com i++, int_id++) { 21313756Sjairo.balart@metempsy.com 21413531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 21513531Sjairo.balart@metempsy.com { 21613531Sjairo.balart@metempsy.com if (irqNsacr[int_id] == 0) { 21713531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 21813531Sjairo.balart@metempsy.com continue; 21913531Sjairo.balart@metempsy.com } 22013531Sjairo.balart@metempsy.com } 22113531Sjairo.balart@metempsy.com 22213531Sjairo.balart@metempsy.com val |= (irqPending[int_id] << i); 22313531Sjairo.balart@metempsy.com } 22413531Sjairo.balart@metempsy.com 22513531Sjairo.balart@metempsy.com return val; 22613531Sjairo.balart@metempsy.com } else if (GICD_ICPENDR.contains(addr)) { 22713756Sjairo.balart@metempsy.com // Interrupt Clear-Pending Registers 22813531Sjairo.balart@metempsy.com uint64_t val = 0x0; 22913531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICPENDR.start()) * 8; 23013531Sjairo.balart@metempsy.com 23113531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 23213531Sjairo.balart@metempsy.com return 0; 23313531Sjairo.balart@metempsy.com } 23413531Sjairo.balart@metempsy.com 23513531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 23613756Sjairo.balart@metempsy.com i++, int_id++) { 23713756Sjairo.balart@metempsy.com 23813531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 23913531Sjairo.balart@metempsy.com { 24013531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 2) { 24113531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 24213531Sjairo.balart@metempsy.com continue; 24313531Sjairo.balart@metempsy.com } 24413531Sjairo.balart@metempsy.com } 24513531Sjairo.balart@metempsy.com 24613531Sjairo.balart@metempsy.com val |= (irqPending[int_id] << i); 24713531Sjairo.balart@metempsy.com } 24813531Sjairo.balart@metempsy.com 24913531Sjairo.balart@metempsy.com return val; 25013756Sjairo.balart@metempsy.com } else if (GICD_ISACTIVER.contains(addr)) { 25113531Sjairo.balart@metempsy.com // Interrupt Set-Active Registers 25213531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISACTIVER.start()) * 8; 25313531Sjairo.balart@metempsy.com 25413531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 25513531Sjairo.balart@metempsy.com return 0; 25613531Sjairo.balart@metempsy.com } 25713531Sjairo.balart@metempsy.com 25813531Sjairo.balart@metempsy.com uint64_t val = 0x0; 25913531Sjairo.balart@metempsy.com 26013531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 26113756Sjairo.balart@metempsy.com i++, int_id++) { 26213756Sjairo.balart@metempsy.com 26313531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 26413531Sjairo.balart@metempsy.com { 26513531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 26613531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 2) { 26713531Sjairo.balart@metempsy.com continue; 26813531Sjairo.balart@metempsy.com } 26913531Sjairo.balart@metempsy.com } 27013531Sjairo.balart@metempsy.com 27113531Sjairo.balart@metempsy.com val |= (irqActive[int_id] << i); 27213531Sjairo.balart@metempsy.com } 27313531Sjairo.balart@metempsy.com 27413531Sjairo.balart@metempsy.com return val; 27513756Sjairo.balart@metempsy.com } else if (GICD_ICACTIVER.contains(addr)) { 27613531Sjairo.balart@metempsy.com // Interrupt Clear-Active Registers 27713531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICACTIVER.start()) * 8; 27813531Sjairo.balart@metempsy.com 27913531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 28013531Sjairo.balart@metempsy.com return 0; 28113531Sjairo.balart@metempsy.com } 28213531Sjairo.balart@metempsy.com 28313531Sjairo.balart@metempsy.com uint64_t val = 0x0; 28413531Sjairo.balart@metempsy.com 28513531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 28613756Sjairo.balart@metempsy.com i++, int_id++) { 28713756Sjairo.balart@metempsy.com 28813531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 28913531Sjairo.balart@metempsy.com { 29013531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 2) { 29113531Sjairo.balart@metempsy.com continue; 29213531Sjairo.balart@metempsy.com } 29313531Sjairo.balart@metempsy.com } 29413531Sjairo.balart@metempsy.com 29513531Sjairo.balart@metempsy.com val |= (irqActive[int_id] << i); 29613531Sjairo.balart@metempsy.com } 29713531Sjairo.balart@metempsy.com 29813531Sjairo.balart@metempsy.com return val; 29913756Sjairo.balart@metempsy.com } else if (GICD_IPRIORITYR.contains(addr)) { 30013531Sjairo.balart@metempsy.com // Interrupt Priority Registers 30113531Sjairo.balart@metempsy.com uint64_t val = 0x0; 30213531Sjairo.balart@metempsy.com int first_intid = addr - GICD_IPRIORITYR.start(); 30313531Sjairo.balart@metempsy.com 30413531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 30513531Sjairo.balart@metempsy.com return 0; 30613531Sjairo.balart@metempsy.com } 30713531Sjairo.balart@metempsy.com 30813531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < size && int_id < itLines; 30913756Sjairo.balart@metempsy.com i++, int_id++) { 31013756Sjairo.balart@metempsy.com 31113531Sjairo.balart@metempsy.com uint8_t prio = irqPriority[int_id]; 31213531Sjairo.balart@metempsy.com 31313531Sjairo.balart@metempsy.com if (!DS && !is_secure_access) { 31413531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 31513531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 31613531Sjairo.balart@metempsy.com continue; 31713531Sjairo.balart@metempsy.com } else { 31813531Sjairo.balart@metempsy.com // NS view 31913531Sjairo.balart@metempsy.com prio = (prio << 1) & 0xff; 32013531Sjairo.balart@metempsy.com } 32113531Sjairo.balart@metempsy.com } 32213531Sjairo.balart@metempsy.com 32313531Sjairo.balart@metempsy.com val |= prio << (i * 8); 32413531Sjairo.balart@metempsy.com } 32513531Sjairo.balart@metempsy.com 32613531Sjairo.balart@metempsy.com return val; 32713531Sjairo.balart@metempsy.com } else if (GICD_ITARGETSR.contains(addr)) { 32813531Sjairo.balart@metempsy.com // Interrupt Processor Targets Registers 32913531Sjairo.balart@metempsy.com // ARE always on, RAZ/WI 33013531Sjairo.balart@metempsy.com warn("Gicv3Distributor::read(): " 33113531Sjairo.balart@metempsy.com "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n"); 33213531Sjairo.balart@metempsy.com return 0; 33313756Sjairo.balart@metempsy.com } else if (GICD_ICFGR.contains(addr)) { 33413531Sjairo.balart@metempsy.com // Interrupt Configuration Registers 33513531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICFGR.start()) * 4; 33613531Sjairo.balart@metempsy.com 33713531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 33813531Sjairo.balart@metempsy.com return 0; 33913531Sjairo.balart@metempsy.com } 34013531Sjairo.balart@metempsy.com 34113531Sjairo.balart@metempsy.com uint64_t val = 0x0; 34213531Sjairo.balart@metempsy.com 34313531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 34413756Sjairo.balart@metempsy.com i = i + 2, int_id++) { 34513756Sjairo.balart@metempsy.com 34613531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 34713531Sjairo.balart@metempsy.com { 34813531Sjairo.balart@metempsy.com continue; 34913531Sjairo.balart@metempsy.com } 35013531Sjairo.balart@metempsy.com 35113531Sjairo.balart@metempsy.com if (irqConfig[int_id] == Gicv3::INT_EDGE_TRIGGERED) { 35213531Sjairo.balart@metempsy.com val |= (0x2 << i); 35313531Sjairo.balart@metempsy.com } 35413531Sjairo.balart@metempsy.com } 35513531Sjairo.balart@metempsy.com 35613531Sjairo.balart@metempsy.com return val; 35713531Sjairo.balart@metempsy.com } else if (GICD_IGRPMODR.contains(addr)) { 35813531Sjairo.balart@metempsy.com // Interrupt Group Modifier Registers 35913531Sjairo.balart@metempsy.com if (DS) { 36013531Sjairo.balart@metempsy.com // RAZ/WI if security disabled 36113531Sjairo.balart@metempsy.com return 0; 36213531Sjairo.balart@metempsy.com } else { 36313531Sjairo.balart@metempsy.com if (!is_secure_access) { 36413531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 36513531Sjairo.balart@metempsy.com return 0; 36613531Sjairo.balart@metempsy.com } else { 36713531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_IGRPMODR.start()) * 8; 36813531Sjairo.balart@metempsy.com 36913531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 37013531Sjairo.balart@metempsy.com return 0; 37113531Sjairo.balart@metempsy.com } 37213531Sjairo.balart@metempsy.com 37313531Sjairo.balart@metempsy.com uint64_t val = 0x0; 37413531Sjairo.balart@metempsy.com 37513531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; 37613756Sjairo.balart@metempsy.com i < 8 * size && int_id < itLines; i++, int_id++) { 37713531Sjairo.balart@metempsy.com val |= irqGrpmod[int_id] << i; 37813531Sjairo.balart@metempsy.com } 37913531Sjairo.balart@metempsy.com 38013531Sjairo.balart@metempsy.com return val; 38113531Sjairo.balart@metempsy.com } 38213531Sjairo.balart@metempsy.com } 38313756Sjairo.balart@metempsy.com } else if (GICD_NSACR.contains(addr)) { 38413531Sjairo.balart@metempsy.com // Non-secure Access Control Registers 38513531Sjairo.balart@metempsy.com // 2 bits per interrupt 38613531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_NSACR.start()) * 4; 38713531Sjairo.balart@metempsy.com 38813531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 38913531Sjairo.balart@metempsy.com return 0; 39013531Sjairo.balart@metempsy.com } 39113531Sjairo.balart@metempsy.com 39213531Sjairo.balart@metempsy.com if (DS || (!DS && !is_secure_access)) { 39313531Sjairo.balart@metempsy.com return 0; 39413531Sjairo.balart@metempsy.com } 39513531Sjairo.balart@metempsy.com 39613531Sjairo.balart@metempsy.com uint64_t val = 0x0; 39713531Sjairo.balart@metempsy.com 39813531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; 39913756Sjairo.balart@metempsy.com i < 8 * size && int_id < itLines; i = i + 2, int_id++) { 40013531Sjairo.balart@metempsy.com val |= irqNsacr[int_id] << i; 40113531Sjairo.balart@metempsy.com } 40213531Sjairo.balart@metempsy.com 40313531Sjairo.balart@metempsy.com return val; 40413531Sjairo.balart@metempsy.com } else if (GICD_CPENDSGIR.contains(addr)) { // SGI Clear-Pending Registers 40513531Sjairo.balart@metempsy.com // ARE always on, RAZ/WI 40613531Sjairo.balart@metempsy.com warn("Gicv3Distributor::read(): " 40713531Sjairo.balart@metempsy.com "GICD_CPENDSGIR is RAZ/WI, legacy not supported!\n"); 40813531Sjairo.balart@metempsy.com return 0x0; 40913531Sjairo.balart@metempsy.com } else if (GICD_SPENDSGIR.contains(addr)) { // SGI Set-Pending Registers 41013531Sjairo.balart@metempsy.com // ARE always on, RAZ/WI 41113531Sjairo.balart@metempsy.com warn("Gicv3Distributor::read(): " 41213531Sjairo.balart@metempsy.com "GICD_SPENDSGIR is RAZ/WI, legacy not supported!\n"); 41313531Sjairo.balart@metempsy.com return 0x0; 41413531Sjairo.balart@metempsy.com } else if (GICD_IROUTER.contains(addr)) { // Interrupt Routing Registers 41513531Sjairo.balart@metempsy.com // 64 bit registers. 2 or 1 access. 41613531Sjairo.balart@metempsy.com int int_id = (addr - GICD_IROUTER.start()) / 8; 41713531Sjairo.balart@metempsy.com 41813531Sjairo.balart@metempsy.com if (isNotSPI(int_id)) { 41913531Sjairo.balart@metempsy.com return 0; 42013531Sjairo.balart@metempsy.com } 42113531Sjairo.balart@metempsy.com 42213531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 42313531Sjairo.balart@metempsy.com { 42413531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 3) { 42513531Sjairo.balart@metempsy.com return 0; 42613531Sjairo.balart@metempsy.com } 42713531Sjairo.balart@metempsy.com } 42813531Sjairo.balart@metempsy.com 42913531Sjairo.balart@metempsy.com if (size == 4) { 43013531Sjairo.balart@metempsy.com if (addr & 7) { // high half of 64 bit register 43113531Sjairo.balart@metempsy.com return irqAffinityRouting[int_id] >> 32; 43213531Sjairo.balart@metempsy.com } else { // high low of 64 bit register 43313531Sjairo.balart@metempsy.com return irqAffinityRouting[int_id] & 0xFFFFFFFF; 43413531Sjairo.balart@metempsy.com } 43513531Sjairo.balart@metempsy.com } else { 43613531Sjairo.balart@metempsy.com return irqAffinityRouting[int_id]; 43713531Sjairo.balart@metempsy.com } 43813531Sjairo.balart@metempsy.com } 43913531Sjairo.balart@metempsy.com 44013531Sjairo.balart@metempsy.com switch (addr) { 44113531Sjairo.balart@metempsy.com case GICD_CTLR: // Control Register 44213531Sjairo.balart@metempsy.com if (!DS) { 44313531Sjairo.balart@metempsy.com if (is_secure_access) { 44413531Sjairo.balart@metempsy.com // E1NWF [7] RAZ/WI 44513531Sjairo.balart@metempsy.com // DS [6] - Disable Security 44613531Sjairo.balart@metempsy.com // ARE_NS [5] RAO/WI 44713531Sjairo.balart@metempsy.com // ARE_S [4] RAO/WI 44813531Sjairo.balart@metempsy.com // EnableGrp1S [2] 44913531Sjairo.balart@metempsy.com // EnableGrp1NS [1] 45013531Sjairo.balart@metempsy.com // EnableGrp0 [0] 45113531Sjairo.balart@metempsy.com return (EnableGrp0 << 0) | 45213531Sjairo.balart@metempsy.com (EnableGrp1NS << 1) | 45313531Sjairo.balart@metempsy.com (EnableGrp1S << 2) | 45413531Sjairo.balart@metempsy.com (1 << 4) | 45513531Sjairo.balart@metempsy.com (1 << 5) | 45613531Sjairo.balart@metempsy.com (DS << 6); 45713531Sjairo.balart@metempsy.com } else { 45813531Sjairo.balart@metempsy.com // ARE_NS [4] RAO/WI; 45913531Sjairo.balart@metempsy.com // EnableGrp1A [1] is a read-write alias of the Secure 46013531Sjairo.balart@metempsy.com // GICD_CTLR.EnableGrp1NS 46113531Sjairo.balart@metempsy.com // EnableGrp1 [0] RES0 46213531Sjairo.balart@metempsy.com return (1 << 4) | (EnableGrp1NS << 1); 46313531Sjairo.balart@metempsy.com } 46413531Sjairo.balart@metempsy.com } else { 46513531Sjairo.balart@metempsy.com return (DS << 6) | (ARE << 4) | 46613531Sjairo.balart@metempsy.com (EnableGrp1NS << 1) | (EnableGrp0 << 0); 46713531Sjairo.balart@metempsy.com } 46813531Sjairo.balart@metempsy.com 46913531Sjairo.balart@metempsy.com case GICD_TYPER: // Interrupt Controller Type Register 47014257Sgiacomo.travaglini@arm.com return gicdTyper; 47113531Sjairo.balart@metempsy.com 47213531Sjairo.balart@metempsy.com case GICD_IIDR: // Implementer Identification Register 47313531Sjairo.balart@metempsy.com //return 0x43b; // ARM JEP106 code (r0p0 GIC-500) 47413531Sjairo.balart@metempsy.com return 0; 47513531Sjairo.balart@metempsy.com 47613531Sjairo.balart@metempsy.com case GICD_STATUSR: // Error Reporting Status Register 47713531Sjairo.balart@metempsy.com // Optional register, RAZ/WI 47813531Sjairo.balart@metempsy.com return 0x0; 47913531Sjairo.balart@metempsy.com 48013756Sjairo.balart@metempsy.com case GICD_PIDR0: // Peripheral ID0 Register 48114167Sgiacomo.travaglini@arm.com return gicdPidr0; 48213531Sjairo.balart@metempsy.com 48314167Sgiacomo.travaglini@arm.com case GICD_PIDR1: // Peripheral ID1 Register 48414167Sgiacomo.travaglini@arm.com return gicdPidr1; 48513531Sjairo.balart@metempsy.com 48614167Sgiacomo.travaglini@arm.com case GICD_PIDR2: // Peripheral ID2 Register 48714167Sgiacomo.travaglini@arm.com return gicdPidr2; 48813531Sjairo.balart@metempsy.com 48913531Sjairo.balart@metempsy.com case GICD_PIDR3: // Peripheral ID3 Register 49014167Sgiacomo.travaglini@arm.com return gicdPidr3; 49113531Sjairo.balart@metempsy.com 49214167Sgiacomo.travaglini@arm.com case GICD_PIDR4: // Peripheral ID4 Register 49314167Sgiacomo.travaglini@arm.com return gicdPidr4; 49413531Sjairo.balart@metempsy.com 49513531Sjairo.balart@metempsy.com case GICD_PIDR5: // Peripheral ID5 Register 49613531Sjairo.balart@metempsy.com case GICD_PIDR6: // Peripheral ID6 Register 49713531Sjairo.balart@metempsy.com case GICD_PIDR7: // Peripheral ID7 Register 49813531Sjairo.balart@metempsy.com return 0; // RES0 49913531Sjairo.balart@metempsy.com 50013531Sjairo.balart@metempsy.com default: 50113531Sjairo.balart@metempsy.com panic("Gicv3Distributor::read(): invalid offset %#x\n", addr); 50213531Sjairo.balart@metempsy.com break; 50313531Sjairo.balart@metempsy.com } 50413531Sjairo.balart@metempsy.com} 50513531Sjairo.balart@metempsy.com 50613531Sjairo.balart@metempsy.comvoid 50713531Sjairo.balart@metempsy.comGicv3Distributor::write(Addr addr, uint64_t data, size_t size, 50813531Sjairo.balart@metempsy.com bool is_secure_access) 50913531Sjairo.balart@metempsy.com{ 51013531Sjairo.balart@metempsy.com if (GICD_IGROUPR.contains(addr)) { // Interrupt Group Registers 51113531Sjairo.balart@metempsy.com if (!DS && !is_secure_access) { 51213531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 51313531Sjairo.balart@metempsy.com return; 51413531Sjairo.balart@metempsy.com } 51513531Sjairo.balart@metempsy.com 51613531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_IGROUPR.start()) * 8; 51713531Sjairo.balart@metempsy.com 51813531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 51913531Sjairo.balart@metempsy.com return; 52013531Sjairo.balart@metempsy.com } 52113531Sjairo.balart@metempsy.com 52213531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 52313756Sjairo.balart@metempsy.com i++, int_id++) { 52413531Sjairo.balart@metempsy.com irqGroup[int_id] = data & (1 << i) ? 1 : 0; 52513531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d group %d\n", 52613531Sjairo.balart@metempsy.com int_id, irqGroup[int_id]); 52713531Sjairo.balart@metempsy.com } 52813531Sjairo.balart@metempsy.com 52913531Sjairo.balart@metempsy.com return; 53013756Sjairo.balart@metempsy.com } else if (GICD_ISENABLER.contains(addr)) { 53113531Sjairo.balart@metempsy.com // Interrupt Set-Enable Registers 53213531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISENABLER.start()) * 8; 53313531Sjairo.balart@metempsy.com 53413531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 53513531Sjairo.balart@metempsy.com return; 53613531Sjairo.balart@metempsy.com } 53713531Sjairo.balart@metempsy.com 53813531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 53913756Sjairo.balart@metempsy.com i++, int_id++) { 54013756Sjairo.balart@metempsy.com 54113531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 54213531Sjairo.balart@metempsy.com { 54313531Sjairo.balart@metempsy.com continue; 54413531Sjairo.balart@metempsy.com } 54513531Sjairo.balart@metempsy.com 54613531Sjairo.balart@metempsy.com bool enable = data & (1 << i) ? 1 : 0; 54713531Sjairo.balart@metempsy.com 54813531Sjairo.balart@metempsy.com if (enable) { 54913531Sjairo.balart@metempsy.com if (!irqEnabled[int_id]) { 55013531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): " 55113531Sjairo.balart@metempsy.com "int_id %d enabled\n", int_id); 55213531Sjairo.balart@metempsy.com } 55313531Sjairo.balart@metempsy.com 55413531Sjairo.balart@metempsy.com irqEnabled[int_id] = true; 55513531Sjairo.balart@metempsy.com } 55613531Sjairo.balart@metempsy.com } 55713531Sjairo.balart@metempsy.com 55813531Sjairo.balart@metempsy.com return; 55913531Sjairo.balart@metempsy.com } else if (GICD_ICENABLER.contains(addr)) { 56013531Sjairo.balart@metempsy.com // Interrupt Clear-Enable Registers 56113531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICENABLER.start()) * 8; 56213531Sjairo.balart@metempsy.com 56313812Sgiacomo.travaglini@arm.com if (isNotSPI(first_intid)) { 56413812Sgiacomo.travaglini@arm.com return; 56513812Sgiacomo.travaglini@arm.com } 56613812Sgiacomo.travaglini@arm.com 56713531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 56813756Sjairo.balart@metempsy.com i++, int_id++) { 56913756Sjairo.balart@metempsy.com 57013531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 57113531Sjairo.balart@metempsy.com { 57213531Sjairo.balart@metempsy.com continue; 57313531Sjairo.balart@metempsy.com } 57413531Sjairo.balart@metempsy.com 57513531Sjairo.balart@metempsy.com bool disable = data & (1 << i) ? 1 : 0; 57613531Sjairo.balart@metempsy.com 57713531Sjairo.balart@metempsy.com if (disable) { 57813531Sjairo.balart@metempsy.com if (irqEnabled[int_id]) { 57913531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): " 58013531Sjairo.balart@metempsy.com "int_id %d disabled\n", int_id); 58113531Sjairo.balart@metempsy.com } 58213531Sjairo.balart@metempsy.com 58313531Sjairo.balart@metempsy.com irqEnabled[int_id] = false; 58413531Sjairo.balart@metempsy.com } 58513531Sjairo.balart@metempsy.com } 58613531Sjairo.balart@metempsy.com 58713531Sjairo.balart@metempsy.com return; 58813531Sjairo.balart@metempsy.com } else if (GICD_ISPENDR.contains(addr)) { 58913756Sjairo.balart@metempsy.com // Interrupt Set-Pending Registers 59013531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISPENDR.start()) * 8; 59113531Sjairo.balart@metempsy.com 59213531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 59313531Sjairo.balart@metempsy.com return; 59413531Sjairo.balart@metempsy.com } 59513531Sjairo.balart@metempsy.com 59613531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 59713756Sjairo.balart@metempsy.com i++, int_id++) { 59813756Sjairo.balart@metempsy.com 59913531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 60013531Sjairo.balart@metempsy.com { 60113531Sjairo.balart@metempsy.com if (irqNsacr[int_id] == 0) { 60213531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 60313531Sjairo.balart@metempsy.com continue; 60413531Sjairo.balart@metempsy.com } 60513531Sjairo.balart@metempsy.com } 60613531Sjairo.balart@metempsy.com 60713531Sjairo.balart@metempsy.com bool pending = data & (1 << i) ? 1 : 0; 60813531Sjairo.balart@metempsy.com 60913531Sjairo.balart@metempsy.com if (pending) { 61013531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write() (GICD_ISPENDR): " 61113531Sjairo.balart@metempsy.com "int_id %d (SPI) pending bit set\n", int_id); 61213531Sjairo.balart@metempsy.com irqPending[int_id] = true; 61313531Sjairo.balart@metempsy.com } 61413531Sjairo.balart@metempsy.com } 61513531Sjairo.balart@metempsy.com 61614231Sgiacomo.travaglini@arm.com update(); 61713531Sjairo.balart@metempsy.com return; 61813531Sjairo.balart@metempsy.com } else if (GICD_ICPENDR.contains(addr)) { 61913756Sjairo.balart@metempsy.com // Interrupt Clear-Pending Registers 62013531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICPENDR.start()) * 8; 62113531Sjairo.balart@metempsy.com 62213531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 62313531Sjairo.balart@metempsy.com return; 62413531Sjairo.balart@metempsy.com } 62513531Sjairo.balart@metempsy.com 62613531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 62713756Sjairo.balart@metempsy.com i++, int_id++) { 62813756Sjairo.balart@metempsy.com 62913531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 63013531Sjairo.balart@metempsy.com { 63113531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 2) { 63213531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 63313531Sjairo.balart@metempsy.com continue; 63413531Sjairo.balart@metempsy.com } 63513531Sjairo.balart@metempsy.com } 63613531Sjairo.balart@metempsy.com 63713531Sjairo.balart@metempsy.com bool clear = data & (1 << i) ? 1 : 0; 63813531Sjairo.balart@metempsy.com 63913531Sjairo.balart@metempsy.com if (clear) { 64013531Sjairo.balart@metempsy.com irqPending[int_id] = false; 64114231Sgiacomo.travaglini@arm.com clearIrqCpuInterface(int_id); 64213531Sjairo.balart@metempsy.com } 64313531Sjairo.balart@metempsy.com } 64413531Sjairo.balart@metempsy.com 64514231Sgiacomo.travaglini@arm.com update(); 64613531Sjairo.balart@metempsy.com return; 64713756Sjairo.balart@metempsy.com } else if (GICD_ISACTIVER.contains(addr)) { 64813531Sjairo.balart@metempsy.com // Interrupt Set-Active Registers 64913531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISACTIVER.start()) * 8; 65013531Sjairo.balart@metempsy.com 65113531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 65213531Sjairo.balart@metempsy.com return; 65313531Sjairo.balart@metempsy.com } 65413531Sjairo.balart@metempsy.com 65513531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 65613756Sjairo.balart@metempsy.com i++, int_id++) { 65713756Sjairo.balart@metempsy.com 65813531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 65913531Sjairo.balart@metempsy.com { 66013531Sjairo.balart@metempsy.com continue; 66113531Sjairo.balart@metempsy.com } 66213531Sjairo.balart@metempsy.com 66313531Sjairo.balart@metempsy.com bool active = data & (1 << i) ? 1 : 0; 66413531Sjairo.balart@metempsy.com 66513531Sjairo.balart@metempsy.com if (active) { 66613531Sjairo.balart@metempsy.com irqActive[int_id] = 1; 66713531Sjairo.balart@metempsy.com } 66813531Sjairo.balart@metempsy.com } 66913531Sjairo.balart@metempsy.com 67013531Sjairo.balart@metempsy.com return; 67113531Sjairo.balart@metempsy.com } else if (GICD_ICACTIVER.contains(addr)) { 67213531Sjairo.balart@metempsy.com // Interrupt Clear-Active Registers 67313531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICACTIVER.start()) * 8; 67413531Sjairo.balart@metempsy.com 67513531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 67613531Sjairo.balart@metempsy.com return; 67713531Sjairo.balart@metempsy.com } 67813531Sjairo.balart@metempsy.com 67913531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 68013756Sjairo.balart@metempsy.com i++, int_id++) { 68113756Sjairo.balart@metempsy.com 68213531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 68313531Sjairo.balart@metempsy.com { 68413531Sjairo.balart@metempsy.com continue; 68513531Sjairo.balart@metempsy.com } 68613531Sjairo.balart@metempsy.com 68713531Sjairo.balart@metempsy.com bool clear = data & (1 << i) ? 1 : 0; 68813531Sjairo.balart@metempsy.com 68913531Sjairo.balart@metempsy.com if (clear) { 69013531Sjairo.balart@metempsy.com if (irqActive[int_id]) { 69113531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): " 69213531Sjairo.balart@metempsy.com "int_id %d active cleared\n", int_id); 69313531Sjairo.balart@metempsy.com } 69413531Sjairo.balart@metempsy.com 69513531Sjairo.balart@metempsy.com irqActive[int_id] = false; 69613531Sjairo.balart@metempsy.com } 69713531Sjairo.balart@metempsy.com } 69813531Sjairo.balart@metempsy.com 69913531Sjairo.balart@metempsy.com return; 70013756Sjairo.balart@metempsy.com } else if (GICD_IPRIORITYR.contains(addr)) { 70113531Sjairo.balart@metempsy.com // Interrupt Priority Registers 70213531Sjairo.balart@metempsy.com int first_intid = addr - GICD_IPRIORITYR.start(); 70313531Sjairo.balart@metempsy.com 70413531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 70513531Sjairo.balart@metempsy.com return; 70613531Sjairo.balart@metempsy.com } 70713531Sjairo.balart@metempsy.com 70813531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < size && int_id < itLines; 70913531Sjairo.balart@metempsy.com i++, int_id++) { 71013531Sjairo.balart@metempsy.com uint8_t prio = bits(data, (i + 1) * 8 - 1, (i * 8)); 71113531Sjairo.balart@metempsy.com 71213531Sjairo.balart@metempsy.com if (!DS && !is_secure_access) { 71313531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 71413531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses to secure interrupts 71513531Sjairo.balart@metempsy.com continue; 71613531Sjairo.balart@metempsy.com } else { 71713531Sjairo.balart@metempsy.com prio = 0x80 | (prio >> 1); 71813531Sjairo.balart@metempsy.com } 71913531Sjairo.balart@metempsy.com } 72013531Sjairo.balart@metempsy.com 72113531Sjairo.balart@metempsy.com irqPriority[int_id] = prio; 72213531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d priority %d\n", 72313531Sjairo.balart@metempsy.com int_id, irqPriority[int_id]); 72413531Sjairo.balart@metempsy.com } 72513531Sjairo.balart@metempsy.com 72613531Sjairo.balart@metempsy.com return; 72713531Sjairo.balart@metempsy.com } else if (GICD_ITARGETSR.contains(addr)) { 72813531Sjairo.balart@metempsy.com // Interrupt Processor Targets Registers 72913531Sjairo.balart@metempsy.com // ARE always on, RAZ/WI 73013531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 73113531Sjairo.balart@metempsy.com "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n"); 73213531Sjairo.balart@metempsy.com return; 73313756Sjairo.balart@metempsy.com } else if (GICD_ICFGR.contains(addr)) { 73413531Sjairo.balart@metempsy.com // Interrupt Configuration Registers 73513756Sjairo.balart@metempsy.com // for x = 0 to 15: 73613756Sjairo.balart@metempsy.com // GICD_ICFGR[2x] = RES0 73713756Sjairo.balart@metempsy.com // GICD_ICFGR[2x + 1] = 73813756Sjairo.balart@metempsy.com // 0 level-sensitive 73913756Sjairo.balart@metempsy.com // 1 edge-triggered 74013531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICFGR.start()) * 4; 74113531Sjairo.balart@metempsy.com 74213531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 74313531Sjairo.balart@metempsy.com return; 74413531Sjairo.balart@metempsy.com } 74513531Sjairo.balart@metempsy.com 74613531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 74713756Sjairo.balart@metempsy.com i = i + 2, int_id++) { 74813531Sjairo.balart@metempsy.com irqConfig[int_id] = data & (0x2 << i) ? 74913531Sjairo.balart@metempsy.com Gicv3::INT_EDGE_TRIGGERED : 75013531Sjairo.balart@metempsy.com Gicv3::INT_LEVEL_SENSITIVE; 75113531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d config %d\n", 75213531Sjairo.balart@metempsy.com int_id, irqConfig[int_id]); 75313531Sjairo.balart@metempsy.com } 75413531Sjairo.balart@metempsy.com 75513531Sjairo.balart@metempsy.com return; 75613531Sjairo.balart@metempsy.com } else if (GICD_IGRPMODR.contains(addr)) { 75713531Sjairo.balart@metempsy.com // Interrupt Group Modifier Registers 75813531Sjairo.balart@metempsy.com if (DS) { 75913531Sjairo.balart@metempsy.com return; 76013531Sjairo.balart@metempsy.com } else { 76113531Sjairo.balart@metempsy.com if (!is_secure_access) { 76213531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 76313531Sjairo.balart@metempsy.com return; 76413531Sjairo.balart@metempsy.com } else { 76513531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_IGRPMODR.start()) * 8; 76613531Sjairo.balart@metempsy.com 76713531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 76813531Sjairo.balart@metempsy.com return; 76913531Sjairo.balart@metempsy.com } 77013531Sjairo.balart@metempsy.com 77113531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; 77213756Sjairo.balart@metempsy.com i < 8 * size && int_id < itLines; i++, int_id++) { 77314230Sgiacomo.travaglini@arm.com irqGrpmod[int_id] = bits(data, i); 77413531Sjairo.balart@metempsy.com } 77513531Sjairo.balart@metempsy.com 77613531Sjairo.balart@metempsy.com return ; 77713531Sjairo.balart@metempsy.com } 77813531Sjairo.balart@metempsy.com } 77913531Sjairo.balart@metempsy.com 78013756Sjairo.balart@metempsy.com } else if (GICD_NSACR.contains(addr)) { 78113531Sjairo.balart@metempsy.com // Non-secure Access Control Registers 78213531Sjairo.balart@metempsy.com // 2 bits per interrupt 78313531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_NSACR.start()) * 4; 78413531Sjairo.balart@metempsy.com 78513531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 78613531Sjairo.balart@metempsy.com return; 78713531Sjairo.balart@metempsy.com } 78813531Sjairo.balart@metempsy.com 78913531Sjairo.balart@metempsy.com if (DS || (!DS && !is_secure_access)) { 79013531Sjairo.balart@metempsy.com return; 79113531Sjairo.balart@metempsy.com } 79213531Sjairo.balart@metempsy.com 79313531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; 79413756Sjairo.balart@metempsy.com i < 8 * size && int_id < itLines; i = i + 2, int_id++) { 79513531Sjairo.balart@metempsy.com irqNsacr[int_id] = (data >> (2 * int_id)) & 0x3; 79613531Sjairo.balart@metempsy.com } 79713531Sjairo.balart@metempsy.com 79813531Sjairo.balart@metempsy.com return; 79913531Sjairo.balart@metempsy.com } else if (GICD_IROUTER.contains(addr)) { // Interrupt Routing Registers 80013531Sjairo.balart@metempsy.com // 64 bit registers. 2 accesses. 80113531Sjairo.balart@metempsy.com int int_id = (addr - GICD_IROUTER.start()) / 8; 80213531Sjairo.balart@metempsy.com 80313531Sjairo.balart@metempsy.com if (isNotSPI(int_id)) { 80413531Sjairo.balart@metempsy.com return; 80513531Sjairo.balart@metempsy.com } 80613531Sjairo.balart@metempsy.com 80713531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 80813531Sjairo.balart@metempsy.com { 80913531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 3) { 81013531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 81113531Sjairo.balart@metempsy.com return; 81213531Sjairo.balart@metempsy.com } 81313531Sjairo.balart@metempsy.com } 81413531Sjairo.balart@metempsy.com 81513531Sjairo.balart@metempsy.com if (size == 4) { 81613531Sjairo.balart@metempsy.com if (addr & 7) { // high half of 64 bit register 81713531Sjairo.balart@metempsy.com irqAffinityRouting[int_id] = 81813531Sjairo.balart@metempsy.com (irqAffinityRouting[int_id] & 0xffffffff) | (data << 32); 81913531Sjairo.balart@metempsy.com } else { // low half of 64 bit register 82013531Sjairo.balart@metempsy.com irqAffinityRouting[int_id] = 82113531Sjairo.balart@metempsy.com (irqAffinityRouting[int_id] & 0xffffffff00000000) | 82213531Sjairo.balart@metempsy.com (data & 0xffffffff); 82313531Sjairo.balart@metempsy.com } 82413531Sjairo.balart@metempsy.com } else { 82513531Sjairo.balart@metempsy.com irqAffinityRouting[int_id] = data; 82613531Sjairo.balart@metempsy.com } 82713531Sjairo.balart@metempsy.com 82813531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): " 82913531Sjairo.balart@metempsy.com "int_id %d GICD_IROUTER %#llx\n", 83013531Sjairo.balart@metempsy.com int_id, irqAffinityRouting[int_id]); 83113531Sjairo.balart@metempsy.com return; 83213531Sjairo.balart@metempsy.com } 83313531Sjairo.balart@metempsy.com 83413531Sjairo.balart@metempsy.com switch (addr) { 83513531Sjairo.balart@metempsy.com case GICD_CTLR: // Control Register 83613531Sjairo.balart@metempsy.com if (DS) { 83713531Sjairo.balart@metempsy.com /* 83813531Sjairo.balart@metempsy.com * E1NWF [7] 83913531Sjairo.balart@metempsy.com * 1 of N wakeup functionality not supported, RAZ/WI 84013531Sjairo.balart@metempsy.com * DS [6] - RAO/WI 84113531Sjairo.balart@metempsy.com * ARE [4] 84213531Sjairo.balart@metempsy.com * affinity routing always on, no GICv2 legacy, RAO/WI 84313531Sjairo.balart@metempsy.com * EnableGrp1 [1] 84413531Sjairo.balart@metempsy.com * EnableGrp0 [0] 84513531Sjairo.balart@metempsy.com */ 84613531Sjairo.balart@metempsy.com if ((data & (1 << 4)) == 0) { 84713531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 84813531Sjairo.balart@metempsy.com "setting ARE to 0 is not supported!\n"); 84913531Sjairo.balart@metempsy.com } 85013531Sjairo.balart@metempsy.com 85113531Sjairo.balart@metempsy.com EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1NS; 85213531Sjairo.balart@metempsy.com EnableGrp0 = data & GICD_CTLR_ENABLEGRP0; 85313531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): (DS 1)" 85413531Sjairo.balart@metempsy.com "EnableGrp1NS %d EnableGrp0 %d\n", 85513531Sjairo.balart@metempsy.com EnableGrp1NS, EnableGrp0); 85613531Sjairo.balart@metempsy.com } else { 85713531Sjairo.balart@metempsy.com if (is_secure_access) { 85813531Sjairo.balart@metempsy.com /* 85913531Sjairo.balart@metempsy.com * E1NWF [7] 86013531Sjairo.balart@metempsy.com * 1 of N wakeup functionality not supported, RAZ/WI 86113531Sjairo.balart@metempsy.com * DS [6] 86213531Sjairo.balart@metempsy.com * ARE_NS [5] 86313531Sjairo.balart@metempsy.com * affinity routing always on, no GICv2 legacy, RAO/WI 86413531Sjairo.balart@metempsy.com * ARE_S [4] 86513531Sjairo.balart@metempsy.com * affinity routing always on, no GICv2 legacy, RAO/WI 86613531Sjairo.balart@metempsy.com * EnableGrp1S [2] 86713531Sjairo.balart@metempsy.com * EnableGrp1NS [1] 86813531Sjairo.balart@metempsy.com * EnableGrp0 [0] 86913531Sjairo.balart@metempsy.com */ 87013531Sjairo.balart@metempsy.com if ((data & (1 << 5)) == 0) { 87113531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 87213531Sjairo.balart@metempsy.com "setting ARE_NS to 0 is not supported!\n"); 87313531Sjairo.balart@metempsy.com } 87413531Sjairo.balart@metempsy.com 87513531Sjairo.balart@metempsy.com if ((data & (1 << 4)) == 0) { 87613531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 87713531Sjairo.balart@metempsy.com "setting ARE_S to 0 is not supported!\n"); 87813531Sjairo.balart@metempsy.com } 87913531Sjairo.balart@metempsy.com 88013531Sjairo.balart@metempsy.com DS = data & GICD_CTLR_DS; 88113531Sjairo.balart@metempsy.com EnableGrp1S = data & GICD_CTLR_ENABLEGRP1S; 88213531Sjairo.balart@metempsy.com EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1NS; 88313531Sjairo.balart@metempsy.com EnableGrp0 = data & GICD_CTLR_ENABLEGRP0; 88413531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): (DS 0 secure)" 88513531Sjairo.balart@metempsy.com "DS %d " 88613531Sjairo.balart@metempsy.com "EnableGrp1S %d EnableGrp1NS %d EnableGrp0 %d\n", 88713531Sjairo.balart@metempsy.com DS, EnableGrp1S, EnableGrp1NS, EnableGrp0); 88813531Sjairo.balart@metempsy.com 88913531Sjairo.balart@metempsy.com if (data & GICD_CTLR_DS) { 89013531Sjairo.balart@metempsy.com EnableGrp1S = 0; 89113531Sjairo.balart@metempsy.com } 89213531Sjairo.balart@metempsy.com } else { 89313531Sjairo.balart@metempsy.com /* 89413531Sjairo.balart@metempsy.com * ARE_NS [4] RAO/WI; 89513531Sjairo.balart@metempsy.com * EnableGrp1A [1] is a read-write alias of the Secure 89613531Sjairo.balart@metempsy.com * GICD_CTLR.EnableGrp1NS 89713531Sjairo.balart@metempsy.com * EnableGrp1 [0] RES0 89813531Sjairo.balart@metempsy.com */ 89913531Sjairo.balart@metempsy.com if ((data & (1 << 4)) == 0) { 90013531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 90113531Sjairo.balart@metempsy.com "setting ARE_NS to 0 is not supported!\n"); 90213531Sjairo.balart@metempsy.com } 90313531Sjairo.balart@metempsy.com 90413531Sjairo.balart@metempsy.com EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1A; 90513531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): (DS 0 non-secure)" 90613531Sjairo.balart@metempsy.com "EnableGrp1NS %d\n", EnableGrp1NS); 90713531Sjairo.balart@metempsy.com } 90813531Sjairo.balart@metempsy.com } 90913531Sjairo.balart@metempsy.com 91014232Sgiacomo.travaglini@arm.com update(); 91114232Sgiacomo.travaglini@arm.com 91213531Sjairo.balart@metempsy.com break; 91313531Sjairo.balart@metempsy.com 91414251Sgiacomo.travaglini@arm.com case GICD_SGIR: // Error Reporting Status Register 91514251Sgiacomo.travaglini@arm.com // Only if affinity routing is disabled, RES0 91614251Sgiacomo.travaglini@arm.com break; 91714251Sgiacomo.travaglini@arm.com 91814253Sgiacomo.travaglini@arm.com case GICD_SETSPI_NSR: { 91914253Sgiacomo.travaglini@arm.com // Writes to this register have no effect if: 92014253Sgiacomo.travaglini@arm.com // * The value written specifies an invalid SPI. 92114253Sgiacomo.travaglini@arm.com // * The SPI is already pending. 92214253Sgiacomo.travaglini@arm.com // * The value written specifies a Secure SPI, the value is 92314253Sgiacomo.travaglini@arm.com // written by a Non-secure access, and the value of the 92414253Sgiacomo.travaglini@arm.com // corresponding GICD_NSACR<n> register is 0. 92514253Sgiacomo.travaglini@arm.com const uint32_t intid = bits(data, 9, 0); 92614253Sgiacomo.travaglini@arm.com if (isNotSPI(intid) || irqPending[intid] || 92714253Sgiacomo.travaglini@arm.com (nsAccessToSecInt(intid, is_secure_access) && 92814253Sgiacomo.travaglini@arm.com irqNsacr[intid] == 0)) { 92914253Sgiacomo.travaglini@arm.com return; 93014253Sgiacomo.travaglini@arm.com } else { 93114253Sgiacomo.travaglini@arm.com // Valid SPI, set interrupt pending 93214253Sgiacomo.travaglini@arm.com sendInt(intid); 93314253Sgiacomo.travaglini@arm.com } 93414253Sgiacomo.travaglini@arm.com break; 93514253Sgiacomo.travaglini@arm.com } 93614253Sgiacomo.travaglini@arm.com 93714253Sgiacomo.travaglini@arm.com case GICD_CLRSPI_NSR: { 93814253Sgiacomo.travaglini@arm.com // Writes to this register have no effect if: 93914253Sgiacomo.travaglini@arm.com // * The value written specifies an invalid SPI. 94014253Sgiacomo.travaglini@arm.com // * The SPI is not pending. 94114253Sgiacomo.travaglini@arm.com // * The value written specifies a Secure SPI, the value is 94214253Sgiacomo.travaglini@arm.com // written by a Non-secure access, and the value of the 94314253Sgiacomo.travaglini@arm.com // corresponding GICD_NSACR<n> register is less than 0b10. 94414253Sgiacomo.travaglini@arm.com const uint32_t intid = bits(data, 9, 0); 94514253Sgiacomo.travaglini@arm.com if (isNotSPI(intid) || !irqPending[intid] || 94614253Sgiacomo.travaglini@arm.com (nsAccessToSecInt(intid, is_secure_access) && 94714253Sgiacomo.travaglini@arm.com irqNsacr[intid] < 2)) { 94814253Sgiacomo.travaglini@arm.com return; 94914253Sgiacomo.travaglini@arm.com } else { 95014253Sgiacomo.travaglini@arm.com // Valid SPI, clear interrupt pending 95114253Sgiacomo.travaglini@arm.com deassertSPI(intid); 95214253Sgiacomo.travaglini@arm.com } 95314253Sgiacomo.travaglini@arm.com break; 95414253Sgiacomo.travaglini@arm.com } 95514253Sgiacomo.travaglini@arm.com 95614253Sgiacomo.travaglini@arm.com case GICD_SETSPI_SR: { 95714253Sgiacomo.travaglini@arm.com // Writes to this register have no effect if: 95814253Sgiacomo.travaglini@arm.com // * GICD_CTLR.DS = 1 (WI) 95914253Sgiacomo.travaglini@arm.com // * The value written specifies an invalid SPI. 96014253Sgiacomo.travaglini@arm.com // * The SPI is already pending. 96114253Sgiacomo.travaglini@arm.com // * The value is written by a Non-secure access. 96214253Sgiacomo.travaglini@arm.com const uint32_t intid = bits(data, 9, 0); 96314253Sgiacomo.travaglini@arm.com if (DS || isNotSPI(intid) || irqPending[intid] || !is_secure_access) { 96414253Sgiacomo.travaglini@arm.com return; 96514253Sgiacomo.travaglini@arm.com } else { 96614253Sgiacomo.travaglini@arm.com // Valid SPI, set interrupt pending 96714253Sgiacomo.travaglini@arm.com sendInt(intid); 96814253Sgiacomo.travaglini@arm.com } 96914253Sgiacomo.travaglini@arm.com break; 97014253Sgiacomo.travaglini@arm.com } 97114253Sgiacomo.travaglini@arm.com 97214253Sgiacomo.travaglini@arm.com case GICD_CLRSPI_SR: { 97314253Sgiacomo.travaglini@arm.com // Writes to this register have no effect if: 97414253Sgiacomo.travaglini@arm.com // * GICD_CTLR.DS = 1 (WI) 97514253Sgiacomo.travaglini@arm.com // * The value written specifies an invalid SPI. 97614253Sgiacomo.travaglini@arm.com // * The SPI is not pending. 97714253Sgiacomo.travaglini@arm.com // * The value is written by a Non-secure access. 97814253Sgiacomo.travaglini@arm.com const uint32_t intid = bits(data, 9, 0); 97914253Sgiacomo.travaglini@arm.com if (DS || isNotSPI(intid) || !irqPending[intid] || !is_secure_access) { 98014253Sgiacomo.travaglini@arm.com return; 98114253Sgiacomo.travaglini@arm.com } else { 98214253Sgiacomo.travaglini@arm.com // Valid SPI, clear interrupt pending 98314253Sgiacomo.travaglini@arm.com deassertSPI(intid); 98414253Sgiacomo.travaglini@arm.com } 98514253Sgiacomo.travaglini@arm.com break; 98614253Sgiacomo.travaglini@arm.com } 98714253Sgiacomo.travaglini@arm.com 98813531Sjairo.balart@metempsy.com default: 98913531Sjairo.balart@metempsy.com panic("Gicv3Distributor::write(): invalid offset %#x\n", addr); 99013531Sjairo.balart@metempsy.com break; 99113531Sjairo.balart@metempsy.com } 99213531Sjairo.balart@metempsy.com} 99313531Sjairo.balart@metempsy.com 99413531Sjairo.balart@metempsy.comvoid 99513531Sjairo.balart@metempsy.comGicv3Distributor::sendInt(uint32_t int_id) 99613531Sjairo.balart@metempsy.com{ 99713531Sjairo.balart@metempsy.com panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!"); 99813531Sjairo.balart@metempsy.com panic_if(int_id > itLines, "Invalid SPI!"); 99913531Sjairo.balart@metempsy.com irqPending[int_id] = true; 100013531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::sendInt(): " 100113531Sjairo.balart@metempsy.com "int_id %d (SPI) pending bit set\n", int_id); 100214231Sgiacomo.travaglini@arm.com update(); 100313531Sjairo.balart@metempsy.com} 100413531Sjairo.balart@metempsy.com 100513531Sjairo.balart@metempsy.comvoid 100613756Sjairo.balart@metempsy.comGicv3Distributor::deassertSPI(uint32_t int_id) 100713531Sjairo.balart@metempsy.com{ 100813531Sjairo.balart@metempsy.com panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!"); 100913531Sjairo.balart@metempsy.com panic_if(int_id > itLines, "Invalid SPI!"); 101013531Sjairo.balart@metempsy.com irqPending[int_id] = false; 101114231Sgiacomo.travaglini@arm.com clearIrqCpuInterface(int_id); 101214231Sgiacomo.travaglini@arm.com 101314231Sgiacomo.travaglini@arm.com update(); 101413531Sjairo.balart@metempsy.com} 101513531Sjairo.balart@metempsy.com 101614231Sgiacomo.travaglini@arm.comGicv3CPUInterface* 101714231Sgiacomo.travaglini@arm.comGicv3Distributor::route(uint32_t int_id) 101813531Sjairo.balart@metempsy.com{ 101914231Sgiacomo.travaglini@arm.com IROUTER affinity_routing = irqAffinityRouting[int_id]; 102014231Sgiacomo.travaglini@arm.com Gicv3Redistributor * target_redistributor = nullptr; 102113531Sjairo.balart@metempsy.com 102214231Sgiacomo.travaglini@arm.com const Gicv3::GroupId int_group = getIntGroup(int_id); 102314231Sgiacomo.travaglini@arm.com 102414231Sgiacomo.travaglini@arm.com if (affinity_routing.IRM) { 102514231Sgiacomo.travaglini@arm.com // Interrupts routed to any PE defined as a participating node 102614231Sgiacomo.travaglini@arm.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 102714231Sgiacomo.travaglini@arm.com Gicv3Redistributor * redistributor_i = 102814231Sgiacomo.travaglini@arm.com gic->getRedistributor(i); 102914231Sgiacomo.travaglini@arm.com 103014231Sgiacomo.travaglini@arm.com if (redistributor_i-> 103114231Sgiacomo.travaglini@arm.com canBeSelectedFor1toNInterrupt(int_group)) { 103214231Sgiacomo.travaglini@arm.com target_redistributor = redistributor_i; 103314231Sgiacomo.travaglini@arm.com break; 103414231Sgiacomo.travaglini@arm.com } 103514231Sgiacomo.travaglini@arm.com } 103614231Sgiacomo.travaglini@arm.com } else { 103714231Sgiacomo.travaglini@arm.com uint32_t affinity = (affinity_routing.Aff3 << 24) | 103814231Sgiacomo.travaglini@arm.com (affinity_routing.Aff2 << 16) | 103914231Sgiacomo.travaglini@arm.com (affinity_routing.Aff1 << 8) | 104014231Sgiacomo.travaglini@arm.com (affinity_routing.Aff0 << 0); 104114231Sgiacomo.travaglini@arm.com target_redistributor = 104214231Sgiacomo.travaglini@arm.com gic->getRedistributorByAffinity(affinity); 104314231Sgiacomo.travaglini@arm.com } 104414231Sgiacomo.travaglini@arm.com 104514231Sgiacomo.travaglini@arm.com if (!target_redistributor) { 104614231Sgiacomo.travaglini@arm.com // Interrrupts targeting not present cpus must remain pending 104714231Sgiacomo.travaglini@arm.com return nullptr; 104814231Sgiacomo.travaglini@arm.com } else { 104914231Sgiacomo.travaglini@arm.com return target_redistributor->getCPUInterface(); 105013531Sjairo.balart@metempsy.com } 105113531Sjairo.balart@metempsy.com} 105213531Sjairo.balart@metempsy.com 105313531Sjairo.balart@metempsy.comvoid 105414231Sgiacomo.travaglini@arm.comGicv3Distributor::clearIrqCpuInterface(uint32_t int_id) 105513531Sjairo.balart@metempsy.com{ 105614231Sgiacomo.travaglini@arm.com auto cpu_interface = route(int_id); 105714231Sgiacomo.travaglini@arm.com if (cpu_interface) 105814231Sgiacomo.travaglini@arm.com cpu_interface->hppi.prio = 0xff; 105913531Sjairo.balart@metempsy.com} 106013531Sjairo.balart@metempsy.com 106113531Sjairo.balart@metempsy.comvoid 106213531Sjairo.balart@metempsy.comGicv3Distributor::update() 106313531Sjairo.balart@metempsy.com{ 106413531Sjairo.balart@metempsy.com // Find the highest priority pending SPI 106513531Sjairo.balart@metempsy.com for (int int_id = Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id < itLines; 106613756Sjairo.balart@metempsy.com int_id++) { 106713531Sjairo.balart@metempsy.com Gicv3::GroupId int_group = getIntGroup(int_id); 106813531Sjairo.balart@metempsy.com bool group_enabled = groupEnabled(int_group); 106913531Sjairo.balart@metempsy.com 107013531Sjairo.balart@metempsy.com if (irqPending[int_id] && irqEnabled[int_id] && 107113756Sjairo.balart@metempsy.com !irqActive[int_id] && group_enabled) { 107213531Sjairo.balart@metempsy.com 107314231Sgiacomo.travaglini@arm.com // Find the cpu interface where to route the interrupt 107414231Sgiacomo.travaglini@arm.com Gicv3CPUInterface *target_cpu_interface = route(int_id); 107513531Sjairo.balart@metempsy.com 107614231Sgiacomo.travaglini@arm.com // Invalid routing 107714231Sgiacomo.travaglini@arm.com if (!target_cpu_interface) continue; 107813531Sjairo.balart@metempsy.com 107913531Sjairo.balart@metempsy.com if ((irqPriority[int_id] < target_cpu_interface->hppi.prio) || 108013756Sjairo.balart@metempsy.com (irqPriority[int_id] == target_cpu_interface->hppi.prio && 108113756Sjairo.balart@metempsy.com int_id < target_cpu_interface->hppi.intid)) { 108214231Sgiacomo.travaglini@arm.com 108313531Sjairo.balart@metempsy.com target_cpu_interface->hppi.intid = int_id; 108413531Sjairo.balart@metempsy.com target_cpu_interface->hppi.prio = irqPriority[int_id]; 108513531Sjairo.balart@metempsy.com target_cpu_interface->hppi.group = int_group; 108613531Sjairo.balart@metempsy.com } 108713531Sjairo.balart@metempsy.com } 108813531Sjairo.balart@metempsy.com } 108913531Sjairo.balart@metempsy.com 109014231Sgiacomo.travaglini@arm.com // Update all redistributors 109113531Sjairo.balart@metempsy.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 109214231Sgiacomo.travaglini@arm.com gic->getRedistributor(i)->update(); 109313531Sjairo.balart@metempsy.com } 109413531Sjairo.balart@metempsy.com} 109513531Sjairo.balart@metempsy.com 109613531Sjairo.balart@metempsy.comGicv3::IntStatus 109713756Sjairo.balart@metempsy.comGicv3Distributor::intStatus(uint32_t int_id) const 109813531Sjairo.balart@metempsy.com{ 109913531Sjairo.balart@metempsy.com panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!"); 110013531Sjairo.balart@metempsy.com panic_if(int_id > itLines, "Invalid SPI!"); 110113531Sjairo.balart@metempsy.com 110213531Sjairo.balart@metempsy.com if (irqPending[int_id]) { 110313531Sjairo.balart@metempsy.com if (irqActive[int_id]) { 110413531Sjairo.balart@metempsy.com return Gicv3::INT_ACTIVE_PENDING; 110513531Sjairo.balart@metempsy.com } 110613531Sjairo.balart@metempsy.com 110713531Sjairo.balart@metempsy.com return Gicv3::INT_PENDING; 110813531Sjairo.balart@metempsy.com } else if (irqActive[int_id]) { 110913531Sjairo.balart@metempsy.com return Gicv3::INT_ACTIVE; 111013531Sjairo.balart@metempsy.com } else { 111113531Sjairo.balart@metempsy.com return Gicv3::INT_INACTIVE; 111213531Sjairo.balart@metempsy.com } 111313531Sjairo.balart@metempsy.com} 111413531Sjairo.balart@metempsy.com 111513531Sjairo.balart@metempsy.comGicv3::GroupId 111613756Sjairo.balart@metempsy.comGicv3Distributor::getIntGroup(int int_id) const 111713531Sjairo.balart@metempsy.com{ 111813531Sjairo.balart@metempsy.com panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!"); 111913531Sjairo.balart@metempsy.com panic_if(int_id > itLines, "Invalid SPI!"); 112013531Sjairo.balart@metempsy.com 112113531Sjairo.balart@metempsy.com if (DS) { 112213531Sjairo.balart@metempsy.com if (irqGroup[int_id] == 1) { 112313531Sjairo.balart@metempsy.com return Gicv3::G1NS; 112413531Sjairo.balart@metempsy.com } else { 112513531Sjairo.balart@metempsy.com return Gicv3::G0S; 112613531Sjairo.balart@metempsy.com } 112713531Sjairo.balart@metempsy.com } else { 112813531Sjairo.balart@metempsy.com if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 0) { 112913531Sjairo.balart@metempsy.com return Gicv3::G0S; 113013531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 1) { 113113531Sjairo.balart@metempsy.com return Gicv3::G1NS; 113213531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 0) { 113313531Sjairo.balart@metempsy.com return Gicv3::G1S; 113413531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 1) { 113513531Sjairo.balart@metempsy.com return Gicv3::G1NS; 113613531Sjairo.balart@metempsy.com } 113713531Sjairo.balart@metempsy.com } 113813531Sjairo.balart@metempsy.com 113913531Sjairo.balart@metempsy.com M5_UNREACHABLE; 114013531Sjairo.balart@metempsy.com} 114113531Sjairo.balart@metempsy.com 114213531Sjairo.balart@metempsy.comvoid 114313531Sjairo.balart@metempsy.comGicv3Distributor::activateIRQ(uint32_t int_id) 114413531Sjairo.balart@metempsy.com{ 114513531Sjairo.balart@metempsy.com irqPending[int_id] = false; 114613531Sjairo.balart@metempsy.com irqActive[int_id] = true; 114713531Sjairo.balart@metempsy.com} 114813531Sjairo.balart@metempsy.com 114913531Sjairo.balart@metempsy.comvoid 115013531Sjairo.balart@metempsy.comGicv3Distributor::deactivateIRQ(uint32_t int_id) 115113531Sjairo.balart@metempsy.com{ 115213531Sjairo.balart@metempsy.com irqActive[int_id] = false; 115313531Sjairo.balart@metempsy.com} 115413531Sjairo.balart@metempsy.com 115513531Sjairo.balart@metempsy.comvoid 115613531Sjairo.balart@metempsy.comGicv3Distributor::serialize(CheckpointOut & cp) const 115713531Sjairo.balart@metempsy.com{ 115813531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(ARE); 115913531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(DS); 116013531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(EnableGrp1S); 116113531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(EnableGrp1NS); 116213531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(EnableGrp0); 116313531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqGroup); 116413531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqEnabled); 116513531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqPending); 116613531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqActive); 116713531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqPriority); 116813531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqConfig); 116913531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqGrpmod); 117013531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqNsacr); 117113531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqAffinityRouting); 117213531Sjairo.balart@metempsy.com} 117313531Sjairo.balart@metempsy.com 117413531Sjairo.balart@metempsy.comvoid 117513531Sjairo.balart@metempsy.comGicv3Distributor::unserialize(CheckpointIn & cp) 117613531Sjairo.balart@metempsy.com{ 117713531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(ARE); 117813531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(DS); 117913531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(EnableGrp1S); 118013531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(EnableGrp1NS); 118113531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(EnableGrp0); 118213531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqGroup); 118313531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqEnabled); 118413531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqPending); 118513531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqActive); 118613531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqPriority); 118713531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqConfig); 118813531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqGrpmod); 118913531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqNsacr); 119013531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqAffinityRouting); 119113531Sjairo.balart@metempsy.com} 1192