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