gic.hh revision 11840
110859Sandreas.sandberg@arm.com/* 211840SCurtis.Dunham@arm.com * Copyright (c) 2015-2017 ARM Limited 310859Sandreas.sandberg@arm.com * All rights reserved 410859Sandreas.sandberg@arm.com * 510859Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 610859Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 710859Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 810859Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 910859Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1010859Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1110859Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1210859Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1310859Sandreas.sandberg@arm.com * 1410859Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1510859Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1610859Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 1710859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 1810859Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1910859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2010859Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2110859Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2210859Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2310859Sandreas.sandberg@arm.com * this software without specific prior written permission. 2410859Sandreas.sandberg@arm.com * 2510859Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610859Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710859Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810859Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910859Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010859Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110859Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210859Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310859Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410859Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510859Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610859Sandreas.sandberg@arm.com * 3710859Sandreas.sandberg@arm.com * Authors: Andreas Sandberg 3811840SCurtis.Dunham@arm.com * Curtis Dunham 3910859Sandreas.sandberg@arm.com */ 4010859Sandreas.sandberg@arm.com 4110859Sandreas.sandberg@arm.com#ifndef __ARCH_ARM_KVM_GIC_HH__ 4210859Sandreas.sandberg@arm.com#define __ARCH_ARM_KVM_GIC_HH__ 4310859Sandreas.sandberg@arm.com 4410859Sandreas.sandberg@arm.com#include "arch/arm/system.hh" 4510859Sandreas.sandberg@arm.com#include "cpu/kvm/device.hh" 4610859Sandreas.sandberg@arm.com#include "cpu/kvm/vm.hh" 4710859Sandreas.sandberg@arm.com#include "dev/arm/base_gic.hh" 4811840SCurtis.Dunham@arm.com#include "dev/arm/gic_pl390.hh" 4910859Sandreas.sandberg@arm.com#include "dev/platform.hh" 5010859Sandreas.sandberg@arm.com 5111461Sandreas.sandberg@arm.com/** 5211461Sandreas.sandberg@arm.com * KVM in-kernel GIC abstraction 5311461Sandreas.sandberg@arm.com * 5411461Sandreas.sandberg@arm.com * This class defines a high-level interface to the KVM in-kernel GIC 5511461Sandreas.sandberg@arm.com * model. It exposes an API that is similar to that of 5611461Sandreas.sandberg@arm.com * software-emulated GIC models in gem5. 5711461Sandreas.sandberg@arm.com */ 5811461Sandreas.sandberg@arm.comclass KvmKernelGicV2 5911461Sandreas.sandberg@arm.com{ 6011461Sandreas.sandberg@arm.com public: 6111461Sandreas.sandberg@arm.com /** 6211461Sandreas.sandberg@arm.com * Instantiate a KVM in-kernel GIC model. 6311461Sandreas.sandberg@arm.com * 6411461Sandreas.sandberg@arm.com * This constructor instantiates an in-kernel GIC model and wires 6511461Sandreas.sandberg@arm.com * it up to the virtual memory system. 6611461Sandreas.sandberg@arm.com * 6711461Sandreas.sandberg@arm.com * @param vm KVM VM representing this system 6811461Sandreas.sandberg@arm.com * @param cpu_addr GIC CPU interface base address 6911461Sandreas.sandberg@arm.com * @param dist_addr GIC distributor base address 7011838SCurtis.Dunham@arm.com * @param it_lines Number of interrupt lines to support 7111461Sandreas.sandberg@arm.com */ 7211462Sandreas.sandberg@arm.com KvmKernelGicV2(KvmVM &vm, Addr cpu_addr, Addr dist_addr, 7311462Sandreas.sandberg@arm.com unsigned it_lines); 7411461Sandreas.sandberg@arm.com virtual ~KvmKernelGicV2(); 7511461Sandreas.sandberg@arm.com 7611461Sandreas.sandberg@arm.com KvmKernelGicV2(const KvmKernelGicV2 &other) = delete; 7711461Sandreas.sandberg@arm.com KvmKernelGicV2(const KvmKernelGicV2 &&other) = delete; 7811461Sandreas.sandberg@arm.com KvmKernelGicV2 &operator=(const KvmKernelGicV2 &&rhs) = delete; 7911461Sandreas.sandberg@arm.com KvmKernelGicV2 &operator=(const KvmKernelGicV2 &rhs) = delete; 8011461Sandreas.sandberg@arm.com 8111461Sandreas.sandberg@arm.com public: 8211461Sandreas.sandberg@arm.com /** 8311461Sandreas.sandberg@arm.com * @{ 8411461Sandreas.sandberg@arm.com * @name In-kernel GIC API 8511461Sandreas.sandberg@arm.com */ 8611461Sandreas.sandberg@arm.com 8711461Sandreas.sandberg@arm.com /** 8811461Sandreas.sandberg@arm.com * Raise a shared peripheral interrupt 8911461Sandreas.sandberg@arm.com * 9011461Sandreas.sandberg@arm.com * @param spi SPI number 9111461Sandreas.sandberg@arm.com */ 9211461Sandreas.sandberg@arm.com void setSPI(unsigned spi); 9311461Sandreas.sandberg@arm.com /** 9411461Sandreas.sandberg@arm.com * Clear a shared peripheral interrupt 9511461Sandreas.sandberg@arm.com * 9611461Sandreas.sandberg@arm.com * @param spi SPI number 9711461Sandreas.sandberg@arm.com */ 9811461Sandreas.sandberg@arm.com void clearSPI(unsigned spi); 9911461Sandreas.sandberg@arm.com 10011461Sandreas.sandberg@arm.com /** 10111461Sandreas.sandberg@arm.com * Raise a private peripheral interrupt 10211461Sandreas.sandberg@arm.com * 10311461Sandreas.sandberg@arm.com * @param vcpu KVM virtual CPU number 10411461Sandreas.sandberg@arm.com * @parma ppi PPI interrupt number 10511461Sandreas.sandberg@arm.com */ 10611461Sandreas.sandberg@arm.com void setPPI(unsigned vcpu, unsigned ppi); 10711461Sandreas.sandberg@arm.com 10811461Sandreas.sandberg@arm.com /** 10911461Sandreas.sandberg@arm.com * Clear a private peripheral interrupt 11011461Sandreas.sandberg@arm.com * 11111461Sandreas.sandberg@arm.com * @param vcpu KVM virtual CPU number 11211461Sandreas.sandberg@arm.com * @parma ppi PPI interrupt number 11311461Sandreas.sandberg@arm.com */ 11411461Sandreas.sandberg@arm.com void clearPPI(unsigned vcpu, unsigned ppi); 11511461Sandreas.sandberg@arm.com 11611461Sandreas.sandberg@arm.com /** Address range for the CPU interfaces */ 11711461Sandreas.sandberg@arm.com const AddrRange cpuRange; 11811461Sandreas.sandberg@arm.com /** Address range for the distributor interface */ 11911461Sandreas.sandberg@arm.com const AddrRange distRange; 12011461Sandreas.sandberg@arm.com 12111461Sandreas.sandberg@arm.com /* @} */ 12211461Sandreas.sandberg@arm.com 12311461Sandreas.sandberg@arm.com protected: 12411461Sandreas.sandberg@arm.com /** 12511461Sandreas.sandberg@arm.com * Update the kernel's VGIC interrupt state 12611461Sandreas.sandberg@arm.com * 12711461Sandreas.sandberg@arm.com * @param type Interrupt type (KVM_ARM_IRQ_TYPE_PPI/KVM_ARM_IRQ_TYPE_SPI) 12811461Sandreas.sandberg@arm.com * @param vcpu CPU id within KVM (ignored for SPIs) 12911461Sandreas.sandberg@arm.com * @param irq Interrupt number 13011461Sandreas.sandberg@arm.com * @param high True to signal an interrupt, false to clear it. 13111461Sandreas.sandberg@arm.com */ 13211461Sandreas.sandberg@arm.com void setIntState(unsigned type, unsigned vcpu, unsigned irq, bool high); 13311461Sandreas.sandberg@arm.com 13411461Sandreas.sandberg@arm.com /** KVM VM in the parent system */ 13511461Sandreas.sandberg@arm.com KvmVM &vm; 13611461Sandreas.sandberg@arm.com 13711461Sandreas.sandberg@arm.com /** Kernel interface to the GIC */ 13811461Sandreas.sandberg@arm.com KvmDevice kdev; 13911461Sandreas.sandberg@arm.com}; 14011461Sandreas.sandberg@arm.com 14111461Sandreas.sandberg@arm.comstruct KvmGicParams; 14210859Sandreas.sandberg@arm.com 14310859Sandreas.sandberg@arm.com/** 14410859Sandreas.sandberg@arm.com * In-kernel GIC model. 14510859Sandreas.sandberg@arm.com * 14610859Sandreas.sandberg@arm.com * When using a KVM-based CPU model, it is possible to offload GIC 14710859Sandreas.sandberg@arm.com * emulation to the kernel. This reduces some overheads when the guest 14810859Sandreas.sandberg@arm.com * accesses the GIC and makes it possible to use in-kernel 14910859Sandreas.sandberg@arm.com * architected/generic timer emulation. 15010859Sandreas.sandberg@arm.com * 15110859Sandreas.sandberg@arm.com * This device uses interfaces with the kernel GicV2 model that is 15210859Sandreas.sandberg@arm.com * documented in Documentation/virtual/kvm/devices/arm-vgic.txt in the 15310859Sandreas.sandberg@arm.com * Linux kernel sources. 15410859Sandreas.sandberg@arm.com * 15510859Sandreas.sandberg@arm.com * This GIC model has the following known limitations: 15610859Sandreas.sandberg@arm.com * <ul> 15710859Sandreas.sandberg@arm.com * <li>Checkpointing is not supported. 15810859Sandreas.sandberg@arm.com * <li>This model only works with kvm. Simulated CPUs are not 15910859Sandreas.sandberg@arm.com * supported since this would require the kernel to inject 16010859Sandreas.sandberg@arm.com * interrupt into the simulated CPU. 16110859Sandreas.sandberg@arm.com * </ul> 16210859Sandreas.sandberg@arm.com * 16310859Sandreas.sandberg@arm.com * @warn This GIC model cannot be used with simulated CPUs! 16410859Sandreas.sandberg@arm.com */ 16510859Sandreas.sandberg@arm.comclass KvmGic : public BaseGic 16610859Sandreas.sandberg@arm.com{ 16710859Sandreas.sandberg@arm.com public: // SimObject / Serializable / Drainable 16810859Sandreas.sandberg@arm.com KvmGic(const KvmGicParams *p); 16910859Sandreas.sandberg@arm.com ~KvmGic(); 17010859Sandreas.sandberg@arm.com 17111168Sandreas.hansson@arm.com void startup() override { verifyMemoryMode(); } 17211168Sandreas.hansson@arm.com void drainResume() override { verifyMemoryMode(); } 17310859Sandreas.sandberg@arm.com 17411168Sandreas.hansson@arm.com void serialize(CheckpointOut &cp) const override; 17511461Sandreas.sandberg@arm.com void unserialize(CheckpointIn &cp) override; 17610859Sandreas.sandberg@arm.com 17710859Sandreas.sandberg@arm.com public: // PioDevice 17810859Sandreas.sandberg@arm.com AddrRangeList getAddrRanges() const { return addrRanges; } 17911168Sandreas.hansson@arm.com Tick read(PacketPtr pkt) override; 18011168Sandreas.hansson@arm.com Tick write(PacketPtr pkt) override; 18110859Sandreas.sandberg@arm.com 18210859Sandreas.sandberg@arm.com public: // BaseGic 18311168Sandreas.hansson@arm.com void sendInt(uint32_t num) override; 18411168Sandreas.hansson@arm.com void clearInt(uint32_t num) override; 18510859Sandreas.sandberg@arm.com 18611168Sandreas.hansson@arm.com void sendPPInt(uint32_t num, uint32_t cpu) override; 18711168Sandreas.hansson@arm.com void clearPPInt(uint32_t num, uint32_t cpu) override; 18810859Sandreas.sandberg@arm.com 18910859Sandreas.sandberg@arm.com protected: 19010859Sandreas.sandberg@arm.com /** 19110859Sandreas.sandberg@arm.com * Do memory mode sanity checks 19210859Sandreas.sandberg@arm.com * 19310859Sandreas.sandberg@arm.com * This method only really exists to warn users that try to switch 19410859Sandreas.sandberg@arm.com * to a simulate CPU. There is no fool proof method to detect 19510859Sandreas.sandberg@arm.com * simulated CPUs, but checking that we're in atomic mode and 19610859Sandreas.sandberg@arm.com * bypassing caches should be robust enough. 19710859Sandreas.sandberg@arm.com */ 19810859Sandreas.sandberg@arm.com void verifyMemoryMode() const; 19910859Sandreas.sandberg@arm.com 20010859Sandreas.sandberg@arm.com /** System this interrupt controller belongs to */ 20110859Sandreas.sandberg@arm.com System &system; 20210859Sandreas.sandberg@arm.com 20311461Sandreas.sandberg@arm.com /** Kernel GIC device */ 20411461Sandreas.sandberg@arm.com KvmKernelGicV2 kernelGic; 20511461Sandreas.sandberg@arm.com 20610859Sandreas.sandberg@arm.com /** Union of all memory */ 20710859Sandreas.sandberg@arm.com const AddrRangeList addrRanges; 20810859Sandreas.sandberg@arm.com}; 20910859Sandreas.sandberg@arm.com 21011840SCurtis.Dunham@arm.comstruct MuxingKvmGicParams; 21111840SCurtis.Dunham@arm.com 21211840SCurtis.Dunham@arm.comclass MuxingKvmGic : public Pl390 21311840SCurtis.Dunham@arm.com{ 21411840SCurtis.Dunham@arm.com public: // SimObject / Serializable / Drainable 21511840SCurtis.Dunham@arm.com MuxingKvmGic(const MuxingKvmGicParams *p); 21611840SCurtis.Dunham@arm.com ~MuxingKvmGic(); 21711840SCurtis.Dunham@arm.com 21811840SCurtis.Dunham@arm.com void startup() override; 21911840SCurtis.Dunham@arm.com void drainResume() override; 22011840SCurtis.Dunham@arm.com 22111840SCurtis.Dunham@arm.com void serialize(CheckpointOut &cp) const override; 22211840SCurtis.Dunham@arm.com void unserialize(CheckpointIn &cp) override; 22311840SCurtis.Dunham@arm.com 22411840SCurtis.Dunham@arm.com public: // PioDevice 22511840SCurtis.Dunham@arm.com Tick read(PacketPtr pkt) override; 22611840SCurtis.Dunham@arm.com Tick write(PacketPtr pkt) override; 22711840SCurtis.Dunham@arm.com 22811840SCurtis.Dunham@arm.com public: // Pl390 22911840SCurtis.Dunham@arm.com void sendInt(uint32_t num) override; 23011840SCurtis.Dunham@arm.com void clearInt(uint32_t num) override; 23111840SCurtis.Dunham@arm.com 23211840SCurtis.Dunham@arm.com void sendPPInt(uint32_t num, uint32_t cpu) override; 23311840SCurtis.Dunham@arm.com void clearPPInt(uint32_t num, uint32_t cpu) override; 23411840SCurtis.Dunham@arm.com 23511840SCurtis.Dunham@arm.com protected: 23611840SCurtis.Dunham@arm.com /** Verify gem5 configuration will support KVM emulation */ 23711840SCurtis.Dunham@arm.com bool validKvmEnvironment() const; 23811840SCurtis.Dunham@arm.com 23911840SCurtis.Dunham@arm.com /** System this interrupt controller belongs to */ 24011840SCurtis.Dunham@arm.com System &system; 24111840SCurtis.Dunham@arm.com 24211840SCurtis.Dunham@arm.com /** Kernel GIC device */ 24311840SCurtis.Dunham@arm.com KvmKernelGicV2 *kernelGic; 24411840SCurtis.Dunham@arm.com 24511840SCurtis.Dunham@arm.com private: 24611840SCurtis.Dunham@arm.com bool usingKvm; 24711840SCurtis.Dunham@arm.com 24811840SCurtis.Dunham@arm.com /** Multiplexing implementation: state transfer functions */ 24911840SCurtis.Dunham@arm.com void fromPl390ToKvm(); 25011840SCurtis.Dunham@arm.com void fromKvmToPl390(); 25111840SCurtis.Dunham@arm.com}; 25211840SCurtis.Dunham@arm.com 25310859Sandreas.sandberg@arm.com#endif // __ARCH_ARM_KVM_GIC_HH__ 254