43 #include "debug/Checkpoint.hh" 44 #include "debug/VGIC.hh" 50 :
PioDevice(p), gicvIIDR(p->gicv_iidr), platform(p->platform),
51 gic(p->
gic), vcpuAddr(p->vcpu_addr), hvAddr(p->hv_addr),
52 pioDelay(p->pio_delay), maintInt(p->maint_int)
57 "Post VInterrupt to CPU");
103 struct vcpuIntData *vid = &
vcpuData[ctx_id];
105 DPRINTF(VGIC,
"VGIC VCPU read register %#x\n", daddr);
109 pkt->
setLE<uint32_t>(vid->vctrl);
113 if (i < 0 || !vid->vctrl.En) {
114 pkt->
setLE<uint32_t>(1023);
116 ListReg *lr = &vid->LR[
i];
118 pkt->
setLE<uint32_t>(lr->VirtualID |
119 (((int)lr->CpuID) << 10));
123 panic(
"VGIC does not support 'HW' List Register feature (LR %#x)!\n",
126 DPRINTF(VGIC,
"Consumed interrupt %d (cpu%d) from LR%d (EOI%d)\n",
127 lr->VirtualID, lr->CpuID, i, lr->EOI);
134 panic(
"VGIC VCPU read of bad address %#x\n", daddr);
150 DPRINTF(VGIC,
"VGIC HVCtrl read register %#x\n", daddr);
155 if (daddr & ~0x1ff) {
156 ctx_id = (daddr >> 9);
158 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
162 struct vcpuIntData *vid = &
vcpuData[ctx_id];
166 pkt->
setLE<uint32_t>(vid->hcr);
174 pkt->
setLE<uint32_t>(
175 ((uint32_t)vid->VMPriMask << 27) |
176 ((uint32_t)vid->VMBP << 21) |
177 ((uint32_t)vid->VMABP << 18) |
178 ((uint32_t)vid->VEM << 9) |
179 ((uint32_t)vid->VMCBPR << 4) |
180 ((uint32_t)vid->VMFiqEn << 3) |
181 ((uint32_t)vid->VMAckCtl << 2) |
182 ((uint32_t)vid->VMGrp1En << 1) |
183 ((uint32_t)vid->VMGrp0En << 0)
192 pkt->
setLE<uint32_t>(vid->eisr & 0xffffffff);
196 pkt->
setLE<uint32_t>(vid->eisr >> 32);
202 if (!vid->LR[
i].State)
205 pkt->
setLE<uint32_t>(bm);
211 if (!vid->LR[
i].State)
214 pkt->
setLE<uint32_t>(bm);
219 pkt->
setLE<uint32_t>(0);
230 panic(
"VGIC HVCtrl read of bad address %#x\n", daddr);
244 struct vcpuIntData *vid = &
vcpuData[ctx_id];
246 DPRINTF(VGIC,
"VGIC VCPU write register %#x <= %#x\n",
247 daddr, pkt->
getLE<uint32_t>());
251 vid->vctrl = pkt->
getLE<uint32_t>();
254 vid->VMPriMask = pkt->
getLE<uint32_t>();
259 assert(!vid->vctrl.EOImode);
260 uint32_t
w = pkt->
getLE<uint32_t>();
261 unsigned int virq = w & 0x3ff;
262 unsigned int vcpu = (w >> 10) & 7;
265 DPRINTF(VGIC,
"EOIR: No LR for irq %d(cpu%d)\n", virq, vcpu);
267 DPRINTF(VGIC,
"EOIR: Found LR%d for irq %d(cpu%d)\n", i, virq, vcpu);
268 ListReg *lr = &vid->LR[
i];
275 panic(
"VGIC VCPU write %#x to unk address %#x\n",
276 pkt->
getLE<uint32_t>(), daddr);
293 DPRINTF(VGIC,
"VGIC HVCtrl write register %#x <= %#x\n",
294 daddr, pkt->
getLE<uint32_t>());
299 if (daddr & ~0x1ff) {
300 ctx_id = (daddr >> 9);
302 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
306 struct vcpuIntData *vid = &
vcpuData[ctx_id];
310 vid->hcr = pkt->
getLE<uint32_t>();
315 uint32_t
d = pkt->
getLE<uint32_t>();
316 vid->VMPriMask = d >> 27;
317 vid->VMBP = (d >> 21) & 7;
318 vid->VMABP = (d >> 18) & 7;
319 vid->VEM = (d >> 9) & 1;
320 vid->VMCBPR = (d >> 4) & 1;
321 vid->VMFiqEn = (d >> 3) & 1;
322 vid->VMAckCtl = (d >> 2) & 1;
323 vid->VMGrp1En = (d >> 1) & 1;
324 vid->VMGrp0En = d & 1;
328 warn_once(
"VGIC GICH_APR0 written, ignored\n");
340 panic(
"VGIC HVCtrl write to bad address %#x\n", daddr);
353 return (!!vid->hcr.VGrp1DIE && !vid->VMGrp1En ? 0x80 : 0) |
354 (!!vid->hcr.VGrp1EIE && vid->VMGrp1En ? 0x40 : 0) |
355 (!!vid->hcr.VGrp0DIE && !vid->VMGrp0En ? 0x20 : 0) |
356 (!!vid->hcr.VGrp0EIE && vid->VMGrp0En ? 0x10 : 0) |
357 (!!vid->hcr.NPIE && !
lrPending(vid) ? 0x08 : 0) |
358 (!!vid->hcr.LRENPIE && vid->hcr.EOICount ? 0x04 : 0) |
359 (!!vid->hcr.UIE &&
lrValid(vid) <= 1 ? 0x02 : 0) |
360 (vid->eisr ? 0x01 : 0);
366 DPRINTF(VGIC,
"Posting VIRQ to %d\n", cpu);
374 DPRINTF(VGIC,
"Unposting VIRQ to %d\n", cpu);
388 DPRINTF(VGIC,
"Posting maintenance PPI to GIC/cpu%d\n", cpu);
396 DPRINTF(VGIC,
"Unposting maintenance PPI to GIC/cpu%d\n", cpu);
410 struct vcpuIntData *tvid = &
vcpuData[ctx_id];
414 if (!tvid->LR[
i].State && tvid->LR[
i].EOI) {
415 tvid->eisr |= 1 <<
i;
435 if (vid->hcr.En &&
getMISR(vid)) {
440 if (!vid->hcr.En || !
getMISR(vid)) {
462 interrupt_time[cpu] = 0;
468 DPRINTF(Checkpoint,
"Serializing VGIC\n");
485 uint32_t vctrl_val = vctrl;
487 uint32_t hcr_val = hcr;
489 uint64_t eisr_val = eisr;
491 uint8_t VMGrp0En_val = VMGrp0En;
493 uint8_t VMGrp1En_val = VMGrp1En;
495 uint8_t VMAckCtl_val = VMAckCtl;
497 uint8_t VMFiqEn_val = VMFiqEn;
499 uint8_t VMCBPR_val = VMCBPR;
501 uint8_t VEM_val = VEM;
503 uint8_t VMABP_val = VMABP;
505 uint8_t VMBP_val = VMBP;
507 uint8_t VMPriMask_val = VMPriMask;
518 DPRINTF(Checkpoint,
"Unserializing Arm GIC\n");
523 if (interrupt_time[cpu])
539 paramIn(cp,
"vctrl_val", vctrl);
542 paramIn(cp,
"VMGrp0En_val", VMGrp0En);
543 paramIn(cp,
"VMGrp1En_val", VMGrp1En);
544 paramIn(cp,
"VMAckCtl_val", VMAckCtl);
545 paramIn(cp,
"VMFiqEn_val", VMFiqEn);
546 paramIn(cp,
"VMCBPR_val", VMCBPR);
548 paramIn(cp,
"VMABP_val", VMABP);
549 paramIn(cp,
"VMPriMask_val", VMPriMask);
560 return new VGic(
this);
EventQueue * eventq
A pointer to this object's event queue.
#define panic(...)
This implements a cprintf based panic() function.
AddrRange RangeSize(Addr start, Addr size)
static const int GICH_HCR
static const int GICH_VTR
static const int GICV_CTLR
EndBitUnion(VCTLR) struct vcpuIntData struct std::array< vcpuIntData, VGIC_CPU_MAX > vcpuData
static const int GICV_SIZE
Implementiation of a GIC-400 List Register-based VGIC interface.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Tick when() const
Get the time that the event is scheduled.
void post(int cpu_id, int int_num, int index)
unsigned int lrValid(struct vcpuIntData *vid)
bool maintIntPosted[VGIC_CPU_MAX]
uint32_t getMISR(struct vcpuIntData *vid)
static const int GICV_IIDR
static const int GICH_LR3
void processPostVIntEvent(uint32_t cpu)
Post interrupt to CPU.
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
int numRunningContexts()
Return number of running (non-halted) thread contexts in system.
void setLE(T v)
Set the value in the data pointer to v as little endian.
RequestPtr req
A pointer to the original request.
#define UNSERIALIZE_SCALAR(scalar)
Tick curTick()
The current simulated tick.
void updateIntState(ContextID ctx_id)
std::string csprintf(const char *format, const Args &...args)
static const int GICH_MISR
virtual void sendPPInt(uint32_t num, uint32_t cpu)=0
Interface call for private peripheral interrupts.
void makeAtomicResponse()
uint64_t Tick
Tick count type.
void unPostVInt(uint32_t cpu)
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
void serialize(CheckpointOut &cp) const override
Serialize an object.
EventFunctionWrapper * postVIntEvent[VGIC_CPU_MAX]
#define SERIALIZE_ARRAY(member, size)
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
This device is the base class which all devices senstive to an address range inherit from...
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
void postMaintInt(uint32_t cpu)
Tick readVCpu(PacketPtr pkt)
#define SERIALIZE_SCALAR(scalar)
#define UNSERIALIZE_ARRAY(member, size)
static const int GICH_ELSR1
static const int GICH_LR0
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Base class for ARM GIC implementations.
static const int GICH_VMCR
void unserialize(CheckpointIn &cp) override
Unserialize an object.
unsigned int lrPending(struct vcpuIntData *vid)
Declaration of the Packet class.
std::ostream CheckpointOut
static const int GICH_LR2
static const int GICV_EOIR
static const int VGIC_CPU_MAX
int findLRForVIRQ(struct vcpuIntData *vid, int virq, int vcpu)
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
int findHighestPendingLR(struct vcpuIntData *vid)
Returns LR index or -1 if none pending.
Tick writeCtrl(PacketPtr pkt)
void schedule(Event &event, Tick when)
static const int GICH_LR1
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void unserialize(ThreadContext &tc, CheckpointIn &cp)
void postVInt(uint32_t cpu, Tick when)
Tick writeVCpu(PacketPtr pkt)
static const int GICH_APR0
static const uint32_t LR_ACTIVE
void clear(int cpu_id, int int_num, int index)
Scoped checkpoint section helper class.
Tick readCtrl(PacketPtr pkt)
static const int GICH_ELSR0
static const int GICH_REG_SIZE
static const int GICV_PMR
static const int GICH_EISR1
int ContextID
Globally unique thread context ID.
static const int GICH_EISR0
bool vIntPosted[VGIC_CPU_MAX]
void unPostMaintInt(uint32_t cpu)
static const int GICV_IAR
virtual void clearPPInt(uint32_t num, uint32_t cpu)=0