43#include "debug/Checkpoint.hh"
44#include "debug/VGIC.hh"
48#include "params/VGic.hh"
61 "Post VInterrupt to CPU");
107 struct vcpuIntData *vid = &
vcpuData[ctx_id];
109 DPRINTF(VGIC,
"VGIC VCPU read register %#x\n", daddr);
113 pkt->
setLE<uint32_t>(vid->vctrl);
118 pkt->
setLE<uint32_t>(1023);
120 ListReg *lr = &vid->LR[
i];
122 pkt->
setLE<uint32_t>(lr->VirtualID |
123 (((int)lr->CpuID) << 10));
127 panic(
"VGIC does not support 'HW' List Register feature (LR %#x)!\n",
130 DPRINTF(VGIC,
"Consumed interrupt %d (cpu%d) from LR%d (EOI%d)\n",
131 lr->VirtualID, lr->CpuID,
i, lr->EOI);
138 panic(
"VGIC VCPU read of bad address %#x\n", daddr);
154 DPRINTF(VGIC,
"VGIC HVCtrl read register %#x\n", daddr);
159 if (daddr & ~0x1ff) {
160 ctx_id = (daddr >> 9);
162 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
166 struct vcpuIntData *vid = &
vcpuData[ctx_id];
170 pkt->
setLE<uint32_t>(vid->hcr);
178 pkt->
setLE<uint32_t>(
179 ((uint32_t)vid->VMPriMask << 27) |
180 ((uint32_t)vid->VMBP << 21) |
181 ((uint32_t)vid->VMABP << 18) |
182 ((uint32_t)vid->VEM << 9) |
183 ((uint32_t)vid->VMCBPR << 4) |
184 ((uint32_t)vid->VMFiqEn << 3) |
185 ((uint32_t)vid->VMAckCtl << 2) |
186 ((uint32_t)vid->VMGrp1En << 1) |
187 ((uint32_t)vid->VMGrp0En << 0)
196 pkt->
setLE<uint32_t>(vid->eisr & 0xffffffff);
200 pkt->
setLE<uint32_t>(vid->eisr >> 32);
206 if (!vid->LR[
i].State)
209 pkt->
setLE<uint32_t>(bm);
215 if (!vid->LR[
i].State)
218 pkt->
setLE<uint32_t>(bm);
223 pkt->
setLE<uint32_t>(0);
234 panic(
"VGIC HVCtrl read of bad address %#x\n", daddr);
248 struct vcpuIntData *vid = &
vcpuData[ctx_id];
250 DPRINTF(VGIC,
"VGIC VCPU write register %#x <= %#x\n",
251 daddr, pkt->
getLE<uint32_t>());
255 vid->vctrl = pkt->
getLE<uint32_t>();
258 vid->VMPriMask = pkt->
getLE<uint32_t>();
263 assert(!vid->vctrl.EOImode);
264 uint32_t
w = pkt->
getLE<uint32_t>();
265 unsigned int virq =
w & 0x3ff;
266 unsigned int vcpu = (
w >> 10) & 7;
269 DPRINTF(VGIC,
"EOIR: No LR for irq %d(cpu%d)\n", virq, vcpu);
271 DPRINTF(VGIC,
"EOIR: Found LR%d for irq %d(cpu%d)\n",
i, virq, vcpu);
272 ListReg *lr = &vid->LR[
i];
279 panic(
"VGIC VCPU write %#x to unk address %#x\n",
280 pkt->
getLE<uint32_t>(), daddr);
297 DPRINTF(VGIC,
"VGIC HVCtrl write register %#x <= %#x\n",
298 daddr, pkt->
getLE<uint32_t>());
303 if (daddr & ~0x1ff) {
304 ctx_id = (daddr >> 9);
306 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
310 struct vcpuIntData *vid = &
vcpuData[ctx_id];
314 vid->hcr = pkt->
getLE<uint32_t>();
319 uint32_t
d = pkt->
getLE<uint32_t>();
320 vid->VMPriMask =
d >> 27;
321 vid->VMBP = (
d >> 21) & 7;
322 vid->VMABP = (
d >> 18) & 7;
323 vid->VEM = (
d >> 9) & 1;
324 vid->VMCBPR = (
d >> 4) & 1;
325 vid->VMFiqEn = (
d >> 3) & 1;
326 vid->VMAckCtl = (
d >> 2) & 1;
327 vid->VMGrp1En = (
d >> 1) & 1;
328 vid->VMGrp0En =
d & 1;
332 warn_once(
"VGIC GICH_APR0 written, ignored\n");
344 panic(
"VGIC HVCtrl write to bad address %#x\n", daddr);
357 return (!!vid->hcr.VGrp1DIE && !vid->VMGrp1En ? 0x80 : 0) |
358 (!!vid->hcr.VGrp1EIE && vid->VMGrp1En ? 0x40 : 0) |
359 (!!vid->hcr.VGrp0DIE && !vid->VMGrp0En ? 0x20 : 0) |
360 (!!vid->hcr.VGrp0EIE && vid->VMGrp0En ? 0x10 : 0) |
361 (!!vid->hcr.NPIE && !
lrPending(vid) ? 0x08 : 0) |
362 (!!vid->hcr.LRENPIE && vid->hcr.EOICount ? 0x04 : 0) |
363 (!!vid->hcr.UIE &&
lrValid(vid) <= 1 ? 0x02 : 0) |
364 (vid->eisr ? 0x01 : 0);
370 DPRINTF(VGIC,
"Posting VIRQ to %d\n", cpu);
378 DPRINTF(VGIC,
"Unposting VIRQ to %d\n", cpu);
379 auto tc =
platform->system->threads[cpu];
386 auto tc =
platform->system->threads[cpu];
394 DPRINTF(VGIC,
"Posting maintenance PPI to GIC/cpu%d\n", cpu);
402 DPRINTF(VGIC,
"Unposting maintenance PPI to GIC/cpu%d\n", cpu);
416 struct vcpuIntData *tvid = &
vcpuData[ctx_id];
420 if (!tvid->LR[
i].State && tvid->LR[
i].EOI) {
421 tvid->eisr |= 1 <<
i;
426 for (
int i = 0;
i <
sys->threads.numRunning();
i++) {
441 if (vid->hcr.En &&
getMISR(vid)) {
446 if (!vid->hcr.En || !
getMISR(vid)) {
468 interrupt_time[cpu] = 0;
474 DPRINTF(Checkpoint,
"Serializing VGIC\n");
491 uint32_t vctrl_val = vctrl;
493 uint32_t hcr_val = hcr;
495 uint64_t eisr_val = eisr;
497 uint8_t VMGrp0En_val = VMGrp0En;
499 uint8_t VMGrp1En_val = VMGrp1En;
501 uint8_t VMAckCtl_val = VMAckCtl;
503 uint8_t VMFiqEn_val = VMFiqEn;
505 uint8_t VMCBPR_val = VMCBPR;
507 uint8_t VEM_val = VEM;
509 uint8_t VMABP_val = VMABP;
511 uint8_t VMBP_val = VMBP;
513 uint8_t VMPriMask_val = VMPriMask;
516 for (
int i = 0;
i < NUM_LR;
i++) {
517 ScopedCheckpointSection sec_lr(
cp,
csprintf(
"LR%d",
i));
524 DPRINTF(Checkpoint,
"Unserializing Arm GIC\n");
529 if (interrupt_time[cpu])
557 for (
int i = 0;
i < NUM_LR;
i++) {
558 ScopedCheckpointSection sec_lr(
cp,
csprintf(
"LR%d",
i));
Base class for ARM GIC implementations.
EventQueue * eventq
A pointer to this object's event queue.
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.
PioDevice(const Params &p)
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)
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
void schedule(Event &event, Tick when)
#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 Arm Limited 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.