summaryrefslogtreecommitdiff
path: root/src/dev/arm/gic_v2.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/arm/gic_v2.cc')
-rw-r--r--src/dev/arm/gic_v2.cc26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/dev/arm/gic_v2.cc b/src/dev/arm/gic_v2.cc
index 01358b732..7bbc89e74 100644
--- a/src/dev/arm/gic_v2.cc
+++ b/src/dev/arm/gic_v2.cc
@@ -88,6 +88,9 @@ GicV2::GicV2(const Params *p)
postIntEvent[x] =
new EventFunctionWrapper([this, x]{ postDelayedInt(x); },
"Post Interrupt to CPU");
+ postFiqEvent[x] =
+ new EventFunctionWrapper([this, x]{ postDelayedFiq(x); },
+ "Post FIQ to CPU");
}
DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled(0),
cpuEnabled(1));
@@ -97,8 +100,10 @@ GicV2::GicV2(const Params *p)
GicV2::~GicV2()
{
- for (int x = 0; x < CPU_MAX; x++)
+ for (int x = 0; x < CPU_MAX; x++) {
delete postIntEvent[x];
+ delete postFiqEvent[x];
+ }
}
Tick
@@ -915,6 +920,25 @@ GicV2::postDelayedInt(uint32_t cpu)
signalDrainDone();
}
+void
+GicV2::postFiq(uint32_t cpu, Tick when)
+{
+ if (!(postFiqEvent[cpu]->scheduled())) {
+ ++pendingDelayedInterrupts;
+ eventq->schedule(postFiqEvent[cpu], when);
+ }
+}
+
+void
+GicV2::postDelayedFiq(uint32_t cpu)
+{
+ platform->intrctrl->post(cpu, ArmISA::INT_FIQ, 0);
+ --pendingDelayedInterrupts;
+ assert(pendingDelayedInterrupts >= 0);
+ if (pendingDelayedInterrupts == 0)
+ signalDrainDone();
+}
+
DrainState
GicV2::drain()
{