]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmbase" with PatchInstructionX86()
[mirror_edk2.git] / ArmVirtPkg / XenAcpiPlatformDxe / XenAcpiPlatformDxe.c
CommitLineData
402dde68
SZ
1/** @file\r
2 Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol\r
3\r
4 Copyright (C) 2016, Linaro Ltd. All rights reserved.\r
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 <Library/BaseLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/UefiBootServicesTableLib.h>\r
19#include <Library/UefiDriverEntryPoint.h>\r
20\r
21#include <Protocol/AcpiTable.h>\r
22#include <Protocol/FdtClient.h>\r
23\r
24#include <IndustryStandard/Acpi.h>\r
25\r
26/**\r
27 Get the address of Xen ACPI Root System Description Pointer (RSDP)\r
28 structure.\r
29\r
30 @param RsdpStructurePtr Return pointer to RSDP structure\r
31\r
32 @return EFI_SUCCESS Find Xen RSDP structure successfully.\r
33 @return EFI_NOT_FOUND Don't find Xen RSDP structure.\r
34 @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.\r
35\r
36**/\r
37STATIC\r
38EFI_STATUS\r
39EFIAPI\r
40GetXenArmAcpiRsdp (\r
41 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr\r
42 )\r
43{\r
44 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;\r
45 EFI_STATUS Status;\r
46 FDT_CLIENT_PROTOCOL *FdtClient;\r
47 CONST UINT64 *Reg;\r
cfc8d51c
AB
48 UINT32 RegSize;\r
49 UINTN AddressCells, SizeCells;\r
402dde68
SZ
50 UINT64 RegBase;\r
51 UINT8 Sum;\r
52\r
53 RsdpStructurePtr = NULL;\r
54 FdtClient = NULL;\r
55 //\r
56 // Get the RSDP structure address from DeviceTree\r
57 //\r
58 Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
59 (VOID **)&FdtClient);\r
60 ASSERT_EFI_ERROR (Status);\r
61\r
62 Status = FdtClient->FindCompatibleNodeReg (FdtClient, "xen,guest-acpi",\r
cfc8d51c
AB
63 (CONST VOID **)&Reg, &AddressCells, &SizeCells,\r
64 &RegSize);\r
402dde68
SZ
65 if (EFI_ERROR (Status)) {\r
66 DEBUG ((EFI_D_WARN, "%a: No 'xen,guest-acpi' compatible DT node found\n",\r
67 __FUNCTION__));\r
68 return EFI_NOT_FOUND;\r
69 }\r
70\r
cfc8d51c
AB
71 ASSERT (AddressCells == 2);\r
72 ASSERT (SizeCells == 2);\r
402dde68
SZ
73 ASSERT (RegSize == 2 * sizeof (UINT64));\r
74\r
75 RegBase = SwapBytes64(Reg[0]);\r
6244c892
LE
76 RsdpStructurePtr =\r
77 (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)RegBase;\r
402dde68
SZ
78\r
79 if (RsdpStructurePtr && RsdpStructurePtr->Revision >= 2) {\r
80 Sum = CalculateSum8 ((CONST UINT8 *)RsdpStructurePtr,\r
81 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER));\r
82 if (Sum != 0) {\r
83 return EFI_ABORTED;\r
84 }\r
85 }\r
86\r
87 *RsdpPtr = RsdpStructurePtr;\r
88 return EFI_SUCCESS;\r
89}\r
90\r
91/**\r
92 Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables\r
93 into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed\r
94 ACPI tables are: FACP, APIC, GTDT, DSDT.\r
95\r
96 @param AcpiProtocol Protocol instance pointer.\r
97\r
98 @return EFI_SUCCESS The table was successfully inserted.\r
99 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is\r
100 NULL, or AcpiTableBufferSize and the size\r
101 field embedded in the ACPI table pointed to\r
102 by AcpiTableBuffer are not in sync.\r
103 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.\r
104\r
105**/\r
106STATIC\r
107EFI_STATUS\r
108EFIAPI\r
109InstallXenArmTables (\r
110 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol\r
111 )\r
112{\r
113 EFI_STATUS Status;\r
114 UINTN TableHandle;\r
115 VOID *CurrentTableEntry;\r
116 UINTN CurrentTablePointer;\r
117 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;\r
118 UINTN Index;\r
119 UINTN NumberOfTableEntries;\r
120 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr;\r
121 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
122 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtTable;\r
123 EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;\r
124\r
125 XenAcpiRsdpStructurePtr = NULL;\r
126 FadtTable = NULL;\r
127 DsdtTable = NULL;\r
128 TableHandle = 0;\r
129 NumberOfTableEntries = 0;\r
130\r
131 //\r
132 // Try to find Xen ARM ACPI tables\r
133 //\r
134 Status = GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr);\r
135 if (EFI_ERROR (Status)) {\r
136 DEBUG ((EFI_D_INFO, "%a: No RSDP table found\n", __FUNCTION__));\r
137 return Status;\r
138 }\r
139\r
140 //\r
141 // If XSDT table is find, just install its tables.\r
142 //\r
143 if (XenAcpiRsdpStructurePtr->XsdtAddress) {\r
144 //\r
145 // Retrieve the addresses of XSDT and\r
146 // calculate the number of its table entries.\r
147 //\r
148 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
149 XenAcpiRsdpStructurePtr->XsdtAddress;\r
150 NumberOfTableEntries = (Xsdt->Length -\r
151 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
152 sizeof (UINT64);\r
153 //\r
154 // Install ACPI tables found in XSDT.\r
155 //\r
156 for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
157 //\r
158 // Get the table entry from XSDT\r
159 //\r
160 CurrentTableEntry = (VOID *) ((UINT8 *) Xsdt +\r
161 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
162 Index * sizeof (UINT64));\r
163 CurrentTablePointer = (UINTN) *(UINT64 *)CurrentTableEntry;\r
164 CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
165\r
166 //\r
167 // Install the XSDT tables\r
168 //\r
169 Status = AcpiProtocol->InstallAcpiTable (\r
170 AcpiProtocol,\r
171 CurrentTable,\r
172 CurrentTable->Length,\r
173 &TableHandle\r
174 );\r
175\r
176 if (EFI_ERROR (Status)) {\r
177 return Status;\r
178 }\r
179\r
180 //\r
181 // Get the FACS and DSDT table address from the table FADT\r
182 //\r
183 if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
184 FadtTable = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
185 (UINTN) CurrentTablePointer;\r
186 DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) FadtTable->Dsdt;\r
187 }\r
188 }\r
189 }\r
190\r
191 //\r
192 // Install DSDT table.\r
193 //\r
194 Status = AcpiProtocol->InstallAcpiTable (\r
195 AcpiProtocol,\r
196 DsdtTable,\r
197 DsdtTable->Length,\r
198 &TableHandle\r
199 );\r
200 if (EFI_ERROR (Status)) {\r
201 return Status;\r
202 }\r
203\r
204 return EFI_SUCCESS;\r
205}\r
206\r
207STATIC\r
208EFI_ACPI_TABLE_PROTOCOL *\r
209FindAcpiTableProtocol (\r
210 VOID\r
211 )\r
212{\r
213 EFI_STATUS Status;\r
214 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
215\r
216 AcpiTable = NULL;\r
217 Status = gBS->LocateProtocol (\r
218 &gEfiAcpiTableProtocolGuid,\r
219 NULL,\r
220 (VOID**)&AcpiTable\r
221 );\r
222 ASSERT_EFI_ERROR (Status);\r
223 return AcpiTable;\r
224}\r
225\r
226/**\r
227 Entrypoint of Xen ARM Acpi Platform driver.\r
228\r
229 @param ImageHandle\r
230 @param SystemTable\r
231\r
232 @return EFI_SUCCESS\r
233 @return EFI_LOAD_ERROR\r
234 @return EFI_OUT_OF_RESOURCES\r
235\r
236**/\r
237\r
238EFI_STATUS\r
239EFIAPI\r
240XenAcpiPlatformEntryPoint (\r
241 IN EFI_HANDLE ImageHandle,\r
242 IN EFI_SYSTEM_TABLE *SystemTable\r
243 )\r
244{\r
245 EFI_STATUS Status;\r
246\r
247 Status = InstallXenArmTables (FindAcpiTableProtocol ());\r
248 return Status;\r
249}\r