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
;
41 // Detect the RSDP structure
43 for (XenAcpiPtr
= (UINT8
*)(UINTN
) XEN_ACPI_PHYSICAL_ADDRESS
;
44 XenAcpiPtr
< (UINT8
*)(UINTN
) XEN_BIOS_PHYSICAL_END
;
47 RsdpStructurePtr
= (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)
50 if (!AsciiStrnCmp ((CHAR8
*) &RsdpStructurePtr
->Signature
, "RSD PTR ", 8)) {
52 // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.
53 // This is only the first 20 bytes of the structure
56 (CONST UINT8
*)RsdpStructurePtr
,
57 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
63 if (RsdpStructurePtr
->Revision
>= 2) {
65 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
68 (CONST UINT8
*)RsdpStructurePtr
,
69 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
75 *RsdpPtr
= RsdpStructurePtr
;
84 Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
85 into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
86 ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.
88 @param AcpiProtocol Protocol instance pointer.
90 @return EFI_SUCCESS The table was successfully inserted.
91 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is
92 NULL, or AcpiTableBufferSize and the size
93 field embedded in the ACPI table pointed to
94 by AcpiTableBuffer are not in sync.
95 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
101 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
107 EFI_ACPI_DESCRIPTION_HEADER
*Rsdt
;
108 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
109 VOID
*CurrentTableEntry
;
110 UINTN CurrentTablePointer
;
111 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
113 UINTN NumberOfTableEntries
;
114 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt2Table
;
115 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt1Table
;
116 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*Facs2Table
;
117 EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*Facs1Table
;
118 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
126 NumberOfTableEntries
= 0;
129 // Try to find Xen ACPI tables
131 Status
= GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr
);
132 if (EFI_ERROR (Status
)) {
137 // If XSDT table is find, just install its tables.
138 // Otherwise, try to find and install the RSDT tables.
140 if (XenAcpiRsdpStructurePtr
->XsdtAddress
) {
142 // Retrieve the addresses of XSDT and
143 // calculate the number of its table entries.
145 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
146 XenAcpiRsdpStructurePtr
->XsdtAddress
;
147 NumberOfTableEntries
= (Xsdt
->Length
-
148 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
152 // Install ACPI tables found in XSDT.
154 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
156 // Get the table entry from XSDT
158 CurrentTableEntry
= (VOID
*) ((UINT8
*) Xsdt
+
159 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
160 Index
* sizeof (UINT64
));
161 CurrentTablePointer
= (UINTN
) *(UINT64
*)CurrentTableEntry
;
162 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
165 // Install the XSDT tables
167 Status
= InstallAcpiTable (
170 CurrentTable
->Length
,
174 if (EFI_ERROR (Status
)) {
179 // Get the FACS and DSDT table address from the table FADT
181 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
182 Fadt2Table
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
183 (UINTN
) CurrentTablePointer
;
184 Facs2Table
= (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)
185 (UINTN
) Fadt2Table
->FirmwareCtrl
;
186 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) Fadt2Table
->Dsdt
;
190 else if (XenAcpiRsdpStructurePtr
->RsdtAddress
) {
192 // Retrieve the addresses of RSDT and
193 // calculate the number of its table entries.
195 Rsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
196 XenAcpiRsdpStructurePtr
->RsdtAddress
;
197 NumberOfTableEntries
= (Rsdt
->Length
-
198 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
202 // Install ACPI tables found in XSDT.
204 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
206 // Get the table entry from RSDT
208 CurrentTableEntry
= (UINT32
*) ((UINT8
*) Rsdt
+
209 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
210 Index
* sizeof (UINT32
));
211 CurrentTablePointer
= *(UINT32
*)CurrentTableEntry
;
212 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
215 // Install the RSDT tables
217 Status
= InstallAcpiTable (
220 CurrentTable
->Length
,
224 if (EFI_ERROR (Status
)) {
229 // Get the FACS and DSDT table address from the table FADT
231 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
232 Fadt1Table
= (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
233 (UINTN
) CurrentTablePointer
;
234 Facs1Table
= (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)
235 (UINTN
) Fadt1Table
->FirmwareCtrl
;
236 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) Fadt1Table
->Dsdt
;
242 // Install the FACS table.
248 Status
= InstallAcpiTable (
254 if (EFI_ERROR (Status
)) {
258 else if (Fadt1Table
) {
262 Status
= InstallAcpiTable (
268 if (EFI_ERROR (Status
)) {
274 // Install DSDT table. If we reached this point without finding the DSDT,
275 // then we're out of sync with the hypervisor, and cannot continue.
277 if (DsdtTable
== NULL
) {
278 DEBUG ((DEBUG_ERROR
, "%a: no DSDT found\n", __FUNCTION__
));
283 Status
= InstallAcpiTable (
289 if (EFI_ERROR (Status
)) {