44#include "debug/GIC.hh"
45#include "debug/Interrupt.hh"
46#include "params/MuxingKvmGicV2.hh"
53 kdev(
vm.createDevice(dev))
59 kdev.
setAttr<uint32_t>(KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0, it_lines);
87 setIntState(KVM_ARM_IRQ_TYPE_PPI, vcpu, ppi,
false);
94 const unsigned vcpu_index = vcpu & 0xff;
95 const unsigned vcpu2_index = (vcpu >> 8) & 0xff;
98 uint32_t kvm_vcpu = (vcpu_index << KVM_ARM_IRQ_VCPU_SHIFT);
100#if defined(KVM_ARM_IRQ_VCPU2_SHIFT)
102 kvm_vcpu |= vcpu2_index << KVM_ARM_IRQ_VCPU2_SHIFT;
105 panic_if((!vcpu2_enabled && vcpu2_index) || kvm_vcpu > 0xffff,
106 "VCPU out of range");
108 assert(
type <= KVM_ARM_IRQ_TYPE_MASK);
109 assert(
irq <= KVM_ARM_IRQ_NUM_MASK);
112 (
type << KVM_ARM_IRQ_TYPE_SHIFT) |
113 (
irq << KVM_ARM_IRQ_NUM_SHIFT));
119 const MuxingKvmGicV2Params &
p)
121 cpuRange(
RangeSize(
p.cpu_addr, KVM_VGIC_V2_CPU_SIZE)),
122 distRange(
RangeSize(
p.dist_addr, KVM_VGIC_V2_DIST_SIZE))
125 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST,
p.dist_addr);
127 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_CPU,
p.cpu_addr);
135 assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
137 ((uint64_t)vcpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) |
138 (
offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
141 return (uint32_t)
reg;
148 uint64_t
reg = value;
150 assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
152 ((uint64_t)vcpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) |
153 (
offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
162 return getGicReg(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, vcpu, daddr);
169 return getGicReg(KVM_DEV_ARM_VGIC_GRP_CPU_REGS, vcpu, daddr);
176 setGicReg(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, vcpu, daddr,
data);
187#define SZ_64K 0x00000040
191 const MuxingKvmGicV3Params &
p)
193 redistRange(
RangeSize(
p.redist_addr, KVM_VGIC_V3_REDIST_SIZE)),
194 distRange(
RangeSize(
p.dist_addr, KVM_VGIC_V3_DIST_SIZE))
197 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_DIST,
p.dist_addr);
199 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_REDIST,
p.redist_addr);
206 KVM_DEV_ARM_VGIC_GRP_CTRL, KVM_DEV_ARM_VGIC_CTRL_INIT, 0);
209template <
typename Ret>
215 assert(mpidr <= KVM_DEV_ARM_VGIC_V3_MPIDR_MASK);
217 ((uint64_t)mpidr << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT) |
218 (
offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
224template <
typename Arg>
231 assert(mpidr <= KVM_DEV_ARM_VGIC_V3_MPIDR_MASK);
233 ((uint64_t)mpidr << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT) |
234 (
offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
242 return getGicReg<uint32_t>(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, 0, daddr);
248 return getGicReg<uint32_t>(KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, aff, daddr);
256 return getGicReg<RegVal>(KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS, aff, sys_reg);
262 setGicReg<uint32_t>(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, 0, daddr,
data);
269 setGicReg<uint32_t>(KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, aff, daddr,
data);
278 setGicReg<RegVal>(KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS, aff, sys_reg,
data);
281template <
class Types>
289 if (
vm && !
p.simulate_gic) {
294template <
class Types>
304 if (
vm &&
vm->validEnvironment()) {
311template <
class Types>
317 return SimGic::drain();
320template <
class Types>
324 SimGic::drainResume();
327 bool use_kvm = kernelGic &&
vm &&
vm->validEnvironment();
328 if (use_kvm != usingKvm) {
338template <
class Types>
343 return SimGic::read(pkt);
345 panic(
"MuxingKvmGic: PIO from gem5 is currently unsupported\n");
348template <
class Types>
353 return SimGic::write(pkt);
355 panic(
"MuxingKvmGic: PIO from gem5 is currently unsupported\n");
358template <
class Types>
363 return SimGic::sendInt(num);
366 kernelGic->setSPI(num);
369template <
class Types>
374 return SimGic::clearInt(num);
377 kernelGic->clearSPI(num);
380template <
class Types>
385 return SimGic::sendPPInt(num, cpu);
387 kernelGic->setPPI(cpu, num);
390template <
class Types>
395 return SimGic::clearPPInt(num, cpu);
398 kernelGic->clearPPI(cpu, num);
401template <
class Types>
412template <
class Types>
416 this->copyGicState(
static_cast<SimGic*
>(
this),
417 static_cast<KvmGic*
>(kernelGic));
420template <
class Types>
424 this->copyGicState(
static_cast<KvmGic*
>(kernelGic),
425 static_cast<SimGic*
>(
this));
431 if constexpr(std::is_same<SimGic, GicV2>::value) {
432 for (
int cpu = 0; cpu <
system.threads.size(); ++cpu) {
433 this->cpuPriority[cpu] <<= 3;
434 assert((this->cpuPriority[cpu] & ~0xff) == 0);
void getAttrPtr(uint32_t group, uint64_t attr, void *data) const
void setAttrPtr(uint32_t group, uint64_t attr, const void *data) const
void setAttr(uint32_t group, uint64_t attr, const T &data) const
Get the value of an attribute.
uint32_t readCpu(ContextID ctx, Addr daddr) override
void setGicReg(unsigned group, unsigned vcpu, unsigned offset, unsigned value)
Set value of GIC register "from" a cpu.
void writeCpu(ContextID ctx, Addr daddr, uint32_t data) override
uint32_t readDistributor(ContextID ctx, Addr daddr) override
uint32_t getGicReg(unsigned group, unsigned vcpu, unsigned offset)
Get value of GIC register "from" a cpu.
void writeDistributor(ContextID ctx, Addr daddr, uint32_t data) override
KvmKernelGicV2(KvmVM &vm, const MuxingKvmGicV2Params ¶ms)
Instantiate a KVM in-kernel GICv2 model.
RegVal readCpu(const ArmISA::Affinity &aff, ArmISA::MiscRegIndex misc_reg) override
void writeRedistributor(const ArmISA::Affinity &aff, Addr daddr, uint32_t data) override
void writeDistributor(Addr daddr, uint32_t data) override
Ret getGicReg(unsigned group, unsigned mpidr, unsigned offset)
Get value of GIC register "from" a cpu.
uint32_t readRedistributor(const ArmISA::Affinity &aff, Addr daddr) override
void writeCpu(const ArmISA::Affinity &aff, ArmISA::MiscRegIndex misc_reg, RegVal data) override
uint32_t readDistributor(Addr daddr) override
void setGicReg(unsigned group, unsigned mpidr, unsigned offset, Arg value)
Set value of GIC register "from" a cpu.
KvmKernelGicV3(KvmVM &vm, const MuxingKvmGicV3Params ¶ms)
Instantiate a KVM in-kernel GICv3 model.
KVM in-kernel GIC abstraction.
void setPPI(unsigned vcpu, unsigned ppi)
Raise a private peripheral interrupt.
void setSPI(unsigned spi)
Raise a shared peripheral interrupt.
KvmKernelGic(KvmVM &vm, uint32_t dev, unsigned it_lines)
Instantiate a KVM in-kernel GIC model.
void clearPPI(unsigned vcpu, unsigned ppi)
Clear a private peripheral interrupt.
KvmDevice kdev
Kernel interface to the GIC.
void setIntState(unsigned type, unsigned vcpu, unsigned irq, bool high)
Update the kernel's VGIC interrupt state.
void clearSPI(unsigned spi)
Clear a shared peripheral interrupt.
KvmVM & vm
KVM VM in the parent system.
long contextIdToVCpuId(ContextID ctx) const
Get the VCPUID for a given context.
Kvm * kvm
Global KVM interface.
bool capIRQLineLayout2() const
Support for ARM IRQ line layout 2.
System & system
System this interrupt controller belongs to.
void sendInt(uint32_t num) override
Tick write(PacketPtr pkt) override
KvmKernelGic * kernelGic
Kernel GIC device.
MuxingKvmGic(const Params &p)
typename Types::KvmGic KvmGic
bool blockIntUpdate() const override
Tick read(PacketPtr pkt) override
DrainState drain() override
void clearInt(uint32_t num) override
void clearPPInt(uint32_t num, uint32_t cpu) override
void drainResume() override
typename Types::Params Params
typename Types::SimGic SimGic
void fromGicToKvm()
Multiplexing implementation.
void sendPPInt(uint32_t num, uint32_t cpu) override
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
KvmVM * getKvmVM() const
Get a pointer to the Kernel Virtual Machine (KVM) SimObject, if present.
void setIRQLine(uint32_t irq, bool high)
Set the status of an IRQ line using KVM_IRQ_LINE.
void enableKernelIRQChip()
Tell the VM and VCPUs to use an in-kernel IRQ chip for interrupt delivery.
AddrRange RangeSize(Addr start, Addr size)
DrainState
Object drain/handover states.
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
MiscRegNum64 encodeAArch64SysReg(MiscRegIndex misc_reg)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
int ContextID
Globally unique thread context ID.