gic_v2.hh revision 13503
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 */ 4213014Sciro.santilli@arm.com 4313014Sciro.santilli@arm.com 4413014Sciro.santilli@arm.com/** @file 4513014Sciro.santilli@arm.com * Implementation of a GICv2 4613014Sciro.santilli@arm.com */ 4713014Sciro.santilli@arm.com 4813014Sciro.santilli@arm.com#ifndef __DEV_ARM_GICV2_H__ 4913014Sciro.santilli@arm.com#define __DEV_ARM_GICV2_H__ 5013014Sciro.santilli@arm.com 5113014Sciro.santilli@arm.com#include <vector> 5213014Sciro.santilli@arm.com 5313014Sciro.santilli@arm.com#include "base/addr_range.hh" 5413014Sciro.santilli@arm.com#include "base/bitunion.hh" 5513014Sciro.santilli@arm.com#include "cpu/intr_control.hh" 5613014Sciro.santilli@arm.com#include "dev/arm/base_gic.hh" 5713014Sciro.santilli@arm.com#include "dev/io_device.hh" 5813014Sciro.santilli@arm.com#include "dev/platform.hh" 5913014Sciro.santilli@arm.com#include "params/GicV2.hh" 6013014Sciro.santilli@arm.com 6113014Sciro.santilli@arm.comclass GicV2 : public BaseGic, public BaseGicRegisters 6213014Sciro.santilli@arm.com{ 6313014Sciro.santilli@arm.com protected: 6413014Sciro.santilli@arm.com // distributor memory addresses 6513014Sciro.santilli@arm.com enum { 6613014Sciro.santilli@arm.com GICD_CTLR = 0x000, // control register 6713014Sciro.santilli@arm.com GICD_TYPER = 0x004, // controller type 6813014Sciro.santilli@arm.com GICD_IIDR = 0x008, // implementer id 6913014Sciro.santilli@arm.com GICD_SGIR = 0xf00, // software generated interrupt 7013014Sciro.santilli@arm.com GICD_PIDR0 = 0xfe0, // distributor peripheral ID0 7113014Sciro.santilli@arm.com GICD_PIDR1 = 0xfe4, // distributor peripheral ID1 7213014Sciro.santilli@arm.com GICD_PIDR2 = 0xfe8, // distributor peripheral ID2 7313014Sciro.santilli@arm.com GICD_PIDR3 = 0xfec, // distributor peripheral ID3 7413014Sciro.santilli@arm.com 7513014Sciro.santilli@arm.com DIST_SIZE = 0x1000, 7613014Sciro.santilli@arm.com }; 7713014Sciro.santilli@arm.com 7813014Sciro.santilli@arm.com /** 7913014Sciro.santilli@arm.com * As defined in: 8013014Sciro.santilli@arm.com * "ARM Generic Interrupt Controller Architecture" version 2.0 8113014Sciro.santilli@arm.com * "CoreLink GIC-400 Generic Interrupt Controller" revision r0p1 8213014Sciro.santilli@arm.com */ 8313014Sciro.santilli@arm.com static constexpr uint32_t GICD_400_PIDR_VALUE = 0x002bb490; 8413014Sciro.santilli@arm.com static constexpr uint32_t GICD_400_IIDR_VALUE = 0x200143B; 8513014Sciro.santilli@arm.com static constexpr uint32_t GICC_400_IIDR_VALUE = 0x202143B; 8613014Sciro.santilli@arm.com 8713014Sciro.santilli@arm.com static const AddrRange GICD_IGROUPR; // interrupt group (unimplemented) 8813014Sciro.santilli@arm.com static const AddrRange GICD_ISENABLER; // interrupt set enable 8913014Sciro.santilli@arm.com static const AddrRange GICD_ICENABLER; // interrupt clear enable 9013014Sciro.santilli@arm.com static const AddrRange GICD_ISPENDR; // set pending interrupt 9113014Sciro.santilli@arm.com static const AddrRange GICD_ICPENDR; // clear pending interrupt 9213014Sciro.santilli@arm.com static const AddrRange GICD_ISACTIVER; // active bit registers 9313014Sciro.santilli@arm.com static const AddrRange GICD_ICACTIVER; // clear bit registers 9413014Sciro.santilli@arm.com static const AddrRange GICD_IPRIORITYR; // interrupt priority registers 9513014Sciro.santilli@arm.com static const AddrRange GICD_ITARGETSR; // processor target registers 9613014Sciro.santilli@arm.com static const AddrRange GICD_ICFGR; // interrupt config registers 9713014Sciro.santilli@arm.com 9813014Sciro.santilli@arm.com // cpu memory addresses 9913014Sciro.santilli@arm.com enum { 10013014Sciro.santilli@arm.com GICC_CTLR = 0x00, // CPU control register 10113014Sciro.santilli@arm.com GICC_PMR = 0x04, // Interrupt priority mask 10213014Sciro.santilli@arm.com GICC_BPR = 0x08, // binary point register 10313014Sciro.santilli@arm.com GICC_IAR = 0x0C, // interrupt ack register 10413014Sciro.santilli@arm.com GICC_EOIR = 0x10, // end of interrupt 10513014Sciro.santilli@arm.com GICC_RPR = 0x14, // running priority 10613014Sciro.santilli@arm.com GICC_HPPIR = 0x18, // highest pending interrupt 10713014Sciro.santilli@arm.com GICC_ABPR = 0x1c, // aliased binary point 10813014Sciro.santilli@arm.com GICC_APR0 = 0xd0, // active priority register 0 10913014Sciro.santilli@arm.com GICC_APR1 = 0xd4, // active priority register 1 11013014Sciro.santilli@arm.com GICC_APR2 = 0xd8, // active priority register 2 11113014Sciro.santilli@arm.com GICC_APR3 = 0xdc, // active priority register 3 11213014Sciro.santilli@arm.com GICC_IIDR = 0xfc, // cpu interface id register 11313503Sanouk.vanlaer@arm.com GICC_DIR = 0x1000, // deactive interrupt register 11413014Sciro.santilli@arm.com }; 11513014Sciro.santilli@arm.com 11613014Sciro.santilli@arm.com static const int SGI_MAX = 16; // Number of Software Gen Interrupts 11713014Sciro.santilli@arm.com static const int PPI_MAX = 16; // Number of Private Peripheral Interrupts 11813014Sciro.santilli@arm.com 11913014Sciro.santilli@arm.com /** Mask off SGI's when setting/clearing pending bits */ 12013014Sciro.santilli@arm.com static const int SGI_MASK = 0xFFFF0000; 12113014Sciro.santilli@arm.com 12213014Sciro.santilli@arm.com /** Mask for bits that config N:N mode in GICD_ICFGR's */ 12313014Sciro.santilli@arm.com static const int NN_CONFIG_MASK = 0x55555555; 12413014Sciro.santilli@arm.com 12513014Sciro.santilli@arm.com static const int CPU_MAX = 256; // Max number of supported CPU interfaces 12613014Sciro.santilli@arm.com static const int SPURIOUS_INT = 1023; 12713014Sciro.santilli@arm.com static const int INT_BITS_MAX = 32; 12813014Sciro.santilli@arm.com static const int INT_LINES_MAX = 1020; 12913014Sciro.santilli@arm.com static const int GLOBAL_INT_LINES = INT_LINES_MAX - SGI_MAX - PPI_MAX; 13013014Sciro.santilli@arm.com 13113014Sciro.santilli@arm.com /** minimum value for Binary Point Register ("IMPLEMENTATION DEFINED"); 13213014Sciro.santilli@arm.com chosen for consistency with Linux's in-kernel KVM GIC model */ 13313014Sciro.santilli@arm.com static const int GICC_BPR_MINIMUM = 2; 13413014Sciro.santilli@arm.com 13513014Sciro.santilli@arm.com BitUnion32(SWI) 13613014Sciro.santilli@arm.com Bitfield<3,0> sgi_id; 13713014Sciro.santilli@arm.com Bitfield<23,16> cpu_list; 13813014Sciro.santilli@arm.com Bitfield<25,24> list_type; 13913014Sciro.santilli@arm.com EndBitUnion(SWI) 14013014Sciro.santilli@arm.com 14113014Sciro.santilli@arm.com BitUnion32(IAR) 14213014Sciro.santilli@arm.com Bitfield<9,0> ack_id; 14313014Sciro.santilli@arm.com Bitfield<12,10> cpu_id; 14413014Sciro.santilli@arm.com EndBitUnion(IAR) 14513014Sciro.santilli@arm.com 14613109Sgiacomo.travaglini@arm.com BitUnion32(CTLR) 14713109Sgiacomo.travaglini@arm.com Bitfield<3> fiqEn; 14813109Sgiacomo.travaglini@arm.com Bitfield<1> enableGrp1; 14913109Sgiacomo.travaglini@arm.com Bitfield<0> enableGrp0; 15013109Sgiacomo.travaglini@arm.com EndBitUnion(CTLR) 15113109Sgiacomo.travaglini@arm.com 15213014Sciro.santilli@arm.com protected: /* Params */ 15313014Sciro.santilli@arm.com /** Address range for the distributor interface */ 15413014Sciro.santilli@arm.com const AddrRange distRange; 15513014Sciro.santilli@arm.com 15613014Sciro.santilli@arm.com /** Address range for the CPU interfaces */ 15713014Sciro.santilli@arm.com const AddrRange cpuRange; 15813014Sciro.santilli@arm.com 15913014Sciro.santilli@arm.com /** All address ranges used by this GIC */ 16013014Sciro.santilli@arm.com const AddrRangeList addrRanges; 16113014Sciro.santilli@arm.com 16213014Sciro.santilli@arm.com /** Latency for a distributor operation */ 16313014Sciro.santilli@arm.com const Tick distPioDelay; 16413014Sciro.santilli@arm.com 16513014Sciro.santilli@arm.com /** Latency for a cpu operation */ 16613014Sciro.santilli@arm.com const Tick cpuPioDelay; 16713014Sciro.santilli@arm.com 16813014Sciro.santilli@arm.com /** Latency for a interrupt to get to CPU */ 16913014Sciro.santilli@arm.com const Tick intLatency; 17013014Sciro.santilli@arm.com 17113014Sciro.santilli@arm.com protected: 17213014Sciro.santilli@arm.com /** Gic enabled */ 17313014Sciro.santilli@arm.com bool enabled; 17413014Sciro.santilli@arm.com 17513014Sciro.santilli@arm.com /** Are gem5 extensions available? */ 17613014Sciro.santilli@arm.com const bool haveGem5Extensions; 17713014Sciro.santilli@arm.com 17813014Sciro.santilli@arm.com /** gem5 many-core extension enabled by driver */ 17913014Sciro.santilli@arm.com bool gem5ExtensionsEnabled; 18013014Sciro.santilli@arm.com 18113014Sciro.santilli@arm.com /** Number of itLines enabled */ 18213014Sciro.santilli@arm.com uint32_t itLines; 18313014Sciro.santilli@arm.com 18413014Sciro.santilli@arm.com /** Registers "banked for each connected processor" per ARM IHI0048B */ 18513014Sciro.santilli@arm.com struct BankedRegs : public Serializable { 18613014Sciro.santilli@arm.com /** GICD_I{S,C}ENABLER0 18713014Sciro.santilli@arm.com * interrupt enable bits for first 32 interrupts, 1b per interrupt */ 18813014Sciro.santilli@arm.com uint32_t intEnabled; 18913014Sciro.santilli@arm.com 19013014Sciro.santilli@arm.com /** GICD_I{S,C}PENDR0 19113014Sciro.santilli@arm.com * interrupt pending bits for first 32 interrupts, 1b per interrupt */ 19213014Sciro.santilli@arm.com uint32_t pendingInt; 19313014Sciro.santilli@arm.com 19413014Sciro.santilli@arm.com /** GICD_I{S,C}ACTIVER0 19513014Sciro.santilli@arm.com * interrupt active bits for first 32 interrupts, 1b per interrupt */ 19613014Sciro.santilli@arm.com uint32_t activeInt; 19713014Sciro.santilli@arm.com 19813110Sgiacomo.travaglini@arm.com /** GICD_IGROUPR0 19913110Sgiacomo.travaglini@arm.com * interrupt group bits for first 32 interrupts, 1b per interrupt */ 20013110Sgiacomo.travaglini@arm.com uint32_t intGroup; 20113110Sgiacomo.travaglini@arm.com 20213014Sciro.santilli@arm.com /** GICD_IPRIORITYR{0..7} 20313014Sciro.santilli@arm.com * interrupt priority for SGIs and PPIs */ 20413014Sciro.santilli@arm.com uint8_t intPriority[SGI_MAX + PPI_MAX]; 20513014Sciro.santilli@arm.com 20613014Sciro.santilli@arm.com void serialize(CheckpointOut &cp) const override; 20713014Sciro.santilli@arm.com void unserialize(CheckpointIn &cp) override; 20813014Sciro.santilli@arm.com 20913014Sciro.santilli@arm.com BankedRegs() : 21013110Sgiacomo.travaglini@arm.com intEnabled(0), pendingInt(0), activeInt(0), 21113110Sgiacomo.travaglini@arm.com intGroup(0), intPriority {0} 21213014Sciro.santilli@arm.com {} 21313014Sciro.santilli@arm.com }; 21413014Sciro.santilli@arm.com std::vector<BankedRegs*> bankedRegs; 21513014Sciro.santilli@arm.com 21613014Sciro.santilli@arm.com BankedRegs& getBankedRegs(ContextID); 21713014Sciro.santilli@arm.com 21813014Sciro.santilli@arm.com /** GICD_I{S,C}ENABLER{1..31} 21913014Sciro.santilli@arm.com * interrupt enable bits for global interrupts 22013014Sciro.santilli@arm.com * 1b per interrupt, 32 bits per word, 31 words */ 22113014Sciro.santilli@arm.com uint32_t intEnabled[INT_BITS_MAX-1]; 22213014Sciro.santilli@arm.com 22313014Sciro.santilli@arm.com uint32_t& getIntEnabled(ContextID ctx, uint32_t ix) { 22413014Sciro.santilli@arm.com if (ix == 0) { 22513014Sciro.santilli@arm.com return getBankedRegs(ctx).intEnabled; 22613014Sciro.santilli@arm.com } else { 22713014Sciro.santilli@arm.com return intEnabled[ix - 1]; 22813014Sciro.santilli@arm.com } 22913014Sciro.santilli@arm.com } 23013014Sciro.santilli@arm.com 23113014Sciro.santilli@arm.com /** GICD_I{S,C}PENDR{1..31} 23213014Sciro.santilli@arm.com * interrupt pending bits for global interrupts 23313014Sciro.santilli@arm.com * 1b per interrupt, 32 bits per word, 31 words */ 23413014Sciro.santilli@arm.com uint32_t pendingInt[INT_BITS_MAX-1]; 23513014Sciro.santilli@arm.com 23613014Sciro.santilli@arm.com uint32_t& getPendingInt(ContextID ctx, uint32_t ix) { 23713014Sciro.santilli@arm.com assert(ix < INT_BITS_MAX); 23813014Sciro.santilli@arm.com if (ix == 0) { 23913014Sciro.santilli@arm.com return getBankedRegs(ctx).pendingInt; 24013014Sciro.santilli@arm.com } else { 24113014Sciro.santilli@arm.com return pendingInt[ix - 1]; 24213014Sciro.santilli@arm.com } 24313014Sciro.santilli@arm.com } 24413014Sciro.santilli@arm.com 24513014Sciro.santilli@arm.com /** GICD_I{S,C}ACTIVER{1..31} 24613014Sciro.santilli@arm.com * interrupt active bits for global interrupts 24713014Sciro.santilli@arm.com * 1b per interrupt, 32 bits per word, 31 words */ 24813014Sciro.santilli@arm.com uint32_t activeInt[INT_BITS_MAX-1]; 24913014Sciro.santilli@arm.com 25013014Sciro.santilli@arm.com uint32_t& getActiveInt(ContextID ctx, uint32_t ix) { 25113014Sciro.santilli@arm.com assert(ix < INT_BITS_MAX); 25213014Sciro.santilli@arm.com if (ix == 0) { 25313014Sciro.santilli@arm.com return getBankedRegs(ctx).activeInt; 25413014Sciro.santilli@arm.com } else { 25513014Sciro.santilli@arm.com return activeInt[ix - 1]; 25613014Sciro.santilli@arm.com } 25713014Sciro.santilli@arm.com } 25813014Sciro.santilli@arm.com 25913110Sgiacomo.travaglini@arm.com /** GICD_IGROUPR{1..31} 26013110Sgiacomo.travaglini@arm.com * interrupt group bits for global interrupts 26113110Sgiacomo.travaglini@arm.com * 1b per interrupt, 32 bits per word, 31 words */ 26213110Sgiacomo.travaglini@arm.com uint32_t intGroup[INT_BITS_MAX-1]; 26313110Sgiacomo.travaglini@arm.com 26413110Sgiacomo.travaglini@arm.com uint32_t& getIntGroup(ContextID ctx, uint32_t ix) { 26513110Sgiacomo.travaglini@arm.com assert(ix < INT_BITS_MAX); 26613110Sgiacomo.travaglini@arm.com if (ix == 0) { 26713110Sgiacomo.travaglini@arm.com return getBankedRegs(ctx).intGroup; 26813110Sgiacomo.travaglini@arm.com } else { 26913110Sgiacomo.travaglini@arm.com return intGroup[ix - 1]; 27013110Sgiacomo.travaglini@arm.com } 27113110Sgiacomo.travaglini@arm.com } 27213110Sgiacomo.travaglini@arm.com 27313014Sciro.santilli@arm.com /** read only running priority register, 1 per cpu*/ 27413014Sciro.santilli@arm.com uint32_t iccrpr[CPU_MAX]; 27513014Sciro.santilli@arm.com 27613014Sciro.santilli@arm.com /** GICD_IPRIORITYR{8..255} 27713014Sciro.santilli@arm.com * an 8 bit priority (lower is higher priority) for each 27813014Sciro.santilli@arm.com * of the global (not replicated per CPU) interrupts. 27913014Sciro.santilli@arm.com */ 28013014Sciro.santilli@arm.com uint8_t intPriority[GLOBAL_INT_LINES]; 28113014Sciro.santilli@arm.com 28213014Sciro.santilli@arm.com uint8_t& getIntPriority(ContextID ctx, uint32_t ix) { 28313014Sciro.santilli@arm.com assert(ix < INT_LINES_MAX); 28413014Sciro.santilli@arm.com if (ix < SGI_MAX + PPI_MAX) { 28513014Sciro.santilli@arm.com return getBankedRegs(ctx).intPriority[ix]; 28613014Sciro.santilli@arm.com } else { 28713014Sciro.santilli@arm.com return intPriority[ix - (SGI_MAX + PPI_MAX)]; 28813014Sciro.santilli@arm.com } 28913014Sciro.santilli@arm.com } 29013014Sciro.santilli@arm.com 29113108Sadrien.pesle@arm.com /** GICD_ICFGRn 29213108Sadrien.pesle@arm.com * get 2 bit config associated to an interrupt. 29313108Sadrien.pesle@arm.com */ 29413108Sadrien.pesle@arm.com uint8_t getIntConfig(ContextID ctx, uint32_t ix) { 29513108Sadrien.pesle@arm.com assert(ix < INT_LINES_MAX); 29613108Sadrien.pesle@arm.com const uint8_t cfg_low = intNumToBit(ix * 2); 29713108Sadrien.pesle@arm.com const uint8_t cfg_hi = cfg_low + 1; 29813108Sadrien.pesle@arm.com return bits(intConfig[intNumToWord(ix * 2)], cfg_hi, cfg_low); 29913108Sadrien.pesle@arm.com } 30013108Sadrien.pesle@arm.com 30113014Sciro.santilli@arm.com /** GICD_ITARGETSR{8..255} 30213014Sciro.santilli@arm.com * an 8 bit cpu target id for each global interrupt. 30313014Sciro.santilli@arm.com */ 30413014Sciro.santilli@arm.com uint8_t cpuTarget[GLOBAL_INT_LINES]; 30513014Sciro.santilli@arm.com 30613014Sciro.santilli@arm.com uint8_t getCpuTarget(ContextID ctx, uint32_t ix) { 30713014Sciro.santilli@arm.com assert(ctx < sys->numRunningContexts()); 30813014Sciro.santilli@arm.com assert(ix < INT_LINES_MAX); 30913014Sciro.santilli@arm.com if (ix < SGI_MAX + PPI_MAX) { 31013014Sciro.santilli@arm.com // "GICD_ITARGETSR0 to GICD_ITARGETSR7 are read-only, and each 31113014Sciro.santilli@arm.com // field returns a value that corresponds only to the processor 31213014Sciro.santilli@arm.com // reading the register." 31313014Sciro.santilli@arm.com uint32_t ctx_mask; 31413014Sciro.santilli@arm.com if (gem5ExtensionsEnabled) { 31513014Sciro.santilli@arm.com ctx_mask = ctx; 31613014Sciro.santilli@arm.com } else { 31713014Sciro.santilli@arm.com // convert the CPU id number into a bit mask 31813014Sciro.santilli@arm.com ctx_mask = power(2, ctx); 31913014Sciro.santilli@arm.com } 32013014Sciro.santilli@arm.com return ctx_mask; 32113014Sciro.santilli@arm.com } else { 32213014Sciro.santilli@arm.com return cpuTarget[ix - 32]; 32313014Sciro.santilli@arm.com } 32413014Sciro.santilli@arm.com } 32513014Sciro.santilli@arm.com 32613014Sciro.santilli@arm.com /** 2 bit per interrupt signaling if it's level or edge sensitive 32713014Sciro.santilli@arm.com * and if it is 1:N or N:N */ 32813014Sciro.santilli@arm.com uint32_t intConfig[INT_BITS_MAX*2]; 32913014Sciro.santilli@arm.com 33013108Sadrien.pesle@arm.com bool isLevelSensitive(ContextID ctx, uint32_t ix) { 33113108Sadrien.pesle@arm.com if (ix == SPURIOUS_INT) { 33213108Sadrien.pesle@arm.com return false; 33313108Sadrien.pesle@arm.com } else { 33413108Sadrien.pesle@arm.com return bits(getIntConfig(ctx, ix), 1) == 0; 33513108Sadrien.pesle@arm.com } 33613108Sadrien.pesle@arm.com } 33713108Sadrien.pesle@arm.com 33813112Sgiacomo.travaglini@arm.com bool isGroup0(ContextID ctx, uint32_t int_num) { 33913112Sgiacomo.travaglini@arm.com const uint32_t group_reg = getIntGroup(ctx, intNumToWord(int_num)); 34013336Sadrien.pesle@arm.com return !bits(group_reg, intNumToBit(int_num)); 34113112Sgiacomo.travaglini@arm.com } 34213112Sgiacomo.travaglini@arm.com 34313112Sgiacomo.travaglini@arm.com /** 34413112Sgiacomo.travaglini@arm.com * This method checks if an interrupt ID must be signaled or has been 34513112Sgiacomo.travaglini@arm.com * signaled as a FIQ to the cpu. It does that by reading: 34613112Sgiacomo.travaglini@arm.com * 34713112Sgiacomo.travaglini@arm.com * 1) GICD_IGROUPR: controls if the interrupt is part of group0 or 34813112Sgiacomo.travaglini@arm.com * group1. Only group0 interrupts can be signaled as FIQs. 34913112Sgiacomo.travaglini@arm.com * 35013112Sgiacomo.travaglini@arm.com * 2) GICC_CTLR.FIQEn: controls whether the CPU interface signals Group 0 35113112Sgiacomo.travaglini@arm.com * interrupts to a target processor using the FIQ or the IRQ signal 35213112Sgiacomo.travaglini@arm.com */ 35313112Sgiacomo.travaglini@arm.com bool isFiq(ContextID ctx, uint32_t int_num) { 35413112Sgiacomo.travaglini@arm.com const bool is_group0 = isGroup0(ctx, int_num); 35513112Sgiacomo.travaglini@arm.com const bool use_fiq = cpuControl[ctx].fiqEn; 35613112Sgiacomo.travaglini@arm.com 35713112Sgiacomo.travaglini@arm.com if (is_group0 && use_fiq) { 35813112Sgiacomo.travaglini@arm.com return true; 35913112Sgiacomo.travaglini@arm.com } else { 36013112Sgiacomo.travaglini@arm.com return false; 36113112Sgiacomo.travaglini@arm.com } 36213112Sgiacomo.travaglini@arm.com } 36313112Sgiacomo.travaglini@arm.com 36413112Sgiacomo.travaglini@arm.com /** CPU enabled: 36513112Sgiacomo.travaglini@arm.com * Checks if GICC_CTLR.EnableGrp0 or EnableGrp1 are set 36613112Sgiacomo.travaglini@arm.com */ 36713109Sgiacomo.travaglini@arm.com bool cpuEnabled(ContextID ctx) const { 36813109Sgiacomo.travaglini@arm.com return cpuControl[ctx].enableGrp0 || 36913109Sgiacomo.travaglini@arm.com cpuControl[ctx].enableGrp1; 37013109Sgiacomo.travaglini@arm.com } 37113109Sgiacomo.travaglini@arm.com 37213109Sgiacomo.travaglini@arm.com /** GICC_CTLR: 37313109Sgiacomo.travaglini@arm.com * CPU interface control register 37413109Sgiacomo.travaglini@arm.com */ 37513109Sgiacomo.travaglini@arm.com CTLR cpuControl[CPU_MAX]; 37613014Sciro.santilli@arm.com 37713014Sciro.santilli@arm.com /** CPU priority */ 37813014Sciro.santilli@arm.com uint8_t cpuPriority[CPU_MAX]; 37913014Sciro.santilli@arm.com uint8_t getCpuPriority(unsigned cpu); // BPR-adjusted priority value 38013014Sciro.santilli@arm.com 38113014Sciro.santilli@arm.com /** Binary point registers */ 38213014Sciro.santilli@arm.com uint8_t cpuBpr[CPU_MAX]; 38313014Sciro.santilli@arm.com 38413014Sciro.santilli@arm.com /** highest interrupt that is interrupting CPU */ 38513014Sciro.santilli@arm.com uint32_t cpuHighestInt[CPU_MAX]; 38613014Sciro.santilli@arm.com 38713014Sciro.santilli@arm.com /** One bit per cpu per software interrupt that is pending for each 38813014Sciro.santilli@arm.com * possible sgi source. Indexed by SGI number. Each byte in generating cpu 38913014Sciro.santilli@arm.com * id and bits in position is destination id. e.g. 0x4 = CPU 0 generated 39013014Sciro.santilli@arm.com * interrupt for CPU 2. */ 39113014Sciro.santilli@arm.com uint64_t cpuSgiPending[SGI_MAX]; 39213014Sciro.santilli@arm.com uint64_t cpuSgiActive[SGI_MAX]; 39313014Sciro.santilli@arm.com 39413014Sciro.santilli@arm.com /** SGI pending arrays for gem5 GIC extension mode, which instead keeps 39513014Sciro.santilli@arm.com * 16 SGI pending bits for each of the (large number of) CPUs. 39613014Sciro.santilli@arm.com */ 39713014Sciro.santilli@arm.com uint32_t cpuSgiPendingExt[CPU_MAX]; 39813014Sciro.santilli@arm.com uint32_t cpuSgiActiveExt[CPU_MAX]; 39913014Sciro.santilli@arm.com 40013014Sciro.santilli@arm.com /** One bit per private peripheral interrupt. Only upper 16 bits 40113014Sciro.santilli@arm.com * will be used since PPI interrupts are numberred from 16 to 32 */ 40213014Sciro.santilli@arm.com uint32_t cpuPpiPending[CPU_MAX]; 40313014Sciro.santilli@arm.com uint32_t cpuPpiActive[CPU_MAX]; 40413014Sciro.santilli@arm.com 40513014Sciro.santilli@arm.com /** software generated interrupt 40613014Sciro.santilli@arm.com * @param data data to decode that indicates which cpus to interrupt 40713014Sciro.santilli@arm.com */ 40813014Sciro.santilli@arm.com void softInt(ContextID ctx, SWI swi); 40913014Sciro.santilli@arm.com 41013014Sciro.santilli@arm.com /** See if some processor interrupt flags need to be enabled/disabled 41113014Sciro.santilli@arm.com * @param hint which set of interrupts needs to be checked 41213014Sciro.santilli@arm.com */ 41313014Sciro.santilli@arm.com virtual void updateIntState(int hint); 41413014Sciro.santilli@arm.com 41513014Sciro.santilli@arm.com /** Update the register that records priority of the highest priority 41613014Sciro.santilli@arm.com * active interrupt*/ 41713014Sciro.santilli@arm.com void updateRunPri(); 41813014Sciro.santilli@arm.com 41913014Sciro.santilli@arm.com /** generate a bit mask to check cpuSgi for an interrupt. */ 42013014Sciro.santilli@arm.com uint64_t genSwiMask(int cpu); 42113014Sciro.santilli@arm.com 42213014Sciro.santilli@arm.com int intNumToWord(int num) const { return num >> 5; } 42313014Sciro.santilli@arm.com int intNumToBit(int num) const { return num % 32; } 42413014Sciro.santilli@arm.com 42513112Sgiacomo.travaglini@arm.com /** Clears a cpu IRQ or FIQ signal */ 42613112Sgiacomo.travaglini@arm.com void clearInt(ContextID ctx, uint32_t int_num); 42713112Sgiacomo.travaglini@arm.com 42813014Sciro.santilli@arm.com /** 42913014Sciro.santilli@arm.com * Post an interrupt to a CPU with a delay 43013014Sciro.santilli@arm.com */ 43113014Sciro.santilli@arm.com void postInt(uint32_t cpu, Tick when); 43213111Sgiacomo.travaglini@arm.com void postFiq(uint32_t cpu, Tick when); 43313014Sciro.santilli@arm.com 43413014Sciro.santilli@arm.com /** 43513014Sciro.santilli@arm.com * Deliver a delayed interrupt to the target CPU 43613014Sciro.santilli@arm.com */ 43713014Sciro.santilli@arm.com void postDelayedInt(uint32_t cpu); 43813111Sgiacomo.travaglini@arm.com void postDelayedFiq(uint32_t cpu); 43913014Sciro.santilli@arm.com 44013014Sciro.santilli@arm.com EventFunctionWrapper *postIntEvent[CPU_MAX]; 44113111Sgiacomo.travaglini@arm.com EventFunctionWrapper *postFiqEvent[CPU_MAX]; 44213014Sciro.santilli@arm.com int pendingDelayedInterrupts; 44313014Sciro.santilli@arm.com 44413014Sciro.santilli@arm.com public: 44513014Sciro.santilli@arm.com typedef GicV2Params Params; 44613014Sciro.santilli@arm.com const Params * 44713014Sciro.santilli@arm.com params() const 44813014Sciro.santilli@arm.com { 44913014Sciro.santilli@arm.com return dynamic_cast<const Params *>(_params); 45013014Sciro.santilli@arm.com } 45113014Sciro.santilli@arm.com GicV2(const Params *p); 45213014Sciro.santilli@arm.com ~GicV2(); 45313014Sciro.santilli@arm.com 45413014Sciro.santilli@arm.com DrainState drain() override; 45513014Sciro.santilli@arm.com void drainResume() override; 45613014Sciro.santilli@arm.com 45713014Sciro.santilli@arm.com void serialize(CheckpointOut &cp) const override; 45813014Sciro.santilli@arm.com void unserialize(CheckpointIn &cp) override; 45913014Sciro.santilli@arm.com 46013014Sciro.santilli@arm.com public: /* PioDevice */ 46113014Sciro.santilli@arm.com AddrRangeList getAddrRanges() const override { return addrRanges; } 46213014Sciro.santilli@arm.com 46313014Sciro.santilli@arm.com /** A PIO read to the device, immediately split up into 46413014Sciro.santilli@arm.com * readDistributor() or readCpu() 46513014Sciro.santilli@arm.com */ 46613014Sciro.santilli@arm.com Tick read(PacketPtr pkt) override; 46713014Sciro.santilli@arm.com 46813014Sciro.santilli@arm.com /** A PIO read to the device, immediately split up into 46913014Sciro.santilli@arm.com * writeDistributor() or writeCpu() 47013014Sciro.santilli@arm.com */ 47113014Sciro.santilli@arm.com Tick write(PacketPtr pkt) override; 47213014Sciro.santilli@arm.com 47313014Sciro.santilli@arm.com public: /* BaseGic */ 47413014Sciro.santilli@arm.com void sendInt(uint32_t number) override; 47513014Sciro.santilli@arm.com void clearInt(uint32_t number) override; 47613014Sciro.santilli@arm.com 47713014Sciro.santilli@arm.com void sendPPInt(uint32_t num, uint32_t cpu) override; 47813014Sciro.santilli@arm.com void clearPPInt(uint32_t num, uint32_t cpu) override; 47913014Sciro.santilli@arm.com 48013014Sciro.santilli@arm.com protected: 48113014Sciro.santilli@arm.com /** Handle a read to the distributor portion of the GIC 48213014Sciro.santilli@arm.com * @param pkt packet to respond to 48313014Sciro.santilli@arm.com */ 48413014Sciro.santilli@arm.com Tick readDistributor(PacketPtr pkt); 48513014Sciro.santilli@arm.com uint32_t readDistributor(ContextID ctx, Addr daddr, 48613014Sciro.santilli@arm.com size_t resp_sz); 48713014Sciro.santilli@arm.com uint32_t readDistributor(ContextID ctx, Addr daddr) override { 48813014Sciro.santilli@arm.com return readDistributor(ctx, daddr, 4); 48913014Sciro.santilli@arm.com } 49013014Sciro.santilli@arm.com 49113014Sciro.santilli@arm.com /** Handle a read to the cpu portion of the GIC 49213014Sciro.santilli@arm.com * @param pkt packet to respond to 49313014Sciro.santilli@arm.com */ 49413014Sciro.santilli@arm.com Tick readCpu(PacketPtr pkt); 49513014Sciro.santilli@arm.com uint32_t readCpu(ContextID ctx, Addr daddr) override; 49613014Sciro.santilli@arm.com 49713014Sciro.santilli@arm.com /** Handle a write to the distributor portion of the GIC 49813014Sciro.santilli@arm.com * @param pkt packet to respond to 49913014Sciro.santilli@arm.com */ 50013014Sciro.santilli@arm.com Tick writeDistributor(PacketPtr pkt); 50113014Sciro.santilli@arm.com void writeDistributor(ContextID ctx, Addr daddr, 50213014Sciro.santilli@arm.com uint32_t data, size_t data_sz); 50313014Sciro.santilli@arm.com void writeDistributor(ContextID ctx, Addr daddr, 50413014Sciro.santilli@arm.com uint32_t data) override { 50513014Sciro.santilli@arm.com return writeDistributor(ctx, daddr, data, 4); 50613014Sciro.santilli@arm.com } 50713014Sciro.santilli@arm.com 50813014Sciro.santilli@arm.com /** Handle a write to the cpu portion of the GIC 50913014Sciro.santilli@arm.com * @param pkt packet to respond to 51013014Sciro.santilli@arm.com */ 51113014Sciro.santilli@arm.com Tick writeCpu(PacketPtr pkt); 51213014Sciro.santilli@arm.com void writeCpu(ContextID ctx, Addr daddr, uint32_t data) override; 51313014Sciro.santilli@arm.com}; 51413014Sciro.santilli@arm.com 51513014Sciro.santilli@arm.com#endif //__DEV_ARM_GIC_H__ 516