| /** @file | |
| * | |
| * Copyright (c) 2014, ARM Limited. All rights reserved. | |
| * | |
| * SPDX-License-Identifier: BSD-2-Clause-Patent | |
| * | |
| **/ | |
| #include <Library/ArmLib.h> | |
| #include <Library/ArmGicLib.h> | |
| ARM_GIC_ARCH_REVISION | |
| EFIAPI | |
| ArmGicGetSupportedArchRevision ( | |
| 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 (ArmHasGicSystemRegisters ()) { | |
| // 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) { | |
| return ARM_GIC_ARCH_REVISION_3; | |
| } | |
| } | |
| return ARM_GIC_ARCH_REVISION_2; | |
| } |