diff options
Diffstat (limited to 'ArmPkg')
-rw-r--r-- | ArmPkg/Drivers/ArmGic/ArmGicLib.c | 31 | ||||
-rw-r--r-- | ArmPkg/Include/Library/ArmGicLib.h | 16 |
2 files changed, 44 insertions, 3 deletions
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c index 666008638c..41e970bc49 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c +++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c @@ -14,6 +14,7 @@ #include <Base.h>
#include <Library/ArmGicLib.h>
+#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include "GicV2/ArmGicV2Lib.h"
@@ -49,13 +50,39 @@ ArmGicSendSgiTo ( MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);
}
+/*
+ * Acknowledge and return the value of the Interrupt Acknowledge Register
+ *
+ * InterruptId is returned separately from the register value because in
+ * the GICv2 the register value contains the CpuId and InterruptId while
+ * in the GICv3 the register value is only the InterruptId.
+ *
+ * @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
+ * @param InterruptId InterruptId read from the Interrupt Acknowledge Register
+ *
+ * @retval value returned by the Interrupt Acknowledge Register
+ *
+ */
UINTN
EFIAPI
ArmGicAcknowledgeInterrupt (
- IN UINTN GicInterruptInterfaceBase
+ IN UINTN GicInterruptInterfaceBase,
+ OUT UINTN *InterruptId
)
{
- return ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
+ UINTN Value;
+
+ Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
+
+ // InterruptId is required for the caller to know if a valid or spurious
+ // interrupt has been read
+ ASSERT (InterruptId != NULL);
+
+ if (InterruptId != NULL) {
+ *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID;
+ }
+
+ return Value;
}
VOID
diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h index f2d4c7b27c..e3ef228dba 100644 --- a/ArmPkg/Include/Library/ArmGicLib.h +++ b/ArmPkg/Include/Library/ArmGicLib.h @@ -140,10 +140,24 @@ ArmGicSendSgiTo ( IN INTN SgiId
);
+/*
+ * Acknowledge and return the value of the Interrupt Acknowledge Register
+ *
+ * InterruptId is returned separately from the register value because in
+ * the GICv2 the register value contains the CpuId and InterruptId while
+ * in the GICv3 the register value is only the InterruptId.
+ *
+ * @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
+ * @param InterruptId InterruptId read from the Interrupt Acknowledge Register
+ *
+ * @retval value returned by the Interrupt Acknowledge Register
+ *
+ */
UINTN
EFIAPI
ArmGicAcknowledgeInterrupt (
- IN UINTN GicInterruptInterfaceBase
+ IN UINTN GicInterruptInterfaceBase,
+ OUT UINTN *InterruptId
);
VOID
|