gic.cc revision 10859
110859Sandreas.sandberg@arm.com/*
210859Sandreas.sandberg@arm.com * Copyright (c) 2015 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
4710859Sandreas.sandberg@arm.comKvmGic::KvmGic(const KvmGicParams *p)
4810859Sandreas.sandberg@arm.com    : BaseGic(p),
4910859Sandreas.sandberg@arm.com      system(*p->system),
5010859Sandreas.sandberg@arm.com      vm(*p->kvmVM),
5110859Sandreas.sandberg@arm.com      kdev(vm.createDevice(KVM_DEV_TYPE_ARM_VGIC_V2)),
5210859Sandreas.sandberg@arm.com      distRange(RangeSize(p->dist_addr, KVM_VGIC_V2_DIST_SIZE)),
5310859Sandreas.sandberg@arm.com      cpuRange(RangeSize(p->cpu_addr, KVM_VGIC_V2_CPU_SIZE)),
5410859Sandreas.sandberg@arm.com      addrRanges{distRange, cpuRange}
5510859Sandreas.sandberg@arm.com{
5610859Sandreas.sandberg@arm.com    kdev.setAttr<uint64_t>(
5710859Sandreas.sandberg@arm.com        KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST,
5810859Sandreas.sandberg@arm.com        p->dist_addr);
5910859Sandreas.sandberg@arm.com    kdev.setAttr<uint64_t>(
6010859Sandreas.sandberg@arm.com        KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_CPU,
6110859Sandreas.sandberg@arm.com        p->cpu_addr);
6210859Sandreas.sandberg@arm.com}
6310859Sandreas.sandberg@arm.com
6410859Sandreas.sandberg@arm.comKvmGic::~KvmGic()
6510859Sandreas.sandberg@arm.com{
6610859Sandreas.sandberg@arm.com}
6710859Sandreas.sandberg@arm.com
6810859Sandreas.sandberg@arm.comvoid
6910859Sandreas.sandberg@arm.comKvmGic::serialize(std::ostream &os)
7010859Sandreas.sandberg@arm.com{
7110859Sandreas.sandberg@arm.com    panic("Checkpointing unsupported\n");
7210859Sandreas.sandberg@arm.com}
7310859Sandreas.sandberg@arm.com
7410859Sandreas.sandberg@arm.comvoid
7510859Sandreas.sandberg@arm.comKvmGic::unserialize(Checkpoint *cp, const std::string &sec)
7610859Sandreas.sandberg@arm.com{
7710859Sandreas.sandberg@arm.com    panic("Checkpointing unsupported\n");
7810859Sandreas.sandberg@arm.com}
7910859Sandreas.sandberg@arm.com
8010859Sandreas.sandberg@arm.comTick
8110859Sandreas.sandberg@arm.comKvmGic::read(PacketPtr pkt)
8210859Sandreas.sandberg@arm.com{
8310859Sandreas.sandberg@arm.com    panic("KvmGic: PIO from gem5 is currently unsupported\n");
8410859Sandreas.sandberg@arm.com}
8510859Sandreas.sandberg@arm.com
8610859Sandreas.sandberg@arm.comTick
8710859Sandreas.sandberg@arm.comKvmGic::write(PacketPtr pkt)
8810859Sandreas.sandberg@arm.com{
8910859Sandreas.sandberg@arm.com    panic("KvmGic: PIO from gem5 is currently unsupported\n");
9010859Sandreas.sandberg@arm.com}
9110859Sandreas.sandberg@arm.com
9210859Sandreas.sandberg@arm.comvoid
9310859Sandreas.sandberg@arm.comKvmGic::sendInt(uint32_t num)
9410859Sandreas.sandberg@arm.com{
9510859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Set SPI %d\n", num);
9610859Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_SPI, 0, num, true);
9710859Sandreas.sandberg@arm.com}
9810859Sandreas.sandberg@arm.com
9910859Sandreas.sandberg@arm.comvoid
10010859Sandreas.sandberg@arm.comKvmGic::clearInt(uint32_t num)
10110859Sandreas.sandberg@arm.com{
10210859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Clear SPI %d\n", num);
10310859Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_SPI, 0, num, false);
10410859Sandreas.sandberg@arm.com}
10510859Sandreas.sandberg@arm.com
10610859Sandreas.sandberg@arm.comvoid
10710859Sandreas.sandberg@arm.comKvmGic::sendPPInt(uint32_t num, uint32_t cpu)
10810859Sandreas.sandberg@arm.com{
10910859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Set PPI %d:%d\n", cpu, num);
11010859Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_PPI, cpu, num, true);
11110859Sandreas.sandberg@arm.com}
11210859Sandreas.sandberg@arm.com
11310859Sandreas.sandberg@arm.comvoid
11410859Sandreas.sandberg@arm.comKvmGic::clearPPInt(uint32_t num, uint32_t cpu)
11510859Sandreas.sandberg@arm.com{
11610859Sandreas.sandberg@arm.com    DPRINTF(Interrupt, "Clear PPI %d:%d\n", cpu, num);
11710859Sandreas.sandberg@arm.com    setIntState(KVM_ARM_IRQ_TYPE_PPI, cpu, num, false);
11810859Sandreas.sandberg@arm.com}
11910859Sandreas.sandberg@arm.com
12010859Sandreas.sandberg@arm.comvoid
12110859Sandreas.sandberg@arm.comKvmGic::verifyMemoryMode() const
12210859Sandreas.sandberg@arm.com{
12310859Sandreas.sandberg@arm.com    if (!(system.isAtomicMode() && system.bypassCaches())) {
12410859Sandreas.sandberg@arm.com        fatal("The in-kernel KVM GIC can only be used with KVM CPUs, but the "
12510859Sandreas.sandberg@arm.com              "current memory mode does not support KVM.\n");
12610859Sandreas.sandberg@arm.com    }
12710859Sandreas.sandberg@arm.com}
12810859Sandreas.sandberg@arm.com
12910859Sandreas.sandberg@arm.comvoid
13010859Sandreas.sandberg@arm.comKvmGic::setIntState(uint8_t type, uint8_t vcpu, uint16_t irq, bool high)
13110859Sandreas.sandberg@arm.com{
13210859Sandreas.sandberg@arm.com    assert(type < KVM_ARM_IRQ_TYPE_MASK);
13310859Sandreas.sandberg@arm.com    assert(vcpu < KVM_ARM_IRQ_VCPU_MASK);
13410859Sandreas.sandberg@arm.com    assert(irq < KVM_ARM_IRQ_NUM_MASK);
13510859Sandreas.sandberg@arm.com    const uint32_t line(
13610859Sandreas.sandberg@arm.com        (type << KVM_ARM_IRQ_TYPE_SHIFT) |
13710859Sandreas.sandberg@arm.com        (vcpu << KVM_ARM_IRQ_VCPU_SHIFT) |
13810859Sandreas.sandberg@arm.com        (irq << KVM_ARM_IRQ_NUM_SHIFT));
13910859Sandreas.sandberg@arm.com
14010859Sandreas.sandberg@arm.com    vm.setIRQLine(line, high);
14110859Sandreas.sandberg@arm.com}
14210859Sandreas.sandberg@arm.com
14310859Sandreas.sandberg@arm.com
14410859Sandreas.sandberg@arm.comKvmGic *
14510859Sandreas.sandberg@arm.comKvmGicParams::create()
14610859Sandreas.sandberg@arm.com{
14710859Sandreas.sandberg@arm.com    return new KvmGic(this);
14810859Sandreas.sandberg@arm.com}
149