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, &reg);
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, &reg);
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