4 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2012, Bei Guan <gbtju85@gmail.com>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "AcpiPlatform.h"
12 #include <Library/BaseLib.h>
14 #define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020
15 #define XEN_BIOS_PHYSICAL_END 0x000FFFFF
17 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*XenAcpiRsdpStructurePtr
= NULL
;
20 Get the address of Xen ACPI Root System Description Pointer (RSDP)
23 @param RsdpStructurePtr Return pointer to RSDP structure
25 @return EFI_SUCCESS Find Xen RSDP structure successfully.
26 @return EFI_NOT_FOUND Don't find Xen RSDP structure.
27 @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.
33 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
**RsdpPtr
36 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*RsdpStructurePtr
;
39 EFI_XEN_INFO
*XenInfo
;
42 // Detect the RSDP structure
46 // First look for PVH one
48 XenInfo
= XenGetInfoHOB ();
49 ASSERT (XenInfo
!= NULL
);
50 if (XenInfo
->RsdpPvh
!= NULL
) {
51 DEBUG ((DEBUG_INFO
, "%a: Use ACPI RSDP table at 0x%p\n",
52 gEfiCallerBaseName
, XenInfo
->RsdpPvh
));
53 *RsdpPtr
= XenInfo
->RsdpPvh
;
58 // Otherwise, look for the HVM one
60 for (XenAcpiPtr
= (UINT8
*)(UINTN
) XEN_ACPI_PHYSICAL_ADDRESS
;
61 XenAcpiPtr
< (UINT8
*)(UINTN
) XEN_BIOS_PHYSICAL_END
;
64 RsdpStructurePtr
= (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)
67 if (!AsciiStrnCmp ((CHAR8
*) &RsdpStructurePtr
->Signature
, "RSD PTR ", 8)) {
69 // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.
70 // This is only the first 20 bytes of the structure
73 (CONST UINT8
*)RsdpStructurePtr
,
74 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
80 if (RsdpStructurePtr
->Revision
>= 2) {
82 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
85 (CONST UINT8
*)RsdpStructurePtr
,
86 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
92 *RsdpPtr
= RsdpStructurePtr
;
101 Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
102 into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
103 ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.
105 @param AcpiProtocol Protocol instance pointer.
107 @return EFI_SUCCESS The table was successfully inserted.
108 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is
109 NULL, or AcpiTableBufferSize and the size
110 field embedded in the ACPI table pointed to
111 by AcpiTableBuffer are not in sync.
112 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
118 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
124 EFI_ACPI_DESCRIPTION_HEADER
*Rsdt
;
125 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
126 VOID
*CurrentTableEntry
;
127 UINTN CurrentTablePointer
;
128 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
130 UINTN NumberOfTableEntries
;
131 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt2Table
;
132 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt1Table
;
133 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*Facs2Table
;
134 EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*Facs1Table
;
135 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
143 NumberOfTableEntries
= 0;
146 // Try to find Xen ACPI tables
148 Status
= GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr
);
149 if (EFI_ERROR (Status
)) {
154 // If XSDT table is find, just install its tables.
155 // Otherwise, try to find and install the RSDT tables.
157 if (XenAcpiRsdpStructurePtr
->XsdtAddress
) {
159 // Retrieve the addresses of XSDT and
160 // calculate the number of its table entries.
162 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
163 XenAcpiRsdpStructurePtr
->XsdtAddress
;
164 NumberOfTableEntries
= (Xsdt
->Length
-
165 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
169 // Install ACPI tables found in XSDT.
171 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
173 // Get the table entry from XSDT
175 CurrentTableEntry
= (VOID
*) ((UINT8
*) Xsdt
+
176 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
177 Index
* sizeof (UINT64
));
178 CurrentTablePointer
= (UINTN
) *(UINT64
*)CurrentTableEntry
;
179 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
182 // Install the XSDT tables
184 Status
= InstallAcpiTable (
187 CurrentTable
->Length
,
191 if (EFI_ERROR (Status
)) {
196 // Get the FACS and DSDT table address from the table FADT
198 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
199 Fadt2Table
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
200 (UINTN
) CurrentTablePointer
;
201 Facs2Table
= (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)
202 (UINTN
) Fadt2Table
->FirmwareCtrl
;
203 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) Fadt2Table
->Dsdt
;
207 else if (XenAcpiRsdpStructurePtr
->RsdtAddress
) {
209 // Retrieve the addresses of RSDT and
210 // calculate the number of its table entries.
212 Rsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
213 XenAcpiRsdpStructurePtr
->RsdtAddress
;
214 NumberOfTableEntries
= (Rsdt
->Length
-
215 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
219 // Install ACPI tables found in XSDT.
221 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
223 // Get the table entry from RSDT
225 CurrentTableEntry
= (UINT32
*) ((UINT8
*) Rsdt
+
226 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
227 Index
* sizeof (UINT32
));
228 CurrentTablePointer
= *(UINT32
*)CurrentTableEntry
;
229 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
232 // Install the RSDT tables
234 Status
= InstallAcpiTable (
237 CurrentTable
->Length
,
241 if (EFI_ERROR (Status
)) {
246 // Get the FACS and DSDT table address from the table FADT
248 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
249 Fadt1Table
= (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
250 (UINTN
) CurrentTablePointer
;
251 Facs1Table
= (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)
252 (UINTN
) Fadt1Table
->FirmwareCtrl
;
253 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) Fadt1Table
->Dsdt
;
259 // Install the FACS table.
265 Status
= InstallAcpiTable (
271 if (EFI_ERROR (Status
)) {
275 else if (Fadt1Table
) {
279 Status
= InstallAcpiTable (
285 if (EFI_ERROR (Status
)) {
291 // Install DSDT table. If we reached this point without finding the DSDT,
292 // then we're out of sync with the hypervisor, and cannot continue.
294 if (DsdtTable
== NULL
) {
295 DEBUG ((DEBUG_ERROR
, "%a: no DSDT found\n", __FUNCTION__
));
300 Status
= InstallAcpiTable (
306 if (EFI_ERROR (Status
)) {