+++ /dev/null
-/** @file\r
- OVMF ACPI Xen support\r
-\r
- Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
- Copyright (c) 2012, Bei Guan <gbtju85@gmail.com>\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/ \r
-\r
-#include "AcpiPlatform.h"\r
-#include <Library/HobLib.h>\r
-#include <Guid/XenInfo.h>\r
-#include <Library/BaseLib.h>\r
-\r
-#define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020\r
-#define XEN_BIOS_PHYSICAL_END 0x000FFFFF\r
-\r
-EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr = NULL;\r
-\r
-/**\r
- This function detects if OVMF is running on Xen.\r
-\r
-**/\r
-BOOLEAN\r
-XenDetected (\r
- VOID\r
- )\r
-{\r
- EFI_HOB_GUID_TYPE *GuidHob;\r
-\r
- //\r
- // See if a XenInfo HOB is available\r
- //\r
- GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);\r
- if (GuidHob == NULL) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Get the address of Xen ACPI Root System Description Pointer (RSDP)\r
- structure.\r
-\r
- @param RsdpStructurePtr Return pointer to RSDP structure\r
-\r
- @return EFI_SUCCESS Find Xen RSDP structure successfully.\r
- @return EFI_NOT_FOUND Don't find Xen RSDP structure.\r
- @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetXenAcpiRsdp (\r
- OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr\r
- )\r
-{\r
- EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;\r
- UINT8 *XenAcpiPtr;\r
- UINT8 Sum;\r
-\r
- //\r
- // Detect the RSDP structure\r
- //\r
- for (XenAcpiPtr = (UINT8*)(UINTN) XEN_ACPI_PHYSICAL_ADDRESS;\r
- XenAcpiPtr < (UINT8*)(UINTN) XEN_BIOS_PHYSICAL_END;\r
- XenAcpiPtr += 0x10) {\r
-\r
- RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)\r
- (UINTN) XenAcpiPtr;\r
-\r
- if (!AsciiStrnCmp ((CHAR8 *) &RsdpStructurePtr->Signature, "RSD PTR ", 8)) {\r
- //\r
- // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.\r
- // This is only the first 20 bytes of the structure\r
- //\r
- Sum = CalculateSum8 (\r
- (CONST UINT8 *)RsdpStructurePtr,\r
- sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)\r
- );\r
- if (Sum != 0) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (RsdpStructurePtr->Revision >= 2) {\r
- //\r
- // RSDP ACPI 2.0/3.0 checksum, this is the entire table\r
- //\r
- Sum = CalculateSum8 (\r
- (CONST UINT8 *)RsdpStructurePtr,\r
- sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)\r
- );\r
- if (Sum != 0) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- *RsdpPtr = RsdpStructurePtr;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables\r
- into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed\r
- ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.\r
-\r
- @param AcpiProtocol Protocol instance pointer.\r
-\r
- @return EFI_SUCCESS The table was successfully inserted.\r
- @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is\r
- NULL, or AcpiTableBufferSize and the size\r
- field embedded in the ACPI table pointed to\r
- by AcpiTableBuffer are not in sync.\r
- @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InstallXenTables (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN TableHandle;\r
-\r
- EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
- EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
- VOID *CurrentTableEntry;\r
- UINTN CurrentTablePointer;\r
- EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;\r
- UINTN Index;\r
- UINTN NumberOfTableEntries;\r
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;\r
- EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt1Table;\r
- EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs2Table;\r
- EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs1Table;\r
- EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;\r
-\r
- Fadt2Table = NULL;\r
- Fadt1Table = NULL;\r
- Facs2Table = NULL;\r
- Facs1Table = NULL;\r
- DsdtTable = NULL;\r
- TableHandle = 0;\r
- NumberOfTableEntries = 0;\r
-\r
- //\r
- // Try to find Xen ACPI tables\r
- //\r
- Status = GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // If XSDT table is find, just install its tables. \r
- // Otherwise, try to find and install the RSDT tables.\r
- //\r
- if (XenAcpiRsdpStructurePtr->XsdtAddress) {\r
- //\r
- // Retrieve the addresses of XSDT and \r
- // calculate the number of its table entries.\r
- //\r
- Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
- XenAcpiRsdpStructurePtr->XsdtAddress;\r
- NumberOfTableEntries = (Xsdt->Length -\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
- sizeof (UINT64);\r
-\r
- //\r
- // Install ACPI tables found in XSDT.\r
- //\r
- for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
- //\r
- // Get the table entry from XSDT\r
- //\r
- CurrentTableEntry = (VOID *) ((UINT8 *) Xsdt +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
- Index * sizeof (UINT64));\r
- CurrentTablePointer = (UINTN) *(UINT64 *)CurrentTableEntry;\r
- CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
-\r
- //\r
- // Install the XSDT tables\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- CurrentTable,\r
- CurrentTable->Length,\r
- &TableHandle\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the FACS and DSDT table address from the table FADT\r
- //\r
- if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
- Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
- (UINTN) CurrentTablePointer;\r
- Facs2Table = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)\r
- (UINTN) Fadt2Table->FirmwareCtrl;\r
- DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt2Table->Dsdt;\r
- }\r
- }\r
- }\r
- else if (XenAcpiRsdpStructurePtr->RsdtAddress) {\r
- //\r
- // Retrieve the addresses of RSDT and\r
- // calculate the number of its table entries.\r
- //\r
- Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
- XenAcpiRsdpStructurePtr->RsdtAddress;\r
- NumberOfTableEntries = (Rsdt->Length -\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / \r
- sizeof (UINT32);\r
-\r
- //\r
- // Install ACPI tables found in XSDT.\r
- //\r
- for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
- //\r
- // Get the table entry from RSDT\r
- //\r
- CurrentTableEntry = (UINT32 *) ((UINT8 *) Rsdt +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
- Index * sizeof (UINT32));\r
- CurrentTablePointer = *(UINT32 *)CurrentTableEntry;\r
- CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
-\r
- //\r
- // Install the RSDT tables\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- CurrentTable,\r
- CurrentTable->Length,\r
- &TableHandle\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the FACS and DSDT table address from the table FADT\r
- //\r
- if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
- Fadt1Table = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
- (UINTN) CurrentTablePointer;\r
- Facs1Table = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)\r
- (UINTN) Fadt1Table->FirmwareCtrl;\r
- DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt1Table->Dsdt;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Install the FACS table.\r
- //\r
- if (Fadt2Table) {\r
- //\r
- // FACS 2.0\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- Facs2Table,\r
- Facs2Table->Length,\r
- &TableHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- else if (Fadt1Table) {\r
- //\r
- // FACS 1.0\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- Facs1Table,\r
- Facs1Table->Length,\r
- &TableHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Install DSDT table.\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- DsdtTable,\r
- DsdtTable->Length,\r
- &TableHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r