vgic.hh revision 12132
1955SN/A/*
2955SN/A * Copyright (c) 2013 ARM Limited
31762SN/A * All rights reserved
4955SN/A *
5955SN/A * The license below extends only to copyright in the software and shall
6955SN/A * not be construed as granting a license to any other intellectual
7955SN/A * property including but not limited to intellectual property relating
8955SN/A * to a hardware implementation of the functionality of the software
9955SN/A * licensed hereunder.  You may use the software subject to the license
10955SN/A * terms below provided that you ensure that this notice is replicated
11955SN/A * unmodified and in its entirety in all distributions of the software,
12955SN/A * modified or unmodified, in source code or in binary form.
13955SN/A *
14955SN/A * Redistribution and use in source and binary forms, with or without
15955SN/A * modification, are permitted provided that the following conditions are
16955SN/A * met: redistributions of source code must retain the above copyright
17955SN/A * notice, this list of conditions and the following disclaimer;
18955SN/A * redistributions in binary form must reproduce the above copyright
19955SN/A * notice, this list of conditions and the following disclaimer in the
20955SN/A * documentation and/or other materials provided with the distribution;
21955SN/A * neither the name of the copyright holders nor the names of its
22955SN/A * contributors may be used to endorse or promote products derived from
23955SN/A * this software without specific prior written permission.
24955SN/A *
25955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
294762Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
315522Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
326143Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
334762Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
345522Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
365522Snate@binkert.org *
37955SN/A * Authors: Matt Evans
385522Snate@binkert.org */
394202Sbinkertn@umich.edu
405742Snate@binkert.org
41955SN/A/** @file
424381Sbinkertn@umich.edu * Implementiation of a GIC-400 List Register-based VGIC interface.
434381Sbinkertn@umich.edu * The VGIC is, in this implementation, completely separate from the GIC itself.
448334Snate@binkert.org * Only a VIRQ line to the CPU and a PPI line to the GIC (for a HV maintenance IRQ)
45955SN/A * is required.
46955SN/A *
474202Sbinkertn@umich.edu * The mode in which the List Registers may flag (via LR.HW) that a hardware EOI
48955SN/A * is to be performed is NOT supported.  (This requires tighter integration with
494382Sbinkertn@umich.edu * the GIC.)
504382Sbinkertn@umich.edu */
514382Sbinkertn@umich.edu
526654Snate@binkert.org#ifndef __DEV_ARM_VGIC_H__
535517Snate@binkert.org#define __DEV_ARM_VGIC_H__
548614Sgblack@eecs.umich.edu
557674Snate@binkert.org#include <algorithm>
566143Snate@binkert.org#include <array>
576143Snate@binkert.org
586143Snate@binkert.org#include "base/addr_range.hh"
598233Snate@binkert.org#include "base/bitunion.hh"
608233Snate@binkert.org#include "cpu/intr_control.hh"
618233Snate@binkert.org#include "dev/io_device.hh"
628233Snate@binkert.org#include "dev/platform.hh"
638233Snate@binkert.org#include "params/VGic.hh"
648334Snate@binkert.org
658334Snate@binkert.orgclass VGic : public PioDevice
6610453SAndrew.Bardsley@arm.com{
6710453SAndrew.Bardsley@arm.com  private:
688233Snate@binkert.org    static const int VGIC_CPU_MAX       = 256;
698233Snate@binkert.org    static const int NUM_LR             = 4;
708233Snate@binkert.org
718233Snate@binkert.org    static const int GICH_SIZE          = 0x200;
728233Snate@binkert.org    static const int GICH_REG_SIZE      = 0x2000;
738233Snate@binkert.org
746143Snate@binkert.org    static const int GICH_HCR           = 0x000;
758233Snate@binkert.org    static const int GICH_VTR           = 0x004;
768233Snate@binkert.org    static const int GICH_VMCR          = 0x008;
778233Snate@binkert.org    static const int GICH_MISR          = 0x010;
786143Snate@binkert.org    static const int GICH_EISR0         = 0x020;
796143Snate@binkert.org    static const int GICH_EISR1         = 0x024;
806143Snate@binkert.org    static const int GICH_ELSR0         = 0x030;
816143Snate@binkert.org    static const int GICH_ELSR1         = 0x034;
828233Snate@binkert.org    static const int GICH_APR0          = 0x0f0;
838233Snate@binkert.org    static const int GICH_LR0           = 0x100;
848233Snate@binkert.org    static const int GICH_LR1           = 0x104;
856143Snate@binkert.org    static const int GICH_LR2           = 0x108;
868233Snate@binkert.org    static const int GICH_LR3           = 0x10c;
878233Snate@binkert.org
888233Snate@binkert.org    static const int GICV_SIZE          = 0x2000;
898233Snate@binkert.org    static const int GICV_CTLR          = 0x000;
906143Snate@binkert.org    static const int GICV_PMR           = 0x004;
916143Snate@binkert.org    static const int GICV_BPR           = 0x008;
926143Snate@binkert.org    static const int GICV_IAR           = 0x00c;
934762Snate@binkert.org    static const int GICV_EOIR          = 0x010;
946143Snate@binkert.org    static const int GICV_RPR           = 0x014;
958233Snate@binkert.org    static const int GICV_HPPIR         = 0x018;
968233Snate@binkert.org    static const int GICV_ABPR          = 0x01c;
978233Snate@binkert.org    static const int GICV_AIAR          = 0x020;
988233Snate@binkert.org    static const int GICV_AEOIR         = 0x024;
998233Snate@binkert.org    static const int GICV_AHPPIR        = 0x028;
1006143Snate@binkert.org    static const int GICV_APR0          = 0x0d0;
1018233Snate@binkert.org    static const int GICV_IIDR          = 0x0fc;
1028233Snate@binkert.org    static const int GICV_DIR           = 0x1000;
1038233Snate@binkert.org
1048233Snate@binkert.org    static const uint32_t LR_PENDING    = 1;
1056143Snate@binkert.org    static const uint32_t LR_ACTIVE     = 2;
1066143Snate@binkert.org
1076143Snate@binkert.org    /** Post interrupt to CPU */
1086143Snate@binkert.org    void processPostVIntEvent(uint32_t cpu);
1096143Snate@binkert.org
1106143Snate@binkert.org    EventFunctionWrapper *postVIntEvent[VGIC_CPU_MAX];
1116143Snate@binkert.org    bool        maintIntPosted[VGIC_CPU_MAX];
1126143Snate@binkert.org    bool        vIntPosted[VGIC_CPU_MAX];
1136143Snate@binkert.org
1147065Snate@binkert.org    Platform *platform;
1156143Snate@binkert.org    BaseGic *gic;
1168233Snate@binkert.org
1178233Snate@binkert.org    Addr vcpuAddr;
1188233Snate@binkert.org    Addr hvAddr;
1198233Snate@binkert.org    Tick pioDelay;
1208233Snate@binkert.org    int maintInt;
1218233Snate@binkert.org
1228233Snate@binkert.org    BitUnion32(ListReg)
1238233Snate@binkert.org    Bitfield<31> HW;
1248233Snate@binkert.org    Bitfield<30> Grp1;
1258233Snate@binkert.org    Bitfield<29,28> State;
1268233Snate@binkert.org    Bitfield<27,23> Priority;
1278233Snate@binkert.org    Bitfield<19> EOI;
1288233Snate@binkert.org    Bitfield<12,10> CpuID;
1298233Snate@binkert.org    Bitfield<9,0> VirtualID;
1308233Snate@binkert.org    EndBitUnion(ListReg)
1318233Snate@binkert.org
1328233Snate@binkert.org    BitUnion32(HCR)
1338233Snate@binkert.org    Bitfield<31,27> EOICount;
1348233Snate@binkert.org    Bitfield<7> VGrp1DIE;
1358233Snate@binkert.org    Bitfield<6> VGrp1EIE;
1368233Snate@binkert.org    Bitfield<5> VGrp0DIE;
1378233Snate@binkert.org    Bitfield<4> VGrp0EIE;
1388233Snate@binkert.org    Bitfield<3> NPIE;
1398233Snate@binkert.org    Bitfield<2> LRENPIE;
1408233Snate@binkert.org    Bitfield<1> UIE;
1418233Snate@binkert.org    Bitfield<0> En;
1428233Snate@binkert.org    EndBitUnion(HCR)
1438233Snate@binkert.org
1448233Snate@binkert.org    BitUnion32(VCTLR)
1458233Snate@binkert.org    Bitfield<9> EOImode;
1468233Snate@binkert.org    Bitfield<4> CPBR;
1476143Snate@binkert.org    Bitfield<3> FIQEn;
1486143Snate@binkert.org    Bitfield<2> AckCtl;
1496143Snate@binkert.org    Bitfield<1> EnGrp1;
1506143Snate@binkert.org    Bitfield<0> En;     // This gets written to enable, not group 1.
1516143Snate@binkert.org    EndBitUnion(VCTLR)
1526143Snate@binkert.org
1539982Satgutier@umich.edu    /* State per CPU.  EVERYTHING should be in this struct and simply replicated
15410196SCurtis.Dunham@arm.com     * N times.
15510196SCurtis.Dunham@arm.com     */
15610196SCurtis.Dunham@arm.com    struct vcpuIntData : public Serializable {
15710196SCurtis.Dunham@arm.com        vcpuIntData()
15810196SCurtis.Dunham@arm.com            : vctrl(0), hcr(0), eisr(0), VMGrp0En(0), VMGrp1En(0),
15910196SCurtis.Dunham@arm.com              VMAckCtl(0), VMFiqEn(0), VMCBPR(0), VEM(0), VMABP(0), VMBP(0),
16010196SCurtis.Dunham@arm.com              VMPriMask(0)
16110196SCurtis.Dunham@arm.com        {
1626143Snate@binkert.org            std::fill(LR.begin(), LR.end(), 0);
1636143Snate@binkert.org        }
1648945Ssteve.reinhardt@amd.com        virtual ~vcpuIntData() {}
1658233Snate@binkert.org
1668233Snate@binkert.org        std::array<ListReg, NUM_LR> LR;
1676143Snate@binkert.org        VCTLR vctrl;
1688945Ssteve.reinhardt@amd.com
1696143Snate@binkert.org        HCR hcr;
1706143Snate@binkert.org        uint64_t eisr;
1716143Snate@binkert.org
1726143Snate@binkert.org        /* Host info, guest info (should be 100% accessible via GICH_* regs!) */
1735522Snate@binkert.org        uint8_t VMGrp0En;
1746143Snate@binkert.org        uint8_t VMGrp1En;
1756143Snate@binkert.org        uint8_t VMAckCtl;
1766143Snate@binkert.org        uint8_t VMFiqEn;
1779982Satgutier@umich.edu        uint8_t VMCBPR;
1788233Snate@binkert.org        uint8_t VEM;
1798233Snate@binkert.org        uint8_t VMABP;
1808233Snate@binkert.org        uint8_t VMBP;
1816143Snate@binkert.org        uint8_t VMPriMask;
1826143Snate@binkert.org
1836143Snate@binkert.org        void serialize(CheckpointOut &cp) const override;
1846143Snate@binkert.org        void unserialize(CheckpointIn &cp) override;
1855522Snate@binkert.org    };
1865522Snate@binkert.org
1875522Snate@binkert.org    struct std::array<vcpuIntData, VGIC_CPU_MAX>  vcpuData;
1885522Snate@binkert.org
1895604Snate@binkert.org  public:
1905604Snate@binkert.org   typedef VGicParams Params;
1916143Snate@binkert.org   const Params *
1926143Snate@binkert.org    params() const
1934762Snate@binkert.org    {
1944762Snate@binkert.org        return dynamic_cast<const Params *>(_params);
1956143Snate@binkert.org    }
1966727Ssteve.reinhardt@amd.com    VGic(const Params *p);
1976727Ssteve.reinhardt@amd.com    ~VGic();
1986727Ssteve.reinhardt@amd.com
1994762Snate@binkert.org    AddrRangeList getAddrRanges() const override;
2006143Snate@binkert.org
2016143Snate@binkert.org    Tick read(PacketPtr pkt) override;
2026143Snate@binkert.org    Tick write(PacketPtr pkt) override;
2036143Snate@binkert.org
2046727Ssteve.reinhardt@amd.com    void serialize(CheckpointOut &cp) const override;
2056143Snate@binkert.org    void unserialize(CheckpointIn &cp) override;
2067674Snate@binkert.org
2077674Snate@binkert.org  private:
2085604Snate@binkert.org    Tick readVCpu(PacketPtr pkt);
2096143Snate@binkert.org    Tick readCtrl(PacketPtr pkt);
2106143Snate@binkert.org
2116143Snate@binkert.org    Tick writeVCpu(PacketPtr pkt);
2124762Snate@binkert.org    Tick writeCtrl(PacketPtr pkt);
2136143Snate@binkert.org
2144762Snate@binkert.org    void updateIntState(ContextID ctx_id);
2154762Snate@binkert.org    uint32_t getMISR(struct vcpuIntData *vid);
2164762Snate@binkert.org    void postVInt(uint32_t cpu, Tick when);
2176143Snate@binkert.org    void unPostVInt(uint32_t cpu);
2186143Snate@binkert.org    void postMaintInt(uint32_t cpu);
2194762Snate@binkert.org    void unPostMaintInt(uint32_t cpu);
2208233Snate@binkert.org
2218233Snate@binkert.org    unsigned int lrPending(struct vcpuIntData *vid)
2228233Snate@binkert.org    {
2238233Snate@binkert.org        unsigned int pend = 0;
2246143Snate@binkert.org        for (int i = 0; i < NUM_LR; i++) {
2256143Snate@binkert.org            if (vid->LR[i].State & LR_PENDING)
2264762Snate@binkert.org                pend++;
2276143Snate@binkert.org        }
2284762Snate@binkert.org        return pend;
2296143Snate@binkert.org    }
2304762Snate@binkert.org    unsigned int lrValid(struct vcpuIntData *vid)
2316143Snate@binkert.org    {
2328233Snate@binkert.org        unsigned int valid = 0;
2338233Snate@binkert.org        for (int i = 0; i < NUM_LR; i++) {
23410453SAndrew.Bardsley@arm.com            if (vid->LR[i].State)
2356143Snate@binkert.org                valid++;
2366143Snate@binkert.org        }
2376143Snate@binkert.org        return valid;
2386143Snate@binkert.org    }
2396143Snate@binkert.org
2406143Snate@binkert.org    /** Returns LR index or -1 if none pending */
2416143Snate@binkert.org    int findHighestPendingLR(struct vcpuIntData *vid)
2426143Snate@binkert.org    {
24310453SAndrew.Bardsley@arm.com        unsigned int prio = 0xff;
24410453SAndrew.Bardsley@arm.com        int p = -1;
245955SN/A        for (int i = 0; i < NUM_LR; i++) {
2469396Sandreas.hansson@arm.com            if ((vid->LR[i].State & LR_PENDING) && (vid->LR[i].Priority < prio)) {
2479396Sandreas.hansson@arm.com                p = i;
2489396Sandreas.hansson@arm.com                prio = vid->LR[i].Priority;
2499396Sandreas.hansson@arm.com            }
2509396Sandreas.hansson@arm.com        }
2519396Sandreas.hansson@arm.com        return p;
2529396Sandreas.hansson@arm.com    }
2539396Sandreas.hansson@arm.com
2549396Sandreas.hansson@arm.com    int findLRForVIRQ(struct vcpuIntData *vid, int virq, int vcpu)
2559396Sandreas.hansson@arm.com    {
2569396Sandreas.hansson@arm.com        for (int i = 0; i < NUM_LR; i++) {
2579396Sandreas.hansson@arm.com            if (vid->LR[i].State &&
2589396Sandreas.hansson@arm.com                vid->LR[i].VirtualID == virq &&
2599930Sandreas.hansson@arm.com                vid->LR[i].CpuID == vcpu)
2609930Sandreas.hansson@arm.com                return i;
2619396Sandreas.hansson@arm.com        }
2628235Snate@binkert.org        return -1;
2638235Snate@binkert.org    }
2646143Snate@binkert.org};
2658235Snate@binkert.org
2669003SAli.Saidi@ARM.com#endif
2678235Snate@binkert.org