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

Reply via email to