summaryrefslogtreecommitdiff
path: root/src/arch/arm/kvm/gic.cc
diff options
context:
space:
mode:
authorCurtis Dunham <Curtis.Dunham@arm.com>2017-02-14 15:09:18 -0600
committerCurtis Dunham <Curtis.Dunham@arm.com>2017-02-14 15:09:18 -0600
commit0edf6dc9560364691ca0d359ab8321b936f0ec85 (patch)
treea712a0487f7f024d9c329c2bb427c71a827cfa1d /src/arch/arm/kvm/gic.cc
parent41beacce088e8f682a0e8ac48f22a3fa4805a43b (diff)
downloadgem5-0edf6dc9560364691ca0d359ab8321b936f0ec85.tar.xz
arm, kvm: implement MuxingKvmGic
This device allows us to, when KVM support is detected and compiled in, instantiate the same Gic device whether the actual simulation is with KVM cores or simulated cores. Checkpointing is not yet supported. Change-Id: I67e4e0b6fb7ab5058e52c933f4f3d8e7ab24981e Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/arch/arm/kvm/gic.cc')
-rw-r--r--src/arch/arm/kvm/gic.cc149
1 files changed, 148 insertions, 1 deletions
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);
+}