43 #include <linux/kvm.h>
46 #include "debug/GIC.hh"
47 #include "debug/Interrupt.hh"
48 #include "params/MuxingKvmGic.hh"
52 : cpuRange(
RangeSize(cpu_addr, KVM_VGIC_V2_CPU_SIZE)),
53 distRange(
RangeSize(dist_addr, KVM_VGIC_V2_DIST_SIZE)),
55 kdev(
vm.createDevice(KVM_DEV_TYPE_ARM_VGIC_V2))
58 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST, dist_addr);
60 KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_CPU, cpu_addr);
62 kdev.
setAttr<uint32_t>(KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0, it_lines);
90 setIntState(KVM_ARM_IRQ_TYPE_PPI, vcpu, ppi,
false);
97 assert(type <= KVM_ARM_IRQ_TYPE_MASK);
98 assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
99 assert(irq <= KVM_ARM_IRQ_NUM_MASK);
101 (type << KVM_ARM_IRQ_TYPE_SHIFT) |
102 (vcpu << KVM_ARM_IRQ_VCPU_SHIFT) |
103 (irq << KVM_ARM_IRQ_NUM_SHIFT));
113 assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
115 (vcpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) |
116 (offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
119 return (uint32_t)
reg;
126 uint64_t
reg = value;
128 assert(vcpu <= KVM_ARM_IRQ_VCPU_MASK);
130 (vcpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) |
131 (offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT));
140 return getGicReg(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, vcpu, daddr);
147 return getGicReg(KVM_DEV_ARM_VGIC_GRP_CPU_REGS, vcpu, daddr);
154 setGicReg(KVM_DEV_ARM_VGIC_GRP_DIST_REGS, vcpu, daddr, data);
161 setGicReg(KVM_DEV_ARM_VGIC_GRP_CPU_REGS, vcpu, daddr, data);
239 panic(
"MuxingKvmGic: PIO from gem5 is currently unsupported\n");
248 panic(
"MuxingKvmGic: PIO from gem5 is currently unsupported\n");
257 DPRINTF(Interrupt,
"Set SPI %d\n", num);
267 DPRINTF(Interrupt,
"Clear SPI %d\n", num);
276 DPRINTF(Interrupt,
"Set PPI %d:%d\n", cpu, num);
286 DPRINTF(Interrupt,
"Clear PPI %d:%d\n", cpu, num);
297 if (dynamic_cast<BaseArmKvmCPU*>(tc->getCpuPtr()) ==
nullptr) {
309 DPRINTF(GIC,
"copy dist 0x%x 0x%08x\n", daddr,
val);
318 DPRINTF(GIC,
"copy cpu 0x%x 0x%08x\n", daddr,
val);
327 for (
auto a = daddr;
a < daddr +
size;
a += 4)
336 for (
auto a = daddr;
a < daddr +
size;
a += 4)
344 for (
auto a = daddr;
a < daddr +
size;
a += 4)
352 for (
auto a = daddr;
a < daddr +
size;
a += 4)
384 set += 4, clear += 4, size -= 4;
395 set += 4, clear += 4, size -= 4;
406 set += 4, clear += 4, size -= 4;
451 MuxingKvmGicParams::create()
void writeDistributor(ContextID ctx, Addr daddr, uint32_t data) override
AddrRange RangeSize(Addr start, Addr size)
Tick write(PacketPtr pkt) override
A PIO read to the device, immediately split up into writeDistributor() or writeCpu() ...
void setAttrPtr(uint32_t group, uint64_t attr, const void *data) const
void fromPl390ToKvm()
Multiplexing implementation.
uint32_t getGicReg(unsigned group, unsigned vcpu, unsigned offset)
Get value of GIC register "from" a cpu.
System & system
System this interrupt controller belongs to.
void sendInt(uint32_t num) override
Post an interrupt from a device that is connected to the GIC.
void setPPI(unsigned vcpu, unsigned ppi)
Raise a private peripheral interrupt.
virtual uint32_t readCpu(ContextID ctx, Addr daddr)=0
void clearInt(uint32_t number) override
Clear an interrupt from a device that is connected to the GIC.
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
void clearPPInt(uint32_t num, uint32_t cpu) override
virtual uint32_t readDistributor(ContextID ctx, Addr daddr)=0
Addr start() const
Get the start address of the range.
DrainState
Object drain/handover states.
void copyDistRange(BaseGicRegisters *from, BaseGicRegisters *to, Addr daddr, size_t size)
static const AddrRange GICD_ITARGETSR
void serialize(CheckpointOut &cp) const override
Serialize an object.
void serialize(CheckpointOut &cp) const override
Serialize an object.
uint32_t itLines
Number of itLines enabled.
void loadState(CheckpointIn &cp) override
loadState() is called on each SimObject when restoring from a checkpoint.
long contextIdToVCpuId(ContextID ctx) const
Get the VCPUID for a given context.
static const AddrRange GICD_ISACTIVER
void sendPPInt(uint32_t num, uint32_t cpu) override
Interface call for private peripheral interrupts.
Tick read(PacketPtr pkt) override
A PIO read to the device, immediately split up into readDistributor() or readCpu() ...
static const AddrRange GICD_ISENABLER
static const AddrRange GICD_ISPENDR
void setIntState(unsigned type, unsigned vcpu, unsigned irq, bool high)
Update the kernel's VGIC interrupt state.
static const AddrRange GICD_ICACTIVER
void clearPPInt(uint32_t num, uint32_t cpu) override
void setIRQLine(uint32_t irq, bool high)
Set the status of an IRQ line using KVM_IRQ_LINE.
void getAttrPtr(uint32_t group, uint64_t attr, void *data) const
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool validKvmEnvironment() const
Verify gem5 configuration will support KVM emulation.
void clearDistRange(BaseGicRegisters *to, Addr daddr, size_t size)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
void sendInt(uint32_t number) override
Post an interrupt from a device that is connected to the GIC.
uint64_t Tick
Tick count type.
void copyCpuRegister(BaseGicRegisters *from, BaseGicRegisters *to, ContextID ctx, Addr daddr)
void clearBankedDistRange(BaseGicRegisters *to, Addr daddr, size_t size)
KvmVM * getKvmVM()
Get a pointer to the Kernel Virtual Machine (KVM) SimObject, if present.
std::vector< ThreadContext * > threadContexts
static const AddrRange GICD_ICPENDR
DrainState drain() override
Notify an object that it needs to drain its state.
void copyBankedDistRange(BaseGicRegisters *from, BaseGicRegisters *to, Addr daddr, size_t size)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
DrainState drain() override
Notify an object that it needs to drain its state.
void clearPPI(unsigned vcpu, unsigned ppi)
Clear a private peripheral interrupt.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
virtual void writeDistributor(ContextID ctx, Addr daddr, uint32_t data)=0
void copyDistRegister(BaseGicRegisters *from, BaseGicRegisters *to, ContextID ctx, Addr daddr)
uint8_t cpuPriority[CPU_MAX]
CPU priority.
KvmKernelGicV2 * kernelGic
Kernel GIC device.
void startup() override
startup() is the final initialization call before simulation.
void writeCpu(ContextID ctx, Addr daddr, uint32_t data) override
KVM in-kernel GIC abstraction.
std::ostream CheckpointOut
KvmVM & vm
KVM VM in the parent system.
virtual ~KvmKernelGicV2()
static const AddrRange GICD_ICFGR
virtual void drainResume()
Resume execution after a successful drain.
static const AddrRange GICD_IPRIORITYR
virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data)=0
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void drainResume() override
Resume execution after a successful drain.
static const AddrRange GICD_ICENABLER
void copyGicState(BaseGicRegisters *from, BaseGicRegisters *to)
KvmDevice kdev
Kernel interface to the GIC.
KvmKernelGicV2(KvmVM &vm, Addr cpu_addr, Addr dist_addr, unsigned it_lines)
Instantiate a KVM in-kernel GIC model.
void setSPI(unsigned spi)
Raise a shared peripheral interrupt.
void setGicReg(unsigned group, unsigned vcpu, unsigned offset, unsigned value)
Set value of GIC register "from" a cpu.
void sendPPInt(uint32_t num, uint32_t cpu) override
Interface call for private peripheral interrupts.
void setAttr(uint32_t group, uint64_t attr, const T &data) const
Get the value of an attribute.
void clearSPI(unsigned spi)
Clear a shared peripheral interrupt.
void clearInt(uint32_t num) override
Clear an interrupt from a device that is connected to the GIC.
MuxingKvmGic(const MuxingKvmGicParams *p)
int ContextID
Globally unique thread context ID.
uint32_t readDistributor(ContextID ctx, Addr daddr) override
BaseGicRegisters interface.
uint32_t readCpu(ContextID ctx, Addr daddr) override
virtual void loadState(CheckpointIn &cp)
loadState() is called on each SimObject when restoring from a checkpoint.
virtual void startup()
startup() is the final initialization call before simulation.