diff options
Diffstat (limited to 'roms/edk2/ArmPkg/Library/ArmGicArchLib')
3 files changed, 148 insertions, 0 deletions
diff --git a/roms/edk2/ArmPkg/Library/ArmGicArchLib/AArch64/ArmGicArchLib.c b/roms/edk2/ArmPkg/Library/ArmGicArchLib/AArch64/ArmGicArchLib.c new file mode 100644 index 000000000..4086a294d --- /dev/null +++ b/roms/edk2/ArmPkg/Library/ArmGicArchLib/AArch64/ArmGicArchLib.c @@ -0,0 +1,60 @@ +/** @file
+*
+* Copyright (c) 2014, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Library/ArmLib.h>
+#include <Library/ArmGicLib.h>
+
+STATIC ARM_GIC_ARCH_REVISION mGicArchRevision;
+
+RETURN_STATUS
+EFIAPI
+ArmGicArchLibInitialize (
+ VOID
+ )
+{
+ UINT32 IccSre;
+
+ // Ideally we would like to use the GICC IIDR Architecture version here, but
+ // this does not seem to be very reliable as the implementation could easily
+ // get it wrong. It is more reliable to check if the GICv3 System Register
+ // feature is implemented on the CPU. This is also convenient as our GICv3
+ // driver requires SRE. If only Memory mapped access is available we try to
+ // drive the GIC as a v2.
+ if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) {
+ // Make sure System Register access is enabled (SRE). This depends on the
+ // higher privilege level giving us permission, otherwise we will either
+ // cause an exception here, or the write doesn't stick in which case we need
+ // to fall back to the GICv2 MMIO interface.
+ // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
+ // at the same exception level.
+ // It is the OS responsibility to set this bit.
+ IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+ if (!(IccSre & ICC_SRE_EL2_SRE)) {
+ ArmGicV3SetControlSystemRegisterEnable (IccSre | ICC_SRE_EL2_SRE);
+ IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+ }
+ if (IccSre & ICC_SRE_EL2_SRE) {
+ mGicArchRevision = ARM_GIC_ARCH_REVISION_3;
+ goto Done;
+ }
+ }
+
+ mGicArchRevision = ARM_GIC_ARCH_REVISION_2;
+
+Done:
+ return RETURN_SUCCESS;
+}
+
+ARM_GIC_ARCH_REVISION
+EFIAPI
+ArmGicGetSupportedArchRevision (
+ VOID
+ )
+{
+ return mGicArchRevision;
+}
diff --git a/roms/edk2/ArmPkg/Library/ArmGicArchLib/Arm/ArmGicArchLib.c b/roms/edk2/ArmPkg/Library/ArmGicArchLib/Arm/ArmGicArchLib.c new file mode 100644 index 000000000..222d80598 --- /dev/null +++ b/roms/edk2/ArmPkg/Library/ArmGicArchLib/Arm/ArmGicArchLib.c @@ -0,0 +1,60 @@ +/** @file
+*
+* Copyright (c) 2014, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Library/ArmLib.h>
+#include <Library/ArmGicLib.h>
+
+STATIC ARM_GIC_ARCH_REVISION mGicArchRevision;
+
+RETURN_STATUS
+EFIAPI
+ArmGicArchLibInitialize (
+ VOID
+ )
+{
+ UINT32 IccSre;
+
+ // Ideally we would like to use the GICC IIDR Architecture version here, but
+ // this does not seem to be very reliable as the implementation could easily
+ // get it wrong. It is more reliable to check if the GICv3 System Register
+ // feature is implemented on the CPU. This is also convenient as our GICv3
+ // driver requires SRE. If only Memory mapped access is available we try to
+ // drive the GIC as a v2.
+ if (ArmReadIdPfr1 () & ARM_PFR1_GIC) {
+ // Make sure System Register access is enabled (SRE). This depends on the
+ // higher privilege level giving us permission, otherwise we will either
+ // cause an exception here, or the write doesn't stick in which case we need
+ // to fall back to the GICv2 MMIO interface.
+ // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
+ // at the same exception level.
+ // It is the OS responsibility to set this bit.
+ IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+ if (!(IccSre & ICC_SRE_EL2_SRE)) {
+ ArmGicV3SetControlSystemRegisterEnable (IccSre| ICC_SRE_EL2_SRE);
+ IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+ }
+ if (IccSre & ICC_SRE_EL2_SRE) {
+ mGicArchRevision = ARM_GIC_ARCH_REVISION_3;
+ goto Done;
+ }
+ }
+
+ mGicArchRevision = ARM_GIC_ARCH_REVISION_2;
+
+Done:
+ return RETURN_SUCCESS;
+}
+
+ARM_GIC_ARCH_REVISION
+EFIAPI
+ArmGicGetSupportedArchRevision (
+ VOID
+ )
+{
+ return mGicArchRevision;
+}
diff --git a/roms/edk2/ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf b/roms/edk2/ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf new file mode 100644 index 000000000..92ac11c2f --- /dev/null +++ b/roms/edk2/ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf @@ -0,0 +1,28 @@ +#/* @file
+# Copyright (c) 2015, Linaro Ltd. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmGicArchLib
+ FILE_GUID = cd67f41a-26e9-4482-90c9-a9aff803382a
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmGicArchLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+ CONSTRUCTOR = ArmGicArchLibInitialize
+
+[Sources.ARM]
+ Arm/ArmGicArchLib.c
+
+[Sources.AARCH64]
+ AArch64/ArmGicArchLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmGicLib
|