ctx, iar.ack_id, iar.cpu_id, iar);
cpuHighestInt[ctx] = SPURIOUS_INT;
updateIntState(-1);
- platform->intrctrl->clear(ctx, ArmISA::INT_IRQ, 0);
+ clearInt(ctx, active_int);
return iar;
} else {
return SPURIOUS_INT;
if (isLevelSensitive(cpu, prev_highest)) {
DPRINTF(Interrupt, "Clear IRQ for cpu%d\n", cpu);
- platform->intrctrl->clear(cpu, ArmISA::INT_IRQ, 0);
+ clearInt(cpu, prev_highest);
}
continue;
}
DPRINTF(Interrupt, "Posting interrupt %d to cpu%d\n", highest_int,
cpu);
- postInt(cpu, curTick() + intLatency);
+
+ if (isFiq(cpu, highest_int)) {
+ postFiq(cpu, curTick() + intLatency);
+ } else {
+ postInt(cpu, curTick() + intLatency);
+ }
}
}
}
updateIntState(intNumToWord(num));
}
+void
+GicV2::clearInt(ContextID ctx, uint32_t int_num)
+{
+ if (isFiq(ctx, int_num)) {
+ platform->intrctrl->clear(ctx, ArmISA::INT_FIQ, 0);
+ } else {
+ platform->intrctrl->clear(ctx, ArmISA::INT_IRQ, 0);
+ }
+}
+
void
GicV2::postInt(uint32_t cpu, Tick when)
{
}
}
- /** CPU enabled */
+ bool isGroup0(ContextID ctx, uint32_t int_num) {
+ const uint32_t group_reg = getIntGroup(ctx, intNumToWord(int_num));
+ return bits(group_reg, intNumToBit(int_num));
+ }
+
+ /**
+ * This method checks if an interrupt ID must be signaled or has been
+ * signaled as a FIQ to the cpu. It does that by reading:
+ *
+ * 1) GICD_IGROUPR: controls if the interrupt is part of group0 or
+ * group1. Only group0 interrupts can be signaled as FIQs.
+ *
+ * 2) GICC_CTLR.FIQEn: controls whether the CPU interface signals Group 0
+ * interrupts to a target processor using the FIQ or the IRQ signal
+ */
+ bool isFiq(ContextID ctx, uint32_t int_num) {
+ const bool is_group0 = isGroup0(ctx, int_num);
+ const bool use_fiq = cpuControl[ctx].fiqEn;
+
+ if (is_group0 && use_fiq) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /** CPU enabled:
+ * Checks if GICC_CTLR.EnableGrp0 or EnableGrp1 are set
+ */
bool cpuEnabled(ContextID ctx) const {
return cpuControl[ctx].enableGrp0 ||
cpuControl[ctx].enableGrp1;
int intNumToWord(int num) const { return num >> 5; }
int intNumToBit(int num) const { return num % 32; }
+ /** Clears a cpu IRQ or FIQ signal */
+ void clearInt(ContextID ctx, uint32_t int_num);
+
/**
* Post an interrupt to a CPU with a delay
*/