40 #include <linux/kvm.h>
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);
209 template <
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));
224 template <
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);
281 template <
class Types>
289 if (
vm && !
p.simulate_gic) {
294 template <
class Types>
304 if (
vm &&
vm->validEnvironment()) {
311 template <
class Types>
317 return SimGic::drain();
320 template <
class Types>
324 SimGic::drainResume();
327 bool use_kvm = kernelGic &&
vm &&
vm->validEnvironment();
328 if (use_kvm != usingKvm) {
338 template <
class Types>
343 return SimGic::read(pkt);
345 panic(
"MuxingKvmGic: PIO from gem5 is currently unsupported\n");
348 template <
class Types>
353 return SimGic::write(pkt);
355 panic(
"MuxingKvmGic: PIO from gem5 is currently unsupported\n");
358 template <
class Types>
363 return SimGic::sendInt(num);
366 kernelGic->setSPI(num);
369 template <
class Types>
374 return SimGic::clearInt(num);
377 kernelGic->clearSPI(num);
380 template <
class Types>
385 return SimGic::sendPPInt(num, cpu);
387 kernelGic->setPPI(cpu, num);
390 template <
class Types>
395 return SimGic::clearPPInt(num, cpu);
398 kernelGic->clearPPI(cpu, num);
401 template <
class Types>
412 template <
class Types>
416 this->copyGicState(
static_cast<SimGic*
>(
this),
417 static_cast<KvmGic*
>(kernelGic));
420 template <
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);