4 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2012, Bei Guan <gbtju85@gmail.com>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "AcpiPlatform.h"
18 #include <Library/HobLib.h>
19 #include <Guid/XenInfo.h>
20 #include <Library/BaseLib.h>
22 #define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020
23 #define XEN_BIOS_PHYSICAL_END 0x000FFFFF
25 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*XenAcpiRsdpStructurePtr
= NULL
;
28 This function detects if OVMF is running on Xen.
36 EFI_HOB_GUID_TYPE
*GuidHob
;
39 // See if a XenInfo HOB is available
41 GuidHob
= GetFirstGuidHob (&gEfiXenInfoGuid
);
42 if (GuidHob
== NULL
) {
50 Get the address of Xen ACPI Root System Description Pointer (RSDP)
53 @param RsdpStructurePtr Return pointer to RSDP structure
55 @return EFI_SUCCESS Find Xen RSDP structure successfully.
56 @return EFI_NOT_FOUND Don't find Xen RSDP structure.
57 @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.
63 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
**RsdpPtr
66 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*RsdpStructurePtr
;
71 // Detect the RSDP structure
73 for (XenAcpiPtr
= (UINT8
*)(UINTN
) XEN_ACPI_PHYSICAL_ADDRESS
;
74 XenAcpiPtr
< (UINT8
*)(UINTN
) XEN_BIOS_PHYSICAL_END
;
77 RsdpStructurePtr
= (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)
80 if (!AsciiStrnCmp ((CHAR8
*) &RsdpStructurePtr
->Signature
, "RSD PTR ", 8)) {
82 // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.
83 // This is only the first 20 bytes of the structure
86 (CONST UINT8
*)RsdpStructurePtr
,
87 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
93 if (RsdpStructurePtr
->Revision
>= 2) {
95 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
98 (CONST UINT8
*)RsdpStructurePtr
,
99 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
105 *RsdpPtr
= RsdpStructurePtr
;
110 return EFI_NOT_FOUND
;
114 Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
115 into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
116 ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.
118 @param AcpiProtocol Protocol instance pointer.
120 @return EFI_SUCCESS The table was successfully inserted.
121 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is
122 NULL, or AcpiTableBufferSize and the size
123 field embedded in the ACPI table pointed to
124 by AcpiTableBuffer are not in sync.
125 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
131 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
137 EFI_ACPI_DESCRIPTION_HEADER
*Rsdt
;
138 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
139 VOID
*CurrentTableEntry
;
140 UINTN CurrentTablePointer
;
141 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
143 UINTN NumberOfTableEntries
;
144 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt2Table
;
145 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt1Table
;
146 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*Facs2Table
;
147 EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*Facs1Table
;
148 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
156 NumberOfTableEntries
= 0;
159 // Try to find Xen ACPI tables
161 Status
= GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr
);
162 if (EFI_ERROR (Status
)) {
167 // If XSDT table is find, just install its tables.
168 // Otherwise, try to find and install the RSDT tables.
170 if (XenAcpiRsdpStructurePtr
->XsdtAddress
) {
172 // Retrieve the addresses of XSDT and
173 // calculate the number of its table entries.
175 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
176 XenAcpiRsdpStructurePtr
->XsdtAddress
;
177 NumberOfTableEntries
= (Xsdt
->Length
-
178 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
182 // Install ACPI tables found in XSDT.
184 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
186 // Get the table entry from XSDT
188 CurrentTableEntry
= (VOID
*) ((UINT8
*) Xsdt
+
189 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
190 Index
* sizeof (UINT64
));
191 CurrentTablePointer
= (UINTN
) *(UINT64
*)CurrentTableEntry
;
192 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
195 // Install the XSDT tables
197 Status
= InstallAcpiTable (
200 CurrentTable
->Length
,
204 if (EFI_ERROR (Status
)) {
209 // Get the FACS and DSDT table address from the table FADT
211 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
212 Fadt2Table
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
213 (UINTN
) CurrentTablePointer
;
214 Facs2Table
= (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)
215 (UINTN
) Fadt2Table
->FirmwareCtrl
;
216 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) Fadt2Table
->Dsdt
;
220 else if (XenAcpiRsdpStructurePtr
->RsdtAddress
) {
222 // Retrieve the addresses of RSDT and
223 // calculate the number of its table entries.
225 Rsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
226 XenAcpiRsdpStructurePtr
->RsdtAddress
;
227 NumberOfTableEntries
= (Rsdt
->Length
-
228 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
232 // Install ACPI tables found in XSDT.
234 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
236 // Get the table entry from RSDT
238 CurrentTableEntry
= (UINT32
*) ((UINT8
*) Rsdt
+
239 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
240 Index
* sizeof (UINT32
));
241 CurrentTablePointer
= *(UINT32
*)CurrentTableEntry
;
242 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
245 // Install the RSDT tables
247 Status
= InstallAcpiTable (
250 CurrentTable
->Length
,
254 if (EFI_ERROR (Status
)) {
259 // Get the FACS and DSDT table address from the table FADT
261 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
262 Fadt1Table
= (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
263 (UINTN
) CurrentTablePointer
;
264 Facs1Table
= (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)
265 (UINTN
) Fadt1Table
->FirmwareCtrl
;
266 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) Fadt1Table
->Dsdt
;
272 // Install the FACS table.
278 Status
= InstallAcpiTable (
284 if (EFI_ERROR (Status
)) {
288 else if (Fadt1Table
) {
292 Status
= InstallAcpiTable (
298 if (EFI_ERROR (Status
)) {
304 // Install DSDT table.
306 Status
= InstallAcpiTable (
312 if (EFI_ERROR (Status
)) {