diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/arm/kvm/KvmGic.py | 8 | ||||
-rw-r--r-- | src/arch/arm/kvm/gic.cc | 149 | ||||
-rw-r--r-- | src/arch/arm/kvm/gic.hh | 47 |
3 files changed, 200 insertions, 4 deletions
diff --git a/src/arch/arm/kvm/KvmGic.py b/src/arch/arm/kvm/KvmGic.py index 9ae52db22..d4cbd6c8b 100644 --- a/src/arch/arm/kvm/KvmGic.py +++ b/src/arch/arm/kvm/KvmGic.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 ARM Limited +# Copyright (c) 2015, 2017 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -38,7 +38,7 @@ from m5.params import * from m5.proxy import * -from Gic import BaseGic +from Gic import BaseGic, Pl390 from KvmVM import KvmVM from System import System @@ -52,3 +52,7 @@ class KvmGic(BaseGic): system = Param.System(Parent.any, 'System this interrupt controller belongs to') + +class MuxingKvmGic(Pl390): + type = 'MuxingKvmGic' + cxx_header = "arch/arm/kvm/gic.hh" diff --git a/src/arch/arm/kvm/gic.cc b/src/arch/arm/kvm/gic.cc index c5a30879c..7bc1ba59f 100644 --- a/src/arch/arm/kvm/gic.cc +++ b/src/arch/arm/kvm/gic.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 ARM Limited + * Copyright (c) 2015-2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -35,14 +35,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Andreas Sandberg + * Curtis Dunham */ #include "arch/arm/kvm/gic.hh" #include <linux/kvm.h> +#include "arch/arm/kvm/base_cpu.hh" #include "debug/Interrupt.hh" #include "params/KvmGic.hh" +#include "params/MuxingKvmGic.hh" KvmKernelGicV2::KvmKernelGicV2(KvmVM &_vm, Addr cpu_addr, Addr dist_addr, unsigned it_lines) @@ -183,3 +186,147 @@ KvmGicParams::create() { return new KvmGic(this); } + + +MuxingKvmGic::MuxingKvmGic(const MuxingKvmGicParams *p) + : Pl390(p), + system(*p->system), + kernelGic(nullptr), + usingKvm(false) +{ + if (auto vm = system.getKvmVM()) { + kernelGic = new KvmKernelGicV2(*vm, p->cpu_addr, p->dist_addr, + p->it_lines); + } +} + +MuxingKvmGic::~MuxingKvmGic() +{ +} + +void +MuxingKvmGic::startup() +{ + usingKvm = (kernelGic != nullptr) && validKvmEnvironment(); +} + +void +MuxingKvmGic::drainResume() +{ + bool use_kvm = (kernelGic != nullptr) && validKvmEnvironment(); + if (use_kvm != usingKvm) { + if (use_kvm) // from simulation to KVM emulation + fromPl390ToKvm(); + else // from KVM emulation to simulation + fromKvmToPl390(); + + usingKvm = use_kvm; + } +} + +void +MuxingKvmGic::serialize(CheckpointOut &cp) const +{ + if (!usingKvm) + return Pl390::serialize(cp); + + panic("Checkpointing unsupported\n"); +} + +void +MuxingKvmGic::unserialize(CheckpointIn &cp) +{ + if (!usingKvm) + return Pl390::unserialize(cp); + + panic("Checkpointing unsupported\n"); +} + +Tick +MuxingKvmGic::read(PacketPtr pkt) +{ + if (!usingKvm) + return Pl390::read(pkt); + + panic("MuxingKvmGic: PIO from gem5 is currently unsupported\n"); +} + +Tick +MuxingKvmGic::write(PacketPtr pkt) +{ + if (!usingKvm) + return Pl390::write(pkt); + + panic("MuxingKvmGic: PIO from gem5 is currently unsupported\n"); +} + +void +MuxingKvmGic::sendInt(uint32_t num) +{ + if (!usingKvm) + return Pl390::sendInt(num); + + DPRINTF(Interrupt, "Set SPI %d\n", num); + kernelGic->setSPI(num); +} + +void +MuxingKvmGic::clearInt(uint32_t num) +{ + if (!usingKvm) + return Pl390::clearInt(num); + + DPRINTF(Interrupt, "Clear SPI %d\n", num); + kernelGic->clearSPI(num); +} + +void +MuxingKvmGic::sendPPInt(uint32_t num, uint32_t cpu) +{ + if (!usingKvm) + return Pl390::sendPPInt(num, cpu); + DPRINTF(Interrupt, "Set PPI %d:%d\n", cpu, num); + kernelGic->setPPI(cpu, num); +} + +void +MuxingKvmGic::clearPPInt(uint32_t num, uint32_t cpu) +{ + if (!usingKvm) + return Pl390::clearPPInt(num, cpu); + + DPRINTF(Interrupt, "Clear PPI %d:%d\n", cpu, num); + kernelGic->clearPPI(cpu, num); +} + +bool +MuxingKvmGic::validKvmEnvironment() const +{ + if (system.threadContexts.empty()) + return false; + + for (auto tc : system.threadContexts) { + if (dynamic_cast<BaseArmKvmCPU*>(tc->getCpuPtr()) == nullptr) { + return false; + } + } + return true; +} + +void +MuxingKvmGic::fromPl390ToKvm() +{ + panic("Gic multiplexing not implemented.\n"); +} + +void +MuxingKvmGic::fromKvmToPl390() +{ + panic("Gic multiplexing not implemented.\n"); +} + +MuxingKvmGic * +MuxingKvmGicParams::create() +{ + return new MuxingKvmGic(this); +} diff --git a/src/arch/arm/kvm/gic.hh b/src/arch/arm/kvm/gic.hh index d6922b24b..fc09da6a0 100644 --- a/src/arch/arm/kvm/gic.hh +++ b/src/arch/arm/kvm/gic.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 ARM Limited + * Copyright (c) 2015-2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -35,6 +35,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Andreas Sandberg + * Curtis Dunham */ #ifndef __ARCH_ARM_KVM_GIC_HH__ @@ -44,6 +45,7 @@ #include "cpu/kvm/device.hh" #include "cpu/kvm/vm.hh" #include "dev/arm/base_gic.hh" +#include "dev/arm/gic_pl390.hh" #include "dev/platform.hh" /** @@ -205,4 +207,47 @@ class KvmGic : public BaseGic const AddrRangeList addrRanges; }; +struct MuxingKvmGicParams; + +class MuxingKvmGic : public Pl390 +{ + public: // SimObject / Serializable / Drainable + MuxingKvmGic(const MuxingKvmGicParams *p); + ~MuxingKvmGic(); + + void startup() override; + void drainResume() override; + + void serialize(CheckpointOut &cp) const override; + void unserialize(CheckpointIn &cp) override; + + public: // PioDevice + Tick read(PacketPtr pkt) override; + Tick write(PacketPtr pkt) override; + + public: // Pl390 + void sendInt(uint32_t num) override; + void clearInt(uint32_t num) override; + + void sendPPInt(uint32_t num, uint32_t cpu) override; + void clearPPInt(uint32_t num, uint32_t cpu) override; + + protected: + /** Verify gem5 configuration will support KVM emulation */ + bool validKvmEnvironment() const; + + /** System this interrupt controller belongs to */ + System &system; + + /** Kernel GIC device */ + KvmKernelGicV2 *kernelGic; + + private: + bool usingKvm; + + /** Multiplexing implementation: state transfer functions */ + void fromPl390ToKvm(); + void fromKvmToPl390(); +}; + #endif // __ARCH_ARM_KVM_GIC_HH__ |