gic_v3_distributor.cc revision 13927
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 */ 3013756Sjairo.balart@metempsy.com 3113531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_distributor.hh" 3213531Sjairo.balart@metempsy.com 3313531Sjairo.balart@metempsy.com#include <algorithm> 3413531Sjairo.balart@metempsy.com 3513531Sjairo.balart@metempsy.com#include "debug/GIC.hh" 3613531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh" 3713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_cpu_interface.hh" 3813531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3_redistributor.hh" 3913531Sjairo.balart@metempsy.com 4013756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_IGROUPR (0x0080, 0x00ff); 4113756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ISENABLER (0x0100, 0x017f); 4213756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ICENABLER (0x0180, 0x01ff); 4313756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ISPENDR (0x0200, 0x027f); 4413756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ICPENDR (0x0280, 0x02ff); 4513756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ISACTIVER (0x0300, 0x037f); 4613756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ICACTIVER (0x0380, 0x03ff); 4713531Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_IPRIORITYR(0x0400, 0x07ff); 4813756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ITARGETSR (0x0800, 0x08ff); 4913756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_ICFGR (0x0c00, 0x0cff); 5013756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_IGRPMODR (0x0d00, 0x0d7f); 5113756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_NSACR (0x0e00, 0x0eff); 5213756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_CPENDSGIR (0x0f10, 0x0f1f); 5313756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_SPENDSGIR (0x0f20, 0x0f2f); 5413756Sjairo.balart@metempsy.comconst AddrRange Gicv3Distributor::GICD_IROUTER (0x6000, 0x7fe0); 5513531Sjairo.balart@metempsy.com 5613531Sjairo.balart@metempsy.comGicv3Distributor::Gicv3Distributor(Gicv3 * gic, uint32_t it_lines) 5713531Sjairo.balart@metempsy.com : gic(gic), 5813531Sjairo.balart@metempsy.com itLines(it_lines), 5913531Sjairo.balart@metempsy.com irqGroup(it_lines), 6013531Sjairo.balart@metempsy.com irqEnabled(it_lines), 6113531Sjairo.balart@metempsy.com irqPending(it_lines), 6213531Sjairo.balart@metempsy.com irqActive(it_lines), 6313531Sjairo.balart@metempsy.com irqPriority(it_lines), 6413531Sjairo.balart@metempsy.com irqConfig(it_lines), 6513531Sjairo.balart@metempsy.com irqGrpmod(it_lines), 6613531Sjairo.balart@metempsy.com irqNsacr(it_lines), 6713531Sjairo.balart@metempsy.com irqAffinityRouting(it_lines) 6813531Sjairo.balart@metempsy.com{ 6913531Sjairo.balart@metempsy.com panic_if(it_lines > Gicv3::INTID_SECURE, "Invalid value for it_lines!"); 7013531Sjairo.balart@metempsy.com} 7113531Sjairo.balart@metempsy.com 7213531Sjairo.balart@metempsy.comvoid 7313531Sjairo.balart@metempsy.comGicv3Distributor::init() 7413531Sjairo.balart@metempsy.com{ 7513531Sjairo.balart@metempsy.com} 7613531Sjairo.balart@metempsy.com 7713531Sjairo.balart@metempsy.comvoid 7813531Sjairo.balart@metempsy.comGicv3Distributor::initState() 7913531Sjairo.balart@metempsy.com{ 8013531Sjairo.balart@metempsy.com reset(); 8113531Sjairo.balart@metempsy.com} 8213531Sjairo.balart@metempsy.com 8313531Sjairo.balart@metempsy.comvoid 8413531Sjairo.balart@metempsy.comGicv3Distributor::reset() 8513531Sjairo.balart@metempsy.com{ 8613531Sjairo.balart@metempsy.com std::fill(irqGroup.begin(), irqGroup.end(), 0); 8713531Sjairo.balart@metempsy.com // Imp. defined reset value 8813531Sjairo.balart@metempsy.com std::fill(irqEnabled.begin(), irqEnabled.end(), false); 8913531Sjairo.balart@metempsy.com std::fill(irqPending.begin(), irqPending.end(), false); 9013531Sjairo.balart@metempsy.com std::fill(irqActive.begin(), irqActive.end(), false); 9113531Sjairo.balart@metempsy.com // Imp. defined reset value 9213531Sjairo.balart@metempsy.com std::fill(irqPriority.begin(), irqPriority.end(), 0xAAAAAAAA); 9313531Sjairo.balart@metempsy.com std::fill(irqConfig.begin(), irqConfig.end(), 9413531Sjairo.balart@metempsy.com Gicv3::INT_LEVEL_SENSITIVE); // Imp. defined reset value 9513531Sjairo.balart@metempsy.com std::fill(irqGrpmod.begin(), irqGrpmod.end(), 0); 9613531Sjairo.balart@metempsy.com std::fill(irqNsacr.begin(), irqNsacr.end(), 0); 9713531Sjairo.balart@metempsy.com /* 9813531Sjairo.balart@metempsy.com * For our implementation affinity routing is always enabled, 9913531Sjairo.balart@metempsy.com * no GICv2 legacy 10013531Sjairo.balart@metempsy.com */ 10113531Sjairo.balart@metempsy.com ARE = true; 10213531Sjairo.balart@metempsy.com 10313531Sjairo.balart@metempsy.com if (gic->getSystem()->haveSecurity()) { 10413531Sjairo.balart@metempsy.com DS = false; 10513531Sjairo.balart@metempsy.com } else { 10613531Sjairo.balart@metempsy.com DS = true; 10713531Sjairo.balart@metempsy.com } 10813531Sjairo.balart@metempsy.com 10913531Sjairo.balart@metempsy.com EnableGrp0 = 0; 11013531Sjairo.balart@metempsy.com EnableGrp1NS = 0; 11113531Sjairo.balart@metempsy.com EnableGrp1S = 0; 11213531Sjairo.balart@metempsy.com} 11313531Sjairo.balart@metempsy.com 11413531Sjairo.balart@metempsy.comuint64_t 11513531Sjairo.balart@metempsy.comGicv3Distributor::read(Addr addr, size_t size, bool is_secure_access) 11613531Sjairo.balart@metempsy.com{ 11713531Sjairo.balart@metempsy.com if (GICD_IGROUPR.contains(addr)) { // Interrupt Group Registers 11813531Sjairo.balart@metempsy.com uint64_t val = 0x0; 11913531Sjairo.balart@metempsy.com 12013531Sjairo.balart@metempsy.com if (!DS && !is_secure_access) { 12113531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 12213531Sjairo.balart@metempsy.com return 0; 12313531Sjairo.balart@metempsy.com } 12413531Sjairo.balart@metempsy.com 12513531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_IGROUPR.start()) * 8; 12613531Sjairo.balart@metempsy.com 12713531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 12813531Sjairo.balart@metempsy.com return 0; 12913531Sjairo.balart@metempsy.com } 13013531Sjairo.balart@metempsy.com 13113531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 13213756Sjairo.balart@metempsy.com i++, int_id++) { 13313531Sjairo.balart@metempsy.com val |= irqGroup[int_id] << i; 13413531Sjairo.balart@metempsy.com } 13513531Sjairo.balart@metempsy.com 13613531Sjairo.balart@metempsy.com return val; 13713756Sjairo.balart@metempsy.com } else if (GICD_ISENABLER.contains(addr)) { 13813531Sjairo.balart@metempsy.com // Interrupt Set-Enable Registers 13913531Sjairo.balart@metempsy.com uint64_t val = 0x0; 14013531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISENABLER.start()) * 8; 14113531Sjairo.balart@metempsy.com 14213531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 14313531Sjairo.balart@metempsy.com return 0; 14413531Sjairo.balart@metempsy.com } 14513531Sjairo.balart@metempsy.com 14613531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 14713756Sjairo.balart@metempsy.com i++, int_id++) { 14813756Sjairo.balart@metempsy.com 14913531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 15013531Sjairo.balart@metempsy.com { 15113531Sjairo.balart@metempsy.com continue; 15213531Sjairo.balart@metempsy.com } 15313531Sjairo.balart@metempsy.com 15413531Sjairo.balart@metempsy.com val |= irqEnabled[int_id] << i; 15513531Sjairo.balart@metempsy.com } 15613531Sjairo.balart@metempsy.com 15713531Sjairo.balart@metempsy.com return val; 15813531Sjairo.balart@metempsy.com } else if (GICD_ICENABLER.contains(addr)) { 15913531Sjairo.balart@metempsy.com // Interrupt Clear-Enable Registers 16013531Sjairo.balart@metempsy.com uint64_t val = 0x0; 16113531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICENABLER.start()) * 8; 16213531Sjairo.balart@metempsy.com 16313531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 16413531Sjairo.balart@metempsy.com return 0; 16513531Sjairo.balart@metempsy.com } 16613531Sjairo.balart@metempsy.com 16713531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 16813756Sjairo.balart@metempsy.com i++, int_id++) { 16913756Sjairo.balart@metempsy.com 17013531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 17113531Sjairo.balart@metempsy.com { 17213531Sjairo.balart@metempsy.com continue; 17313531Sjairo.balart@metempsy.com } 17413531Sjairo.balart@metempsy.com 17513531Sjairo.balart@metempsy.com val |= (irqEnabled[int_id] << i); 17613531Sjairo.balart@metempsy.com } 17713531Sjairo.balart@metempsy.com 17813531Sjairo.balart@metempsy.com return val; 17913531Sjairo.balart@metempsy.com } else if (GICD_ISPENDR.contains(addr)) { 18013756Sjairo.balart@metempsy.com // Interrupt Set-Pending Registers 18113531Sjairo.balart@metempsy.com uint64_t val = 0x0; 18213531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISPENDR.start()) * 8; 18313531Sjairo.balart@metempsy.com 18413531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 18513531Sjairo.balart@metempsy.com return 0; 18613531Sjairo.balart@metempsy.com } 18713531Sjairo.balart@metempsy.com 18813531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 18913756Sjairo.balart@metempsy.com i++, int_id++) { 19013756Sjairo.balart@metempsy.com 19113531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 19213531Sjairo.balart@metempsy.com { 19313531Sjairo.balart@metempsy.com if (irqNsacr[int_id] == 0) { 19413531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 19513531Sjairo.balart@metempsy.com continue; 19613531Sjairo.balart@metempsy.com } 19713531Sjairo.balart@metempsy.com } 19813531Sjairo.balart@metempsy.com 19913531Sjairo.balart@metempsy.com val |= (irqPending[int_id] << i); 20013531Sjairo.balart@metempsy.com } 20113531Sjairo.balart@metempsy.com 20213531Sjairo.balart@metempsy.com return val; 20313531Sjairo.balart@metempsy.com } else if (GICD_ICPENDR.contains(addr)) { 20413756Sjairo.balart@metempsy.com // Interrupt Clear-Pending Registers 20513531Sjairo.balart@metempsy.com uint64_t val = 0x0; 20613531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICPENDR.start()) * 8; 20713531Sjairo.balart@metempsy.com 20813531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 20913531Sjairo.balart@metempsy.com return 0; 21013531Sjairo.balart@metempsy.com } 21113531Sjairo.balart@metempsy.com 21213531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 21313756Sjairo.balart@metempsy.com i++, int_id++) { 21413756Sjairo.balart@metempsy.com 21513531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 21613531Sjairo.balart@metempsy.com { 21713531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 2) { 21813531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 21913531Sjairo.balart@metempsy.com continue; 22013531Sjairo.balart@metempsy.com } 22113531Sjairo.balart@metempsy.com } 22213531Sjairo.balart@metempsy.com 22313531Sjairo.balart@metempsy.com val |= (irqPending[int_id] << i); 22413531Sjairo.balart@metempsy.com } 22513531Sjairo.balart@metempsy.com 22613531Sjairo.balart@metempsy.com return val; 22713756Sjairo.balart@metempsy.com } else if (GICD_ISACTIVER.contains(addr)) { 22813531Sjairo.balart@metempsy.com // Interrupt Set-Active Registers 22913531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISACTIVER.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 uint64_t val = 0x0; 23613531Sjairo.balart@metempsy.com 23713531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 23813756Sjairo.balart@metempsy.com i++, int_id++) { 23913756Sjairo.balart@metempsy.com 24013531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 24113531Sjairo.balart@metempsy.com { 24213531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 24313531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 2) { 24413531Sjairo.balart@metempsy.com continue; 24513531Sjairo.balart@metempsy.com } 24613531Sjairo.balart@metempsy.com } 24713531Sjairo.balart@metempsy.com 24813531Sjairo.balart@metempsy.com val |= (irqActive[int_id] << i); 24913531Sjairo.balart@metempsy.com } 25013531Sjairo.balart@metempsy.com 25113531Sjairo.balart@metempsy.com return val; 25213756Sjairo.balart@metempsy.com } else if (GICD_ICACTIVER.contains(addr)) { 25313531Sjairo.balart@metempsy.com // Interrupt Clear-Active Registers 25413531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICACTIVER.start()) * 8; 25513531Sjairo.balart@metempsy.com 25613531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 25713531Sjairo.balart@metempsy.com return 0; 25813531Sjairo.balart@metempsy.com } 25913531Sjairo.balart@metempsy.com 26013531Sjairo.balart@metempsy.com uint64_t val = 0x0; 26113531Sjairo.balart@metempsy.com 26213531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 26313756Sjairo.balart@metempsy.com i++, int_id++) { 26413756Sjairo.balart@metempsy.com 26513531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 26613531Sjairo.balart@metempsy.com { 26713531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 2) { 26813531Sjairo.balart@metempsy.com continue; 26913531Sjairo.balart@metempsy.com } 27013531Sjairo.balart@metempsy.com } 27113531Sjairo.balart@metempsy.com 27213531Sjairo.balart@metempsy.com val |= (irqActive[int_id] << i); 27313531Sjairo.balart@metempsy.com } 27413531Sjairo.balart@metempsy.com 27513531Sjairo.balart@metempsy.com return val; 27613756Sjairo.balart@metempsy.com } else if (GICD_IPRIORITYR.contains(addr)) { 27713531Sjairo.balart@metempsy.com // Interrupt Priority Registers 27813531Sjairo.balart@metempsy.com uint64_t val = 0x0; 27913531Sjairo.balart@metempsy.com int first_intid = addr - GICD_IPRIORITYR.start(); 28013531Sjairo.balart@metempsy.com 28113531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 28213531Sjairo.balart@metempsy.com return 0; 28313531Sjairo.balart@metempsy.com } 28413531Sjairo.balart@metempsy.com 28513531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < size && int_id < itLines; 28613756Sjairo.balart@metempsy.com i++, int_id++) { 28713756Sjairo.balart@metempsy.com 28813531Sjairo.balart@metempsy.com uint8_t prio = irqPriority[int_id]; 28913531Sjairo.balart@metempsy.com 29013531Sjairo.balart@metempsy.com if (!DS && !is_secure_access) { 29113531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 29213531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses for secure interrupts 29313531Sjairo.balart@metempsy.com continue; 29413531Sjairo.balart@metempsy.com } else { 29513531Sjairo.balart@metempsy.com // NS view 29613531Sjairo.balart@metempsy.com prio = (prio << 1) & 0xff; 29713531Sjairo.balart@metempsy.com } 29813531Sjairo.balart@metempsy.com } 29913531Sjairo.balart@metempsy.com 30013531Sjairo.balart@metempsy.com val |= prio << (i * 8); 30113531Sjairo.balart@metempsy.com } 30213531Sjairo.balart@metempsy.com 30313531Sjairo.balart@metempsy.com return val; 30413531Sjairo.balart@metempsy.com } else if (GICD_ITARGETSR.contains(addr)) { 30513531Sjairo.balart@metempsy.com // Interrupt Processor Targets Registers 30613531Sjairo.balart@metempsy.com // ARE always on, RAZ/WI 30713531Sjairo.balart@metempsy.com warn("Gicv3Distributor::read(): " 30813531Sjairo.balart@metempsy.com "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n"); 30913531Sjairo.balart@metempsy.com return 0; 31013756Sjairo.balart@metempsy.com } else if (GICD_ICFGR.contains(addr)) { 31113531Sjairo.balart@metempsy.com // Interrupt Configuration Registers 31213531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICFGR.start()) * 4; 31313531Sjairo.balart@metempsy.com 31413531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 31513531Sjairo.balart@metempsy.com return 0; 31613531Sjairo.balart@metempsy.com } 31713531Sjairo.balart@metempsy.com 31813531Sjairo.balart@metempsy.com uint64_t val = 0x0; 31913531Sjairo.balart@metempsy.com 32013531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 32113756Sjairo.balart@metempsy.com i = i + 2, int_id++) { 32213756Sjairo.balart@metempsy.com 32313531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 32413531Sjairo.balart@metempsy.com { 32513531Sjairo.balart@metempsy.com continue; 32613531Sjairo.balart@metempsy.com } 32713531Sjairo.balart@metempsy.com 32813531Sjairo.balart@metempsy.com if (irqConfig[int_id] == Gicv3::INT_EDGE_TRIGGERED) { 32913531Sjairo.balart@metempsy.com val |= (0x2 << i); 33013531Sjairo.balart@metempsy.com } 33113531Sjairo.balart@metempsy.com } 33213531Sjairo.balart@metempsy.com 33313531Sjairo.balart@metempsy.com return val; 33413531Sjairo.balart@metempsy.com } else if (GICD_IGRPMODR.contains(addr)) { 33513531Sjairo.balart@metempsy.com // Interrupt Group Modifier Registers 33613531Sjairo.balart@metempsy.com if (DS) { 33713531Sjairo.balart@metempsy.com // RAZ/WI if security disabled 33813531Sjairo.balart@metempsy.com return 0; 33913531Sjairo.balart@metempsy.com } else { 34013531Sjairo.balart@metempsy.com if (!is_secure_access) { 34113531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 34213531Sjairo.balart@metempsy.com return 0; 34313531Sjairo.balart@metempsy.com } else { 34413531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_IGRPMODR.start()) * 8; 34513531Sjairo.balart@metempsy.com 34613531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 34713531Sjairo.balart@metempsy.com return 0; 34813531Sjairo.balart@metempsy.com } 34913531Sjairo.balart@metempsy.com 35013531Sjairo.balart@metempsy.com uint64_t val = 0x0; 35113531Sjairo.balart@metempsy.com 35213531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; 35313756Sjairo.balart@metempsy.com i < 8 * size && int_id < itLines; i++, int_id++) { 35413531Sjairo.balart@metempsy.com val |= irqGrpmod[int_id] << i; 35513531Sjairo.balart@metempsy.com } 35613531Sjairo.balart@metempsy.com 35713531Sjairo.balart@metempsy.com return val; 35813531Sjairo.balart@metempsy.com } 35913531Sjairo.balart@metempsy.com } 36013756Sjairo.balart@metempsy.com } else if (GICD_NSACR.contains(addr)) { 36113531Sjairo.balart@metempsy.com // Non-secure Access Control Registers 36213531Sjairo.balart@metempsy.com // 2 bits per interrupt 36313531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_NSACR.start()) * 4; 36413531Sjairo.balart@metempsy.com 36513531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 36613531Sjairo.balart@metempsy.com return 0; 36713531Sjairo.balart@metempsy.com } 36813531Sjairo.balart@metempsy.com 36913531Sjairo.balart@metempsy.com if (DS || (!DS && !is_secure_access)) { 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 = i + 2, int_id++) { 37713531Sjairo.balart@metempsy.com val |= irqNsacr[int_id] << i; 37813531Sjairo.balart@metempsy.com } 37913531Sjairo.balart@metempsy.com 38013531Sjairo.balart@metempsy.com return val; 38113531Sjairo.balart@metempsy.com } else if (GICD_CPENDSGIR.contains(addr)) { // SGI Clear-Pending Registers 38213531Sjairo.balart@metempsy.com // ARE always on, RAZ/WI 38313531Sjairo.balart@metempsy.com warn("Gicv3Distributor::read(): " 38413531Sjairo.balart@metempsy.com "GICD_CPENDSGIR is RAZ/WI, legacy not supported!\n"); 38513531Sjairo.balart@metempsy.com return 0x0; 38613531Sjairo.balart@metempsy.com } else if (GICD_SPENDSGIR.contains(addr)) { // SGI Set-Pending Registers 38713531Sjairo.balart@metempsy.com // ARE always on, RAZ/WI 38813531Sjairo.balart@metempsy.com warn("Gicv3Distributor::read(): " 38913531Sjairo.balart@metempsy.com "GICD_SPENDSGIR is RAZ/WI, legacy not supported!\n"); 39013531Sjairo.balart@metempsy.com return 0x0; 39113531Sjairo.balart@metempsy.com } else if (GICD_IROUTER.contains(addr)) { // Interrupt Routing Registers 39213531Sjairo.balart@metempsy.com // 64 bit registers. 2 or 1 access. 39313531Sjairo.balart@metempsy.com int int_id = (addr - GICD_IROUTER.start()) / 8; 39413531Sjairo.balart@metempsy.com 39513531Sjairo.balart@metempsy.com if (isNotSPI(int_id)) { 39613531Sjairo.balart@metempsy.com return 0; 39713531Sjairo.balart@metempsy.com } 39813531Sjairo.balart@metempsy.com 39913531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 40013531Sjairo.balart@metempsy.com { 40113531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 3) { 40213531Sjairo.balart@metempsy.com return 0; 40313531Sjairo.balart@metempsy.com } 40413531Sjairo.balart@metempsy.com } 40513531Sjairo.balart@metempsy.com 40613531Sjairo.balart@metempsy.com if (size == 4) { 40713531Sjairo.balart@metempsy.com if (addr & 7) { // high half of 64 bit register 40813531Sjairo.balart@metempsy.com return irqAffinityRouting[int_id] >> 32; 40913531Sjairo.balart@metempsy.com } else { // high low of 64 bit register 41013531Sjairo.balart@metempsy.com return irqAffinityRouting[int_id] & 0xFFFFFFFF; 41113531Sjairo.balart@metempsy.com } 41213531Sjairo.balart@metempsy.com } else { 41313531Sjairo.balart@metempsy.com return irqAffinityRouting[int_id]; 41413531Sjairo.balart@metempsy.com } 41513531Sjairo.balart@metempsy.com } 41613531Sjairo.balart@metempsy.com 41713531Sjairo.balart@metempsy.com switch (addr) { 41813531Sjairo.balart@metempsy.com case GICD_CTLR: // Control Register 41913531Sjairo.balart@metempsy.com if (!DS) { 42013531Sjairo.balart@metempsy.com if (is_secure_access) { 42113531Sjairo.balart@metempsy.com // E1NWF [7] RAZ/WI 42213531Sjairo.balart@metempsy.com // DS [6] - Disable Security 42313531Sjairo.balart@metempsy.com // ARE_NS [5] RAO/WI 42413531Sjairo.balart@metempsy.com // ARE_S [4] RAO/WI 42513531Sjairo.balart@metempsy.com // EnableGrp1S [2] 42613531Sjairo.balart@metempsy.com // EnableGrp1NS [1] 42713531Sjairo.balart@metempsy.com // EnableGrp0 [0] 42813531Sjairo.balart@metempsy.com return (EnableGrp0 << 0) | 42913531Sjairo.balart@metempsy.com (EnableGrp1NS << 1) | 43013531Sjairo.balart@metempsy.com (EnableGrp1S << 2) | 43113531Sjairo.balart@metempsy.com (1 << 4) | 43213531Sjairo.balart@metempsy.com (1 << 5) | 43313531Sjairo.balart@metempsy.com (DS << 6); 43413531Sjairo.balart@metempsy.com } else { 43513531Sjairo.balart@metempsy.com // ARE_NS [4] RAO/WI; 43613531Sjairo.balart@metempsy.com // EnableGrp1A [1] is a read-write alias of the Secure 43713531Sjairo.balart@metempsy.com // GICD_CTLR.EnableGrp1NS 43813531Sjairo.balart@metempsy.com // EnableGrp1 [0] RES0 43913531Sjairo.balart@metempsy.com return (1 << 4) | (EnableGrp1NS << 1); 44013531Sjairo.balart@metempsy.com } 44113531Sjairo.balart@metempsy.com } else { 44213531Sjairo.balart@metempsy.com return (DS << 6) | (ARE << 4) | 44313531Sjairo.balart@metempsy.com (EnableGrp1NS << 1) | (EnableGrp0 << 0); 44413531Sjairo.balart@metempsy.com } 44513531Sjairo.balart@metempsy.com 44613531Sjairo.balart@metempsy.com case GICD_TYPER: // Interrupt Controller Type Register 44713531Sjairo.balart@metempsy.com /* 44813531Sjairo.balart@metempsy.com * RSS [26] == 1 44913531Sjairo.balart@metempsy.com * (The implementation does supports targeted SGIs with affinity 45013531Sjairo.balart@metempsy.com * level 0 values of 0 - 255) 45113531Sjairo.balart@metempsy.com * No1N [25] == 1 45213531Sjairo.balart@metempsy.com * (1 of N SPI interrupts are not supported) 45313531Sjairo.balart@metempsy.com * A3V [24] == 1 45413531Sjairo.balart@metempsy.com * (Supports nonzero values of Affinity level 3) 45513531Sjairo.balart@metempsy.com * IDbits [23:19] == 0xf 45613531Sjairo.balart@metempsy.com * (The number of interrupt identifier bits supported, minus one) 45713531Sjairo.balart@metempsy.com * DVIS [18] == 0 45813531Sjairo.balart@metempsy.com * (The implementation does not support Direct Virtual LPI 45913531Sjairo.balart@metempsy.com * injection) 46013690Sjairo.balart@metempsy.com * LPIS [17] == 1 46113531Sjairo.balart@metempsy.com * (The implementation does not support LPIs) 46213531Sjairo.balart@metempsy.com * MBIS [16] == 0 46313531Sjairo.balart@metempsy.com * (The implementation does not support message-based interrupts 46413531Sjairo.balart@metempsy.com * by writing to Distributor registers) 46513531Sjairo.balart@metempsy.com * SecurityExtn [10] == X 46613531Sjairo.balart@metempsy.com * (The GIC implementation supports two Security states) 46713531Sjairo.balart@metempsy.com * CPUNumber [7:5] == 0 46813531Sjairo.balart@metempsy.com * (since for us ARE is always 1 [(ARE = 0) == Gicv2 legacy]) 46913531Sjairo.balart@metempsy.com * ITLinesNumber [4:0] == N 47013531Sjairo.balart@metempsy.com * (MaxSPIIntId = 32 (N + 1) - 1) 47113531Sjairo.balart@metempsy.com */ 47213531Sjairo.balart@metempsy.com { 47313531Sjairo.balart@metempsy.com int max_spi_int_id = itLines - 1; 47413531Sjairo.balart@metempsy.com int it_lines_number = ceil((max_spi_int_id + 1) / 32.0) - 1; 47513927Sgiacomo.travaglini@arm.com return (1 << 26) | (1 << 25) | (1 << 24) | (IDBITS << 19) | 47613690Sjairo.balart@metempsy.com (1 << 17) | (gic->getSystem()->haveSecurity() << 10) | 47713531Sjairo.balart@metempsy.com (it_lines_number << 0); 47813531Sjairo.balart@metempsy.com } 47913531Sjairo.balart@metempsy.com 48013531Sjairo.balart@metempsy.com case GICD_IIDR: // Implementer Identification Register 48113531Sjairo.balart@metempsy.com //return 0x43b; // ARM JEP106 code (r0p0 GIC-500) 48213531Sjairo.balart@metempsy.com return 0; 48313531Sjairo.balart@metempsy.com 48413531Sjairo.balart@metempsy.com case GICD_STATUSR: // Error Reporting Status Register 48513531Sjairo.balart@metempsy.com // Optional register, RAZ/WI 48613531Sjairo.balart@metempsy.com return 0x0; 48713531Sjairo.balart@metempsy.com 48813756Sjairo.balart@metempsy.com case GICD_PIDR0: // Peripheral ID0 Register 48913756Sjairo.balart@metempsy.com return 0x92; // Part number, bits[7:0] 49013531Sjairo.balart@metempsy.com 49113531Sjairo.balart@metempsy.com case GICD_PIDR1: { // Peripheral ID1 Register 49213531Sjairo.balart@metempsy.com uint8_t des_0 = 0xB; // JEP106 identification code, bits[3:0] 49313531Sjairo.balart@metempsy.com uint8_t part_1 = 0x4; // Part number, bits[11:8] 49413531Sjairo.balart@metempsy.com return (des_0 << 4) | (part_1 << 0); 49513531Sjairo.balart@metempsy.com } 49613531Sjairo.balart@metempsy.com 49713531Sjairo.balart@metempsy.com case GICD_PIDR2: { // Peripheral ID2 Register 49813531Sjairo.balart@metempsy.com uint8_t arch_rev = 0x3; // 0x3 GICv3 49913531Sjairo.balart@metempsy.com uint8_t jdec = 0x1; // JEP code 50013531Sjairo.balart@metempsy.com uint8_t des_1 = 0x3; // JEP106 identification code, bits[6:4] 50113531Sjairo.balart@metempsy.com return (arch_rev << 4) | (jdec << 3) | (des_1 << 0); 50213531Sjairo.balart@metempsy.com } 50313531Sjairo.balart@metempsy.com 50413531Sjairo.balart@metempsy.com case GICD_PIDR3: // Peripheral ID3 Register 50513531Sjairo.balart@metempsy.com return 0x0; // Implementation defined 50613531Sjairo.balart@metempsy.com 50713531Sjairo.balart@metempsy.com case GICD_PIDR4: { // Peripheral ID4 Register 50813531Sjairo.balart@metempsy.com uint8_t size = 0x4; // 64 KB software visible page 50913531Sjairo.balart@metempsy.com uint8_t des_2 = 0x4; // ARM implementation 51013531Sjairo.balart@metempsy.com return (size << 4) | (des_2 << 0); 51113531Sjairo.balart@metempsy.com } 51213531Sjairo.balart@metempsy.com 51313531Sjairo.balart@metempsy.com case GICD_PIDR5: // Peripheral ID5 Register 51413531Sjairo.balart@metempsy.com case GICD_PIDR6: // Peripheral ID6 Register 51513531Sjairo.balart@metempsy.com case GICD_PIDR7: // Peripheral ID7 Register 51613531Sjairo.balart@metempsy.com return 0; // RES0 51713531Sjairo.balart@metempsy.com 51813531Sjairo.balart@metempsy.com default: 51913531Sjairo.balart@metempsy.com panic("Gicv3Distributor::read(): invalid offset %#x\n", addr); 52013531Sjairo.balart@metempsy.com break; 52113531Sjairo.balart@metempsy.com } 52213531Sjairo.balart@metempsy.com} 52313531Sjairo.balart@metempsy.com 52413531Sjairo.balart@metempsy.comvoid 52513531Sjairo.balart@metempsy.comGicv3Distributor::write(Addr addr, uint64_t data, size_t size, 52613531Sjairo.balart@metempsy.com bool is_secure_access) 52713531Sjairo.balart@metempsy.com{ 52813531Sjairo.balart@metempsy.com if (GICD_IGROUPR.contains(addr)) { // Interrupt Group Registers 52913531Sjairo.balart@metempsy.com if (!DS && !is_secure_access) { 53013531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 53113531Sjairo.balart@metempsy.com return; 53213531Sjairo.balart@metempsy.com } 53313531Sjairo.balart@metempsy.com 53413531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_IGROUPR.start()) * 8; 53513531Sjairo.balart@metempsy.com 53613531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 53713531Sjairo.balart@metempsy.com return; 53813531Sjairo.balart@metempsy.com } 53913531Sjairo.balart@metempsy.com 54013531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 54113756Sjairo.balart@metempsy.com i++, int_id++) { 54213531Sjairo.balart@metempsy.com irqGroup[int_id] = data & (1 << i) ? 1 : 0; 54313531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d group %d\n", 54413531Sjairo.balart@metempsy.com int_id, irqGroup[int_id]); 54513531Sjairo.balart@metempsy.com } 54613531Sjairo.balart@metempsy.com 54713531Sjairo.balart@metempsy.com return; 54813756Sjairo.balart@metempsy.com } else if (GICD_ISENABLER.contains(addr)) { 54913531Sjairo.balart@metempsy.com // Interrupt Set-Enable Registers 55013531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISENABLER.start()) * 8; 55113531Sjairo.balart@metempsy.com 55213531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 55313531Sjairo.balart@metempsy.com return; 55413531Sjairo.balart@metempsy.com } 55513531Sjairo.balart@metempsy.com 55613531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 55713756Sjairo.balart@metempsy.com i++, int_id++) { 55813756Sjairo.balart@metempsy.com 55913531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 56013531Sjairo.balart@metempsy.com { 56113531Sjairo.balart@metempsy.com continue; 56213531Sjairo.balart@metempsy.com } 56313531Sjairo.balart@metempsy.com 56413531Sjairo.balart@metempsy.com bool enable = data & (1 << i) ? 1 : 0; 56513531Sjairo.balart@metempsy.com 56613531Sjairo.balart@metempsy.com if (enable) { 56713531Sjairo.balart@metempsy.com if (!irqEnabled[int_id]) { 56813531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): " 56913531Sjairo.balart@metempsy.com "int_id %d enabled\n", int_id); 57013531Sjairo.balart@metempsy.com } 57113531Sjairo.balart@metempsy.com 57213531Sjairo.balart@metempsy.com irqEnabled[int_id] = true; 57313531Sjairo.balart@metempsy.com } 57413531Sjairo.balart@metempsy.com } 57513531Sjairo.balart@metempsy.com 57613531Sjairo.balart@metempsy.com return; 57713531Sjairo.balart@metempsy.com } else if (GICD_ICENABLER.contains(addr)) { 57813531Sjairo.balart@metempsy.com // Interrupt Clear-Enable Registers 57913531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICENABLER.start()) * 8; 58013531Sjairo.balart@metempsy.com 58113812Sgiacomo.travaglini@arm.com if (isNotSPI(first_intid)) { 58213812Sgiacomo.travaglini@arm.com return; 58313812Sgiacomo.travaglini@arm.com } 58413812Sgiacomo.travaglini@arm.com 58513531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 58613756Sjairo.balart@metempsy.com i++, int_id++) { 58713756Sjairo.balart@metempsy.com 58813531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 58913531Sjairo.balart@metempsy.com { 59013531Sjairo.balart@metempsy.com continue; 59113531Sjairo.balart@metempsy.com } 59213531Sjairo.balart@metempsy.com 59313531Sjairo.balart@metempsy.com bool disable = data & (1 << i) ? 1 : 0; 59413531Sjairo.balart@metempsy.com 59513531Sjairo.balart@metempsy.com if (disable) { 59613531Sjairo.balart@metempsy.com if (irqEnabled[int_id]) { 59713531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): " 59813531Sjairo.balart@metempsy.com "int_id %d disabled\n", int_id); 59913531Sjairo.balart@metempsy.com } 60013531Sjairo.balart@metempsy.com 60113531Sjairo.balart@metempsy.com irqEnabled[int_id] = false; 60213531Sjairo.balart@metempsy.com } 60313531Sjairo.balart@metempsy.com } 60413531Sjairo.balart@metempsy.com 60513531Sjairo.balart@metempsy.com return; 60613531Sjairo.balart@metempsy.com } else if (GICD_ISPENDR.contains(addr)) { 60713756Sjairo.balart@metempsy.com // Interrupt Set-Pending Registers 60813531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISPENDR.start()) * 8; 60913531Sjairo.balart@metempsy.com 61013531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 61113531Sjairo.balart@metempsy.com return; 61213531Sjairo.balart@metempsy.com } 61313531Sjairo.balart@metempsy.com 61413531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 61513756Sjairo.balart@metempsy.com i++, int_id++) { 61613756Sjairo.balart@metempsy.com 61713531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 61813531Sjairo.balart@metempsy.com { 61913531Sjairo.balart@metempsy.com if (irqNsacr[int_id] == 0) { 62013531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 62113531Sjairo.balart@metempsy.com continue; 62213531Sjairo.balart@metempsy.com } 62313531Sjairo.balart@metempsy.com } 62413531Sjairo.balart@metempsy.com 62513531Sjairo.balart@metempsy.com bool pending = data & (1 << i) ? 1 : 0; 62613531Sjairo.balart@metempsy.com 62713531Sjairo.balart@metempsy.com if (pending) { 62813531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write() (GICD_ISPENDR): " 62913531Sjairo.balart@metempsy.com "int_id %d (SPI) pending bit set\n", int_id); 63013531Sjairo.balart@metempsy.com irqPending[int_id] = true; 63113531Sjairo.balart@metempsy.com } 63213531Sjairo.balart@metempsy.com } 63313531Sjairo.balart@metempsy.com 63413531Sjairo.balart@metempsy.com updateAndInformCPUInterfaces(); 63513531Sjairo.balart@metempsy.com return; 63613531Sjairo.balart@metempsy.com } else if (GICD_ICPENDR.contains(addr)) { 63713756Sjairo.balart@metempsy.com // Interrupt Clear-Pending Registers 63813531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICPENDR.start()) * 8; 63913531Sjairo.balart@metempsy.com 64013531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 64113531Sjairo.balart@metempsy.com return; 64213531Sjairo.balart@metempsy.com } 64313531Sjairo.balart@metempsy.com 64413531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 64513756Sjairo.balart@metempsy.com i++, int_id++) { 64613756Sjairo.balart@metempsy.com 64713531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 64813531Sjairo.balart@metempsy.com { 64913531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 2) { 65013531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 65113531Sjairo.balart@metempsy.com continue; 65213531Sjairo.balart@metempsy.com } 65313531Sjairo.balart@metempsy.com } 65413531Sjairo.balart@metempsy.com 65513531Sjairo.balart@metempsy.com bool clear = data & (1 << i) ? 1 : 0; 65613531Sjairo.balart@metempsy.com 65713531Sjairo.balart@metempsy.com if (clear) { 65813531Sjairo.balart@metempsy.com irqPending[int_id] = false; 65913531Sjairo.balart@metempsy.com } 66013531Sjairo.balart@metempsy.com } 66113531Sjairo.balart@metempsy.com 66213531Sjairo.balart@metempsy.com updateAndInformCPUInterfaces(); 66313531Sjairo.balart@metempsy.com return; 66413756Sjairo.balart@metempsy.com } else if (GICD_ISACTIVER.contains(addr)) { 66513531Sjairo.balart@metempsy.com // Interrupt Set-Active Registers 66613531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ISACTIVER.start()) * 8; 66713531Sjairo.balart@metempsy.com 66813531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 66913531Sjairo.balart@metempsy.com return; 67013531Sjairo.balart@metempsy.com } 67113531Sjairo.balart@metempsy.com 67213531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 67313756Sjairo.balart@metempsy.com i++, int_id++) { 67413756Sjairo.balart@metempsy.com 67513531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 67613531Sjairo.balart@metempsy.com { 67713531Sjairo.balart@metempsy.com continue; 67813531Sjairo.balart@metempsy.com } 67913531Sjairo.balart@metempsy.com 68013531Sjairo.balart@metempsy.com bool active = data & (1 << i) ? 1 : 0; 68113531Sjairo.balart@metempsy.com 68213531Sjairo.balart@metempsy.com if (active) { 68313531Sjairo.balart@metempsy.com irqActive[int_id] = 1; 68413531Sjairo.balart@metempsy.com } 68513531Sjairo.balart@metempsy.com } 68613531Sjairo.balart@metempsy.com 68713531Sjairo.balart@metempsy.com return; 68813531Sjairo.balart@metempsy.com } else if (GICD_ICACTIVER.contains(addr)) { 68913531Sjairo.balart@metempsy.com // Interrupt Clear-Active Registers 69013531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICACTIVER.start()) * 8; 69113531Sjairo.balart@metempsy.com 69213531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 69313531Sjairo.balart@metempsy.com return; 69413531Sjairo.balart@metempsy.com } 69513531Sjairo.balart@metempsy.com 69613531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 69713756Sjairo.balart@metempsy.com i++, int_id++) { 69813756Sjairo.balart@metempsy.com 69913531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 70013531Sjairo.balart@metempsy.com { 70113531Sjairo.balart@metempsy.com continue; 70213531Sjairo.balart@metempsy.com } 70313531Sjairo.balart@metempsy.com 70413531Sjairo.balart@metempsy.com bool clear = data & (1 << i) ? 1 : 0; 70513531Sjairo.balart@metempsy.com 70613531Sjairo.balart@metempsy.com if (clear) { 70713531Sjairo.balart@metempsy.com if (irqActive[int_id]) { 70813531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): " 70913531Sjairo.balart@metempsy.com "int_id %d active cleared\n", int_id); 71013531Sjairo.balart@metempsy.com } 71113531Sjairo.balart@metempsy.com 71213531Sjairo.balart@metempsy.com irqActive[int_id] = false; 71313531Sjairo.balart@metempsy.com } 71413531Sjairo.balart@metempsy.com } 71513531Sjairo.balart@metempsy.com 71613531Sjairo.balart@metempsy.com return; 71713756Sjairo.balart@metempsy.com } else if (GICD_IPRIORITYR.contains(addr)) { 71813531Sjairo.balart@metempsy.com // Interrupt Priority Registers 71913531Sjairo.balart@metempsy.com int first_intid = addr - GICD_IPRIORITYR.start(); 72013531Sjairo.balart@metempsy.com 72113531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 72213531Sjairo.balart@metempsy.com return; 72313531Sjairo.balart@metempsy.com } 72413531Sjairo.balart@metempsy.com 72513531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < size && int_id < itLines; 72613531Sjairo.balart@metempsy.com i++, int_id++) { 72713531Sjairo.balart@metempsy.com uint8_t prio = bits(data, (i + 1) * 8 - 1, (i * 8)); 72813531Sjairo.balart@metempsy.com 72913531Sjairo.balart@metempsy.com if (!DS && !is_secure_access) { 73013531Sjairo.balart@metempsy.com if (getIntGroup(int_id) != Gicv3::G1NS) { 73113531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses to secure interrupts 73213531Sjairo.balart@metempsy.com continue; 73313531Sjairo.balart@metempsy.com } else { 73413531Sjairo.balart@metempsy.com prio = 0x80 | (prio >> 1); 73513531Sjairo.balart@metempsy.com } 73613531Sjairo.balart@metempsy.com } 73713531Sjairo.balart@metempsy.com 73813531Sjairo.balart@metempsy.com irqPriority[int_id] = prio; 73913531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d priority %d\n", 74013531Sjairo.balart@metempsy.com int_id, irqPriority[int_id]); 74113531Sjairo.balart@metempsy.com } 74213531Sjairo.balart@metempsy.com 74313531Sjairo.balart@metempsy.com return; 74413531Sjairo.balart@metempsy.com } else if (GICD_ITARGETSR.contains(addr)) { 74513531Sjairo.balart@metempsy.com // Interrupt Processor Targets Registers 74613531Sjairo.balart@metempsy.com // ARE always on, RAZ/WI 74713531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 74813531Sjairo.balart@metempsy.com "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n"); 74913531Sjairo.balart@metempsy.com return; 75013756Sjairo.balart@metempsy.com } else if (GICD_ICFGR.contains(addr)) { 75113531Sjairo.balart@metempsy.com // Interrupt Configuration Registers 75213756Sjairo.balart@metempsy.com // for x = 0 to 15: 75313756Sjairo.balart@metempsy.com // GICD_ICFGR[2x] = RES0 75413756Sjairo.balart@metempsy.com // GICD_ICFGR[2x + 1] = 75513756Sjairo.balart@metempsy.com // 0 level-sensitive 75613756Sjairo.balart@metempsy.com // 1 edge-triggered 75713531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_ICFGR.start()) * 4; 75813531Sjairo.balart@metempsy.com 75913531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 76013531Sjairo.balart@metempsy.com return; 76113531Sjairo.balart@metempsy.com } 76213531Sjairo.balart@metempsy.com 76313531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines; 76413756Sjairo.balart@metempsy.com i = i + 2, int_id++) { 76513531Sjairo.balart@metempsy.com irqConfig[int_id] = data & (0x2 << i) ? 76613531Sjairo.balart@metempsy.com Gicv3::INT_EDGE_TRIGGERED : 76713531Sjairo.balart@metempsy.com Gicv3::INT_LEVEL_SENSITIVE; 76813531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d config %d\n", 76913531Sjairo.balart@metempsy.com int_id, irqConfig[int_id]); 77013531Sjairo.balart@metempsy.com } 77113531Sjairo.balart@metempsy.com 77213531Sjairo.balart@metempsy.com return; 77313531Sjairo.balart@metempsy.com } else if (GICD_IGRPMODR.contains(addr)) { 77413531Sjairo.balart@metempsy.com // Interrupt Group Modifier Registers 77513531Sjairo.balart@metempsy.com if (DS) { 77613531Sjairo.balart@metempsy.com return; 77713531Sjairo.balart@metempsy.com } else { 77813531Sjairo.balart@metempsy.com if (!is_secure_access) { 77913531Sjairo.balart@metempsy.com // RAZ/WI for non-secure accesses 78013531Sjairo.balart@metempsy.com return; 78113531Sjairo.balart@metempsy.com } else { 78213531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_IGRPMODR.start()) * 8; 78313531Sjairo.balart@metempsy.com 78413531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 78513531Sjairo.balart@metempsy.com return; 78613531Sjairo.balart@metempsy.com } 78713531Sjairo.balart@metempsy.com 78813531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; 78913756Sjairo.balart@metempsy.com i < 8 * size && int_id < itLines; i++, int_id++) { 79013531Sjairo.balart@metempsy.com irqGrpmod[int_id] = data & (0x1 << i); 79113531Sjairo.balart@metempsy.com } 79213531Sjairo.balart@metempsy.com 79313531Sjairo.balart@metempsy.com return ; 79413531Sjairo.balart@metempsy.com } 79513531Sjairo.balart@metempsy.com } 79613531Sjairo.balart@metempsy.com 79713756Sjairo.balart@metempsy.com } else if (GICD_NSACR.contains(addr)) { 79813531Sjairo.balart@metempsy.com // Non-secure Access Control Registers 79913531Sjairo.balart@metempsy.com // 2 bits per interrupt 80013531Sjairo.balart@metempsy.com int first_intid = (addr - GICD_NSACR.start()) * 4; 80113531Sjairo.balart@metempsy.com 80213531Sjairo.balart@metempsy.com if (isNotSPI(first_intid)) { 80313531Sjairo.balart@metempsy.com return; 80413531Sjairo.balart@metempsy.com } 80513531Sjairo.balart@metempsy.com 80613531Sjairo.balart@metempsy.com if (DS || (!DS && !is_secure_access)) { 80713531Sjairo.balart@metempsy.com return; 80813531Sjairo.balart@metempsy.com } 80913531Sjairo.balart@metempsy.com 81013531Sjairo.balart@metempsy.com for (int i = 0, int_id = first_intid; 81113756Sjairo.balart@metempsy.com i < 8 * size && int_id < itLines; i = i + 2, int_id++) { 81213531Sjairo.balart@metempsy.com irqNsacr[int_id] = (data >> (2 * int_id)) & 0x3; 81313531Sjairo.balart@metempsy.com } 81413531Sjairo.balart@metempsy.com 81513531Sjairo.balart@metempsy.com return; 81613531Sjairo.balart@metempsy.com } else if (GICD_IROUTER.contains(addr)) { // Interrupt Routing Registers 81713531Sjairo.balart@metempsy.com // 64 bit registers. 2 accesses. 81813531Sjairo.balart@metempsy.com int int_id = (addr - GICD_IROUTER.start()) / 8; 81913531Sjairo.balart@metempsy.com 82013531Sjairo.balart@metempsy.com if (isNotSPI(int_id)) { 82113531Sjairo.balart@metempsy.com return; 82213531Sjairo.balart@metempsy.com } 82313531Sjairo.balart@metempsy.com 82413531Sjairo.balart@metempsy.com if (nsAccessToSecInt(int_id, is_secure_access)) 82513531Sjairo.balart@metempsy.com { 82613531Sjairo.balart@metempsy.com if (irqNsacr[int_id] < 3) { 82713531Sjairo.balart@metempsy.com // Group 0 or Secure Group 1 interrupts are RAZ/WI 82813531Sjairo.balart@metempsy.com return; 82913531Sjairo.balart@metempsy.com } 83013531Sjairo.balart@metempsy.com } 83113531Sjairo.balart@metempsy.com 83213531Sjairo.balart@metempsy.com if (size == 4) { 83313531Sjairo.balart@metempsy.com if (addr & 7) { // high half of 64 bit register 83413531Sjairo.balart@metempsy.com irqAffinityRouting[int_id] = 83513531Sjairo.balart@metempsy.com (irqAffinityRouting[int_id] & 0xffffffff) | (data << 32); 83613531Sjairo.balart@metempsy.com } else { // low half of 64 bit register 83713531Sjairo.balart@metempsy.com irqAffinityRouting[int_id] = 83813531Sjairo.balart@metempsy.com (irqAffinityRouting[int_id] & 0xffffffff00000000) | 83913531Sjairo.balart@metempsy.com (data & 0xffffffff); 84013531Sjairo.balart@metempsy.com } 84113531Sjairo.balart@metempsy.com } else { 84213531Sjairo.balart@metempsy.com irqAffinityRouting[int_id] = data; 84313531Sjairo.balart@metempsy.com } 84413531Sjairo.balart@metempsy.com 84513531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): " 84613531Sjairo.balart@metempsy.com "int_id %d GICD_IROUTER %#llx\n", 84713531Sjairo.balart@metempsy.com int_id, irqAffinityRouting[int_id]); 84813531Sjairo.balart@metempsy.com return; 84913531Sjairo.balart@metempsy.com } 85013531Sjairo.balart@metempsy.com 85113531Sjairo.balart@metempsy.com switch (addr) { 85213531Sjairo.balart@metempsy.com case GICD_CTLR: // Control Register 85313531Sjairo.balart@metempsy.com if (DS) { 85413531Sjairo.balart@metempsy.com /* 85513531Sjairo.balart@metempsy.com * E1NWF [7] 85613531Sjairo.balart@metempsy.com * 1 of N wakeup functionality not supported, RAZ/WI 85713531Sjairo.balart@metempsy.com * DS [6] - RAO/WI 85813531Sjairo.balart@metempsy.com * ARE [4] 85913531Sjairo.balart@metempsy.com * affinity routing always on, no GICv2 legacy, RAO/WI 86013531Sjairo.balart@metempsy.com * EnableGrp1 [1] 86113531Sjairo.balart@metempsy.com * EnableGrp0 [0] 86213531Sjairo.balart@metempsy.com */ 86313531Sjairo.balart@metempsy.com if ((data & (1 << 4)) == 0) { 86413531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 86513531Sjairo.balart@metempsy.com "setting ARE to 0 is not supported!\n"); 86613531Sjairo.balart@metempsy.com } 86713531Sjairo.balart@metempsy.com 86813531Sjairo.balart@metempsy.com EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1NS; 86913531Sjairo.balart@metempsy.com EnableGrp0 = data & GICD_CTLR_ENABLEGRP0; 87013531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): (DS 1)" 87113531Sjairo.balart@metempsy.com "EnableGrp1NS %d EnableGrp0 %d\n", 87213531Sjairo.balart@metempsy.com EnableGrp1NS, EnableGrp0); 87313531Sjairo.balart@metempsy.com } else { 87413531Sjairo.balart@metempsy.com if (is_secure_access) { 87513531Sjairo.balart@metempsy.com /* 87613531Sjairo.balart@metempsy.com * E1NWF [7] 87713531Sjairo.balart@metempsy.com * 1 of N wakeup functionality not supported, RAZ/WI 87813531Sjairo.balart@metempsy.com * DS [6] 87913531Sjairo.balart@metempsy.com * ARE_NS [5] 88013531Sjairo.balart@metempsy.com * affinity routing always on, no GICv2 legacy, RAO/WI 88113531Sjairo.balart@metempsy.com * ARE_S [4] 88213531Sjairo.balart@metempsy.com * affinity routing always on, no GICv2 legacy, RAO/WI 88313531Sjairo.balart@metempsy.com * EnableGrp1S [2] 88413531Sjairo.balart@metempsy.com * EnableGrp1NS [1] 88513531Sjairo.balart@metempsy.com * EnableGrp0 [0] 88613531Sjairo.balart@metempsy.com */ 88713531Sjairo.balart@metempsy.com if ((data & (1 << 5)) == 0) { 88813531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 88913531Sjairo.balart@metempsy.com "setting ARE_NS to 0 is not supported!\n"); 89013531Sjairo.balart@metempsy.com } 89113531Sjairo.balart@metempsy.com 89213531Sjairo.balart@metempsy.com if ((data & (1 << 4)) == 0) { 89313531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 89413531Sjairo.balart@metempsy.com "setting ARE_S to 0 is not supported!\n"); 89513531Sjairo.balart@metempsy.com } 89613531Sjairo.balart@metempsy.com 89713531Sjairo.balart@metempsy.com DS = data & GICD_CTLR_DS; 89813531Sjairo.balart@metempsy.com EnableGrp1S = data & GICD_CTLR_ENABLEGRP1S; 89913531Sjairo.balart@metempsy.com EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1NS; 90013531Sjairo.balart@metempsy.com EnableGrp0 = data & GICD_CTLR_ENABLEGRP0; 90113531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): (DS 0 secure)" 90213531Sjairo.balart@metempsy.com "DS %d " 90313531Sjairo.balart@metempsy.com "EnableGrp1S %d EnableGrp1NS %d EnableGrp0 %d\n", 90413531Sjairo.balart@metempsy.com DS, EnableGrp1S, EnableGrp1NS, EnableGrp0); 90513531Sjairo.balart@metempsy.com 90613531Sjairo.balart@metempsy.com if (data & GICD_CTLR_DS) { 90713531Sjairo.balart@metempsy.com EnableGrp1S = 0; 90813531Sjairo.balart@metempsy.com } 90913531Sjairo.balart@metempsy.com } else { 91013531Sjairo.balart@metempsy.com /* 91113531Sjairo.balart@metempsy.com * ARE_NS [4] RAO/WI; 91213531Sjairo.balart@metempsy.com * EnableGrp1A [1] is a read-write alias of the Secure 91313531Sjairo.balart@metempsy.com * GICD_CTLR.EnableGrp1NS 91413531Sjairo.balart@metempsy.com * EnableGrp1 [0] RES0 91513531Sjairo.balart@metempsy.com */ 91613531Sjairo.balart@metempsy.com if ((data & (1 << 4)) == 0) { 91713531Sjairo.balart@metempsy.com warn("Gicv3Distributor::write(): " 91813531Sjairo.balart@metempsy.com "setting ARE_NS to 0 is not supported!\n"); 91913531Sjairo.balart@metempsy.com } 92013531Sjairo.balart@metempsy.com 92113531Sjairo.balart@metempsy.com EnableGrp1NS = data & GICD_CTLR_ENABLEGRP1A; 92213531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::write(): (DS 0 non-secure)" 92313531Sjairo.balart@metempsy.com "EnableGrp1NS %d\n", EnableGrp1NS); 92413531Sjairo.balart@metempsy.com } 92513531Sjairo.balart@metempsy.com } 92613531Sjairo.balart@metempsy.com 92713531Sjairo.balart@metempsy.com break; 92813531Sjairo.balart@metempsy.com 92913531Sjairo.balart@metempsy.com default: 93013531Sjairo.balart@metempsy.com panic("Gicv3Distributor::write(): invalid offset %#x\n", addr); 93113531Sjairo.balart@metempsy.com break; 93213531Sjairo.balart@metempsy.com } 93313531Sjairo.balart@metempsy.com} 93413531Sjairo.balart@metempsy.com 93513531Sjairo.balart@metempsy.comvoid 93613531Sjairo.balart@metempsy.comGicv3Distributor::sendInt(uint32_t int_id) 93713531Sjairo.balart@metempsy.com{ 93813531Sjairo.balart@metempsy.com panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!"); 93913531Sjairo.balart@metempsy.com panic_if(int_id > itLines, "Invalid SPI!"); 94013531Sjairo.balart@metempsy.com irqPending[int_id] = true; 94113531Sjairo.balart@metempsy.com DPRINTF(GIC, "Gicv3Distributor::sendInt(): " 94213531Sjairo.balart@metempsy.com "int_id %d (SPI) pending bit set\n", int_id); 94313531Sjairo.balart@metempsy.com updateAndInformCPUInterfaces(); 94413531Sjairo.balart@metempsy.com} 94513531Sjairo.balart@metempsy.com 94613531Sjairo.balart@metempsy.comvoid 94713756Sjairo.balart@metempsy.comGicv3Distributor::deassertSPI(uint32_t int_id) 94813531Sjairo.balart@metempsy.com{ 94913531Sjairo.balart@metempsy.com panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!"); 95013531Sjairo.balart@metempsy.com panic_if(int_id > itLines, "Invalid SPI!"); 95113531Sjairo.balart@metempsy.com irqPending[int_id] = false; 95213531Sjairo.balart@metempsy.com updateAndInformCPUInterfaces(); 95313531Sjairo.balart@metempsy.com} 95413531Sjairo.balart@metempsy.com 95513531Sjairo.balart@metempsy.comvoid 95613531Sjairo.balart@metempsy.comGicv3Distributor::updateAndInformCPUInterfaces() 95713531Sjairo.balart@metempsy.com{ 95813531Sjairo.balart@metempsy.com update(); 95913531Sjairo.balart@metempsy.com 96013531Sjairo.balart@metempsy.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 96113531Sjairo.balart@metempsy.com gic->getCPUInterface(i)->update(); 96213531Sjairo.balart@metempsy.com } 96313531Sjairo.balart@metempsy.com} 96413531Sjairo.balart@metempsy.com 96513531Sjairo.balart@metempsy.comvoid 96613531Sjairo.balart@metempsy.comGicv3Distributor::fullUpdate() 96713531Sjairo.balart@metempsy.com{ 96813531Sjairo.balart@metempsy.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 96913531Sjairo.balart@metempsy.com Gicv3CPUInterface * cpu_interface_i = gic->getCPUInterface(i); 97013531Sjairo.balart@metempsy.com cpu_interface_i->hppi.prio = 0xff; 97113531Sjairo.balart@metempsy.com } 97213531Sjairo.balart@metempsy.com 97313531Sjairo.balart@metempsy.com update(); 97413531Sjairo.balart@metempsy.com 97513531Sjairo.balart@metempsy.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 97613531Sjairo.balart@metempsy.com Gicv3Redistributor * redistributor_i = gic->getRedistributor(i); 97713531Sjairo.balart@metempsy.com redistributor_i->update(); 97813531Sjairo.balart@metempsy.com } 97913531Sjairo.balart@metempsy.com} 98013531Sjairo.balart@metempsy.com 98113531Sjairo.balart@metempsy.comvoid 98213531Sjairo.balart@metempsy.comGicv3Distributor::update() 98313531Sjairo.balart@metempsy.com{ 98413531Sjairo.balart@metempsy.com std::vector<bool> new_hppi(gic->getSystem()->numContexts(), false); 98513531Sjairo.balart@metempsy.com 98613531Sjairo.balart@metempsy.com // Find the highest priority pending SPI 98713531Sjairo.balart@metempsy.com for (int int_id = Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id < itLines; 98813756Sjairo.balart@metempsy.com int_id++) { 98913531Sjairo.balart@metempsy.com Gicv3::GroupId int_group = getIntGroup(int_id); 99013531Sjairo.balart@metempsy.com bool group_enabled = groupEnabled(int_group); 99113531Sjairo.balart@metempsy.com 99213531Sjairo.balart@metempsy.com if (irqPending[int_id] && irqEnabled[int_id] && 99313756Sjairo.balart@metempsy.com !irqActive[int_id] && group_enabled) { 99413531Sjairo.balart@metempsy.com IROUTER affinity_routing = irqAffinityRouting[int_id]; 99513531Sjairo.balart@metempsy.com Gicv3Redistributor * target_redistributor = nullptr; 99613531Sjairo.balart@metempsy.com 99713531Sjairo.balart@metempsy.com if (affinity_routing.IRM) { 99813531Sjairo.balart@metempsy.com // Interrupts routed to any PE defined as a participating node 99913531Sjairo.balart@metempsy.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 100013531Sjairo.balart@metempsy.com Gicv3Redistributor * redistributor_i = 100113531Sjairo.balart@metempsy.com gic->getRedistributor(i); 100213531Sjairo.balart@metempsy.com 100313531Sjairo.balart@metempsy.com if (redistributor_i-> 100413531Sjairo.balart@metempsy.com canBeSelectedFor1toNInterrupt(int_group)) { 100513531Sjairo.balart@metempsy.com target_redistributor = redistributor_i; 100613531Sjairo.balart@metempsy.com break; 100713531Sjairo.balart@metempsy.com } 100813531Sjairo.balart@metempsy.com } 100913531Sjairo.balart@metempsy.com } else { 101013531Sjairo.balart@metempsy.com uint32_t affinity = (affinity_routing.Aff3 << 24) | 101113531Sjairo.balart@metempsy.com (affinity_routing.Aff3 << 16) | 101213531Sjairo.balart@metempsy.com (affinity_routing.Aff1 << 8) | 101313531Sjairo.balart@metempsy.com (affinity_routing.Aff0 << 0); 101413531Sjairo.balart@metempsy.com target_redistributor = 101513531Sjairo.balart@metempsy.com gic->getRedistributorByAffinity(affinity); 101613531Sjairo.balart@metempsy.com } 101713531Sjairo.balart@metempsy.com 101813531Sjairo.balart@metempsy.com if (!target_redistributor) { 101913531Sjairo.balart@metempsy.com // Interrrupts targeting not present cpus must remain pending 102013531Sjairo.balart@metempsy.com return; 102113531Sjairo.balart@metempsy.com } 102213531Sjairo.balart@metempsy.com 102313531Sjairo.balart@metempsy.com Gicv3CPUInterface * target_cpu_interface = 102413531Sjairo.balart@metempsy.com target_redistributor->getCPUInterface(); 102513531Sjairo.balart@metempsy.com uint32_t target_cpu = target_redistributor->cpuId; 102613531Sjairo.balart@metempsy.com 102713531Sjairo.balart@metempsy.com if ((irqPriority[int_id] < target_cpu_interface->hppi.prio) || 102813756Sjairo.balart@metempsy.com /* 102913756Sjairo.balart@metempsy.com * Multiple pending ints with same priority. 103013756Sjairo.balart@metempsy.com * Implementation choice which one to signal. 103113756Sjairo.balart@metempsy.com * Our implementation selects the one with the lower id. 103213756Sjairo.balart@metempsy.com */ 103313756Sjairo.balart@metempsy.com (irqPriority[int_id] == target_cpu_interface->hppi.prio && 103413756Sjairo.balart@metempsy.com int_id < target_cpu_interface->hppi.intid)) { 103513531Sjairo.balart@metempsy.com target_cpu_interface->hppi.intid = int_id; 103613531Sjairo.balart@metempsy.com target_cpu_interface->hppi.prio = irqPriority[int_id]; 103713531Sjairo.balart@metempsy.com target_cpu_interface->hppi.group = int_group; 103813531Sjairo.balart@metempsy.com new_hppi[target_cpu] = true; 103913531Sjairo.balart@metempsy.com } 104013531Sjairo.balart@metempsy.com } 104113531Sjairo.balart@metempsy.com } 104213531Sjairo.balart@metempsy.com 104313531Sjairo.balart@metempsy.com for (int i = 0; i < gic->getSystem()->numContexts(); i++) { 104413531Sjairo.balart@metempsy.com Gicv3Redistributor * redistributor_i = gic->getRedistributor(i); 104513531Sjairo.balart@metempsy.com Gicv3CPUInterface * cpu_interface_i = 104613531Sjairo.balart@metempsy.com redistributor_i->getCPUInterface(); 104713531Sjairo.balart@metempsy.com 104813531Sjairo.balart@metempsy.com if (!new_hppi[i] && cpu_interface_i->hppi.prio != 0xff && 104913756Sjairo.balart@metempsy.com cpu_interface_i->hppi.intid >= (Gicv3::SGI_MAX + Gicv3::PPI_MAX) && 105013756Sjairo.balart@metempsy.com cpu_interface_i->hppi.intid < Gicv3::INTID_SECURE) { 105113531Sjairo.balart@metempsy.com fullUpdate(); 105213531Sjairo.balart@metempsy.com } 105313531Sjairo.balart@metempsy.com } 105413531Sjairo.balart@metempsy.com} 105513531Sjairo.balart@metempsy.com 105613531Sjairo.balart@metempsy.comGicv3::IntStatus 105713756Sjairo.balart@metempsy.comGicv3Distributor::intStatus(uint32_t int_id) const 105813531Sjairo.balart@metempsy.com{ 105913531Sjairo.balart@metempsy.com panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!"); 106013531Sjairo.balart@metempsy.com panic_if(int_id > itLines, "Invalid SPI!"); 106113531Sjairo.balart@metempsy.com 106213531Sjairo.balart@metempsy.com if (irqPending[int_id]) { 106313531Sjairo.balart@metempsy.com if (irqActive[int_id]) { 106413531Sjairo.balart@metempsy.com return Gicv3::INT_ACTIVE_PENDING; 106513531Sjairo.balart@metempsy.com } 106613531Sjairo.balart@metempsy.com 106713531Sjairo.balart@metempsy.com return Gicv3::INT_PENDING; 106813531Sjairo.balart@metempsy.com } else if (irqActive[int_id]) { 106913531Sjairo.balart@metempsy.com return Gicv3::INT_ACTIVE; 107013531Sjairo.balart@metempsy.com } else { 107113531Sjairo.balart@metempsy.com return Gicv3::INT_INACTIVE; 107213531Sjairo.balart@metempsy.com } 107313531Sjairo.balart@metempsy.com} 107413531Sjairo.balart@metempsy.com 107513531Sjairo.balart@metempsy.comGicv3::GroupId 107613756Sjairo.balart@metempsy.comGicv3Distributor::getIntGroup(int int_id) const 107713531Sjairo.balart@metempsy.com{ 107813531Sjairo.balart@metempsy.com panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!"); 107913531Sjairo.balart@metempsy.com panic_if(int_id > itLines, "Invalid SPI!"); 108013531Sjairo.balart@metempsy.com 108113531Sjairo.balart@metempsy.com if (DS) { 108213531Sjairo.balart@metempsy.com if (irqGroup[int_id] == 1) { 108313531Sjairo.balart@metempsy.com return Gicv3::G1NS; 108413531Sjairo.balart@metempsy.com } else { 108513531Sjairo.balart@metempsy.com return Gicv3::G0S; 108613531Sjairo.balart@metempsy.com } 108713531Sjairo.balart@metempsy.com } else { 108813531Sjairo.balart@metempsy.com if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 0) { 108913531Sjairo.balart@metempsy.com return Gicv3::G0S; 109013531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 1) { 109113531Sjairo.balart@metempsy.com return Gicv3::G1NS; 109213531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 0) { 109313531Sjairo.balart@metempsy.com return Gicv3::G1S; 109413531Sjairo.balart@metempsy.com } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 1) { 109513531Sjairo.balart@metempsy.com return Gicv3::G1NS; 109613531Sjairo.balart@metempsy.com } 109713531Sjairo.balart@metempsy.com } 109813531Sjairo.balart@metempsy.com 109913531Sjairo.balart@metempsy.com M5_UNREACHABLE; 110013531Sjairo.balart@metempsy.com} 110113531Sjairo.balart@metempsy.com 110213531Sjairo.balart@metempsy.comvoid 110313531Sjairo.balart@metempsy.comGicv3Distributor::activateIRQ(uint32_t int_id) 110413531Sjairo.balart@metempsy.com{ 110513531Sjairo.balart@metempsy.com irqPending[int_id] = false; 110613531Sjairo.balart@metempsy.com irqActive[int_id] = true; 110713531Sjairo.balart@metempsy.com} 110813531Sjairo.balart@metempsy.com 110913531Sjairo.balart@metempsy.comvoid 111013531Sjairo.balart@metempsy.comGicv3Distributor::deactivateIRQ(uint32_t int_id) 111113531Sjairo.balart@metempsy.com{ 111213531Sjairo.balart@metempsy.com irqActive[int_id] = false; 111313531Sjairo.balart@metempsy.com} 111413531Sjairo.balart@metempsy.com 111513531Sjairo.balart@metempsy.comvoid 111613531Sjairo.balart@metempsy.comGicv3Distributor::serialize(CheckpointOut & cp) const 111713531Sjairo.balart@metempsy.com{ 111813531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(ARE); 111913531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(DS); 112013531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(EnableGrp1S); 112113531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(EnableGrp1NS); 112213531Sjairo.balart@metempsy.com SERIALIZE_SCALAR(EnableGrp0); 112313531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqGroup); 112413531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqEnabled); 112513531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqPending); 112613531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqActive); 112713531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqPriority); 112813531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqConfig); 112913531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqGrpmod); 113013531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqNsacr); 113113531Sjairo.balart@metempsy.com SERIALIZE_CONTAINER(irqAffinityRouting); 113213531Sjairo.balart@metempsy.com} 113313531Sjairo.balart@metempsy.com 113413531Sjairo.balart@metempsy.comvoid 113513531Sjairo.balart@metempsy.comGicv3Distributor::unserialize(CheckpointIn & cp) 113613531Sjairo.balart@metempsy.com{ 113713531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(ARE); 113813531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(DS); 113913531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(EnableGrp1S); 114013531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(EnableGrp1NS); 114113531Sjairo.balart@metempsy.com UNSERIALIZE_SCALAR(EnableGrp0); 114213531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqGroup); 114313531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqEnabled); 114413531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqPending); 114513531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqActive); 114613531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqPriority); 114713531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqConfig); 114813531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqGrpmod); 114913531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqNsacr); 115013531Sjairo.balart@metempsy.com UNSERIALIZE_CONTAINER(irqAffinityRouting); 115113531Sjairo.balart@metempsy.com} 1152