]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c
SecurityPkg/TrEEDxe: remove TrEE.
[mirror_edk2.git] / ArmVirtPkg / Library / ArmVirtGicArchLib / ArmVirtGicArchLib.c
CommitLineData
15c9b25e
AB
1/** @file\r
2 ArmGicArchLib library class implementation for DT based virt platforms\r
3\r
22486318 4 Copyright (c) 2015 - 2016, Linaro Ltd. All rights reserved.<BR>\r
15c9b25e
AB
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <Base.h>\r
22486318 17#include <Uefi.h>\r
15c9b25e
AB
18\r
19#include <Library/ArmGicLib.h>\r
20#include <Library/ArmGicArchLib.h>\r
22486318 21#include <Library/BaseLib.h>\r
15c9b25e 22#include <Library/DebugLib.h>\r
22486318
AB
23#include <Library/PcdLib.h>\r
24#include <Library/UefiBootServicesTableLib.h>\r
25\r
26#include <Protocol/FdtClient.h>\r
15c9b25e
AB
27\r
28STATIC ARM_GIC_ARCH_REVISION mGicArchRevision;\r
29\r
30RETURN_STATUS\r
31EFIAPI\r
32ArmVirtGicArchLibConstructor (\r
33 VOID\r
34 )\r
35{\r
22486318
AB
36 UINT32 IccSre;\r
37 FDT_CLIENT_PROTOCOL *FdtClient;\r
38 CONST UINT64 *Reg;\r
cfc8d51c
AB
39 UINT32 RegSize;\r
40 UINTN AddressCells, SizeCells;\r
22486318
AB
41 UINTN GicRevision;\r
42 EFI_STATUS Status;\r
43 UINT64 DistBase, CpuBase, RedistBase;\r
65ebe6e6 44 RETURN_STATUS PcdStatus;\r
15c9b25e 45\r
22486318
AB
46 Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
47 (VOID **)&FdtClient);\r
48 ASSERT_EFI_ERROR (Status);\r
49\r
50 GicRevision = 2;\r
51 Status = FdtClient->FindCompatibleNodeReg (FdtClient, "arm,cortex-a15-gic",\r
cfc8d51c
AB
52 (CONST VOID **)&Reg, &AddressCells, &SizeCells,\r
53 &RegSize);\r
22486318
AB
54 if (Status == EFI_NOT_FOUND) {\r
55 GicRevision = 3;\r
56 Status = FdtClient->FindCompatibleNodeReg (FdtClient, "arm,gic-v3",\r
cfc8d51c
AB
57 (CONST VOID **)&Reg, &AddressCells, &SizeCells,\r
58 &RegSize);\r
22486318
AB
59 }\r
60 if (EFI_ERROR (Status)) {\r
61 return Status;\r
62 }\r
63\r
64 switch (GicRevision) {\r
15c9b25e
AB
65\r
66 case 3:\r
22486318
AB
67 //\r
68 // The GIC v3 DT binding describes a series of at least 3 physical (base\r
69 // addresses, size) pairs: the distributor interface (GICD), at least one\r
70 // redistributor region (GICR) containing dedicated redistributor\r
71 // interfaces for all individual CPUs, and the CPU interface (GICC).\r
72 // Under virtualization, we assume that the first redistributor region\r
73 // listed covers the boot CPU. Also, our GICv3 driver only supports the\r
74 // system register CPU interface, so we can safely ignore the MMIO version\r
75 // which is listed after the sequence of redistributor interfaces.\r
76 // This means we are only interested in the first two memory regions\r
77 // supplied, and ignore everything else.\r
78 //\r
79 ASSERT (RegSize >= 32);\r
80\r
81 // RegProp[0..1] == { GICD base, GICD size }\r
82 DistBase = SwapBytes64 (Reg[0]);\r
041e842a 83 ASSERT (DistBase < MAX_UINTN);\r
22486318
AB
84\r
85 // RegProp[2..3] == { GICR base, GICR size }\r
86 RedistBase = SwapBytes64 (Reg[2]);\r
041e842a 87 ASSERT (RedistBase < MAX_UINTN);\r
22486318 88\r
65ebe6e6
LE
89 PcdStatus = PcdSet64S (PcdGicDistributorBase, DistBase);\r
90 ASSERT_RETURN_ERROR (PcdStatus);\r
91 PcdStatus = PcdSet64S (PcdGicRedistributorsBase, RedistBase);\r
92 ASSERT_RETURN_ERROR (PcdStatus);\r
22486318
AB
93\r
94 DEBUG ((EFI_D_INFO, "Found GIC v3 (re)distributor @ 0x%Lx (0x%Lx)\n",\r
95 DistBase, RedistBase));\r
96\r
15c9b25e
AB
97 //\r
98 // The default implementation of ArmGicArchLib is responsible for enabling\r
99 // the system register interface on the GICv3 if one is found. So let's do\r
100 // the same here.\r
101 //\r
102 IccSre = ArmGicV3GetControlSystemRegisterEnable ();\r
103 if (!(IccSre & ICC_SRE_EL2_SRE)) {\r
104 ArmGicV3SetControlSystemRegisterEnable (IccSre | ICC_SRE_EL2_SRE);\r
105 IccSre = ArmGicV3GetControlSystemRegisterEnable ();\r
106 }\r
107\r
108 //\r
109 // Unlike the default implementation, there is no fall through to GICv2\r
110 // mode if this GICv3 cannot be driven in native mode due to the fact\r
111 // that the System Register interface is unavailable.\r
112 //\r
113 ASSERT (IccSre & ICC_SRE_EL2_SRE);\r
114\r
115 mGicArchRevision = ARM_GIC_ARCH_REVISION_3;\r
116 break;\r
117\r
118 case 2:\r
22486318
AB
119 ASSERT (RegSize == 32);\r
120\r
121 DistBase = SwapBytes64 (Reg[0]);\r
122 CpuBase = SwapBytes64 (Reg[2]);\r
041e842a
DC
123 ASSERT (DistBase < MAX_UINTN);\r
124 ASSERT (CpuBase < MAX_UINTN);\r
22486318 125\r
65ebe6e6
LE
126 PcdStatus = PcdSet64S (PcdGicDistributorBase, DistBase);\r
127 ASSERT_RETURN_ERROR (PcdStatus);\r
128 PcdStatus = PcdSet64S (PcdGicInterruptInterfaceBase, CpuBase);\r
129 ASSERT_RETURN_ERROR (PcdStatus);\r
22486318
AB
130\r
131 DEBUG ((EFI_D_INFO, "Found GIC @ 0x%Lx/0x%Lx\n", DistBase, CpuBase));\r
132\r
15c9b25e
AB
133 mGicArchRevision = ARM_GIC_ARCH_REVISION_2;\r
134 break;\r
135\r
136 default:\r
137 DEBUG ((EFI_D_ERROR, "%a: No GIC revision specified!\n", __FUNCTION__));\r
138 return RETURN_NOT_FOUND;\r
139 }\r
140 return RETURN_SUCCESS;\r
141}\r
142\r
143ARM_GIC_ARCH_REVISION\r
144EFIAPI\r
145ArmGicGetSupportedArchRevision (\r
146 VOID\r
147 )\r
148{\r
149 return mGicArchRevision;\r
150}\r