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 kvm_vcpu |= vcpu2_index << KVM_ARM_IRQ_VCPU2_SHIFT;
102 panic_if((!vcpu2_enabled && vcpu2_index) || kvm_vcpu > 0xffff,
103 "VCPU out of range");
105 assert(
type <= KVM_ARM_IRQ_TYPE_MASK);
106 assert(
irq <= KVM_ARM_IRQ_NUM_MASK);
109 (
type << KVM_ARM_IRQ_TYPE_SHIFT) |
110 (
irq << KVM_ARM_IRQ_NUM_SHIFT));
116 const MuxingKvmGicV2Params &
p)
118 cpuRange(
RangeSize(
p.cpu_addr, KVM_VGIC_V2_CPU_SIZE)),
119 distRange(
RangeSize(
p.dist_addr, KVM_VGIC_V2_DIST_SIZE))
122 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST,
p.dist_addr);
124 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_CPU,
p.cpu_addr);
132 assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
134 ((uint64_t)vcpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) |
135 (
offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
138 return (uint32_t)
reg;
145 uint64_t
reg = value;
147 assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
149 ((uint64_t)vcpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) |
150 (
offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
159 return getGicReg(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, vcpu, daddr);
166 return getGicReg(KVM_DEV_ARM_VGIC_GRP_CPU_REGS, vcpu, daddr);
173 setGicReg(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, vcpu, daddr,
data);
184 #define SZ_64K 0x00000040
188 const MuxingKvmGicV3Params &
p)
190 redistRange(
RangeSize(
p.redist_addr, KVM_VGIC_V3_REDIST_SIZE)),
191 distRange(
RangeSize(
p.dist_addr, KVM_VGIC_V3_DIST_SIZE))
194 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_DIST,
p.dist_addr);
196 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_REDIST,
p.redist_addr);
203 KVM_DEV_ARM_VGIC_GRP_CTRL, KVM_DEV_ARM_VGIC_CTRL_INIT, 0);
206 template <
typename Ret>
212 assert(mpidr <= KVM_DEV_ARM_VGIC_V3_MPIDR_MASK);
214 ((uint64_t)mpidr << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT) |
215 (
offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
221 template <
typename Arg>
228 assert(mpidr <= KVM_DEV_ARM_VGIC_V3_MPIDR_MASK);
230 ((uint64_t)mpidr << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT) |
231 (
offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
239 return getGicReg<uint32_t>(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, 0, daddr);
245 return getGicReg<uint32_t>(KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, aff, daddr);
253 return getGicReg<RegVal>(KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS, aff, sys_reg);
259 setGicReg<uint32_t>(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, 0, daddr,
data);
266 setGicReg<uint32_t>(KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, aff, daddr,
data);
275 setGicReg<RegVal>(KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS, aff, sys_reg,
data);
278 template <
class Types>
286 if (
vm && !
p.simulate_gic) {
291 template <
class Types>
301 if (
vm &&
vm->validEnvironment()) {
308 template <
class Types>
314 return SimGic::drain();
317 template <
class Types>
321 SimGic::drainResume();
324 bool use_kvm = kernelGic &&
vm &&
vm->validEnvironment();
325 if (use_kvm != usingKvm) {
335 template <
class Types>
340 return SimGic::read(pkt);
342 panic(
"MuxingKvmGic: PIO from gem5 is currently unsupported\n");
345 template <
class Types>
350 return SimGic::write(pkt);
352 panic(
"MuxingKvmGic: PIO from gem5 is currently unsupported\n");
355 template <
class Types>
360 return SimGic::sendInt(num);
363 kernelGic->setSPI(num);
366 template <
class Types>
371 return SimGic::clearInt(num);
374 kernelGic->clearSPI(num);
377 template <
class Types>
382 return SimGic::sendPPInt(num, cpu);
384 kernelGic->setPPI(cpu, num);
387 template <
class Types>
392 return SimGic::clearPPInt(num, cpu);
395 kernelGic->clearPPI(cpu, num);
398 template <
class Types>
409 template <
class Types>
413 this->copyGicState(
static_cast<SimGic*
>(
this),
414 static_cast<KvmGic*
>(kernelGic));
417 template <
class Types>
421 this->copyGicState(
static_cast<KvmGic*
>(kernelGic),
422 static_cast<SimGic*
>(
this));
428 if constexpr(std::is_same<SimGic, GicV2>::value) {
429 for (
int cpu = 0; cpu <
system.threads.size(); ++cpu) {
430 this->cpuPriority[cpu] <<= 3;
431 assert((this->cpuPriority[cpu] & ~0xff) == 0);