]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c
ArmPkg ArmPlatformPkg ArmVirtPkg: ARM GICv2/v3 Base Address width fix-up
[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
39 UINT32 RegElemSize, RegSize;\r
40 UINTN GicRevision;\r
41 EFI_STATUS Status;\r
42 UINT64 DistBase, CpuBase, RedistBase;\r
15c9b25e 43\r
22486318
AB
44 Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
45 (VOID **)&FdtClient);\r
46 ASSERT_EFI_ERROR (Status);\r
47\r
48 GicRevision = 2;\r
49 Status = FdtClient->FindCompatibleNodeReg (FdtClient, "arm,cortex-a15-gic",\r
50 (CONST VOID **)&Reg, &RegElemSize, &RegSize);\r
51 if (Status == EFI_NOT_FOUND) {\r
52 GicRevision = 3;\r
53 Status = FdtClient->FindCompatibleNodeReg (FdtClient, "arm,gic-v3",\r
54 (CONST VOID **)&Reg, &RegElemSize, &RegSize);\r
55 }\r
56 if (EFI_ERROR (Status)) {\r
57 return Status;\r
58 }\r
59\r
60 switch (GicRevision) {\r
15c9b25e
AB
61\r
62 case 3:\r
22486318
AB
63 //\r
64 // The GIC v3 DT binding describes a series of at least 3 physical (base\r
65 // addresses, size) pairs: the distributor interface (GICD), at least one\r
66 // redistributor region (GICR) containing dedicated redistributor\r
67 // interfaces for all individual CPUs, and the CPU interface (GICC).\r
68 // Under virtualization, we assume that the first redistributor region\r
69 // listed covers the boot CPU. Also, our GICv3 driver only supports the\r
70 // system register CPU interface, so we can safely ignore the MMIO version\r
71 // which is listed after the sequence of redistributor interfaces.\r
72 // This means we are only interested in the first two memory regions\r
73 // supplied, and ignore everything else.\r
74 //\r
75 ASSERT (RegSize >= 32);\r
76\r
77 // RegProp[0..1] == { GICD base, GICD size }\r
78 DistBase = SwapBytes64 (Reg[0]);\r
79 ASSERT (DistBase < MAX_UINT32);\r
80\r
81 // RegProp[2..3] == { GICR base, GICR size }\r
82 RedistBase = SwapBytes64 (Reg[2]);\r
83 ASSERT (RedistBase < MAX_UINT32);\r
84\r
8a1f2378
DC
85 PcdSet64 (PcdGicDistributorBase, DistBase);\r
86 PcdSet64 (PcdGicRedistributorsBase, RedistBase);\r
22486318
AB
87\r
88 DEBUG ((EFI_D_INFO, "Found GIC v3 (re)distributor @ 0x%Lx (0x%Lx)\n",\r
89 DistBase, RedistBase));\r
90\r
15c9b25e
AB
91 //\r
92 // The default implementation of ArmGicArchLib is responsible for enabling\r
93 // the system register interface on the GICv3 if one is found. So let's do\r
94 // the same here.\r
95 //\r
96 IccSre = ArmGicV3GetControlSystemRegisterEnable ();\r
97 if (!(IccSre & ICC_SRE_EL2_SRE)) {\r
98 ArmGicV3SetControlSystemRegisterEnable (IccSre | ICC_SRE_EL2_SRE);\r
99 IccSre = ArmGicV3GetControlSystemRegisterEnable ();\r
100 }\r
101\r
102 //\r
103 // Unlike the default implementation, there is no fall through to GICv2\r
104 // mode if this GICv3 cannot be driven in native mode due to the fact\r
105 // that the System Register interface is unavailable.\r
106 //\r
107 ASSERT (IccSre & ICC_SRE_EL2_SRE);\r
108\r
109 mGicArchRevision = ARM_GIC_ARCH_REVISION_3;\r
110 break;\r
111\r
112 case 2:\r
22486318
AB
113 ASSERT (RegSize == 32);\r
114\r
115 DistBase = SwapBytes64 (Reg[0]);\r
116 CpuBase = SwapBytes64 (Reg[2]);\r
117 ASSERT (DistBase < MAX_UINT32);\r
118 ASSERT (CpuBase < MAX_UINT32);\r
119\r
8a1f2378
DC
120 PcdSet64 (PcdGicDistributorBase, DistBase);\r
121 PcdSet64 (PcdGicInterruptInterfaceBase, CpuBase);\r
22486318
AB
122\r
123 DEBUG ((EFI_D_INFO, "Found GIC @ 0x%Lx/0x%Lx\n", DistBase, CpuBase));\r
124\r
15c9b25e
AB
125 mGicArchRevision = ARM_GIC_ARCH_REVISION_2;\r
126 break;\r
127\r
128 default:\r
129 DEBUG ((EFI_D_ERROR, "%a: No GIC revision specified!\n", __FUNCTION__));\r
130 return RETURN_NOT_FOUND;\r
131 }\r
132 return RETURN_SUCCESS;\r
133}\r
134\r
135ARM_GIC_ARCH_REVISION\r
136EFIAPI\r
137ArmGicGetSupportedArchRevision (\r
138 VOID\r
139 )\r
140{\r
141 return mGicArchRevision;\r
142}\r