gic.cc revision 11462
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
4711462Sandreas.sandberg@arm.comKvmKernelGicV2::KvmKernelGicV2(KvmVM &_vm, Addr cpu_addr, Addr dist_addr,
4811462Sandreas.sandberg@arm.com                               unsigned it_lines)
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);
5811462Sandreas.sandberg@arm.com
5911462Sandreas.sandberg@arm.com    kdev.setAttr<uint32_t>(KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0, it_lines);
6011461Sandreas.sandberg@arm.com}
6111461Sandreas.sandberg@arm.com
6211461Sandreas.sandberg@arm.comKvmKernelGicV2::~KvmKernelGicV2()
6311461Sandreas.sandberg@arm.com{
6411461Sandreas.sandberg@arm.com}
6511461Sandreas.sandberg@arm.com
6611461Sandreas.sandberg@arm.comvoid
6711461Sandreas.sandberg@arm.comKvmKernelGicV2::setSPI(unsigned spi)
6811461Sandreas.sandberg@arm.com{
6911461Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_SPI, 0, spi, true);
7011461Sandreas.sandberg@arm.com}
7111461Sandreas.sandberg@arm.com
7211461Sandreas.sandberg@arm.comvoid
7311461Sandreas.sandberg@arm.comKvmKernelGicV2::clearSPI(unsigned spi)
7411461Sandreas.sandberg@arm.com{
7511461Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_SPI, 0, spi, false);
7611461Sandreas.sandberg@arm.com}
7711461Sandreas.sandberg@arm.com
7811461Sandreas.sandberg@arm.comvoid
7911461Sandreas.sandberg@arm.comKvmKernelGicV2::setPPI(unsigned vcpu, unsigned ppi)
8011461Sandreas.sandberg@arm.com{
8111461Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_PPI, vcpu, ppi, true);
8211461Sandreas.sandberg@arm.com}
8311461Sandreas.sandberg@arm.com
8411461Sandreas.sandberg@arm.comvoid
8511461Sandreas.sandberg@arm.comKvmKernelGicV2::clearPPI(unsigned vcpu, unsigned ppi)
8611461Sandreas.sandberg@arm.com{
8711461Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_PPI, vcpu, ppi, false);
8811461Sandreas.sandberg@arm.com}
8911461Sandreas.sandberg@arm.com
9011461Sandreas.sandberg@arm.comvoid
9111461Sandreas.sandberg@arm.comKvmKernelGicV2::setIntState(unsigned type, unsigned vcpu, unsigned irq,
9211461Sandreas.sandberg@arm.com                            bool high)
9311461Sandreas.sandberg@arm.com{
9411461Sandreas.sandberg@arm.com    assert(type <= KVM_ARM_IRQ_TYPE_MASK);
9511461Sandreas.sandberg@arm.com    assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
9611461Sandreas.sandberg@arm.com    assert(irq <= KVM_ARM_IRQ_NUM_MASK);
9711461Sandreas.sandberg@arm.com    const uint32_t line(
9811461Sandreas.sandberg@arm.com        (type << KVM_ARM_IRQ_TYPE_SHIFT) |
9911461Sandreas.sandberg@arm.com        (vcpu << KVM_ARM_IRQ_VCPU_SHIFT) |
10011461Sandreas.sandberg@arm.com        (irq << KVM_ARM_IRQ_NUM_SHIFT));
10111461Sandreas.sandberg@arm.com
10211461Sandreas.sandberg@arm.com    vm.setIRQLine(line, high);
10311461Sandreas.sandberg@arm.com}
10411461Sandreas.sandberg@arm.com
10511461Sandreas.sandberg@arm.com
10610859Sandreas.sandberg@arm.comKvmGic::KvmGic(const KvmGicParams *p)
10710859Sandreas.sandberg@arm.com    : BaseGic(p),
10810859Sandreas.sandberg@arm.com      system(*p->system),
10911462Sandreas.sandberg@arm.com      kernelGic(*p->kvmVM, p->cpu_addr, p->dist_addr, p->it_lines),
11011461Sandreas.sandberg@arm.com      addrRanges{kernelGic.distRange, kernelGic.cpuRange}
11110859Sandreas.sandberg@arm.com{
11210859Sandreas.sandberg@arm.com}
11310859Sandreas.sandberg@arm.com
11410859Sandreas.sandberg@arm.comKvmGic::~KvmGic()
11510859Sandreas.sandberg@arm.com{
11610859Sandreas.sandberg@arm.com}
11710859Sandreas.sandberg@arm.com
11810859Sandreas.sandberg@arm.comvoid
11910905Sandreas.sandberg@arm.comKvmGic::serialize(CheckpointOut &cp) const
12010859Sandreas.sandberg@arm.com{
12110859Sandreas.sandberg@arm.com    panic("Checkpointing unsupported\n");
12210859Sandreas.sandberg@arm.com}
12310859Sandreas.sandberg@arm.com
12410859Sandreas.sandberg@arm.comvoid
12510905Sandreas.sandberg@arm.comKvmGic::unserialize(CheckpointIn &cp)
12610859Sandreas.sandberg@arm.com{
12710859Sandreas.sandberg@arm.com    panic("Checkpointing unsupported\n");
12810859Sandreas.sandberg@arm.com}
12910859Sandreas.sandberg@arm.com
13010859Sandreas.sandberg@arm.comTick
13110859Sandreas.sandberg@arm.comKvmGic::read(PacketPtr pkt)
13210859Sandreas.sandberg@arm.com{
13310859Sandreas.sandberg@arm.com    panic("KvmGic: PIO from gem5 is currently unsupported\n");
13410859Sandreas.sandberg@arm.com}
13510859Sandreas.sandberg@arm.com
13610859Sandreas.sandberg@arm.comTick
13710859Sandreas.sandberg@arm.comKvmGic::write(PacketPtr pkt)
13810859Sandreas.sandberg@arm.com{
13910859Sandreas.sandberg@arm.com    panic("KvmGic: PIO from gem5 is currently unsupported\n");
14010859Sandreas.sandberg@arm.com}
14110859Sandreas.sandberg@arm.com
14210859Sandreas.sandberg@arm.comvoid
14310859Sandreas.sandberg@arm.comKvmGic::sendInt(uint32_t num)
14410859Sandreas.sandberg@arm.com{
14510859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Set SPI %d\n", num);
14611461Sandreas.sandberg@arm.com    kernelGic.setSPI(num);
14710859Sandreas.sandberg@arm.com}
14810859Sandreas.sandberg@arm.com
14910859Sandreas.sandberg@arm.comvoid
15010859Sandreas.sandberg@arm.comKvmGic::clearInt(uint32_t num)
15110859Sandreas.sandberg@arm.com{
15210859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Clear SPI %d\n", num);
15311461Sandreas.sandberg@arm.com    kernelGic.clearSPI(num);
15410859Sandreas.sandberg@arm.com}
15510859Sandreas.sandberg@arm.com
15610859Sandreas.sandberg@arm.comvoid
15710859Sandreas.sandberg@arm.comKvmGic::sendPPInt(uint32_t num, uint32_t cpu)
15810859Sandreas.sandberg@arm.com{
15910859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Set PPI %d:%d\n", cpu, num);
16011461Sandreas.sandberg@arm.com    kernelGic.setPPI(cpu, num);
16110859Sandreas.sandberg@arm.com}
16210859Sandreas.sandberg@arm.com
16310859Sandreas.sandberg@arm.comvoid
16410859Sandreas.sandberg@arm.comKvmGic::clearPPInt(uint32_t num, uint32_t cpu)
16510859Sandreas.sandberg@arm.com{
16610859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Clear PPI %d:%d\n", cpu, num);
16711461Sandreas.sandberg@arm.com    kernelGic.clearPPI(cpu, num);
16810859Sandreas.sandberg@arm.com}
16910859Sandreas.sandberg@arm.com
17010859Sandreas.sandberg@arm.comvoid
17110859Sandreas.sandberg@arm.comKvmGic::verifyMemoryMode() const
17210859Sandreas.sandberg@arm.com{
17310859Sandreas.sandberg@arm.com    if (!(system.isAtomicMode() && system.bypassCaches())) {
17410859Sandreas.sandberg@arm.com        fatal("The in-kernel KVM GIC can only be used with KVM CPUs, but the "
17510859Sandreas.sandberg@arm.com              "current memory mode does not support KVM.\n");
17610859Sandreas.sandberg@arm.com    }
17710859Sandreas.sandberg@arm.com}
17810859Sandreas.sandberg@arm.com
17910859Sandreas.sandberg@arm.com
18010859Sandreas.sandberg@arm.comKvmGic *
18110859Sandreas.sandberg@arm.comKvmGicParams::create()
18210859Sandreas.sandberg@arm.com{
18310859Sandreas.sandberg@arm.com    return new KvmGic(this);
18410859Sandreas.sandberg@arm.com}
185