From 48108e5f0b234cc36064fb554e62a3a0c525dc75 Mon Sep 17 00:00:00 2001
From: Olivier Martin <olivier.martin@arm.com>
Date: Tue, 25 Mar 2014 17:49:37 +0000
Subject: [PATCH 13/14] ArmPkg/ArmGic: Added GicV3 support to ArmGicLib

Change-Id: Ib6171747c015d7a73f6f84267603365a6249fe56
---
 ArmPkg/Drivers/ArmGic/ArmGicLib.c              |   9 ++
 ArmPkg/Drivers/ArmGic/ArmGicLib.inf            |   3 +
 ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf         |   3 +
 ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S | 117 +++++++++++++++++++++++++
 ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S     |  84 ++++++++++++++++++
 ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm   |  83 ++++++++++++++++++
 ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h      |  52 +++++++++++
 7 files changed, 351 insertions(+)
 create mode 100755 ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
 create mode 100755 ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
 create mode 100755 ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
 create mode 100644 ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h

diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
index 1b0a4cf..de6a7e6 100755
--- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
@@ -18,6 +18,7 @@
 #include <Library/IoLib.h>
 
 #include "GicV2/ArmGicV2Lib.h"
+#include "GicV3/ArmGicV3Lib.h"
 
 UINTN
 EFIAPI
@@ -61,6 +62,8 @@ ArmGicAcknowledgeInterrupt (
   Revision = ArmGicGetSupportedArchRevision ();
   if (Revision == ARM_GIC_ARCH_REVISION_2) {
     return ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+    return ArmGicV3AcknowledgeInterrupt ();
   } else {
     ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
     return 0;
@@ -79,6 +82,8 @@ ArmGicEndOfInterrupt (
   Revision = ArmGicGetSupportedArchRevision ();
   if (Revision == ARM_GIC_ARCH_REVISION_2) {
     return ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source);
+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+    return ArmGicV3EndOfInterrupt (Source);
   } else {
     ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
     return RETURN_UNSUPPORTED;
@@ -167,6 +172,8 @@ ArmGicEnableInterruptInterface (
   Revision = ArmGicGetSupportedArchRevision ();
   if (Revision == ARM_GIC_ARCH_REVISION_2) {
     ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase);
+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+    ArmGicV3EnableInterruptInterface ();
   } else {
     ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
   }
@@ -183,6 +190,8 @@ ArmGicDisableInterruptInterface (
   Revision = ArmGicGetSupportedArchRevision ();
   if (Revision == ARM_GIC_ARCH_REVISION_2) {
     ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase);
+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+    ArmGicV3DisableInterruptInterface ();
   } else {
     ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
   }
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
index 0171f3d..f982db0 100755
--- a/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
@@ -28,9 +28,12 @@
 
 [Sources.ARM]
   Arm/ArmGicArchLib.c
+  GicV3/Arm/ArmGicV3.S     | GCC
+  GicV3/Arm/ArmGicV3.asm   | RVCT
 
 [Sources.AARCH64]
   AArch64/ArmGicArchLib.c
+  GicV3/AArch64/ArmGicV3.S | GCC
 
 [LibraryClasses]
   ArmLib
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
index 84a3e60..1940fcd 100755
--- a/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
@@ -28,9 +28,12 @@
 
 [Sources.ARM]
   Arm/ArmGicArchLib.c
+  GicV3/Arm/ArmGicV3.S     | GCC
+  GicV3/Arm/ArmGicV3.asm   | RVCT
 
 [Sources.AARCH64]
   AArch64/ArmGicArchLib.c
+  GicV3/AArch64/ArmGicV3.S | GCC
 
 [Packages]
   ArmPkg/ArmPkg.dec
diff --git a/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S b/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
new file mode 100755
index 0000000..a47c1d3
--- /dev/null
+++ b/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
@@ -0,0 +1,117 @@
+#
+#  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 <AsmMacroIoLibV8.h>
+
+#define ICC_SRE_EL1			S3_0_C12_C12_5
+#define ICC_SRE_EL2			S3_4_C12_C9_5
+#define ICC_SRE_EL3			S3_6_C12_C12_5
+#define ICC_IGRPEN1_EL1		S3_0_C12_C12_7
+#define ICC_EOIR1_EL1		S3_0_C12_C12_1
+#define ICC_IAR1_EL1		S3_0_C12_C12_0
+#define ICC_PMR_EL1			S3_0_C4_C6_0
+#define ICC_BPR1_EL1		S3_0_C12_C12_3
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmGicGetControlSystemRegisterEnable)
+GCC_ASM_EXPORT(ArmGicSetControlSystemRegisterEnable)
+GCC_ASM_EXPORT(ArmGicV3EnableInterruptInterface)
+GCC_ASM_EXPORT(ArmGicV3DisableInterruptInterface)
+GCC_ASM_EXPORT(ArmGicV3EndOfInterrupt)
+GCC_ASM_EXPORT(ArmGicV3AcknowledgeInterrupt)
+GCC_ASM_EXPORT(ArmGicV3SetPriorityMask)
+GCC_ASM_EXPORT(ArmGicV3SetBinaryPointer)
+
+//UINT32
+//EFIAPI
+//ArmGicGetControlSystemRegisterEnable (
+//  VOID
+//  );
+ASM_PFX(ArmGicGetControlSystemRegisterEnable):
+	EL1_OR_EL2_OR_EL3(x1)
+1:  mrs	x0, ICC_SRE_EL1
+	b	4f
+2:  mrs	x0, ICC_SRE_EL2
+	b	4f
+3:  mrs	x0, ICC_SRE_EL3
+	b	4f
+4:  isb
+	ret
+
+//RETURN_STATUS
+//EFIAPI
+//ArmGicSetControlSystemRegisterEnable (
+//  IN UINT32         ControlSystemRegisterEnable
+//  );
+ASM_PFX(ArmGicSetControlSystemRegisterEnable):
+	EL1_OR_EL2_OR_EL3(x1)
+1:  msr	ICC_SRE_EL1, x0
+	b	4f
+2:  msr	ICC_SRE_EL2, x0
+	b	4f
+3:  msr	ICC_SRE_EL3, x0
+	b	4f
+4:  isb
+	ret
+
+//VOID
+//ArmGicV3EnableInterruptInterface (
+//  VOID
+//  );
+ASM_PFX(ArmGicV3EnableInterruptInterface):
+	mov	x0, #1
+	msr	ICC_IGRPEN1_EL1, x0
+ 	ret
+
+//VOID
+//ArmGicV3DisableInterruptInterface (
+//  VOID
+//  );
+ASM_PFX(ArmGicV3DisableInterruptInterface):
+	mov	x0, #0
+	msr	ICC_IGRPEN1_EL1, x0
+	ret
+
+//VOID
+//ArmGicV3EndOfInterrupt (
+//  IN UINTN InterruptId
+//  );
+ASM_PFX(ArmGicV3EndOfInterrupt):
+	msr	ICC_EOIR1_EL1, x0
+	ret
+
+//UINTN
+//ArmGicV3AcknowledgeInterrupt (
+//  VOID
+//  );
+ASM_PFX(ArmGicV3AcknowledgeInterrupt):
+	mrs	x0, ICC_IAR1_EL1
+	ret
+
+//VOID
+//ArmGicV3SetPriorityMask (
+//  IN UINTN                  Priority
+//  );
+ASM_PFX(ArmGicV3SetPriorityMask):
+	msr ICC_PMR_EL1, x0
+	ret
+
+//VOID
+//ArmGicV3SetBinaryPointer (
+//  IN UINTN                  BinaryPoint
+//  );
+ASM_PFX(ArmGicV3SetBinaryPointer):
+	msr	ICC_BPR1_EL1, x0
+	ret
diff --git a/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S b/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
new file mode 100755
index 0000000..d39f145
--- /dev/null
+++ b/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
@@ -0,0 +1,84 @@
+#
+#  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 <AsmMacroIoLib.h>
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmGicGetControlSystemRegisterEnable)
+GCC_ASM_EXPORT(ArmGicSetControlSystemRegisterEnable)
+GCC_ASM_EXPORT(ArmGicV3EnableInterruptInterface)
+GCC_ASM_EXPORT(ArmGicV3DisableInterruptInterface)
+GCC_ASM_EXPORT(ArmGicV3EndOfInterrupt)
+GCC_ASM_EXPORT(ArmGicV3AcknowledgeInterrupt)
+GCC_ASM_EXPORT(ArmGicV3SetPriorityMask)
+GCC_ASM_EXPORT(ArmGicV3SetBinaryPointer)
+
+//UINT32
+//EFIAPI
+//ArmGicGetControlSystemRegisterEnable (
+//  VOID
+//  );
+ASM_PFX(ArmGicGetControlSystemRegisterEnable):
+	bx	lr
+
+//RETURN_STATUS
+//EFIAPI
+//ArmGicSetControlSystemRegisterEnable (
+//  IN UINT32         ControlSystemRegisterEnable
+//  );
+ASM_PFX(ArmGicSetControlSystemRegisterEnable):
+	bx	lr
+
+//VOID
+//ArmGicV3EnableInterruptInterface (
+//  VOID
+//  );
+ASM_PFX(ArmGicV3EnableInterruptInterface):
+	bx	lr
+
+//VOID
+//ArmGicV3DisableInterruptInterface (
+//  VOID
+//  );
+ASM_PFX(ArmGicV3DisableInterruptInterface):
+	bx	lr
+
+//VOID
+//ArmGicV3EndOfInterrupt (
+//  IN UINTN InterruptId
+//  );
+ASM_PFX(ArmGicV3EndOfInterrupt):
+	bx	lr
+
+//UINTN
+//ArmGicV3AcknowledgeInterrupt (
+//  VOID
+//  );
+ASM_PFX(ArmGicV3AcknowledgeInterrupt):
+	bx	lr
+
+//VOID
+//ArmGicV3SetPriorityMask (
+//  IN UINTN                  Priority
+//  );
+ASM_PFX(ArmGicV3SetPriorityMask):
+	bx	lr
+
+//VOID
+//ArmGicV3SetBinaryPointer (
+//  IN UINTN                  BinaryPoint
+//  );
+ASM_PFX(ArmGicV3SetBinaryPointer):
+	bx	lr
diff --git a/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm b/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
new file mode 100755
index 0000000..ece0a18
--- /dev/null
+++ b/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
@@ -0,0 +1,83 @@
+//
+//  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.
+//
+//
+
+    EXPORT  ArmGicGetControlSystemRegisterEnable
+    EXPORT  ArmGicSetControlSystemRegisterEnable
+    EXPORT  ArmGicV3EnableInterruptInterface
+    EXPORT  ArmGicV3DisableInterruptInterface
+    EXPORT  ArmGicV3EndOfInterrupt
+    EXPORT  ArmGicV3AcknowledgeInterrupt
+    EXPORT  ArmGicV3SetPriorityMask
+    EXPORT  ArmGicV3SetBinaryPointer
+
+    AREA ArmGicV3, CODE, READONLY
+
+//UINT32
+//EFIAPI
+//ArmGicGetControlSystemRegisterEnable (
+//  VOID
+//  );
+ArmGicGetControlSystemRegisterEnable
+	bx	lr
+
+//RETURN_STATUS
+//EFIAPI
+//ArmGicSetControlSystemRegisterEnable (
+//  IN UINT32         ControlSystemRegisterEnable
+//  );
+ArmGicSetControlSystemRegisterEnable
+	bx	lr
+
+//VOID
+//ArmGicV3EnableInterruptInterface (
+//  VOID
+//  );
+ArmGicV3EnableInterruptInterface
+	bx	lr
+
+//VOID
+//ArmGicV3DisableInterruptInterface (
+//  VOID
+//  );
+ArmGicV3DisableInterruptInterface
+	bx	lr
+
+//VOID
+//ArmGicV3EndOfInterrupt (
+//  IN UINTN InterruptId
+//  );
+ArmGicV3EndOfInterrupt
+	bx	lr
+
+//UINTN
+//ArmGicV3AcknowledgeInterrupt (
+//  VOID
+//  );
+ArmGicV3AcknowledgeInterrupt
+	bx	lr
+
+//VOID
+//ArmGicV3SetPriorityMask (
+//  IN UINTN                  Priority
+//  );
+ArmGicV3SetPriorityMask
+	bx	lr
+
+//VOID
+//ArmGicV3SetBinaryPointer (
+//  IN UINTN                  BinaryPoint
+//  );
+ArmGicV3SetBinaryPointer
+	bx	lr
+
+	END
diff --git a/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h b/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
new file mode 100644
index 0000000..0cec97a
--- /dev/null
+++ b/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
@@ -0,0 +1,52 @@
+/** @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_V3_H_
+#define _ARM_GIC_V3_H_
+
+VOID
+EFIAPI
+ArmGicV3EnableInterruptInterface (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmGicV3DisableInterruptInterface (
+  VOID
+  );
+
+UINTN
+EFIAPI
+ArmGicV3AcknowledgeInterrupt (
+  VOID
+  );
+
+RETURN_STATUS
+EFIAPI
+ArmGicV3EndOfInterrupt (
+  IN UINTN                  Source
+  );
+
+VOID
+ArmGicV3SetBinaryPointer (
+  IN UINTN                  BinaryPoint
+  );
+
+VOID
+ArmGicV3SetPriorityMask (
+  IN UINTN                  Priority
+  );
+
+#endif
-- 
1.8.5

