diff --git a/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c b/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c index 5a7837f43d..9da69b2131 100644 --- a/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c +++ b/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c @@ -15,6 +15,8 @@ #include #include +#include "GicV3/ArmGicV3Lib.h" + ARM_GIC_ARCH_REVISION EFIAPI ArmGicGetSupportedArchRevision ( @@ -28,7 +30,17 @@ ArmGicGetSupportedArchRevision ( // driver requires SRE. If only Memory mapped access is available we try to // drive the GIC as a v2. if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) { - return ARM_GIC_ARCH_REVISION_3; + // 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. + ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE); + if (ArmGicV3GetControlSystemRegisterEnable () & ICC_SRE_EL2_SRE) { + return ARM_GIC_ARCH_REVISION_3; + } } return ARM_GIC_ARCH_REVISION_2; diff --git a/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c b/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c index 668858f79a..f360a40583 100644 --- a/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c +++ b/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c @@ -15,6 +15,8 @@ #include #include +#include "GicV3/ArmGicV3Lib.h" + ARM_GIC_ARCH_REVISION EFIAPI ArmGicGetSupportedArchRevision ( @@ -28,7 +30,17 @@ ArmGicGetSupportedArchRevision ( // driver requires SRE. If only Memory mapped access is available we try to // drive the GIC as a v2. if (ArmReadIdPfr1 () & ARM_PFR1_GIC) { - return ARM_GIC_ARCH_REVISION_3; + // 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. + ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE); + if (ArmGicV3GetControlSystemRegisterEnable () & ICC_SRE_EL2_SRE) { + return ARM_GIC_ARCH_REVISION_3; + } } return ARM_GIC_ARCH_REVISION_2; diff --git a/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c b/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c index 8042f718f5..f756d30803 100644 --- a/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c +++ b/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c @@ -281,14 +281,6 @@ GicV3DxeInitialize ( } } - // Make sure System Register access is enabled (SRE). This depends on the - // lower levels giving us permission, otherwise we will cause an exception - // here. - // 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. - ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE); - // Set binary point reg to 0x7 (no preemption) ArmGicV3SetBinaryPointer (0x7);