2 ArmGicArchLib library class implementation for DT based virt platforms
4 Copyright (c) 2015 - 2016, Linaro Ltd. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Library/ArmGicLib.h>
20 #include <Library/ArmGicArchLib.h>
21 #include <Library/BaseLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/PcdLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
26 #include <Protocol/FdtClient.h>
28 STATIC ARM_GIC_ARCH_REVISION mGicArchRevision
;
32 ArmVirtGicArchLibConstructor (
37 FDT_CLIENT_PROTOCOL
*FdtClient
;
40 UINTN AddressCells
, SizeCells
;
43 UINT64 DistBase
, CpuBase
, RedistBase
;
44 RETURN_STATUS PcdStatus
;
46 Status
= gBS
->LocateProtocol (&gFdtClientProtocolGuid
, NULL
,
48 ASSERT_EFI_ERROR (Status
);
51 Status
= FdtClient
->FindCompatibleNodeReg (FdtClient
, "arm,cortex-a15-gic",
52 (CONST VOID
**)&Reg
, &AddressCells
, &SizeCells
,
54 if (Status
== EFI_NOT_FOUND
) {
56 Status
= FdtClient
->FindCompatibleNodeReg (FdtClient
, "arm,gic-v3",
57 (CONST VOID
**)&Reg
, &AddressCells
, &SizeCells
,
60 if (EFI_ERROR (Status
)) {
64 switch (GicRevision
) {
68 // The GIC v3 DT binding describes a series of at least 3 physical (base
69 // addresses, size) pairs: the distributor interface (GICD), at least one
70 // redistributor region (GICR) containing dedicated redistributor
71 // interfaces for all individual CPUs, and the CPU interface (GICC).
72 // Under virtualization, we assume that the first redistributor region
73 // listed covers the boot CPU. Also, our GICv3 driver only supports the
74 // system register CPU interface, so we can safely ignore the MMIO version
75 // which is listed after the sequence of redistributor interfaces.
76 // This means we are only interested in the first two memory regions
77 // supplied, and ignore everything else.
79 ASSERT (RegSize
>= 32);
81 // RegProp[0..1] == { GICD base, GICD size }
82 DistBase
= SwapBytes64 (Reg
[0]);
83 ASSERT (DistBase
< MAX_UINTN
);
85 // RegProp[2..3] == { GICR base, GICR size }
86 RedistBase
= SwapBytes64 (Reg
[2]);
87 ASSERT (RedistBase
< MAX_UINTN
);
89 PcdStatus
= PcdSet64S (PcdGicDistributorBase
, DistBase
);
90 ASSERT_RETURN_ERROR (PcdStatus
);
91 PcdStatus
= PcdSet64S (PcdGicRedistributorsBase
, RedistBase
);
92 ASSERT_RETURN_ERROR (PcdStatus
);
94 DEBUG ((EFI_D_INFO
, "Found GIC v3 (re)distributor @ 0x%Lx (0x%Lx)\n",
95 DistBase
, RedistBase
));
98 // The default implementation of ArmGicArchLib is responsible for enabling
99 // the system register interface on the GICv3 if one is found. So let's do
102 IccSre
= ArmGicV3GetControlSystemRegisterEnable ();
103 if (!(IccSre
& ICC_SRE_EL2_SRE
)) {
104 ArmGicV3SetControlSystemRegisterEnable (IccSre
| ICC_SRE_EL2_SRE
);
105 IccSre
= ArmGicV3GetControlSystemRegisterEnable ();
109 // Unlike the default implementation, there is no fall through to GICv2
110 // mode if this GICv3 cannot be driven in native mode due to the fact
111 // that the System Register interface is unavailable.
113 ASSERT (IccSre
& ICC_SRE_EL2_SRE
);
115 mGicArchRevision
= ARM_GIC_ARCH_REVISION_3
;
119 ASSERT (RegSize
== 32);
121 DistBase
= SwapBytes64 (Reg
[0]);
122 CpuBase
= SwapBytes64 (Reg
[2]);
123 ASSERT (DistBase
< MAX_UINTN
);
124 ASSERT (CpuBase
< MAX_UINTN
);
126 PcdStatus
= PcdSet64S (PcdGicDistributorBase
, DistBase
);
127 ASSERT_RETURN_ERROR (PcdStatus
);
128 PcdStatus
= PcdSet64S (PcdGicInterruptInterfaceBase
, CpuBase
);
129 ASSERT_RETURN_ERROR (PcdStatus
);
131 DEBUG ((EFI_D_INFO
, "Found GIC @ 0x%Lx/0x%Lx\n", DistBase
, CpuBase
));
133 mGicArchRevision
= ARM_GIC_ARCH_REVISION_2
;
137 DEBUG ((EFI_D_ERROR
, "%a: No GIC revision specified!\n", __FUNCTION__
));
138 return RETURN_NOT_FOUND
;
140 return RETURN_SUCCESS
;
143 ARM_GIC_ARCH_REVISION
145 ArmGicGetSupportedArchRevision (
149 return mGicArchRevision
;