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"
4713014Sciro.santilli@arm.com#include "dev/arm/gic_v2.hh"
4810859Sandreas.sandberg@arm.com#include "dev/platform.hh"
4910859Sandreas.sandberg@arm.com
5011461Sandreas.sandberg@arm.com/**
5111461Sandreas.sandberg@arm.com * KVM in-kernel GIC abstraction
5211461Sandreas.sandberg@arm.com *
5311461Sandreas.sandberg@arm.com * This class defines a high-level interface to the KVM in-kernel GIC
5411461Sandreas.sandberg@arm.com * model. It exposes an API that is similar to that of
5511461Sandreas.sandberg@arm.com * software-emulated GIC models in gem5.
5611461Sandreas.sandberg@arm.com */
5711943SCurtis.Dunham@arm.comclass KvmKernelGicV2 : public BaseGicRegisters
5811461Sandreas.sandberg@arm.com{
5911461Sandreas.sandberg@arm.com  public:
6011461Sandreas.sandberg@arm.com    /**
6111461Sandreas.sandberg@arm.com     * Instantiate a KVM in-kernel GIC model.
6211461Sandreas.sandberg@arm.com     *
6311461Sandreas.sandberg@arm.com     * This constructor instantiates an in-kernel GIC model and wires
6411461Sandreas.sandberg@arm.com     * it up to the virtual memory system.
6511461Sandreas.sandberg@arm.com     *
6611461Sandreas.sandberg@arm.com     * @param vm KVM VM representing this system
6711461Sandreas.sandberg@arm.com     * @param cpu_addr GIC CPU interface base address
6811461Sandreas.sandberg@arm.com     * @param dist_addr GIC distributor base address
6911838SCurtis.Dunham@arm.com     * @param it_lines Number of interrupt lines to support
7011461Sandreas.sandberg@arm.com     */
7111462Sandreas.sandberg@arm.com    KvmKernelGicV2(KvmVM &vm, Addr cpu_addr, Addr dist_addr,
7211462Sandreas.sandberg@arm.com                   unsigned it_lines);
7311461Sandreas.sandberg@arm.com    virtual ~KvmKernelGicV2();
7411461Sandreas.sandberg@arm.com
7511461Sandreas.sandberg@arm.com    KvmKernelGicV2(const KvmKernelGicV2 &other) = delete;
7611461Sandreas.sandberg@arm.com    KvmKernelGicV2(const KvmKernelGicV2 &&other) = delete;
7711461Sandreas.sandberg@arm.com    KvmKernelGicV2 &operator=(const KvmKernelGicV2 &&rhs) = delete;
7811461Sandreas.sandberg@arm.com    KvmKernelGicV2 &operator=(const KvmKernelGicV2 &rhs) = delete;
7911461Sandreas.sandberg@arm.com
8011461Sandreas.sandberg@arm.com  public:
8111461Sandreas.sandberg@arm.com    /**
8211461Sandreas.sandberg@arm.com     * @{
8311461Sandreas.sandberg@arm.com     * @name In-kernel GIC API
8411461Sandreas.sandberg@arm.com     */
8511461Sandreas.sandberg@arm.com
8611461Sandreas.sandberg@arm.com    /**
8711461Sandreas.sandberg@arm.com     * Raise a shared peripheral interrupt
8811461Sandreas.sandberg@arm.com     *
8911461Sandreas.sandberg@arm.com     * @param spi SPI number
9011461Sandreas.sandberg@arm.com     */
9111461Sandreas.sandberg@arm.com    void setSPI(unsigned spi);
9211461Sandreas.sandberg@arm.com    /**
9311461Sandreas.sandberg@arm.com     * Clear a shared peripheral interrupt
9411461Sandreas.sandberg@arm.com     *
9511461Sandreas.sandberg@arm.com     * @param spi SPI number
9611461Sandreas.sandberg@arm.com     */
9711461Sandreas.sandberg@arm.com    void clearSPI(unsigned spi);
9811461Sandreas.sandberg@arm.com
9911461Sandreas.sandberg@arm.com    /**
10011461Sandreas.sandberg@arm.com     * Raise a private peripheral interrupt
10111461Sandreas.sandberg@arm.com     *
10211461Sandreas.sandberg@arm.com     * @param vcpu KVM virtual CPU number
10311461Sandreas.sandberg@arm.com     * @parma ppi PPI interrupt number
10411461Sandreas.sandberg@arm.com     */
10511461Sandreas.sandberg@arm.com    void setPPI(unsigned vcpu, unsigned ppi);
10611461Sandreas.sandberg@arm.com
10711461Sandreas.sandberg@arm.com    /**
10811461Sandreas.sandberg@arm.com     * Clear a private peripheral interrupt
10911461Sandreas.sandberg@arm.com     *
11011461Sandreas.sandberg@arm.com     * @param vcpu KVM virtual CPU number
11111461Sandreas.sandberg@arm.com     * @parma ppi PPI interrupt number
11211461Sandreas.sandberg@arm.com     */
11311461Sandreas.sandberg@arm.com    void clearPPI(unsigned vcpu, unsigned ppi);
11411461Sandreas.sandberg@arm.com
11511461Sandreas.sandberg@arm.com    /** Address range for the CPU interfaces */
11611461Sandreas.sandberg@arm.com    const AddrRange cpuRange;
11711461Sandreas.sandberg@arm.com    /** Address range for the distributor interface */
11811461Sandreas.sandberg@arm.com    const AddrRange distRange;
11911461Sandreas.sandberg@arm.com
12011943SCurtis.Dunham@arm.com    /** BaseGicRegisters interface */
12111943SCurtis.Dunham@arm.com    uint32_t readDistributor(ContextID ctx, Addr daddr) override;
12211943SCurtis.Dunham@arm.com    uint32_t readCpu(ContextID ctx, Addr daddr) override;
12311943SCurtis.Dunham@arm.com
12411943SCurtis.Dunham@arm.com    void writeDistributor(ContextID ctx, Addr daddr,
12511943SCurtis.Dunham@arm.com                          uint32_t data) override;
12611943SCurtis.Dunham@arm.com    void writeCpu(ContextID ctx, Addr daddr, uint32_t data) override;
12711943SCurtis.Dunham@arm.com
12811461Sandreas.sandberg@arm.com    /* @} */
12911461Sandreas.sandberg@arm.com
13011461Sandreas.sandberg@arm.com  protected:
13111461Sandreas.sandberg@arm.com    /**
13211461Sandreas.sandberg@arm.com     * Update the kernel's VGIC interrupt state
13311461Sandreas.sandberg@arm.com     *
13411461Sandreas.sandberg@arm.com     * @param type Interrupt type (KVM_ARM_IRQ_TYPE_PPI/KVM_ARM_IRQ_TYPE_SPI)
13511461Sandreas.sandberg@arm.com     * @param vcpu CPU id within KVM (ignored for SPIs)
13611461Sandreas.sandberg@arm.com     * @param irq Interrupt number
13711461Sandreas.sandberg@arm.com     * @param high True to signal an interrupt, false to clear it.
13811461Sandreas.sandberg@arm.com     */
13911461Sandreas.sandberg@arm.com    void setIntState(unsigned type, unsigned vcpu, unsigned irq, bool high);
14011461Sandreas.sandberg@arm.com
14111943SCurtis.Dunham@arm.com    /**
14211943SCurtis.Dunham@arm.com     * Get value of GIC register "from" a cpu
14311943SCurtis.Dunham@arm.com     *
14411943SCurtis.Dunham@arm.com     * @param group Distributor or CPU (KVM_DEV_ARM_VGIC_GRP_{DIST,CPU}_REGS)
14511943SCurtis.Dunham@arm.com     * @param vcpu CPU id within KVM
14611943SCurtis.Dunham@arm.com     * @param offset register offset
14711943SCurtis.Dunham@arm.com     */
14811943SCurtis.Dunham@arm.com    uint32_t getGicReg(unsigned group, unsigned vcpu, unsigned offset);
14911943SCurtis.Dunham@arm.com
15011943SCurtis.Dunham@arm.com    /**
15111943SCurtis.Dunham@arm.com     * Set value of GIC register "from" a cpu
15211943SCurtis.Dunham@arm.com     *
15311943SCurtis.Dunham@arm.com     * @param group Distributor or CPU (KVM_DEV_ARM_VGIC_GRP_{DIST,CPU}_REGS)
15411943SCurtis.Dunham@arm.com     * @param vcpu CPU id within KVM
15511943SCurtis.Dunham@arm.com     * @param offset register offset
15611943SCurtis.Dunham@arm.com     * @param value value to set register to
15711943SCurtis.Dunham@arm.com     */
15811943SCurtis.Dunham@arm.com    void setGicReg(unsigned group, unsigned vcpu, unsigned offset,
15911943SCurtis.Dunham@arm.com                   unsigned value);
16011943SCurtis.Dunham@arm.com
16111461Sandreas.sandberg@arm.com    /** KVM VM in the parent system */
16211461Sandreas.sandberg@arm.com    KvmVM &vm;
16311461Sandreas.sandberg@arm.com
16411461Sandreas.sandberg@arm.com    /** Kernel interface to the GIC */
16511461Sandreas.sandberg@arm.com    KvmDevice kdev;
16611461Sandreas.sandberg@arm.com};
16711461Sandreas.sandberg@arm.com
16810859Sandreas.sandberg@arm.com
16911840SCurtis.Dunham@arm.comstruct MuxingKvmGicParams;
17011840SCurtis.Dunham@arm.com
17113014Sciro.santilli@arm.comclass MuxingKvmGic : public GicV2
17211840SCurtis.Dunham@arm.com{
17311840SCurtis.Dunham@arm.com  public: // SimObject / Serializable / Drainable
17411840SCurtis.Dunham@arm.com    MuxingKvmGic(const MuxingKvmGicParams *p);
17511840SCurtis.Dunham@arm.com    ~MuxingKvmGic();
17611840SCurtis.Dunham@arm.com
17711840SCurtis.Dunham@arm.com    void startup() override;
17811943SCurtis.Dunham@arm.com    DrainState drain() override;
17911840SCurtis.Dunham@arm.com    void drainResume() override;
18011840SCurtis.Dunham@arm.com
18111840SCurtis.Dunham@arm.com  public: // PioDevice
18211840SCurtis.Dunham@arm.com    Tick read(PacketPtr pkt) override;
18311840SCurtis.Dunham@arm.com    Tick write(PacketPtr pkt) override;
18411840SCurtis.Dunham@arm.com
18513014Sciro.santilli@arm.com  public: // GicV2
18611840SCurtis.Dunham@arm.com    void sendInt(uint32_t num) override;
18711840SCurtis.Dunham@arm.com    void clearInt(uint32_t num) override;
18811840SCurtis.Dunham@arm.com
18911840SCurtis.Dunham@arm.com    void sendPPInt(uint32_t num, uint32_t cpu) override;
19011840SCurtis.Dunham@arm.com    void clearPPInt(uint32_t num, uint32_t cpu) override;
19111840SCurtis.Dunham@arm.com
19213014Sciro.santilli@arm.com  protected: // GicV2
19312112SCurtis.Dunham@arm.com    void updateIntState(int hint) override;
19412112SCurtis.Dunham@arm.com
19511840SCurtis.Dunham@arm.com  protected:
19611840SCurtis.Dunham@arm.com    /** System this interrupt controller belongs to */
19711840SCurtis.Dunham@arm.com    System &system;
19811840SCurtis.Dunham@arm.com
19911840SCurtis.Dunham@arm.com    /** Kernel GIC device */
20011840SCurtis.Dunham@arm.com    KvmKernelGicV2 *kernelGic;
20111840SCurtis.Dunham@arm.com
20211840SCurtis.Dunham@arm.com  private:
20311840SCurtis.Dunham@arm.com    bool usingKvm;
20411840SCurtis.Dunham@arm.com
20511943SCurtis.Dunham@arm.com    /** Multiplexing implementation */
20613014Sciro.santilli@arm.com    void fromGicV2ToKvm();
20713014Sciro.santilli@arm.com    void fromKvmToGicV2();
20811943SCurtis.Dunham@arm.com
20911943SCurtis.Dunham@arm.com    void copyGicState(BaseGicRegisters* from, BaseGicRegisters* to);
21011943SCurtis.Dunham@arm.com
21111943SCurtis.Dunham@arm.com    void copyDistRegister(BaseGicRegisters* from, BaseGicRegisters* to,
21211943SCurtis.Dunham@arm.com                          ContextID ctx, Addr daddr);
21311943SCurtis.Dunham@arm.com    void copyCpuRegister(BaseGicRegisters* from, BaseGicRegisters* to,
21411943SCurtis.Dunham@arm.com                         ContextID ctx, Addr daddr);
21511943SCurtis.Dunham@arm.com
21611943SCurtis.Dunham@arm.com    void copyBankedDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
21711943SCurtis.Dunham@arm.com                             Addr daddr, size_t size);
21811943SCurtis.Dunham@arm.com    void clearBankedDistRange(BaseGicRegisters* to,
21911943SCurtis.Dunham@arm.com                              Addr daddr, size_t size);
22011943SCurtis.Dunham@arm.com    void copyDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
22111943SCurtis.Dunham@arm.com                       Addr daddr, size_t size);
22211943SCurtis.Dunham@arm.com    void clearDistRange(BaseGicRegisters* to,
22311943SCurtis.Dunham@arm.com                        Addr daddr, size_t size);
22411840SCurtis.Dunham@arm.com};
22511840SCurtis.Dunham@arm.com
22610859Sandreas.sandberg@arm.com#endif // __ARCH_ARM_KVM_GIC_HH__
227