From 599945503f210292a9f0cd9b41734ceb2d0a7beb Mon Sep 17 00:00:00 2001
From: Olivier Martin <olivier.martin@arm.com>
Date: Fri, 27 Sep 2013 11:47:07 +0100
Subject: [PATCH 05/14] ArmPkg/ArmGic: Introduced helper functions to access
 the GIC controller

Change-Id: I3a1efd2ce07f51712b145adaa8969ef4b6ec30c6
---
 ArmPkg/Drivers/ArmGic/ArmGicDxe.c                  | 46 +++-----------
 ArmPkg/Drivers/ArmGic/ArmGicLib.c                  | 71 ++++++++++++++++++++++
 ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c            | 21 +++++++
 ArmPkg/Include/Library/ArmGicLib.h                 | 43 +++++++++++--
 .../Library/ArmVExpressSecLibRTSM/RTSMSec.c        |  4 +-
 5 files changed, 139 insertions(+), 46 deletions(-)

diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
index 9608c31..ca3a12f 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
@@ -111,22 +111,12 @@ EnableInterruptSource (
   IN HARDWARE_INTERRUPT_SOURCE          Source
   )
 {
-  UINT32    RegOffset;
-  UINTN     RegShift;
-  
   if (Source > mGicNumInterrupts) {
     ASSERT(FALSE);
     return EFI_UNSUPPORTED;
   }
   
-  // Calculate enable register offset and bit position
-  RegOffset = Source / 32;
-  RegShift = Source % 32;
-
-  // Write set-enable register
-  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset), 1 << RegShift);
-  
-  return EFI_SUCCESS;
+  return ArmGicEnableInterrupt (PcdGet32(PcdGicDistributorBase), Source);
 }
 
 /**
@@ -146,22 +136,12 @@ DisableInterruptSource (
   IN HARDWARE_INTERRUPT_SOURCE          Source
   )
 {
-  UINT32    RegOffset;
-  UINTN     RegShift;
-  
   if (Source > mGicNumInterrupts) {
     ASSERT(FALSE);
     return EFI_UNSUPPORTED;
   }
   
-  // Calculate enable register offset and bit position
-  RegOffset = Source / 32;
-  RegShift = Source % 32;
-
-  // Write set-enable register
-  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDICER + (4*RegOffset), 1 << RegShift);
-  
-  return EFI_SUCCESS;
+  return ArmGicDisableInterrupt (PcdGet32(PcdGicDistributorBase), Source);
 }
 
 /**
@@ -183,23 +163,12 @@ GetInterruptSourceState (
   IN BOOLEAN                            *InterruptState
   )
 {
-  UINT32    RegOffset;
-  UINTN     RegShift;
-  
   if (Source > mGicNumInterrupts) {
     ASSERT(FALSE);
     return EFI_UNSUPPORTED;
   }
-  
-  // calculate enable register offset and bit position
-  RegOffset = Source / 32;
-  RegShift = Source % 32;
     
-  if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset)) & (1<<RegShift)) == 0) {
-    *InterruptState = FALSE;
-  } else {
-    *InterruptState = TRUE;
-  }
+  *InterruptState = ArmGicIsInterruptEnabled (PcdGet32(PcdGicDistributorBase), Source);
   
   return EFI_SUCCESS;
 }
@@ -315,11 +284,10 @@ ExitBootServicesEvent (
   }
 
   // Disable Gic Interface
-  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x0);
-  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0x0);
+  ArmGicDisableInterruptInterface (PcdGet32(PcdGicInterruptInterfaceBase));
 
   // Disable Gic Distributor
-  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x0);
+  ArmGicDisableDistributor (PcdGet32(PcdGicDistributorBase));
 }
 
 /**
@@ -393,10 +361,10 @@ InterruptDxeInitialize (
   MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff);
   
   // Enable gic cpu interface
-  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1);
+  ArmGicEnableInterruptInterface (PcdGet32(PcdGicInterruptInterfaceBase));
 
   // Enable gic distributor
-  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x1);
+  ArmGicEnableDistributor (PcdGet32(PcdGicDistributorBase));
   
   // Initialize the array for the Interrupt Handlers
   gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
index ee35190..4da2ed7 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
@@ -19,6 +19,16 @@
 
 UINTN
 EFIAPI
+ArmGicGetInterfaceIdentification (
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{
+  // Read the GIC Identification Register
+  return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIIDR);
+}
+
+UINTN
+EFIAPI
 ArmGicGetMaxNumInterrupts (
   IN  INTN          GicDistributorBase
   )
@@ -58,3 +68,64 @@ ArmGicEndOfInterrupt (
   MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);
   return RETURN_SUCCESS;
 }
+
+RETURN_STATUS
+EFIAPI
+ArmGicEnableInterrupt (
+  IN UINTN                  GicDistributorBase,
+  IN UINTN                  Source
+  )
+{
+  UINT32    RegOffset;
+  UINTN     RegShift;
+
+  // Calculate enable register offset and bit position
+  RegOffset = Source / 32;
+  RegShift = Source % 32;
+
+  // Write set-enable register
+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);
+
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+ArmGicDisableInterrupt (
+  IN UINTN                  GicDistributorBase,
+  IN UINTN                  Source
+  )
+{
+  UINT32    RegOffset;
+  UINTN     RegShift;
+
+  // Calculate enable register offset and bit position
+  RegOffset = Source / 32;
+  RegShift = Source % 32;
+
+  // Write clear-enable register
+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);
+
+  return RETURN_SUCCESS;
+}
+
+BOOLEAN
+EFIAPI
+ArmGicIsInterruptEnabled (
+  IN UINTN                  GicDistributorBase,
+  IN UINTN                  Source
+  )
+{
+  UINT32    RegOffset;
+  UINTN     RegShift;
+
+  // Calculate enable register offset and bit position
+  RegOffset = Source / 32;
+  RegShift = Source % 32;
+
+  if ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) == 0) {
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c b/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
index 55ff56e..ad9e40d 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
@@ -32,6 +32,17 @@ ArmGicEnableInterruptInterface (
 
 VOID
 EFIAPI
+ArmGicDisableInterruptInterface (
+  IN  INTN          GicInterruptInterfaceBase
+  )
+{
+  // Disable Gic Interface
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x0);
+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x0);
+}
+
+VOID
+EFIAPI
 ArmGicEnableDistributor (
   IN  INTN          GicDistributorBase
   )
@@ -42,3 +53,13 @@ ArmGicEnableDistributor (
    */
   MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
 }
+
+VOID
+EFIAPI
+ArmGicDisableDistributor (
+  IN  INTN          GicDistributorBase
+  )
+{
+  // Disable Gic Distributor
+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x0);
+}
diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h
index dc0bae4..9a42748 100644
--- a/ArmPkg/Include/Library/ArmGicLib.h
+++ b/ArmPkg/Include/Library/ArmGicLib.h
@@ -57,7 +57,7 @@
 #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_ICCIDR          0xFC  // Identification Register
+#define ARM_GIC_ICCIIDR         0xFC  // Identification Register
 
 #define ARM_GIC_ICDSGIR_FILTER_TARGETLIST       0x0
 #define ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE     0x1
@@ -71,14 +71,20 @@
 #define ARM_GIC_ICCICR_USE_SBPR                 0x10
 
 // Bit Mask for GICC_IIDR
-#define ARM_GIC_ICCIDR_GET_PRODUCT_ID(IccIdr)   (((IccIdr) >> 20) & 0xFFF)
-#define ARM_GIC_ICCIDR_GET_ARCH_VERSION(IccIdr) (((IccIdr) >> 16) & 0xF)
-#define ARM_GIC_ICCIDR_GET_REVISION(IccIdr)     (((IccIdr) >> 12) & 0xF)
-#define ARM_GIC_ICCIDR_GET_IMPLEMENTER(IccIdr)  ((IccIdr) & 0xFFF)
+#define ARM_GIC_ICCIIDR_GET_PRODUCT_ID(IccIidr)   (((IccIidr) >> 20) & 0xFFF)
+#define ARM_GIC_ICCIIDR_GET_ARCH_VERSION(IccIidr) (((IccIidr) >> 16) & 0xF)
+#define ARM_GIC_ICCIIDR_GET_REVISION(IccIidr)     (((IccIidr) >> 12) & 0xF)
+#define ARM_GIC_ICCIIDR_GET_IMPLEMENTER(IccIidr)  ((IccIidr) & 0xFFF)
 
 // Bit Mask for
 #define ARM_GIC_ICCIAR_ACKINTID                 0x3FF
 
+UINTN
+EFIAPI
+ArmGicGetInterfaceIdentification (
+  IN  INTN          GicInterruptInterfaceBase
+  );
+
 //
 // GIC Secure interfaces
 //
@@ -116,6 +122,12 @@ ArmGicEnableDistributor (
   IN  INTN          GicDistributorBase
   );
 
+VOID
+EFIAPI
+ArmGicDisableDistributor (
+  IN  INTN          GicDistributorBase
+  );
+
 UINTN
 EFIAPI
 ArmGicGetMaxNumInterrupts (
@@ -158,4 +170,25 @@ ArmGicSetPriorityMask (
   IN  INTN          PriorityMask
   );
 
+RETURN_STATUS
+EFIAPI
+ArmGicEnableInterrupt (
+  IN UINTN                  GicDistributorBase,
+  IN UINTN                  Source
+  );
+
+RETURN_STATUS
+EFIAPI
+ArmGicDisableInterrupt (
+  IN UINTN                  GicDistributorBase,
+  IN UINTN                  Source
+  );
+
+BOOLEAN
+EFIAPI
+ArmGicIsInterruptEnabled (
+  IN UINTN                  GicDistributorBase,
+  IN UINTN                  Source
+  );
+
 #endif
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c
index 4c018f7..7afab97 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c
@@ -73,10 +73,10 @@ ArmPlatformSecInitialize (
   MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER3_EN, SP810_SYS_CTRL_TIMER3_TIMCLK);
 
   // Read the GIC Identification Register
-  Identification = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIDR);
+  Identification = ArmGicGetInterfaceIdentification (PcdGet32 (PcdGicInterruptInterfaceBase));
 
   // Check if we are GICv3
-  if (ARM_GIC_ICCIDR_GET_ARCH_VERSION(Identification) >= 0x3) {
+  if (ARM_GIC_ICCIIDR_GET_ARCH_VERSION(Identification) >= 0x3) {
     InitializeGicV3 ();
   }
 
-- 
1.8.5

