diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Library/AcpiLib/AcpiLib.c | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Library/AcpiLib/AcpiLib.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Library/AcpiLib/AcpiLib.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Library/AcpiLib/AcpiLib.c b/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Library/AcpiLib/AcpiLib.c new file mode 100644 index 00000000..e71bbad7 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Library/AcpiLib/AcpiLib.c @@ -0,0 +1,172 @@ +/** @file +* +* Copyright (c) 2014-2015, ARM Limited. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include <Uefi.h> + +#include <Library/AcpiLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include <Protocol/AcpiTable.h> +#include <Protocol/FirmwareVolume2.h> + +#include <IndustryStandard/Acpi.h> + +/** + Locate and Install the ACPI tables from the Firmware Volume if it verifies + the function condition. + + @param AcpiFile Guid of the ACPI file into the Firmware Volume + @param CheckAcpiTableFunction Function that checks if the ACPI table should be installed + + @return EFI_SUCCESS The function completed successfully. + @return EFI_NOT_FOUND The protocol could not be located. + @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. + +**/ +EFI_STATUS +LocateAndInstallAcpiFromFvConditional ( + IN CONST EFI_GUID* AcpiFile, + IN EFI_LOCATE_ACPI_CHECK CheckAcpiTableFunction + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + UINT32 FvStatus; + UINTN Index; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance; + INTN SectionInstance; + UINTN SectionSize; + EFI_ACPI_COMMON_HEADER *AcpiTable; + UINTN AcpiTableSize; + UINTN AcpiTableKey; + BOOLEAN Valid; + + // Ensure the ACPI Table is present + Status = gBS->LocateProtocol ( + &gEfiAcpiTableProtocolGuid, + NULL, + (VOID**)&AcpiProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + FvStatus = 0; + SectionInstance = 0; + + // Locate all the Firmware Volume protocols. + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // Looking for FV with ACPI storage file + for (Index = 0; Index < NumberOfHandles; Index++) { + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID**) &FvInstance + ); + if (EFI_ERROR (Status)) { + goto FREE_HANDLE_BUFFER; + } + + while (Status == EFI_SUCCESS) { + // AcpiTable must be allocated by ReadSection (ie: AcpiTable == NULL) + AcpiTable = NULL; + + // See if it has the ACPI storage file + Status = FvInstance->ReadSection ( + FvInstance, + AcpiFile, + EFI_SECTION_RAW, + SectionInstance, + (VOID**) &AcpiTable, + &SectionSize, + &FvStatus + ); + if (!EFI_ERROR (Status)) { + AcpiTableKey = 0; + AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Length; + ASSERT (SectionSize >= AcpiTableSize); + + DEBUG ((EFI_D_ERROR, "- Found '%c%c%c%c' ACPI Table\n", + (((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature & 0xFF), + ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 8) & 0xFF), + ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 16) & 0xFF), + ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 24) & 0xFF))); + + // Is the ACPI table valid? + if (CheckAcpiTableFunction) { + Valid = CheckAcpiTableFunction ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable); + } else { + Valid = TRUE; + } + + // Install the ACPI Table + if (Valid) { + Status = AcpiProtocol->InstallAcpiTable ( + AcpiProtocol, + AcpiTable, + AcpiTableSize, + &AcpiTableKey + ); + } + + // Free memory allocated by ReadSection + gBS->FreePool (AcpiTable); + + if (EFI_ERROR (Status)) { + break; + } + + // Increment the section instance + SectionInstance++; + } + } + } + +FREE_HANDLE_BUFFER: + // + // Free any allocated buffers + // + gBS->FreePool (HandleBuffer); + + return EFI_SUCCESS; +} + +/** + Locate and Install the ACPI tables from the Firmware Volume + + @param AcpiFile Guid of the ACPI file into the Firmware Volume + + @return EFI_SUCCESS The function completed successfully. + @return EFI_NOT_FOUND The protocol could not be located. + @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. + +**/ +EFI_STATUS +LocateAndInstallAcpiFromFv ( + IN CONST EFI_GUID* AcpiFile + ) +{ + return LocateAndInstallAcpiFromFvConditional (AcpiFile, NULL); +} |