gic.cc revision 11461
110859Sandreas.sandberg@arm.com/*
211461Sandreas.sandberg@arm.com * Copyright (c) 2015-2016 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
3810859Sandreas.sandberg@arm.com */
3910859Sandreas.sandberg@arm.com
4010859Sandreas.sandberg@arm.com#include "arch/arm/kvm/gic.hh"
4110859Sandreas.sandberg@arm.com
4210859Sandreas.sandberg@arm.com#include <linux/kvm.h>
4310859Sandreas.sandberg@arm.com
4410859Sandreas.sandberg@arm.com#include "debug/Interrupt.hh"
4510859Sandreas.sandberg@arm.com#include "params/KvmGic.hh"
4610859Sandreas.sandberg@arm.com
4711461Sandreas.sandberg@arm.com
4811461Sandreas.sandberg@arm.comKvmKernelGicV2::KvmKernelGicV2(KvmVM &_vm, Addr cpu_addr, Addr dist_addr)
4911461Sandreas.sandberg@arm.com    : cpuRange(RangeSize(cpu_addr, KVM_VGIC_V2_CPU_SIZE)),
5011461Sandreas.sandberg@arm.com      distRange(RangeSize(dist_addr, KVM_VGIC_V2_DIST_SIZE)),
5111461Sandreas.sandberg@arm.com      vm(_vm),
5211461Sandreas.sandberg@arm.com      kdev(vm.createDevice(KVM_DEV_TYPE_ARM_VGIC_V2))
5311461Sandreas.sandberg@arm.com{
5411461Sandreas.sandberg@arm.com    kdev.setAttr<uint64_t>(
5511461Sandreas.sandberg@arm.com        KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST, dist_addr);
5611461Sandreas.sandberg@arm.com    kdev.setAttr<uint64_t>(
5711461Sandreas.sandberg@arm.com        KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_CPU, cpu_addr);
5811461Sandreas.sandberg@arm.com}
5911461Sandreas.sandberg@arm.com
6011461Sandreas.sandberg@arm.comKvmKernelGicV2::~KvmKernelGicV2()
6111461Sandreas.sandberg@arm.com{
6211461Sandreas.sandberg@arm.com}
6311461Sandreas.sandberg@arm.com
6411461Sandreas.sandberg@arm.comvoid
6511461Sandreas.sandberg@arm.comKvmKernelGicV2::setSPI(unsigned spi)
6611461Sandreas.sandberg@arm.com{
6711461Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_SPI, 0, spi, true);
6811461Sandreas.sandberg@arm.com}
6911461Sandreas.sandberg@arm.com
7011461Sandreas.sandberg@arm.comvoid
7111461Sandreas.sandberg@arm.comKvmKernelGicV2::clearSPI(unsigned spi)
7211461Sandreas.sandberg@arm.com{
7311461Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_SPI, 0, spi, false);
7411461Sandreas.sandberg@arm.com}
7511461Sandreas.sandberg@arm.com
7611461Sandreas.sandberg@arm.comvoid
7711461Sandreas.sandberg@arm.comKvmKernelGicV2::setPPI(unsigned vcpu, unsigned ppi)
7811461Sandreas.sandberg@arm.com{
7911461Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_PPI, vcpu, ppi, true);
8011461Sandreas.sandberg@arm.com}
8111461Sandreas.sandberg@arm.com
8211461Sandreas.sandberg@arm.comvoid
8311461Sandreas.sandberg@arm.comKvmKernelGicV2::clearPPI(unsigned vcpu, unsigned ppi)
8411461Sandreas.sandberg@arm.com{
8511461Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_PPI, vcpu, ppi, false);
8611461Sandreas.sandberg@arm.com}
8711461Sandreas.sandberg@arm.com
8811461Sandreas.sandberg@arm.comvoid
8911461Sandreas.sandberg@arm.comKvmKernelGicV2::setIntState(unsigned type, unsigned vcpu, unsigned irq,
9011461Sandreas.sandberg@arm.com                            bool high)
9111461Sandreas.sandberg@arm.com{
9211461Sandreas.sandberg@arm.com    assert(type <= KVM_ARM_IRQ_TYPE_MASK);
9311461Sandreas.sandberg@arm.com    assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
9411461Sandreas.sandberg@arm.com    assert(irq <= KVM_ARM_IRQ_NUM_MASK);
9511461Sandreas.sandberg@arm.com    const uint32_t line(
9611461Sandreas.sandberg@arm.com        (type << KVM_ARM_IRQ_TYPE_SHIFT) |
9711461Sandreas.sandberg@arm.com        (vcpu << KVM_ARM_IRQ_VCPU_SHIFT) |
9811461Sandreas.sandberg@arm.com        (irq << KVM_ARM_IRQ_NUM_SHIFT));
9911461Sandreas.sandberg@arm.com
10011461Sandreas.sandberg@arm.com    vm.setIRQLine(line, high);
10111461Sandreas.sandberg@arm.com}
10211461Sandreas.sandberg@arm.com
10311461Sandreas.sandberg@arm.com
10410859Sandreas.sandberg@arm.comKvmGic::KvmGic(const KvmGicParams *p)
10510859Sandreas.sandberg@arm.com    : BaseGic(p),
10610859Sandreas.sandberg@arm.com      system(*p->system),
10711461Sandreas.sandberg@arm.com      kernelGic(*p->kvmVM, p->cpu_addr, p->dist_addr),
10811461Sandreas.sandberg@arm.com      addrRanges{kernelGic.distRange, kernelGic.cpuRange}
10910859Sandreas.sandberg@arm.com{
11010859Sandreas.sandberg@arm.com}
11110859Sandreas.sandberg@arm.com
11210859Sandreas.sandberg@arm.comKvmGic::~KvmGic()
11310859Sandreas.sandberg@arm.com{
11410859Sandreas.sandberg@arm.com}
11510859Sandreas.sandberg@arm.com
11610859Sandreas.sandberg@arm.comvoid
11710905Sandreas.sandberg@arm.comKvmGic::serialize(CheckpointOut &cp) const
11810859Sandreas.sandberg@arm.com{
11910859Sandreas.sandberg@arm.com    panic("Checkpointing unsupported\n");
12010859Sandreas.sandberg@arm.com}
12110859Sandreas.sandberg@arm.com
12210859Sandreas.sandberg@arm.comvoid
12310905Sandreas.sandberg@arm.comKvmGic::unserialize(CheckpointIn &cp)
12410859Sandreas.sandberg@arm.com{
12510859Sandreas.sandberg@arm.com    panic("Checkpointing unsupported\n");
12610859Sandreas.sandberg@arm.com}
12710859Sandreas.sandberg@arm.com
12810859Sandreas.sandberg@arm.comTick
12910859Sandreas.sandberg@arm.comKvmGic::read(PacketPtr pkt)
13010859Sandreas.sandberg@arm.com{
13110859Sandreas.sandberg@arm.com    panic("KvmGic: PIO from gem5 is currently unsupported\n");
13210859Sandreas.sandberg@arm.com}
13310859Sandreas.sandberg@arm.com
13410859Sandreas.sandberg@arm.comTick
13510859Sandreas.sandberg@arm.comKvmGic::write(PacketPtr pkt)
13610859Sandreas.sandberg@arm.com{
13710859Sandreas.sandberg@arm.com    panic("KvmGic: PIO from gem5 is currently unsupported\n");
13810859Sandreas.sandberg@arm.com}
13910859Sandreas.sandberg@arm.com
14010859Sandreas.sandberg@arm.comvoid
14110859Sandreas.sandberg@arm.comKvmGic::sendInt(uint32_t num)
14210859Sandreas.sandberg@arm.com{
14310859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Set SPI %d\n", num);
14411461Sandreas.sandberg@arm.com    kernelGic.setSPI(num);
14510859Sandreas.sandberg@arm.com}
14610859Sandreas.sandberg@arm.com
14710859Sandreas.sandberg@arm.comvoid
14810859Sandreas.sandberg@arm.comKvmGic::clearInt(uint32_t num)
14910859Sandreas.sandberg@arm.com{
15010859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Clear SPI %d\n", num);
15111461Sandreas.sandberg@arm.com    kernelGic.clearSPI(num);
15210859Sandreas.sandberg@arm.com}
15310859Sandreas.sandberg@arm.com
15410859Sandreas.sandberg@arm.comvoid
15510859Sandreas.sandberg@arm.comKvmGic::sendPPInt(uint32_t num, uint32_t cpu)
15610859Sandreas.sandberg@arm.com{
15710859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Set PPI %d:%d\n", cpu, num);
15811461Sandreas.sandberg@arm.com    kernelGic.setPPI(cpu, num);
15910859Sandreas.sandberg@arm.com}
16010859Sandreas.sandberg@arm.com
16110859Sandreas.sandberg@arm.comvoid
16210859Sandreas.sandberg@arm.comKvmGic::clearPPInt(uint32_t num, uint32_t cpu)
16310859Sandreas.sandberg@arm.com{
16410859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Clear PPI %d:%d\n", cpu, num);
16511461Sandreas.sandberg@arm.com    kernelGic.clearPPI(cpu, num);
16610859Sandreas.sandberg@arm.com}
16710859Sandreas.sandberg@arm.com
16810859Sandreas.sandberg@arm.comvoid
16910859Sandreas.sandberg@arm.comKvmGic::verifyMemoryMode() const
17010859Sandreas.sandberg@arm.com{
17110859Sandreas.sandberg@arm.com    if (!(system.isAtomicMode() && system.bypassCaches())) {
17210859Sandreas.sandberg@arm.com        fatal("The in-kernel KVM GIC can only be used with KVM CPUs, but the "
17310859Sandreas.sandberg@arm.com              "current memory mode does not support KVM.\n");
17410859Sandreas.sandberg@arm.com    }
17510859Sandreas.sandberg@arm.com}
17610859Sandreas.sandberg@arm.com
17710859Sandreas.sandberg@arm.com
17810859Sandreas.sandberg@arm.comKvmGic *
17910859Sandreas.sandberg@arm.comKvmGicParams::create()
18010859Sandreas.sandberg@arm.com{
18110859Sandreas.sandberg@arm.com    return new KvmGic(this);
18210859Sandreas.sandberg@arm.com}
183