dev-arm: Enable FIQ signaling for Group0 interrupts in GICv2
Change-Id: Iafaf26344a26eade60c08dd2c0d716af14d9b328 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/12948 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -364,7 +364,7 @@ GicV2::readCpu(ContextID ctx, Addr daddr)
|
||||
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;
|
||||
@@ -802,7 +802,7 @@ GicV2::updateIntState(int hint)
|
||||
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;
|
||||
}
|
||||
@@ -816,7 +816,12 @@ GicV2::updateIntState(int hint)
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -901,6 +906,16 @@ GicV2::clearPPInt(uint32_t num, uint32_t cpu)
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -334,7 +334,35 @@ class GicV2 : public BaseGic, public BaseGicRegisters
|
||||
}
|
||||
}
|
||||
|
||||
/** 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;
|
||||
@@ -393,6 +421,9 @@ class GicV2 : public BaseGic, public BaseGicRegisters
|
||||
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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user