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