From 44fb197e37f45ba7b15d8393e0bffc526ef5e2b2 Mon Sep 17 00:00:00 2001
From: Olivier Martin <olivier.martin@arm.com>
Date: Tue, 25 Mar 2014 14:49:06 +0000
Subject: [PATCH 11/14] ArmPkg/ArmGic: Introduced
 ArmGicGetSupportedArchRevision()

This function returns the revision of the GIC Architecture.
Some GICv3 controllers can work in GICv2 mode. Switching to an
older GIC revision is driven by the higher level exception level.
This function allows code to support any GIC revision at runtime.

Change-Id: Icd0d0528717d0cc97422f33214321a87b4ed17b8
---
 ArmPkg/Drivers/ArmGic/ArmGicDxe.c   | 11 +++++++--
 ArmPkg/Drivers/ArmGic/ArmGicLib.c   | 48 +++++++++++++++++++++++++++++++++----
 ArmPkg/Drivers/ArmGic/ArmGicLib.inf |  1 +
 ArmPkg/Include/Library/ArmGicLib.h  | 11 ++++++++-
 4 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
index 3f32165..1fd67ca 100755
--- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
@@ -46,9 +46,16 @@ InterruptDxeInitialize (
   IN EFI_SYSTEM_TABLE   *SystemTable
   )
 {
-  EFI_STATUS  Status;
+  EFI_STATUS            Status;
+  ARM_GIC_ARCH_REVISION Revision;
 
-  Status = GicV2DxeInitialize (ImageHandle, SystemTable);
+  Revision = ArmGicGetSupportedArchRevision ();
+
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    Status = GicV2DxeInitialize (ImageHandle, SystemTable);
+  } else {
+    Status = EFI_UNSUPPORTED;
+  }
 
   return Status;
 }
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
index 14deaa4..bf1810f 100755
--- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
@@ -14,10 +14,20 @@
 
 #include <Base.h>
 #include <Library/ArmGicLib.h>
+#include <Library/DebugLib.h>
 #include <Library/IoLib.h>
 
 #include "GicV2/ArmGicV2Lib.h"
 
+ARM_GIC_ARCH_REVISION
+EFIAPI
+ArmGicGetSupportedArchRevision (
+  VOID
+  )
+{
+  return ARM_GIC_ARCH_REVISION_2;
+}
+
 UINTN
 EFIAPI
 ArmGicGetInterfaceIdentification (
@@ -55,7 +65,15 @@ ArmGicAcknowledgeInterrupt (
   IN  UINTN          GicInterruptInterfaceBase
   )
 {
-  return ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
+  ARM_GIC_ARCH_REVISION Revision;
+
+  Revision = ArmGicGetSupportedArchRevision ();
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    return ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
+  } else {
+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+    return 0;
+  }
 }
 
 RETURN_STATUS
@@ -65,7 +83,15 @@ ArmGicEndOfInterrupt (
   IN UINTN                  Source
   )
 {
-  return ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source);
+  ARM_GIC_ARCH_REVISION Revision;
+
+  Revision = ArmGicGetSupportedArchRevision ();
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    return ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source);
+  } else {
+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+    return RETURN_UNSUPPORTED;
+  }
 }
 
 RETURN_STATUS
@@ -145,7 +171,14 @@ ArmGicEnableInterruptInterface (
   IN  INTN          GicInterruptInterfaceBase
   )
 {
-  return ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase);
+  ARM_GIC_ARCH_REVISION Revision;
+
+  Revision = ArmGicGetSupportedArchRevision ();
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase);
+  } else {
+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+  }
 }
 
 VOID
@@ -154,5 +187,12 @@ ArmGicDisableInterruptInterface (
   IN  INTN          GicInterruptInterfaceBase
   )
 {
-  return ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase);
+  ARM_GIC_ARCH_REVISION Revision;
+
+  Revision = ArmGicGetSupportedArchRevision ();
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase);
+  } else {
+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+  }
 }
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
index 4652348..5fe07e6 100755
--- a/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
@@ -27,6 +27,7 @@
   GicV2/ArmGicV2NonSecLib.c
 
 [LibraryClasses]
+  DebugLib
   IoLib
 
 [Packages]
diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h
index 9a42748..6c88bff 100644
--- a/ArmPkg/Include/Library/ArmGicLib.h
+++ b/ArmPkg/Include/Library/ArmGicLib.h
@@ -1,6 +1,6 @@
 /** @file
 *
-*  Copyright (c) 2011-2013, 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
@@ -18,6 +18,9 @@
 //
 // GIC definitions
 //
+typedef enum {
+  ARM_GIC_ARCH_REVISION_2
+} ARM_GIC_ARCH_REVISION;
 
 //
 // GIC Distributor
@@ -79,6 +82,12 @@
 // Bit Mask for
 #define ARM_GIC_ICCIAR_ACKINTID                 0x3FF
 
+ARM_GIC_ARCH_REVISION
+EFIAPI
+ArmGicGetSupportedArchRevision (
+  VOID
+  );
+
 UINTN
 EFIAPI
 ArmGicGetInterfaceIdentification (
-- 
1.8.5

