From 1288c5415c81af7b184567c7cb02b59aeb662be9 Mon Sep 17 00:00:00 2001 From: Corvin Köhne Date: Tue, 6 Jun 2023 11:21:38 +0200 Subject: OvmfPkg/Xen: export AcpiTable installation into AcpiPlatformLib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the function reuseable by bhyve. Signed-off-by: Corvin Köhne Reviewed-by: Anthony PERARD Acked-by: Gerd Hoffmann --- OvmfPkg/Include/Library/AcpiPlatformLib.h | 25 ++ .../Library/AcpiPlatformLib/DxeAcpiPlatformLib.c | 185 +++++++++++++++ OvmfPkg/XenAcpiPlatformDxe/AcpiPlatform.c | 47 +++- OvmfPkg/XenAcpiPlatformDxe/Xen.c | 257 --------------------- OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf | 1 - 5 files changed, 254 insertions(+), 261 deletions(-) delete mode 100644 OvmfPkg/XenAcpiPlatformDxe/Xen.c diff --git a/OvmfPkg/Include/Library/AcpiPlatformLib.h b/OvmfPkg/Include/Library/AcpiPlatformLib.h index b0a3c5bd00..73a1706360 100644 --- a/OvmfPkg/Include/Library/AcpiPlatformLib.h +++ b/OvmfPkg/Include/Library/AcpiPlatformLib.h @@ -4,6 +4,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include + /** Searches and returns the address of the ACPI Root System Description Pointer (RSDP) in system memory. @@ -22,3 +24,26 @@ GetAcpiRsdpFromMemory ( IN UINT64 EndAddress, OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr ); + +/** + Get Acpi tables from the RSDP structure. And installs ACPI tables + into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed + ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT. + + @param AcpiProtocol Protocol instance pointer. + + @return EFI_SUCCESS The table was successfully inserted. + @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is + NULL, or AcpiTableBufferSize and the size + field embedded in the ACPI table pointed to + by AcpiTableBuffer are not in sync. + @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the +request. + +**/ +EFI_STATUS +EFIAPI +InstallAcpiTablesFromRsdp ( + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol, + IN EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp + ); diff --git a/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c b/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c index 9dd9026edb..228cb20ee6 100644 --- a/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c +++ b/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c @@ -65,3 +65,188 @@ GetAcpiRsdpFromMemory ( return EFI_NOT_FOUND; } + +EFI_STATUS +EFIAPI +InstallAcpiTablesFromRsdp ( + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol, + IN EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp + ) +{ + EFI_STATUS Status; + UINTN TableHandle; + + EFI_ACPI_DESCRIPTION_HEADER *Rsdt; + EFI_ACPI_DESCRIPTION_HEADER *Xsdt; + VOID *CurrentTableEntry; + UINTN CurrentTablePointer; + EFI_ACPI_DESCRIPTION_HEADER *CurrentTable; + UINTN Index; + UINTN NumberOfTableEntries; + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table; + EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt1Table; + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs2Table; + EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs1Table; + EFI_ACPI_DESCRIPTION_HEADER *DsdtTable; + + Fadt2Table = NULL; + Fadt1Table = NULL; + Facs2Table = NULL; + Facs1Table = NULL; + DsdtTable = NULL; + TableHandle = 0; + NumberOfTableEntries = 0; + + // + // If XSDT table is find, just install its tables. + // Otherwise, try to find and install the RSDT tables. + // + if (Rsdp->XsdtAddress) { + // + // Retrieve the addresses of XSDT and + // calculate the number of its table entries. + // + Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress; + NumberOfTableEntries = + (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64); + + // + // Install ACPI tables found in XSDT. + // + for (Index = 0; Index < NumberOfTableEntries; Index++) { + // + // Get the table entry from XSDT + // + CurrentTableEntry = + (VOID *)((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + + Index * sizeof (UINT64)); + CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry; + CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer; + + // + // Install the XSDT tables + // + Status = AcpiProtocol->InstallAcpiTable ( + AcpiProtocol, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the FACS and DSDT table address from the table FADT + // + if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) { + Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN) + CurrentTablePointer; + Facs2Table = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN) + Fadt2Table->FirmwareCtrl; + DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt2Table->Dsdt; + } + } + } else if (Rsdp->RsdtAddress) { + // + // Retrieve the addresses of RSDT and + // calculate the number of its table entries. + // + Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress; + NumberOfTableEntries = + (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT32); + + // + // Install ACPI tables found in XSDT. + // + for (Index = 0; Index < NumberOfTableEntries; Index++) { + // + // Get the table entry from RSDT + // + CurrentTableEntry = + (UINT32 *)((UINT8 *)Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + + Index * sizeof (UINT32)); + CurrentTablePointer = *(UINT32 *)CurrentTableEntry; + CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer; + + // + // Install the RSDT tables + // + Status = AcpiProtocol->InstallAcpiTable ( + AcpiProtocol, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the FACS and DSDT table address from the table FADT + // + if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) { + Fadt1Table = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN) + CurrentTablePointer; + Facs1Table = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN) + Fadt1Table->FirmwareCtrl; + DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt1Table->Dsdt; + } + } + } + + // + // Install the FACS table. + // + if (Fadt2Table) { + // + // FACS 2.0 + // + Status = AcpiProtocol->InstallAcpiTable ( + AcpiProtocol, + Facs2Table, + Facs2Table->Length, + &TableHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + } else if (Fadt1Table) { + // + // FACS 1.0 + // + Status = AcpiProtocol->InstallAcpiTable ( + AcpiProtocol, + Facs1Table, + Facs1Table->Length, + &TableHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Install DSDT table. If we reached this point without finding the DSDT, + // then we're out of sync with the hypervisor, and cannot continue. + // + if (DsdtTable == NULL) { + DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __func__)); + ASSERT (FALSE); + CpuDeadLoop (); + } + + Status = AcpiProtocol->InstallAcpiTable ( + AcpiProtocol, + DsdtTable, + DsdtTable->Length, + &TableHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/XenAcpiPlatformDxe/AcpiPlatform.c b/OvmfPkg/XenAcpiPlatformDxe/AcpiPlatform.c index e06bb25dfc..2dbc812953 100644 --- a/OvmfPkg/XenAcpiPlatformDxe/AcpiPlatform.c +++ b/OvmfPkg/XenAcpiPlatformDxe/AcpiPlatform.c @@ -7,10 +7,15 @@ **/ -#include // XenDetected() +#include // InstallAcpiTablesFromMemory() +#include // DEBUG() +#include // XenDetected() #include "AcpiPlatform.h" +#define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020 +#define XEN_BIOS_PHYSICAL_END 0x000FFFFF + /** Effective entrypoint of Acpi Platform driver. @@ -28,10 +33,46 @@ InstallAcpiTables ( IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable ) { - EFI_STATUS Status; + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr; + EFI_XEN_INFO *XenInfo; + EFI_STATUS Status; if (XenDetected ()) { - Status = InstallXenTables (AcpiTable); + // + // 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 + )); + RsdpStructurePtr = XenInfo->RsdpPvh; + } else { + // + // Otherwise, look for the HVM one + // + Status = GetAcpiRsdpFromMemory ( + XEN_ACPI_PHYSICAL_ADDRESS, + XEN_BIOS_PHYSICAL_END, + &RsdpStructurePtr + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + Status = InstallAcpiTablesFromRsdp ( + AcpiTable, + RsdpStructurePtr + ); } else { Status = EFI_UNSUPPORTED; } diff --git a/OvmfPkg/XenAcpiPlatformDxe/Xen.c b/OvmfPkg/XenAcpiPlatformDxe/Xen.c deleted file mode 100644 index a3812cb8d6..0000000000 --- a/OvmfPkg/XenAcpiPlatformDxe/Xen.c +++ /dev/null @@ -1,257 +0,0 @@ -/** @file - OVMF ACPI Xen support - - Copyright (C) 2021, Red Hat, Inc. - Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
- Copyright (c) 2012, Bei Guan - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include // CpuDeadLoop() -#include // DEBUG() -#include // XenGetInfoHOB() - -#include "AcpiPlatform.h" - -#define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020 -#define XEN_BIOS_PHYSICAL_END 0x000FFFFF - -EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr = NULL; - -/** - Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables - into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed - ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT. - - @param AcpiProtocol Protocol instance pointer. - - @return EFI_SUCCESS The table was successfully inserted. - @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is - NULL, or AcpiTableBufferSize and the size - field embedded in the ACPI table pointed to - by AcpiTableBuffer are not in sync. - @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request. - -**/ -EFI_STATUS -EFIAPI -InstallXenTables ( - IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol - ) -{ - EFI_STATUS Status; - UINTN TableHandle; - - EFI_ACPI_DESCRIPTION_HEADER *Rsdt; - EFI_ACPI_DESCRIPTION_HEADER *Xsdt; - VOID *CurrentTableEntry; - UINTN CurrentTablePointer; - EFI_ACPI_DESCRIPTION_HEADER *CurrentTable; - UINTN Index; - UINTN NumberOfTableEntries; - EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table; - EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt1Table; - 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; - Facs2Table = NULL; - Facs1Table = NULL; - DsdtTable = NULL; - TableHandle = 0; - NumberOfTableEntries = 0; - - // - // 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 - )); - 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. - // Otherwise, try to find and install the RSDT tables. - // - if (XenAcpiRsdpStructurePtr->XsdtAddress) { - // - // Retrieve the addresses of XSDT and - // calculate the number of its table entries. - // - Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) - XenAcpiRsdpStructurePtr->XsdtAddress; - NumberOfTableEntries = (Xsdt->Length - - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / - sizeof (UINT64); - - // - // Install ACPI tables found in XSDT. - // - for (Index = 0; Index < NumberOfTableEntries; Index++) { - // - // Get the table entry from XSDT - // - CurrentTableEntry = (VOID *)((UINT8 *)Xsdt + - sizeof (EFI_ACPI_DESCRIPTION_HEADER) + - Index * sizeof (UINT64)); - CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry; - CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer; - - // - // Install the XSDT tables - // - Status = AcpiProtocol->InstallAcpiTable ( - AcpiProtocol, - CurrentTable, - CurrentTable->Length, - &TableHandle - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the FACS and DSDT table address from the table FADT - // - if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) { - Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) - (UINTN)CurrentTablePointer; - Facs2Table = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) - (UINTN)Fadt2Table->FirmwareCtrl; - DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt2Table->Dsdt; - } - } - } else if (XenAcpiRsdpStructurePtr->RsdtAddress) { - // - // Retrieve the addresses of RSDT and - // calculate the number of its table entries. - // - Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) - XenAcpiRsdpStructurePtr->RsdtAddress; - NumberOfTableEntries = (Rsdt->Length - - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / - sizeof (UINT32); - - // - // Install ACPI tables found in XSDT. - // - for (Index = 0; Index < NumberOfTableEntries; Index++) { - // - // Get the table entry from RSDT - // - CurrentTableEntry = (UINT32 *)((UINT8 *)Rsdt + - sizeof (EFI_ACPI_DESCRIPTION_HEADER) + - Index * sizeof (UINT32)); - CurrentTablePointer = *(UINT32 *)CurrentTableEntry; - CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer; - - // - // Install the RSDT tables - // - Status = AcpiProtocol->InstallAcpiTable ( - AcpiProtocol, - CurrentTable, - CurrentTable->Length, - &TableHandle - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the FACS and DSDT table address from the table FADT - // - if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) { - Fadt1Table = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) - (UINTN)CurrentTablePointer; - Facs1Table = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) - (UINTN)Fadt1Table->FirmwareCtrl; - DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt1Table->Dsdt; - } - } - } - - // - // Install the FACS table. - // - if (Fadt2Table) { - // - // FACS 2.0 - // - Status = AcpiProtocol->InstallAcpiTable ( - AcpiProtocol, - Facs2Table, - Facs2Table->Length, - &TableHandle - ); - if (EFI_ERROR (Status)) { - return Status; - } - } else if (Fadt1Table) { - // - // FACS 1.0 - // - Status = AcpiProtocol->InstallAcpiTable ( - AcpiProtocol, - Facs1Table, - Facs1Table->Length, - &TableHandle - ); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Install DSDT table. If we reached this point without finding the DSDT, - // then we're out of sync with the hypervisor, and cannot continue. - // - if (DsdtTable == NULL) { - DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __func__)); - ASSERT (FALSE); - CpuDeadLoop (); - } - - Status = AcpiProtocol->InstallAcpiTable ( - AcpiProtocol, - DsdtTable, - DsdtTable->Length, - &TableHandle - ); - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_SUCCESS; -} diff --git a/OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf b/OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf index 65374569dd..be175d290f 100644 --- a/OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf +++ b/OvmfPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf @@ -25,7 +25,6 @@ AcpiPlatform.c AcpiPlatform.h EntryPoint.c - Xen.c [Packages] MdePkg/MdePkg.dec -- cgit