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:
Giacomo Travaglini
2018-09-11 13:39:00 +01:00
parent 4439c58688
commit 721ea8bb83
2 changed files with 50 additions and 4 deletions

View File

@@ -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)
{

View File

@@ -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
*/