1 /** @file
2 *
3 *  Copyright (c) 2014, ARM Limited. All rights reserved.
4 *
5 *  This program and the accompanying materials are licensed and made available
6 *  under the terms and conditions of the BSD License which accompanies this
7 *  distribution.  The full text of the license may be found at
8 *  http://opensource.org/licenses/bsd-license.php
9 *
10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14 
15 #include <Library/ArmLib.h>
16 #include <Library/ArmGicLib.h>
17 
18 ARM_GIC_ARCH_REVISION
19 EFIAPI
ArmGicGetSupportedArchRevision(VOID)20 ArmGicGetSupportedArchRevision (
21   VOID
22   )
23 {
24   UINT32    IccSre;
25 
26   // Ideally we would like to use the GICC IIDR Architecture version here, but
27   // this does not seem to be very reliable as the implementation could easily
28   // get it wrong. It is more reliable to check if the GICv3 System Register
29   // feature is implemented on the CPU. This is also convenient as our GICv3
30   // driver requires SRE. If only Memory mapped access is available we try to
31   // drive the GIC as a v2.
32   if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) {
33     // Make sure System Register access is enabled (SRE). This depends on the
34     // higher privilege level giving us permission, otherwise we will either
35     // cause an exception here, or the write doesn't stick in which case we need
36     // to fall back to the GICv2 MMIO interface.
37     // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
38     // at the same exception level.
39     // It is the OS responsibility to set this bit.
40     IccSre = ArmGicV3GetControlSystemRegisterEnable ();
41     if (!(IccSre & ICC_SRE_EL2_SRE)) {
42       ArmGicV3SetControlSystemRegisterEnable (IccSre | ICC_SRE_EL2_SRE);
43       IccSre = ArmGicV3GetControlSystemRegisterEnable ();
44     }
45     if (IccSre & ICC_SRE_EL2_SRE) {
46       return ARM_GIC_ARCH_REVISION_3;
47     }
48   }
49 
50   return ARM_GIC_ARCH_REVISION_2;
51 }
52