19525SAndreas.Sandberg@ARM.com/* 212739Sandreas.sandberg@arm.com * Copyright (c) 2012-2013, 2017-2018 ARM Limited 39525SAndreas.Sandberg@ARM.com * All rights reserved 49525SAndreas.Sandberg@ARM.com * 59525SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 69525SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 79525SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 89525SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 99525SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 109525SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 119525SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 129525SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 139525SAndreas.Sandberg@ARM.com * 149525SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 159525SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 169525SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 179525SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 189525SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 199525SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 209525SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 219525SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 229525SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 239525SAndreas.Sandberg@ARM.com * this software without specific prior written permission. 249525SAndreas.Sandberg@ARM.com * 259525SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 269525SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 279525SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 289525SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 299525SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 309525SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 319525SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 329525SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 339525SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 349525SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 359525SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 369525SAndreas.Sandberg@ARM.com * 379525SAndreas.Sandberg@ARM.com * Authors: Andreas Sandberg 389525SAndreas.Sandberg@ARM.com */ 399525SAndreas.Sandberg@ARM.com 409525SAndreas.Sandberg@ARM.com/** @file 419525SAndreas.Sandberg@ARM.com * Base class for ARM GIC implementations 429525SAndreas.Sandberg@ARM.com */ 439525SAndreas.Sandberg@ARM.com 449525SAndreas.Sandberg@ARM.com#ifndef __DEV_ARM_BASE_GIC_H__ 459525SAndreas.Sandberg@ARM.com#define __DEV_ARM_BASE_GIC_H__ 469525SAndreas.Sandberg@ARM.com 4712974Sgiacomo.travaglini@arm.com#include <unordered_map> 4812974Sgiacomo.travaglini@arm.com 4913531Sjairo.balart@metempsy.com#include "arch/arm/system.hh" 509525SAndreas.Sandberg@ARM.com#include "dev/io_device.hh" 519525SAndreas.Sandberg@ARM.com 529525SAndreas.Sandberg@ARM.comclass Platform; 5312739Sandreas.sandberg@arm.comclass RealView; 5412739Sandreas.sandberg@arm.comclass ThreadContext; 5512974Sgiacomo.travaglini@arm.comclass ArmInterruptPin; 5612974Sgiacomo.travaglini@arm.comclass ArmSPI; 5712974Sgiacomo.travaglini@arm.comclass ArmPPI; 5812739Sandreas.sandberg@arm.com 5912739Sandreas.sandberg@arm.comstruct ArmInterruptPinParams; 6012739Sandreas.sandberg@arm.comstruct ArmPPIParams; 6112739Sandreas.sandberg@arm.comstruct ArmSPIParams; 6212739Sandreas.sandberg@arm.comstruct BaseGicParams; 639525SAndreas.Sandberg@ARM.com 649525SAndreas.Sandberg@ARM.comclass BaseGic : public PioDevice 659525SAndreas.Sandberg@ARM.com{ 669525SAndreas.Sandberg@ARM.com public: 6712739Sandreas.sandberg@arm.com typedef BaseGicParams Params; 689525SAndreas.Sandberg@ARM.com 699525SAndreas.Sandberg@ARM.com BaseGic(const Params *p); 709525SAndreas.Sandberg@ARM.com virtual ~BaseGic(); 7113531Sjairo.balart@metempsy.com void init() override; 729525SAndreas.Sandberg@ARM.com 739525SAndreas.Sandberg@ARM.com const Params * params() const; 749525SAndreas.Sandberg@ARM.com 759525SAndreas.Sandberg@ARM.com /** 769525SAndreas.Sandberg@ARM.com * Post an interrupt from a device that is connected to the GIC. 779525SAndreas.Sandberg@ARM.com * 789525SAndreas.Sandberg@ARM.com * Depending on the configuration, the GIC will pass this interrupt 799525SAndreas.Sandberg@ARM.com * on through to a CPU. 809525SAndreas.Sandberg@ARM.com * 819525SAndreas.Sandberg@ARM.com * @param num number of interrupt to send 829525SAndreas.Sandberg@ARM.com */ 839525SAndreas.Sandberg@ARM.com virtual void sendInt(uint32_t num) = 0; 849525SAndreas.Sandberg@ARM.com 859525SAndreas.Sandberg@ARM.com /** 869525SAndreas.Sandberg@ARM.com * Interface call for private peripheral interrupts. 879525SAndreas.Sandberg@ARM.com * 889525SAndreas.Sandberg@ARM.com * @param num number of interrupt to send 899525SAndreas.Sandberg@ARM.com * @param cpu CPU to forward interrupt to 909525SAndreas.Sandberg@ARM.com */ 919525SAndreas.Sandberg@ARM.com virtual void sendPPInt(uint32_t num, uint32_t cpu) = 0; 929942Smatt.evans@arm.com virtual void clearPPInt(uint32_t num, uint32_t cpu) = 0; 939525SAndreas.Sandberg@ARM.com 949525SAndreas.Sandberg@ARM.com /** 959525SAndreas.Sandberg@ARM.com * Clear an interrupt from a device that is connected to the GIC. 969525SAndreas.Sandberg@ARM.com * 979525SAndreas.Sandberg@ARM.com * Depending on the configuration, the GIC may de-assert it's CPU 989525SAndreas.Sandberg@ARM.com * line. 999525SAndreas.Sandberg@ARM.com * 1009525SAndreas.Sandberg@ARM.com * @param num number of interrupt to send 1019525SAndreas.Sandberg@ARM.com */ 1029525SAndreas.Sandberg@ARM.com virtual void clearInt(uint32_t num) = 0; 1039525SAndreas.Sandberg@ARM.com 10413531Sjairo.balart@metempsy.com ArmSystem * 10513531Sjairo.balart@metempsy.com getSystem() const 10613531Sjairo.balart@metempsy.com { 10713531Sjairo.balart@metempsy.com return (ArmSystem *) sys; 10813531Sjairo.balart@metempsy.com } 10913531Sjairo.balart@metempsy.com 1109525SAndreas.Sandberg@ARM.com protected: 1119525SAndreas.Sandberg@ARM.com /** Platform this GIC belongs to. */ 1129525SAndreas.Sandberg@ARM.com Platform *platform; 1139525SAndreas.Sandberg@ARM.com}; 1149525SAndreas.Sandberg@ARM.com 11511943SCurtis.Dunham@arm.comclass BaseGicRegisters 11611943SCurtis.Dunham@arm.com{ 11711943SCurtis.Dunham@arm.com public: 11811943SCurtis.Dunham@arm.com virtual uint32_t readDistributor(ContextID ctx, Addr daddr) = 0; 11911943SCurtis.Dunham@arm.com virtual uint32_t readCpu(ContextID ctx, Addr daddr) = 0; 12011943SCurtis.Dunham@arm.com 12111943SCurtis.Dunham@arm.com virtual void writeDistributor(ContextID ctx, Addr daddr, 12211943SCurtis.Dunham@arm.com uint32_t data) = 0; 12311943SCurtis.Dunham@arm.com virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data) = 0; 12411943SCurtis.Dunham@arm.com}; 12511943SCurtis.Dunham@arm.com 12612739Sandreas.sandberg@arm.com/** 12712974Sgiacomo.travaglini@arm.com * This SimObject is instantiated in the python world and 12812974Sgiacomo.travaglini@arm.com * serves as an ArmInterruptPin generator. In this way it 12912974Sgiacomo.travaglini@arm.com * is possible to instantiate a single generator per component 13012974Sgiacomo.travaglini@arm.com * during configuration, and to dynamically spawn ArmInterruptPins. 13112974Sgiacomo.travaglini@arm.com * See ArmPPIGen for more info on how this is used. 13212974Sgiacomo.travaglini@arm.com */ 13312974Sgiacomo.travaglini@arm.comclass ArmInterruptPinGen : public SimObject 13412974Sgiacomo.travaglini@arm.com{ 13512974Sgiacomo.travaglini@arm.com public: 13612974Sgiacomo.travaglini@arm.com ArmInterruptPinGen(const ArmInterruptPinParams *p); 13712974Sgiacomo.travaglini@arm.com 13812974Sgiacomo.travaglini@arm.com virtual ArmInterruptPin* get(ThreadContext *tc = nullptr) = 0; 13912974Sgiacomo.travaglini@arm.com}; 14012974Sgiacomo.travaglini@arm.com 14112974Sgiacomo.travaglini@arm.com/** 14212974Sgiacomo.travaglini@arm.com * Shared Peripheral Interrupt Generator 14312974Sgiacomo.travaglini@arm.com * It is capable of generating one interrupt only: it maintains a pointer 14412974Sgiacomo.travaglini@arm.com * to it and returns it every time it is asked for it (via the get metod) 14512974Sgiacomo.travaglini@arm.com */ 14612974Sgiacomo.travaglini@arm.comclass ArmSPIGen : public ArmInterruptPinGen 14712974Sgiacomo.travaglini@arm.com{ 14812974Sgiacomo.travaglini@arm.com public: 14912974Sgiacomo.travaglini@arm.com ArmSPIGen(const ArmSPIParams *p); 15012974Sgiacomo.travaglini@arm.com 15112974Sgiacomo.travaglini@arm.com ArmInterruptPin* get(ThreadContext *tc = nullptr) override; 15212974Sgiacomo.travaglini@arm.com protected: 15312974Sgiacomo.travaglini@arm.com ArmSPI* pin; 15412974Sgiacomo.travaglini@arm.com}; 15512974Sgiacomo.travaglini@arm.com 15612974Sgiacomo.travaglini@arm.com/** 15712974Sgiacomo.travaglini@arm.com * Private Peripheral Interrupt Generator 15812974Sgiacomo.travaglini@arm.com * Since PPIs are banked in the GIC, this class is capable of generating 15912974Sgiacomo.travaglini@arm.com * more than one interrupt (one per ContextID). 16012974Sgiacomo.travaglini@arm.com */ 16112974Sgiacomo.travaglini@arm.comclass ArmPPIGen : public ArmInterruptPinGen 16212974Sgiacomo.travaglini@arm.com{ 16312974Sgiacomo.travaglini@arm.com public: 16412974Sgiacomo.travaglini@arm.com ArmPPIGen(const ArmPPIParams *p); 16512974Sgiacomo.travaglini@arm.com 16612974Sgiacomo.travaglini@arm.com ArmInterruptPin* get(ThreadContext* tc = nullptr) override; 16712974Sgiacomo.travaglini@arm.com protected: 16812974Sgiacomo.travaglini@arm.com std::unordered_map<ContextID, ArmPPI*> pins; 16912974Sgiacomo.travaglini@arm.com}; 17012974Sgiacomo.travaglini@arm.com 17112974Sgiacomo.travaglini@arm.com/** 17212739Sandreas.sandberg@arm.com * Generic representation of an Arm interrupt pin. 17312739Sandreas.sandberg@arm.com */ 17412974Sgiacomo.travaglini@arm.comclass ArmInterruptPin 17512739Sandreas.sandberg@arm.com{ 17612974Sgiacomo.travaglini@arm.com friend class ArmInterruptPinGen; 17712974Sgiacomo.travaglini@arm.com protected: 17812974Sgiacomo.travaglini@arm.com ArmInterruptPin(Platform *platform, ThreadContext *tc, 17912974Sgiacomo.travaglini@arm.com uint32_t int_num); 18012739Sandreas.sandberg@arm.com 18112739Sandreas.sandberg@arm.com public: /* Public interface */ 18212739Sandreas.sandberg@arm.com /** 18312739Sandreas.sandberg@arm.com * Set the thread context owning this interrupt. 18412739Sandreas.sandberg@arm.com * 18512739Sandreas.sandberg@arm.com * This method is used to set the thread context for interrupts 18612739Sandreas.sandberg@arm.com * that are thread/CPU-specific. Only devices that are used in 18712739Sandreas.sandberg@arm.com * such a context are expected to call this method. 18812739Sandreas.sandberg@arm.com */ 18912739Sandreas.sandberg@arm.com void setThreadContext(ThreadContext *tc); 19012739Sandreas.sandberg@arm.com 19112970Sgiacomo.travaglini@arm.com /** Get interrupt number */ 19212970Sgiacomo.travaglini@arm.com uint32_t num() const { return intNum; } 19312970Sgiacomo.travaglini@arm.com 19412739Sandreas.sandberg@arm.com /** Signal an interrupt */ 19512739Sandreas.sandberg@arm.com virtual void raise() = 0; 19612739Sandreas.sandberg@arm.com /** Clear a signalled interrupt */ 19712739Sandreas.sandberg@arm.com virtual void clear() = 0; 19812739Sandreas.sandberg@arm.com 19912739Sandreas.sandberg@arm.com protected: 20012739Sandreas.sandberg@arm.com /** 20112739Sandreas.sandberg@arm.com * Get the target context ID of this interrupt. 20212739Sandreas.sandberg@arm.com * 20312739Sandreas.sandberg@arm.com * @pre setThreadContext() must have been called prior to calling 20412739Sandreas.sandberg@arm.com * this method. 20512739Sandreas.sandberg@arm.com */ 20612739Sandreas.sandberg@arm.com ContextID targetContext() const; 20712739Sandreas.sandberg@arm.com 20812739Sandreas.sandberg@arm.com /** 20912739Sandreas.sandberg@arm.com * Pointer to the thread context that owns this interrupt in case 21012739Sandreas.sandberg@arm.com * it is a thread-/CPU-private interrupt 21112739Sandreas.sandberg@arm.com */ 21212739Sandreas.sandberg@arm.com const ThreadContext *threadContext; 21312739Sandreas.sandberg@arm.com 21412739Sandreas.sandberg@arm.com /** Arm platform to use for interrupt generation */ 21512739Sandreas.sandberg@arm.com RealView *const platform; 21612974Sgiacomo.travaglini@arm.com 21712739Sandreas.sandberg@arm.com /** Interrupt number to generate */ 21812739Sandreas.sandberg@arm.com const uint32_t intNum; 21912739Sandreas.sandberg@arm.com}; 22012739Sandreas.sandberg@arm.com 22112739Sandreas.sandberg@arm.comclass ArmSPI : public ArmInterruptPin 22212739Sandreas.sandberg@arm.com{ 22312974Sgiacomo.travaglini@arm.com friend class ArmSPIGen; 22412974Sgiacomo.travaglini@arm.com private: 22512974Sgiacomo.travaglini@arm.com ArmSPI(Platform *platform, uint32_t int_num); 22612974Sgiacomo.travaglini@arm.com 22712739Sandreas.sandberg@arm.com public: 22812739Sandreas.sandberg@arm.com void raise() override; 22912739Sandreas.sandberg@arm.com void clear() override; 23012739Sandreas.sandberg@arm.com}; 23112739Sandreas.sandberg@arm.com 23212739Sandreas.sandberg@arm.comclass ArmPPI : public ArmInterruptPin 23312739Sandreas.sandberg@arm.com{ 23412974Sgiacomo.travaglini@arm.com friend class ArmPPIGen; 23512974Sgiacomo.travaglini@arm.com private: 23612974Sgiacomo.travaglini@arm.com ArmPPI(Platform *platform, ThreadContext *tc, uint32_t int_num); 23712974Sgiacomo.travaglini@arm.com 23812739Sandreas.sandberg@arm.com public: 23912739Sandreas.sandberg@arm.com void raise() override; 24012739Sandreas.sandberg@arm.com void clear() override; 24112739Sandreas.sandberg@arm.com}; 24212739Sandreas.sandberg@arm.com 2439525SAndreas.Sandberg@ARM.com#endif 244