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