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>
21 #define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020
22 #define XEN_BIOS_PHYSICAL_END 0x000FFFFF
24 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*XenAcpiRsdpStructurePtr
= NULL
;
27 Calculates the checksum of the ACPI tables.
29 @param Buffer Address of the ACPI table.
30 @param Size Size of the ACPI table need to check.
34 CalculateTableChecksum (
49 // Add all content of buffer
51 while ((Size
--) != 0) {
52 Sum
= (UINT8
) (Sum
+ (*Ptr
++));
59 This function detects if OVMF is running on Xen.
67 EFI_HOB_GUID_TYPE
*GuidHob
;
70 // See if a XenInfo HOB is available
72 GuidHob
= GetFirstGuidHob (&gEfiXenInfoGuid
);
73 if (GuidHob
== NULL
) {
81 Get the address of Xen ACPI Root System Description Pointer (RSDP)
84 @param RsdpStructurePtr Return pointer to RSDP structure
86 @return EFI_SUCCESS Find Xen RSDP structure successfully.
87 @return EFI_NOT_FOUND Don't find Xen RSDP structure.
88 @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.
94 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
**RsdpPtr
97 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*RsdpStructurePtr
;
102 // Detect the RSDP structure
104 for (XenAcpiPtr
= (UINT8
*)(UINTN
) XEN_ACPI_PHYSICAL_ADDRESS
;
105 XenAcpiPtr
< (UINT8
*)(UINTN
) XEN_BIOS_PHYSICAL_END
;
106 XenAcpiPtr
+= 0x10) {
108 RsdpStructurePtr
= (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)
111 if (!AsciiStrnCmp ((CHAR8
*) &RsdpStructurePtr
->Signature
, "RSD PTR ", 8)) {
113 // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.
114 // This is only the first 20 bytes of the structure
116 Sum
= CalculateTableChecksum (
118 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
124 if (RsdpStructurePtr
->Revision
>= 2) {
126 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
128 Sum
= CalculateTableChecksum (
130 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
136 *RsdpPtr
= RsdpStructurePtr
;
141 return EFI_NOT_FOUND
;
145 Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
146 into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
147 ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.
149 @param AcpiProtocol Protocol instance pointer.
151 @return EFI_SUCCESS The table was successfully inserted.
152 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is
153 NULL, or AcpiTableBufferSize and the size
154 field embedded in the ACPI table pointed to
155 by AcpiTableBuffer are not in sync.
156 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
162 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
168 EFI_ACPI_DESCRIPTION_HEADER
*Rsdt
;
169 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
170 VOID
*CurrentTableEntry
;
171 UINTN CurrentTablePointer
;
172 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
174 UINTN NumberOfTableEntries
;
175 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt2Table
;
176 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt1Table
;
177 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*Facs2Table
;
178 EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*Facs1Table
;
179 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
187 NumberOfTableEntries
= 0;
190 // Try to find Xen ACPI tables
192 Status
= GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr
);
193 if (EFI_ERROR (Status
)) {
198 // If XSDT table is find, just install its tables.
199 // Otherwise, try to find and install the RSDT tables.
201 if (XenAcpiRsdpStructurePtr
->XsdtAddress
) {
203 // Retrieve the addresses of XSDT and
204 // calculate the number of its table entries.
206 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
207 XenAcpiRsdpStructurePtr
->XsdtAddress
;
208 NumberOfTableEntries
= (Xsdt
->Length
-
209 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
213 // Install ACPI tables found in XSDT.
215 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
217 // Get the table entry from XSDT
219 CurrentTableEntry
= (VOID
*) ((UINT8
*) Xsdt
+
220 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
221 Index
* sizeof (UINT64
));
222 CurrentTablePointer
= *(UINT64
*)CurrentTableEntry
;
223 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
226 // Install the XSDT tables
228 Status
= InstallAcpiTable (
231 CurrentTable
->Length
,
235 if (EFI_ERROR (Status
)) {
240 // Get the FACS and DSDT table address from the table FADT
242 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
243 Fadt2Table
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
244 (UINTN
) CurrentTablePointer
;
245 Facs2Table
= (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)
246 (UINTN
) Fadt2Table
->FirmwareCtrl
;
247 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) Fadt2Table
->Dsdt
;
251 else if (XenAcpiRsdpStructurePtr
->RsdtAddress
) {
253 // Retrieve the addresses of RSDT and
254 // calculate the number of its table entries.
256 Rsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
257 XenAcpiRsdpStructurePtr
->RsdtAddress
;
258 NumberOfTableEntries
= (Rsdt
->Length
-
259 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
263 // Install ACPI tables found in XSDT.
265 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
267 // Get the table entry from RSDT
269 CurrentTableEntry
= (UINT32
*) ((UINT8
*) Rsdt
+
270 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
271 Index
* sizeof (UINT32
));
272 CurrentTablePointer
= *(UINT32
*)CurrentTableEntry
;
273 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
276 // Install the RSDT tables
278 Status
= InstallAcpiTable (
281 CurrentTable
->Length
,
285 if (EFI_ERROR (Status
)) {
290 // Get the FACS and DSDT table address from the table FADT
292 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
293 Fadt1Table
= (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
294 (UINTN
) CurrentTablePointer
;
295 Facs1Table
= (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)
296 (UINTN
) Fadt1Table
->FirmwareCtrl
;
297 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) Fadt1Table
->Dsdt
;
303 // Install the FACS table.
309 Status
= InstallAcpiTable (
315 if (EFI_ERROR (Status
)) {
319 else if (Fadt1Table
) {
323 Status
= InstallAcpiTable (
329 if (EFI_ERROR (Status
)) {
335 // Install DSDT table.
337 Status
= InstallAcpiTable (
343 if (EFI_ERROR (Status
)) {