gic.hh revision 11462
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
6811462Sandreas.sandberg@arm.com     * @param it_liens Number of interrupt lines to support
6911461Sandreas.sandberg@arm.com     */
7011462Sandreas.sandberg@arm.com    KvmKernelGicV2(KvmVM &vm, Addr cpu_addr, Addr dist_addr,
7111462Sandreas.sandberg@arm.com                   unsigned it_lines);
7211461Sandreas.sandberg@arm.com    virtual ~KvmKernelGicV2();
7311461Sandreas.sandberg@arm.com
7411461Sandreas.sandberg@arm.com    KvmKernelGicV2(const KvmKernelGicV2 &other) = delete;
7511461Sandreas.sandberg@arm.com    KvmKernelGicV2(const KvmKernelGicV2 &&other) = delete;
7611461Sandreas.sandberg@arm.com    KvmKernelGicV2 &operator=(const KvmKernelGicV2 &&rhs) = delete;
7711461Sandreas.sandberg@arm.com    KvmKernelGicV2 &operator=(const KvmKernelGicV2 &rhs) = delete;
7811461Sandreas.sandberg@arm.com
7911461Sandreas.sandberg@arm.com  public:
8011461Sandreas.sandberg@arm.com    /**
8111461Sandreas.sandberg@arm.com     * @{
8211461Sandreas.sandberg@arm.com     * @name In-kernel GIC API
8311461Sandreas.sandberg@arm.com     */
8411461Sandreas.sandberg@arm.com
8511461Sandreas.sandberg@arm.com    /**
8611461Sandreas.sandberg@arm.com     * Raise a shared peripheral interrupt
8711461Sandreas.sandberg@arm.com     *
8811461Sandreas.sandberg@arm.com     * @param spi SPI number
8911461Sandreas.sandberg@arm.com     */
9011461Sandreas.sandberg@arm.com    void setSPI(unsigned spi);
9111461Sandreas.sandberg@arm.com    /**
9211461Sandreas.sandberg@arm.com     * Clear a shared peripheral interrupt
9311461Sandreas.sandberg@arm.com     *
9411461Sandreas.sandberg@arm.com     * @param spi SPI number
9511461Sandreas.sandberg@arm.com     */
9611461Sandreas.sandberg@arm.com    void clearSPI(unsigned spi);
9711461Sandreas.sandberg@arm.com
9811461Sandreas.sandberg@arm.com    /**
9911461Sandreas.sandberg@arm.com     * Raise a private peripheral interrupt
10011461Sandreas.sandberg@arm.com     *
10111461Sandreas.sandberg@arm.com     * @param vcpu KVM virtual CPU number
10211461Sandreas.sandberg@arm.com     * @parma ppi PPI interrupt number
10311461Sandreas.sandberg@arm.com     */
10411461Sandreas.sandberg@arm.com    void setPPI(unsigned vcpu, unsigned ppi);
10511461Sandreas.sandberg@arm.com
10611461Sandreas.sandberg@arm.com    /**
10711461Sandreas.sandberg@arm.com     * Clear a private peripheral interrupt
10811461Sandreas.sandberg@arm.com     *
10911461Sandreas.sandberg@arm.com     * @param vcpu KVM virtual CPU number
11011461Sandreas.sandberg@arm.com     * @parma ppi PPI interrupt number
11111461Sandreas.sandberg@arm.com     */
11211461Sandreas.sandberg@arm.com    void clearPPI(unsigned vcpu, unsigned ppi);
11311461Sandreas.sandberg@arm.com
11411461Sandreas.sandberg@arm.com    /** Address range for the CPU interfaces */
11511461Sandreas.sandberg@arm.com    const AddrRange cpuRange;
11611461Sandreas.sandberg@arm.com    /** Address range for the distributor interface */
11711461Sandreas.sandberg@arm.com    const AddrRange distRange;
11811461Sandreas.sandberg@arm.com
11911461Sandreas.sandberg@arm.com    /* @} */
12011461Sandreas.sandberg@arm.com
12111461Sandreas.sandberg@arm.com  protected:
12211461Sandreas.sandberg@arm.com    /**
12311461Sandreas.sandberg@arm.com     * Update the kernel's VGIC interrupt state
12411461Sandreas.sandberg@arm.com     *
12511461Sandreas.sandberg@arm.com     * @param type Interrupt type (KVM_ARM_IRQ_TYPE_PPI/KVM_ARM_IRQ_TYPE_SPI)
12611461Sandreas.sandberg@arm.com     * @param vcpu CPU id within KVM (ignored for SPIs)
12711461Sandreas.sandberg@arm.com     * @param irq Interrupt number
12811461Sandreas.sandberg@arm.com     * @param high True to signal an interrupt, false to clear it.
12911461Sandreas.sandberg@arm.com     */
13011461Sandreas.sandberg@arm.com    void setIntState(unsigned type, unsigned vcpu, unsigned irq, bool high);
13111461Sandreas.sandberg@arm.com
13211461Sandreas.sandberg@arm.com    /** KVM VM in the parent system */
13311461Sandreas.sandberg@arm.com    KvmVM &vm;
13411461Sandreas.sandberg@arm.com
13511461Sandreas.sandberg@arm.com    /** Kernel interface to the GIC */
13611461Sandreas.sandberg@arm.com    KvmDevice kdev;
13711461Sandreas.sandberg@arm.com};
13811461Sandreas.sandberg@arm.com
13911461Sandreas.sandberg@arm.comstruct KvmGicParams;
14010859Sandreas.sandberg@arm.com
14110859Sandreas.sandberg@arm.com/**
14210859Sandreas.sandberg@arm.com * In-kernel GIC model.
14310859Sandreas.sandberg@arm.com *
14410859Sandreas.sandberg@arm.com * When using a KVM-based CPU model, it is possible to offload GIC
14510859Sandreas.sandberg@arm.com * emulation to the kernel. This reduces some overheads when the guest
14610859Sandreas.sandberg@arm.com * accesses the GIC and makes it possible to use in-kernel
14710859Sandreas.sandberg@arm.com * architected/generic timer emulation.
14810859Sandreas.sandberg@arm.com *
14910859Sandreas.sandberg@arm.com * This device uses interfaces with the kernel GicV2 model that is
15010859Sandreas.sandberg@arm.com * documented in Documentation/virtual/kvm/devices/arm-vgic.txt in the
15110859Sandreas.sandberg@arm.com * Linux kernel sources.
15210859Sandreas.sandberg@arm.com *
15310859Sandreas.sandberg@arm.com * This GIC model has the following known limitations:
15410859Sandreas.sandberg@arm.com * <ul>
15510859Sandreas.sandberg@arm.com *   <li>Checkpointing is not supported.
15610859Sandreas.sandberg@arm.com *   <li>This model only works with kvm. Simulated CPUs are not
15710859Sandreas.sandberg@arm.com *       supported since this would require the kernel to inject
15810859Sandreas.sandberg@arm.com *       interrupt into the simulated CPU.
15910859Sandreas.sandberg@arm.com * </ul>
16010859Sandreas.sandberg@arm.com *
16110859Sandreas.sandberg@arm.com * @warn This GIC model cannot be used with simulated CPUs!
16210859Sandreas.sandberg@arm.com */
16310859Sandreas.sandberg@arm.comclass KvmGic : public BaseGic
16410859Sandreas.sandberg@arm.com{
16510859Sandreas.sandberg@arm.com  public: // SimObject / Serializable / Drainable
16610859Sandreas.sandberg@arm.com    KvmGic(const KvmGicParams *p);
16710859Sandreas.sandberg@arm.com    ~KvmGic();
16810859Sandreas.sandberg@arm.com
16911168Sandreas.hansson@arm.com    void startup() override { verifyMemoryMode(); }
17011168Sandreas.hansson@arm.com    void drainResume() override { verifyMemoryMode(); }
17110859Sandreas.sandberg@arm.com
17211168Sandreas.hansson@arm.com    void serialize(CheckpointOut &cp) const override;
17311461Sandreas.sandberg@arm.com    void unserialize(CheckpointIn &cp) override;
17410859Sandreas.sandberg@arm.com
17510859Sandreas.sandberg@arm.com  public: // PioDevice
17610859Sandreas.sandberg@arm.com    AddrRangeList getAddrRanges() const { return addrRanges; }
17711168Sandreas.hansson@arm.com    Tick read(PacketPtr pkt) override;
17811168Sandreas.hansson@arm.com    Tick write(PacketPtr pkt) override;
17910859Sandreas.sandberg@arm.com
18010859Sandreas.sandberg@arm.com  public: // BaseGic
18111168Sandreas.hansson@arm.com    void sendInt(uint32_t num) override;
18211168Sandreas.hansson@arm.com    void clearInt(uint32_t num) override;
18310859Sandreas.sandberg@arm.com
18411168Sandreas.hansson@arm.com    void sendPPInt(uint32_t num, uint32_t cpu) override;
18511168Sandreas.hansson@arm.com    void clearPPInt(uint32_t num, uint32_t cpu) override;
18610859Sandreas.sandberg@arm.com
18710859Sandreas.sandberg@arm.com  protected:
18810859Sandreas.sandberg@arm.com    /**
18910859Sandreas.sandberg@arm.com     * Do memory mode sanity checks
19010859Sandreas.sandberg@arm.com     *
19110859Sandreas.sandberg@arm.com     * This method only really exists to warn users that try to switch
19210859Sandreas.sandberg@arm.com     * to a simulate CPU. There is no fool proof method to detect
19310859Sandreas.sandberg@arm.com     * simulated CPUs, but checking that we're in atomic mode and
19410859Sandreas.sandberg@arm.com     * bypassing caches should be robust enough.
19510859Sandreas.sandberg@arm.com     */
19610859Sandreas.sandberg@arm.com    void verifyMemoryMode() const;
19710859Sandreas.sandberg@arm.com
19810859Sandreas.sandberg@arm.com    /** System this interrupt controller belongs to */
19910859Sandreas.sandberg@arm.com    System &system;
20010859Sandreas.sandberg@arm.com
20111461Sandreas.sandberg@arm.com    /** Kernel GIC device */
20211461Sandreas.sandberg@arm.com    KvmKernelGicV2 kernelGic;
20311461Sandreas.sandberg@arm.com
20410859Sandreas.sandberg@arm.com    /** Union of all memory  */
20510859Sandreas.sandberg@arm.com    const AddrRangeList addrRanges;
20610859Sandreas.sandberg@arm.com};
20710859Sandreas.sandberg@arm.com
20810859Sandreas.sandberg@arm.com#endif // __ARCH_ARM_KVM_GIC_HH__
209