43#include "debug/Checkpoint.hh"
44#include "debug/VGIC.hh"
53 :
PioDevice(
p), gicvIIDR(
p.gicv_iidr), platform(
p.platform),
54 gic(
p.
gic), vcpuAddr(
p.vcpu_addr), hvAddr(
p.hv_addr),
55 pioDelay(
p.pio_delay), maintInt(
p.maint_int)
60 "Post VInterrupt to CPU");
106 struct vcpuIntData *vid = &
vcpuData[ctx_id];
108 DPRINTF(VGIC,
"VGIC VCPU read register %#x\n", daddr);
112 pkt->
setLE<uint32_t>(vid->vctrl);
117 pkt->
setLE<uint32_t>(1023);
119 ListReg *lr = &vid->LR[
i];
121 pkt->
setLE<uint32_t>(lr->VirtualID |
122 (((int)lr->CpuID) << 10));
126 panic(
"VGIC does not support 'HW' List Register feature (LR %#x)!\n",
129 DPRINTF(VGIC,
"Consumed interrupt %d (cpu%d) from LR%d (EOI%d)\n",
130 lr->VirtualID, lr->CpuID,
i, lr->EOI);
137 panic(
"VGIC VCPU read of bad address %#x\n", daddr);
153 DPRINTF(VGIC,
"VGIC HVCtrl read register %#x\n", daddr);
158 if (daddr & ~0x1ff) {
159 ctx_id = (daddr >> 9);
161 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
165 struct vcpuIntData *vid = &
vcpuData[ctx_id];
169 pkt->
setLE<uint32_t>(vid->hcr);
177 pkt->
setLE<uint32_t>(
178 ((uint32_t)vid->VMPriMask << 27) |
179 ((uint32_t)vid->VMBP << 21) |
180 ((uint32_t)vid->VMABP << 18) |
181 ((uint32_t)vid->VEM << 9) |
182 ((uint32_t)vid->VMCBPR << 4) |
183 ((uint32_t)vid->VMFiqEn << 3) |
184 ((uint32_t)vid->VMAckCtl << 2) |
185 ((uint32_t)vid->VMGrp1En << 1) |
186 ((uint32_t)vid->VMGrp0En << 0)
195 pkt->
setLE<uint32_t>(vid->eisr & 0xffffffff);
199 pkt->
setLE<uint32_t>(vid->eisr >> 32);
205 if (!vid->LR[
i].State)
208 pkt->
setLE<uint32_t>(bm);
214 if (!vid->LR[
i].State)
217 pkt->
setLE<uint32_t>(bm);
222 pkt->
setLE<uint32_t>(0);
233 panic(
"VGIC HVCtrl read of bad address %#x\n", daddr);
247 struct vcpuIntData *vid = &
vcpuData[ctx_id];
249 DPRINTF(VGIC,
"VGIC VCPU write register %#x <= %#x\n",
250 daddr, pkt->
getLE<uint32_t>());
254 vid->vctrl = pkt->
getLE<uint32_t>();
257 vid->VMPriMask = pkt->
getLE<uint32_t>();
262 assert(!vid->vctrl.EOImode);
263 uint32_t
w = pkt->
getLE<uint32_t>();
264 unsigned int virq =
w & 0x3ff;
265 unsigned int vcpu = (
w >> 10) & 7;
268 DPRINTF(VGIC,
"EOIR: No LR for irq %d(cpu%d)\n", virq, vcpu);
270 DPRINTF(VGIC,
"EOIR: Found LR%d for irq %d(cpu%d)\n",
i, virq, vcpu);
271 ListReg *lr = &vid->LR[
i];
278 panic(
"VGIC VCPU write %#x to unk address %#x\n",
279 pkt->
getLE<uint32_t>(), daddr);
296 DPRINTF(VGIC,
"VGIC HVCtrl write register %#x <= %#x\n",
297 daddr, pkt->
getLE<uint32_t>());
302 if (daddr & ~0x1ff) {
303 ctx_id = (daddr >> 9);
305 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
309 struct vcpuIntData *vid = &
vcpuData[ctx_id];
313 vid->hcr = pkt->
getLE<uint32_t>();
318 uint32_t
d = pkt->
getLE<uint32_t>();
319 vid->VMPriMask =
d >> 27;
320 vid->VMBP = (
d >> 21) & 7;
321 vid->VMABP = (
d >> 18) & 7;
322 vid->VEM = (
d >> 9) & 1;
323 vid->VMCBPR = (
d >> 4) & 1;
324 vid->VMFiqEn = (
d >> 3) & 1;
325 vid->VMAckCtl = (
d >> 2) & 1;
326 vid->VMGrp1En = (
d >> 1) & 1;
327 vid->VMGrp0En =
d & 1;
331 warn_once(
"VGIC GICH_APR0 written, ignored\n");
343 panic(
"VGIC HVCtrl write to bad address %#x\n", daddr);
356 return (!!vid->hcr.VGrp1DIE && !vid->VMGrp1En ? 0x80 : 0) |
357 (!!vid->hcr.VGrp1EIE && vid->VMGrp1En ? 0x40 : 0) |
358 (!!vid->hcr.VGrp0DIE && !vid->VMGrp0En ? 0x20 : 0) |
359 (!!vid->hcr.VGrp0EIE && vid->VMGrp0En ? 0x10 : 0) |
360 (!!vid->hcr.NPIE && !
lrPending(vid) ? 0x08 : 0) |
361 (!!vid->hcr.LRENPIE && vid->hcr.EOICount ? 0x04 : 0) |
362 (!!vid->hcr.UIE &&
lrValid(vid) <= 1 ? 0x02 : 0) |
363 (vid->eisr ? 0x01 : 0);
369 DPRINTF(VGIC,
"Posting VIRQ to %d\n", cpu);
377 DPRINTF(VGIC,
"Unposting VIRQ to %d\n", cpu);
378 auto tc =
platform->system->threads[cpu];
385 auto tc =
platform->system->threads[cpu];
393 DPRINTF(VGIC,
"Posting maintenance PPI to GIC/cpu%d\n", cpu);
401 DPRINTF(VGIC,
"Unposting maintenance PPI to GIC/cpu%d\n", cpu);
415 struct vcpuIntData *tvid = &
vcpuData[ctx_id];
419 if (!tvid->LR[
i].State && tvid->LR[
i].EOI) {
420 tvid->eisr |= 1 <<
i;
440 if (vid->hcr.En &&
getMISR(vid)) {
445 if (!vid->hcr.En || !
getMISR(vid)) {
467 interrupt_time[cpu] = 0;
473 DPRINTF(Checkpoint,
"Serializing VGIC\n");
490 uint32_t vctrl_val = vctrl;
492 uint32_t hcr_val = hcr;
494 uint64_t eisr_val = eisr;
496 uint8_t VMGrp0En_val = VMGrp0En;
498 uint8_t VMGrp1En_val = VMGrp1En;
500 uint8_t VMAckCtl_val = VMAckCtl;
502 uint8_t VMFiqEn_val = VMFiqEn;
504 uint8_t VMCBPR_val = VMCBPR;
506 uint8_t VEM_val = VEM;
508 uint8_t VMABP_val = VMABP;
510 uint8_t VMBP_val = VMBP;
512 uint8_t VMPriMask_val = VMPriMask;
515 for (
int i = 0;
i < NUM_LR;
i++) {
516 ScopedCheckpointSection sec_lr(cp,
csprintf(
"LR%d",
i));
523 DPRINTF(Checkpoint,
"Unserializing Arm GIC\n");
528 if (interrupt_time[cpu])
544 paramIn(cp,
"vctrl_val", vctrl);
547 paramIn(cp,
"VMGrp0En_val", VMGrp0En);
548 paramIn(cp,
"VMGrp1En_val", VMGrp1En);
549 paramIn(cp,
"VMAckCtl_val", VMAckCtl);
550 paramIn(cp,
"VMFiqEn_val", VMFiqEn);
551 paramIn(cp,
"VMCBPR_val", VMCBPR);
553 paramIn(cp,
"VMABP_val", VMABP);
554 paramIn(cp,
"VMPriMask_val", VMPriMask);
556 for (
int i = 0;
i < NUM_LR;
i++) {
557 ScopedCheckpointSection sec_lr(cp,
csprintf(
"LR%d",
i));
Base class for ARM GIC implementations.
virtual void sendPPInt(uint32_t num, uint32_t cpu)=0
Interface call for private peripheral interrupts.
virtual void clearPPInt(uint32_t num, uint32_t cpu)=0
EventQueue * eventq
A pointer to this object's event queue.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setLE(T v)
Set the value in the data pointer to v as little endian.
RequestPtr req
A pointer to the original request.
void makeAtomicResponse()
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
This device is the base class which all devices senstive to an address range inherit from.
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Tick writeCtrl(PacketPtr pkt)
static const int GICH_LR2
static const int GICV_CTLR
static const int GICH_HCR
static const int GICH_MISR
static const int GICH_ELSR1
Tick readVCpu(PacketPtr pkt)
void postVInt(uint32_t cpu, Tick when)
void unPostMaintInt(uint32_t cpu)
EventFunctionWrapper * postVIntEvent[VGIC_CPU_MAX]
static const int GICH_VMCR
Tick readCtrl(PacketPtr pkt)
uint32_t getMISR(struct vcpuIntData *vid)
int findLRForVIRQ(struct vcpuIntData *vid, int virq, int vcpu)
void serialize(CheckpointOut &cp) const override
Serialize an object.
static const int GICH_EISR0
unsigned int lrPending(struct vcpuIntData *vid)
static const int GICH_REG_SIZE
unsigned int lrValid(struct vcpuIntData *vid)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
int findHighestPendingLR(struct vcpuIntData *vid)
Returns LR index or -1 if none pending.
static const uint32_t LR_ACTIVE
static const int GICH_LR1
static const int GICV_EOIR
static const int GICH_APR0
static const int GICH_LR0
static const int GICV_PMR
bool maintIntPosted[VGIC_CPU_MAX]
bool vIntPosted[VGIC_CPU_MAX]
void unPostVInt(uint32_t cpu)
Tick writeVCpu(PacketPtr pkt)
EndBitUnion(VCTLR) struct vcpuIntData struct std::array< vcpuIntData, VGIC_CPU_MAX > vcpuData
static const int GICH_LR3
void updateIntState(ContextID ctx_id)
static const int GICV_SIZE
static const int VGIC_CPU_MAX
void postMaintInt(uint32_t cpu)
static const int GICH_VTR
static const int GICV_IIDR
void unserialize(CheckpointIn &cp) override
Unserialize an object.
static const int GICV_IAR
static const int GICH_EISR1
static const int GICH_ELSR0
void processPostVIntEvent(uint32_t cpu)
Post interrupt to CPU.
AddrRange RangeSize(Addr start, Addr size)
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
void schedule(Event &event, Tick when)
Tick when() const
Get the time that the event is scheduled.
#define panic(...)
This implements a cprintf based panic() function.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
#define UNSERIALIZE_ARRAY(member, size)
#define SERIALIZE_ARRAY(member, size)
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
uint64_t Tick
Tick count type.
int ContextID
Globally unique thread context ID.
std::string csprintf(const char *format, const Args &...args)
Declaration of the Packet class.
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)
Implementiation of a GIC-400 List Register-based VGIC interface.