43 #include "debug/Checkpoint.hh"
44 #include "debug/VGIC.hh"
51 :
PioDevice(p), platform(p->platform), gic(p->gic), vcpuAddr(p->vcpu_addr),
52 hvAddr(p->hv_addr), pioDelay(p->pio_delay),
96 struct vcpuIntData *vid = &
vcpuData[ctx_id];
98 DPRINTF(VGIC,
"VGIC VCPU read register %#x\n", daddr);
102 pkt->
set<uint32_t>(vid->vctrl);
106 if (i < 0 || !vid->
vctrl.En) {
107 pkt->
set<uint32_t>(1023);
109 ListReg *lr = &vid->LR[
i];
111 pkt->
set<uint32_t>(lr->VirtualID |
112 (((int)lr->CpuID) << 10));
116 panic(
"VGIC does not support 'HW' List Register feature (LR %#x)!\n",
119 DPRINTF(VGIC,
"Consumed interrupt %d (cpu%d) from LR%d (EOI%d)\n",
120 lr->VirtualID, lr->CpuID, i, lr->EOI);
124 panic(
"VGIC VCPU read of bad address %#x\n", daddr);
140 DPRINTF(VGIC,
"VGIC HVCtrl read register %#x\n", daddr);
145 if (daddr & ~0x1ff) {
146 ctx_id = (daddr >> 9);
148 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
152 struct vcpuIntData *vid = &
vcpuData[ctx_id];
156 pkt->
set<uint32_t>(vid->hcr);
160 pkt->
set<uint32_t>(0x44000000 | (
NUM_LR - 1));
165 ((uint32_t)vid->VMPriMask << 27) |
166 ((uint32_t)vid->VMBP << 21) |
167 ((uint32_t)vid->VMABP << 18) |
168 ((uint32_t)vid->VEM << 9) |
169 ((uint32_t)vid->VMCBPR << 4) |
170 ((uint32_t)vid->VMFiqEn << 3) |
171 ((uint32_t)vid->VMAckCtl << 2) |
172 ((uint32_t)vid->VMGrp1En << 1) |
173 ((uint32_t)vid->VMGrp0En << 0)
182 pkt->
set<uint32_t>(vid->eisr & 0xffffffff);
186 pkt->
set<uint32_t>(vid->eisr >> 32);
192 if (!vid->LR[
i].State)
195 pkt->
set<uint32_t>(bm);
201 if (!vid->LR[
i].State)
204 pkt->
set<uint32_t>(bm);
209 pkt->
set<uint32_t>(0);
216 pkt->
set<uint32_t>(vid->LR[(daddr -
GICH_LR0) >> 2]);
220 panic(
"VGIC HVCtrl read of bad address %#x\n", daddr);
234 struct vcpuIntData *vid = &
vcpuData[ctx_id];
236 DPRINTF(VGIC,
"VGIC VCPU write register %#x <= %#x\n", daddr, pkt->
get<uint32_t>());
240 vid->vctrl = pkt->
get<uint32_t>();
243 vid->VMPriMask = pkt->
get<uint32_t>();
248 assert(!vid->vctrl.EOImode);
249 uint32_t
w = pkt->
get<uint32_t>();
250 unsigned int virq = w & 0x3ff;
251 unsigned int vcpu = (w >> 10) & 7;
254 DPRINTF(VGIC,
"EOIR: No LR for irq %d(cpu%d)\n", virq, vcpu);
256 DPRINTF(VGIC,
"EOIR: Found LR%d for irq %d(cpu%d)\n", i, virq, vcpu);
257 ListReg *lr = &vid->LR[
i];
264 panic(
"VGIC VCPU write %#x to unk address %#x\n", pkt->
get<uint32_t>(), daddr);
281 DPRINTF(VGIC,
"VGIC HVCtrl write register %#x <= %#x\n", daddr, pkt->
get<uint32_t>());
286 if (daddr & ~0x1ff) {
287 ctx_id = (daddr >> 9);
289 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
293 struct vcpuIntData *vid = &
vcpuData[ctx_id];
297 vid->hcr = pkt->
get<uint32_t>();
302 uint32_t
d = pkt->
get<uint32_t>();
303 vid->VMPriMask = d >> 27;
304 vid->VMBP = (d >> 21) & 7;
305 vid->VMABP = (d >> 18) & 7;
306 vid->VEM = (d >> 9) & 1;
307 vid->VMCBPR = (d >> 4) & 1;
308 vid->VMFiqEn = (d >> 3) & 1;
309 vid->VMAckCtl = (d >> 2) & 1;
310 vid->VMGrp1En = (d >> 1) & 1;
311 vid->VMGrp0En = d & 1;
315 warn_once(
"VGIC GICH_APR0 written, ignored\n");
322 vid->LR[(daddr -
GICH_LR0) >> 2] = pkt->
get<uint32_t>();
327 panic(
"VGIC HVCtrl write to bad address %#x\n", daddr);
340 return (!!vid->hcr.VGrp1DIE && !vid->VMGrp1En ? 0x80 : 0) |
341 (!!vid->hcr.VGrp1EIE && vid->VMGrp1En ? 0x40 : 0) |
342 (!!vid->hcr.VGrp0DIE && !vid->VMGrp0En ? 0x20 : 0) |
343 (!!vid->hcr.VGrp0EIE && vid->VMGrp0En ? 0x10 : 0) |
344 (!!vid->hcr.NPIE && !
lrPending(vid) ? 0x08 : 0) |
345 (!!vid->hcr.LRENPIE && vid->hcr.EOICount ? 0x04 : 0) |
346 (!!vid->hcr.UIE &&
lrValid(vid) <= 1 ? 0x02 : 0) |
347 (vid->eisr ? 0x01 : 0);
353 DPRINTF(VGIC,
"Posting VIRQ to %d\n", cpu);
361 DPRINTF(VGIC,
"Unposting VIRQ to %d\n", cpu);
368 DPRINTF(VGIC,
"Posting maintenance PPI to GIC/cpu%d\n", cpu);
376 DPRINTF(VGIC,
"Unposting maintenance PPI to GIC/cpu%d\n", cpu);
390 struct vcpuIntData *tvid = &
vcpuData[ctx_id];
394 if (!tvid->LR[
i].State && tvid->LR[
i].EOI) {
395 tvid->eisr |= 1 <<
i;
415 if (vid->hcr.En &&
getMISR(vid)) {
420 if (!vid->hcr.En || !
getMISR(vid)) {
442 interrupt_time[cpu] = 0;
448 DPRINTF(Checkpoint,
"Serializing VGIC\n");
465 uint32_t vctrl_val = vctrl;
467 uint32_t hcr_val = hcr;
469 uint64_t eisr_val = eisr;
471 uint8_t VMGrp0En_val = VMGrp0En;
473 uint8_t VMGrp1En_val = VMGrp1En;
475 uint8_t VMAckCtl_val = VMAckCtl;
477 uint8_t VMFiqEn_val = VMFiqEn;
479 uint8_t VMCBPR_val = VMCBPR;
481 uint8_t VEM_val = VEM;
483 uint8_t VMABP_val = VMABP;
485 uint8_t VMBP_val = VMBP;
487 uint8_t VMPriMask_val = VMPriMask;
490 for (
int i = 0;
i < NUM_LR;
i++) {
491 ScopedCheckpointSection sec_lr(cp,
csprintf(
"LR%d",
i));
498 DPRINTF(Checkpoint,
"Unserializing Arm GIC\n");
503 if (interrupt_time[cpu])
519 paramIn(cp,
"vctrl_val", vctrl);
522 paramIn(cp,
"VMGrp0En_val", VMGrp0En);
523 paramIn(cp,
"VMGrp1En_val", VMGrp1En);
524 paramIn(cp,
"VMAckCtl_val", VMAckCtl);
525 paramIn(cp,
"VMFiqEn_val", VMFiqEn);
526 paramIn(cp,
"VMCBPR_val", VMCBPR);
528 paramIn(cp,
"VMABP_val", VMABP);
529 paramIn(cp,
"VMPriMask_val", VMPriMask);
531 for (
int i = 0;
i < NUM_LR;
i++) {
532 ScopedCheckpointSection sec_lr(cp,
csprintf(
"LR%d",
i));
540 return new VGic(
this);
EventQueue * eventq
A pointer to this object's event queue.
AddrRange RangeSize(Addr start, Addr size)
static const int GICH_HCR
static const int GICH_VTR
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
static const int GICV_CTLR
static const int GICV_SIZE
Implementiation of a GIC-400 List Register-based VGIC interface.
ContextID contextId() const
Accessor function for context ID.
unsigned int lrValid(struct vcpuIntData *vid)
bool maintIntPosted[VGIC_CPU_MAX]
uint32_t getMISR(struct vcpuIntData *vid)
Event definition to post interrupt to CPU after a delay.
static const int GICH_LR3
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
int numRunningContexts()
Return number of running (non-halted) thread contexts in system.
PostVIntEvent * postVIntEvent[VGIC_CPU_MAX]
#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.
Tick when() const
Get the time that the event is scheduled.
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.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
#define SERIALIZE_ARRAY(member, size)
const RequestPtr req
A pointer to the original request.
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...
struct std::array< vcpuIntData, VGIC_CPU_MAX > vcpuData
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)
void postVInt(uint32_t cpu, Tick when)
Tick writeVCpu(PacketPtr pkt)
void serialize(CheckpointOut &cp) const override
static const int GICH_APR0
void unserialize(CheckpointIn &cp) override
static const uint32_t LR_ACTIVE
void clear(int cpu_id, int int_num, int index)
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