From aae35976ee69761366f3967de2b4b45507ede541 Mon Sep 17 00:00:00 2001
From: Olivier Martin <olivier.martin@arm.com>
Date: Fri, 27 Sep 2013 10:58:22 +0100
Subject: [PATCH 02/14] ArmPkg/ArmGic: Move out the EndOfInterrupt from the
 interrupt acknowledgement

Change-Id: Id73a25f9bd2495a471993368c045c60660fcb82a
---
 ArmPkg/Drivers/ArmGic/ArmGic.c                     | 29 +++-------------------
 ArmPkg/Drivers/ArmGic/ArmGicDxe.c                  |  4 +--
 ArmPkg/Drivers/ArmGic/ArmGicDxe.inf                |  2 +-
 ArmPkg/Include/Library/ArmGicLib.h                 | 17 +++++++++----
 .../DebugSecExtraActionLib.c                       |  8 +++++-
 ArmPlatformPkg/PrePeiCore/MainMPCore.c             |  8 +++++-
 ArmPlatformPkg/PrePi/MainMPCore.c                  |  8 +++++-
 7 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/ArmPkg/Drivers/ArmGic/ArmGic.c b/ArmPkg/Drivers/ArmGic/ArmGic.c
index 86bbb1d..ee35190 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGic.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGic.c
@@ -1,6 +1,6 @@
 /** @file
 *
-*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
 *  
 *  This program and the accompanying materials                          
 *  are licensed and made available under the terms and conditions of the BSD License         
@@ -38,35 +38,14 @@ ArmGicSendSgiTo (
   MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);
 }
 
-RETURN_STATUS
+UINTN
 EFIAPI
 ArmGicAcknowledgeInterrupt (
-  IN  UINTN          GicDistributorBase,
-  IN  UINTN          GicInterruptInterfaceBase,
-  OUT UINTN          *CoreId,
-  OUT UINTN          *InterruptId
+  IN  UINTN          GicInterruptInterfaceBase
   )
 {
-  UINT32            Interrupt;
-
   // Read the Interrupt Acknowledge Register
-  Interrupt = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
-
-  // Check if it is a valid interrupt ID
-  if ((Interrupt & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase)) {
-    // Got a valid SGI number hence signal End of Interrupt by writing to ICCEOIR
-    ArmGicEndOfInterrupt (GicInterruptInterfaceBase, Interrupt);
-
-    if (CoreId) {
-      *CoreId = (Interrupt >> 10) & 0x7;
-    }
-    if (InterruptId) {
-      *InterruptId = Interrupt & 0x3FF;
-    }
-    return RETURN_SUCCESS;
-  } else {
-    return RETURN_INVALID_PARAMETER;
-  }
+  return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
 }
 
 RETURN_STATUS
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
index e227f19..9608c31 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
@@ -252,10 +252,10 @@ IrqInterruptHandler (
   UINT32                      GicInterrupt;
   HARDWARE_INTERRUPT_HANDLER  InterruptHandler;
 
-  GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIAR);
+  GicInterrupt = ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicInterruptInterfaceBase));
 
   // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).
-  if (GicInterrupt >= mGicNumInterrupts) {
+  if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) {
     // The special interrupt do not need to be acknowledge
     return;
   }
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
index 9dc557a..3974f3c 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
@@ -1,7 +1,7 @@
 #/** @file
 #  
 #  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
-#  Copyright (c) 2012, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h
index 75c1c1f..dc0bae4 100644
--- a/ArmPkg/Include/Library/ArmGicLib.h
+++ b/ArmPkg/Include/Library/ArmGicLib.h
@@ -76,6 +76,9 @@
 #define ARM_GIC_ICCIDR_GET_REVISION(IccIdr)     (((IccIdr) >> 12) & 0xF)
 #define ARM_GIC_ICCIDR_GET_IMPLEMENTER(IccIdr)  ((IccIdr) & 0xFFF)
 
+// Bit Mask for
+#define ARM_GIC_ICCIAR_ACKINTID                 0x3FF
+
 //
 // GIC Secure interfaces
 //
@@ -128,13 +131,17 @@ ArmGicSendSgiTo (
   IN  INTN          SgiId
   );
 
-RETURN_STATUS
+UINTN
 EFIAPI
 ArmGicAcknowledgeInterrupt (
-  IN  UINTN          GicDistributorBase,
-  IN  UINTN          GicInterruptInterfaceBase,
-  OUT UINTN          *CoreId,
-  OUT UINTN          *InterruptId
+  IN  UINTN          GicInterruptInterfaceBase
+  );
+
+RETURN_STATUS
+EFIAPI
+ArmGicEndOfInterrupt (
+  IN  UINTN                 GicInterruptInterfaceBase,
+  IN UINTN                  Source
   );
 
 RETURN_STATUS
diff --git a/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c b/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
index f8f91e8..f42f518 100755
--- a/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
+++ b/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
@@ -31,6 +31,7 @@ NonSecureWaitForFirmware (
   )
 {
   VOID (*secondary_start)(VOID);
+  UINTN Interrupt;
 
   // The secondary cores will execute the firmware once wake from WFI.
   secondary_start = (VOID (*)())PcdGet32(PcdFvBaseAddress);
@@ -38,7 +39,12 @@ NonSecureWaitForFirmware (
   ArmCallWFI();
 
   // Acknowledge the interrupt and send End of Interrupt signal.
-  ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), NULL, NULL);
+  Interrupt = ArmGicAcknowledgeInterrupt (PcdGet32 (PcdGicInterruptInterfaceBase));
+  // Check if it is a valid interrupt ID
+  if ((Interrupt & ARM_GIC_ICCIAR_ACKINTID) < ArmGicGetMaxNumInterrupts (PcdGet32 (PcdGicDistributorBase))) {
+    // Got a valid SGI number hence signal End of Interrupt
+    ArmGicEndOfInterrupt (PcdGet32 (PcdGicInterruptInterfaceBase), Interrupt);
+  }
 
   // Jump to secondary core entry point.
   secondary_start ();
diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
index 9bfc990..69863de 100644
--- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c
+++ b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
@@ -45,6 +45,7 @@ SecondaryMain (
   UINT32                  CoreId;
   VOID                    (*SecondaryStart)(VOID);
   UINTN                   SecondaryEntryAddr;
+  UINTN                   Interrupt;
 
   ClusterId = GET_CLUSTER_ID(MpId);
   CoreId    = GET_CORE_ID(MpId);
@@ -87,7 +88,12 @@ SecondaryMain (
     SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
 
     // Acknowledge the interrupt and send End of Interrupt signal.
-    ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), NULL, NULL);
+    Interrupt = ArmGicAcknowledgeInterrupt (PcdGet32 (PcdGicInterruptInterfaceBase));
+    // Check if it is a valid interrupt ID
+    if ((Interrupt & ARM_GIC_ICCIAR_ACKINTID) < ArmGicGetMaxNumInterrupts (PcdGet32 (PcdGicDistributorBase))) {
+      // Got a valid SGI number hence signal End of Interrupt
+      ArmGicEndOfInterrupt (PcdGet32 (PcdGicInterruptInterfaceBase), Interrupt);
+    }
   } while (SecondaryEntryAddr == 0);
 
   // Jump to secondary core entry point.
diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c
index 5868993..3db3ce6 100644
--- a/ArmPlatformPkg/PrePi/MainMPCore.c
+++ b/ArmPlatformPkg/PrePi/MainMPCore.c
@@ -55,6 +55,7 @@ SecondaryMain (
   UINT32                  CoreId;
   VOID                    (*SecondaryStart)(VOID);
   UINTN                   SecondaryEntryAddr;
+  UINTN                   Interrupt;
 
   ClusterId = GET_CLUSTER_ID(MpId);
   CoreId    = GET_CORE_ID(MpId);
@@ -87,7 +88,12 @@ SecondaryMain (
     SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
 
     // Acknowledge the interrupt and send End of Interrupt signal.
-    ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), NULL, NULL);
+    Interrupt = ArmGicAcknowledgeInterrupt (PcdGet32 (PcdGicInterruptInterfaceBase));
+    // Check if it is a valid interrupt ID
+    if ((Interrupt & ARM_GIC_ICCIAR_ACKINTID) < ArmGicGetMaxNumInterrupts (PcdGet32 (PcdGicDistributorBase))) {
+      // Got a valid SGI number hence signal End of Interrupt
+      ArmGicEndOfInterrupt (PcdGet32 (PcdGicInterruptInterfaceBase), Interrupt);
+    }
   } while (SecondaryEntryAddr == 0);
 
   // Jump to secondary core entry point.
-- 
1.8.5

