From 0f612c1443975904ff9ef1b9e3b980f8ea009ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corvin=20K=C3=B6hne?= Date: Wed, 21 Jun 2023 09:31:14 +0200 Subject: OvmfPkg: move BootScript into AcpiPlatformLib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required to move InstallQemuFwCfgTables into AcpiPlatformLib. Signed-off-by: Corvin Köhne Acked-by: Peter Grehan --- OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h | 27 -- OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | 2 - OvmfPkg/AcpiPlatformDxe/BootScript.c | 276 --------------------- OvmfPkg/Include/Library/AcpiPlatformLib.h | 27 ++ OvmfPkg/Library/AcpiPlatformLib/BootScript.c | 275 ++++++++++++++++++++ .../Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf | 2 + 6 files changed, 304 insertions(+), 305 deletions(-) delete mode 100644 OvmfPkg/AcpiPlatformDxe/BootScript.c create mode 100644 OvmfPkg/Library/AcpiPlatformLib/BootScript.c diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h index 1328f6d..c9f2755 100644 --- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h +++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h @@ -11,8 +11,6 @@ #include // EFI_ACPI_TABLE_PROTOCOL -typedef struct S3_CONTEXT S3_CONTEXT; - EFI_STATUS EFIAPI InstallCloudHvTablesTdx ( @@ -37,29 +35,4 @@ InstallAcpiTables ( IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable ); -EFI_STATUS -AllocateS3Context ( - OUT S3_CONTEXT **S3Context, - IN UINTN WritePointerCount - ); - -VOID -ReleaseS3Context ( - IN S3_CONTEXT *S3Context - ); - -EFI_STATUS -SaveCondensedWritePointerToS3Context ( - IN OUT S3_CONTEXT *S3Context, - IN UINT16 PointerItem, - IN UINT8 PointerSize, - IN UINT32 PointerOffset, - IN UINT64 PointerValue - ); - -EFI_STATUS -TransferS3ContextToBootScript ( - IN S3_CONTEXT *S3Context - ); - #endif diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf index b22aad9..6001b96 100644 --- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -23,7 +23,6 @@ [Sources] AcpiPlatform.c AcpiPlatform.h - BootScript.c CloudHvAcpi.c EntryPoint.c QemuFwCfgAcpi.c @@ -40,7 +39,6 @@ MemoryAllocationLib OrderedCollectionLib QemuFwCfgLib - QemuFwCfgS3Lib UefiDriverEntryPoint HobLib TpmMeasurementLib diff --git a/OvmfPkg/AcpiPlatformDxe/BootScript.c b/OvmfPkg/AcpiPlatformDxe/BootScript.c deleted file mode 100644 index ff1491d..0000000 --- a/OvmfPkg/AcpiPlatformDxe/BootScript.c +++ /dev/null @@ -1,276 +0,0 @@ -/** @file - Append an ACPI S3 Boot Script fragment from the QEMU_LOADER_WRITE_POINTER - commands of QEMU's fully processed table linker/loader script. - - Copyright (C) 2017, Red Hat, Inc. - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include // CpuDeadLoop() -#include // DEBUG() -#include // AllocatePool() -#include // QemuFwCfgS3ScriptSkipBytes() - -#include "AcpiPlatform.h" - -// -// Condensed structure for capturing the fw_cfg operations -- select, skip, -// write -- inherent in executing a QEMU_LOADER_WRITE_POINTER command. -// -typedef struct { - UINT16 PointerItem; // resolved from QEMU_LOADER_WRITE_POINTER.PointerFile - UINT8 PointerSize; // copied as-is from QEMU_LOADER_WRITE_POINTER - UINT32 PointerOffset; // copied as-is from QEMU_LOADER_WRITE_POINTER - UINT64 PointerValue; // resolved from QEMU_LOADER_WRITE_POINTER.PointeeFile - // and QEMU_LOADER_WRITE_POINTER.PointeeOffset -} CONDENSED_WRITE_POINTER; - -// -// Context structure to accumulate CONDENSED_WRITE_POINTER objects from -// QEMU_LOADER_WRITE_POINTER commands. -// -// Any pointers in this structure own the pointed-to objects; that is, when the -// context structure is released, all pointed-to objects must be released too. -// -struct S3_CONTEXT { - CONDENSED_WRITE_POINTER *WritePointers; // one array element per processed - // QEMU_LOADER_WRITE_POINTER - // command - UINTN Allocated; // number of elements allocated for - // WritePointers - UINTN Used; // number of elements populated in - // WritePointers -}; - -// -// Scratch buffer, allocated in EfiReservedMemoryType type memory, for the ACPI -// S3 Boot Script opcodes to work on. -// -#pragma pack (1) -typedef union { - UINT64 PointerValue; // filled in from CONDENSED_WRITE_POINTER.PointerValue -} SCRATCH_BUFFER; -#pragma pack () - -/** - Allocate an S3_CONTEXT object. - - @param[out] S3Context The allocated S3_CONTEXT object is returned - through this parameter. - - @param[in] WritePointerCount Number of CONDENSED_WRITE_POINTER elements to - allocate room for. WritePointerCount must be - positive. - - @retval EFI_SUCCESS Allocation successful. - - @retval EFI_OUT_OF_RESOURCES Out of memory. - - @retval EFI_INVALID_PARAMETER WritePointerCount is zero. -**/ -EFI_STATUS -AllocateS3Context ( - OUT S3_CONTEXT **S3Context, - IN UINTN WritePointerCount - ) -{ - EFI_STATUS Status; - S3_CONTEXT *Context; - - if (WritePointerCount == 0) { - return EFI_INVALID_PARAMETER; - } - - Context = AllocateZeroPool (sizeof *Context); - if (Context == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Context->WritePointers = AllocatePool ( - WritePointerCount * - sizeof *Context->WritePointers - ); - if (Context->WritePointers == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto FreeContext; - } - - Context->Allocated = WritePointerCount; - *S3Context = Context; - return EFI_SUCCESS; - -FreeContext: - FreePool (Context); - - return Status; -} - -/** - Release an S3_CONTEXT object. - - @param[in] S3Context The object to release. -**/ -VOID -ReleaseS3Context ( - IN S3_CONTEXT *S3Context - ) -{ - FreePool (S3Context->WritePointers); - FreePool (S3Context); -} - -/** - Save the information necessary to replicate a QEMU_LOADER_WRITE_POINTER - command during S3 resume, in condensed format. - - This function is to be called from ProcessCmdWritePointer(), after all the - sanity checks have passed, and before the fw_cfg operations are performed. - - @param[in,out] S3Context The S3_CONTEXT object into which the caller wants - to save the information that was derived from - QEMU_LOADER_WRITE_POINTER. - - @param[in] PointerItem The FIRMWARE_CONFIG_ITEM that - QEMU_LOADER_WRITE_POINTER.PointerFile was resolved - to, expressed as a UINT16 value. - - @param[in] PointerSize Copied directly from - QEMU_LOADER_WRITE_POINTER.PointerSize. - - @param[in] PointerOffset Copied directly from - QEMU_LOADER_WRITE_POINTER.PointerOffset. - - @param[in] PointerValue The base address of the allocated / downloaded - fw_cfg blob that is identified by - QEMU_LOADER_WRITE_POINTER.PointeeFile, plus - QEMU_LOADER_WRITE_POINTER.PointeeOffset. - - @retval EFI_SUCCESS The information derived from - QEMU_LOADER_WRITE_POINTER has been successfully - absorbed into S3Context. - - @retval EFI_OUT_OF_RESOURCES No room available in S3Context. -**/ -EFI_STATUS -SaveCondensedWritePointerToS3Context ( - IN OUT S3_CONTEXT *S3Context, - IN UINT16 PointerItem, - IN UINT8 PointerSize, - IN UINT32 PointerOffset, - IN UINT64 PointerValue - ) -{ - CONDENSED_WRITE_POINTER *Condensed; - - if (S3Context->Used == S3Context->Allocated) { - return EFI_OUT_OF_RESOURCES; - } - - Condensed = S3Context->WritePointers + S3Context->Used; - Condensed->PointerItem = PointerItem; - Condensed->PointerSize = PointerSize; - Condensed->PointerOffset = PointerOffset; - Condensed->PointerValue = PointerValue; - DEBUG (( - DEBUG_VERBOSE, - "%a: 0x%04x/[0x%08x+%d] := 0x%Lx (%Lu)\n", - __func__, - PointerItem, - PointerOffset, - PointerSize, - PointerValue, - (UINT64)S3Context->Used - )); - ++S3Context->Used; - return EFI_SUCCESS; -} - -/** - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION provided to QemuFwCfgS3Lib. -**/ -STATIC -VOID -EFIAPI -AppendFwCfgBootScript ( - IN OUT VOID *Context OPTIONAL, - IN OUT VOID *ExternalScratchBuffer - ) -{ - S3_CONTEXT *S3Context; - SCRATCH_BUFFER *ScratchBuffer; - UINTN Index; - - S3Context = Context; - ScratchBuffer = ExternalScratchBuffer; - - for (Index = 0; Index < S3Context->Used; ++Index) { - CONST CONDENSED_WRITE_POINTER *Condensed; - RETURN_STATUS Status; - - Condensed = &S3Context->WritePointers[Index]; - - Status = QemuFwCfgS3ScriptSkipBytes ( - Condensed->PointerItem, - Condensed->PointerOffset - ); - if (RETURN_ERROR (Status)) { - goto FatalError; - } - - ScratchBuffer->PointerValue = Condensed->PointerValue; - Status = QemuFwCfgS3ScriptWriteBytes (-1, Condensed->PointerSize); - if (RETURN_ERROR (Status)) { - goto FatalError; - } - } - - DEBUG ((DEBUG_VERBOSE, "%a: boot script fragment saved\n", __func__)); - - ReleaseS3Context (S3Context); - return; - -FatalError: - ASSERT (FALSE); - CpuDeadLoop (); -} - -/** - Translate and append the information from an S3_CONTEXT object to the ACPI S3 - Boot Script. - - The effects of a successful call to this function cannot be undone. - - @param[in] S3Context The S3_CONTEXT object to translate to ACPI S3 Boot - Script opcodes. If the function returns successfully, - the caller must set the S3Context pointer -- originally - returned by AllocateS3Context() -- immediately to NULL, - because the ownership of S3Context has been transferred. - - @retval EFI_SUCCESS The translation of S3Context to ACPI S3 Boot Script - opcodes has been successfully executed or queued. (This - includes the case when S3Context was empty on input and - no ACPI S3 Boot Script opcodes have been necessary to - produce.) - - @return Error codes from underlying functions. -**/ -EFI_STATUS -TransferS3ContextToBootScript ( - IN S3_CONTEXT *S3Context - ) -{ - RETURN_STATUS Status; - - if (S3Context->Used == 0) { - ReleaseS3Context (S3Context); - return EFI_SUCCESS; - } - - Status = QemuFwCfgS3CallWhenBootScriptReady ( - AppendFwCfgBootScript, - S3Context, - sizeof (SCRATCH_BUFFER) - ); - return (EFI_STATUS)Status; -} diff --git a/OvmfPkg/Include/Library/AcpiPlatformLib.h b/OvmfPkg/Include/Library/AcpiPlatformLib.h index 167d6c4..70c974d 100644 --- a/OvmfPkg/Include/Library/AcpiPlatformLib.h +++ b/OvmfPkg/Include/Library/AcpiPlatformLib.h @@ -15,6 +15,8 @@ typedef struct { UINT64 PciAttributes; } ORIGINAL_ATTRIBUTES; +typedef struct S3_CONTEXT S3_CONTEXT; + /** Searches and returns the address of the ACPI Root System Description Pointer (RSDP) in system memory. @@ -69,4 +71,29 @@ RestorePciDecoding ( IN UINTN Count ); +EFI_STATUS +AllocateS3Context ( + OUT S3_CONTEXT **S3Context, + IN UINTN WritePointerCount + ); + +VOID +ReleaseS3Context ( + IN S3_CONTEXT *S3Context + ); + +EFI_STATUS +SaveCondensedWritePointerToS3Context ( + IN OUT S3_CONTEXT *S3Context, + IN UINT16 PointerItem, + IN UINT8 PointerSize, + IN UINT32 PointerOffset, + IN UINT64 PointerValue + ); + +EFI_STATUS +TransferS3ContextToBootScript ( + IN S3_CONTEXT *S3Context + ); + #endif diff --git a/OvmfPkg/Library/AcpiPlatformLib/BootScript.c b/OvmfPkg/Library/AcpiPlatformLib/BootScript.c new file mode 100644 index 0000000..1b1658d --- /dev/null +++ b/OvmfPkg/Library/AcpiPlatformLib/BootScript.c @@ -0,0 +1,275 @@ +/** @file + Append an ACPI S3 Boot Script fragment from the QEMU_LOADER_WRITE_POINTER + commands of QEMU's fully processed table linker/loader script. + + Copyright (C) 2017, Red Hat, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include // CpuDeadLoop() +#include // DEBUG() +#include // AllocatePool() +#include // QemuFwCfgS3ScriptSkipBytes() + +// +// Condensed structure for capturing the fw_cfg operations -- select, skip, +// write -- inherent in executing a QEMU_LOADER_WRITE_POINTER command. +// +typedef struct { + UINT16 PointerItem; // resolved from QEMU_LOADER_WRITE_POINTER.PointerFile + UINT8 PointerSize; // copied as-is from QEMU_LOADER_WRITE_POINTER + UINT32 PointerOffset; // copied as-is from QEMU_LOADER_WRITE_POINTER + UINT64 PointerValue; // resolved from QEMU_LOADER_WRITE_POINTER.PointeeFile + // and QEMU_LOADER_WRITE_POINTER.PointeeOffset +} CONDENSED_WRITE_POINTER; + +// +// Context structure to accumulate CONDENSED_WRITE_POINTER objects from +// QEMU_LOADER_WRITE_POINTER commands. +// +// Any pointers in this structure own the pointed-to objects; that is, when the +// context structure is released, all pointed-to objects must be released too. +// +struct S3_CONTEXT { + CONDENSED_WRITE_POINTER *WritePointers; // one array element per processed + // QEMU_LOADER_WRITE_POINTER + // command + UINTN Allocated; // number of elements allocated for + // WritePointers + UINTN Used; // number of elements populated in + // WritePointers +}; + +// +// Scratch buffer, allocated in EfiReservedMemoryType type memory, for the ACPI +// S3 Boot Script opcodes to work on. +// +#pragma pack (1) +typedef union { + UINT64 PointerValue; // filled in from CONDENSED_WRITE_POINTER.PointerValue +} SCRATCH_BUFFER; +#pragma pack () + +/** + Allocate an S3_CONTEXT object. + + @param[out] S3Context The allocated S3_CONTEXT object is returned + through this parameter. + + @param[in] WritePointerCount Number of CONDENSED_WRITE_POINTER elements to + allocate room for. WritePointerCount must be + positive. + + @retval EFI_SUCCESS Allocation successful. + + @retval EFI_OUT_OF_RESOURCES Out of memory. + + @retval EFI_INVALID_PARAMETER WritePointerCount is zero. +**/ +EFI_STATUS +AllocateS3Context ( + OUT S3_CONTEXT **S3Context, + IN UINTN WritePointerCount + ) +{ + EFI_STATUS Status; + S3_CONTEXT *Context; + + if (WritePointerCount == 0) { + return EFI_INVALID_PARAMETER; + } + + Context = AllocateZeroPool (sizeof *Context); + if (Context == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Context->WritePointers = AllocatePool ( + WritePointerCount * + sizeof *Context->WritePointers + ); + if (Context->WritePointers == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto FreeContext; + } + + Context->Allocated = WritePointerCount; + *S3Context = Context; + return EFI_SUCCESS; + +FreeContext: + FreePool (Context); + + return Status; +} + +/** + Release an S3_CONTEXT object. + + @param[in] S3Context The object to release. +**/ +VOID +ReleaseS3Context ( + IN S3_CONTEXT *S3Context + ) +{ + FreePool (S3Context->WritePointers); + FreePool (S3Context); +} + +/** + Save the information necessary to replicate a QEMU_LOADER_WRITE_POINTER + command during S3 resume, in condensed format. + + This function is to be called from ProcessCmdWritePointer(), after all the + sanity checks have passed, and before the fw_cfg operations are performed. + + @param[in,out] S3Context The S3_CONTEXT object into which the caller wants + to save the information that was derived from + QEMU_LOADER_WRITE_POINTER. + + @param[in] PointerItem The FIRMWARE_CONFIG_ITEM that + QEMU_LOADER_WRITE_POINTER.PointerFile was resolved + to, expressed as a UINT16 value. + + @param[in] PointerSize Copied directly from + QEMU_LOADER_WRITE_POINTER.PointerSize. + + @param[in] PointerOffset Copied directly from + QEMU_LOADER_WRITE_POINTER.PointerOffset. + + @param[in] PointerValue The base address of the allocated / downloaded + fw_cfg blob that is identified by + QEMU_LOADER_WRITE_POINTER.PointeeFile, plus + QEMU_LOADER_WRITE_POINTER.PointeeOffset. + + @retval EFI_SUCCESS The information derived from + QEMU_LOADER_WRITE_POINTER has been successfully + absorbed into S3Context. + + @retval EFI_OUT_OF_RESOURCES No room available in S3Context. +**/ +EFI_STATUS +SaveCondensedWritePointerToS3Context ( + IN OUT S3_CONTEXT *S3Context, + IN UINT16 PointerItem, + IN UINT8 PointerSize, + IN UINT32 PointerOffset, + IN UINT64 PointerValue + ) +{ + CONDENSED_WRITE_POINTER *Condensed; + + if (S3Context->Used == S3Context->Allocated) { + return EFI_OUT_OF_RESOURCES; + } + + Condensed = S3Context->WritePointers + S3Context->Used; + Condensed->PointerItem = PointerItem; + Condensed->PointerSize = PointerSize; + Condensed->PointerOffset = PointerOffset; + Condensed->PointerValue = PointerValue; + DEBUG (( + DEBUG_VERBOSE, + "%a: 0x%04x/[0x%08x+%d] := 0x%Lx (%Lu)\n", + __func__, + PointerItem, + PointerOffset, + PointerSize, + PointerValue, + (UINT64)S3Context->Used + )); + ++S3Context->Used; + return EFI_SUCCESS; +} + +/** + FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION provided to QemuFwCfgS3Lib. +**/ +STATIC +VOID +EFIAPI +AppendFwCfgBootScript ( + IN OUT VOID *Context OPTIONAL, + IN OUT VOID *ExternalScratchBuffer + ) +{ + S3_CONTEXT *S3Context; + SCRATCH_BUFFER *ScratchBuffer; + UINTN Index; + + S3Context = Context; + ScratchBuffer = ExternalScratchBuffer; + + for (Index = 0; Index < S3Context->Used; ++Index) { + CONST CONDENSED_WRITE_POINTER *Condensed; + RETURN_STATUS Status; + + Condensed = &S3Context->WritePointers[Index]; + + Status = QemuFwCfgS3ScriptSkipBytes ( + Condensed->PointerItem, + Condensed->PointerOffset + ); + if (RETURN_ERROR (Status)) { + goto FatalError; + } + + ScratchBuffer->PointerValue = Condensed->PointerValue; + Status = QemuFwCfgS3ScriptWriteBytes (-1, Condensed->PointerSize); + if (RETURN_ERROR (Status)) { + goto FatalError; + } + } + + DEBUG ((DEBUG_VERBOSE, "%a: boot script fragment saved\n", __func__)); + + ReleaseS3Context (S3Context); + return; + +FatalError: + ASSERT (FALSE); + CpuDeadLoop (); +} + +/** + Translate and append the information from an S3_CONTEXT object to the ACPI S3 + Boot Script. + + The effects of a successful call to this function cannot be undone. + + @param[in] S3Context The S3_CONTEXT object to translate to ACPI S3 Boot + Script opcodes. If the function returns successfully, + the caller must set the S3Context pointer -- originally + returned by AllocateS3Context() -- immediately to NULL, + because the ownership of S3Context has been transferred. + + @retval EFI_SUCCESS The translation of S3Context to ACPI S3 Boot Script + opcodes has been successfully executed or queued. (This + includes the case when S3Context was empty on input and + no ACPI S3 Boot Script opcodes have been necessary to + produce.) + + @return Error codes from underlying functions. +**/ +EFI_STATUS +TransferS3ContextToBootScript ( + IN S3_CONTEXT *S3Context + ) +{ + RETURN_STATUS Status; + + if (S3Context->Used == 0) { + ReleaseS3Context (S3Context); + return EFI_SUCCESS; + } + + Status = QemuFwCfgS3CallWhenBootScriptReady ( + AppendFwCfgBootScript, + S3Context, + sizeof (SCRATCH_BUFFER) + ); + return (EFI_STATUS)Status; +} diff --git a/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf b/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf index 4be501b..b6e55b6 100644 --- a/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf +++ b/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf @@ -15,6 +15,7 @@ LIBRARY_CLASS = AcpiPlatformLib [Sources] + BootScript.c DxeAcpiPlatformLib.c PciDecoding.c @@ -27,6 +28,7 @@ BaseLib DebugLib PcdLib + QemuFwCfgS3Lib UefiBootServicesTableLib [Pcd] -- cgit v1.1