gic.hh revision 11461
110859Sandreas.sandberg@arm.com/*
211461Sandreas.sandberg@arm.com * Copyright (c) 2015-2016 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
3810859Sandreas.sandberg@arm.com */
3910859Sandreas.sandberg@arm.com
4010859Sandreas.sandberg@arm.com#ifndef __ARCH_ARM_KVM_GIC_HH__
4110859Sandreas.sandberg@arm.com#define __ARCH_ARM_KVM_GIC_HH__
4210859Sandreas.sandberg@arm.com
4310859Sandreas.sandberg@arm.com#include "arch/arm/system.hh"
4410859Sandreas.sandberg@arm.com#include "cpu/kvm/device.hh"
4510859Sandreas.sandberg@arm.com#include "cpu/kvm/vm.hh"
4610859Sandreas.sandberg@arm.com#include "dev/arm/base_gic.hh"
4710859Sandreas.sandberg@arm.com#include "dev/platform.hh"
4810859Sandreas.sandberg@arm.com
4911461Sandreas.sandberg@arm.com/**
5011461Sandreas.sandberg@arm.com * KVM in-kernel GIC abstraction
5111461Sandreas.sandberg@arm.com *
5211461Sandreas.sandberg@arm.com * This class defines a high-level interface to the KVM in-kernel GIC
5311461Sandreas.sandberg@arm.com * model. It exposes an API that is similar to that of
5411461Sandreas.sandberg@arm.com * software-emulated GIC models in gem5.
5511461Sandreas.sandberg@arm.com */
5611461Sandreas.sandberg@arm.comclass KvmKernelGicV2
5711461Sandreas.sandberg@arm.com{
5811461Sandreas.sandberg@arm.com  public:
5911461Sandreas.sandberg@arm.com    /**
6011461Sandreas.sandberg@arm.com     * Instantiate a KVM in-kernel GIC model.
6111461Sandreas.sandberg@arm.com     *
6211461Sandreas.sandberg@arm.com     * This constructor instantiates an in-kernel GIC model and wires
6311461Sandreas.sandberg@arm.com     * it up to the virtual memory system.
6411461Sandreas.sandberg@arm.com     *
6511461Sandreas.sandberg@arm.com     * @param vm KVM VM representing this system
6611461Sandreas.sandberg@arm.com     * @param cpu_addr GIC CPU interface base address
6711461Sandreas.sandberg@arm.com     * @param dist_addr GIC distributor base address
6811461Sandreas.sandberg@arm.com     */
6911461Sandreas.sandberg@arm.com    KvmKernelGicV2(KvmVM &vm, Addr cpu_addr, Addr dist_addr);
7011461Sandreas.sandberg@arm.com    virtual ~KvmKernelGicV2();
7111461Sandreas.sandberg@arm.com
7211461Sandreas.sandberg@arm.com    KvmKernelGicV2(const KvmKernelGicV2 &other) = delete;
7311461Sandreas.sandberg@arm.com    KvmKernelGicV2(const KvmKernelGicV2 &&other) = delete;
7411461Sandreas.sandberg@arm.com    KvmKernelGicV2 &operator=(const KvmKernelGicV2 &&rhs) = delete;
7511461Sandreas.sandberg@arm.com    KvmKernelGicV2 &operator=(const KvmKernelGicV2 &rhs) = delete;
7611461Sandreas.sandberg@arm.com
7711461Sandreas.sandberg@arm.com  public:
7811461Sandreas.sandberg@arm.com    /**
7911461Sandreas.sandberg@arm.com     * @{
8011461Sandreas.sandberg@arm.com     * @name In-kernel GIC API
8111461Sandreas.sandberg@arm.com     */
8211461Sandreas.sandberg@arm.com
8311461Sandreas.sandberg@arm.com    /**
8411461Sandreas.sandberg@arm.com     * Raise a shared peripheral interrupt
8511461Sandreas.sandberg@arm.com     *
8611461Sandreas.sandberg@arm.com     * @param spi SPI number
8711461Sandreas.sandberg@arm.com     */
8811461Sandreas.sandberg@arm.com    void setSPI(unsigned spi);
8911461Sandreas.sandberg@arm.com    /**
9011461Sandreas.sandberg@arm.com     * Clear a shared peripheral interrupt
9111461Sandreas.sandberg@arm.com     *
9211461Sandreas.sandberg@arm.com     * @param spi SPI number
9311461Sandreas.sandberg@arm.com     */
9411461Sandreas.sandberg@arm.com    void clearSPI(unsigned spi);
9511461Sandreas.sandberg@arm.com
9611461Sandreas.sandberg@arm.com    /**
9711461Sandreas.sandberg@arm.com     * Raise a private peripheral interrupt
9811461Sandreas.sandberg@arm.com     *
9911461Sandreas.sandberg@arm.com     * @param vcpu KVM virtual CPU number
10011461Sandreas.sandberg@arm.com     * @parma ppi PPI interrupt number
10111461Sandreas.sandberg@arm.com     */
10211461Sandreas.sandberg@arm.com    void setPPI(unsigned vcpu, unsigned ppi);
10311461Sandreas.sandberg@arm.com
10411461Sandreas.sandberg@arm.com    /**
10511461Sandreas.sandberg@arm.com     * Clear a private peripheral interrupt
10611461Sandreas.sandberg@arm.com     *
10711461Sandreas.sandberg@arm.com     * @param vcpu KVM virtual CPU number
10811461Sandreas.sandberg@arm.com     * @parma ppi PPI interrupt number
10911461Sandreas.sandberg@arm.com     */
11011461Sandreas.sandberg@arm.com    void clearPPI(unsigned vcpu, unsigned ppi);
11111461Sandreas.sandberg@arm.com
11211461Sandreas.sandberg@arm.com    /** Address range for the CPU interfaces */
11311461Sandreas.sandberg@arm.com    const AddrRange cpuRange;
11411461Sandreas.sandberg@arm.com    /** Address range for the distributor interface */
11511461Sandreas.sandberg@arm.com    const AddrRange distRange;
11611461Sandreas.sandberg@arm.com
11711461Sandreas.sandberg@arm.com    /* @} */
11811461Sandreas.sandberg@arm.com
11911461Sandreas.sandberg@arm.com  protected:
12011461Sandreas.sandberg@arm.com    /**
12111461Sandreas.sandberg@arm.com     * Update the kernel's VGIC interrupt state
12211461Sandreas.sandberg@arm.com     *
12311461Sandreas.sandberg@arm.com     * @param type Interrupt type (KVM_ARM_IRQ_TYPE_PPI/KVM_ARM_IRQ_TYPE_SPI)
12411461Sandreas.sandberg@arm.com     * @param vcpu CPU id within KVM (ignored for SPIs)
12511461Sandreas.sandberg@arm.com     * @param irq Interrupt number
12611461Sandreas.sandberg@arm.com     * @param high True to signal an interrupt, false to clear it.
12711461Sandreas.sandberg@arm.com     */
12811461Sandreas.sandberg@arm.com    void setIntState(unsigned type, unsigned vcpu, unsigned irq, bool high);
12911461Sandreas.sandberg@arm.com
13011461Sandreas.sandberg@arm.com    /** KVM VM in the parent system */
13111461Sandreas.sandberg@arm.com    KvmVM &vm;
13211461Sandreas.sandberg@arm.com
13311461Sandreas.sandberg@arm.com    /** Kernel interface to the GIC */
13411461Sandreas.sandberg@arm.com    KvmDevice kdev;
13511461Sandreas.sandberg@arm.com};
13611461Sandreas.sandberg@arm.com
13711461Sandreas.sandberg@arm.comstruct KvmGicParams;
13810859Sandreas.sandberg@arm.com
13910859Sandreas.sandberg@arm.com/**
14010859Sandreas.sandberg@arm.com * In-kernel GIC model.
14110859Sandreas.sandberg@arm.com *
14210859Sandreas.sandberg@arm.com * When using a KVM-based CPU model, it is possible to offload GIC
14310859Sandreas.sandberg@arm.com * emulation to the kernel. This reduces some overheads when the guest
14410859Sandreas.sandberg@arm.com * accesses the GIC and makes it possible to use in-kernel
14510859Sandreas.sandberg@arm.com * architected/generic timer emulation.
14610859Sandreas.sandberg@arm.com *
14710859Sandreas.sandberg@arm.com * This device uses interfaces with the kernel GicV2 model that is
14810859Sandreas.sandberg@arm.com * documented in Documentation/virtual/kvm/devices/arm-vgic.txt in the
14910859Sandreas.sandberg@arm.com * Linux kernel sources.
15010859Sandreas.sandberg@arm.com *
15110859Sandreas.sandberg@arm.com * This GIC model has the following known limitations:
15210859Sandreas.sandberg@arm.com * <ul>
15310859Sandreas.sandberg@arm.com *   <li>Checkpointing is not supported.
15410859Sandreas.sandberg@arm.com *   <li>This model only works with kvm. Simulated CPUs are not
15510859Sandreas.sandberg@arm.com *       supported since this would require the kernel to inject
15610859Sandreas.sandberg@arm.com *       interrupt into the simulated CPU.
15710859Sandreas.sandberg@arm.com * </ul>
15810859Sandreas.sandberg@arm.com *
15910859Sandreas.sandberg@arm.com * @warn This GIC model cannot be used with simulated CPUs!
16010859Sandreas.sandberg@arm.com */
16110859Sandreas.sandberg@arm.comclass KvmGic : public BaseGic
16210859Sandreas.sandberg@arm.com{
16310859Sandreas.sandberg@arm.com  public: // SimObject / Serializable / Drainable
16410859Sandreas.sandberg@arm.com    KvmGic(const KvmGicParams *p);
16510859Sandreas.sandberg@arm.com    ~KvmGic();
16610859Sandreas.sandberg@arm.com
16711168Sandreas.hansson@arm.com    void startup() override { verifyMemoryMode(); }
16811168Sandreas.hansson@arm.com    void drainResume() override { verifyMemoryMode(); }
16910859Sandreas.sandberg@arm.com
17011168Sandreas.hansson@arm.com    void serialize(CheckpointOut &cp) const override;
17111461Sandreas.sandberg@arm.com    void unserialize(CheckpointIn &cp) override;
17210859Sandreas.sandberg@arm.com
17310859Sandreas.sandberg@arm.com  public: // PioDevice
17410859Sandreas.sandberg@arm.com    AddrRangeList getAddrRanges() const { return addrRanges; }
17511168Sandreas.hansson@arm.com    Tick read(PacketPtr pkt) override;
17611168Sandreas.hansson@arm.com    Tick write(PacketPtr pkt) override;
17710859Sandreas.sandberg@arm.com
17810859Sandreas.sandberg@arm.com  public: // BaseGic
17911168Sandreas.hansson@arm.com    void sendInt(uint32_t num) override;
18011168Sandreas.hansson@arm.com    void clearInt(uint32_t num) override;
18110859Sandreas.sandberg@arm.com
18211168Sandreas.hansson@arm.com    void sendPPInt(uint32_t num, uint32_t cpu) override;
18311168Sandreas.hansson@arm.com    void clearPPInt(uint32_t num, uint32_t cpu) override;
18410859Sandreas.sandberg@arm.com
18510859Sandreas.sandberg@arm.com  protected:
18610859Sandreas.sandberg@arm.com    /**
18710859Sandreas.sandberg@arm.com     * Do memory mode sanity checks
18810859Sandreas.sandberg@arm.com     *
18910859Sandreas.sandberg@arm.com     * This method only really exists to warn users that try to switch
19010859Sandreas.sandberg@arm.com     * to a simulate CPU. There is no fool proof method to detect
19110859Sandreas.sandberg@arm.com     * simulated CPUs, but checking that we're in atomic mode and
19210859Sandreas.sandberg@arm.com     * bypassing caches should be robust enough.
19310859Sandreas.sandberg@arm.com     */
19410859Sandreas.sandberg@arm.com    void verifyMemoryMode() const;
19510859Sandreas.sandberg@arm.com
19610859Sandreas.sandberg@arm.com    /** System this interrupt controller belongs to */
19710859Sandreas.sandberg@arm.com    System &system;
19810859Sandreas.sandberg@arm.com
19911461Sandreas.sandberg@arm.com    /** Kernel GIC device */
20011461Sandreas.sandberg@arm.com    KvmKernelGicV2 kernelGic;
20111461Sandreas.sandberg@arm.com
20210859Sandreas.sandberg@arm.com    /** Union of all memory  */
20310859Sandreas.sandberg@arm.com    const AddrRangeList addrRanges;
20410859Sandreas.sandberg@arm.com};
20510859Sandreas.sandberg@arm.com
20610859Sandreas.sandberg@arm.com#endif // __ARCH_ARM_KVM_GIC_HH__
207