OvmfPkg/Xen: export search of RSDP into a library function

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 <corvink@FreeBSD.org>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Corvin Köhne 2023-06-06 11:21:37 +02:00 committed by mergify[bot]
parent c1dd400a13
commit f211292711
7 changed files with 152 additions and 90 deletions

View File

@ -0,0 +1,24 @@
/** @file
Copyright (c) 2023, Corvin Köhne <corvink@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 RSDP successfully found.
@retval EFI_NOT_FOUND Couldn't find RSDP.
@retval EFI_ABORTED Invalid RSDP found.
**/
EFI_STATUS
EFIAPI
GetAcpiRsdpFromMemory (
IN UINT64 StartAddress,
IN UINT64 EndAddress,
OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr
);

View File

@ -0,0 +1,67 @@
/** @file
OVMF ACPI support
Copyright (C) 2021, Red Hat, Inc.
Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2012, Bei Guan <gbtju85@gmail.com>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/AcpiPlatformLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
EFI_STATUS
EFIAPI
GetAcpiRsdpFromMemory (
IN UINTN StartAddress,
IN UINTN EndAddress,
OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr
)
{
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;
UINT8 *AcpiPtr;
UINT8 Sum;
for (AcpiPtr = (UINT8 *)StartAddress;
AcpiPtr < (UINT8 *)EndAddress;
AcpiPtr += 0x10)
{
RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)
(UINTN)AcpiPtr;
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;
}

View File

@ -0,0 +1,26 @@
## @file
# ACPI Platform Library Instance.
#
# Copyright (C) 2023, Corvin Köhne <corvink@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

View File

@ -20,6 +20,10 @@
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

View File

@ -322,6 +322,7 @@
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

View File

@ -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
@ -142,6 +57,7 @@ InstallXenTables (
EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs2Table;
EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs1Table;
EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;
EFI_XEN_INFO *XenInfo;
Fadt2Table = NULL;
Fadt1Table = NULL;
@ -152,12 +68,35 @@ InstallXenTables (
NumberOfTableEntries = 0;
//
// Try to find Xen ACPI tables
// Detect the RSDP structure
//
Status = GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr);
//
// 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
));
XenAcpiRsdpStructurePtr = XenInfo->RsdpPvh;
} else {
//
// Otherwise, look for the HVM one
//
Status = GetAcpiRsdpFromMemory (
XEN_ACPI_PHYSICAL_ADDRESS,
XEN_BIOS_PHYSICAL_END,
&XenAcpiRsdpStructurePtr
);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// If XSDT table is find, just install its tables.

View File

@ -32,6 +32,7 @@
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
AcpiPlatformLib
BaseLib
DebugLib
UefiBootServicesTableLib