gic_v2.cc revision 13105
113014Sciro.santilli@arm.com/* 213014Sciro.santilli@arm.com * Copyright (c) 2010, 2013, 2015-2018 ARM Limited 313014Sciro.santilli@arm.com * All rights reserved 413014Sciro.santilli@arm.com * 513014Sciro.santilli@arm.com * The license below extends only to copyright in the software and shall 613014Sciro.santilli@arm.com * not be construed as granting a license to any other intellectual 713014Sciro.santilli@arm.com * property including but not limited to intellectual property relating 813014Sciro.santilli@arm.com * to a hardware implementation of the functionality of the software 913014Sciro.santilli@arm.com * licensed hereunder. You may use the software subject to the license 1013014Sciro.santilli@arm.com * terms below provided that you ensure that this notice is replicated 1113014Sciro.santilli@arm.com * unmodified and in its entirety in all distributions of the software, 1213014Sciro.santilli@arm.com * modified or unmodified, in source code or in binary form. 1313014Sciro.santilli@arm.com * 1413014Sciro.santilli@arm.com * Copyright (c) 2005 The Regents of The University of Michigan 1513014Sciro.santilli@arm.com * All rights reserved. 1613014Sciro.santilli@arm.com * 1713014Sciro.santilli@arm.com * Redistribution and use in source and binary forms, with or without 1813014Sciro.santilli@arm.com * modification, are permitted provided that the following conditions are 1913014Sciro.santilli@arm.com * met: redistributions of source code must retain the above copyright 2013014Sciro.santilli@arm.com * notice, this list of conditions and the following disclaimer; 2113014Sciro.santilli@arm.com * redistributions in binary form must reproduce the above copyright 2213014Sciro.santilli@arm.com * notice, this list of conditions and the following disclaimer in the 2313014Sciro.santilli@arm.com * documentation and/or other materials provided with the distribution; 2413014Sciro.santilli@arm.com * neither the name of the copyright holders nor the names of its 2513014Sciro.santilli@arm.com * contributors may be used to endorse or promote products derived from 2613014Sciro.santilli@arm.com * this software without specific prior written permission. 2713014Sciro.santilli@arm.com * 2813014Sciro.santilli@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2913014Sciro.santilli@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3013014Sciro.santilli@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3113014Sciro.santilli@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3213014Sciro.santilli@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3313014Sciro.santilli@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3413014Sciro.santilli@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3513014Sciro.santilli@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3613014Sciro.santilli@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3713014Sciro.santilli@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3813014Sciro.santilli@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3913014Sciro.santilli@arm.com * 4013014Sciro.santilli@arm.com * Authors: Ali Saidi 4113014Sciro.santilli@arm.com * Prakash Ramrakhyani 4213014Sciro.santilli@arm.com */ 4313014Sciro.santilli@arm.com 4413014Sciro.santilli@arm.com#include "dev/arm/gic_v2.hh" 4513014Sciro.santilli@arm.com 4613014Sciro.santilli@arm.com#include "base/trace.hh" 4713014Sciro.santilli@arm.com#include "debug/Checkpoint.hh" 4813014Sciro.santilli@arm.com#include "debug/GIC.hh" 4913014Sciro.santilli@arm.com#include "debug/IPI.hh" 5013014Sciro.santilli@arm.com#include "debug/Interrupt.hh" 5113014Sciro.santilli@arm.com#include "mem/packet.hh" 5213014Sciro.santilli@arm.com#include "mem/packet_access.hh" 5313014Sciro.santilli@arm.com 5413014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_IGROUPR (0x080, 0x0ff); 5513014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_ISENABLER (0x100, 0x17f); 5613014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_ICENABLER (0x180, 0x1ff); 5713014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_ISPENDR (0x200, 0x27f); 5813014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_ICPENDR (0x280, 0x2ff); 5913014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_ISACTIVER (0x300, 0x37f); 6013014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_ICACTIVER (0x380, 0x3ff); 6113014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_IPRIORITYR(0x400, 0x7ff); 6213014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_ITARGETSR (0x800, 0xbff); 6313014Sciro.santilli@arm.comconst AddrRange GicV2::GICD_ICFGR (0xc00, 0xcff); 6413014Sciro.santilli@arm.com 6513014Sciro.santilli@arm.comGicV2::GicV2(const Params *p) 6613014Sciro.santilli@arm.com : BaseGic(p), 6713014Sciro.santilli@arm.com distRange(RangeSize(p->dist_addr, DIST_SIZE)), 6813014Sciro.santilli@arm.com cpuRange(RangeSize(p->cpu_addr, p->cpu_size)), 6913014Sciro.santilli@arm.com addrRanges{distRange, cpuRange}, 7013014Sciro.santilli@arm.com distPioDelay(p->dist_pio_delay), 7113014Sciro.santilli@arm.com cpuPioDelay(p->cpu_pio_delay), intLatency(p->int_latency), 7213014Sciro.santilli@arm.com enabled(false), haveGem5Extensions(p->gem5_extensions), 7313014Sciro.santilli@arm.com itLines(p->it_lines), 7413014Sciro.santilli@arm.com intEnabled {}, pendingInt {}, activeInt {}, 7513014Sciro.santilli@arm.com intPriority {}, cpuTarget {}, intConfig {}, 7613014Sciro.santilli@arm.com cpuSgiPending {}, cpuSgiActive {}, 7713014Sciro.santilli@arm.com cpuSgiPendingExt {}, cpuSgiActiveExt {}, 7813014Sciro.santilli@arm.com cpuPpiPending {}, cpuPpiActive {}, 7913014Sciro.santilli@arm.com pendingDelayedInterrupts(0) 8013014Sciro.santilli@arm.com{ 8113014Sciro.santilli@arm.com for (int x = 0; x < CPU_MAX; x++) { 8213014Sciro.santilli@arm.com iccrpr[x] = 0xff; 8313014Sciro.santilli@arm.com cpuEnabled[x] = false; 8413014Sciro.santilli@arm.com cpuPriority[x] = 0xff; 8513014Sciro.santilli@arm.com cpuBpr[x] = GICC_BPR_MINIMUM; 8613014Sciro.santilli@arm.com // Initialize cpu highest int 8713014Sciro.santilli@arm.com cpuHighestInt[x] = SPURIOUS_INT; 8813014Sciro.santilli@arm.com postIntEvent[x] = 8913014Sciro.santilli@arm.com new EventFunctionWrapper([this, x]{ postDelayedInt(x); }, 9013014Sciro.santilli@arm.com "Post Interrupt to CPU"); 9113014Sciro.santilli@arm.com } 9213014Sciro.santilli@arm.com DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled[0], 9313014Sciro.santilli@arm.com cpuEnabled[1]); 9413014Sciro.santilli@arm.com 9513014Sciro.santilli@arm.com gem5ExtensionsEnabled = false; 9613014Sciro.santilli@arm.com} 9713014Sciro.santilli@arm.com 9813014Sciro.santilli@arm.comGicV2::~GicV2() 9913014Sciro.santilli@arm.com{ 10013014Sciro.santilli@arm.com for (int x = 0; x < CPU_MAX; x++) 10113014Sciro.santilli@arm.com delete postIntEvent[x]; 10213014Sciro.santilli@arm.com} 10313014Sciro.santilli@arm.com 10413014Sciro.santilli@arm.comTick 10513014Sciro.santilli@arm.comGicV2::read(PacketPtr pkt) 10613014Sciro.santilli@arm.com{ 10713014Sciro.santilli@arm.com const Addr addr = pkt->getAddr(); 10813014Sciro.santilli@arm.com 10913014Sciro.santilli@arm.com if (distRange.contains(addr)) 11013014Sciro.santilli@arm.com return readDistributor(pkt); 11113014Sciro.santilli@arm.com else if (cpuRange.contains(addr)) 11213014Sciro.santilli@arm.com return readCpu(pkt); 11313014Sciro.santilli@arm.com else 11413014Sciro.santilli@arm.com panic("Read to unknown address %#x\n", pkt->getAddr()); 11513014Sciro.santilli@arm.com} 11613014Sciro.santilli@arm.com 11713014Sciro.santilli@arm.com 11813014Sciro.santilli@arm.comTick 11913014Sciro.santilli@arm.comGicV2::write(PacketPtr pkt) 12013014Sciro.santilli@arm.com{ 12113014Sciro.santilli@arm.com const Addr addr = pkt->getAddr(); 12213014Sciro.santilli@arm.com 12313014Sciro.santilli@arm.com if (distRange.contains(addr)) 12413014Sciro.santilli@arm.com return writeDistributor(pkt); 12513014Sciro.santilli@arm.com else if (cpuRange.contains(addr)) 12613014Sciro.santilli@arm.com return writeCpu(pkt); 12713014Sciro.santilli@arm.com else 12813014Sciro.santilli@arm.com panic("Write to unknown address %#x\n", pkt->getAddr()); 12913014Sciro.santilli@arm.com} 13013014Sciro.santilli@arm.com 13113014Sciro.santilli@arm.comTick 13213014Sciro.santilli@arm.comGicV2::readDistributor(PacketPtr pkt) 13313014Sciro.santilli@arm.com{ 13413014Sciro.santilli@arm.com const Addr daddr = pkt->getAddr() - distRange.start(); 13513014Sciro.santilli@arm.com const ContextID ctx = pkt->req->contextId(); 13613014Sciro.santilli@arm.com 13713014Sciro.santilli@arm.com DPRINTF(GIC, "gic distributor read register %#x\n", daddr); 13813014Sciro.santilli@arm.com 13913014Sciro.santilli@arm.com const uint32_t resp = readDistributor(ctx, daddr, pkt->getSize()); 14013014Sciro.santilli@arm.com 14113014Sciro.santilli@arm.com switch (pkt->getSize()) { 14213014Sciro.santilli@arm.com case 1: 14313014Sciro.santilli@arm.com pkt->set<uint8_t>(resp); 14413014Sciro.santilli@arm.com break; 14513014Sciro.santilli@arm.com case 2: 14613014Sciro.santilli@arm.com pkt->set<uint16_t>(resp); 14713014Sciro.santilli@arm.com break; 14813014Sciro.santilli@arm.com case 4: 14913014Sciro.santilli@arm.com pkt->set<uint32_t>(resp); 15013014Sciro.santilli@arm.com break; 15113014Sciro.santilli@arm.com default: 15213014Sciro.santilli@arm.com panic("Invalid size while reading Distributor regs in GIC: %d\n", 15313014Sciro.santilli@arm.com pkt->getSize()); 15413014Sciro.santilli@arm.com } 15513014Sciro.santilli@arm.com 15613014Sciro.santilli@arm.com pkt->makeAtomicResponse(); 15713014Sciro.santilli@arm.com return distPioDelay; 15813014Sciro.santilli@arm.com} 15913014Sciro.santilli@arm.com 16013014Sciro.santilli@arm.comuint32_t 16113014Sciro.santilli@arm.comGicV2::readDistributor(ContextID ctx, Addr daddr, size_t resp_sz) 16213014Sciro.santilli@arm.com{ 16313014Sciro.santilli@arm.com if (GICD_IGROUPR.contains(daddr)) { 16413014Sciro.santilli@arm.com return 0; // unimplemented; RAZ (read as zero) 16513014Sciro.santilli@arm.com } 16613014Sciro.santilli@arm.com 16713014Sciro.santilli@arm.com if (GICD_ISENABLER.contains(daddr)) { 16813014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ISENABLER.start()) >> 2; 16913014Sciro.santilli@arm.com assert(ix < 32); 17013014Sciro.santilli@arm.com return getIntEnabled(ctx, ix); 17113014Sciro.santilli@arm.com } 17213014Sciro.santilli@arm.com 17313014Sciro.santilli@arm.com if (GICD_ICENABLER.contains(daddr)) { 17413014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ICENABLER.start()) >> 2; 17513014Sciro.santilli@arm.com assert(ix < 32); 17613014Sciro.santilli@arm.com return getIntEnabled(ctx, ix); 17713014Sciro.santilli@arm.com } 17813014Sciro.santilli@arm.com 17913014Sciro.santilli@arm.com if (GICD_ISPENDR.contains(daddr)) { 18013014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ISPENDR.start()) >> 2; 18113014Sciro.santilli@arm.com assert(ix < 32); 18213014Sciro.santilli@arm.com return getPendingInt(ctx, ix); 18313014Sciro.santilli@arm.com } 18413014Sciro.santilli@arm.com 18513014Sciro.santilli@arm.com if (GICD_ICPENDR.contains(daddr)) { 18613014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ICPENDR.start()) >> 2; 18713014Sciro.santilli@arm.com assert(ix < 32); 18813014Sciro.santilli@arm.com return getPendingInt(ctx, ix); 18913014Sciro.santilli@arm.com } 19013014Sciro.santilli@arm.com 19113014Sciro.santilli@arm.com if (GICD_ISACTIVER.contains(daddr)) { 19213014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ISACTIVER.start()) >> 2; 19313014Sciro.santilli@arm.com assert(ix < 32); 19413014Sciro.santilli@arm.com return getActiveInt(ctx, ix); 19513014Sciro.santilli@arm.com } 19613014Sciro.santilli@arm.com 19713014Sciro.santilli@arm.com if (GICD_ICACTIVER.contains(daddr)) { 19813014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ICACTIVER.start()) >> 2; 19913014Sciro.santilli@arm.com assert(ix < 32); 20013014Sciro.santilli@arm.com return getActiveInt(ctx, ix); 20113014Sciro.santilli@arm.com } 20213014Sciro.santilli@arm.com 20313014Sciro.santilli@arm.com if (GICD_IPRIORITYR.contains(daddr)) { 20413014Sciro.santilli@arm.com Addr int_num = daddr - GICD_IPRIORITYR.start(); 20513014Sciro.santilli@arm.com assert(int_num < INT_LINES_MAX); 20613014Sciro.santilli@arm.com DPRINTF(Interrupt, "Reading interrupt priority at int# %#x \n", 20713014Sciro.santilli@arm.com int_num); 20813014Sciro.santilli@arm.com 20913014Sciro.santilli@arm.com switch (resp_sz) { 21013014Sciro.santilli@arm.com default: // will panic() after return to caller anyway 21113014Sciro.santilli@arm.com case 1: 21213014Sciro.santilli@arm.com return getIntPriority(ctx, int_num); 21313014Sciro.santilli@arm.com case 2: 21413014Sciro.santilli@arm.com assert((int_num + 1) < INT_LINES_MAX); 21513014Sciro.santilli@arm.com return (getIntPriority(ctx, int_num) | 21613014Sciro.santilli@arm.com getIntPriority(ctx, int_num+1) << 8); 21713014Sciro.santilli@arm.com case 4: 21813014Sciro.santilli@arm.com assert((int_num + 3) < INT_LINES_MAX); 21913014Sciro.santilli@arm.com return (getIntPriority(ctx, int_num) | 22013014Sciro.santilli@arm.com getIntPriority(ctx, int_num+1) << 8 | 22113014Sciro.santilli@arm.com getIntPriority(ctx, int_num+2) << 16 | 22213014Sciro.santilli@arm.com getIntPriority(ctx, int_num+3) << 24); 22313014Sciro.santilli@arm.com } 22413014Sciro.santilli@arm.com } 22513014Sciro.santilli@arm.com 22613014Sciro.santilli@arm.com if (GICD_ITARGETSR.contains(daddr)) { 22713014Sciro.santilli@arm.com Addr int_num = daddr - GICD_ITARGETSR.start(); 22813014Sciro.santilli@arm.com DPRINTF(GIC, "Reading processor target register for int# %#x \n", 22913014Sciro.santilli@arm.com int_num); 23013014Sciro.santilli@arm.com assert(int_num < INT_LINES_MAX); 23113014Sciro.santilli@arm.com 23213014Sciro.santilli@arm.com if (resp_sz == 1) { 23313014Sciro.santilli@arm.com return getCpuTarget(ctx, int_num); 23413014Sciro.santilli@arm.com } else { 23513014Sciro.santilli@arm.com assert(resp_sz == 4); 23613014Sciro.santilli@arm.com int_num = mbits(int_num, 31, 2); 23713014Sciro.santilli@arm.com return (getCpuTarget(ctx, int_num) | 23813014Sciro.santilli@arm.com getCpuTarget(ctx, int_num+1) << 8 | 23913014Sciro.santilli@arm.com getCpuTarget(ctx, int_num+2) << 16 | 24013014Sciro.santilli@arm.com getCpuTarget(ctx, int_num+3) << 24) ; 24113014Sciro.santilli@arm.com } 24213014Sciro.santilli@arm.com } 24313014Sciro.santilli@arm.com 24413014Sciro.santilli@arm.com if (GICD_ICFGR.contains(daddr)) { 24513014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ICFGR.start()) >> 2; 24613014Sciro.santilli@arm.com assert(ix < 64); 24713014Sciro.santilli@arm.com /** @todo software generated interrupts and PPIs 24813014Sciro.santilli@arm.com * can't be configured in some ways */ 24913014Sciro.santilli@arm.com return intConfig[ix]; 25013014Sciro.santilli@arm.com } 25113014Sciro.santilli@arm.com 25213014Sciro.santilli@arm.com switch(daddr) { 25313014Sciro.santilli@arm.com case GICD_CTLR: 25413014Sciro.santilli@arm.com return enabled; 25513014Sciro.santilli@arm.com case GICD_TYPER: 25613014Sciro.santilli@arm.com /* The 0x100 is a made-up flag to show that gem5 extensions 25713014Sciro.santilli@arm.com * are available, 25813014Sciro.santilli@arm.com * write 0x200 to this register to enable it. */ 25913014Sciro.santilli@arm.com return (((sys->numRunningContexts() - 1) << 5) | 26013014Sciro.santilli@arm.com (itLines/INT_BITS_MAX -1) | 26113014Sciro.santilli@arm.com (haveGem5Extensions ? 0x100 : 0x0)); 26213014Sciro.santilli@arm.com case GICD_PIDR0: 26313014Sciro.santilli@arm.com //ARM defined DevID 26413014Sciro.santilli@arm.com return (GICD_400_PIDR_VALUE & 0xFF); 26513014Sciro.santilli@arm.com case GICD_PIDR1: 26613014Sciro.santilli@arm.com return ((GICD_400_PIDR_VALUE >> 8) & 0xFF); 26713014Sciro.santilli@arm.com case GICD_PIDR2: 26813014Sciro.santilli@arm.com return ((GICD_400_PIDR_VALUE >> 16) & 0xFF); 26913014Sciro.santilli@arm.com case GICD_PIDR3: 27013014Sciro.santilli@arm.com return ((GICD_400_PIDR_VALUE >> 24) & 0xFF); 27113014Sciro.santilli@arm.com case GICD_IIDR: 27213014Sciro.santilli@arm.com /* revision id is resorted to 1 and variant to 0*/ 27313014Sciro.santilli@arm.com return GICD_400_IIDR_VALUE; 27413014Sciro.santilli@arm.com default: 27513014Sciro.santilli@arm.com panic("Tried to read Gic distributor at offset %#x\n", daddr); 27613014Sciro.santilli@arm.com break; 27713014Sciro.santilli@arm.com } 27813014Sciro.santilli@arm.com} 27913014Sciro.santilli@arm.com 28013014Sciro.santilli@arm.comTick 28113014Sciro.santilli@arm.comGicV2::readCpu(PacketPtr pkt) 28213014Sciro.santilli@arm.com{ 28313014Sciro.santilli@arm.com const Addr daddr = pkt->getAddr() - cpuRange.start(); 28413014Sciro.santilli@arm.com 28513014Sciro.santilli@arm.com assert(pkt->req->hasContextId()); 28613014Sciro.santilli@arm.com const ContextID ctx = pkt->req->contextId(); 28713014Sciro.santilli@arm.com assert(ctx < sys->numRunningContexts()); 28813014Sciro.santilli@arm.com 28913014Sciro.santilli@arm.com DPRINTF(GIC, "gic cpu read register %#x cpu context: %d\n", daddr, 29013014Sciro.santilli@arm.com ctx); 29113014Sciro.santilli@arm.com 29213014Sciro.santilli@arm.com pkt->set<uint32_t>(readCpu(ctx, daddr)); 29313014Sciro.santilli@arm.com 29413014Sciro.santilli@arm.com pkt->makeAtomicResponse(); 29513014Sciro.santilli@arm.com return cpuPioDelay; 29613014Sciro.santilli@arm.com} 29713014Sciro.santilli@arm.com 29813014Sciro.santilli@arm.comuint32_t 29913014Sciro.santilli@arm.comGicV2::readCpu(ContextID ctx, Addr daddr) 30013014Sciro.santilli@arm.com{ 30113014Sciro.santilli@arm.com switch(daddr) { 30213014Sciro.santilli@arm.com case GICC_IIDR: 30313014Sciro.santilli@arm.com return GICC_400_IIDR_VALUE; 30413014Sciro.santilli@arm.com case GICC_CTLR: 30513014Sciro.santilli@arm.com return cpuEnabled[ctx]; 30613014Sciro.santilli@arm.com case GICC_PMR: 30713014Sciro.santilli@arm.com return cpuPriority[ctx]; 30813014Sciro.santilli@arm.com case GICC_BPR: 30913014Sciro.santilli@arm.com return cpuBpr[ctx]; 31013014Sciro.santilli@arm.com case GICC_IAR: 31113014Sciro.santilli@arm.com if (enabled && cpuEnabled[ctx]) { 31213014Sciro.santilli@arm.com int active_int = cpuHighestInt[ctx]; 31313014Sciro.santilli@arm.com IAR iar = 0; 31413014Sciro.santilli@arm.com iar.ack_id = active_int; 31513014Sciro.santilli@arm.com iar.cpu_id = 0; 31613014Sciro.santilli@arm.com if (active_int < SGI_MAX) { 31713014Sciro.santilli@arm.com // this is a software interrupt from another CPU 31813014Sciro.santilli@arm.com if (!gem5ExtensionsEnabled) { 31913014Sciro.santilli@arm.com panic_if(!cpuSgiPending[active_int], 32013014Sciro.santilli@arm.com "Interrupt %d active but no CPU generated it?\n", 32113014Sciro.santilli@arm.com active_int); 32213014Sciro.santilli@arm.com for (int x = 0; x < sys->numRunningContexts(); x++) { 32313014Sciro.santilli@arm.com // See which CPU generated the interrupt 32413014Sciro.santilli@arm.com uint8_t cpugen = 32513014Sciro.santilli@arm.com bits(cpuSgiPending[active_int], 7 + 8 * x, 8 * x); 32613014Sciro.santilli@arm.com if (cpugen & (1 << ctx)) { 32713014Sciro.santilli@arm.com iar.cpu_id = x; 32813014Sciro.santilli@arm.com break; 32913014Sciro.santilli@arm.com } 33013014Sciro.santilli@arm.com } 33113014Sciro.santilli@arm.com uint64_t sgi_num = ULL(1) << (ctx + 8 * iar.cpu_id); 33213014Sciro.santilli@arm.com cpuSgiActive[iar.ack_id] |= sgi_num; 33313014Sciro.santilli@arm.com cpuSgiPending[iar.ack_id] &= ~sgi_num; 33413014Sciro.santilli@arm.com } else { 33513014Sciro.santilli@arm.com uint64_t sgi_num = ULL(1) << iar.ack_id; 33613014Sciro.santilli@arm.com cpuSgiActiveExt[ctx] |= sgi_num; 33713014Sciro.santilli@arm.com cpuSgiPendingExt[ctx] &= ~sgi_num; 33813014Sciro.santilli@arm.com } 33913014Sciro.santilli@arm.com } else if (active_int < (SGI_MAX + PPI_MAX) ) { 34013014Sciro.santilli@arm.com uint32_t int_num = 1 << (cpuHighestInt[ctx] - SGI_MAX); 34113014Sciro.santilli@arm.com cpuPpiActive[ctx] |= int_num; 34213014Sciro.santilli@arm.com updateRunPri(); 34313014Sciro.santilli@arm.com cpuPpiPending[ctx] &= ~int_num; 34413014Sciro.santilli@arm.com 34513014Sciro.santilli@arm.com } else { 34613014Sciro.santilli@arm.com uint32_t int_num = 1 << intNumToBit(cpuHighestInt[ctx]); 34713014Sciro.santilli@arm.com getActiveInt(ctx, intNumToWord(cpuHighestInt[ctx])) |= int_num; 34813014Sciro.santilli@arm.com updateRunPri(); 34913014Sciro.santilli@arm.com getPendingInt(ctx, intNumToWord(cpuHighestInt[ctx])) 35013014Sciro.santilli@arm.com &= ~int_num; 35113014Sciro.santilli@arm.com } 35213014Sciro.santilli@arm.com 35313014Sciro.santilli@arm.com DPRINTF(Interrupt, 35413014Sciro.santilli@arm.com "CPU %d reading IAR.id=%d IAR.cpu=%d, iar=0x%x\n", 35513014Sciro.santilli@arm.com ctx, iar.ack_id, iar.cpu_id, iar); 35613014Sciro.santilli@arm.com cpuHighestInt[ctx] = SPURIOUS_INT; 35713014Sciro.santilli@arm.com updateIntState(-1); 35813014Sciro.santilli@arm.com platform->intrctrl->clear(ctx, ArmISA::INT_IRQ, 0); 35913014Sciro.santilli@arm.com return iar; 36013014Sciro.santilli@arm.com } else { 36113014Sciro.santilli@arm.com return SPURIOUS_INT; 36213014Sciro.santilli@arm.com } 36313014Sciro.santilli@arm.com 36413014Sciro.santilli@arm.com break; 36513014Sciro.santilli@arm.com case GICC_RPR: 36613014Sciro.santilli@arm.com return iccrpr[0]; 36713014Sciro.santilli@arm.com case GICC_HPPIR: 36813014Sciro.santilli@arm.com panic("Need to implement HPIR"); 36913014Sciro.santilli@arm.com break; 37013014Sciro.santilli@arm.com default: 37113014Sciro.santilli@arm.com panic("Tried to read Gic cpu at offset %#x\n", daddr); 37213014Sciro.santilli@arm.com break; 37313014Sciro.santilli@arm.com } 37413014Sciro.santilli@arm.com} 37513014Sciro.santilli@arm.com 37613014Sciro.santilli@arm.comTick 37713014Sciro.santilli@arm.comGicV2::writeDistributor(PacketPtr pkt) 37813014Sciro.santilli@arm.com{ 37913014Sciro.santilli@arm.com const Addr daddr = pkt->getAddr() - distRange.start(); 38013014Sciro.santilli@arm.com 38113014Sciro.santilli@arm.com assert(pkt->req->hasContextId()); 38213014Sciro.santilli@arm.com const ContextID ctx = pkt->req->contextId(); 38313014Sciro.santilli@arm.com const size_t data_sz = pkt->getSize(); 38413014Sciro.santilli@arm.com 38513014Sciro.santilli@arm.com uint32_t pkt_data M5_VAR_USED; 38613014Sciro.santilli@arm.com switch (data_sz) 38713014Sciro.santilli@arm.com { 38813014Sciro.santilli@arm.com case 1: 38913014Sciro.santilli@arm.com pkt_data = pkt->get<uint8_t>(); 39013014Sciro.santilli@arm.com break; 39113014Sciro.santilli@arm.com case 2: 39213014Sciro.santilli@arm.com pkt_data = pkt->get<uint16_t>(); 39313014Sciro.santilli@arm.com break; 39413014Sciro.santilli@arm.com case 4: 39513014Sciro.santilli@arm.com pkt_data = pkt->get<uint32_t>(); 39613014Sciro.santilli@arm.com break; 39713014Sciro.santilli@arm.com default: 39813014Sciro.santilli@arm.com panic("Invalid size when writing to priority regs in Gic: %d\n", 39913014Sciro.santilli@arm.com data_sz); 40013014Sciro.santilli@arm.com } 40113014Sciro.santilli@arm.com 40213014Sciro.santilli@arm.com DPRINTF(GIC, "gic distributor write register %#x size %#x value %#x \n", 40313014Sciro.santilli@arm.com daddr, data_sz, pkt_data); 40413014Sciro.santilli@arm.com 40513014Sciro.santilli@arm.com writeDistributor(ctx, daddr, pkt_data, data_sz); 40613014Sciro.santilli@arm.com 40713014Sciro.santilli@arm.com pkt->makeAtomicResponse(); 40813014Sciro.santilli@arm.com return distPioDelay; 40913014Sciro.santilli@arm.com} 41013014Sciro.santilli@arm.com 41113014Sciro.santilli@arm.comvoid 41213014Sciro.santilli@arm.comGicV2::writeDistributor(ContextID ctx, Addr daddr, uint32_t data, 41313014Sciro.santilli@arm.com size_t data_sz) 41413014Sciro.santilli@arm.com{ 41513014Sciro.santilli@arm.com if (GICD_IGROUPR.contains(daddr)) { 41613014Sciro.santilli@arm.com return; // unimplemented; WI (writes ignored) 41713014Sciro.santilli@arm.com } 41813014Sciro.santilli@arm.com 41913014Sciro.santilli@arm.com if (GICD_ISENABLER.contains(daddr)) { 42013014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ISENABLER.start()) >> 2; 42113014Sciro.santilli@arm.com assert(ix < 32); 42213014Sciro.santilli@arm.com getIntEnabled(ctx, ix) |= data; 42313014Sciro.santilli@arm.com return; 42413014Sciro.santilli@arm.com } 42513014Sciro.santilli@arm.com 42613014Sciro.santilli@arm.com if (GICD_ICENABLER.contains(daddr)) { 42713014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ICENABLER.start()) >> 2; 42813014Sciro.santilli@arm.com assert(ix < 32); 42913014Sciro.santilli@arm.com getIntEnabled(ctx, ix) &= ~data; 43013014Sciro.santilli@arm.com return; 43113014Sciro.santilli@arm.com } 43213014Sciro.santilli@arm.com 43313014Sciro.santilli@arm.com if (GICD_ISPENDR.contains(daddr)) { 43413014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ISPENDR.start()) >> 2; 43513014Sciro.santilli@arm.com auto mask = data; 43613014Sciro.santilli@arm.com if (ix == 0) mask &= SGI_MASK; // Don't allow SGIs to be changed 43713014Sciro.santilli@arm.com getPendingInt(ctx, ix) |= mask; 43813014Sciro.santilli@arm.com updateIntState(ix); 43913014Sciro.santilli@arm.com return; 44013014Sciro.santilli@arm.com } 44113014Sciro.santilli@arm.com 44213014Sciro.santilli@arm.com if (GICD_ICPENDR.contains(daddr)) { 44313014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ICPENDR.start()) >> 2; 44413014Sciro.santilli@arm.com auto mask = data; 44513014Sciro.santilli@arm.com if (ix == 0) mask &= SGI_MASK; // Don't allow SGIs to be changed 44613014Sciro.santilli@arm.com getPendingInt(ctx, ix) &= ~mask; 44713014Sciro.santilli@arm.com updateIntState(ix); 44813014Sciro.santilli@arm.com return; 44913014Sciro.santilli@arm.com } 45013014Sciro.santilli@arm.com 45113014Sciro.santilli@arm.com if (GICD_ISACTIVER.contains(daddr)) { 45213014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ISACTIVER.start()) >> 2; 45313014Sciro.santilli@arm.com getActiveInt(ctx, ix) |= data; 45413014Sciro.santilli@arm.com return; 45513014Sciro.santilli@arm.com } 45613014Sciro.santilli@arm.com 45713014Sciro.santilli@arm.com if (GICD_ICACTIVER.contains(daddr)) { 45813014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ICACTIVER.start()) >> 2; 45913014Sciro.santilli@arm.com getActiveInt(ctx, ix) &= ~data; 46013014Sciro.santilli@arm.com return; 46113014Sciro.santilli@arm.com } 46213014Sciro.santilli@arm.com 46313014Sciro.santilli@arm.com if (GICD_IPRIORITYR.contains(daddr)) { 46413014Sciro.santilli@arm.com Addr int_num = daddr - GICD_IPRIORITYR.start(); 46513014Sciro.santilli@arm.com switch(data_sz) { 46613014Sciro.santilli@arm.com case 1: 46713014Sciro.santilli@arm.com getIntPriority(ctx, int_num) = data; 46813014Sciro.santilli@arm.com break; 46913014Sciro.santilli@arm.com case 2: { 47013014Sciro.santilli@arm.com getIntPriority(ctx, int_num) = bits(data, 7, 0); 47113014Sciro.santilli@arm.com getIntPriority(ctx, int_num + 1) = bits(data, 15, 8); 47213014Sciro.santilli@arm.com break; 47313014Sciro.santilli@arm.com } 47413014Sciro.santilli@arm.com case 4: { 47513014Sciro.santilli@arm.com getIntPriority(ctx, int_num) = bits(data, 7, 0); 47613014Sciro.santilli@arm.com getIntPriority(ctx, int_num + 1) = bits(data, 15, 8); 47713014Sciro.santilli@arm.com getIntPriority(ctx, int_num + 2) = bits(data, 23, 16); 47813014Sciro.santilli@arm.com getIntPriority(ctx, int_num + 3) = bits(data, 31, 24); 47913014Sciro.santilli@arm.com break; 48013014Sciro.santilli@arm.com } 48113014Sciro.santilli@arm.com default: 48213014Sciro.santilli@arm.com panic("Invalid size when writing to priority regs in Gic: %d\n", 48313014Sciro.santilli@arm.com data_sz); 48413014Sciro.santilli@arm.com } 48513014Sciro.santilli@arm.com 48613014Sciro.santilli@arm.com updateIntState(-1); 48713014Sciro.santilli@arm.com updateRunPri(); 48813014Sciro.santilli@arm.com return; 48913014Sciro.santilli@arm.com } 49013014Sciro.santilli@arm.com 49113014Sciro.santilli@arm.com if (GICD_ITARGETSR.contains(daddr)) { 49213014Sciro.santilli@arm.com Addr int_num = daddr - GICD_ITARGETSR.start(); 49313014Sciro.santilli@arm.com // Interrupts 0-31 are read only 49413014Sciro.santilli@arm.com unsigned offset = SGI_MAX + PPI_MAX; 49513014Sciro.santilli@arm.com if (int_num >= offset) { 49613014Sciro.santilli@arm.com unsigned ix = int_num - offset; // index into cpuTarget array 49713014Sciro.santilli@arm.com if (data_sz == 1) { 49813014Sciro.santilli@arm.com cpuTarget[ix] = data & 0xff; 49913014Sciro.santilli@arm.com } else { 50013014Sciro.santilli@arm.com assert (data_sz == 4); 50113014Sciro.santilli@arm.com cpuTarget[ix] = bits(data, 7, 0); 50213014Sciro.santilli@arm.com cpuTarget[ix+1] = bits(data, 15, 8); 50313014Sciro.santilli@arm.com cpuTarget[ix+2] = bits(data, 23, 16); 50413014Sciro.santilli@arm.com cpuTarget[ix+3] = bits(data, 31, 24); 50513014Sciro.santilli@arm.com } 50613014Sciro.santilli@arm.com updateIntState(int_num >> 2); 50713014Sciro.santilli@arm.com } 50813014Sciro.santilli@arm.com return; 50913014Sciro.santilli@arm.com } 51013014Sciro.santilli@arm.com 51113014Sciro.santilli@arm.com if (GICD_ICFGR.contains(daddr)) { 51213014Sciro.santilli@arm.com uint32_t ix = (daddr - GICD_ICFGR.start()) >> 2; 51313014Sciro.santilli@arm.com assert(ix < INT_BITS_MAX*2); 51413014Sciro.santilli@arm.com intConfig[ix] = data; 51513014Sciro.santilli@arm.com if (data & NN_CONFIG_MASK) 51613014Sciro.santilli@arm.com warn("GIC N:N mode selected and not supported at this time\n"); 51713014Sciro.santilli@arm.com return; 51813014Sciro.santilli@arm.com } 51913014Sciro.santilli@arm.com 52013014Sciro.santilli@arm.com switch(daddr) { 52113014Sciro.santilli@arm.com case GICD_CTLR: 52213014Sciro.santilli@arm.com enabled = data; 52313014Sciro.santilli@arm.com DPRINTF(Interrupt, "Distributor enable flag set to = %d\n", enabled); 52413014Sciro.santilli@arm.com break; 52513014Sciro.santilli@arm.com case GICD_TYPER: 52613014Sciro.santilli@arm.com /* 0x200 is a made-up flag to enable gem5 extension functionality. 52713014Sciro.santilli@arm.com * This reg is not normally written. 52813014Sciro.santilli@arm.com */ 52913014Sciro.santilli@arm.com gem5ExtensionsEnabled = (data & 0x200) && haveGem5Extensions; 53013014Sciro.santilli@arm.com DPRINTF(GIC, "gem5 extensions %s\n", 53113014Sciro.santilli@arm.com gem5ExtensionsEnabled ? "enabled" : "disabled"); 53213014Sciro.santilli@arm.com break; 53313014Sciro.santilli@arm.com case GICD_SGIR: 53413014Sciro.santilli@arm.com softInt(ctx, data); 53513014Sciro.santilli@arm.com break; 53613014Sciro.santilli@arm.com default: 53713014Sciro.santilli@arm.com panic("Tried to write Gic distributor at offset %#x\n", daddr); 53813014Sciro.santilli@arm.com break; 53913014Sciro.santilli@arm.com } 54013014Sciro.santilli@arm.com} 54113014Sciro.santilli@arm.com 54213014Sciro.santilli@arm.comTick 54313014Sciro.santilli@arm.comGicV2::writeCpu(PacketPtr pkt) 54413014Sciro.santilli@arm.com{ 54513014Sciro.santilli@arm.com const Addr daddr = pkt->getAddr() - cpuRange.start(); 54613014Sciro.santilli@arm.com 54713014Sciro.santilli@arm.com assert(pkt->req->hasContextId()); 54813014Sciro.santilli@arm.com const ContextID ctx = pkt->req->contextId(); 54913014Sciro.santilli@arm.com const uint32_t data = pkt->get<uint32_t>(); 55013014Sciro.santilli@arm.com 55113014Sciro.santilli@arm.com DPRINTF(GIC, "gic cpu write register cpu:%d %#x val: %#x\n", 55213014Sciro.santilli@arm.com ctx, daddr, data); 55313014Sciro.santilli@arm.com 55413014Sciro.santilli@arm.com writeCpu(ctx, daddr, data); 55513014Sciro.santilli@arm.com 55613014Sciro.santilli@arm.com pkt->makeAtomicResponse(); 55713014Sciro.santilli@arm.com return cpuPioDelay; 55813014Sciro.santilli@arm.com} 55913014Sciro.santilli@arm.com 56013014Sciro.santilli@arm.comvoid 56113014Sciro.santilli@arm.comGicV2::writeCpu(ContextID ctx, Addr daddr, uint32_t data) 56213014Sciro.santilli@arm.com{ 56313014Sciro.santilli@arm.com switch(daddr) { 56413014Sciro.santilli@arm.com case GICC_CTLR: 56513014Sciro.santilli@arm.com cpuEnabled[ctx] = data; 56613014Sciro.santilli@arm.com break; 56713014Sciro.santilli@arm.com case GICC_PMR: 56813014Sciro.santilli@arm.com cpuPriority[ctx] = data; 56913014Sciro.santilli@arm.com break; 57013014Sciro.santilli@arm.com case GICC_BPR: { 57113014Sciro.santilli@arm.com auto bpr = data & 0x7; 57213014Sciro.santilli@arm.com if (bpr < GICC_BPR_MINIMUM) 57313014Sciro.santilli@arm.com bpr = GICC_BPR_MINIMUM; 57413014Sciro.santilli@arm.com cpuBpr[ctx] = bpr; 57513014Sciro.santilli@arm.com break; 57613014Sciro.santilli@arm.com } 57713014Sciro.santilli@arm.com case GICC_EOIR: { 57813014Sciro.santilli@arm.com const IAR iar = data; 57913014Sciro.santilli@arm.com if (iar.ack_id < SGI_MAX) { 58013014Sciro.santilli@arm.com // Clear out the bit that corresponds to the cleared int 58113014Sciro.santilli@arm.com uint64_t clr_int = ULL(1) << (ctx + 8 * iar.cpu_id); 58213014Sciro.santilli@arm.com if (!(cpuSgiActive[iar.ack_id] & clr_int) && 58313014Sciro.santilli@arm.com !(cpuSgiActiveExt[ctx] & (1 << iar.ack_id))) 58413014Sciro.santilli@arm.com panic("Done handling a SGI that isn't active?\n"); 58513014Sciro.santilli@arm.com if (gem5ExtensionsEnabled) 58613014Sciro.santilli@arm.com cpuSgiActiveExt[ctx] &= ~(1 << iar.ack_id); 58713014Sciro.santilli@arm.com else 58813014Sciro.santilli@arm.com cpuSgiActive[iar.ack_id] &= ~clr_int; 58913014Sciro.santilli@arm.com } else if (iar.ack_id < (SGI_MAX + PPI_MAX) ) { 59013014Sciro.santilli@arm.com uint32_t int_num = 1 << (iar.ack_id - SGI_MAX); 59113014Sciro.santilli@arm.com if (!(cpuPpiActive[ctx] & int_num)) 59213014Sciro.santilli@arm.com panic("CPU %d Done handling a PPI interrupt " 59313014Sciro.santilli@arm.com "that isn't active?\n", ctx); 59413014Sciro.santilli@arm.com cpuPpiActive[ctx] &= ~int_num; 59513014Sciro.santilli@arm.com } else { 59613014Sciro.santilli@arm.com uint32_t int_num = 1 << intNumToBit(iar.ack_id); 59713014Sciro.santilli@arm.com if (!(getActiveInt(ctx, intNumToWord(iar.ack_id)) & int_num)) 59813014Sciro.santilli@arm.com warn("Done handling interrupt that isn't active: %d\n", 59913014Sciro.santilli@arm.com intNumToBit(iar.ack_id)); 60013014Sciro.santilli@arm.com getActiveInt(ctx, intNumToWord(iar.ack_id)) &= ~int_num; 60113014Sciro.santilli@arm.com } 60213014Sciro.santilli@arm.com updateRunPri(); 60313014Sciro.santilli@arm.com DPRINTF(Interrupt, "CPU %d done handling intr IAR = %d from cpu %d\n", 60413014Sciro.santilli@arm.com ctx, iar.ack_id, iar.cpu_id); 60513014Sciro.santilli@arm.com break; 60613014Sciro.santilli@arm.com } 60713014Sciro.santilli@arm.com case GICC_APR0: 60813014Sciro.santilli@arm.com case GICC_APR1: 60913014Sciro.santilli@arm.com case GICC_APR2: 61013014Sciro.santilli@arm.com case GICC_APR3: 61113014Sciro.santilli@arm.com warn("GIC APRn write ignored because not implemented: %#x\n", daddr); 61213014Sciro.santilli@arm.com break; 61313014Sciro.santilli@arm.com default: 61413014Sciro.santilli@arm.com panic("Tried to write Gic cpu at offset %#x\n", daddr); 61513014Sciro.santilli@arm.com break; 61613014Sciro.santilli@arm.com } 61713014Sciro.santilli@arm.com if (cpuEnabled[ctx]) updateIntState(-1); 61813014Sciro.santilli@arm.com} 61913014Sciro.santilli@arm.com 62013014Sciro.santilli@arm.comGicV2::BankedRegs& 62113014Sciro.santilli@arm.comGicV2::getBankedRegs(ContextID ctx) { 62213014Sciro.santilli@arm.com if (bankedRegs.size() <= ctx) 62313014Sciro.santilli@arm.com bankedRegs.resize(ctx + 1); 62413014Sciro.santilli@arm.com 62513014Sciro.santilli@arm.com if (!bankedRegs[ctx]) 62613014Sciro.santilli@arm.com bankedRegs[ctx] = new BankedRegs; 62713014Sciro.santilli@arm.com return *bankedRegs[ctx]; 62813014Sciro.santilli@arm.com} 62913014Sciro.santilli@arm.com 63013014Sciro.santilli@arm.comvoid 63113014Sciro.santilli@arm.comGicV2::softInt(ContextID ctx, SWI swi) 63213014Sciro.santilli@arm.com{ 63313014Sciro.santilli@arm.com if (gem5ExtensionsEnabled) { 63413014Sciro.santilli@arm.com switch (swi.list_type) { 63513014Sciro.santilli@arm.com case 0: { 63613014Sciro.santilli@arm.com // interrupt cpus specified 63713014Sciro.santilli@arm.com int dest = swi.cpu_list; 63813014Sciro.santilli@arm.com DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n", 63913014Sciro.santilli@arm.com ctx, dest); 64013014Sciro.santilli@arm.com if (cpuEnabled[dest]) { 64113014Sciro.santilli@arm.com cpuSgiPendingExt[dest] |= (1 << swi.sgi_id); 64213014Sciro.santilli@arm.com DPRINTF(IPI, "SGI[%d]=%#x\n", dest, 64313014Sciro.santilli@arm.com cpuSgiPendingExt[dest]); 64413014Sciro.santilli@arm.com } 64513014Sciro.santilli@arm.com } break; 64613014Sciro.santilli@arm.com case 1: { 64713014Sciro.santilli@arm.com // interrupt all 64813014Sciro.santilli@arm.com for (int i = 0; i < sys->numContexts(); i++) { 64913014Sciro.santilli@arm.com DPRINTF(IPI, "Processing CPU %d\n", i); 65013014Sciro.santilli@arm.com if (!cpuEnabled[i]) 65113014Sciro.santilli@arm.com continue; 65213014Sciro.santilli@arm.com cpuSgiPendingExt[i] |= 1 << swi.sgi_id; 65313014Sciro.santilli@arm.com DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id, 65413014Sciro.santilli@arm.com cpuSgiPendingExt[i]); 65513014Sciro.santilli@arm.com } 65613014Sciro.santilli@arm.com } break; 65713014Sciro.santilli@arm.com case 2: { 65813014Sciro.santilli@arm.com // Interrupt requesting cpu only 65913014Sciro.santilli@arm.com DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n", 66013014Sciro.santilli@arm.com ctx, ctx); 66113014Sciro.santilli@arm.com if (cpuEnabled[ctx]) { 66213014Sciro.santilli@arm.com cpuSgiPendingExt[ctx] |= (1 << swi.sgi_id); 66313014Sciro.santilli@arm.com DPRINTF(IPI, "SGI[%d]=%#x\n", ctx, 66413014Sciro.santilli@arm.com cpuSgiPendingExt[ctx]); 66513014Sciro.santilli@arm.com } 66613014Sciro.santilli@arm.com } break; 66713014Sciro.santilli@arm.com } 66813014Sciro.santilli@arm.com } else { 66913014Sciro.santilli@arm.com switch (swi.list_type) { 67013014Sciro.santilli@arm.com case 1: 67113014Sciro.santilli@arm.com // interrupt all 67213014Sciro.santilli@arm.com uint8_t cpu_list; 67313014Sciro.santilli@arm.com cpu_list = 0; 67413014Sciro.santilli@arm.com for (int x = 0; x < sys->numContexts(); x++) 67513014Sciro.santilli@arm.com cpu_list |= cpuEnabled[x] ? 1 << x : 0; 67613014Sciro.santilli@arm.com swi.cpu_list = cpu_list; 67713014Sciro.santilli@arm.com break; 67813014Sciro.santilli@arm.com case 2: 67913014Sciro.santilli@arm.com // interrupt requesting cpu only 68013014Sciro.santilli@arm.com swi.cpu_list = 1 << ctx; 68113014Sciro.santilli@arm.com break; 68213014Sciro.santilli@arm.com // else interrupt cpus specified 68313014Sciro.santilli@arm.com } 68413014Sciro.santilli@arm.com 68513014Sciro.santilli@arm.com DPRINTF(IPI, "Generating softIRQ from CPU %d for %#x\n", ctx, 68613014Sciro.santilli@arm.com swi.cpu_list); 68713014Sciro.santilli@arm.com for (int i = 0; i < sys->numContexts(); i++) { 68813014Sciro.santilli@arm.com DPRINTF(IPI, "Processing CPU %d\n", i); 68913014Sciro.santilli@arm.com if (!cpuEnabled[i]) 69013014Sciro.santilli@arm.com continue; 69113014Sciro.santilli@arm.com if (swi.cpu_list & (1 << i)) 69213014Sciro.santilli@arm.com cpuSgiPending[swi.sgi_id] |= (1 << i) << (8 * ctx); 69313014Sciro.santilli@arm.com DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id, 69413014Sciro.santilli@arm.com cpuSgiPending[swi.sgi_id]); 69513014Sciro.santilli@arm.com } 69613014Sciro.santilli@arm.com } 69713014Sciro.santilli@arm.com updateIntState(-1); 69813014Sciro.santilli@arm.com} 69913014Sciro.santilli@arm.com 70013014Sciro.santilli@arm.comuint64_t 70113014Sciro.santilli@arm.comGicV2::genSwiMask(int cpu) 70213014Sciro.santilli@arm.com{ 70313014Sciro.santilli@arm.com if (cpu > sys->numContexts()) 70413014Sciro.santilli@arm.com panic("Invalid CPU ID\n"); 70513014Sciro.santilli@arm.com return ULL(0x0101010101010101) << cpu; 70613014Sciro.santilli@arm.com} 70713014Sciro.santilli@arm.com 70813014Sciro.santilli@arm.comuint8_t 70913014Sciro.santilli@arm.comGicV2::getCpuPriority(unsigned cpu) 71013014Sciro.santilli@arm.com{ 71113014Sciro.santilli@arm.com // see Table 3-2 in IHI0048B.b (GICv2) 71213014Sciro.santilli@arm.com // mask some low-order priority bits per BPR value 71313014Sciro.santilli@arm.com // NB: the GIC prioritization scheme is upside down: 71413014Sciro.santilli@arm.com // lower values are higher priority; masking off bits 71513014Sciro.santilli@arm.com // actually creates a higher priority, not lower. 71613014Sciro.santilli@arm.com return cpuPriority[cpu] & (0xff00 >> (7 - cpuBpr[cpu])); 71713014Sciro.santilli@arm.com} 71813014Sciro.santilli@arm.com 71913014Sciro.santilli@arm.comvoid 72013014Sciro.santilli@arm.comGicV2::updateIntState(int hint) 72113014Sciro.santilli@arm.com{ 72213014Sciro.santilli@arm.com for (int cpu = 0; cpu < sys->numContexts(); cpu++) { 72313014Sciro.santilli@arm.com if (!cpuEnabled[cpu]) 72413014Sciro.santilli@arm.com continue; 72513014Sciro.santilli@arm.com 72613014Sciro.santilli@arm.com /*@todo use hint to do less work. */ 72713014Sciro.santilli@arm.com int highest_int = SPURIOUS_INT; 72813014Sciro.santilli@arm.com // Priorities below that set in GICC_PMR can be ignored 72913014Sciro.santilli@arm.com uint8_t highest_pri = getCpuPriority(cpu); 73013014Sciro.santilli@arm.com 73113014Sciro.santilli@arm.com // Check SGIs 73213014Sciro.santilli@arm.com for (int swi = 0; swi < SGI_MAX; swi++) { 73313014Sciro.santilli@arm.com if (!cpuSgiPending[swi] && !cpuSgiPendingExt[cpu]) 73413014Sciro.santilli@arm.com continue; 73513014Sciro.santilli@arm.com if ((cpuSgiPending[swi] & genSwiMask(cpu)) || 73613014Sciro.santilli@arm.com (cpuSgiPendingExt[cpu] & (1 << swi))) 73713014Sciro.santilli@arm.com if (highest_pri > getIntPriority(cpu, swi)) { 73813014Sciro.santilli@arm.com highest_pri = getIntPriority(cpu, swi); 73913014Sciro.santilli@arm.com highest_int = swi; 74013014Sciro.santilli@arm.com } 74113014Sciro.santilli@arm.com } 74213014Sciro.santilli@arm.com 74313014Sciro.santilli@arm.com // Check PPIs 74413014Sciro.santilli@arm.com if (cpuPpiPending[cpu]) { 74513105Sgiacomo.travaglini@arm.com for (int ppi_idx = 0, int_num = SGI_MAX; 74613105Sgiacomo.travaglini@arm.com int_num < PPI_MAX + SGI_MAX; 74713105Sgiacomo.travaglini@arm.com ppi_idx++, int_num++) { 74813105Sgiacomo.travaglini@arm.com 74913105Sgiacomo.travaglini@arm.com const bool ppi_pending = bits(cpuPpiPending[cpu], ppi_idx); 75013105Sgiacomo.travaglini@arm.com const bool ppi_enabled = bits(getIntEnabled(cpu, 0), int_num); 75113105Sgiacomo.travaglini@arm.com const bool higher_priority = 75213105Sgiacomo.travaglini@arm.com highest_pri > getIntPriority(cpu, int_num); 75313105Sgiacomo.travaglini@arm.com 75413105Sgiacomo.travaglini@arm.com if (ppi_pending && ppi_enabled && higher_priority) { 75513105Sgiacomo.travaglini@arm.com highest_pri = getIntPriority(cpu, int_num); 75613105Sgiacomo.travaglini@arm.com highest_int = int_num; 75713014Sciro.santilli@arm.com } 75813014Sciro.santilli@arm.com } 75913014Sciro.santilli@arm.com } 76013014Sciro.santilli@arm.com 76113014Sciro.santilli@arm.com bool mp_sys = sys->numRunningContexts() > 1; 76213014Sciro.santilli@arm.com // Check other ints 76313014Sciro.santilli@arm.com for (int x = 0; x < (itLines/INT_BITS_MAX); x++) { 76413014Sciro.santilli@arm.com if (getIntEnabled(cpu, x) & getPendingInt(cpu, x)) { 76513014Sciro.santilli@arm.com for (int y = 0; y < INT_BITS_MAX; y++) { 76613014Sciro.santilli@arm.com uint32_t int_nm = x * INT_BITS_MAX + y; 76713014Sciro.santilli@arm.com DPRINTF(GIC, "Checking for interrupt# %d \n",int_nm); 76813014Sciro.santilli@arm.com /* Set current pending int as highest int for current cpu 76913014Sciro.santilli@arm.com if the interrupt's priority higher than current priority 77013014Sciro.santilli@arm.com and if current cpu is the target (for mp configs only) 77113014Sciro.santilli@arm.com */ 77213014Sciro.santilli@arm.com if ((bits(getIntEnabled(cpu, x), y) 77313014Sciro.santilli@arm.com &bits(getPendingInt(cpu, x), y)) && 77413014Sciro.santilli@arm.com (getIntPriority(cpu, int_nm) < highest_pri)) 77513014Sciro.santilli@arm.com if ((!mp_sys) || 77613014Sciro.santilli@arm.com (gem5ExtensionsEnabled 77713014Sciro.santilli@arm.com ? (getCpuTarget(cpu, int_nm) == cpu) 77813014Sciro.santilli@arm.com : (getCpuTarget(cpu, int_nm) & (1 << cpu)))) { 77913014Sciro.santilli@arm.com highest_pri = getIntPriority(cpu, int_nm); 78013014Sciro.santilli@arm.com highest_int = int_nm; 78113014Sciro.santilli@arm.com } 78213014Sciro.santilli@arm.com } 78313014Sciro.santilli@arm.com } 78413014Sciro.santilli@arm.com } 78513014Sciro.santilli@arm.com 78613014Sciro.santilli@arm.com cpuHighestInt[cpu] = highest_int; 78713014Sciro.santilli@arm.com 78813014Sciro.santilli@arm.com if (highest_int == SPURIOUS_INT) 78913014Sciro.santilli@arm.com continue; 79013014Sciro.santilli@arm.com 79113014Sciro.santilli@arm.com /* @todo make this work for more than one cpu, need to handle 1:N, N:N 79213014Sciro.santilli@arm.com * models */ 79313014Sciro.santilli@arm.com if (enabled && cpuEnabled[cpu] && 79413014Sciro.santilli@arm.com (highest_pri < getCpuPriority(cpu)) && 79513014Sciro.santilli@arm.com !(getActiveInt(cpu, intNumToWord(highest_int)) 79613014Sciro.santilli@arm.com & (1 << intNumToBit(highest_int)))) { 79713014Sciro.santilli@arm.com 79813014Sciro.santilli@arm.com DPRINTF(Interrupt, "Posting interrupt %d to cpu%d\n", highest_int, 79913014Sciro.santilli@arm.com cpu); 80013014Sciro.santilli@arm.com postInt(cpu, curTick() + intLatency); 80113014Sciro.santilli@arm.com } 80213014Sciro.santilli@arm.com } 80313014Sciro.santilli@arm.com} 80413014Sciro.santilli@arm.com 80513014Sciro.santilli@arm.comvoid 80613014Sciro.santilli@arm.comGicV2::updateRunPri() 80713014Sciro.santilli@arm.com{ 80813014Sciro.santilli@arm.com for (int cpu = 0; cpu < sys->numContexts(); cpu++) { 80913014Sciro.santilli@arm.com if (!cpuEnabled[cpu]) 81013014Sciro.santilli@arm.com continue; 81113014Sciro.santilli@arm.com uint8_t maxPriority = 0xff; 81213014Sciro.santilli@arm.com for (int i = 0; i < itLines; i++) { 81313014Sciro.santilli@arm.com if (i < SGI_MAX) { 81413014Sciro.santilli@arm.com if (((cpuSgiActive[i] & genSwiMask(cpu)) || 81513014Sciro.santilli@arm.com (cpuSgiActiveExt[cpu] & (1 << i))) && 81613014Sciro.santilli@arm.com (getIntPriority(cpu, i) < maxPriority)) 81713014Sciro.santilli@arm.com maxPriority = getIntPriority(cpu, i); 81813014Sciro.santilli@arm.com } else if (i < (SGI_MAX + PPI_MAX)) { 81913014Sciro.santilli@arm.com if ((cpuPpiActive[cpu] & ( 1 << (i - SGI_MAX))) && 82013014Sciro.santilli@arm.com (getIntPriority(cpu, i) < maxPriority)) 82113014Sciro.santilli@arm.com maxPriority = getIntPriority(cpu, i); 82213014Sciro.santilli@arm.com 82313014Sciro.santilli@arm.com } else { 82413014Sciro.santilli@arm.com if (getActiveInt(cpu, intNumToWord(i)) 82513014Sciro.santilli@arm.com & (1 << intNumToBit(i))) 82613014Sciro.santilli@arm.com if (getIntPriority(cpu, i) < maxPriority) 82713014Sciro.santilli@arm.com maxPriority = getIntPriority(cpu, i); 82813014Sciro.santilli@arm.com } 82913014Sciro.santilli@arm.com } 83013014Sciro.santilli@arm.com iccrpr[cpu] = maxPriority; 83113014Sciro.santilli@arm.com } 83213014Sciro.santilli@arm.com} 83313014Sciro.santilli@arm.com 83413014Sciro.santilli@arm.comvoid 83513014Sciro.santilli@arm.comGicV2::sendInt(uint32_t num) 83613014Sciro.santilli@arm.com{ 83713014Sciro.santilli@arm.com uint8_t target = getCpuTarget(0, num); 83813014Sciro.santilli@arm.com DPRINTF(Interrupt, "Received Interrupt number %d, cpuTarget %#x: \n", 83913014Sciro.santilli@arm.com num, target); 84013014Sciro.santilli@arm.com if ((target & (target - 1)) && !gem5ExtensionsEnabled) 84113014Sciro.santilli@arm.com panic("Multiple targets for peripheral interrupts is not supported\n"); 84213014Sciro.santilli@arm.com panic_if(num < SGI_MAX + PPI_MAX, 84313014Sciro.santilli@arm.com "sentInt() must only be used for interrupts 32 and higher"); 84413014Sciro.santilli@arm.com getPendingInt(target, intNumToWord(num)) |= 1 << intNumToBit(num); 84513014Sciro.santilli@arm.com updateIntState(intNumToWord(num)); 84613014Sciro.santilli@arm.com} 84713014Sciro.santilli@arm.com 84813014Sciro.santilli@arm.comvoid 84913014Sciro.santilli@arm.comGicV2::sendPPInt(uint32_t num, uint32_t cpu) 85013014Sciro.santilli@arm.com{ 85113014Sciro.santilli@arm.com DPRINTF(Interrupt, "Received PPI %d, cpuTarget %#x: \n", 85213014Sciro.santilli@arm.com num, cpu); 85313014Sciro.santilli@arm.com cpuPpiPending[cpu] |= 1 << (num - SGI_MAX); 85413014Sciro.santilli@arm.com updateIntState(intNumToWord(num)); 85513014Sciro.santilli@arm.com} 85613014Sciro.santilli@arm.com 85713014Sciro.santilli@arm.comvoid 85813014Sciro.santilli@arm.comGicV2::clearInt(uint32_t number) 85913014Sciro.santilli@arm.com{ 86013014Sciro.santilli@arm.com /* @todo assume edge triggered only at the moment. Nothing to do. */ 86113014Sciro.santilli@arm.com} 86213014Sciro.santilli@arm.com 86313014Sciro.santilli@arm.comvoid 86413014Sciro.santilli@arm.comGicV2::clearPPInt(uint32_t num, uint32_t cpu) 86513014Sciro.santilli@arm.com{ 86613014Sciro.santilli@arm.com DPRINTF(Interrupt, "Clearing PPI %d, cpuTarget %#x: \n", 86713014Sciro.santilli@arm.com num, cpu); 86813014Sciro.santilli@arm.com cpuPpiPending[cpu] &= ~(1 << (num - SGI_MAX)); 86913014Sciro.santilli@arm.com updateIntState(intNumToWord(num)); 87013014Sciro.santilli@arm.com} 87113014Sciro.santilli@arm.com 87213014Sciro.santilli@arm.comvoid 87313014Sciro.santilli@arm.comGicV2::postInt(uint32_t cpu, Tick when) 87413014Sciro.santilli@arm.com{ 87513014Sciro.santilli@arm.com if (!(postIntEvent[cpu]->scheduled())) { 87613014Sciro.santilli@arm.com ++pendingDelayedInterrupts; 87713014Sciro.santilli@arm.com eventq->schedule(postIntEvent[cpu], when); 87813014Sciro.santilli@arm.com } 87913014Sciro.santilli@arm.com} 88013014Sciro.santilli@arm.com 88113014Sciro.santilli@arm.comvoid 88213014Sciro.santilli@arm.comGicV2::postDelayedInt(uint32_t cpu) 88313014Sciro.santilli@arm.com{ 88413014Sciro.santilli@arm.com platform->intrctrl->post(cpu, ArmISA::INT_IRQ, 0); 88513014Sciro.santilli@arm.com --pendingDelayedInterrupts; 88613014Sciro.santilli@arm.com assert(pendingDelayedInterrupts >= 0); 88713014Sciro.santilli@arm.com if (pendingDelayedInterrupts == 0) 88813014Sciro.santilli@arm.com signalDrainDone(); 88913014Sciro.santilli@arm.com} 89013014Sciro.santilli@arm.com 89113014Sciro.santilli@arm.comDrainState 89213014Sciro.santilli@arm.comGicV2::drain() 89313014Sciro.santilli@arm.com{ 89413014Sciro.santilli@arm.com if (pendingDelayedInterrupts == 0) { 89513014Sciro.santilli@arm.com return DrainState::Drained; 89613014Sciro.santilli@arm.com } else { 89713014Sciro.santilli@arm.com return DrainState::Draining; 89813014Sciro.santilli@arm.com } 89913014Sciro.santilli@arm.com} 90013014Sciro.santilli@arm.com 90113014Sciro.santilli@arm.com 90213014Sciro.santilli@arm.comvoid 90313014Sciro.santilli@arm.comGicV2::drainResume() 90413014Sciro.santilli@arm.com{ 90513014Sciro.santilli@arm.com // There may be pending interrupts if checkpointed from Kvm; post them. 90613014Sciro.santilli@arm.com updateIntState(-1); 90713014Sciro.santilli@arm.com} 90813014Sciro.santilli@arm.com 90913014Sciro.santilli@arm.comvoid 91013014Sciro.santilli@arm.comGicV2::serialize(CheckpointOut &cp) const 91113014Sciro.santilli@arm.com{ 91213014Sciro.santilli@arm.com DPRINTF(Checkpoint, "Serializing Arm GIC\n"); 91313014Sciro.santilli@arm.com 91413014Sciro.santilli@arm.com SERIALIZE_SCALAR(enabled); 91513014Sciro.santilli@arm.com SERIALIZE_SCALAR(itLines); 91613014Sciro.santilli@arm.com SERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1); 91713014Sciro.santilli@arm.com SERIALIZE_ARRAY(pendingInt, INT_BITS_MAX-1); 91813014Sciro.santilli@arm.com SERIALIZE_ARRAY(activeInt, INT_BITS_MAX-1); 91913014Sciro.santilli@arm.com SERIALIZE_ARRAY(iccrpr, CPU_MAX); 92013014Sciro.santilli@arm.com SERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES); 92113014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES); 92213014Sciro.santilli@arm.com SERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2); 92313014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuEnabled, CPU_MAX); 92413014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuPriority, CPU_MAX); 92513014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuBpr, CPU_MAX); 92613014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuHighestInt, CPU_MAX); 92713014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuSgiActive, SGI_MAX); 92813014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuSgiPending, SGI_MAX); 92913014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuSgiActiveExt, CPU_MAX); 93013014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuSgiPendingExt, CPU_MAX); 93113014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuPpiActive, CPU_MAX); 93213014Sciro.santilli@arm.com SERIALIZE_ARRAY(cpuPpiPending, CPU_MAX); 93313014Sciro.santilli@arm.com SERIALIZE_SCALAR(gem5ExtensionsEnabled); 93413014Sciro.santilli@arm.com 93513014Sciro.santilli@arm.com for (uint32_t i=0; i < bankedRegs.size(); ++i) { 93613014Sciro.santilli@arm.com if (!bankedRegs[i]) 93713014Sciro.santilli@arm.com continue; 93813014Sciro.santilli@arm.com bankedRegs[i]->serializeSection(cp, csprintf("bankedRegs%i", i)); 93913014Sciro.santilli@arm.com } 94013014Sciro.santilli@arm.com} 94113014Sciro.santilli@arm.com 94213014Sciro.santilli@arm.comvoid 94313014Sciro.santilli@arm.comGicV2::BankedRegs::serialize(CheckpointOut &cp) const 94413014Sciro.santilli@arm.com{ 94513014Sciro.santilli@arm.com SERIALIZE_SCALAR(intEnabled); 94613014Sciro.santilli@arm.com SERIALIZE_SCALAR(pendingInt); 94713014Sciro.santilli@arm.com SERIALIZE_SCALAR(activeInt); 94813014Sciro.santilli@arm.com SERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX); 94913014Sciro.santilli@arm.com} 95013014Sciro.santilli@arm.com 95113014Sciro.santilli@arm.comvoid 95213014Sciro.santilli@arm.comGicV2::unserialize(CheckpointIn &cp) 95313014Sciro.santilli@arm.com{ 95413014Sciro.santilli@arm.com DPRINTF(Checkpoint, "Unserializing Arm GIC\n"); 95513014Sciro.santilli@arm.com 95613014Sciro.santilli@arm.com UNSERIALIZE_SCALAR(enabled); 95713014Sciro.santilli@arm.com UNSERIALIZE_SCALAR(itLines); 95813014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1); 95913014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(pendingInt, INT_BITS_MAX-1); 96013014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(activeInt, INT_BITS_MAX-1); 96113014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(iccrpr, CPU_MAX); 96213014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES); 96313014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES); 96413014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2); 96513014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuEnabled, CPU_MAX); 96613014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuPriority, CPU_MAX); 96713014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuBpr, CPU_MAX); 96813014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuHighestInt, CPU_MAX); 96913014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuSgiActive, SGI_MAX); 97013014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuSgiPending, SGI_MAX); 97113014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuSgiActiveExt, CPU_MAX); 97213014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuSgiPendingExt, CPU_MAX); 97313014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuPpiActive, CPU_MAX); 97413014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(cpuPpiPending, CPU_MAX); 97513014Sciro.santilli@arm.com 97613014Sciro.santilli@arm.com // Handle checkpoints from before we drained the GIC to prevent 97713014Sciro.santilli@arm.com // in-flight interrupts. 97813014Sciro.santilli@arm.com if (cp.entryExists(Serializable::currentSection(), "interrupt_time")) { 97913014Sciro.santilli@arm.com Tick interrupt_time[CPU_MAX]; 98013014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(interrupt_time, CPU_MAX); 98113014Sciro.santilli@arm.com 98213014Sciro.santilli@arm.com for (uint32_t cpu = 0; cpu < CPU_MAX; cpu++) { 98313014Sciro.santilli@arm.com if (interrupt_time[cpu]) 98413014Sciro.santilli@arm.com schedule(postIntEvent[cpu], interrupt_time[cpu]); 98513014Sciro.santilli@arm.com } 98613014Sciro.santilli@arm.com } 98713014Sciro.santilli@arm.com 98813014Sciro.santilli@arm.com if (!UNSERIALIZE_OPT_SCALAR(gem5ExtensionsEnabled)) 98913014Sciro.santilli@arm.com gem5ExtensionsEnabled = false; 99013014Sciro.santilli@arm.com 99113014Sciro.santilli@arm.com for (uint32_t i=0; i < CPU_MAX; ++i) { 99213014Sciro.santilli@arm.com ScopedCheckpointSection sec(cp, csprintf("bankedRegs%i", i)); 99313014Sciro.santilli@arm.com if (cp.sectionExists(Serializable::currentSection())) { 99413014Sciro.santilli@arm.com getBankedRegs(i).unserialize(cp); 99513014Sciro.santilli@arm.com } 99613014Sciro.santilli@arm.com } 99713014Sciro.santilli@arm.com} 99813014Sciro.santilli@arm.com 99913014Sciro.santilli@arm.comvoid 100013014Sciro.santilli@arm.comGicV2::BankedRegs::unserialize(CheckpointIn &cp) 100113014Sciro.santilli@arm.com{ 100213014Sciro.santilli@arm.com UNSERIALIZE_SCALAR(intEnabled); 100313014Sciro.santilli@arm.com UNSERIALIZE_SCALAR(pendingInt); 100413014Sciro.santilli@arm.com UNSERIALIZE_SCALAR(activeInt); 100513014Sciro.santilli@arm.com UNSERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX); 100613014Sciro.santilli@arm.com} 100713014Sciro.santilli@arm.com 100813014Sciro.santilli@arm.comGicV2 * 100913014Sciro.santilli@arm.comGicV2Params::create() 101013014Sciro.santilli@arm.com{ 101113014Sciro.santilli@arm.com return new GicV2(this); 101213014Sciro.santilli@arm.com} 1013