From 4b9c7d6889496ef2aab37299ef2b5d97cc36a5bb Mon Sep 17 00:00:00 2001
From: Olivier Martin <olivier.martin@arm.com>
Date: Tue, 25 Mar 2014 13:03:03 +0000
Subject: [PATCH 09/14] ArmPkg/ArmGic: Introduced support for GicV2 to
 ArmGicLib

The support for GIcV2 was already existing. This change separate the GicV2
specific functions from the common Gic code (in preparation for GicV3 support).

Change-Id: Id8750593190f02231d2b9b0286ae4b15ac40267d
---
 ArmPkg/Drivers/ArmGic/ArmGicLib.c               |  26 +++++-
 ArmPkg/Drivers/ArmGic/ArmGicLib.inf             |   5 +-
 ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c         |  25 ------
 ArmPkg/Drivers/ArmGic/ArmGicSecLib.c            | 101 ++++--------------------
 ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf          |   5 +-
 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c       |  37 +++++++++
 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h       |  98 +++++++++++++++++++++++
 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c |  42 ++++++++++
 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c    |  98 +++++++++++++++++++++++
 9 files changed, 322 insertions(+), 115 deletions(-)
 mode change 100644 => 100755 ArmPkg/Drivers/ArmGic/ArmGicLib.inf
 mode change 100644 => 100755 ArmPkg/Drivers/ArmGic/ArmGicSecLib.c
 mode change 100644 => 100755 ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
 create mode 100755 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c
 create mode 100755 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h
 create mode 100755 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c
 create mode 100755 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c

diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
index 75286ba..14deaa4 100755
--- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
@@ -16,6 +16,8 @@
 #include <Library/ArmGicLib.h>
 #include <Library/IoLib.h>
 
+#include "GicV2/ArmGicV2Lib.h"
+
 UINTN
 EFIAPI
 ArmGicGetInterfaceIdentification (
@@ -53,8 +55,7 @@ ArmGicAcknowledgeInterrupt (
   IN  UINTN          GicInterruptInterfaceBase
   )
 {
-  // Read the Interrupt Acknowledge Register
-  return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+  return ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
 }
 
 RETURN_STATUS
@@ -64,8 +65,7 @@ ArmGicEndOfInterrupt (
   IN UINTN                  Source
   )
 {
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);
-  return RETURN_SUCCESS;
+  return ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source);
 }
 
 RETURN_STATUS
@@ -138,3 +138,21 @@ ArmGicDisableDistributor (
   // Disable Gic Distributor
   MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x0);
 }
+
+VOID
+EFIAPI
+ArmGicEnableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{
+  return ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase);
+}
+
+VOID
+EFIAPI
+ArmGicDisableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{
+  return ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase);
+}
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
old mode 100644
new mode 100755
index d5223df..4652348
--- a/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
@@ -1,5 +1,5 @@
 #/* @file
-#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2011-2014, 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         
@@ -23,6 +23,9 @@
   ArmGicLib.c
   ArmGicNonSecLib.c
 
+  GicV2/ArmGicV2Lib.c
+  GicV2/ArmGicV2NonSecLib.c
+
 [LibraryClasses]
   IoLib
 
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c b/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
index 3ff9b48..06367f9 100755
--- a/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
@@ -16,31 +16,6 @@
 #include <Library/IoLib.h>
 #include <Library/ArmGicLib.h>
 
-
-VOID
-EFIAPI
-ArmGicEnableInterruptInterface (
-  IN  INTN          GicInterruptInterfaceBase
-  )
-{  
-  /*
-  * Enable the CPU interface in Non-Secure world
-  * Note: The ICCICR register is banked when Security extensions are implemented
-  */
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x1);
-}
-
-VOID
-EFIAPI
-ArmGicDisableInterruptInterface (
-  IN  INTN          GicInterruptInterfaceBase
-  )
-{
-  // Disable Gic Interface
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x0);
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x0);
-}
-
 VOID
 EFIAPI
 ArmGicEnableDistributor (
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c
old mode 100644
new mode 100755
index f249eac..1fdd4d7
--- a/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c
@@ -1,70 +1,23 @@
 /** @file
 *
-*  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         
-*  which accompanies this distribution.  The full text of the license may be found at        
-*  http://opensource.org/licenses/bsd-license.php                                            
+*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
 *
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 *
 **/
 
 #include <Base.h>
-#include <Library/ArmLib.h>
-#include <Library/ArmPlatformLib.h>
 #include <Library/DebugLib.h>
 #include <Library/IoLib.h>
 #include <Library/ArmGicLib.h>
 
-/*
- * This function configures the all interrupts to be Non-secure.
- *
- */
-VOID
-EFIAPI
-ArmGicSetupNonSecure (
-  IN  UINTN         MpId,
-  IN  INTN          GicDistributorBase,
-  IN  INTN          GicInterruptInterfaceBase
-  )
-{
-  UINTN InterruptId;
-  UINTN CachedPriorityMask;
-  UINTN Index;
-
-  CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);
-
-  // Set priority Mask so that no interrupts get through to CPU
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);
-
-  InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
-
-  // Only try to clear valid interrupts. Ignore spurious interrupts.
-  while ((InterruptId & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase))   {
-    // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
-    ArmGicEndOfInterrupt (GicInterruptInterfaceBase, InterruptId);
-
-    // Next
-    InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
-  }
-
-  // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
-  if (ArmPlatformIsPrimaryCore (MpId)) {
-    // Ensure all GIC interrupts are Non-Secure
-    for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {
-      MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);
-    }
-  } else {
-    // The secondary cores only set the Non Secure bit to their banked PPIs
-    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);
-  }
-
-  // Ensure all interrupts can get through the priority mask
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);
-}
+#include "GicV2/ArmGicV2Lib.h"
 
 /*
  * This function configures the interrupts set by the mask to be secure.
@@ -93,41 +46,21 @@ ArmGicSetSecureInterrupts (
 
 VOID
 EFIAPI
-ArmGicEnableInterruptInterface (
-  IN  INTN          GicInterruptInterfaceBase
+ArmGicEnableDistributor (
+  IN  INTN          GicDistributorBase
   )
 {
-  // Set Priority Mask to allow interrupts
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);
-
-  // Enable CPU interface in Secure world
-  // Enable CPU interface in Non-secure World
-  // Signal Secure Interrupts to CPU using FIQ line *
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,
-      ARM_GIC_ICCICR_ENABLE_SECURE |
-      ARM_GIC_ICCICR_ENABLE_NS |
-      ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);
+  // Turn on the GIC distributor
+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);
 }
 
 VOID
 EFIAPI
-ArmGicDisableInterruptInterface (
+ArmGicSetupNonSecure (
+  IN  UINTN         MpId,
+  IN  INTN          GicDistributorBase,
   IN  INTN          GicInterruptInterfaceBase
   )
 {
-  UINT32    ControlValue;
-
-  // Disable CPU interface in Secure world and Non-secure World
-  ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR);
-  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS));
-}
-
-VOID
-EFIAPI
-ArmGicEnableDistributor (
-  IN  INTN          GicDistributorBase
-  )
-{
-  // Turn on the GIC distributor
-  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);
+  ArmGicV2SetupNonSecure (MpId, GicDistributorBase, GicInterruptInterfaceBase);
 }
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
old mode 100644
new mode 100755
index b888eb5..07e750f
--- a/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
@@ -1,5 +1,5 @@
 #/* @file
-#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2011-2014, 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         
@@ -23,6 +23,9 @@
   ArmGicLib.c
   ArmGicSecLib.c
 
+  GicV2/ArmGicV2Lib.c
+  GicV2/ArmGicV2SecLib.c
+
 [Packages]
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
diff --git a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c
new file mode 100755
index 0000000..aecca0c
--- /dev/null
+++ b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c
@@ -0,0 +1,37 @@
+/** @file
+*
+*  Copyright (c) 2013-2014, 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
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/ArmGicLib.h>
+#include <Library/IoLib.h>
+
+UINTN
+EFIAPI
+ArmGicV2AcknowledgeInterrupt (
+  IN  UINTN          GicInterruptInterfaceBase
+  )
+{
+  // Read the Interrupt Acknowledge Register
+  return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+}
+
+RETURN_STATUS
+EFIAPI
+ArmGicV2EndOfInterrupt (
+  IN  UINTN                 GicInterruptInterfaceBase,
+  IN UINTN                  Source
+  )
+{
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);
+  return RETURN_SUCCESS;
+}
diff --git a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h
new file mode 100755
index 0000000..65674b2
--- /dev/null
+++ b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h
@@ -0,0 +1,98 @@
+/** @file
+*
+*  Copyright (c) 2013-2014, 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
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _ARM_GIC_V2_H_
+#define _ARM_GIC_V2_H_
+
+//
+// GIC definitions
+//
+
+//
+// GIC Distributor
+//
+#define ARM_GIC_ICDDCR          0x000 // Distributor Control Register
+#define ARM_GIC_ICDICTR         0x004 // Interrupt Controller Type Register
+#define ARM_GIC_ICDIIDR         0x008 // Implementer Identification Register
+
+// Each reg base below repeats for VE_NUM_ARM_GIC_REG_PER_INT_BITS (see GIC spec)
+#define ARM_GIC_ICDISR          0x080 // Interrupt Security Registers
+#define ARM_GIC_ICDISER         0x100 // Interrupt Set-Enable Registers
+#define ARM_GIC_ICDICER         0x180 // Interrupt Clear-Enable Registers
+#define ARM_GIC_ICDSPR          0x200 // Interrupt Set-Pending Registers
+#define ARM_GIC_ICDICPR         0x280 // Interrupt Clear-Pending Registers
+#define ARM_GIC_ICDABR          0x300 // Active Bit Registers
+
+// Each reg base below repeats for VE_NUM_ARM_GIC_REG_PER_INT_BYTES
+#define ARM_GIC_ICDIPR          0x400 // Interrupt Priority Registers
+
+// Each reg base below repeats for VE_NUM_ARM_GIC_INTERRUPTS
+#define ARM_GIC_ICDIPTR         0x800 // Interrupt Processor Target Registers
+#define ARM_GIC_ICDICFR         0xC00 // Interrupt Configuration Registers
+
+#define ARM_GIC_ICDPPISR        0xD00 // PPI Status register
+
+// just one of these
+#define ARM_GIC_ICDSGIR         0xF00 // Software Generated Interrupt Register
+
+//
+// GIC Cpu interface
+//
+#define ARM_GIC_ICCICR          0x00  // CPU Interface Control Register
+#define ARM_GIC_ICCPMR          0x04  // Interrupt Priority Mask Register
+#define ARM_GIC_ICCBPR          0x08  // Binary Point Register
+#define ARM_GIC_ICCIAR          0x0C  // Interrupt Acknowledge Register
+#define ARM_GIC_ICCEIOR         0x10  // End Of Interrupt Register
+#define ARM_GIC_ICCRPR          0x14  // Running Priority Register
+#define ARM_GIC_ICCPIR          0x18  // Highest Pending Interrupt Register
+#define ARM_GIC_ICCABPR         0x1C  // Aliased Binary Point Register
+#define ARM_GIC_ICCIIDR         0xFC  // Identification Register
+
+// Bit Mask for
+#define ARM_GIC_ICCIAR_ACKINTID                 0x3FF
+
+VOID
+EFIAPI
+ArmGicV2SetupNonSecure (
+  IN  UINTN         MpId,
+  IN  INTN          GicDistributorBase,
+  IN  INTN          GicInterruptInterfaceBase
+  );
+
+VOID
+EFIAPI
+ArmGicV2EnableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  );
+
+VOID
+EFIAPI
+ArmGicV2DisableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  );
+
+UINTN
+EFIAPI
+ArmGicV2AcknowledgeInterrupt (
+  IN  UINTN          GicInterruptInterfaceBase
+  );
+
+RETURN_STATUS
+EFIAPI
+ArmGicV2EndOfInterrupt (
+  IN  UINTN                 GicInterruptInterfaceBase,
+  IN UINTN                  Source
+  );
+
+#endif
diff --git a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c
new file mode 100755
index 0000000..0108894
--- /dev/null
+++ b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c
@@ -0,0 +1,42 @@
+/** @file
+*
+*  Copyright (c) 2011-2014, 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
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+
+
+VOID
+EFIAPI
+ArmGicV2EnableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{  
+  /*
+  * Enable the CPU interface in Non-Secure world
+  * Note: The ICCICR register is banked when Security extensions are implemented
+  */
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x1);
+}
+
+VOID
+EFIAPI
+ArmGicV2DisableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{
+  // Disable Gic Interface
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x0);
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x0);
+}
diff --git a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c
new file mode 100755
index 0000000..5764bf3
--- /dev/null
+++ b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c
@@ -0,0 +1,98 @@
+/** @file
+*
+*  Copyright (c) 2011-2014, 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
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+
+/*
+ * This function configures the all interrupts to be Non-secure.
+ *
+ */
+VOID
+EFIAPI
+ArmGicV2SetupNonSecure (
+  IN  UINTN         MpId,
+  IN  INTN          GicDistributorBase,
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{
+  UINTN InterruptId;
+  UINTN CachedPriorityMask;
+  UINTN Index;
+
+  CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);
+
+  // Set priority Mask so that no interrupts get through to CPU
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);
+
+  InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+
+  // Only try to clear valid interrupts. Ignore spurious interrupts.
+  while ((InterruptId & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase))   {
+    // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
+    ArmGicEndOfInterrupt (GicInterruptInterfaceBase, InterruptId);
+
+    // Next
+    InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+  }
+
+  // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
+  if (ArmPlatformIsPrimaryCore (MpId)) {
+    // Ensure all GIC interrupts are Non-Secure
+    for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {
+      MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);
+    }
+  } else {
+    // The secondary cores only set the Non Secure bit to their banked PPIs
+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);
+  }
+
+  // Ensure all interrupts can get through the priority mask
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);
+}
+
+VOID
+EFIAPI
+ArmGicV2EnableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{
+  // Set Priority Mask to allow interrupts
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);
+
+  // Enable CPU interface in Secure world
+  // Enable CPU interface in Non-secure World
+  // Signal Secure Interrupts to CPU using FIQ line *
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,
+      ARM_GIC_ICCICR_ENABLE_SECURE |
+      ARM_GIC_ICCICR_ENABLE_NS |
+      ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);
+}
+
+VOID
+EFIAPI
+ArmGicV2DisableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{
+  UINT32    ControlValue;
+
+  // Disable CPU interface in Secure world and Non-secure World
+  ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR);
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS));
+}
-- 
1.8.5

