Xen and bhyve are placing ACPI tables into system memory. So, they can share the same code. Therefore, create a new library which searches and installs ACPI tables from system memory.
Signed-off-by: Corvin Köhne <corv...@freebsd.org> Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> Cc: Jiewen Yao <jiewen....@intel.com> Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: Gerd Hoffmann <kra...@redhat.com> Cc: Anthony Perard <anthony.per...@citrix.com> Cc: Julien Grall <jul...@xen.org> --- OvmfPkg/OvmfPkg.dec | 4 + OvmfPkg/OvmfXen.dsc | 1 + .../AcpiPlatformLib/DxeAcpiPlatformLib.inf | 26 ++++++ .../XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf | 1 + OvmfPkg/Include/Library/AcpiPlatformLib.h | 25 +++++ .../AcpiPlatformLib/DxeAcpiPlatformLib.c | 90 ++++++++++++++++++ OvmfPkg/XenAcpiPlatformDxe/Xen.c | 93 ++----------------- 7 files changed, 153 insertions(+), 87 deletions(-) create mode 100644 OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf create mode 100644 OvmfPkg/Include/Library/AcpiPlatformLib.h create mode 100644 OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 749fbd3b6bf4..8a71b4aaa266 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -20,6 +20,10 @@ [Includes] Csm/Include [LibraryClasses] + ## @libraryclass Search and install ACPI tables. + # + AcpiPlatformLib|Include/Library/AcpiPlatformLib.h + ## @libraryclass Access bhyve's firmware control interface. BhyveFwCtlLib|Include/Library/BhyveFwCtlLib.h diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index 8bfc16c2d3d6..0d91e04e4116 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -319,6 +319,7 @@ [LibraryClasses.common.UEFI_DRIVER] PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf [LibraryClasses.common.DXE_DRIVER] + AcpiPlatformLib|OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf diff --git a/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf b/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf new file mode 100644 index 000000000000..dfe0e5623d32 --- /dev/null +++ b/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf @@ -0,0 +1,26 @@ +## @file +# ACPI Platform Library Instance. +# +# Copyright (C) 2023, Corvin Köhne <corv...@freebsd.org> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeAcpiPlatformLib + FILE_GUID = 578F441A-4A4C-4D24-B9BE-F783152B46F6 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = AcpiPlatformLib + +[Sources] + DxeAcpiPlatformLib.c + +[Packages] + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib diff --git a/OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf b/OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf index d3a6353a50a6..65374569ddc2 100644 --- a/OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf +++ b/OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf @@ -32,6 +32,7 @@ [Packages] OvmfPkg/OvmfPkg.dec [LibraryClasses] + AcpiPlatformLib BaseLib DebugLib UefiBootServicesTableLib diff --git a/OvmfPkg/Include/Library/AcpiPlatformLib.h b/OvmfPkg/Include/Library/AcpiPlatformLib.h new file mode 100644 index 000000000000..431ab1c54f5b --- /dev/null +++ b/OvmfPkg/Include/Library/AcpiPlatformLib.h @@ -0,0 +1,25 @@ +/** @file + Copyright (c) 2023, Corvin Köhne <corv...@freebsd.org> + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +/** + Searches and returns the address of the ACPI Root System Description Pointer (RSDP) in system memory. + + @param StartAddress Start address of search range. + @param EndAddress End address of search range. + @param RsdpPtr Return pointer to RSDP. + + @retval EFI_SUCCESS Bhyve's RSDP successfully found. + @retval EFI_NOT_FOUND Couldn't find bhyve's RSDP. + @retval EFI_UNSUPPORTED Revision is lower than 2. + @retval EFI_PROTOCOL_ERROR Invalid RSDP found. +**/ +EFI_STATUS +EFIAPI +GetAcpiRsdpFromMemory ( + IN UINT64 StartAddress, + IN UINT64 EndAddress, + OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr + ); diff --git a/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c b/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c new file mode 100644 index 000000000000..80f9b5367b6d --- /dev/null +++ b/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c @@ -0,0 +1,90 @@ +/** @file + Copyright (c) 2023, Corvin Köhne <corv...@freebsd.org> + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Library/AcpiPlatformLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> + +EFI_STATUS +EFIAPI +GetAcpiRsdpFromMemory ( + IN UINT64 StartAddress, + IN UINT64 EndAddress, + OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr + ) +{ + UINTN RsdpAddress; + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; + UINT8 Sum; + + if (RsdpPtr == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Detect the RSDP + // + for (RsdpAddress = StartAddress; RsdpAddress < EndAddress; + RsdpAddress += 0x10) + { + Rsdp = NUMERIC_VALUE_AS_POINTER ( + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER, + RsdpAddress + ); + if (Rsdp->Signature != + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) + { + continue; + } + + if (Rsdp->Revision < 2) { + DEBUG ((DEBUG_WARN, "%a: unsupported RSDP found\n", __func__)); + return EFI_UNSUPPORTED; + } + + // + // For ACPI 1.0/2.0/3.0 the checksum of first 20 bytes should be 0. + // For ACPI 2.0/3.0 the checksum of the entire table should be 0. + // + Sum = CalculateCheckSum8 ( + (CONST UINT8 *)Rsdp, + sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) + ); + if (Sum != 0) { + DEBUG (( + DEBUG_ERROR, + "%a: RSDP header checksum not valid: 0x%02x\n", + __func__, + Sum + )); + return EFI_PROTOCOL_ERROR; + } + + Sum = CalculateCheckSum8 ( + (CONST UINT8 *)Rsdp, + sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER) + ); + if (Sum != 0) { + DEBUG (( + DEBUG_ERROR, + "%a: RSDP table checksum not valid: 0x%02x\n", + __func__, + Sum + )); + return EFI_PROTOCOL_ERROR; + } + + // + // RSDP was found and is valid + // + *RsdpPtr = Rsdp; + + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_WARN, "%a: RSDP not found\n", __func__)); + return EFI_NOT_FOUND; +} diff --git a/OvmfPkg/XenAcpiPlatformDxe/Xen.c b/OvmfPkg/XenAcpiPlatformDxe/Xen.c index a80a24628c08..28fa1d1e0e03 100644 --- a/OvmfPkg/XenAcpiPlatformDxe/Xen.c +++ b/OvmfPkg/XenAcpiPlatformDxe/Xen.c @@ -9,6 +9,7 @@ **/ +#include <Library/AcpiPlatformLib.h> #include <Library/BaseLib.h> // CpuDeadLoop() #include <Library/DebugLib.h> // DEBUG() #include <Library/XenPlatformLib.h> // XenGetInfoHOB() @@ -20,92 +21,6 @@ EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr = NULL; -/** - Get the address of Xen ACPI Root System Description Pointer (RSDP) - structure. - - @param RsdpStructurePtr Return pointer to RSDP structure - - @return EFI_SUCCESS Find Xen RSDP structure successfully. - @return EFI_NOT_FOUND Don't find Xen RSDP structure. - @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated. - -**/ -EFI_STATUS -EFIAPI -GetXenAcpiRsdp ( - OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr - ) -{ - EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr; - UINT8 *XenAcpiPtr; - UINT8 Sum; - EFI_XEN_INFO *XenInfo; - - // - // Detect the RSDP structure - // - - // - // First look for PVH one - // - XenInfo = XenGetInfoHOB (); - ASSERT (XenInfo != NULL); - if (XenInfo->RsdpPvh != NULL) { - DEBUG (( - DEBUG_INFO, - "%a: Use ACPI RSDP table at 0x%p\n", - gEfiCallerBaseName, - XenInfo->RsdpPvh - )); - *RsdpPtr = XenInfo->RsdpPvh; - return EFI_SUCCESS; - } - - // - // Otherwise, look for the HVM one - // - for (XenAcpiPtr = (UINT8 *)(UINTN)XEN_ACPI_PHYSICAL_ADDRESS; - XenAcpiPtr < (UINT8 *)(UINTN)XEN_BIOS_PHYSICAL_END; - XenAcpiPtr += 0x10) - { - RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) - (UINTN)XenAcpiPtr; - - if (!AsciiStrnCmp ((CHAR8 *)&RsdpStructurePtr->Signature, "RSD PTR ", 8)) { - // - // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table. - // This is only the first 20 bytes of the structure - // - Sum = CalculateSum8 ( - (CONST UINT8 *)RsdpStructurePtr, - sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) - ); - if (Sum != 0) { - return EFI_ABORTED; - } - - if (RsdpStructurePtr->Revision >= 2) { - // - // RSDP ACPI 2.0/3.0 checksum, this is the entire table - // - Sum = CalculateSum8 ( - (CONST UINT8 *)RsdpStructurePtr, - sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER) - ); - if (Sum != 0) { - return EFI_ABORTED; - } - } - - *RsdpPtr = RsdpStructurePtr; - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - /** Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed @@ -154,7 +69,11 @@ InstallXenTables ( // // Try to find Xen ACPI tables // - Status = GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr); + Status = GetAcpiRsdpFromMemory ( + XEN_ACPI_PHYSICAL_ADDRESS, + XEN_BIOS_PHYSICAL_END, + &XenAcpiRsdpStructurePtr + ); if (EFI_ERROR (Status)) { return Status; } -- 2.40.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#103883): https://edk2.groups.io/g/devel/message/103883 Mute This Topic: https://groups.io/mt/98656946/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-