Go to the documentation of this file.
42 #include "debug/Checkpoint.hh"
43 #include "debug/VGIC.hh"
49 :
PioDevice(
p), gicvIIDR(
p->gicv_iidr), platform(
p->platform),
50 gic(
p->
gic), vcpuAddr(
p->vcpu_addr), hvAddr(
p->hv_addr),
51 pioDelay(
p->pio_delay), maintInt(
p->maint_int)
56 "Post VInterrupt to CPU");
102 struct vcpuIntData *vid = &
vcpuData[ctx_id];
104 DPRINTF(VGIC,
"VGIC VCPU read register %#x\n", daddr);
108 pkt->
setLE<uint32_t>(vid->vctrl);
112 if (i < 0 || !vid->vctrl.En) {
113 pkt->
setLE<uint32_t>(1023);
115 ListReg *lr = &vid->LR[
i];
117 pkt->
setLE<uint32_t>(lr->VirtualID |
118 (((int)lr->CpuID) << 10));
122 panic(
"VGIC does not support 'HW' List Register feature (LR %#x)!\n",
125 DPRINTF(VGIC,
"Consumed interrupt %d (cpu%d) from LR%d (EOI%d)\n",
126 lr->VirtualID, lr->CpuID,
i, lr->EOI);
133 panic(
"VGIC VCPU read of bad address %#x\n", daddr);
149 DPRINTF(VGIC,
"VGIC HVCtrl read register %#x\n", daddr);
154 if (daddr & ~0x1ff) {
155 ctx_id = (daddr >> 9);
157 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
161 struct vcpuIntData *vid = &
vcpuData[ctx_id];
165 pkt->
setLE<uint32_t>(vid->hcr);
173 pkt->
setLE<uint32_t>(
174 ((uint32_t)vid->VMPriMask << 27) |
175 ((uint32_t)vid->VMBP << 21) |
176 ((uint32_t)vid->VMABP << 18) |
177 ((uint32_t)vid->VEM << 9) |
178 ((uint32_t)vid->VMCBPR << 4) |
179 ((uint32_t)vid->VMFiqEn << 3) |
180 ((uint32_t)vid->VMAckCtl << 2) |
181 ((uint32_t)vid->VMGrp1En << 1) |
182 ((uint32_t)vid->VMGrp0En << 0)
191 pkt->
setLE<uint32_t>(vid->eisr & 0xffffffff);
195 pkt->
setLE<uint32_t>(vid->eisr >> 32);
201 if (!vid->LR[
i].State)
204 pkt->
setLE<uint32_t>(bm);
210 if (!vid->LR[
i].State)
213 pkt->
setLE<uint32_t>(bm);
218 pkt->
setLE<uint32_t>(0);
229 panic(
"VGIC HVCtrl read of bad address %#x\n", daddr);
243 struct vcpuIntData *vid = &
vcpuData[ctx_id];
245 DPRINTF(VGIC,
"VGIC VCPU write register %#x <= %#x\n",
246 daddr, pkt->
getLE<uint32_t>());
250 vid->vctrl = pkt->
getLE<uint32_t>();
253 vid->VMPriMask = pkt->
getLE<uint32_t>();
258 assert(!vid->vctrl.EOImode);
259 uint32_t
w = pkt->
getLE<uint32_t>();
260 unsigned int virq =
w & 0x3ff;
261 unsigned int vcpu = (
w >> 10) & 7;
264 DPRINTF(VGIC,
"EOIR: No LR for irq %d(cpu%d)\n", virq, vcpu);
266 DPRINTF(VGIC,
"EOIR: Found LR%d for irq %d(cpu%d)\n",
i, virq, vcpu);
267 ListReg *lr = &vid->LR[
i];
274 panic(
"VGIC VCPU write %#x to unk address %#x\n",
275 pkt->
getLE<uint32_t>(), daddr);
292 DPRINTF(VGIC,
"VGIC HVCtrl write register %#x <= %#x\n",
293 daddr, pkt->
getLE<uint32_t>());
298 if (daddr & ~0x1ff) {
299 ctx_id = (daddr >> 9);
301 panic(
"VGIC: Weird unbanked hv ctrl address %#x!\n", daddr);
305 struct vcpuIntData *vid = &
vcpuData[ctx_id];
309 vid->hcr = pkt->
getLE<uint32_t>();
314 uint32_t
d = pkt->
getLE<uint32_t>();
315 vid->VMPriMask =
d >> 27;
316 vid->VMBP = (
d >> 21) & 7;
317 vid->VMABP = (
d >> 18) & 7;
318 vid->VEM = (
d >> 9) & 1;
319 vid->VMCBPR = (
d >> 4) & 1;
320 vid->VMFiqEn = (
d >> 3) & 1;
321 vid->VMAckCtl = (
d >> 2) & 1;
322 vid->VMGrp1En = (
d >> 1) & 1;
323 vid->VMGrp0En =
d & 1;
327 warn_once(
"VGIC GICH_APR0 written, ignored\n");
339 panic(
"VGIC HVCtrl write to bad address %#x\n", daddr);
352 return (!!vid->hcr.VGrp1DIE && !vid->VMGrp1En ? 0x80 : 0) |
353 (!!vid->hcr.VGrp1EIE && vid->VMGrp1En ? 0x40 : 0) |
354 (!!vid->hcr.VGrp0DIE && !vid->VMGrp0En ? 0x20 : 0) |
355 (!!vid->hcr.VGrp0EIE && vid->VMGrp0En ? 0x10 : 0) |
356 (!!vid->hcr.NPIE && !
lrPending(vid) ? 0x08 : 0) |
357 (!!vid->hcr.LRENPIE && vid->hcr.EOICount ? 0x04 : 0) |
358 (!!vid->hcr.UIE &&
lrValid(vid) <= 1 ? 0x02 : 0) |
359 (vid->eisr ? 0x01 : 0);
365 DPRINTF(VGIC,
"Posting VIRQ to %d\n", cpu);
373 DPRINTF(VGIC,
"Unposting VIRQ to %d\n", cpu);
387 DPRINTF(VGIC,
"Posting maintenance PPI to GIC/cpu%d\n", cpu);
395 DPRINTF(VGIC,
"Unposting maintenance PPI to GIC/cpu%d\n", cpu);
409 struct vcpuIntData *tvid = &
vcpuData[ctx_id];
413 if (!tvid->LR[
i].State && tvid->LR[
i].EOI) {
414 tvid->eisr |= 1 <<
i;
434 if (vid->hcr.En &&
getMISR(vid)) {
439 if (!vid->hcr.En || !
getMISR(vid)) {
461 interrupt_time[cpu] = 0;
467 DPRINTF(Checkpoint,
"Serializing VGIC\n");
484 uint32_t vctrl_val = vctrl;
486 uint32_t hcr_val = hcr;
488 uint64_t eisr_val = eisr;
490 uint8_t VMGrp0En_val = VMGrp0En;
492 uint8_t VMGrp1En_val = VMGrp1En;
494 uint8_t VMAckCtl_val = VMAckCtl;
496 uint8_t VMFiqEn_val = VMFiqEn;
498 uint8_t VMCBPR_val = VMCBPR;
500 uint8_t VEM_val = VEM;
502 uint8_t VMABP_val = VMABP;
504 uint8_t VMBP_val = VMBP;
506 uint8_t VMPriMask_val = VMPriMask;
509 for (
int i = 0;
i < NUM_LR;
i++) {
510 ScopedCheckpointSection sec_lr(
cp,
csprintf(
"LR%d",
i));
517 DPRINTF(Checkpoint,
"Unserializing Arm GIC\n");
522 if (interrupt_time[cpu])
550 for (
int i = 0;
i < NUM_LR;
i++) {
551 ScopedCheckpointSection sec_lr(
cp,
csprintf(
"LR%d",
i));
559 return new VGic(
this);
void unPostVInt(uint32_t cpu)
void makeAtomicResponse()
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
void clear(int cpu_id, int int_num, int index)
static const int GICH_VMCR
static const int GICH_LR1
static const int GICH_EISR0
bool vIntPosted[VGIC_CPU_MAX]
void post(int cpu_id, int int_num, int index)
#define UNSERIALIZE_SCALAR(scalar)
uint32_t getMISR(struct vcpuIntData *vid)
void postMaintInt(uint32_t cpu)
bool maintIntPosted[VGIC_CPU_MAX]
static const int GICV_IAR
static const int GICH_VTR
int ContextID
Globally unique thread context ID.
void updateIntState(ContextID ctx_id)
uint64_t Tick
Tick count type.
static const int GICH_EISR1
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
Tick writeVCpu(PacketPtr pkt)
RequestPtr req
A pointer to the original request.
Tick readCtrl(PacketPtr pkt)
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.
static const int GICV_EOIR
int findLRForVIRQ(struct vcpuIntData *vid, int virq, int vcpu)
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Tick writeCtrl(PacketPtr pkt)
void unserialize(ThreadContext &tc, CheckpointIn &cp)
unsigned int lrPending(struct vcpuIntData *vid)
unsigned int lrValid(struct vcpuIntData *vid)
static const int GICH_ELSR0
This device is the base class which all devices senstive to an address range inherit from.
void schedule(Event &event, Tick when)
static const int GICH_APR0
static const int GICV_IIDR
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
static const int GICH_MISR
AddrRange RangeSize(Addr start, Addr size)
static const int GICV_CTLR
void serialize(CheckpointOut &cp) const override
Serialize an object.
Tick readVCpu(PacketPtr pkt)
static const int GICH_LR0
#define SERIALIZE_ARRAY(member, size)
EventFunctionWrapper * postVIntEvent[VGIC_CPU_MAX]
EndBitUnion(VCTLR) struct vcpuIntData struct std::array< vcpuIntData, VGIC_CPU_MAX > vcpuData
virtual void clearPPInt(uint32_t num, uint32_t cpu)=0
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
static const int GICH_ELSR1
#define SERIALIZE_SCALAR(scalar)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
static const uint32_t LR_ACTIVE
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
#define UNSERIALIZE_ARRAY(member, size)
int findHighestPendingLR(struct vcpuIntData *vid)
Returns LR index or -1 if none pending.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
static const int GICV_PMR
EventQueue * eventq
A pointer to this object's event queue.
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
void processPostVIntEvent(uint32_t cpu)
Post interrupt to CPU.
static const int GICV_SIZE
void setLE(T v)
Set the value in the data pointer to v as little endian.
void unPostMaintInt(uint32_t cpu)
std::ostream CheckpointOut
virtual void sendPPInt(uint32_t num, uint32_t cpu)=0
Interface call for private peripheral interrupts.
void postVInt(uint32_t cpu, Tick when)
std::string csprintf(const char *format, const Args &...args)
static const int GICH_LR2
static const int GICH_HCR
static const int VGIC_CPU_MAX
#define panic(...)
This implements a cprintf based panic() function.
Tick curTick()
The current simulated tick.
static const int GICH_LR3
static const int GICH_REG_SIZE
Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17