diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dev/arm/gic_v2.cc | 26 | ||||
-rw-r--r-- | src/dev/arm/gic_v2.hh | 3 |
2 files changed, 28 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() { diff --git a/src/dev/arm/gic_v2.hh b/src/dev/arm/gic_v2.hh index 4ca2f38e2..4f30b00e6 100644 --- a/src/dev/arm/gic_v2.hh +++ b/src/dev/arm/gic_v2.hh @@ -397,13 +397,16 @@ class GicV2 : public BaseGic, public BaseGicRegisters * Post an interrupt to a CPU with a delay */ void postInt(uint32_t cpu, Tick when); + void postFiq(uint32_t cpu, Tick when); /** * Deliver a delayed interrupt to the target CPU */ void postDelayedInt(uint32_t cpu); + void postDelayedFiq(uint32_t cpu); EventFunctionWrapper *postIntEvent[CPU_MAX]; + EventFunctionWrapper *postFiqEvent[CPU_MAX]; int pendingDelayedInterrupts; public: |