Giacomo Travaglini has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/55611 )
Change subject: arch-arm: Templatize MuxingKvmGic to support flexible
hierarchy
......................................................................
arch-arm: Templatize MuxingKvmGic to support flexible hierarchy
By templatizing the MuxingKvmGic we decouple it from the GicV2
class, unlocking non GICv2 (e.g. GICv3) KVM and guest implementations
Signed-off-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Change-Id: I26838903fa7c9f8b9de40678021329cb3390cc74
---
M src/arch/arm/kvm/KvmGic.py
M src/arch/arm/kvm/gic.cc
M src/arch/arm/kvm/gic.hh
M src/arch/arm/kvm/SConscript
M src/dev/arm/RealView.py
5 files changed, 99 insertions(+), 63 deletions(-)
diff --git a/src/arch/arm/kvm/KvmGic.py b/src/arch/arm/kvm/KvmGic.py
index c435f44..a192944 100644
--- a/src/arch/arm/kvm/KvmGic.py
+++ b/src/arch/arm/kvm/KvmGic.py
@@ -38,10 +38,11 @@
from m5.objects.Gic import GicV2
-class MuxingKvmGic(GicV2):
- type = 'MuxingKvmGic'
+class MuxingKvmGicV2(GicV2):
+ type = 'MuxingKvmGicV2'
cxx_header = "arch/arm/kvm/gic.hh"
- cxx_class = 'gem5::MuxingKvmGic'
+ cxx_class = 'gem5::MuxingKvmGic<gem5::GicV2Types>'
+ cxx_template_params = [ 'class Types' ]
simulate_gic = Param.Bool(False,
"Forcing the simulation to use the gem5 GIC instead of the host
GIC")
diff --git a/src/arch/arm/kvm/SConscript b/src/arch/arm/kvm/SConscript
index 44134a4..d06501f 100644
--- a/src/arch/arm/kvm/SConscript
+++ b/src/arch/arm/kvm/SConscript
@@ -43,7 +43,8 @@
if not (env['USE_KVM'] and env['KVM_ISA'] == 'arm'):
Return()
-SimObject('KvmGic.py', sim_objects=['MuxingKvmGic'], tags='arm isa')
+SimObject('KvmGic.py',
+ sim_objects=['MuxingKvmGicV2'], tags='arm isa')
Source('gic.cc', tags='arm isa')
SimObject('BaseArmKvmCPU.py', sim_objects=['BaseArmKvmCPU'], tags='arm
isa')
diff --git a/src/arch/arm/kvm/gic.cc b/src/arch/arm/kvm/gic.cc
index ae4314f..058ee6b 100644
--- a/src/arch/arm/kvm/gic.cc
+++ b/src/arch/arm/kvm/gic.cc
@@ -42,7 +42,7 @@
#include "arch/arm/kvm/base_cpu.hh"
#include "debug/GIC.hh"
#include "debug/Interrupt.hh"
-#include "params/MuxingKvmGic.hh"
+#include "params/MuxingKvmGicV2.hh"
namespace gem5
{
@@ -157,56 +157,55 @@
setGicReg(KVM_DEV_ARM_VGIC_GRP_CPU_REGS, vcpu, daddr, data);
}
-KvmKernelGicV2::KvmKernelGicV2(KvmVM &_vm, Addr cpu_addr, Addr dist_addr,
- unsigned it_lines)
- : KvmKernelGic(_vm, KVM_DEV_TYPE_ARM_VGIC_V2, it_lines),
- cpuRange(RangeSize(cpu_addr, KVM_VGIC_V2_CPU_SIZE)),
- distRange(RangeSize(dist_addr, KVM_VGIC_V2_DIST_SIZE))
+KvmKernelGicV2::KvmKernelGicV2(KvmVM &_vm,
+ const MuxingKvmGicV2Params &p)
+ : KvmKernelGic(_vm, KVM_DEV_TYPE_ARM_VGIC_V2, p.it_lines),
+ cpuRange(RangeSize(p.cpu_addr, KVM_VGIC_V2_CPU_SIZE)),
+ distRange(RangeSize(p.dist_addr, KVM_VGIC_V2_DIST_SIZE))
{
kdev.setAttr<uint64_t>(
- KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST, dist_addr);
+ KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST,
p.dist_addr);
kdev.setAttr<uint64_t>(
- KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_CPU, cpu_addr);
+ KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_CPU, p.cpu_addr);
}
-MuxingKvmGic::MuxingKvmGic(const MuxingKvmGicParams &p)
- : GicV2(p),
- system(*p.system),
- kernelGic(nullptr),
- usingKvm(false)
+template <class Types>
+MuxingKvmGic<Types>::MuxingKvmGic(const Params &p)
+ : GuestGic(p),
+ system(*p.system),
+ kernelGic(nullptr),
+ usingKvm(false)
{
auto vm = system.getKvmVM();
if (vm && !p.simulate_gic) {
- kernelGic = new KvmKernelGicV2(*vm, p.cpu_addr, p.dist_addr,
- p.it_lines);
+ kernelGic = new KvmGic(*vm, p);
}
}
-MuxingKvmGic::~MuxingKvmGic()
-{
-}
-
+template <class Types>
void
-MuxingKvmGic::startup()
+MuxingKvmGic<Types>::startup()
{
- GicV2::startup();
+ GuestGic::startup();
usingKvm = (kernelGic != nullptr) && system.validKvmEnvironment();
if (usingKvm)
fromGicToKvm();
}
+template <class Types>
DrainState
-MuxingKvmGic::drain()
+MuxingKvmGic<Types>::drain()
{
if (usingKvm)
fromKvmToGic();
- return GicV2::drain();
+ return GuestGic::drain();
}
+template <class Types>
void
-MuxingKvmGic::drainResume()
+MuxingKvmGic<Types>::drainResume()
{
- GicV2::drainResume();
+ GuestGic::drainResume();
bool use_kvm = (kernelGic != nullptr) && system.validKvmEnvironment();
if (use_kvm != usingKvm) {
// Should only occur due to CPU switches
@@ -218,65 +217,72 @@
}
}
+template <class Types>
Tick
-MuxingKvmGic::read(PacketPtr pkt)
+MuxingKvmGic<Types>::read(PacketPtr pkt)
{
if (!usingKvm)
- return GicV2::read(pkt);
+ return GuestGic::read(pkt);
panic("MuxingKvmGic: PIO from gem5 is currently unsupported\n");
}
+template <class Types>
Tick
-MuxingKvmGic::write(PacketPtr pkt)
+MuxingKvmGic<Types>::write(PacketPtr pkt)
{
if (!usingKvm)
- return GicV2::write(pkt);
+ return GuestGic::write(pkt);
panic("MuxingKvmGic: PIO from gem5 is currently unsupported\n");
}
+template <class Types>
void
-MuxingKvmGic::sendInt(uint32_t num)
+MuxingKvmGic<Types>::sendInt(uint32_t num)
{
if (!usingKvm)
- return GicV2::sendInt(num);
+ return GuestGic::sendInt(num);
DPRINTF(Interrupt, "Set SPI %d\n", num);
kernelGic->setSPI(num);
}
+template <class Types>
void
-MuxingKvmGic::clearInt(uint32_t num)
+MuxingKvmGic<Types>::clearInt(uint32_t num)
{
if (!usingKvm)
- return GicV2::clearInt(num);
+ return GuestGic::clearInt(num);
DPRINTF(Interrupt, "Clear SPI %d\n", num);
kernelGic->clearSPI(num);
}
+template <class Types>
void
-MuxingKvmGic::sendPPInt(uint32_t num, uint32_t cpu)
+MuxingKvmGic<Types>::sendPPInt(uint32_t num, uint32_t cpu)
{
if (!usingKvm)
- return GicV2::sendPPInt(num, cpu);
+ return GuestGic::sendPPInt(num, cpu);
DPRINTF(Interrupt, "Set PPI %d:%d\n", cpu, num);
kernelGic->setPPI(cpu, num);
}
+template <class Types>
void
-MuxingKvmGic::clearPPInt(uint32_t num, uint32_t cpu)
+MuxingKvmGic<Types>::clearPPInt(uint32_t num, uint32_t cpu)
{
if (!usingKvm)
- return GicV2::clearPPInt(num, cpu);
+ return GuestGic::clearPPInt(num, cpu);
DPRINTF(Interrupt, "Clear PPI %d:%d\n", cpu, num);
kernelGic->clearPPI(cpu, num);
}
+template <class Types>
bool
-MuxingKvmGic::blockIntUpdate() const
+MuxingKvmGic<Types>::blockIntUpdate() const
{
// During Kvm->Gic state transfer, writes to the Gic will call
// updateIntState() which can post an interrupt. Since we're only
@@ -285,25 +291,31 @@
return usingKvm;
}
+template <class Types>
void
-MuxingKvmGic::fromGicToKvm()
+MuxingKvmGic<Types>::fromGicToKvm()
{
- copyGicState(static_cast<GicV2*>(this), kernelGic);
+ this->copyGicState(static_cast<GuestGic*>(this), kernelGic);
}
+template <class Types>
void
-MuxingKvmGic::fromKvmToGic()
+MuxingKvmGic<Types>::fromKvmToGic()
{
- copyGicState(kernelGic, static_cast<GicV2*>(this));
+ this->copyGicState(kernelGic, static_cast<GuestGic*>(this));
// the values read for the Interrupt Priority Mask Register (PMR)
// have been shifted by three bits due to its having been emulated by
// a VGIC with only 5 PMR bits in its VMCR register. Presently the
// Linux kernel does not repair this inaccuracy, so we correct it here.
- for (int cpu = 0; cpu < system.threads.size(); ++cpu) {
- cpuPriority[cpu] <<= 3;
- assert((cpuPriority[cpu] & ~0xff) == 0);
+ if constexpr(std::is_same<GuestGic, GicV2>::value) {
+ for (int cpu = 0; cpu < system.threads.size(); ++cpu) {
+ this->cpuPriority[cpu] <<= 3;
+ assert((this->cpuPriority[cpu] & ~0xff) == 0);
+ }
}
}
+template class MuxingKvmGic<GicV2Types>;
+
} // namespace gem5
diff --git a/src/arch/arm/kvm/gic.hh b/src/arch/arm/kvm/gic.hh
index bf3a106..3c021a1 100644
--- a/src/arch/arm/kvm/gic.hh
+++ b/src/arch/arm/kvm/gic.hh
@@ -44,6 +44,8 @@
#include "dev/arm/gic_v2.hh"
#include "dev/platform.hh"
+#include "params/MuxingKvmGicV2.hh"
+
namespace gem5
{
@@ -163,18 +165,16 @@
{
public:
/**
- * Instantiate a KVM in-kernel GIC model.
+ * Instantiate a KVM in-kernel GICv2 model.
*
- * This constructor instantiates an in-kernel GIC model and wires
+ * This constructor instantiates an in-kernel GICv2 model and wires
* it up to the virtual memory system.
*
* @param vm KVM VM representing this system
- * @param cpu_addr GIC CPU interface base address
- * @param dist_addr GIC distributor base address
- * @param it_lines Number of interrupt lines to support
+ * @param params MuxingKvmGicV2 params
*/
- KvmKernelGicV2(KvmVM &vm, Addr cpu_addr, Addr dist_addr,
- unsigned it_lines);
+ KvmKernelGicV2(KvmVM &vm,
+ const MuxingKvmGicV2Params ¶ms);
private:
/** Address range for the CPU interfaces */
@@ -184,13 +184,22 @@
};
-struct MuxingKvmGicParams;
-
-class MuxingKvmGic : public GicV2
+struct GicV2Types
{
+ using GuestGic = GicV2;
+ using KvmGic = KvmKernelGicV2;
+ using Params = MuxingKvmGicV2Params;
+};
+
+template <class Types>
+class MuxingKvmGic : public Types::GuestGic
+{
+ using GuestGic = typename Types::GuestGic;
+ using KvmGic = typename Types::KvmGic;
+ using Params = typename Types::Params;
+
public: // SimObject / Serializable / Drainable
- MuxingKvmGic(const MuxingKvmGicParams &p);
- ~MuxingKvmGic();
+ MuxingKvmGic(const Params &p);
void startup() override;
DrainState drain() override;
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py
index 3229983..6cb28dd 100644
--- a/src/dev/arm/RealView.py
+++ b/src/dev/arm/RealView.py
@@ -73,8 +73,8 @@
# emulation. Use a GIC model that automatically switches between
# gem5's GIC model and KVM's GIC model if KVM is available.
try:
- from m5.objects.KvmGic import MuxingKvmGic
- kvm_gicv2_class = MuxingKvmGic
+ from m5.objects.KvmGic import MuxingKvmGicV2
+ kvm_gicv2_class = MuxingKvmGicV2
except ImportError:
# KVM support wasn't compiled into gem5. Fallback to a
# software-only GIC.
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/55611
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I26838903fa7c9f8b9de40678021329cb3390cc74
Gerrit-Change-Number: 55611
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s