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