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 7813505Sgiacomo.travaglini@arm.com const uint32_t gicdPIDR; 7913505Sgiacomo.travaglini@arm.com const uint32_t gicdIIDR; 8013505Sgiacomo.travaglini@arm.com const uint32_t giccIIDR; 8113014Sciro.santilli@arm.com 8213014Sciro.santilli@arm.com static const AddrRange GICD_IGROUPR; // interrupt group (unimplemented) 8313014Sciro.santilli@arm.com static const AddrRange GICD_ISENABLER; // interrupt set enable 8413014Sciro.santilli@arm.com static const AddrRange GICD_ICENABLER; // interrupt clear enable 8513014Sciro.santilli@arm.com static const AddrRange GICD_ISPENDR; // set pending interrupt 8613014Sciro.santilli@arm.com static const AddrRange GICD_ICPENDR; // clear pending interrupt 8713014Sciro.santilli@arm.com static const AddrRange GICD_ISACTIVER; // active bit registers 8813014Sciro.santilli@arm.com static const AddrRange GICD_ICACTIVER; // clear bit registers 8913014Sciro.santilli@arm.com static const AddrRange GICD_IPRIORITYR; // interrupt priority registers 9013014Sciro.santilli@arm.com static const AddrRange GICD_ITARGETSR; // processor target registers 9113014Sciro.santilli@arm.com static const AddrRange GICD_ICFGR; // interrupt config registers 9213014Sciro.santilli@arm.com 9313014Sciro.santilli@arm.com // cpu memory addresses 9413014Sciro.santilli@arm.com enum { 9513014Sciro.santilli@arm.com GICC_CTLR = 0x00, // CPU control register 9613014Sciro.santilli@arm.com GICC_PMR = 0x04, // Interrupt priority mask 9713014Sciro.santilli@arm.com GICC_BPR = 0x08, // binary point register 9813014Sciro.santilli@arm.com GICC_IAR = 0x0C, // interrupt ack register 9913014Sciro.santilli@arm.com GICC_EOIR = 0x10, // end of interrupt 10013014Sciro.santilli@arm.com GICC_RPR = 0x14, // running priority 10113014Sciro.santilli@arm.com GICC_HPPIR = 0x18, // highest pending interrupt 10213014Sciro.santilli@arm.com GICC_ABPR = 0x1c, // aliased binary point 10313014Sciro.santilli@arm.com GICC_APR0 = 0xd0, // active priority register 0 10413014Sciro.santilli@arm.com GICC_APR1 = 0xd4, // active priority register 1 10513014Sciro.santilli@arm.com GICC_APR2 = 0xd8, // active priority register 2 10613014Sciro.santilli@arm.com GICC_APR3 = 0xdc, // active priority register 3 10713014Sciro.santilli@arm.com GICC_IIDR = 0xfc, // cpu interface id register 10813503Sanouk.vanlaer@arm.com GICC_DIR = 0x1000, // deactive interrupt register 10913014Sciro.santilli@arm.com }; 11013014Sciro.santilli@arm.com 11113014Sciro.santilli@arm.com static const int SGI_MAX = 16; // Number of Software Gen Interrupts 11213014Sciro.santilli@arm.com static const int PPI_MAX = 16; // Number of Private Peripheral Interrupts 11313014Sciro.santilli@arm.com 11413014Sciro.santilli@arm.com /** Mask off SGI's when setting/clearing pending bits */ 11513014Sciro.santilli@arm.com static const int SGI_MASK = 0xFFFF0000; 11613014Sciro.santilli@arm.com 11713014Sciro.santilli@arm.com /** Mask for bits that config N:N mode in GICD_ICFGR's */ 11813014Sciro.santilli@arm.com static const int NN_CONFIG_MASK = 0x55555555; 11913014Sciro.santilli@arm.com 12013014Sciro.santilli@arm.com static const int CPU_MAX = 256; // Max number of supported CPU interfaces 12113014Sciro.santilli@arm.com static const int SPURIOUS_INT = 1023; 12213014Sciro.santilli@arm.com static const int INT_BITS_MAX = 32; 12313014Sciro.santilli@arm.com static const int INT_LINES_MAX = 1020; 12413014Sciro.santilli@arm.com static const int GLOBAL_INT_LINES = INT_LINES_MAX - SGI_MAX - PPI_MAX; 12513014Sciro.santilli@arm.com 12613014Sciro.santilli@arm.com /** minimum value for Binary Point Register ("IMPLEMENTATION DEFINED"); 12713014Sciro.santilli@arm.com chosen for consistency with Linux's in-kernel KVM GIC model */ 12813014Sciro.santilli@arm.com static const int GICC_BPR_MINIMUM = 2; 12913014Sciro.santilli@arm.com 13013014Sciro.santilli@arm.com BitUnion32(SWI) 13113014Sciro.santilli@arm.com Bitfield<3,0> sgi_id; 13213014Sciro.santilli@arm.com Bitfield<23,16> cpu_list; 13313014Sciro.santilli@arm.com Bitfield<25,24> list_type; 13413014Sciro.santilli@arm.com EndBitUnion(SWI) 13513014Sciro.santilli@arm.com 13613014Sciro.santilli@arm.com BitUnion32(IAR) 13713014Sciro.santilli@arm.com Bitfield<9,0> ack_id; 13813014Sciro.santilli@arm.com Bitfield<12,10> cpu_id; 13913014Sciro.santilli@arm.com EndBitUnion(IAR) 14013014Sciro.santilli@arm.com 14113109Sgiacomo.travaglini@arm.com BitUnion32(CTLR) 14213109Sgiacomo.travaglini@arm.com Bitfield<3> fiqEn; 14313109Sgiacomo.travaglini@arm.com Bitfield<1> enableGrp1; 14413109Sgiacomo.travaglini@arm.com Bitfield<0> enableGrp0; 14513109Sgiacomo.travaglini@arm.com EndBitUnion(CTLR) 14613109Sgiacomo.travaglini@arm.com 14713014Sciro.santilli@arm.com protected: /* Params */ 14813014Sciro.santilli@arm.com /** Address range for the distributor interface */ 14913014Sciro.santilli@arm.com const AddrRange distRange; 15013014Sciro.santilli@arm.com 15113014Sciro.santilli@arm.com /** Address range for the CPU interfaces */ 15213014Sciro.santilli@arm.com const AddrRange cpuRange; 15313014Sciro.santilli@arm.com 15413014Sciro.santilli@arm.com /** All address ranges used by this GIC */ 15513014Sciro.santilli@arm.com const AddrRangeList addrRanges; 15613014Sciro.santilli@arm.com 15713014Sciro.santilli@arm.com /** Latency for a distributor operation */ 15813014Sciro.santilli@arm.com const Tick distPioDelay; 15913014Sciro.santilli@arm.com 16013014Sciro.santilli@arm.com /** Latency for a cpu operation */ 16113014Sciro.santilli@arm.com const Tick cpuPioDelay; 16213014Sciro.santilli@arm.com 16313014Sciro.santilli@arm.com /** Latency for a interrupt to get to CPU */ 16413014Sciro.santilli@arm.com const Tick intLatency; 16513014Sciro.santilli@arm.com 16613014Sciro.santilli@arm.com protected: 16713014Sciro.santilli@arm.com /** Gic enabled */ 16813014Sciro.santilli@arm.com bool enabled; 16913014Sciro.santilli@arm.com 17013014Sciro.santilli@arm.com /** Are gem5 extensions available? */ 17113014Sciro.santilli@arm.com const bool haveGem5Extensions; 17213014Sciro.santilli@arm.com 17313014Sciro.santilli@arm.com /** gem5 many-core extension enabled by driver */ 17413014Sciro.santilli@arm.com bool gem5ExtensionsEnabled; 17513014Sciro.santilli@arm.com 17613014Sciro.santilli@arm.com /** Number of itLines enabled */ 17713014Sciro.santilli@arm.com uint32_t itLines; 17813014Sciro.santilli@arm.com 17913014Sciro.santilli@arm.com /** Registers "banked for each connected processor" per ARM IHI0048B */ 18013014Sciro.santilli@arm.com struct BankedRegs : public Serializable { 18113014Sciro.santilli@arm.com /** GICD_I{S,C}ENABLER0 18213014Sciro.santilli@arm.com * interrupt enable bits for first 32 interrupts, 1b per interrupt */ 18313014Sciro.santilli@arm.com uint32_t intEnabled; 18413014Sciro.santilli@arm.com 18513014Sciro.santilli@arm.com /** GICD_I{S,C}PENDR0 18613014Sciro.santilli@arm.com * interrupt pending bits for first 32 interrupts, 1b per interrupt */ 18713014Sciro.santilli@arm.com uint32_t pendingInt; 18813014Sciro.santilli@arm.com 18913014Sciro.santilli@arm.com /** GICD_I{S,C}ACTIVER0 19013014Sciro.santilli@arm.com * interrupt active bits for first 32 interrupts, 1b per interrupt */ 19113014Sciro.santilli@arm.com uint32_t activeInt; 19213014Sciro.santilli@arm.com 19313110Sgiacomo.travaglini@arm.com /** GICD_IGROUPR0 19413110Sgiacomo.travaglini@arm.com * interrupt group bits for first 32 interrupts, 1b per interrupt */ 19513110Sgiacomo.travaglini@arm.com uint32_t intGroup; 19613110Sgiacomo.travaglini@arm.com 19713014Sciro.santilli@arm.com /** GICD_IPRIORITYR{0..7} 19813014Sciro.santilli@arm.com * interrupt priority for SGIs and PPIs */ 19913014Sciro.santilli@arm.com uint8_t intPriority[SGI_MAX + PPI_MAX]; 20013014Sciro.santilli@arm.com 20113014Sciro.santilli@arm.com void serialize(CheckpointOut &cp) const override; 20213014Sciro.santilli@arm.com void unserialize(CheckpointIn &cp) override; 20313014Sciro.santilli@arm.com 20413014Sciro.santilli@arm.com BankedRegs() : 20513110Sgiacomo.travaglini@arm.com intEnabled(0), pendingInt(0), activeInt(0), 20613110Sgiacomo.travaglini@arm.com intGroup(0), intPriority {0} 20713014Sciro.santilli@arm.com {} 20813014Sciro.santilli@arm.com }; 20913014Sciro.santilli@arm.com std::vector<BankedRegs*> bankedRegs; 21013014Sciro.santilli@arm.com 21113014Sciro.santilli@arm.com BankedRegs& getBankedRegs(ContextID); 21213014Sciro.santilli@arm.com 21313014Sciro.santilli@arm.com /** GICD_I{S,C}ENABLER{1..31} 21413014Sciro.santilli@arm.com * interrupt enable bits for global interrupts 21513014Sciro.santilli@arm.com * 1b per interrupt, 32 bits per word, 31 words */ 21613014Sciro.santilli@arm.com uint32_t intEnabled[INT_BITS_MAX-1]; 21713014Sciro.santilli@arm.com 21813014Sciro.santilli@arm.com uint32_t& getIntEnabled(ContextID ctx, uint32_t ix) { 21913014Sciro.santilli@arm.com if (ix == 0) { 22013014Sciro.santilli@arm.com return getBankedRegs(ctx).intEnabled; 22113014Sciro.santilli@arm.com } else { 22213014Sciro.santilli@arm.com return intEnabled[ix - 1]; 22313014Sciro.santilli@arm.com } 22413014Sciro.santilli@arm.com } 22513014Sciro.santilli@arm.com 22613014Sciro.santilli@arm.com /** GICD_I{S,C}PENDR{1..31} 22713014Sciro.santilli@arm.com * interrupt pending bits for global interrupts 22813014Sciro.santilli@arm.com * 1b per interrupt, 32 bits per word, 31 words */ 22913014Sciro.santilli@arm.com uint32_t pendingInt[INT_BITS_MAX-1]; 23013014Sciro.santilli@arm.com 23113014Sciro.santilli@arm.com uint32_t& getPendingInt(ContextID ctx, uint32_t ix) { 23213014Sciro.santilli@arm.com assert(ix < INT_BITS_MAX); 23313014Sciro.santilli@arm.com if (ix == 0) { 23413014Sciro.santilli@arm.com return getBankedRegs(ctx).pendingInt; 23513014Sciro.santilli@arm.com } else { 23613014Sciro.santilli@arm.com return pendingInt[ix - 1]; 23713014Sciro.santilli@arm.com } 23813014Sciro.santilli@arm.com } 23913014Sciro.santilli@arm.com 24013014Sciro.santilli@arm.com /** GICD_I{S,C}ACTIVER{1..31} 24113014Sciro.santilli@arm.com * interrupt active bits for global interrupts 24213014Sciro.santilli@arm.com * 1b per interrupt, 32 bits per word, 31 words */ 24313014Sciro.santilli@arm.com uint32_t activeInt[INT_BITS_MAX-1]; 24413014Sciro.santilli@arm.com 24513014Sciro.santilli@arm.com uint32_t& getActiveInt(ContextID ctx, uint32_t ix) { 24613014Sciro.santilli@arm.com assert(ix < INT_BITS_MAX); 24713014Sciro.santilli@arm.com if (ix == 0) { 24813014Sciro.santilli@arm.com return getBankedRegs(ctx).activeInt; 24913014Sciro.santilli@arm.com } else { 25013014Sciro.santilli@arm.com return activeInt[ix - 1]; 25113014Sciro.santilli@arm.com } 25213014Sciro.santilli@arm.com } 25313014Sciro.santilli@arm.com 25413110Sgiacomo.travaglini@arm.com /** GICD_IGROUPR{1..31} 25513110Sgiacomo.travaglini@arm.com * interrupt group bits for global interrupts 25613110Sgiacomo.travaglini@arm.com * 1b per interrupt, 32 bits per word, 31 words */ 25713110Sgiacomo.travaglini@arm.com uint32_t intGroup[INT_BITS_MAX-1]; 25813110Sgiacomo.travaglini@arm.com 25913110Sgiacomo.travaglini@arm.com uint32_t& getIntGroup(ContextID ctx, uint32_t ix) { 26013110Sgiacomo.travaglini@arm.com assert(ix < INT_BITS_MAX); 26113110Sgiacomo.travaglini@arm.com if (ix == 0) { 26213110Sgiacomo.travaglini@arm.com return getBankedRegs(ctx).intGroup; 26313110Sgiacomo.travaglini@arm.com } else { 26413110Sgiacomo.travaglini@arm.com return intGroup[ix - 1]; 26513110Sgiacomo.travaglini@arm.com } 26613110Sgiacomo.travaglini@arm.com } 26713110Sgiacomo.travaglini@arm.com 26813014Sciro.santilli@arm.com /** read only running priority register, 1 per cpu*/ 26913014Sciro.santilli@arm.com uint32_t iccrpr[CPU_MAX]; 27013014Sciro.santilli@arm.com 27113014Sciro.santilli@arm.com /** GICD_IPRIORITYR{8..255} 27213014Sciro.santilli@arm.com * an 8 bit priority (lower is higher priority) for each 27313014Sciro.santilli@arm.com * of the global (not replicated per CPU) interrupts. 27413014Sciro.santilli@arm.com */ 27513014Sciro.santilli@arm.com uint8_t intPriority[GLOBAL_INT_LINES]; 27613014Sciro.santilli@arm.com 27713014Sciro.santilli@arm.com uint8_t& getIntPriority(ContextID ctx, uint32_t ix) { 27813014Sciro.santilli@arm.com assert(ix < INT_LINES_MAX); 27913014Sciro.santilli@arm.com if (ix < SGI_MAX + PPI_MAX) { 28013014Sciro.santilli@arm.com return getBankedRegs(ctx).intPriority[ix]; 28113014Sciro.santilli@arm.com } else { 28213014Sciro.santilli@arm.com return intPriority[ix - (SGI_MAX + PPI_MAX)]; 28313014Sciro.santilli@arm.com } 28413014Sciro.santilli@arm.com } 28513014Sciro.santilli@arm.com 28613108Sadrien.pesle@arm.com /** GICD_ICFGRn 28713108Sadrien.pesle@arm.com * get 2 bit config associated to an interrupt. 28813108Sadrien.pesle@arm.com */ 28913108Sadrien.pesle@arm.com uint8_t getIntConfig(ContextID ctx, uint32_t ix) { 29013108Sadrien.pesle@arm.com assert(ix < INT_LINES_MAX); 29113108Sadrien.pesle@arm.com const uint8_t cfg_low = intNumToBit(ix * 2); 29213108Sadrien.pesle@arm.com const uint8_t cfg_hi = cfg_low + 1; 29313108Sadrien.pesle@arm.com return bits(intConfig[intNumToWord(ix * 2)], cfg_hi, cfg_low); 29413108Sadrien.pesle@arm.com } 29513108Sadrien.pesle@arm.com 29613014Sciro.santilli@arm.com /** GICD_ITARGETSR{8..255} 29713014Sciro.santilli@arm.com * an 8 bit cpu target id for each global interrupt. 29813014Sciro.santilli@arm.com */ 29913014Sciro.santilli@arm.com uint8_t cpuTarget[GLOBAL_INT_LINES]; 30013014Sciro.santilli@arm.com 30113014Sciro.santilli@arm.com uint8_t getCpuTarget(ContextID ctx, uint32_t ix) { 30213014Sciro.santilli@arm.com assert(ctx < sys->numRunningContexts()); 30313014Sciro.santilli@arm.com assert(ix < INT_LINES_MAX); 30413014Sciro.santilli@arm.com if (ix < SGI_MAX + PPI_MAX) { 30513014Sciro.santilli@arm.com // "GICD_ITARGETSR0 to GICD_ITARGETSR7 are read-only, and each 30613014Sciro.santilli@arm.com // field returns a value that corresponds only to the processor 30713014Sciro.santilli@arm.com // reading the register." 30813014Sciro.santilli@arm.com uint32_t ctx_mask; 30913014Sciro.santilli@arm.com if (gem5ExtensionsEnabled) { 31013014Sciro.santilli@arm.com ctx_mask = ctx; 31113014Sciro.santilli@arm.com } else { 31213014Sciro.santilli@arm.com // convert the CPU id number into a bit mask 31313014Sciro.santilli@arm.com ctx_mask = power(2, ctx); 31413014Sciro.santilli@arm.com } 31513014Sciro.santilli@arm.com return ctx_mask; 31613014Sciro.santilli@arm.com } else { 31713014Sciro.santilli@arm.com return cpuTarget[ix - 32]; 31813014Sciro.santilli@arm.com } 31913014Sciro.santilli@arm.com } 32013014Sciro.santilli@arm.com 32113014Sciro.santilli@arm.com /** 2 bit per interrupt signaling if it's level or edge sensitive 32213014Sciro.santilli@arm.com * and if it is 1:N or N:N */ 32313014Sciro.santilli@arm.com uint32_t intConfig[INT_BITS_MAX*2]; 32413014Sciro.santilli@arm.com 32513108Sadrien.pesle@arm.com bool isLevelSensitive(ContextID ctx, uint32_t ix) { 32613108Sadrien.pesle@arm.com if (ix == SPURIOUS_INT) { 32713108Sadrien.pesle@arm.com return false; 32813108Sadrien.pesle@arm.com } else { 32913108Sadrien.pesle@arm.com return bits(getIntConfig(ctx, ix), 1) == 0; 33013108Sadrien.pesle@arm.com } 33113108Sadrien.pesle@arm.com } 33213108Sadrien.pesle@arm.com 33313112Sgiacomo.travaglini@arm.com bool isGroup0(ContextID ctx, uint32_t int_num) { 33413112Sgiacomo.travaglini@arm.com const uint32_t group_reg = getIntGroup(ctx, intNumToWord(int_num)); 33513336Sadrien.pesle@arm.com return !bits(group_reg, intNumToBit(int_num)); 33613112Sgiacomo.travaglini@arm.com } 33713112Sgiacomo.travaglini@arm.com 33813112Sgiacomo.travaglini@arm.com /** 33913112Sgiacomo.travaglini@arm.com * This method checks if an interrupt ID must be signaled or has been 34013112Sgiacomo.travaglini@arm.com * signaled as a FIQ to the cpu. It does that by reading: 34113112Sgiacomo.travaglini@arm.com * 34213112Sgiacomo.travaglini@arm.com * 1) GICD_IGROUPR: controls if the interrupt is part of group0 or 34313112Sgiacomo.travaglini@arm.com * group1. Only group0 interrupts can be signaled as FIQs. 34413112Sgiacomo.travaglini@arm.com * 34513112Sgiacomo.travaglini@arm.com * 2) GICC_CTLR.FIQEn: controls whether the CPU interface signals Group 0 34613112Sgiacomo.travaglini@arm.com * interrupts to a target processor using the FIQ or the IRQ signal 34713112Sgiacomo.travaglini@arm.com */ 34813112Sgiacomo.travaglini@arm.com bool isFiq(ContextID ctx, uint32_t int_num) { 34913112Sgiacomo.travaglini@arm.com const bool is_group0 = isGroup0(ctx, int_num); 35013112Sgiacomo.travaglini@arm.com const bool use_fiq = cpuControl[ctx].fiqEn; 35113112Sgiacomo.travaglini@arm.com 35213112Sgiacomo.travaglini@arm.com if (is_group0 && use_fiq) { 35313112Sgiacomo.travaglini@arm.com return true; 35413112Sgiacomo.travaglini@arm.com } else { 35513112Sgiacomo.travaglini@arm.com return false; 35613112Sgiacomo.travaglini@arm.com } 35713112Sgiacomo.travaglini@arm.com } 35813112Sgiacomo.travaglini@arm.com 35913112Sgiacomo.travaglini@arm.com /** CPU enabled: 36013112Sgiacomo.travaglini@arm.com * Checks if GICC_CTLR.EnableGrp0 or EnableGrp1 are set 36113112Sgiacomo.travaglini@arm.com */ 36213109Sgiacomo.travaglini@arm.com bool cpuEnabled(ContextID ctx) const { 36313109Sgiacomo.travaglini@arm.com return cpuControl[ctx].enableGrp0 || 36413109Sgiacomo.travaglini@arm.com cpuControl[ctx].enableGrp1; 36513109Sgiacomo.travaglini@arm.com } 36613109Sgiacomo.travaglini@arm.com 36713109Sgiacomo.travaglini@arm.com /** GICC_CTLR: 36813109Sgiacomo.travaglini@arm.com * CPU interface control register 36913109Sgiacomo.travaglini@arm.com */ 37013109Sgiacomo.travaglini@arm.com CTLR cpuControl[CPU_MAX]; 37113014Sciro.santilli@arm.com 37213014Sciro.santilli@arm.com /** CPU priority */ 37313014Sciro.santilli@arm.com uint8_t cpuPriority[CPU_MAX]; 37413014Sciro.santilli@arm.com uint8_t getCpuPriority(unsigned cpu); // BPR-adjusted priority value 37513014Sciro.santilli@arm.com 37613014Sciro.santilli@arm.com /** Binary point registers */ 37713014Sciro.santilli@arm.com uint8_t cpuBpr[CPU_MAX]; 37813014Sciro.santilli@arm.com 37913014Sciro.santilli@arm.com /** highest interrupt that is interrupting CPU */ 38013014Sciro.santilli@arm.com uint32_t cpuHighestInt[CPU_MAX]; 38113014Sciro.santilli@arm.com 38213014Sciro.santilli@arm.com /** One bit per cpu per software interrupt that is pending for each 38313014Sciro.santilli@arm.com * possible sgi source. Indexed by SGI number. Each byte in generating cpu 38413014Sciro.santilli@arm.com * id and bits in position is destination id. e.g. 0x4 = CPU 0 generated 38513014Sciro.santilli@arm.com * interrupt for CPU 2. */ 38613014Sciro.santilli@arm.com uint64_t cpuSgiPending[SGI_MAX]; 38713014Sciro.santilli@arm.com uint64_t cpuSgiActive[SGI_MAX]; 38813014Sciro.santilli@arm.com 38913014Sciro.santilli@arm.com /** SGI pending arrays for gem5 GIC extension mode, which instead keeps 39013014Sciro.santilli@arm.com * 16 SGI pending bits for each of the (large number of) CPUs. 39113014Sciro.santilli@arm.com */ 39213014Sciro.santilli@arm.com uint32_t cpuSgiPendingExt[CPU_MAX]; 39313014Sciro.santilli@arm.com uint32_t cpuSgiActiveExt[CPU_MAX]; 39413014Sciro.santilli@arm.com 39513014Sciro.santilli@arm.com /** One bit per private peripheral interrupt. Only upper 16 bits 39613014Sciro.santilli@arm.com * will be used since PPI interrupts are numberred from 16 to 32 */ 39713014Sciro.santilli@arm.com uint32_t cpuPpiPending[CPU_MAX]; 39813014Sciro.santilli@arm.com uint32_t cpuPpiActive[CPU_MAX]; 39913014Sciro.santilli@arm.com 40013014Sciro.santilli@arm.com /** software generated interrupt 40113014Sciro.santilli@arm.com * @param data data to decode that indicates which cpus to interrupt 40213014Sciro.santilli@arm.com */ 40313014Sciro.santilli@arm.com void softInt(ContextID ctx, SWI swi); 40413014Sciro.santilli@arm.com 40513014Sciro.santilli@arm.com /** See if some processor interrupt flags need to be enabled/disabled 40613014Sciro.santilli@arm.com * @param hint which set of interrupts needs to be checked 40713014Sciro.santilli@arm.com */ 40813014Sciro.santilli@arm.com virtual void updateIntState(int hint); 40913014Sciro.santilli@arm.com 41013014Sciro.santilli@arm.com /** Update the register that records priority of the highest priority 41113014Sciro.santilli@arm.com * active interrupt*/ 41213014Sciro.santilli@arm.com void updateRunPri(); 41313014Sciro.santilli@arm.com 41413014Sciro.santilli@arm.com /** generate a bit mask to check cpuSgi for an interrupt. */ 41513014Sciro.santilli@arm.com uint64_t genSwiMask(int cpu); 41613014Sciro.santilli@arm.com 41713014Sciro.santilli@arm.com int intNumToWord(int num) const { return num >> 5; } 41813014Sciro.santilli@arm.com int intNumToBit(int num) const { return num % 32; } 41913014Sciro.santilli@arm.com 42013112Sgiacomo.travaglini@arm.com /** Clears a cpu IRQ or FIQ signal */ 42113112Sgiacomo.travaglini@arm.com void clearInt(ContextID ctx, uint32_t int_num); 42213112Sgiacomo.travaglini@arm.com 42313014Sciro.santilli@arm.com /** 42413014Sciro.santilli@arm.com * Post an interrupt to a CPU with a delay 42513014Sciro.santilli@arm.com */ 42613014Sciro.santilli@arm.com void postInt(uint32_t cpu, Tick when); 42713111Sgiacomo.travaglini@arm.com void postFiq(uint32_t cpu, Tick when); 42813014Sciro.santilli@arm.com 42913014Sciro.santilli@arm.com /** 43013014Sciro.santilli@arm.com * Deliver a delayed interrupt to the target CPU 43113014Sciro.santilli@arm.com */ 43213014Sciro.santilli@arm.com void postDelayedInt(uint32_t cpu); 43313111Sgiacomo.travaglini@arm.com void postDelayedFiq(uint32_t cpu); 43413014Sciro.santilli@arm.com 43513014Sciro.santilli@arm.com EventFunctionWrapper *postIntEvent[CPU_MAX]; 43613111Sgiacomo.travaglini@arm.com EventFunctionWrapper *postFiqEvent[CPU_MAX]; 43713014Sciro.santilli@arm.com int pendingDelayedInterrupts; 43813014Sciro.santilli@arm.com 43913014Sciro.santilli@arm.com public: 44013014Sciro.santilli@arm.com typedef GicV2Params Params; 44113014Sciro.santilli@arm.com const Params * 44213014Sciro.santilli@arm.com params() const 44313014Sciro.santilli@arm.com { 44413014Sciro.santilli@arm.com return dynamic_cast<const Params *>(_params); 44513014Sciro.santilli@arm.com } 44613014Sciro.santilli@arm.com GicV2(const Params *p); 44713014Sciro.santilli@arm.com ~GicV2(); 44813014Sciro.santilli@arm.com 44913014Sciro.santilli@arm.com DrainState drain() override; 45013014Sciro.santilli@arm.com void drainResume() override; 45113014Sciro.santilli@arm.com 45213014Sciro.santilli@arm.com void serialize(CheckpointOut &cp) const override; 45313014Sciro.santilli@arm.com void unserialize(CheckpointIn &cp) override; 45413014Sciro.santilli@arm.com 45513014Sciro.santilli@arm.com public: /* PioDevice */ 45613014Sciro.santilli@arm.com AddrRangeList getAddrRanges() const override { return addrRanges; } 45713014Sciro.santilli@arm.com 45813014Sciro.santilli@arm.com /** A PIO read to the device, immediately split up into 45913014Sciro.santilli@arm.com * readDistributor() or readCpu() 46013014Sciro.santilli@arm.com */ 46113014Sciro.santilli@arm.com Tick read(PacketPtr pkt) override; 46213014Sciro.santilli@arm.com 46313014Sciro.santilli@arm.com /** A PIO read to the device, immediately split up into 46413014Sciro.santilli@arm.com * writeDistributor() or writeCpu() 46513014Sciro.santilli@arm.com */ 46613014Sciro.santilli@arm.com Tick write(PacketPtr pkt) override; 46713014Sciro.santilli@arm.com 46813014Sciro.santilli@arm.com public: /* BaseGic */ 46913014Sciro.santilli@arm.com void sendInt(uint32_t number) override; 47013014Sciro.santilli@arm.com void clearInt(uint32_t number) override; 47113014Sciro.santilli@arm.com 47213014Sciro.santilli@arm.com void sendPPInt(uint32_t num, uint32_t cpu) override; 47313014Sciro.santilli@arm.com void clearPPInt(uint32_t num, uint32_t cpu) override; 47413014Sciro.santilli@arm.com 47513014Sciro.santilli@arm.com protected: 47613014Sciro.santilli@arm.com /** Handle a read to the distributor portion of the GIC 47713014Sciro.santilli@arm.com * @param pkt packet to respond to 47813014Sciro.santilli@arm.com */ 47913014Sciro.santilli@arm.com Tick readDistributor(PacketPtr pkt); 48013014Sciro.santilli@arm.com uint32_t readDistributor(ContextID ctx, Addr daddr, 48113014Sciro.santilli@arm.com size_t resp_sz); 48213014Sciro.santilli@arm.com uint32_t readDistributor(ContextID ctx, Addr daddr) override { 48313014Sciro.santilli@arm.com return readDistributor(ctx, daddr, 4); 48413014Sciro.santilli@arm.com } 48513014Sciro.santilli@arm.com 48613014Sciro.santilli@arm.com /** Handle a read to the cpu portion of the GIC 48713014Sciro.santilli@arm.com * @param pkt packet to respond to 48813014Sciro.santilli@arm.com */ 48913014Sciro.santilli@arm.com Tick readCpu(PacketPtr pkt); 49013014Sciro.santilli@arm.com uint32_t readCpu(ContextID ctx, Addr daddr) override; 49113014Sciro.santilli@arm.com 49213014Sciro.santilli@arm.com /** Handle a write to the distributor portion of the GIC 49313014Sciro.santilli@arm.com * @param pkt packet to respond to 49413014Sciro.santilli@arm.com */ 49513014Sciro.santilli@arm.com Tick writeDistributor(PacketPtr pkt); 49613014Sciro.santilli@arm.com void writeDistributor(ContextID ctx, Addr daddr, 49713014Sciro.santilli@arm.com uint32_t data, size_t data_sz); 49813014Sciro.santilli@arm.com void writeDistributor(ContextID ctx, Addr daddr, 49913014Sciro.santilli@arm.com uint32_t data) override { 50013014Sciro.santilli@arm.com return writeDistributor(ctx, daddr, data, 4); 50113014Sciro.santilli@arm.com } 50213014Sciro.santilli@arm.com 50313014Sciro.santilli@arm.com /** Handle a write to the cpu portion of the GIC 50413014Sciro.santilli@arm.com * @param pkt packet to respond to 50513014Sciro.santilli@arm.com */ 50613014Sciro.santilli@arm.com Tick writeCpu(PacketPtr pkt); 50713014Sciro.santilli@arm.com void writeCpu(ContextID ctx, Addr daddr, uint32_t data) override; 50813014Sciro.santilli@arm.com}; 50913014Sciro.santilli@arm.com 51013014Sciro.santilli@arm.com#endif //__DEV_ARM_GIC_H__ 511