From d5c6b7fca306f5034f1200261bf9f77c52498cd5 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Mon, 27 Oct 2014 10:27:27 +0000 Subject: [PATCH] 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. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16231 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Drivers/ArmGic/ArmGicDxe.c | 12 +++++- ArmPkg/Drivers/ArmGic/ArmGicLib.c | 59 +++++++++++++++++++++++------ ArmPkg/Drivers/ArmGic/ArmGicLib.inf | 1 + ArmPkg/Include/Library/ArmGicLib.h | 9 +++++ 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c index 37c32504a5..8be2d6fe5e 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c +++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c @@ -33,6 +33,7 @@ Abstract: @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems + @retval EFI_UNSUPPORTED GIC version not supported **/ EFI_STATUS @@ -41,9 +42,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 717b18b9e6..23b312362f 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c +++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c @@ -19,6 +19,15 @@ #include "GicV2/ArmGicV2Lib.h" +ARM_GIC_ARCH_REVISION +EFIAPI +ArmGicGetSupportedArchRevision ( + VOID + ) +{ + return ARM_GIC_ARCH_REVISION_2; +} + UINTN EFIAPI ArmGicGetInterfaceIdentification ( @@ -71,15 +80,22 @@ ArmGicAcknowledgeInterrupt ( ) { UINTN Value; + ARM_GIC_ARCH_REVISION Revision; - Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase); - - // InterruptId is required for the caller to know if a valid or spurious - // interrupt has been read - ASSERT (InterruptId != NULL); - - if (InterruptId != NULL) { - *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID; + Revision = ArmGicGetSupportedArchRevision (); + if (Revision == ARM_GIC_ARCH_REVISION_2) { + Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase); + // InterruptId is required for the caller to know if a valid or spurious + // interrupt has been read + ASSERT (InterruptId != NULL); + if (InterruptId != NULL) { + *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID; + } + } else { + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); + // Report Spurious interrupt which is what the above controllers would + // return if no interrupt was available + Value = 1023; } return Value; @@ -92,7 +108,14 @@ ArmGicEndOfInterrupt ( IN UINTN Source ) { - ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source); + ARM_GIC_ARCH_REVISION Revision; + + Revision = ArmGicGetSupportedArchRevision (); + if (Revision == ARM_GIC_ARCH_REVISION_2) { + ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source); + } else { + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); + } } VOID @@ -164,7 +187,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 @@ -173,5 +203,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 a3e110e69f..def70a0d5e 100644 --- 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 e3ef228dba..7ffd026378 100644 --- a/ArmPkg/Include/Library/ArmGicLib.h +++ b/ArmPkg/Include/Library/ArmGicLib.h @@ -18,6 +18,9 @@ // // GIC definitions // +typedef enum { + ARM_GIC_ARCH_REVISION_2 +} ARM_GIC_ARCH_REVISION; // // GIC Distributor @@ -76,6 +79,12 @@ #define ARM_GIC_ICCIIDR_GET_REVISION(IccIidr) (((IccIidr) >> 12) & 0xF) #define ARM_GIC_ICCIIDR_GET_IMPLEMENTER(IccIidr) ((IccIidr) & 0xFFF) +ARM_GIC_ARCH_REVISION +EFIAPI +ArmGicGetSupportedArchRevision ( + VOID + ); + UINTN EFIAPI ArmGicGetInterfaceIdentification (