Unlike SGIs and PPIs, which are private to the CPU and are managed at the redistributor level (which is also a per-CPU construct), shared interrupts (SPIs) are shared between all CPUs, and therefore managed at the distributor level.
Reported-by: Narinder Dhillon <[email protected]> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <[email protected]> --- ArmPkg/Drivers/ArmGic/ArmGicLib.c | 25 +++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c index 248e896c4b94..73795ed4e56c 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c +++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c @@ -20,6 +20,19 @@ #include <Library/PcdLib.h> /** + * + * Return whether the Source interrupt index refers to a shared interrupt (SPI) + */ +STATIC +BOOLEAN +SourceIsSpi ( + IN UINTN Source + ) +{ + return Source >= 32 && Source < 1020; +} + +/** * Return the base address of the GIC redistributor for the current CPU * * @param Revision GIC Revision. The GIC redistributor might have a different @@ -183,7 +196,9 @@ ArmGicEnableInterrupt ( RegShift = Source % 32; Revision = ArmGicGetSupportedArchRevision (); - if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { + if ((Revision == ARM_GIC_ARCH_REVISION_2) || + FeaturePcdGet (PcdArmGicV3WithV2Legacy) || + SourceIsSpi (Source)) { // Write set-enable register MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift); } else { @@ -216,7 +231,9 @@ ArmGicDisableInterrupt ( RegShift = Source % 32; Revision = ArmGicGetSupportedArchRevision (); - if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { + if ((Revision == ARM_GIC_ARCH_REVISION_2) || + FeaturePcdGet (PcdArmGicV3WithV2Legacy) || + SourceIsSpi (Source)) { // Write clear-enable register MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift); } else { @@ -249,7 +266,9 @@ ArmGicIsInterruptEnabled ( RegShift = Source % 32; Revision = ArmGicGetSupportedArchRevision (); - if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { + if ((Revision == ARM_GIC_ARCH_REVISION_2) || + FeaturePcdGet (PcdArmGicV3WithV2Legacy) || + SourceIsSpi (Source)) { Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0); } else { GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision); -- 2.7.4 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

