gic.cc revision 12184:3aabca509b7a
16019Shines@cs.fsu.edu/* 212528Schuan.zhu@arm.com * Copyright (c) 2015-2017 ARM Limited 37093Sgblack@eecs.umich.edu * All rights reserved 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67093Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77093Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87093Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97093Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107093Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117093Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127093Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137093Sgblack@eecs.umich.edu * 146019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without 156019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are 166019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright 176019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer; 186019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright 196019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the 206019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution; 216019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its 226019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from 236019Shines@cs.fsu.edu * this software without specific prior written permission. 246019Shines@cs.fsu.edu * 256019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 296019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 306019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366019Shines@cs.fsu.edu * 376019Shines@cs.fsu.edu * Authors: Andreas Sandberg 386019Shines@cs.fsu.edu * Curtis Dunham 396019Shines@cs.fsu.edu */ 407399SAli.Saidi@ARM.com 417399SAli.Saidi@ARM.com#include "arch/arm/kvm/gic.hh" 426019Shines@cs.fsu.edu 436019Shines@cs.fsu.edu#include <linux/kvm.h> 446019Shines@cs.fsu.edu 4510873Sandreas.sandberg@arm.com#include "arch/arm/kvm/base_cpu.hh" 4610873Sandreas.sandberg@arm.com#include "debug/GIC.hh" 4710474Sandreas.hansson@arm.com#include "debug/Interrupt.hh" 486019Shines@cs.fsu.edu#include "params/MuxingKvmGic.hh" 496019Shines@cs.fsu.edu 506019Shines@cs.fsu.eduKvmKernelGicV2::KvmKernelGicV2(KvmVM &_vm, Addr cpu_addr, Addr dist_addr, 516116Snate@binkert.org unsigned it_lines) 526019Shines@cs.fsu.edu : cpuRange(RangeSize(cpu_addr, KVM_VGIC_V2_CPU_SIZE)), 5311793Sbrandon.potter@amd.com distRange(RangeSize(dist_addr, KVM_VGIC_V2_DIST_SIZE)), 5411793Sbrandon.potter@amd.com vm(_vm), 558782Sgblack@eecs.umich.edu kdev(vm.createDevice(KVM_DEV_TYPE_ARM_VGIC_V2)) 568756Sgblack@eecs.umich.edu{ 576019Shines@cs.fsu.edu // Tell the VM that we will emulate the GIC in the kernel. This 5812005Sandreas.sandberg@arm.com // disables IRQ and FIQ handling in the KVM CPU model. 596019Shines@cs.fsu.edu vm.enableKernelIRQChip(); 606019Shines@cs.fsu.edu 616019Shines@cs.fsu.edu kdev.setAttr<uint64_t>( 6210024Sdam.sunwoo@arm.com KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST, dist_addr); 636019Shines@cs.fsu.edu kdev.setAttr<uint64_t>( 648232Snate@binkert.org KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_CPU, cpu_addr); 658232Snate@binkert.org 668232Snate@binkert.org kdev.setAttr<uint32_t>(KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0, it_lines); 676116Snate@binkert.org} 6811608Snikos.nikoleris@arm.com 696116Snate@binkert.orgKvmKernelGicV2::~KvmKernelGicV2() 708756Sgblack@eecs.umich.edu{ 716019Shines@cs.fsu.edu} 726019Shines@cs.fsu.edu 736019Shines@cs.fsu.eduvoid 746019Shines@cs.fsu.eduKvmKernelGicV2::setSPI(unsigned spi) 756019Shines@cs.fsu.edu{ 7610037SARM gem5 Developers setIntState(KVM_ARM_IRQ_TYPE_SPI, 0, spi, true); 7710037SARM gem5 Developers} 7813374Sanouk.vanlaer@arm.com 7910418Sandreas.hansson@arm.comvoid 8011395Sandreas.sandberg@arm.comKvmKernelGicV2::clearSPI(unsigned spi) 8110537Sandreas.hansson@arm.com{ 8213453Srekai.gonzalezalberquilla@arm.com setIntState(KVM_ARM_IRQ_TYPE_SPI, 0, spi, false); 8311152Smitch.hayenga@arm.com} 846019Shines@cs.fsu.edu 8512005Sandreas.sandberg@arm.comvoid 8612005Sandreas.sandberg@arm.comKvmKernelGicV2::setPPI(unsigned vcpu, unsigned ppi) 8710037SARM gem5 Developers{ 887399SAli.Saidi@ARM.com setIntState(KVM_ARM_IRQ_TYPE_PPI, vcpu, ppi, true); 8910037SARM gem5 Developers} 9010037SARM gem5 Developers 9110037SARM gem5 Developersvoid 9210037SARM gem5 DevelopersKvmKernelGicV2::clearPPI(unsigned vcpu, unsigned ppi) 9312005Sandreas.sandberg@arm.com{ 9412005Sandreas.sandberg@arm.com setIntState(KVM_ARM_IRQ_TYPE_PPI, vcpu, ppi, false); 9512005Sandreas.sandberg@arm.com} 966019Shines@cs.fsu.edu 976019Shines@cs.fsu.eduvoid 986019Shines@cs.fsu.eduKvmKernelGicV2::setIntState(unsigned type, unsigned vcpu, unsigned irq, 996019Shines@cs.fsu.edu bool high) 10010037SARM gem5 Developers{ 10110037SARM gem5 Developers assert(type <= KVM_ARM_IRQ_TYPE_MASK); 10210037SARM gem5 Developers assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK); 10310037SARM gem5 Developers assert(irq <= KVM_ARM_IRQ_NUM_MASK); 10410037SARM gem5 Developers const uint32_t line( 10510037SARM gem5 Developers (type << KVM_ARM_IRQ_TYPE_SHIFT) | 10610037SARM gem5 Developers (vcpu << KVM_ARM_IRQ_VCPU_SHIFT) | 10710037SARM gem5 Developers (irq << KVM_ARM_IRQ_NUM_SHIFT)); 10810037SARM gem5 Developers 10910037SARM gem5 Developers vm.setIRQLine(line, high); 11010037SARM gem5 Developers} 11110717Sandreas.hansson@arm.com 11210037SARM gem5 Developersuint32_t 11310037SARM gem5 DevelopersKvmKernelGicV2::getGicReg(unsigned group, unsigned vcpu, unsigned offset) 11410717Sandreas.hansson@arm.com{ 1156019Shines@cs.fsu.edu uint64_t reg; 1166019Shines@cs.fsu.edu 1177694SAli.Saidi@ARM.com assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK); 1187694SAli.Saidi@ARM.com const uint32_t attr( 1197694SAli.Saidi@ARM.com (vcpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) | 12010037SARM gem5 Developers (offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)); 12110037SARM gem5 Developers 12210037SARM gem5 Developers kdev.getAttrPtr(group, attr, ®); 12310037SARM gem5 Developers return (uint32_t) reg; 12410037SARM gem5 Developers} 12510037SARM gem5 Developers 12610037SARM gem5 Developersvoid 12710037SARM gem5 DevelopersKvmKernelGicV2::setGicReg(unsigned group, unsigned vcpu, unsigned offset, 12810037SARM gem5 Developers unsigned value) 1297694SAli.Saidi@ARM.com{ 1307694SAli.Saidi@ARM.com uint64_t reg = value; 1317694SAli.Saidi@ARM.com 1327694SAli.Saidi@ARM.com assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK); 1337694SAli.Saidi@ARM.com const uint32_t attr( 1347694SAli.Saidi@ARM.com (vcpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) | 1359738Sandreas@sandberg.pp.se (offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)); 13612749Sgiacomo.travaglini@arm.com 13712749Sgiacomo.travaglini@arm.com kdev.setAttrPtr(group, attr, ®); 1389738Sandreas@sandberg.pp.se} 13912005Sandreas.sandberg@arm.com 14012005Sandreas.sandberg@arm.comuint32_t 14112005Sandreas.sandberg@arm.comKvmKernelGicV2::readDistributor(ContextID ctx, Addr daddr) 14212005Sandreas.sandberg@arm.com{ 14312005Sandreas.sandberg@arm.com auto vcpu = vm.contextIdToVCpuId(ctx); 14412005Sandreas.sandberg@arm.com return getGicReg(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, vcpu, daddr); 14512005Sandreas.sandberg@arm.com} 14612005Sandreas.sandberg@arm.com 14712005Sandreas.sandberg@arm.comuint32_t 1489738Sandreas@sandberg.pp.seKvmKernelGicV2::readCpu(ContextID ctx, Addr daddr) 1499738Sandreas@sandberg.pp.se{ 1509738Sandreas@sandberg.pp.se auto vcpu = vm.contextIdToVCpuId(ctx); 1517404SAli.Saidi@ARM.com return getGicReg(KVM_DEV_ARM_VGIC_GRP_CPU_REGS, vcpu, daddr); 15210037SARM gem5 Developers} 15310037SARM gem5 Developers 1546019Shines@cs.fsu.eduvoid 1557404SAli.Saidi@ARM.comKvmKernelGicV2::writeDistributor(ContextID ctx, Addr daddr, uint32_t data) 1567404SAli.Saidi@ARM.com{ 1577404SAli.Saidi@ARM.com auto vcpu = vm.contextIdToVCpuId(ctx); 15810037SARM gem5 Developers setGicReg(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, vcpu, daddr, data); 1597404SAli.Saidi@ARM.com} 1607404SAli.Saidi@ARM.com 16110037SARM gem5 Developersvoid 16210037SARM gem5 DevelopersKvmKernelGicV2::writeCpu(ContextID ctx, Addr daddr, uint32_t data) 16310037SARM gem5 Developers{ 16410037SARM gem5 Developers auto vcpu = vm.contextIdToVCpuId(ctx); 16510037SARM gem5 Developers setGicReg(KVM_DEV_ARM_VGIC_GRP_CPU_REGS, vcpu, daddr, data); 1669535Smrinmoy.ghosh@arm.com} 1677697SAli.Saidi@ARM.com 16811321Ssteve.reinhardt@amd.com 16910037SARM gem5 Developers 1707697SAli.Saidi@ARM.comMuxingKvmGic::MuxingKvmGic(const MuxingKvmGicParams *p) 1717697SAli.Saidi@ARM.com : Pl390(p), 1727697SAli.Saidi@ARM.com system(*p->system), 1737697SAli.Saidi@ARM.com kernelGic(nullptr), 1747697SAli.Saidi@ARM.com usingKvm(false) 1757404SAli.Saidi@ARM.com{ 1767404SAli.Saidi@ARM.com if (auto vm = system.getKvmVM()) { 17710037SARM gem5 Developers kernelGic = new KvmKernelGicV2(*vm, p->cpu_addr, p->dist_addr, 1787404SAli.Saidi@ARM.com p->it_lines); 1797404SAli.Saidi@ARM.com } 18010037SARM gem5 Developers} 18110037SARM gem5 Developers 18210037SARM gem5 DevelopersMuxingKvmGic::~MuxingKvmGic() 18310037SARM gem5 Developers{ 18410037SARM gem5 Developers} 18510037SARM gem5 Developers 18610037SARM gem5 Developersvoid 18710037SARM gem5 DevelopersMuxingKvmGic::startup() 18810367SAndrew.Bardsley@arm.com{ 18910037SARM gem5 Developers Pl390::startup(); 1907404SAli.Saidi@ARM.com usingKvm = (kernelGic != nullptr) && system.validKvmEnvironment(); 1916019Shines@cs.fsu.edu if (usingKvm) 1926019Shines@cs.fsu.edu fromPl390ToKvm(); 1936019Shines@cs.fsu.edu} 1946019Shines@cs.fsu.edu 1957404SAli.Saidi@ARM.comDrainState 1966019Shines@cs.fsu.eduMuxingKvmGic::drain() 1977404SAli.Saidi@ARM.com{ 19810037SARM gem5 Developers if (usingKvm) 19910037SARM gem5 Developers fromKvmToPl390(); 20010037SARM gem5 Developers return Pl390::drain(); 20110037SARM gem5 Developers} 20210037SARM gem5 Developers 20310037SARM gem5 Developersvoid 2047404SAli.Saidi@ARM.comMuxingKvmGic::drainResume() 20510037SARM gem5 Developers{ 20610037SARM gem5 Developers Pl390::drainResume(); 20710037SARM gem5 Developers bool use_kvm = (kernelGic != nullptr) && system.validKvmEnvironment(); 2087697SAli.Saidi@ARM.com if (use_kvm != usingKvm) { 20910037SARM gem5 Developers // Should only occur due to CPU switches 21010037SARM gem5 Developers if (use_kvm) // from simulation to KVM emulation 21110037SARM gem5 Developers fromPl390ToKvm(); 21210037SARM gem5 Developers // otherwise, drain() already sync'd the state back to the Pl390 2137404SAli.Saidi@ARM.com 2147697SAli.Saidi@ARM.com usingKvm = use_kvm; 2157404SAli.Saidi@ARM.com } 21610037SARM gem5 Developers} 21710037SARM gem5 Developers 2187697SAli.Saidi@ARM.comTick 2197734SAli.Saidi@ARM.comMuxingKvmGic::read(PacketPtr pkt) 2207734SAli.Saidi@ARM.com{ 22110463SAndreas.Sandberg@ARM.com if (!usingKvm) 2226019Shines@cs.fsu.edu return Pl390::read(pkt); 2236019Shines@cs.fsu.edu 2246019Shines@cs.fsu.edu panic("MuxingKvmGic: PIO from gem5 is currently unsupported\n"); 22510037SARM gem5 Developers} 2267404SAli.Saidi@ARM.com 2277404SAli.Saidi@ARM.comTick 2287404SAli.Saidi@ARM.comMuxingKvmGic::write(PacketPtr pkt) 2297404SAli.Saidi@ARM.com{ 2307404SAli.Saidi@ARM.com if (!usingKvm) 23110037SARM gem5 Developers return Pl390::write(pkt); 23210037SARM gem5 Developers 23310037SARM gem5 Developers panic("MuxingKvmGic: PIO from gem5 is currently unsupported\n"); 23410037SARM gem5 Developers} 2357404SAli.Saidi@ARM.com 2367404SAli.Saidi@ARM.comvoid 2377404SAli.Saidi@ARM.comMuxingKvmGic::sendInt(uint32_t num) 2387404SAli.Saidi@ARM.com{ 23910037SARM gem5 Developers if (!usingKvm) 2406019Shines@cs.fsu.edu return Pl390::sendInt(num); 24110037SARM gem5 Developers 24210037SARM gem5 Developers DPRINTF(Interrupt, "Set SPI %d\n", num); 2437404SAli.Saidi@ARM.com kernelGic->setSPI(num); 2447404SAli.Saidi@ARM.com} 2457404SAli.Saidi@ARM.com 24610037SARM gem5 Developersvoid 24710037SARM gem5 DevelopersMuxingKvmGic::clearInt(uint32_t num) 24810037SARM gem5 Developers{ 24910037SARM gem5 Developers if (!usingKvm) 25010037SARM gem5 Developers return Pl390::clearInt(num); 25110037SARM gem5 Developers 25210037SARM gem5 Developers DPRINTF(Interrupt, "Clear SPI %d\n", num); 25310037SARM gem5 Developers kernelGic->clearSPI(num); 25410037SARM gem5 Developers} 25510037SARM gem5 Developers 2567404SAli.Saidi@ARM.comvoid 2577404SAli.Saidi@ARM.comMuxingKvmGic::sendPPInt(uint32_t num, uint32_t cpu) 25810037SARM gem5 Developers{ 25910037SARM gem5 Developers if (!usingKvm) 26010037SARM gem5 Developers return Pl390::sendPPInt(num, cpu); 26110037SARM gem5 Developers DPRINTF(Interrupt, "Set PPI %d:%d\n", cpu, num); 26210037SARM gem5 Developers kernelGic->setPPI(cpu, num); 26310037SARM gem5 Developers} 26410037SARM gem5 Developers 26510037SARM gem5 Developersvoid 26610037SARM gem5 DevelopersMuxingKvmGic::clearPPInt(uint32_t num, uint32_t cpu) 26710037SARM gem5 Developers{ 26810037SARM gem5 Developers if (!usingKvm) 26910037SARM gem5 Developers return Pl390::clearPPInt(num, cpu); 27010037SARM gem5 Developers 27110037SARM gem5 Developers DPRINTF(Interrupt, "Clear PPI %d:%d\n", cpu, num); 27210037SARM gem5 Developers kernelGic->clearPPI(cpu, num); 27310037SARM gem5 Developers} 27410037SARM gem5 Developers 27510037SARM gem5 Developersvoid 27610037SARM gem5 DevelopersMuxingKvmGic::updateIntState(int hint) 27710037SARM gem5 Developers{ 27810037SARM gem5 Developers // During Kvm->Pl390 state transfer, writes to the Pl390 will call 27910037SARM gem5 Developers // updateIntState() which can post an interrupt. Since we're only 28010037SARM gem5 Developers // using the Pl390 model for holding state in this circumstance, we 28110037SARM gem5 Developers // short-circuit this behavior, as the Pl390 is not actually active. 28210037SARM gem5 Developers if (!usingKvm) 28310037SARM gem5 Developers return Pl390::updateIntState(hint); 28410037SARM gem5 Developers} 2857734SAli.Saidi@ARM.com 2867734SAli.Saidi@ARM.comvoid 28710037SARM gem5 DevelopersMuxingKvmGic::copyDistRegister(BaseGicRegisters* from, BaseGicRegisters* to, 28810037SARM gem5 Developers ContextID ctx, Addr daddr) 28910037SARM gem5 Developers{ 29010037SARM gem5 Developers auto val = from->readDistributor(ctx, daddr); 29110037SARM gem5 Developers DPRINTF(GIC, "copy dist 0x%x 0x%08x\n", daddr, val); 2926019Shines@cs.fsu.edu to->writeDistributor(ctx, daddr, val); 2936019Shines@cs.fsu.edu} 2947404SAli.Saidi@ARM.com 29510037SARM gem5 Developersvoid 2967404SAli.Saidi@ARM.comMuxingKvmGic::copyCpuRegister(BaseGicRegisters* from, BaseGicRegisters* to, 29710037SARM gem5 Developers ContextID ctx, Addr daddr) 29810037SARM gem5 Developers{ 29910037SARM gem5 Developers auto val = from->readCpu(ctx, daddr); 30010037SARM gem5 Developers DPRINTF(GIC, "copy cpu 0x%x 0x%08x\n", daddr, val); 3017734SAli.Saidi@ARM.com to->writeCpu(ctx, daddr, val); 3027404SAli.Saidi@ARM.com} 3037404SAli.Saidi@ARM.com 3047404SAli.Saidi@ARM.comvoid 30510037SARM gem5 DevelopersMuxingKvmGic::copyBankedDistRange(BaseGicRegisters* from, BaseGicRegisters* to, 3067404SAli.Saidi@ARM.com Addr daddr, size_t size) 30710037SARM gem5 Developers{ 30810037SARM gem5 Developers for (int ctx = 0; ctx < system._numContexts; ++ctx) 3097404SAli.Saidi@ARM.com for (auto a = daddr; a < daddr + size; a += 4) 31010037SARM gem5 Developers copyDistRegister(from, to, ctx, a); 3117404SAli.Saidi@ARM.com} 3127404SAli.Saidi@ARM.com 3137404SAli.Saidi@ARM.comvoid 3147404SAli.Saidi@ARM.comMuxingKvmGic::clearBankedDistRange(BaseGicRegisters* to, 31510037SARM gem5 Developers Addr daddr, size_t size) 31610037SARM gem5 Developers{ 31710037SARM gem5 Developers for (int ctx = 0; ctx < system._numContexts; ++ctx) 31810037SARM gem5 Developers for (auto a = daddr; a < daddr + size; a += 4) 3197404SAli.Saidi@ARM.com to->writeDistributor(ctx, a, 0xFFFFFFFF); 32010037SARM gem5 Developers} 3217734SAli.Saidi@ARM.com 3227404SAli.Saidi@ARM.comvoid 32310037SARM gem5 DevelopersMuxingKvmGic::copyDistRange(BaseGicRegisters* from, BaseGicRegisters* to, 3247404SAli.Saidi@ARM.com Addr daddr, size_t size) 3257734SAli.Saidi@ARM.com{ 3267404SAli.Saidi@ARM.com for (auto a = daddr; a < daddr + size; a += 4) 3277404SAli.Saidi@ARM.com copyDistRegister(from, to, 0, a); 3287404SAli.Saidi@ARM.com} 32910037SARM gem5 Developers 3307404SAli.Saidi@ARM.comvoid 33110037SARM gem5 DevelopersMuxingKvmGic::clearDistRange(BaseGicRegisters* to, 33210037SARM gem5 Developers Addr daddr, size_t size) 33310037SARM gem5 Developers{ 33410037SARM gem5 Developers for (auto a = daddr; a < daddr + size; a += 4) 33510037SARM gem5 Developers to->writeDistributor(0, a, 0xFFFFFFFF); 3367404SAli.Saidi@ARM.com} 33710037SARM gem5 Developers 33810037SARM gem5 Developersvoid 33910037SARM gem5 DevelopersMuxingKvmGic::copyGicState(BaseGicRegisters* from, BaseGicRegisters* to) 34010037SARM gem5 Developers{ 3417404SAli.Saidi@ARM.com Addr set, clear; 34210037SARM gem5 Developers size_t size; 34310037SARM gem5 Developers 34410037SARM gem5 Developers /// CPU state (GICC_*) 34510037SARM gem5 Developers // Copy CPU Interface Control Register (CTLR), 34610037SARM gem5 Developers // Interrupt Priority Mask Register (PMR), and 34710037SARM gem5 Developers // Binary Point Register (BPR) 34810037SARM gem5 Developers for (int ctx = 0; ctx < system._numContexts; ++ctx) { 3497404SAli.Saidi@ARM.com copyCpuRegister(from, to, ctx, GICC_CTLR); 3507734SAli.Saidi@ARM.com copyCpuRegister(from, to, ctx, GICC_PMR); 3517404SAli.Saidi@ARM.com copyCpuRegister(from, to, ctx, GICC_BPR); 35210037SARM gem5 Developers } 35310037SARM gem5 Developers 3547404SAli.Saidi@ARM.com 35510037SARM gem5 Developers /// Distributor state (GICD_*) 35610037SARM gem5 Developers // Copy Distributor Control Register (CTLR) 35711584SDylan.Johnson@ARM.com copyDistRegister(from, to, 0, GICD_CTLR); 35811584SDylan.Johnson@ARM.com 35911584SDylan.Johnson@ARM.com // Copy interrupt-enabled statuses (I[CS]ENABLERn; R0 is per-CPU banked) 36011584SDylan.Johnson@ARM.com set = Pl390::GICD_ISENABLER.start(); 36111584SDylan.Johnson@ARM.com clear = Pl390::GICD_ICENABLER.start(); 36211584SDylan.Johnson@ARM.com size = Pl390::itLines / 8; 36311584SDylan.Johnson@ARM.com clearBankedDistRange(to, clear, 4); 36410037SARM gem5 Developers copyBankedDistRange(from, to, set, 4); 36510037SARM gem5 Developers 36610037SARM gem5 Developers set += 4, clear += 4, size -= 4; 36710037SARM gem5 Developers clearDistRange(to, clear, size); 36810037SARM gem5 Developers copyDistRange(from, to, set, size); 36910037SARM gem5 Developers 37010037SARM gem5 Developers // Copy pending interrupts (I[CS]PENDRn; R0 is per-CPU banked) 37110037SARM gem5 Developers set = Pl390::GICD_ISPENDR.start(); 37210037SARM gem5 Developers clear = Pl390::GICD_ICPENDR.start(); 37310037SARM gem5 Developers size = Pl390::itLines / 8; 37410037SARM gem5 Developers clearBankedDistRange(to, clear, 4); 37510037SARM gem5 Developers copyBankedDistRange(from, to, set, 4); 3767404SAli.Saidi@ARM.com 3777404SAli.Saidi@ARM.com set += 4, clear += 4, size -= 4; 3786019Shines@cs.fsu.edu clearDistRange(to, clear, size); 3799439SAndreas.Sandberg@ARM.com copyDistRange(from, to, set, size); 3809439SAndreas.Sandberg@ARM.com 3819439SAndreas.Sandberg@ARM.com // Copy active interrupts (I[CS]ACTIVERn; R0 is per-CPU banked) 3829439SAndreas.Sandberg@ARM.com set = Pl390::GICD_ISACTIVER.start(); 3839439SAndreas.Sandberg@ARM.com clear = Pl390::GICD_ICACTIVER.start(); 3849439SAndreas.Sandberg@ARM.com size = Pl390::itLines / 8; 3859439SAndreas.Sandberg@ARM.com clearBankedDistRange(to, clear, 4); 3869439SAndreas.Sandberg@ARM.com copyBankedDistRange(from, to, set, 4); 38710194SGeoffrey.Blake@arm.com 38810194SGeoffrey.Blake@arm.com set += 4, clear += 4, size -= 4; 38910194SGeoffrey.Blake@arm.com clearDistRange(to, clear, size); 39010194SGeoffrey.Blake@arm.com copyDistRange(from, to, set, size); 39110194SGeoffrey.Blake@arm.com 39210194SGeoffrey.Blake@arm.com // Copy interrupt priorities (IPRIORITYRn; R0-7 are per-CPU banked) 39310194SGeoffrey.Blake@arm.com set = Pl390::GICD_IPRIORITYR.start(); 39410194SGeoffrey.Blake@arm.com copyBankedDistRange(from, to, set, 32); 39510194SGeoffrey.Blake@arm.com 39613374Sanouk.vanlaer@arm.com set += 32; 39710194SGeoffrey.Blake@arm.com size = Pl390::itLines - 32; 39810194SGeoffrey.Blake@arm.com copyDistRange(from, to, set, size); 39910194SGeoffrey.Blake@arm.com 40010194SGeoffrey.Blake@arm.com // Copy interrupt processor target regs (ITARGETRn; R0-7 are read-only) 40110194SGeoffrey.Blake@arm.com set = Pl390::GICD_ITARGETSR.start() + 32; 40210194SGeoffrey.Blake@arm.com size = Pl390::itLines - 32; 40310194SGeoffrey.Blake@arm.com copyDistRange(from, to, set, size); 40410194SGeoffrey.Blake@arm.com 40510194SGeoffrey.Blake@arm.com // Copy interrupt configuration registers (ICFGRn) 40610194SGeoffrey.Blake@arm.com set = Pl390::GICD_ICFGR.start(); 40710194SGeoffrey.Blake@arm.com size = Pl390::itLines / 4; 40810194SGeoffrey.Blake@arm.com copyDistRange(from, to, set, size); 40910194SGeoffrey.Blake@arm.com} 41010194SGeoffrey.Blake@arm.com 41110905Sandreas.sandberg@arm.comvoid 4126019Shines@cs.fsu.eduMuxingKvmGic::fromPl390ToKvm() 4137733SAli.Saidi@ARM.com{ 4147733SAli.Saidi@ARM.com copyGicState(static_cast<Pl390*>(this), kernelGic); 4157733SAli.Saidi@ARM.com} 41610037SARM gem5 Developers 41710037SARM gem5 Developersvoid 41810037SARM gem5 DevelopersMuxingKvmGic::fromKvmToPl390() 41913374Sanouk.vanlaer@arm.com{ 4208353SAli.Saidi@ARM.com copyGicState(kernelGic, static_cast<Pl390*>(this)); 4218353SAli.Saidi@ARM.com 4228353SAli.Saidi@ARM.com // the values read for the Interrupt Priority Mask Register (PMR) 42311321Ssteve.reinhardt@amd.com // have been shifted by three bits due to its having been emulated by 42410905Sandreas.sandberg@arm.com // a VGIC with only 5 PMR bits in its VMCR register. Presently the 4256019Shines@cs.fsu.edu // Linux kernel does not repair this inaccuracy, so we correct it here. 4266019Shines@cs.fsu.edu for (int cpu = 0; cpu < system._numContexts; ++cpu) { 4276019Shines@cs.fsu.edu cpuPriority[cpu] <<= 3; 42810905Sandreas.sandberg@arm.com assert((cpuPriority[cpu] & ~0xff) == 0); 4296019Shines@cs.fsu.edu } 4307733SAli.Saidi@ARM.com} 4316019Shines@cs.fsu.edu 4327733SAli.Saidi@ARM.comMuxingKvmGic * 43310037SARM gem5 DevelopersMuxingKvmGicParams::create() 43410037SARM gem5 Developers{ 43510037SARM gem5 Developers return new MuxingKvmGic(this); 43613374Sanouk.vanlaer@arm.com} 43710037SARM gem5 Developers