]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/AcpiPlatformDxe/Xen.c
ShellPkg/Ls: sort output by FileName in non-SFO mode
[mirror_edk2.git] / OvmfPkg / AcpiPlatformDxe / Xen.c
CommitLineData
522203de 1/** @file\r
377e758c 2 OVMF ACPI Xen support\r
522203de 3\r
4 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
377e758c 5 Copyright (c) 2012, Bei Guan <gbtju85@gmail.com>\r
6\r
b26f0cf9 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
522203de 8\r
4040754d 9**/\r
522203de 10\r
11#include "AcpiPlatform.h"\r
4804ef49 12#include <Library/BaseLib.h>\r
522203de 13\r
377e758c 14#define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020\r
15#define XEN_BIOS_PHYSICAL_END 0x000FFFFF\r
16\r
17EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr = NULL;\r
18\r
377e758c 19/**\r
20 Get the address of Xen ACPI Root System Description Pointer (RSDP)\r
21 structure.\r
522203de 22\r
377e758c 23 @param RsdpStructurePtr Return pointer to RSDP structure\r
24\r
25 @return EFI_SUCCESS Find Xen RSDP structure successfully.\r
26 @return EFI_NOT_FOUND Don't find Xen RSDP structure.\r
27 @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.\r
28\r
29**/\r
522203de 30EFI_STATUS\r
31EFIAPI\r
377e758c 32GetXenAcpiRsdp (\r
33 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr\r
522203de 34 )\r
35{\r
377e758c 36 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;\r
37 UINT8 *XenAcpiPtr;\r
38 UINT8 Sum;\r
2a4a6242 39 EFI_XEN_INFO *XenInfo;\r
377e758c 40\r
41 //\r
42 // Detect the RSDP structure\r
43 //\r
2a4a6242
AP
44\r
45 //\r
46 // First look for PVH one\r
47 //\r
48 XenInfo = XenGetInfoHOB ();\r
49 ASSERT (XenInfo != NULL);\r
50 if (XenInfo->RsdpPvh != NULL) {\r
51 DEBUG ((DEBUG_INFO, "%a: Use ACPI RSDP table at 0x%p\n",\r
52 gEfiCallerBaseName, XenInfo->RsdpPvh));\r
53 *RsdpPtr = XenInfo->RsdpPvh;\r
54 return EFI_SUCCESS;\r
55 }\r
56\r
57 //\r
58 // Otherwise, look for the HVM one\r
59 //\r
377e758c 60 for (XenAcpiPtr = (UINT8*)(UINTN) XEN_ACPI_PHYSICAL_ADDRESS;\r
61 XenAcpiPtr < (UINT8*)(UINTN) XEN_BIOS_PHYSICAL_END;\r
62 XenAcpiPtr += 0x10) {\r
63\r
64 RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)\r
65 (UINTN) XenAcpiPtr;\r
66\r
67 if (!AsciiStrnCmp ((CHAR8 *) &RsdpStructurePtr->Signature, "RSD PTR ", 8)) {\r
68 //\r
69 // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.\r
70 // This is only the first 20 bytes of the structure\r
71 //\r
4804ef49 72 Sum = CalculateSum8 (\r
73 (CONST UINT8 *)RsdpStructurePtr,\r
377e758c 74 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)\r
75 );\r
76 if (Sum != 0) {\r
77 return EFI_ABORTED;\r
78 }\r
79\r
80 if (RsdpStructurePtr->Revision >= 2) {\r
81 //\r
82 // RSDP ACPI 2.0/3.0 checksum, this is the entire table\r
83 //\r
4804ef49 84 Sum = CalculateSum8 (\r
85 (CONST UINT8 *)RsdpStructurePtr,\r
377e758c 86 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)\r
87 );\r
88 if (Sum != 0) {\r
89 return EFI_ABORTED;\r
90 }\r
91 }\r
92 *RsdpPtr = RsdpStructurePtr;\r
93 return EFI_SUCCESS;\r
94 }\r
95 }\r
96\r
97 return EFI_NOT_FOUND;\r
98}\r
99\r
100/**\r
101 Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables\r
102 into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed\r
103 ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.\r
104\r
105 @param AcpiProtocol Protocol instance pointer.\r
106\r
107 @return EFI_SUCCESS The table was successfully inserted.\r
108 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is\r
109 NULL, or AcpiTableBufferSize and the size\r
110 field embedded in the ACPI table pointed to\r
111 by AcpiTableBuffer are not in sync.\r
112 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.\r
113\r
114**/\r
115EFI_STATUS\r
116EFIAPI\r
117InstallXenTables (\r
118 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol\r
119 )\r
120{\r
121 EFI_STATUS Status;\r
122 UINTN TableHandle;\r
123\r
124 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
125 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
126 VOID *CurrentTableEntry;\r
127 UINTN CurrentTablePointer;\r
128 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;\r
129 UINTN Index;\r
130 UINTN NumberOfTableEntries;\r
131 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;\r
132 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt1Table;\r
133 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs2Table;\r
134 EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs1Table;\r
135 EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;\r
136\r
137 Fadt2Table = NULL;\r
138 Fadt1Table = NULL;\r
139 Facs2Table = NULL;\r
140 Facs1Table = NULL;\r
141 DsdtTable = NULL;\r
142 TableHandle = 0;\r
143 NumberOfTableEntries = 0;\r
144\r
145 //\r
146 // Try to find Xen ACPI tables\r
147 //\r
148 Status = GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr);\r
149 if (EFI_ERROR (Status)) {\r
150 return Status;\r
151 }\r
152\r
153 //\r
4040754d 154 // If XSDT table is find, just install its tables.\r
377e758c 155 // Otherwise, try to find and install the RSDT tables.\r
156 //\r
157 if (XenAcpiRsdpStructurePtr->XsdtAddress) {\r
158 //\r
4040754d 159 // Retrieve the addresses of XSDT and\r
377e758c 160 // calculate the number of its table entries.\r
161 //\r
162 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
163 XenAcpiRsdpStructurePtr->XsdtAddress;\r
164 NumberOfTableEntries = (Xsdt->Length -\r
165 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
166 sizeof (UINT64);\r
167\r
168 //\r
169 // Install ACPI tables found in XSDT.\r
170 //\r
171 for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
172 //\r
173 // Get the table entry from XSDT\r
174 //\r
175 CurrentTableEntry = (VOID *) ((UINT8 *) Xsdt +\r
176 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
177 Index * sizeof (UINT64));\r
26af9aca 178 CurrentTablePointer = (UINTN) *(UINT64 *)CurrentTableEntry;\r
377e758c 179 CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
180\r
181 //\r
182 // Install the XSDT tables\r
183 //\r
184 Status = InstallAcpiTable (\r
185 AcpiProtocol,\r
186 CurrentTable,\r
187 CurrentTable->Length,\r
188 &TableHandle\r
189 );\r
190\r
191 if (EFI_ERROR (Status)) {\r
192 return Status;\r
193 }\r
194\r
195 //\r
196 // Get the FACS and DSDT table address from the table FADT\r
197 //\r
198 if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
199 Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
200 (UINTN) CurrentTablePointer;\r
201 Facs2Table = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)\r
202 (UINTN) Fadt2Table->FirmwareCtrl;\r
203 DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt2Table->Dsdt;\r
204 }\r
205 }\r
206 }\r
207 else if (XenAcpiRsdpStructurePtr->RsdtAddress) {\r
208 //\r
209 // Retrieve the addresses of RSDT and\r
210 // calculate the number of its table entries.\r
211 //\r
212 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
213 XenAcpiRsdpStructurePtr->RsdtAddress;\r
214 NumberOfTableEntries = (Rsdt->Length -\r
4040754d 215 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
377e758c 216 sizeof (UINT32);\r
217\r
218 //\r
219 // Install ACPI tables found in XSDT.\r
220 //\r
221 for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
222 //\r
223 // Get the table entry from RSDT\r
224 //\r
225 CurrentTableEntry = (UINT32 *) ((UINT8 *) Rsdt +\r
226 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
227 Index * sizeof (UINT32));\r
228 CurrentTablePointer = *(UINT32 *)CurrentTableEntry;\r
229 CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
230\r
231 //\r
232 // Install the RSDT tables\r
233 //\r
234 Status = InstallAcpiTable (\r
235 AcpiProtocol,\r
236 CurrentTable,\r
237 CurrentTable->Length,\r
238 &TableHandle\r
239 );\r
240\r
241 if (EFI_ERROR (Status)) {\r
242 return Status;\r
243 }\r
244\r
245 //\r
246 // Get the FACS and DSDT table address from the table FADT\r
247 //\r
248 if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
249 Fadt1Table = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
250 (UINTN) CurrentTablePointer;\r
251 Facs1Table = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)\r
252 (UINTN) Fadt1Table->FirmwareCtrl;\r
253 DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt1Table->Dsdt;\r
254 }\r
255 }\r
256 }\r
257\r
258 //\r
259 // Install the FACS table.\r
260 //\r
261 if (Fadt2Table) {\r
262 //\r
263 // FACS 2.0\r
264 //\r
265 Status = InstallAcpiTable (\r
266 AcpiProtocol,\r
267 Facs2Table,\r
268 Facs2Table->Length,\r
269 &TableHandle\r
270 );\r
271 if (EFI_ERROR (Status)) {\r
272 return Status;\r
273 }\r
274 }\r
275 else if (Fadt1Table) {\r
276 //\r
277 // FACS 1.0\r
278 //\r
279 Status = InstallAcpiTable (\r
280 AcpiProtocol,\r
281 Facs1Table,\r
282 Facs1Table->Length,\r
283 &TableHandle\r
284 );\r
285 if (EFI_ERROR (Status)) {\r
286 return Status;\r
287 }\r
288 }\r
289\r
290 //\r
e3099174
LE
291 // Install DSDT table. If we reached this point without finding the DSDT,\r
292 // then we're out of sync with the hypervisor, and cannot continue.\r
377e758c 293 //\r
e3099174
LE
294 if (DsdtTable == NULL) {\r
295 DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));\r
296 ASSERT (FALSE);\r
297 CpuDeadLoop ();\r
298 }\r
299\r
377e758c 300 Status = InstallAcpiTable (\r
301 AcpiProtocol,\r
302 DsdtTable,\r
303 DsdtTable->Length,\r
304 &TableHandle\r
305 );\r
306 if (EFI_ERROR (Status)) {\r
307 return Status;\r
308 }\r
309\r
310 return EFI_SUCCESS;\r
522203de 311}\r
312\r