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