diff --git a/Platforms/QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatform.h b/Platforms/QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatform.h index 342339750..27aacc1b8 100644 --- a/Platforms/QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatform.h +++ b/Platforms/QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatform.h @@ -17,8 +17,6 @@ typedef struct { UINT64 PciAttributes; } ORIGINAL_ATTRIBUTES; -typedef struct S3_CONTEXT S3_CONTEXT; - EFI_STATUS EFIAPI InstallCloudHvTables ( @@ -49,29 +47,4 @@ 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/Platforms/QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platforms/QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatformDxe.inf index 7ed5c73f5..7c20b45f7 100644 --- a/Platforms/QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/Platforms/QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -23,7 +23,6 @@ [Sources] AcpiPlatform.c AcpiPlatform.h - BootScript.c CloudHvAcpi.c EntryPoint.c PciDecoding.c @@ -43,7 +42,6 @@ OrderedCollectionLib PcdLib QemuFwCfgLib - QemuFwCfgS3Lib UefiBootServicesTableLib UefiDriverEntryPoint diff --git a/Platforms/QemuQ35Pkg/AcpiPlatformDxe/BootScript.c b/Platforms/QemuQ35Pkg/AcpiPlatformDxe/BootScript.c deleted file mode 100644 index 08d0f41bd..000000000 --- a/Platforms/QemuQ35Pkg/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", - __FUNCTION__, - 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", __FUNCTION__)); - - 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/Platforms/QemuQ35Pkg/AcpiPlatformDxe/QemuFwCfgAcpi.c b/Platforms/QemuQ35Pkg/AcpiPlatformDxe/QemuFwCfgAcpi.c index b885965a6..bff108ca8 100644 --- a/Platforms/QemuQ35Pkg/AcpiPlatformDxe/QemuFwCfgAcpi.c +++ b/Platforms/QemuQ35Pkg/AcpiPlatformDxe/QemuFwCfgAcpi.c @@ -3,6 +3,7 @@ Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
Copyright (C) 2012-2014, Red Hat, Inc. + Copyright (c) Microsoft Corporation SPDX-License-Identifier: BSD-2-Clause-Patent @@ -16,7 +17,6 @@ #include // AllocatePool() #include // OrderedCollectionMin() #include // QemuFwCfgFindFile() -#include // QemuFwCfgS3Enabled() #include // gBS #include "AcpiPlatform.h" @@ -622,10 +622,6 @@ ProcessCmdAddChecksum ( @param[in] Tracker The ORDERED_COLLECTION tracking the BLOB user structures created thus far. - @param[in,out] S3Context The S3_CONTEXT object capturing the fw_cfg actions - of successfully processed QEMU_LOADER_WRITE_POINTER - commands, to be replayed at S3 resume. S3Context - may be NULL if S3 is disabled. @retval EFI_PROTOCOL_ERROR Malformed fw_cfg file name(s) have been found in WritePointer. Or, the WritePointer command @@ -636,21 +632,16 @@ ProcessCmdAddChecksum ( does not fit in the given pointer size. @retval EFI_SUCCESS The pointer object inside the writeable fw_cfg - file has been written. If S3Context is not NULL, - then WritePointer has been condensed into - S3Context. + file has been written. - @return Error codes propagated from - SaveCondensedWritePointerToS3Context(). The - pointer object inside the writeable fw_cfg file + @return The pointer object inside the writeable fw_cfg file has not been written. **/ STATIC EFI_STATUS ProcessCmdWritePointer ( IN CONST QEMU_LOADER_WRITE_POINTER *WritePointer, - IN CONST ORDERED_COLLECTION *Tracker, - IN OUT S3_CONTEXT *S3Context OPTIONAL + IN CONST ORDERED_COLLECTION *Tracker ) { RETURN_STATUS Status; @@ -725,25 +716,6 @@ ProcessCmdWritePointer ( return EFI_PROTOCOL_ERROR; } - // - // If S3 is enabled, we have to capture the below fw_cfg actions in condensed - // form, to be replayed during S3 resume. - // - if (S3Context != NULL) { - EFI_STATUS SaveStatus; - - SaveStatus = SaveCondensedWritePointerToS3Context ( - S3Context, - (UINT16)PointerItem, - WritePointer->PointerSize, - WritePointer->PointerOffset, - PointerValue - ); - if (EFI_ERROR (SaveStatus)) { - return SaveStatus; - } - } - QemuFwCfgSelectItem (PointerItem); QemuFwCfgSkipBytes (WritePointer->PointerOffset); QemuFwCfgWriteBytes (WritePointer->PointerSize, &PointerValue); @@ -1093,7 +1065,6 @@ InstallQemuFwCfgTables ( ORIGINAL_ATTRIBUTES *OriginalPciAttributes; UINTN OriginalPciAttributesCount; ORDERED_COLLECTION *AllocationsRestrictedTo32Bit; - S3_CONTEXT *S3Context; ORDERED_COLLECTION *Tracker; UINTN *InstalledKey; INT32 Installed; @@ -1137,22 +1108,10 @@ InstallQemuFwCfgTables ( goto FreeLoader; } - S3Context = NULL; - if (QemuFwCfgS3Enabled ()) { - // - // Size the allocation pessimistically, assuming that all commands in the - // script are QEMU_LOADER_WRITE_POINTER commands. - // - Status = AllocateS3Context (&S3Context, LoaderEnd - LoaderStart); - if (EFI_ERROR (Status)) { - goto FreeAllocationsRestrictedTo32Bit; - } - } - Tracker = OrderedCollectionInit (BlobCompare, BlobKeyCompare); if (Tracker == NULL) { Status = EFI_OUT_OF_RESOURCES; - goto FreeS3Context; + goto FreeAllocationsRestrictedTo32Bit; } // @@ -1188,11 +1147,7 @@ InstallQemuFwCfgTables ( break; case QemuLoaderCmdWritePointer: - Status = ProcessCmdWritePointer ( - &LoaderEntry->Command.WritePointer, - Tracker, - S3Context - ); + Status = ProcessCmdWritePointer (&LoaderEntry->Command.WritePointer, Tracker); if (!EFI_ERROR (Status)) { WritePointerSubsetEnd = LoaderEntry + 1; } @@ -1246,23 +1201,6 @@ InstallQemuFwCfgTables ( } } - // - // Translating the condensed QEMU_LOADER_WRITE_POINTER commands to ACPI S3 - // Boot Script opcodes has to be the last operation in this function, because - // if it succeeds, it cannot be undone. - // - if (S3Context != NULL) { - Status = TransferS3ContextToBootScript (S3Context); - if (EFI_ERROR (Status)) { - goto UninstallAcpiTables; - } - - // - // Ownership of S3Context has been transferred. - // - S3Context = NULL; - } - UninstallAcpiTables: if (EFI_ERROR (Status)) { // @@ -1334,11 +1272,6 @@ InstallQemuFwCfgTables ( OrderedCollectionUninit (Tracker); -FreeS3Context: - if (S3Context != NULL) { - ReleaseS3Context (S3Context); - } - FreeAllocationsRestrictedTo32Bit: ReleaseAllocationsRestrictedTo32Bit (AllocationsRestrictedTo32Bit); diff --git a/Platforms/QemuQ35Pkg/CpuS3DataDxe/CpuS3Data.c b/Platforms/QemuQ35Pkg/CpuS3DataDxe/CpuS3Data.c deleted file mode 100644 index c192a09cf..000000000 --- a/Platforms/QemuQ35Pkg/CpuS3DataDxe/CpuS3Data.c +++ /dev/null @@ -1,281 +0,0 @@ -/** @file -ACPI CPU Data initialization module - -This module initializes the ACPI_CPU_DATA structure and registers the address -of this structure in the PcdCpuS3DataAddress PCD. This is a generic/simple -version of this module. It does not provide a machine check handler or CPU -register initialization tables for ACPI S3 resume. It also only supports the -number of CPUs reported by the MP Services Protocol, so this module does not -support hot plug CPUs. This module can be copied into a CPU specific package -and customized if these additional features are required. - -Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.
-Copyright (c) 2015 - 2020, Red Hat, Inc. - -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -// -// Data structure used to allocate ACPI_CPU_DATA and its supporting structures -// -typedef struct { - ACPI_CPU_DATA AcpiCpuData; - MTRR_SETTINGS MtrrTable; - IA32_DESCRIPTOR GdtrProfile; - IA32_DESCRIPTOR IdtrProfile; -} ACPI_CPU_DATA_EX; - -/** - Allocate EfiACPIMemoryNVS memory. - - @param[in] Size Size of memory to allocate. - - @return Allocated address for output. - -**/ -VOID * -AllocateAcpiNvsMemory ( - IN UINTN Size - ) -{ - EFI_PHYSICAL_ADDRESS Address; - EFI_STATUS Status; - VOID *Buffer; - - Status = gBS->AllocatePages ( - AllocateAnyPages, - EfiACPIMemoryNVS, - EFI_SIZE_TO_PAGES (Size), - &Address - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - Buffer = (VOID *)(UINTN)Address; - ZeroMem (Buffer, Size); - - return Buffer; -} - -/** - Allocate memory and clean it with zero. - - @param[in] Size Size of memory to allocate. - - @return Allocated address for output. - -**/ -VOID * -AllocateZeroPages ( - IN UINTN Size - ) -{ - VOID *Buffer; - - Buffer = AllocatePages (EFI_SIZE_TO_PAGES (Size)); - if (Buffer != NULL) { - ZeroMem (Buffer, Size); - } - - return Buffer; -} - -/** - Callback function executed when the EndOfDxe event group is signaled. - - We delay allocating StartupVector and saving the MTRR settings until BDS signals EndOfDxe. - - @param[in] Event Event whose notification function is being invoked. - @param[out] Context Pointer to the MTRR_SETTINGS buffer to fill in. -**/ -VOID -EFIAPI -CpuS3DataOnEndOfDxe ( - IN EFI_EVENT Event, - OUT VOID *Context - ) -{ - EFI_STATUS Status; - ACPI_CPU_DATA_EX *AcpiCpuDataEx; - - AcpiCpuDataEx = (ACPI_CPU_DATA_EX *)Context; - // - // Allocate a 4KB reserved page below 1MB - // - AcpiCpuDataEx->AcpiCpuData.StartupVector = BASE_1MB - 1; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - 1, - &AcpiCpuDataEx->AcpiCpuData.StartupVector - ); - ASSERT_EFI_ERROR (Status); - - DEBUG ((DEBUG_VERBOSE, "%a\n", __FUNCTION__)); - MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable); - - // - // Close event, so it will not be invoked again. - // - gBS->CloseEvent (Event); -} - -/** - The entry function of the CpuS3Data driver. - - Allocate and initialize all fields of the ACPI_CPU_DATA structure except the - MTRR settings. Register an event notification on gEfiEndOfDxeEventGroupGuid - to capture the ACPI_CPU_DATA MTRR settings. The PcdCpuS3DataAddress is set - to the address that ACPI_CPU_DATA is allocated at. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval EFI_UNSUPPORTED Do not support ACPI S3. - @retval other Some error occurs when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -CpuS3DataInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - ACPI_CPU_DATA_EX *AcpiCpuDataEx; - ACPI_CPU_DATA *AcpiCpuData; - EFI_MP_SERVICES_PROTOCOL *MpServices; - UINTN NumberOfCpus; - VOID *Stack; - UINTN GdtSize; - UINTN IdtSize; - VOID *Gdt; - VOID *Idt; - EFI_EVENT Event; - ACPI_CPU_DATA *OldAcpiCpuData; - - if (!PcdGetBool (PcdAcpiS3Enable)) { - return EFI_UNSUPPORTED; - } - - // - // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure - // - OldAcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress); - - AcpiCpuDataEx = AllocateZeroPages (sizeof (ACPI_CPU_DATA_EX)); - ASSERT (AcpiCpuDataEx != NULL); - AcpiCpuData = &AcpiCpuDataEx->AcpiCpuData; - - if (PcdGetBool (PcdQ35SmramAtDefaultSmbase)) { - NumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); - } else { - UINTN NumberOfEnabledProcessors; - - // - // Get MP Services Protocol - // - Status = gBS->LocateProtocol ( - &gEfiMpServiceProtocolGuid, - NULL, - (VOID **)&MpServices - ); - ASSERT_EFI_ERROR (Status); - - // - // Get the number of CPUs - // - Status = MpServices->GetNumberOfProcessors ( - MpServices, - &NumberOfCpus, - &NumberOfEnabledProcessors - ); - ASSERT_EFI_ERROR (Status); - } - - AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus; - - // - // Initialize ACPI_CPU_DATA fields - // - AcpiCpuData->StackSize = PcdGet32 (PcdCpuApStackSize); - AcpiCpuData->ApMachineCheckHandlerBase = 0; - AcpiCpuData->ApMachineCheckHandlerSize = 0; - AcpiCpuData->GdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->GdtrProfile; - AcpiCpuData->IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->IdtrProfile; - AcpiCpuData->MtrrTable = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->MtrrTable; - - // - // Allocate stack space for all CPUs. - // Use ACPI NVS memory type because this data will be directly used by APs - // in S3 resume phase in long mode. Also during S3 resume, the stack buffer - // will only be used as scratch space. i.e. we won't read anything from it - // before we write to it, in PiSmmCpuDxeSmm. - // - Stack = AllocateAcpiNvsMemory (NumberOfCpus * AcpiCpuData->StackSize); - ASSERT (Stack != NULL); - AcpiCpuData->StackAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Stack; - - // - // Get the boot processor's GDT and IDT - // - AsmReadGdtr (&AcpiCpuDataEx->GdtrProfile); - AsmReadIdtr (&AcpiCpuDataEx->IdtrProfile); - - // - // Allocate GDT and IDT and copy current GDT and IDT contents - // - GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1; - IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1; - Gdt = AllocateZeroPages (GdtSize + IdtSize); - ASSERT (Gdt != NULL); - Idt = (VOID *)((UINTN)Gdt + GdtSize); - CopyMem (Gdt, (VOID *)AcpiCpuDataEx->GdtrProfile.Base, GdtSize); - CopyMem (Idt, (VOID *)AcpiCpuDataEx->IdtrProfile.Base, IdtSize); - AcpiCpuDataEx->GdtrProfile.Base = (UINTN)Gdt; - AcpiCpuDataEx->IdtrProfile.Base = (UINTN)Idt; - - if (OldAcpiCpuData != NULL) { - CopyMem (&AcpiCpuData->CpuFeatureInitData, &OldAcpiCpuData->CpuFeatureInitData, sizeof (CPU_FEATURE_INIT_DATA)); - } - - // - // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure - // - Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData); - ASSERT_EFI_ERROR (Status); - - // - // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event. - // The notification function allocates StartupVector and saves MTRRs for ACPI_CPU_DATA - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - CpuS3DataOnEndOfDxe, - AcpiCpuData, - &gEfiEndOfDxeEventGroupGuid, - &Event - ); - ASSERT_EFI_ERROR (Status); - - return EFI_SUCCESS; -} diff --git a/Platforms/QemuQ35Pkg/CpuS3DataDxe/CpuS3DataDxe.inf b/Platforms/QemuQ35Pkg/CpuS3DataDxe/CpuS3DataDxe.inf deleted file mode 100644 index 41addf9c6..000000000 --- a/Platforms/QemuQ35Pkg/CpuS3DataDxe/CpuS3DataDxe.inf +++ /dev/null @@ -1,64 +0,0 @@ -## @file -# ACPI CPU Data initialization module -# -# This module initializes the ACPI_CPU_DATA structure and registers the address -# of this structure in the PcdCpuS3DataAddress PCD. This is a generic/simple -# version of this module. It does not provide a machine check handler or CPU -# register initialization tables for ACPI S3 resume. It also only supports the -# number of CPUs reported by the MP Services Protocol, so this module does not -# support hot plug CPUs. This module can be copied into a CPU specific package -# and customized if these additional features are required. -# -# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.
-# Copyright (c) 2015-2020, Red Hat, Inc. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 1.29 - BASE_NAME = CpuS3DataDxe - FILE_GUID = 229B7EFD-DA02-46B9-93F4-E20C009F94E9 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = CpuS3DataInitialize - -# The following information is for reference only and not required by the build -# tools. -# -# VALID_ARCHITECTURES = IA32 X64 - -[Sources] - CpuS3Data.c - -[Packages] - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - QemuQ35Pkg/QemuQ35Pkg.dec - UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - MemoryAllocationLib - MtrrLib - UefiBootServicesTableLib - UefiDriverEntryPoint - -[Guids] - gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event - -[Protocols] - gEfiMpServiceProtocolGuid ## CONSUMES - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## PRODUCES - gUefiQemuQ35PkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase ## CONSUMES - -[Depex] - gEfiMpServiceProtocolGuid diff --git a/Platforms/QemuQ35Pkg/Include/Library/QemuFwCfgS3Lib.h b/Platforms/QemuQ35Pkg/Include/Library/QemuFwCfgS3Lib.h deleted file mode 100644 index b6b1e30da..000000000 --- a/Platforms/QemuQ35Pkg/Include/Library/QemuFwCfgS3Lib.h +++ /dev/null @@ -1,349 +0,0 @@ -/** @file - S3 support for QEMU fw_cfg - - This library class enables driver modules (a) to query whether S3 support was - enabled on the QEMU command line, (b) to produce fw_cfg DMA operations that - are to be replayed at S3 resume time. - - Copyright (C) 2017, Red Hat, Inc. - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#ifndef __FW_CFG_S3_LIB__ -#define __FW_CFG_S3_LIB__ - -#include - -/** - Determine if S3 support is explicitly enabled. - - @retval TRUE If S3 support is explicitly enabled. Other functions in this - library may be called (subject to their individual - restrictions). - - FALSE Otherwise. This includes unavailability of the firmware - configuration interface. No other function in this library - must be called. -**/ -BOOLEAN -EFIAPI -QemuFwCfgS3Enabled ( - VOID - ); - -/** - Prototype for the callback function that the client module provides. - - In the callback function, the client module calls the - QemuFwCfgS3ScriptWriteBytes(), QemuFwCfgS3ScriptReadBytes(), - QemuFwCfgS3ScriptSkipBytes(), and QemuFwCfgS3ScriptCheckValue() functions. - Those functions produce ACPI S3 Boot Script opcodes that will perform fw_cfg - DMA operations, and will check any desired values that were read, during S3 - resume. - - The callback function is invoked when the production of ACPI S3 Boot Script - opcodes becomes possible. This may occur directly on the call stack of - QemuFwCfgS3CallWhenBootScriptReady() (see below), or after - QemuFwCfgS3CallWhenBootScriptReady() has successfully returned. - - The callback function must not return if it fails -- in the general case, - there is noone to propagate any errors to. Therefore, on error, an error - message should be logged, and CpuDeadLoop() must be called. - - @param[in,out] Context Carries information from the client module - itself (i.e., from the invocation of - QemuFwCfgS3CallWhenBootScriptReady()) to the - callback function. - - If Context points to dynamically allocated - storage, then the callback function must - release it. - - @param[in,out] ScratchBuffer Points to reserved memory, allocated by - QemuFwCfgS3CallWhenBootScriptReady() - internally. - - ScratchBuffer is typed and sized by the client - module when it calls - QemuFwCfgS3CallWhenBootScriptReady(). The - client module defines a union type of - structures for ScratchBuffer such that the - union can hold client data for any desired - fw_cfg DMA read and write operations, and value - checking. - - The callback function casts ScratchBuffer to - the union type described above. It passes union - member sizes as NumberOfBytes to - QemuFwCfgS3ScriptReadBytes() and - QemuFwCfgS3ScriptWriteBytes(). It passes field - addresses and sizes in structures in the union - as ScratchData and ValueSize to - QemuFwCfgS3ScriptCheckValue(). - - ScratchBuffer is aligned at 8 bytes. -**/ -typedef -VOID(EFIAPI FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION)( - IN OUT VOID *Context OPTIONAL, - IN OUT VOID *ScratchBuffer - ); - -/** - Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for - when the production of ACPI S3 Boot Script opcodes becomes possible. - - Take ownership of the client-provided Context, and pass it to the callback - function, when the latter is invoked. - - Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon - that the client will produce in the callback function. - - @param[in] Callback FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke - when the production of ACPI S3 Boot Script - opcodes becomes possible. Callback() may be - called immediately from - QemuFwCfgS3CallWhenBootScriptReady(). - - @param[in,out] Context Client-provided data structure for the - Callback() callback function to consume. - - If Context points to dynamically allocated - memory, then Callback() must release it. - - If Context points to dynamically allocated - memory, and - QemuFwCfgS3CallWhenBootScriptReady() returns - successfully, then the caller of - QemuFwCfgS3CallWhenBootScriptReady() must - neither dereference nor even evaluate Context - any longer, as ownership of the referenced area - has been transferred to Callback(). - - @param[in] ScratchBufferSize The size of the scratch buffer that will hold, - in reserved memory, all client data read, - written, and checked by the ACPI S3 Boot Script - opcodes produced by Callback(). - - @retval RETURN_UNSUPPORTED The library instance does not support this - function. - - @retval RETURN_NOT_FOUND The fw_cfg DMA interface to QEMU is - unavailable. - - @retval RETURN_BAD_BUFFER_SIZE ScratchBufferSize is too large. - - @retval RETURN_OUT_OF_RESOURCES Memory allocation failed. - - @retval RETURN_SUCCESS Callback() has been installed, and the - ownership of Context has been transferred. - Reserved memory has been allocated for the - scratch buffer. - - A successful invocation of - QemuFwCfgS3CallWhenBootScriptReady() cannot - be rolled back. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3CallWhenBootScriptReady ( - IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback, - IN OUT VOID *Context OPTIONAL, - IN UINTN ScratchBufferSize - ); - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and transfer data to it. - - The opcodes produced by QemuFwCfgS3ScriptWriteBytes() will first restore - NumberOfBytes bytes in ScratchBuffer in-place, in reserved memory, then write - them to fw_cfg using DMA. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to write, expressed as INT32. If - FirmwareConfigItem is -1, no selection is - made, the write will occur to the currently - selected item, at its currently selected - offset. Otherwise, the specified item will be - selected, and the write will occur at offset - 0. - - @param[in] NumberOfBytes Size of the data to restore in ScratchBuffer, - and to write from ScratchBuffer, during S3 - resume. NumberOfBytes must not exceed - ScratchBufferSize, which was passed to - QemuFwCfgS3CallWhenBootScriptReady(). - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than - ScratchBufferSize. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptWriteBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ); - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and transfer data from it. - - The opcodes produced by QemuFwCfgS3ScriptReadBytes() will read NumberOfBytes - bytes from fw_cfg using DMA, storing the result in ScratchBuffer, in reserved - memory. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to read, expressed as INT32. If - FirmwareConfigItem is -1, no selection is - made, the read will occur from the currently - selected item, from its currently selected - offset. Otherwise, the specified item will be - selected, and the read will occur from offset - 0. - - @param[in] NumberOfBytes Size of the data to read during S3 resume. - NumberOfBytes must not exceed - ScratchBufferSize, which was passed to - QemuFwCfgS3CallWhenBootScriptReady(). - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than - ScratchBufferSize. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptReadBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ); - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and increase its offset. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to advance the offset of, expressed as - INT32. If FirmwareConfigItem is -1, no - selection is made, and the offset for the - currently selected item is increased. - Otherwise, the specified item will be - selected, and the offset increment will occur - from offset 0. - - @param[in] NumberOfBytes The number of bytes to skip in the subject - fw_cfg item. - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is too large. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptSkipBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ); - -/** - Produce ACPI S3 Boot Script opcodes that check a value in ScratchBuffer. - - If the check fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] ScratchData Pointer to the UINT8, UINT16, UINT32 or UINT64 field - in ScratchBuffer that should be checked. The caller - is responsible for populating the field during S3 - resume, by calling QemuFwCfgS3ScriptReadBytes() ahead - of QemuFwCfgS3ScriptCheckValue(). - - ScratchData must point into ScratchBuffer, which was - allocated, and passed to Callback(), by - QemuFwCfgS3CallWhenBootScriptReady(). - - ScratchData must be aligned at ValueSize bytes. - - @param[in] ValueSize One of 1, 2, 4 or 8, specifying the size of the field - to check. - - @param[in] ValueMask The value read from ScratchData is binarily AND-ed - with ValueMask, and the result is compared against - Value. If the masked data equals Value, the check - passes, and the boot script can proceed. Otherwise, - the check fails, and the boot script hangs. - - @param[in] Value Refer to ValueMask. - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER ValueSize is invalid. - - @retval RETURN_INVALID_PARAMETER ValueMask or Value cannot be represented in - ValueSize bytes. - - @retval RETURN_INVALID_PARAMETER ScratchData is not aligned at ValueSize - bytes. - - @retval RETURN_BAD_BUFFER_SIZE The ValueSize bytes at ScratchData aren't - wholly contained in the ScratchBufferSize - bytes at ScratchBuffer. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptCheckValue ( - IN VOID *ScratchData, - IN UINT8 ValueSize, - IN UINT64 ValueMask, - IN UINT64 Value - ); - -#endif diff --git a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf b/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf deleted file mode 100644 index db4a22df1..000000000 --- a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf +++ /dev/null @@ -1,38 +0,0 @@ -## @file -# Base Null library instance of the QemuFwCfgS3Lib class. -# -# This library instance returns constant FALSE from QemuFwCfgS3Enabled(), and -# all other library functions trigger assertion failures. It is suitable for -# QEMU targets and machine types that never enable S3. -# -# Copyright (c) 2018, Intel Corporation. All rights reserved.
-# Copyright (C) 2017, Red Hat, Inc. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 1.25 - BASE_NAME = BaseQemuFwCfgS3LibNull - FILE_GUID = EA7D2B69-D221-4950-9C2C-C38A65BCC96E - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = QemuFwCfgS3Lib - -# -# The following information is for reference only and not required by the build -# tools. -# -# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 EBC -# - -[Sources] - QemuFwCfgS3Base.c - QemuFwCfgS3BasePei.c - -[Packages] - MdePkg/MdePkg.dec - QemuQ35Pkg/QemuQ35Pkg.dec - -[LibraryClasses] - DebugLib diff --git a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf b/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf deleted file mode 100644 index 08e85df3e..000000000 --- a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf +++ /dev/null @@ -1,42 +0,0 @@ -## @file -# Full functionality QemuFwCfgS3Lib instance, for DXE phase modules. -# -# Copyright (c) 2018, Intel Corporation. All rights reserved.
-# Copyright (C) 2017, Red Hat, Inc. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 1.25 - BASE_NAME = DxeQemuFwCfgS3LibFwCfg - FILE_GUID = C5DE76EB-E8DE-4057-A487-C5A09AB039AB - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = QemuFwCfgS3Lib|DXE_DRIVER DXE_RUNTIME_DRIVER - -# -# The following information is for reference only and not required by the build -# tools. -# -# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 EBC -# - -[Sources] - QemuFwCfgS3Dxe.c - QemuFwCfgS3PeiDxe.c - -[Packages] - MdePkg/MdePkg.dec - QemuPkg/QemuPkg.dec - QemuQ35Pkg/QemuQ35Pkg.dec - -[LibraryClasses] - BaseLib - DebugLib - MemoryAllocationLib - QemuFwCfgLib - UefiBootServicesTableLib - -[Protocols] - gEfiS3SaveStateProtocolGuid ## SOMETIMES_CONSUMES diff --git a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf b/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf deleted file mode 100644 index 7d4147875..000000000 --- a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf +++ /dev/null @@ -1,40 +0,0 @@ -## @file -# Limited functionality QemuFwCfgS3Lib instance, for PEI phase modules. -# -# QemuFwCfgS3Enabled() queries S3 enablement via fw_cfg. Other library APIs -# will report lack of support. -# -# Copyright (c) 2018, Intel Corporation. All rights reserved.
-# Copyright (C) 2017, Red Hat, Inc. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 1.25 - BASE_NAME = PeiQemuFwCfgS3LibFwCfg - FILE_GUID = DD8D28B4-C1DC-4CAF-BB93-074BE80DAE6D - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - LIBRARY_CLASS = QemuFwCfgS3Lib|PEIM - -# -# The following information is for reference only and not required by the build -# tools. -# -# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 EBC -# - -[Sources] - QemuFwCfgS3BasePei.c - QemuFwCfgS3Pei.c - QemuFwCfgS3PeiDxe.c - -[Packages] - MdePkg/MdePkg.dec - QemuPkg/QemuPkg.dec - QemuQ35Pkg/QemuQ35Pkg.dec - -[LibraryClasses] - DebugLib - QemuFwCfgLib diff --git a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c b/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c deleted file mode 100644 index b0356a2e2..000000000 --- a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Base.c +++ /dev/null @@ -1,103 +0,0 @@ -/** @file - Base Null library instance of the QemuFwCfgS3Lib class. - - This library instance returns constant FALSE from QemuFwCfgS3Enabled(), and - all other library functions trigger assertion failures. It is suitable for - QEMU targets and machine types that never enable S3. - - Copyright (C) 2017, Red Hat, Inc. - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include - -/** - Determine if S3 support is explicitly enabled. - - @retval TRUE If S3 support is explicitly enabled. Other functions in this - library may be called (subject to their individual - restrictions). - - FALSE Otherwise. This includes unavailability of the firmware - configuration interface. No other function in this library - must be called. -**/ -BOOLEAN -EFIAPI -QemuFwCfgS3Enabled ( - VOID - ) -{ - return FALSE; -} - -/** - Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for - when the production of ACPI S3 Boot Script opcodes becomes possible. - - Take ownership of the client-provided Context, and pass it to the callback - function, when the latter is invoked. - - Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon - that the client will produce in the callback function. - - @param[in] Callback FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke - when the production of ACPI S3 Boot Script - opcodes becomes possible. Callback() may be - called immediately from - QemuFwCfgS3CallWhenBootScriptReady(). - - @param[in,out] Context Client-provided data structure for the - Callback() callback function to consume. - - If Context points to dynamically allocated - memory, then Callback() must release it. - - If Context points to dynamically allocated - memory, and - QemuFwCfgS3CallWhenBootScriptReady() returns - successfully, then the caller of - QemuFwCfgS3CallWhenBootScriptReady() must - neither dereference nor even evaluate Context - any longer, as ownership of the referenced area - has been transferred to Callback(). - - @param[in] ScratchBufferSize The size of the scratch buffer that will hold, - in reserved memory, all client data read, - written, and checked by the ACPI S3 Boot Script - opcodes produced by Callback(). - - @retval RETURN_UNSUPPORTED The library instance does not support this - function. - - @retval RETURN_NOT_FOUND The fw_cfg DMA interface to QEMU is - unavailable. - - @retval RETURN_BAD_BUFFER_SIZE ScratchBufferSize is too large. - - @retval RETURN_OUT_OF_RESOURCES Memory allocation failed. - - @retval RETURN_SUCCESS Callback() has been installed, and the - ownership of Context has been transferred. - Reserved memory has been allocated for the - scratch buffer. - - A successful invocation of - QemuFwCfgS3CallWhenBootScriptReady() cannot - be rolled back. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3CallWhenBootScriptReady ( - IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback, - IN OUT VOID *Context OPTIONAL, - IN UINTN ScratchBufferSize - ) -{ - ASSERT (FALSE); - return RETURN_UNSUPPORTED; -} diff --git a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c b/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c deleted file mode 100644 index 3c1b28ba2..000000000 --- a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3BasePei.c +++ /dev/null @@ -1,218 +0,0 @@ -/** @file - Shared code for the Base Null and PEI fw_cfg instances of the QemuFwCfgS3Lib - class. - - Copyright (C) 2017, Red Hat, Inc. - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and transfer data to it. - - The opcodes produced by QemuFwCfgS3ScriptWriteBytes() will first restore - NumberOfBytes bytes in ScratchBuffer in-place, in reserved memory, then write - them to fw_cfg using DMA. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to write, expressed as INT32. If - FirmwareConfigItem is -1, no selection is - made, the write will occur to the currently - selected item, at its currently selected - offset. Otherwise, the specified item will be - selected, and the write will occur at offset - 0. - - @param[in] NumberOfBytes Size of the data to restore in ScratchBuffer, - and to write from ScratchBuffer, during S3 - resume. NumberOfBytes must not exceed - ScratchBufferSize, which was passed to - QemuFwCfgS3CallWhenBootScriptReady(). - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than - ScratchBufferSize. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptWriteBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ) -{ - ASSERT (FALSE); - return RETURN_UNSUPPORTED; -} - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and transfer data from it. - - The opcodes produced by QemuFwCfgS3ScriptReadBytes() will read NumberOfBytes - bytes from fw_cfg using DMA, storing the result in ScratchBuffer, in reserved - memory. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to read, expressed as INT32. If - FirmwareConfigItem is -1, no selection is - made, the read will occur from the currently - selected item, from its currently selected - offset. Otherwise, the specified item will be - selected, and the read will occur from offset - 0. - - @param[in] NumberOfBytes Size of the data to read during S3 resume. - NumberOfBytes must not exceed - ScratchBufferSize, which was passed to - QemuFwCfgS3CallWhenBootScriptReady(). - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than - ScratchBufferSize. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptReadBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ) -{ - ASSERT (FALSE); - return RETURN_UNSUPPORTED; -} - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and increase its offset. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to advance the offset of, expressed as - INT32. If FirmwareConfigItem is -1, no - selection is made, and the offset for the - currently selected item is increased. - Otherwise, the specified item will be - selected, and the offset increment will occur - from offset 0. - - @param[in] NumberOfBytes The number of bytes to skip in the subject - fw_cfg item. - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is too large. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptSkipBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ) -{ - ASSERT (FALSE); - return RETURN_UNSUPPORTED; -} - -/** - Produce ACPI S3 Boot Script opcodes that check a value in ScratchBuffer. - - If the check fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] ScratchData Pointer to the UINT8, UINT16, UINT32 or UINT64 field - in ScratchBuffer that should be checked. The caller - is responsible for populating the field during S3 - resume, by calling QemuFwCfgS3ScriptReadBytes() ahead - of QemuFwCfgS3ScriptCheckValue(). - - ScratchData must point into ScratchBuffer, which was - allocated, and passed to Callback(), by - QemuFwCfgS3CallWhenBootScriptReady(). - - ScratchData must be aligned at ValueSize bytes. - - @param[in] ValueSize One of 1, 2, 4 or 8, specifying the size of the field - to check. - - @param[in] ValueMask The value read from ScratchData is binarily AND-ed - with ValueMask, and the result is compared against - Value. If the masked data equals Value, the check - passes, and the boot script can proceed. Otherwise, - the check fails, and the boot script hangs. - - @param[in] Value Refer to ValueMask. - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER ValueSize is invalid. - - @retval RETURN_INVALID_PARAMETER ValueMask or Value cannot be represented in - ValueSize bytes. - - @retval RETURN_INVALID_PARAMETER ScratchData is not aligned at ValueSize - bytes. - - @retval RETURN_BAD_BUFFER_SIZE The ValueSize bytes at ScratchData aren't - wholly contained in the ScratchBufferSize - bytes at ScratchBuffer. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptCheckValue ( - IN VOID *ScratchData, - IN UINT8 ValueSize, - IN UINT64 ValueMask, - IN UINT64 Value - ) -{ - ASSERT (FALSE); - return RETURN_UNSUPPORTED; -} diff --git a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c b/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c deleted file mode 100644 index 5706fa9be..000000000 --- a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Dxe.c +++ /dev/null @@ -1,887 +0,0 @@ -/** @file - Full functionality QemuFwCfgS3Lib instance, for DXE phase modules. - - Copyright (C) 2017, Red Hat, Inc. - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include -#include -#include -#include -#include -#include - -// -// Event to signal when the S3SaveState protocol interface is installed. -// -STATIC EFI_EVENT mS3SaveStateInstalledEvent; - -// -// Reference to the S3SaveState protocol interface, after it is installed. -// -STATIC EFI_S3_SAVE_STATE_PROTOCOL *mS3SaveState; - -// -// The control structure is allocated in reserved memory, aligned at 8 bytes. -// The client-requested ScratchBuffer will be allocated adjacently, also -// aligned at 8 bytes. -// -#define RESERVED_MEM_ALIGNMENT 8 - -STATIC FW_CFG_DMA_ACCESS *mDmaAccess; -STATIC VOID *mScratchBuffer; -STATIC UINTN mScratchBufferSize; - -// -// Callback provided by the client, for appending ACPI S3 Boot Script opcodes. -// To be called from S3SaveStateInstalledNotify(). -// -STATIC FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *mCallback; - -/** - Event notification function for mS3SaveStateInstalledEvent. -**/ -STATIC -VOID -EFIAPI -S3SaveStateInstalledNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - - ASSERT (Event == mS3SaveStateInstalledEvent); - - Status = gBS->LocateProtocol ( - &gEfiS3SaveStateProtocolGuid, - NULL /* Registration */, - (VOID **)&mS3SaveState - ); - if (EFI_ERROR (Status)) { - return; - } - - ASSERT (mCallback != NULL); - - DEBUG (( - DEBUG_INFO, - "%a: %a: DmaAccess@0x%Lx ScratchBuffer@[0x%Lx+0x%Lx]\n", - gEfiCallerBaseName, - __FUNCTION__, - (UINT64)(UINTN)mDmaAccess, - (UINT64)(UINTN)mScratchBuffer, - (UINT64)mScratchBufferSize - )); - mCallback (Context, mScratchBuffer); - - gBS->CloseEvent (mS3SaveStateInstalledEvent); - mS3SaveStateInstalledEvent = NULL; -} - -/** - Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for - when the production of ACPI S3 Boot Script opcodes becomes possible. - - Take ownership of the client-provided Context, and pass it to the callback - function, when the latter is invoked. - - Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon - that the client will produce in the callback function. - - @param[in] Callback FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke - when the production of ACPI S3 Boot Script - opcodes becomes possible. Callback() may be - called immediately from - QemuFwCfgS3CallWhenBootScriptReady(). - - @param[in,out] Context Client-provided data structure for the - Callback() callback function to consume. - - If Context points to dynamically allocated - memory, then Callback() must release it. - - If Context points to dynamically allocated - memory, and - QemuFwCfgS3CallWhenBootScriptReady() returns - successfully, then the caller of - QemuFwCfgS3CallWhenBootScriptReady() must - neither dereference nor even evaluate Context - any longer, as ownership of the referenced area - has been transferred to Callback(). - - @param[in] ScratchBufferSize The size of the scratch buffer that will hold, - in reserved memory, all client data read, - written, and checked by the ACPI S3 Boot Script - opcodes produced by Callback(). - - @retval RETURN_UNSUPPORTED The library instance does not support this - function. - - @retval RETURN_NOT_FOUND The fw_cfg DMA interface to QEMU is - unavailable. - - @retval RETURN_BAD_BUFFER_SIZE ScratchBufferSize is too large. - - @retval RETURN_OUT_OF_RESOURCES Memory allocation failed. - - @retval RETURN_SUCCESS Callback() has been installed, and the - ownership of Context has been transferred. - Reserved memory has been allocated for the - scratch buffer. - - A successful invocation of - QemuFwCfgS3CallWhenBootScriptReady() cannot - be rolled back. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3CallWhenBootScriptReady ( - IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback, - IN OUT VOID *Context OPTIONAL, - IN UINTN ScratchBufferSize - ) -{ - EFI_STATUS Status; - VOID *Registration; - - // - // Basic fw_cfg is certainly available, as we can only be here after a - // successful call to QemuFwCfgS3Enabled(). Check fw_cfg DMA availability. - // - ASSERT (QemuFwCfgIsAvailable ()); - QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); - if ((QemuFwCfgRead32 () & FW_CFG_F_DMA) == 0) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: fw_cfg DMA unavailable\n", - gEfiCallerBaseName, - __FUNCTION__ - )); - return RETURN_NOT_FOUND; - } - - // - // Allocate a reserved buffer for the DMA access control structure and the - // client data together. - // - if (ScratchBufferSize > - MAX_UINT32 - (RESERVED_MEM_ALIGNMENT - 1) - sizeof *mDmaAccess) - { - DEBUG (( - DEBUG_ERROR, - "%a: %a: ScratchBufferSize too big: %Lu\n", - gEfiCallerBaseName, - __FUNCTION__, - (UINT64)ScratchBufferSize - )); - return RETURN_BAD_BUFFER_SIZE; - } - - mDmaAccess = AllocateReservedPool ( - (RESERVED_MEM_ALIGNMENT - 1) + - sizeof *mDmaAccess + ScratchBufferSize - ); - if (mDmaAccess == NULL) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: AllocateReservedPool(): out of resources\n", - gEfiCallerBaseName, - __FUNCTION__ - )); - return RETURN_OUT_OF_RESOURCES; - } - - mDmaAccess = ALIGN_POINTER (mDmaAccess, RESERVED_MEM_ALIGNMENT); - - // - // Set up a protocol notify for EFI_S3_SAVE_STATE_PROTOCOL. Forward the - // client's Context to the callback. - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - S3SaveStateInstalledNotify, - Context, - &mS3SaveStateInstalledEvent - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: CreateEvent(): %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - goto FreeDmaAccess; - } - - Status = gBS->RegisterProtocolNotify ( - &gEfiS3SaveStateProtocolGuid, - mS3SaveStateInstalledEvent, - &Registration - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: RegisterProtocolNotify(): %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - goto CloseEvent; - } - - // - // Set the remaining global variables. For the alignment guarantee on - // mScratchBuffer, we rely on the fact that *mDmaAccess has a size that is an - // integral multiple of RESERVED_MEM_ALIGNMENT. - // - ASSERT (sizeof *mDmaAccess % RESERVED_MEM_ALIGNMENT == 0); - mScratchBuffer = mDmaAccess + 1; - mScratchBufferSize = ScratchBufferSize; - mCallback = Callback; - - // - // Kick the event; EFI_S3_SAVE_STATE_PROTOCOL could be available already. - // - Status = gBS->SignalEvent (mS3SaveStateInstalledEvent); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: SignalEvent(): %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - goto NullGlobals; - } - - return RETURN_SUCCESS; - -NullGlobals: - mScratchBuffer = NULL; - mScratchBufferSize = 0; - mCallback = NULL; - -CloseEvent: - gBS->CloseEvent (mS3SaveStateInstalledEvent); - mS3SaveStateInstalledEvent = NULL; - -FreeDmaAccess: - FreePool (mDmaAccess); - mDmaAccess = NULL; - - return (RETURN_STATUS)Status; -} - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and transfer data to it. - - The opcodes produced by QemuFwCfgS3ScriptWriteBytes() will first restore - NumberOfBytes bytes in ScratchBuffer in-place, in reserved memory, then write - them to fw_cfg using DMA. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to write, expressed as INT32. If - FirmwareConfigItem is -1, no selection is - made, the write will occur to the currently - selected item, at its currently selected - offset. Otherwise, the specified item will be - selected, and the write will occur at offset - 0. - - @param[in] NumberOfBytes Size of the data to restore in ScratchBuffer, - and to write from ScratchBuffer, during S3 - resume. NumberOfBytes must not exceed - ScratchBufferSize, which was passed to - QemuFwCfgS3CallWhenBootScriptReady(). - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than - ScratchBufferSize. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptWriteBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ) -{ - UINTN Count; - EFI_STATUS Status; - UINT64 AccessAddress; - UINT32 ControlPollData; - UINT32 ControlPollMask; - - ASSERT (mDmaAccess != NULL); - ASSERT (mS3SaveState != NULL); - - if ((FirmwareConfigItem < -1) || (FirmwareConfigItem > MAX_UINT16)) { - return RETURN_INVALID_PARAMETER; - } - - if (NumberOfBytes > mScratchBufferSize) { - return RETURN_BAD_BUFFER_SIZE; - } - - // - // Set up a write[+select] fw_cfg DMA command. - // - mDmaAccess->Control = FW_CFG_DMA_CTL_WRITE; - if (FirmwareConfigItem != -1) { - mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT; - mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16; - } - - mDmaAccess->Control = SwapBytes32 (mDmaAccess->Control); - - // - // We ensured the following constraint via mScratchBufferSize in - // QemuFwCfgS3CallWhenBootScriptReady(). - // - ASSERT (NumberOfBytes <= MAX_UINT32); - mDmaAccess->Length = SwapBytes32 ((UINT32)NumberOfBytes); - - mDmaAccess->Address = SwapBytes64 ((UINTN)mScratchBuffer); - - // - // Copy mDmaAccess and NumberOfBytes bytes from mScratchBuffer into the boot - // script. When executed at S3 resume, this opcode will restore all of them - // in-place. - // - Count = (UINTN)mScratchBuffer + NumberOfBytes - (UINTN)mDmaAccess; - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode - EfiBootScriptWidthUint8, // Width - (UINT64)(UINTN)mDmaAccess, // Address - Count, // Count - (VOID *)mDmaAccess // Buffer - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - // - // Append an opcode that will write the address of the fw_cfg DMA command to - // the fw_cfg DMA address register, which consists of two 32-bit IO ports. - // The second (highest address, least significant) write will start the - // transfer. - // - AccessAddress = SwapBytes64 ((UINTN)mDmaAccess); - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode - EfiBootScriptWidthUint32, // Width - (UINT64)FW_CFG_IO_DMA_ADDRESS, // Address - (UINTN)2, // Count - (VOID *)&AccessAddress // Buffer - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - // - // The following opcode will wait until the Control word reads as zero - // (transfer complete). As timeout we use MAX_UINT64 * 100ns, which is - // approximately 58494 years. - // - ControlPollData = 0; - ControlPollMask = MAX_UINT32; - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, // OpCode - EfiBootScriptWidthUint32, // Width - (UINT64)(UINTN)&mDmaAccess->Control, // Address - (VOID *)&ControlPollData, // Data - (VOID *)&ControlPollMask, // DataMask - MAX_UINT64 // Delay - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - return RETURN_SUCCESS; -} - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and transfer data from it. - - The opcodes produced by QemuFwCfgS3ScriptReadBytes() will read NumberOfBytes - bytes from fw_cfg using DMA, storing the result in ScratchBuffer, in reserved - memory. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to read, expressed as INT32. If - FirmwareConfigItem is -1, no selection is - made, the read will occur from the currently - selected item, from its currently selected - offset. Otherwise, the specified item will be - selected, and the read will occur from offset - 0. - - @param[in] NumberOfBytes Size of the data to read during S3 resume. - NumberOfBytes must not exceed - ScratchBufferSize, which was passed to - QemuFwCfgS3CallWhenBootScriptReady(). - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than - ScratchBufferSize. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptReadBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ) -{ - EFI_STATUS Status; - UINT64 AccessAddress; - UINT32 ControlPollData; - UINT32 ControlPollMask; - - ASSERT (mDmaAccess != NULL); - ASSERT (mS3SaveState != NULL); - - if ((FirmwareConfigItem < -1) || (FirmwareConfigItem > MAX_UINT16)) { - return RETURN_INVALID_PARAMETER; - } - - if (NumberOfBytes > mScratchBufferSize) { - return RETURN_BAD_BUFFER_SIZE; - } - - // - // Set up a read[+select] fw_cfg DMA command. - // - mDmaAccess->Control = FW_CFG_DMA_CTL_READ; - if (FirmwareConfigItem != -1) { - mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT; - mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16; - } - - mDmaAccess->Control = SwapBytes32 (mDmaAccess->Control); - - // - // We ensured the following constraint via mScratchBufferSize in - // QemuFwCfgS3CallWhenBootScriptReady(). - // - ASSERT (NumberOfBytes <= MAX_UINT32); - mDmaAccess->Length = SwapBytes32 ((UINT32)NumberOfBytes); - - mDmaAccess->Address = SwapBytes64 ((UINTN)mScratchBuffer); - - // - // Copy mDmaAccess into the boot script. When executed at S3 resume, this - // opcode will restore it in-place. - // - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode - EfiBootScriptWidthUint8, // Width - (UINT64)(UINTN)mDmaAccess, // Address - sizeof *mDmaAccess, // Count - (VOID *)mDmaAccess // Buffer - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - // - // Append an opcode that will write the address of the fw_cfg DMA command to - // the fw_cfg DMA address register, which consists of two 32-bit IO ports. - // The second (highest address, least significant) write will start the - // transfer. - // - AccessAddress = SwapBytes64 ((UINTN)mDmaAccess); - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode - EfiBootScriptWidthUint32, // Width - (UINT64)FW_CFG_IO_DMA_ADDRESS, // Address - (UINTN)2, // Count - (VOID *)&AccessAddress // Buffer - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - // - // The following opcode will wait until the Control word reads as zero - // (transfer complete). As timeout we use MAX_UINT64 * 100ns, which is - // approximately 58494 years. - // - ControlPollData = 0; - ControlPollMask = MAX_UINT32; - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, // OpCode - EfiBootScriptWidthUint32, // Width - (UINT64)(UINTN)&mDmaAccess->Control, // Address - (VOID *)&ControlPollData, // Data - (VOID *)&ControlPollMask, // DataMask - MAX_UINT64 // Delay - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - return RETURN_SUCCESS; -} - -/** - Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, - and increase its offset. - - If the operation fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config - item to advance the offset of, expressed as - INT32. If FirmwareConfigItem is -1, no - selection is made, and the offset for the - currently selected item is increased. - Otherwise, the specified item will be - selected, and the offset increment will occur - from offset 0. - - @param[in] NumberOfBytes The number of bytes to skip in the subject - fw_cfg item. - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. - - @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is too large. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptSkipBytes ( - IN INT32 FirmwareConfigItem, - IN UINTN NumberOfBytes - ) -{ - EFI_STATUS Status; - UINT64 AccessAddress; - UINT32 ControlPollData; - UINT32 ControlPollMask; - - ASSERT (mDmaAccess != NULL); - ASSERT (mS3SaveState != NULL); - - if ((FirmwareConfigItem < -1) || (FirmwareConfigItem > MAX_UINT16)) { - return RETURN_INVALID_PARAMETER; - } - - if (NumberOfBytes > MAX_UINT32) { - return RETURN_BAD_BUFFER_SIZE; - } - - // - // Set up a skip[+select] fw_cfg DMA command. - // - mDmaAccess->Control = FW_CFG_DMA_CTL_SKIP; - if (FirmwareConfigItem != -1) { - mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT; - mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16; - } - - mDmaAccess->Control = SwapBytes32 (mDmaAccess->Control); - - mDmaAccess->Length = SwapBytes32 ((UINT32)NumberOfBytes); - mDmaAccess->Address = 0; - - // - // Copy mDmaAccess into the boot script. When executed at S3 resume, this - // opcode will restore it in-place. - // - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, // OpCode - EfiBootScriptWidthUint8, // Width - (UINT64)(UINTN)mDmaAccess, // Address - sizeof *mDmaAccess, // Count - (VOID *)mDmaAccess // Buffer - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - // - // Append an opcode that will write the address of the fw_cfg DMA command to - // the fw_cfg DMA address register, which consists of two 32-bit IO ports. - // The second (highest address, least significant) write will start the - // transfer. - // - AccessAddress = SwapBytes64 ((UINTN)mDmaAccess); - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_IO_WRITE_OPCODE, // OpCode - EfiBootScriptWidthUint32, // Width - (UINT64)FW_CFG_IO_DMA_ADDRESS, // Address - (UINTN)2, // Count - (VOID *)&AccessAddress // Buffer - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - // - // The following opcode will wait until the Control word reads as zero - // (transfer complete). As timeout we use MAX_UINT64 * 100ns, which is - // approximately 58494 years. - // - ControlPollData = 0; - ControlPollMask = MAX_UINT32; - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, // OpCode - EfiBootScriptWidthUint32, // Width - (UINT64)(UINTN)&mDmaAccess->Control, // Address - (VOID *)&ControlPollData, // Data - (VOID *)&ControlPollMask, // DataMask - MAX_UINT64 // Delay - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - return RETURN_SUCCESS; -} - -/** - Produce ACPI S3 Boot Script opcodes that check a value in ScratchBuffer. - - If the check fails during S3 resume, the boot script will hang. - - This function may only be called from the client module's - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to - QemuFwCfgS3CallWhenBootScriptReady() as Callback. - - @param[in] ScratchData Pointer to the UINT8, UINT16, UINT32 or UINT64 field - in ScratchBuffer that should be checked. The caller - is responsible for populating the field during S3 - resume, by calling QemuFwCfgS3ScriptReadBytes() ahead - of QemuFwCfgS3ScriptCheckValue(). - - ScratchData must point into ScratchBuffer, which was - allocated, and passed to Callback(), by - QemuFwCfgS3CallWhenBootScriptReady(). - - ScratchData must be aligned at ValueSize bytes. - - @param[in] ValueSize One of 1, 2, 4 or 8, specifying the size of the field - to check. - - @param[in] ValueMask The value read from ScratchData is binarily AND-ed - with ValueMask, and the result is compared against - Value. If the masked data equals Value, the check - passes, and the boot script can proceed. Otherwise, - the check fails, and the boot script hangs. - - @param[in] Value Refer to ValueMask. - - @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 - Boot Script successfully. There is no way - to undo this action. - - @retval RETURN_INVALID_PARAMETER ValueSize is invalid. - - @retval RETURN_INVALID_PARAMETER ValueMask or Value cannot be represented in - ValueSize bytes. - - @retval RETURN_INVALID_PARAMETER ScratchData is not aligned at ValueSize - bytes. - - @retval RETURN_BAD_BUFFER_SIZE The ValueSize bytes at ScratchData aren't - wholly contained in the ScratchBufferSize - bytes at ScratchBuffer. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3ScriptCheckValue ( - IN VOID *ScratchData, - IN UINT8 ValueSize, - IN UINT64 ValueMask, - IN UINT64 Value - ) -{ - EFI_BOOT_SCRIPT_WIDTH Width; - EFI_STATUS Status; - - ASSERT (mS3SaveState != NULL); - - switch (ValueSize) { - case 1: - Width = EfiBootScriptWidthUint8; - break; - - case 2: - Width = EfiBootScriptWidthUint16; - break; - - case 4: - Width = EfiBootScriptWidthUint32; - break; - - case 8: - Width = EfiBootScriptWidthUint64; - break; - - default: - return RETURN_INVALID_PARAMETER; - } - - if ((ValueSize < 8) && - ((RShiftU64 (ValueMask, ValueSize * 8) > 0) || - (RShiftU64 (Value, ValueSize * 8) > 0))) - { - return RETURN_INVALID_PARAMETER; - } - - if ((UINTN)ScratchData % ValueSize > 0) { - return RETURN_INVALID_PARAMETER; - } - - if (((UINTN)ScratchData < (UINTN)mScratchBuffer) || - ((UINTN)ScratchData > MAX_UINTN - ValueSize) || - ((UINTN)ScratchData + ValueSize > - (UINTN)mScratchBuffer + mScratchBufferSize)) - { - return RETURN_BAD_BUFFER_SIZE; - } - - // - // The following opcode will wait "until" (*ScratchData & ValueMask) reads as - // Value, considering the least significant ValueSize bytes. As timeout we - // use MAX_UINT64 * 100ns, which is approximately 58494 years. - // - Status = mS3SaveState->Write ( - mS3SaveState, // This - EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, // OpCode - Width, // Width - (UINT64)(UINTN)ScratchData, // Address - (VOID *)&Value, // Data - (VOID *)&ValueMask, // DataMask - MAX_UINT64 // Delay - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n", - gEfiCallerBaseName, - __FUNCTION__, - Status - )); - return (RETURN_STATUS)Status; - } - - return RETURN_SUCCESS; -} diff --git a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c b/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c deleted file mode 100644 index 78a8f1544..000000000 --- a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3Pei.c +++ /dev/null @@ -1,80 +0,0 @@ -/** @file - Limited functionality QemuFwCfgS3Lib instance, for PEI phase modules. - - QemuFwCfgS3Enabled() queries S3 enablement via fw_cfg. Other library APIs - will report lack of support. - - Copyright (C) 2017, Red Hat, Inc. - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include - -/** - Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for - when the production of ACPI S3 Boot Script opcodes becomes possible. - - Take ownership of the client-provided Context, and pass it to the callback - function, when the latter is invoked. - - Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon - that the client will produce in the callback function. - - @param[in] Callback FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke - when the production of ACPI S3 Boot Script - opcodes becomes possible. Callback() may be - called immediately from - QemuFwCfgS3CallWhenBootScriptReady(). - - @param[in,out] Context Client-provided data structure for the - Callback() callback function to consume. - - If Context points to dynamically allocated - memory, then Callback() must release it. - - If Context points to dynamically allocated - memory, and - QemuFwCfgS3CallWhenBootScriptReady() returns - successfully, then the caller of - QemuFwCfgS3CallWhenBootScriptReady() must - neither dereference nor even evaluate Context - any longer, as ownership of the referenced area - has been transferred to Callback(). - - @param[in] ScratchBufferSize The size of the scratch buffer that will hold, - in reserved memory, all client data read, - written, and checked by the ACPI S3 Boot Script - opcodes produced by Callback(). - - @retval RETURN_UNSUPPORTED The library instance does not support this - function. - - @retval RETURN_NOT_FOUND The fw_cfg DMA interface to QEMU is - unavailable. - - @retval RETURN_BAD_BUFFER_SIZE ScratchBufferSize is too large. - - @retval RETURN_OUT_OF_RESOURCES Memory allocation failed. - - @retval RETURN_SUCCESS Callback() has been installed, and the - ownership of Context has been transferred. - Reserved memory has been allocated for the - scratch buffer. - - A successful invocation of - QemuFwCfgS3CallWhenBootScriptReady() cannot - be rolled back. - - @return Error codes from underlying functions. -**/ -RETURN_STATUS -EFIAPI -QemuFwCfgS3CallWhenBootScriptReady ( - IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback, - IN OUT VOID *Context OPTIONAL, - IN UINTN ScratchBufferSize - ) -{ - return RETURN_UNSUPPORTED; -} diff --git a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c b/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c deleted file mode 100644 index 270f05033..000000000 --- a/Platforms/QemuQ35Pkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c +++ /dev/null @@ -1,43 +0,0 @@ -/** @file - Shared code for the PEI fw_cfg and DXE fw_cfg instances of the QemuFwCfgS3Lib - class. - - Copyright (C) 2017, Red Hat, Inc. - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include - -/** - Determine if S3 support is explicitly enabled. - - @retval TRUE If S3 support is explicitly enabled. Other functions in this - library may be called (subject to their individual - restrictions). - - FALSE Otherwise. This includes unavailability of the firmware - configuration interface. No other function in this library - must be called. -**/ -BOOLEAN -EFIAPI -QemuFwCfgS3Enabled ( - VOID - ) -{ - RETURN_STATUS Status; - FIRMWARE_CONFIG_ITEM FwCfgItem; - UINTN FwCfgSize; - UINT8 SystemStates[6]; - - Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize); - if ((Status != RETURN_SUCCESS) || (FwCfgSize != sizeof SystemStates)) { - return FALSE; - } - - QemuFwCfgSelectItem (FwCfgItem); - QemuFwCfgReadBytes (sizeof SystemStates, SystemStates); - return (BOOLEAN)(SystemStates[3] & BIT7); -} diff --git a/Platforms/QemuQ35Pkg/Library/SmmRelocationLib/SmmRelocationLib.c b/Platforms/QemuQ35Pkg/Library/SmmRelocationLib/SmmRelocationLib.c index 7e65bbf92..71effa166 100644 --- a/Platforms/QemuQ35Pkg/Library/SmmRelocationLib/SmmRelocationLib.c +++ b/Platforms/QemuQ35Pkg/Library/SmmRelocationLib/SmmRelocationLib.c @@ -155,7 +155,6 @@ SmmInitHandler ( /** Relocate SmmBases for each processor. - Execute on first boot and all S3 resumes @param[in] MpServices2 Pointer to this instance of the MpServices. @param[in] SmmRelocationStart The start address of Smm relocated memory in SMRAM. diff --git a/Platforms/QemuQ35Pkg/PlatformPei/Fv.c b/Platforms/QemuQ35Pkg/PlatformPei/Fv.c index 8cd8cacc5..60dac394f 100644 --- a/Platforms/QemuQ35Pkg/PlatformPei/Fv.c +++ b/Platforms/QemuQ35Pkg/PlatformPei/Fv.c @@ -25,19 +25,15 @@ PeiFvInitialization ( VOID ) { - BOOLEAN SecureS3Needed; - DEBUG ((DEBUG_INFO, "Platform PEI Firmware Volume Initialization\n")); // // Create a memory allocation HOB for the PEI FV. // - // Allocate as ACPI NVS is S3 is supported - // BuildMemoryAllocationHob ( PcdGet32 (PcdOvmfPeiMemFvBase), PcdGet32 (PcdOvmfPeiMemFvSize), - mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData + EfiBootServicesData ); // @@ -45,38 +41,15 @@ PeiFvInitialization ( // BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize)); - SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire); - // // Create a memory allocation HOB for the DXE FV. // - // If "secure" S3 is needed, then SEC will decompress both PEI and DXE - // firmware volumes at S3 resume too, hence we need to keep away the OS from - // DXEFV as well. Otherwise we only need to keep away DXE itself from the - // DXEFV area. - // BuildMemoryAllocationHob ( PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize), - SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData + EfiBootServicesData ); - // - // Additionally, said decompression will use temporary memory above the end - // of DXEFV, so let's keep away the OS from there too. - // - if (SecureS3Needed) { - UINT32 DxeMemFvEnd; - - DxeMemFvEnd = PcdGet32 (PcdOvmfDxeMemFvBase) + - PcdGet32 (PcdOvmfDxeMemFvSize); - BuildMemoryAllocationHob ( - DxeMemFvEnd, - PcdGet32 (PcdOvmfDecompressionScratchEnd) - DxeMemFvEnd, - EfiACPIMemoryNVS - ); - } - // // Let PEI know about the DXE FV so it can find the DXE Core // diff --git a/Platforms/QemuQ35Pkg/PlatformPei/MemDetect.c b/Platforms/QemuQ35Pkg/PlatformPei/MemDetect.c index 623df5e8d..96654e6fd 100644 --- a/Platforms/QemuQ35Pkg/PlatformPei/MemDetect.c +++ b/Platforms/QemuQ35Pkg/PlatformPei/MemDetect.c @@ -2,11 +2,9 @@ Memory Detection for Virtual Machines. Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -Module Name: + Copyright (c) Microsoft Corporation - MemDetect.c + SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -43,9 +41,6 @@ Module Name: UINT8 mPhysMemAddressWidth; -STATIC UINT32 mS3AcpiReservedMemoryBase; -STATIC UINT32 mS3AcpiReservedMemorySize; - STATIC UINT16 mQ35TsegMbytes; BOOLEAN mQ35SmramAtDefaultSmbase; @@ -70,7 +65,7 @@ Q35TsegMbytesInitialization ( // // On a QEMU machine type that does not offer an extended TSEG, the initial // write overwrites whatever value a malicious guest OS may have placed in - // the (unimplemented) register, before entering S3 or rebooting. + // the (unimplemented) register before rebooting. // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged. // // On a QEMU machine type that offers an extended TSEG, the initial write @@ -673,56 +668,31 @@ PublishPeiMemory ( LowerMemorySize -= mQ35TsegMbytes * SIZE_1MB; } - // - // If S3 is supported, then the S3 permanent PEI memory is placed next, - // downwards. Its size is primarily dictated by CpuMpPei. The formula below - // is an approximation. - // - if (mS3Supported) { - mS3AcpiReservedMemorySize = SIZE_512KB + - mMaxCpuCount * - PcdGet32 (PcdCpuApStackSize); - mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize; - LowerMemorySize = mS3AcpiReservedMemoryBase; - } + // S3 is not supported + ASSERT (mBootMode != BOOT_ON_S3_RESUME); - if (mBootMode == BOOT_ON_S3_RESUME) { - MemoryBase = mS3AcpiReservedMemoryBase; - MemorySize = mS3AcpiReservedMemorySize; - } else { - PeiMemoryCap = GetPeiMemoryCap (); - DEBUG (( - DEBUG_INFO, - "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n", - __FUNCTION__, - mPhysMemAddressWidth, - PeiMemoryCap >> 10 - )); + PeiMemoryCap = GetPeiMemoryCap (); + DEBUG (( + DEBUG_INFO, + "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n", + __func__, + mPhysMemAddressWidth, + PeiMemoryCap >> 10 + )); - // - // Determine the range of memory to use during PEI - // - // Technically we could lay the permanent PEI RAM over SEC's temporary - // decompression and scratch buffer even if "secure S3" is needed, since - // their lifetimes don't overlap. However, PeiFvInitialization() will cover - // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory - // allocation HOB, and other allocations served from the permanent PEI RAM - // shouldn't overlap with that HOB. - // - MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ? - PcdGet32 (PcdOvmfDecompressionScratchEnd) : - PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize); - MemorySize = LowerMemorySize - MemoryBase; - if (MemorySize > PeiMemoryCap) { - MemoryBase = LowerMemorySize - PeiMemoryCap; - MemorySize = PeiMemoryCap; - } + // + // Determine the range of memory to use during PEI + // + MemoryBase = PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize); + MemorySize = LowerMemorySize - MemoryBase; + if (MemorySize > PeiMemoryCap) { + MemoryBase = LowerMemorySize - PeiMemoryCap; + MemorySize = PeiMemoryCap; } // // MEMFD_BASE_ADDRESS separates the SMRAM at the default SMBASE from the - // normal boot permanent PEI RAM. Regarding the S3 boot path, the S3 - // permanent PEI RAM is located even higher. + // normal boot permanent PEI RAM. // if (FeaturePcdGet (PcdSmmSmramRequire) && mQ35SmramAtDefaultSmbase) { ASSERT (SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE <= MemoryBase); @@ -758,7 +728,7 @@ CreateSmmSmramMemoryHob ( EFI_PEI_HOB_POINTERS Hob; EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock; - SmramRanges = 2; + SmramRanges = 1; BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + (SmramRanges - 1) * sizeof (EFI_SMRAM_DESCRIPTOR); Hob.Raw = BuildGuidHob ( @@ -771,21 +741,12 @@ CreateSmmSmramMemoryHob ( SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges; // - // 1. Create first SMRAM descriptor, which contains data structures used in S3 resume. - // One page is enough for the data structure + // Create SMRAM descriptor, which is free and will be used by the SMM foundation. // SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = StartAddress; SmramHobDescriptorBlock->Descriptor[0].CpuStart = StartAddress; - SmramHobDescriptorBlock->Descriptor[0].PhysicalSize = EFI_PAGE_SIZE; - SmramHobDescriptorBlock->Descriptor[0].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE | EFI_ALLOCATED; - - // - // 2. Create second SMRAM descriptor, which is free and will be used by SMM foundation. - // - SmramHobDescriptorBlock->Descriptor[1].PhysicalStart = SmramHobDescriptorBlock->Descriptor[0].PhysicalStart + EFI_PAGE_SIZE; - SmramHobDescriptorBlock->Descriptor[1].CpuStart = SmramHobDescriptorBlock->Descriptor[0].CpuStart + EFI_PAGE_SIZE; - SmramHobDescriptorBlock->Descriptor[1].PhysicalSize = Size - EFI_PAGE_SIZE; - SmramHobDescriptorBlock->Descriptor[1].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE; + SmramHobDescriptorBlock->Descriptor[0].PhysicalSize = Size; + SmramHobDescriptorBlock->Descriptor[0].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE; } STATIC @@ -824,10 +785,12 @@ QemuInitializeRam ( VOID ) { - UINT64 LowerMemorySize; - UINT64 UpperMemorySize; - MTRR_SETTINGS MtrrSettings; - EFI_STATUS Status; + UINT32 TsegSize; + UINT64 LowerMemorySize; + UINT64 UpperMemorySize; + EFI_PHYSICAL_ADDRESS TsegBase; + MTRR_SETTINGS MtrrSettings; + EFI_STATUS Status; DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); @@ -836,65 +799,38 @@ QemuInitializeRam ( // LowerMemorySize = GetSystemMemorySizeBelow4gb (); - if (mBootMode == BOOT_ON_S3_RESUME) { - // - // Create the following memory HOB as an exception on the S3 boot path. - // - // Normally we'd create memory HOBs only on the normal boot path. However, - // CpuMpPei specifically needs such a low-memory HOB on the S3 path as - // well, for "borrowing" a subset of it temporarily, for the AP startup - // vector. - // - // CpuMpPei saves the original contents of the borrowed area in permanent - // PEI RAM, in a backup buffer allocated with the normal PEI services. - // CpuMpPei restores the original contents ("returns" the borrowed area) at - // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before - // transferring control to the OS's wakeup vector in the FACS. + // + // Create memory HOBs + // + QemuInitializeRamBelow1gb (); + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + TsegSize = mQ35TsegMbytes * SIZE_1MB; + TsegBase = LowerMemorySize - TsegSize; + AddMemoryRangeHob (BASE_1MB, TsegBase); + AddReservedMemoryBaseSizeHob ( + TsegBase, + TsegSize, + TRUE + ); // - // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to - // restore the original contents. Furthermore, we expect all such PEIMs - // (CpuMpPei included) to claim the borrowed areas by producing memory - // allocation HOBs, and to honor preexistent memory allocation HOBs when - // looking for an area to borrow. + // Create gEfiSmmSmramMemoryGuid HOB // - QemuInitializeRamBelow1gb (); + CreateSmmSmramMemoryHob (TsegBase, TsegSize); } else { - // - // Create memory HOBs - // - QemuInitializeRamBelow1gb (); - - if (FeaturePcdGet (PcdSmmSmramRequire)) { - UINT32 TsegSize; - EFI_PHYSICAL_ADDRESS TsegBase; - - TsegSize = mQ35TsegMbytes * SIZE_1MB; - TsegBase = LowerMemorySize - TsegSize; - AddMemoryRangeHob (BASE_1MB, TsegBase); - AddReservedMemoryBaseSizeHob ( - TsegBase, - TsegSize, - TRUE - ); - // - // Create gEfiSmmSmramMemoryGuid HOB - // - CreateSmmSmramMemoryHob (TsegBase, TsegSize); - } else { - AddMemoryRangeHob (BASE_1MB, LowerMemorySize); - } + AddMemoryRangeHob (BASE_1MB, LowerMemorySize); + } - // - // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM - // entries. Otherwise, create a single memory HOB with the flat >=4GB - // memory size read from the CMOS. - // - Status = ScanOrAdd64BitE820Ram (TRUE, NULL, NULL); - if (EFI_ERROR (Status)) { - UpperMemorySize = GetSystemMemorySizeAbove4gb (); - if (UpperMemorySize != 0) { - AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize); - } + // + // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM + // entries. Otherwise, create a single memory HOB with the flat >=4GB + // memory size read from the CMOS. + // + Status = ScanOrAdd64BitE820Ram (TRUE, NULL, NULL); + if (EFI_ERROR (Status)) { + UpperMemorySize = GetSystemMemorySizeAbove4gb (); + if (UpperMemorySize != 0) { + AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize); } } @@ -959,151 +895,57 @@ InitializeRamRegions ( VOID ) { - QemuInitializeRam (); + UINT32 TsegSize; + QemuInitializeRam (); SevInitializeRam (); - if (mS3Supported && (mBootMode != BOOT_ON_S3_RESUME)) { - // - // This is the memory range that will be used for PEI on S3 resume - // - BuildMemoryAllocationHob ( - mS3AcpiReservedMemoryBase, - mS3AcpiReservedMemorySize, - EfiACPIMemoryNVS - ); + // S3 is not supported. + ASSERT (mBootMode != BOOT_ON_S3_RESUME); + if (FeaturePcdGet (PcdSmmSmramRequire)) { // - // Cover the initial RAM area used as stack and temporary PEI heap. - // - // This is reserved as ACPI NVS so it can be used on S3 resume. + // Make sure the TSEG area that we reported as a reserved memory resource + // cannot be used for reserved memory allocations. // + TsegSize = mQ35TsegMbytes * SIZE_1MB; BuildMemoryAllocationHob ( - PcdGet32 (PcdSecPeiTemporaryRamBase), - PcdGet32 (PcdSecPeiTemporaryRamSize), - EfiACPIMemoryNVS + GetSystemMemorySizeBelow4gb () - TsegSize, + TsegSize, + EfiReservedMemoryType ); - // - // SEC stores its table of GUIDed section handlers here. + // Similarly, allocate away the (already reserved) SMRAM at the default + // SMBASE, if it exists. // - BuildMemoryAllocationHob ( - PcdGet64 (PcdGuidedExtractHandlerTableAddress), - PcdGet32 (PcdGuidedExtractHandlerTableSize), - EfiACPIMemoryNVS - ); + if (mQ35SmramAtDefaultSmbase) { + BuildMemoryAllocationHob ( + SMM_DEFAULT_SMBASE, + MCH_DEFAULT_SMBASE_SIZE, + EfiReservedMemoryType + ); + } + } #ifdef MDE_CPU_X64 + if (FixedPcdGet32 (PcdOvmfWorkAreaSize) != 0) { // - // Reserve the initial page tables built by the reset vector code. + // Reserve the work area. // - // Since this memory range will be used by the Reset Vector on S3 - // resume, it must be reserved as ACPI NVS. + // This range was originally used by the Reset Vector on S3 + // resume and in that case, it would be allocated as ACPI NVS. + // + // S3 is no longer supported. However, drivers might still write to the + // work area. We ought to prevent DXE from serving allocation requests + // such that they would overlap the work area. The area is also allocated + // as boot services data to prevent impact on OS mapped memory. // BuildMemoryAllocationHob ( - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase), - (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize), - EfiACPIMemoryNVS + (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase), + (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize), + EfiBootServicesData ); - - if (MemEncryptSevEsIsEnabled ()) { - // - // If SEV-ES is enabled, reserve the GHCB-related memory area. This - // includes the extra page table used to break down the 2MB page - // mapping into 4KB page entries where the GHCB resides and the - // GHCB area itself. - // - // Since this memory range will be used by the Reset Vector on S3 - // resume, it must be reserved as ACPI NVS. - // - BuildMemoryAllocationHob ( - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableBase), - (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableSize), - EfiACPIMemoryNVS - ); - BuildMemoryAllocationHob ( - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBase), - (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbSize), - EfiACPIMemoryNVS - ); - BuildMemoryAllocationHob ( - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase), - (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupSize), - EfiACPIMemoryNVS - ); - } - - #endif } - if (mBootMode != BOOT_ON_S3_RESUME) { - if (!FeaturePcdGet (PcdSmmSmramRequire)) { - // - // Reserve the lock box storage area - // - // Since this memory range will be used on S3 resume, it must be - // reserved as ACPI NVS. - // - // If S3 is unsupported, then various drivers might still write to the - // LockBox area. We ought to prevent DXE from serving allocation requests - // such that they would overlap the LockBox storage. - // - ZeroMem ( - (VOID *)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase), - (UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize) - ); - BuildMemoryAllocationHob ( - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase), - (UINT64)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize), - mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData - ); - } - - if (FeaturePcdGet (PcdSmmSmramRequire)) { - UINT32 TsegSize; - - // - // Make sure the TSEG area that we reported as a reserved memory resource - // cannot be used for reserved memory allocations. - // - TsegSize = mQ35TsegMbytes * SIZE_1MB; - BuildMemoryAllocationHob ( - GetSystemMemorySizeBelow4gb () - TsegSize, - TsegSize, - EfiReservedMemoryType - ); - // - // Similarly, allocate away the (already reserved) SMRAM at the default - // SMBASE, if it exists. - // - if (mQ35SmramAtDefaultSmbase) { - BuildMemoryAllocationHob ( - SMM_DEFAULT_SMBASE, - MCH_DEFAULT_SMBASE_SIZE, - EfiReservedMemoryType - ); - } - } - - #ifdef MDE_CPU_X64 - if (FixedPcdGet32 (PcdOvmfWorkAreaSize) != 0) { - // - // Reserve the work area. - // - // Since this memory range will be used by the Reset Vector on S3 - // resume, it must be reserved as ACPI NVS. - // - // If S3 is unsupported, then various drivers might still write to the - // work area. We ought to prevent DXE from serving allocation requests - // such that they would overlap the work area. - // - BuildMemoryAllocationHob ( - (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase), - (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize), - mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData - ); - } - #endif - } } diff --git a/Platforms/QemuQ35Pkg/PlatformPei/Platform.c b/Platforms/QemuQ35Pkg/PlatformPei/Platform.c index c486da992..0be839775 100644 --- a/Platforms/QemuQ35Pkg/PlatformPei/Platform.c +++ b/Platforms/QemuQ35Pkg/PlatformPei/Platform.c @@ -3,6 +3,7 @@ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
Copyright (c) 2011, Andrei Warkentin + Copyright (c) Microsoft Corporation SPDX-License-Identifier: BSD-2-Clause-Patent @@ -27,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -55,8 +55,6 @@ UINT16 mHostBridgeDevId; EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION; -BOOLEAN mS3Supported = FALSE; - UINT32 mMaxCpuCount; VOID @@ -416,8 +414,7 @@ MiscInitialization ( // // Build the CPU HOB with guest RAM size dependent address width and 16-bits - // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during - // S3 resume as well, so we build it unconditionally.) + // of IO space. // BuildCpuHob (mPhysMemAddressWidth, 16); @@ -516,7 +513,9 @@ BootModeInitialization ( EFI_STATUS Status; if (CmosRead8 (0xF) == 0xFE) { - mBootMode = BOOT_ON_S3_RESUME; + // S3 is not supported. Do not modify the boot mode. + DEBUG ((DEBUG_ERROR, "[%a] S3 is enabled in CMOS, but not supported!\n", __func__)); + ASSERT (FALSE); } CmosWrite8 (0xF, 0x00); @@ -578,35 +577,6 @@ DebugDumpCmos ( } } -VOID -S3Verification ( - VOID - ) -{ - #if defined (MDE_CPU_X64) - if (FeaturePcdGet (PcdSmmSmramRequire) && mS3Supported) { - DEBUG (( - DEBUG_ERROR, - "%a: S3Resume2Pei doesn't support X64 PEI + SMM yet.\n", - __FUNCTION__ - )); - DEBUG (( - DEBUG_ERROR, - "%a: Please disable S3 on the QEMU command line (see the README),\n", - __FUNCTION__ - )); - DEBUG (( - DEBUG_ERROR, - "%a: or build OVMF with \"QemuQ35PkgIa32X64.dsc\".\n", - __FUNCTION__ - )); - ASSERT (FALSE); - CpuDeadLoop (); - } - - #endif -} - VOID Q35BoardVerification ( VOID @@ -818,7 +788,6 @@ InitializePlatform ( IN CONST EFI_PEI_SERVICES **PeiServices ) { - EFI_STATUS Status; // MU_CHANGE START DXE_MEMORY_PROTECTION_SETTINGS DxeSettings; MM_MEMORY_PROTECTION_SETTINGS MmSettings; @@ -852,14 +821,6 @@ InitializePlatform ( DebugDumpCmos (); - if (QemuFwCfgS3Enabled ()) { - DEBUG ((DEBUG_INFO, "S3 support was detected on QEMU\n")); - mS3Supported = TRUE; - Status = PcdSetBoolS (PcdAcpiS3Enable, TRUE); - ASSERT_EFI_ERROR (Status); - } - - S3Verification (); BootModeInitialization (); AddressWidthInitialization (); @@ -882,17 +843,15 @@ InitializePlatform ( InitializeRamRegions (); - if (mBootMode != BOOT_ON_S3_RESUME) { - if (!FeaturePcdGet (PcdSmmSmramRequire)) { - ReserveEmuVariableNvStore (); - } - - PeiFvInitialization (); - MemTypeInfoInitialization (); - MemMapInitialization (); - NoexecDxeInitialization (); + if (!FeaturePcdGet (PcdSmmSmramRequire)) { + ReserveEmuVariableNvStore (); } + PeiFvInitialization (); + MemTypeInfoInitialization (); + MemMapInitialization (); + NoexecDxeInitialization (); + InstallClearCacheCallback (); AmdSevInitialize (); MiscInitialization (); diff --git a/Platforms/QemuQ35Pkg/PlatformPei/Platform.h b/Platforms/QemuQ35Pkg/PlatformPei/Platform.h index e2645fa33..3ca143c96 100644 --- a/Platforms/QemuQ35Pkg/PlatformPei/Platform.h +++ b/Platforms/QemuQ35Pkg/PlatformPei/Platform.h @@ -114,8 +114,6 @@ SevInitializeRam ( VOID ); -extern BOOLEAN mS3Supported; - extern UINT8 mPhysMemAddressWidth; extern UINT32 mMaxCpuCount; diff --git a/Platforms/QemuQ35Pkg/PlatformPei/PlatformPei.inf b/Platforms/QemuQ35Pkg/PlatformPei/PlatformPei.inf index 77ef1f480..bc2a7a7f5 100644 --- a/Platforms/QemuQ35Pkg/PlatformPei/PlatformPei.inf +++ b/Platforms/QemuQ35Pkg/PlatformPei/PlatformPei.inf @@ -63,7 +63,6 @@ PeiServicesTablePointerLib PeimEntryPoint QemuFwCfgLib - QemuFwCfgS3Lib QemuFwCfgSimpleParserLib MtrrLib MemEncryptSevLib @@ -83,8 +82,6 @@ gUefiQemuQ35PkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize gUefiQemuQ35PkgTokenSpaceGuid.PcdOvmfSecGhcbBase gUefiQemuQ35PkgTokenSpaceGuid.PcdOvmfSecGhcbSize - gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase - gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize gUefiQemuQ35PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize gQemuPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId gUefiQemuQ35PkgTokenSpaceGuid.PcdPciIoBase @@ -104,7 +101,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable # gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack MU_CHANGE - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize diff --git a/Platforms/QemuQ35Pkg/QemuQ35Pkg.dec b/Platforms/QemuQ35Pkg/QemuQ35Pkg.dec index 930615396..de829cf07 100644 --- a/Platforms/QemuQ35Pkg/QemuQ35Pkg.dec +++ b/Platforms/QemuQ35Pkg/QemuQ35Pkg.dec @@ -29,10 +29,6 @@ # instances in ArmVirtPkg and OvmfPkg. PciHostBridgeUtilityLib|Include/Library/PciHostBridgeUtilityLib.h - ## @libraryclass S3 support for QEMU fw_cfg - # - QemuFwCfgS3Lib|Include/Library/QemuFwCfgS3Lib.h - ## @libraryclass Parse the contents of named fw_cfg files as simple # (scalar) data types. QemuFwCfgSimpleParserLib|Include/Library/QemuFwCfgSimpleParserLib.h diff --git a/Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc b/Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc index 173b552ec..243b3b5c8 100644 --- a/Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc +++ b/Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc @@ -184,7 +184,7 @@ # Security Libraries SecurityManagementLib |MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf SecurityLockAuditLib |MdeModulePkg/Library/SecurityLockAuditDebugMessageLib/SecurityLockAuditDebugMessageLib.inf ##MU_CHANGE - LockBoxLib |QemuPkg/Library/LockBoxLib/LockBoxBaseLib.inf + LockBoxLib |MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf PlatformSecureLib |SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf PasswordStoreLib |MsCorePkg/Library/PasswordStoreLibNull/PasswordStoreLibNull.inf PasswordPolicyLib |OemPkg/Library/PasswordPolicyLib/PasswordPolicyLib.inf @@ -229,7 +229,6 @@ # Power/Thermal/Power State Libraries MsNVBootReasonLib |OemPkg/Library/MsNVBootReasonLib/MsNVBootReasonLib.inf # interface on Reboot Reason non volatile variables ResetUtilityLib |MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf - S3BootScriptLib |MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf PowerServicesLib |PcBdsPkg/Library/PowerServicesLibNull/PowerServicesLibNull.inf ThermalServicesLib |PcBdsPkg/Library/ThermalServicesLibNull/ThermalServicesLibNull.inf MsPlatformPowerCheckLib |PcBdsPkg/Library/MsPlatformPowerCheckLibNull/MsPlatformPowerCheckLibNull.inf @@ -380,12 +379,10 @@ PeimEntryPoint |MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf MsPlatformEarlyGraphicsLib |MsGraphicsPkg/Library/MsEarlyGraphicsLibNull/Pei/MsEarlyGraphicsLibNull.inf MsUiThemeLib |MsGraphicsPkg/Library/MsUiThemeLib/Pei/MsUiThemeLib.inf - LockBoxLib |MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf ResourcePublicationLib |MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib |MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf CpuExceptionHandlerLib |UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf MpInitLib |UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf - QemuFwCfgS3Lib |QemuQ35Pkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf PcdLib |MdePkg/Library/PeiPcdLib/PeiPcdLib.inf QemuFwCfgLib |QemuQ35Pkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf PcdDatabaseLoaderLib |MdeModulePkg/Library/PcdDatabaseLoaderLib/Pei/PcdDatabaseLoaderLibPei.inf @@ -418,7 +415,6 @@ MemoryAllocationLib |MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf CpuExceptionHandlerLib |UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf ReportStatusCodeLib |MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf - QemuFwCfgS3Lib |QemuQ35Pkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf MmUnblockMemoryLib |MmSupervisorPkg/Library/MmSupervisorUnblockMemoryLib/MmSupervisorUnblockMemoryLibDxe.inf # Non DXE Core but everything else @@ -455,7 +451,6 @@ [LibraryClasses.common.DXE_DRIVER] PlatformBootManagerLib|MsCorePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf PlatformBmPrintScLib|QemuPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf - LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf QemuLoadImageLib|QemuQ35Pkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf UpdateFacsHardwareSignatureLib|OemPkg/Library/UpdateFacsHardwareSignatureLib/UpdateFacsHardwareSignatureLib.inf @@ -486,7 +481,6 @@ SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf - LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf AdvLoggerAccessLib|AdvLoggerPkg/Library/AdvLoggerSmmAccessLib/AdvLoggerSmmAccessLib.inf [LibraryClasses.common.SMM_CORE] @@ -523,7 +517,6 @@ MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf HobLib|MmSupervisorPkg/Library/StandaloneMmHobLibSyscall/StandaloneMmHobLibSyscall.inf MemLib|MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorMemLibSyscall.inf - LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxStandaloneMmLib.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf HwResetSystemLib|QemuQ35Pkg/Library/ResetSystemLib/StandaloneMmResetSystemLib.inf @@ -926,13 +919,6 @@ QemuQ35Pkg/Library/ResetSystemLib/StandaloneMmResetSystemLib.inf NULL|StandaloneMmPkg/Library/PeiStandaloneMmHobProductionLib/PeiStandaloneMmHobProductionLib.inf } - UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf { - - - LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf - - } - MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf MdeModulePkg/Universal/Variable/Pei/VariablePei.inf QemuQ35Pkg/SmmAccess/SmmAccessPei.inf @@ -1176,8 +1162,6 @@ QemuQ35Pkg/Library/ResetSystemLib/StandaloneMmResetSystemLib.inf # MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatformDxe.inf - MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf - MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf # @@ -1288,9 +1272,6 @@ QemuQ35Pkg/Library/ResetSystemLib/StandaloneMmResetSystemLib.inf } QemuQ35Pkg/IoMmuDxe/IoMmuDxe.inf - - QemuQ35Pkg/CpuS3DataDxe/CpuS3DataDxe.inf - AdvLoggerPkg/AdvancedFileLogger/AdvancedFileLogger.inf MsCorePkg/Universal/StatusCodeHandler/Serial/Dxe/SerialStatusCodeHandlerDxe.inf MsCorePkg/MuCryptoDxe/MuCryptoDxe.inf @@ -1419,11 +1400,6 @@ QemuQ35Pkg/Library/ResetSystemLib/StandaloneMmResetSystemLib.inf # Privileged drivers (DXE_SMM_DRIVER modules) # UefiCpuPkg/CpuIo2Smm/CpuIo2StandaloneMm.inf - MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf { - - LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf - } - QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.inf diff --git a/Platforms/QemuQ35Pkg/QemuQ35Pkg.fdf b/Platforms/QemuQ35Pkg/QemuQ35Pkg.fdf index 86320b723..6002dc52f 100644 --- a/Platforms/QemuQ35Pkg/QemuQ35Pkg.fdf +++ b/Platforms/QemuQ35Pkg/QemuQ35Pkg.fdf @@ -153,9 +153,6 @@ NumBlocks = 0xD0 gUefiQemuQ35PkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiQemuQ35PkgTokenSpaceGuid.PcdOvmfSecPageTablesSize 0x006000|0x001000 -gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize - -0x007000|0x001000 gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiQemuQ35PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize 0x010000|0x010000 @@ -236,7 +233,6 @@ INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf INF SecurityPkg/RandomNumberGenerator/RngPei/RngPei.inf INF QemuQ35Pkg/PlatformPei/PlatformPei.inf INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf -INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf @@ -381,8 +377,6 @@ INF QemuQ35Pkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf INF QemuQ35Pkg/AcpiPlatformDxe/AcpiPlatformDxe.inf -INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf -INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf INF FatPkg/EnhancedFatDxe/Fat.inf @@ -445,7 +439,6 @@ INF QemuQ35Pkg/QemuVideoDxe/QemuVideoDxe.inf INF QemuQ35Pkg/QemuRamfbDxe/QemuRamfbDxe.inf INF QemuQ35Pkg/IoMmuDxe/IoMmuDxe.inf -INF QemuQ35Pkg/CpuS3DataDxe/CpuS3DataDxe.inf !if $(SMM_ENABLED) == TRUE INF QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.inf !if $(PEI_MM_IPL_ENABLED) == TRUE @@ -459,7 +452,6 @@ INF QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.inf !endif INF MmSupervisorPkg/Core/MmSupervisorCore.inf INF UefiCpuPkg/CpuIo2Smm/CpuIo2StandaloneMm.inf -INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf !endif # diff --git a/Platforms/QemuQ35Pkg/Sec/SecMain.c b/Platforms/QemuQ35Pkg/Sec/SecMain.c index 6aff88870..4ff3a8d21 100644 --- a/Platforms/QemuQ35Pkg/Sec/SecMain.c +++ b/Platforms/QemuQ35Pkg/Sec/SecMain.c @@ -527,16 +527,6 @@ IsS3Resume ( return (CmosRead8 (0xF) == 0xFE); } -STATIC -EFI_STATUS -GetS3ResumePeiFv ( - IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv - ) -{ - *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfPeiMemFvBase); - return EFI_SUCCESS; -} - /** Locates the PEI Core entry point address @@ -559,28 +549,12 @@ FindPeiCoreImageBase ( *PeiCoreImageBase = 0; S3Resume = IsS3Resume (); - if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) { - // - // A malicious runtime OS may have injected something into our previously - // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required. - // - DEBUG ((DEBUG_VERBOSE, "SEC: S3 resume\n")); - GetS3ResumePeiFv (BootFv); - } else { - // - // We're either not resuming, or resuming "securely" -- we'll decompress - // both PEI FV and DXE FV from pristine flash. - // - DEBUG (( - DEBUG_VERBOSE, - "SEC: %a\n", - S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot" - )); - FindMainFv (BootFv); - - DecompressMemFvs (BootFv); - } + // S3 is not supported + ASSERT (!S3Resume); + + FindMainFv (BootFv); + DecompressMemFvs (BootFv); FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase); } diff --git a/Platforms/QemuQ35Pkg/SmmAccess/SmmAccessPei.c b/Platforms/QemuQ35Pkg/SmmAccess/SmmAccessPei.c index 105e89daa..2a5b10dc4 100644 --- a/Platforms/QemuQ35Pkg/SmmAccess/SmmAccessPei.c +++ b/Platforms/QemuQ35Pkg/SmmAccess/SmmAccessPei.c @@ -2,10 +2,8 @@ A PEIM with the following responsibilities: - - verify & configure the Q35 TSEG in the entry point, - - provide SMRAM access by producing PEI_SMM_ACCESS_PPI, - - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose - it via the gEfiAcpiVariableGuid GUID HOB. + - verify & configure the Q35 TSEG in the entry point + - provide SMRAM access by producing PEI_SMM_ACCESS_PPI This PEIM runs from RAM, so we can write to variables with static storage duration. @@ -17,7 +15,6 @@ **/ -#include #include // MU_CHANGE: Added support for Standalone MM mode #include #include @@ -248,7 +245,6 @@ SmmAccessPeiEntryPoint ( EFI_STATUS Status; UINTN SmramMapSize; EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount]; - VOID *GuidHob; // // This module should only be included if SMRAM support is required. @@ -403,31 +399,12 @@ SmmAccessPeiEntryPoint ( } DEBUG_CODE_END (); - GuidHob = BuildGuidHob ( - &gEfiAcpiVariableGuid, - sizeof SmramMap[DescIdxSmmS3ResumeState] - ); - if (GuidHob == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - CopyMem ( - GuidHob, - &SmramMap[DescIdxSmmS3ResumeState], - sizeof SmramMap[DescIdxSmmS3ResumeState] - ); - // // SmramAccessLock() depends on "mQ35SmramAtDefaultSmbase"; init the latter // just before exposing the former via PEI_SMM_ACCESS_PPI.Lock(). // InitQ35SmramAtDefaultSmbase (); - // - // We're done. The next step should succeed, but even if it fails, we can't - // roll back the above BuildGuidHob() allocation, because PEI doesn't support - // releasing memory. - // return PeiServicesInstallPpi (mPpiList); WrongConfig: diff --git a/Platforms/QemuQ35Pkg/SmmAccess/SmmAccessPei.inf b/Platforms/QemuQ35Pkg/SmmAccess/SmmAccessPei.inf index 0b60dc44e..a373d8c93 100644 --- a/Platforms/QemuQ35Pkg/SmmAccess/SmmAccessPei.inf +++ b/Platforms/QemuQ35Pkg/SmmAccess/SmmAccessPei.inf @@ -1,10 +1,8 @@ ## @file # A PEIM with the following responsibilities: # -# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI, -# - verify & configure the Q35 TSEG in the entry point, -# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose -# it via the gEfiAcpiVariableGuid GUIDed HOB. +# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI +# - verify & configure the Q35 TSEG in the entry point # # Copyright (C) 2013, 2015, Red Hat, Inc. # diff --git a/Platforms/QemuQ35Pkg/SmmAccess/SmramInternal.c b/Platforms/QemuQ35Pkg/SmmAccess/SmramInternal.c index d391ddc9a..50c401e5f 100644 --- a/Platforms/QemuQ35Pkg/SmmAccess/SmramInternal.c +++ b/Platforms/QemuQ35Pkg/SmmAccess/SmramInternal.c @@ -8,7 +8,6 @@ **/ -#include #include #include #include @@ -196,18 +195,6 @@ SmramAccessGetCapabilities ( (LockState ? EFI_SMRAM_LOCKED : 0) | EFI_CACHEABLE; - // - // The first region hosts an SMM_S3_RESUME_STATE object. It is located at the - // start of TSEG. We round up the size to whole pages, and we report it as - // EFI_ALLOCATED, so that the SMM_CORE stays away from it. - // - SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase; - SmramMap[DescIdxSmmS3ResumeState].CpuStart = TsegMemoryBase; - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize = - EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (SMM_S3_RESUME_STATE))); - SmramMap[DescIdxSmmS3ResumeState].RegionState = - CommonRegionState | EFI_ALLOCATED; - // // Get the TSEG size bits from the ESMRAMC register. // @@ -217,16 +204,13 @@ SmramAccessGetCapabilities ( // // The second region is the main one, following the first. // - SmramMap[DescIdxMain].PhysicalStart = - SmramMap[DescIdxSmmS3ResumeState].PhysicalStart + - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize; - SmramMap[DescIdxMain].CpuStart = SmramMap[DescIdxMain].PhysicalStart; - SmramMap[DescIdxMain].PhysicalSize = + SmramMap[DescIdxMain].PhysicalStart = TsegMemoryBase; + SmramMap[DescIdxMain].CpuStart = SmramMap[DescIdxMain].PhysicalStart; + SmramMap[DescIdxMain].PhysicalSize = (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB : TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB : TsegSizeBits == MCH_ESMRAMC_TSEG_1MB ? SIZE_1MB : - mQ35TsegMbytes * SIZE_1MB) - - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize; + mQ35TsegMbytes * SIZE_1MB); SmramMap[DescIdxMain].RegionState = CommonRegionState; return EFI_SUCCESS; diff --git a/Platforms/QemuQ35Pkg/SmmAccess/SmramInternal.h b/Platforms/QemuQ35Pkg/SmmAccess/SmramInternal.h index e0afb6a65..f83081463 100644 --- a/Platforms/QemuQ35Pkg/SmmAccess/SmramInternal.h +++ b/Platforms/QemuQ35Pkg/SmmAccess/SmramInternal.h @@ -3,6 +3,7 @@ Functions and types shared by the SMM accessor PEI and DXE modules. Copyright (C) 2015, Red Hat, Inc. + Copyright (c) Microsoft Corporation SPDX-License-Identifier: BSD-2-Clause-Patent @@ -14,18 +15,11 @@ #include // -// We'll have two SMRAM ranges. -// -// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to be -// filled in by the CPU SMM driver during normal boot, for the PEI instance of -// the LockBox library (which will rely on the object during S3 resume). -// -// The other SMRAM range is the main one, for the SMM core and the SMM drivers. +// A single MMRAM range is used for both the MM core and MM drivers. // typedef enum { - DescIdxSmmS3ResumeState = 0, - DescIdxMain = 1, - DescIdxCount = 2 + DescIdxMain = 0, + DescIdxCount = 1 } DESCRIPTOR_INDEX; // diff --git a/Platforms/QemuQ35Pkg/SmmControl2Dxe/MmControlPei.c b/Platforms/QemuQ35Pkg/SmmControl2Dxe/MmControlPei.c index 59d184c83..94899ecdd 100644 --- a/Platforms/QemuQ35Pkg/SmmControl2Dxe/MmControlPei.c +++ b/Platforms/QemuQ35Pkg/SmmControl2Dxe/MmControlPei.c @@ -29,16 +29,12 @@ #include #include #include -#include #include #include "SmiFeatures.h" // -// The absolute IO port address of the SMI Control and Enable Register. It is -// only used to carry information from the entry point function to the -// S3SaveState protocol installation callback, strictly before the runtime -// phase. +// The absolute IO port address of the SMI Control and Enable Register. // STATIC UINTN mSmiEnable; diff --git a/Platforms/QemuQ35Pkg/SmmControl2Dxe/MmControlPei.inf b/Platforms/QemuQ35Pkg/SmmControl2Dxe/MmControlPei.inf index b6310b870..c7efa1dc7 100644 --- a/Platforms/QemuQ35Pkg/SmmControl2Dxe/MmControlPei.inf +++ b/Platforms/QemuQ35Pkg/SmmControl2Dxe/MmControlPei.inf @@ -52,7 +52,6 @@ PcdLib PciLib QemuFwCfgLib - QemuFwCfgS3Lib PeimEntryPoint [Ppis] diff --git a/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmiFeatures.c b/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmiFeatures.c index f12d34b3b..4d6b9b396 100644 --- a/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmiFeatures.c +++ b/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmiFeatures.c @@ -3,6 +3,7 @@ accordingly. Copyright (C) 2016-2017, Red Hat, Inc. + Copyright (c) Microsoft Corporation SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -13,7 +14,6 @@ #include #include #include -#include #include "SmiFeatures.h" @@ -35,41 +35,27 @@ // #define ICH9_LPC_SMI_F_CPU_HOT_UNPLUG BIT2 -// -// Provides a scratch buffer (allocated in EfiReservedMemoryType type memory) -// for the S3 boot script fragment to write to and read from. -// -#pragma pack (1) -typedef union { - UINT64 Features; - UINT8 FeaturesOk; -} SCRATCH_BUFFER; -#pragma pack () - // // These carry the selector keys of the "etc/smi/requested-features" and -// "etc/smi/features-ok" fw_cfg files from NegotiateSmiFeatures() to -// AppendFwCfgBootScript(). +// "etc/smi/features-ok" fw_cfg files from NegotiateSmiFeatures(). // STATIC FIRMWARE_CONFIG_ITEM mRequestedFeaturesItem; STATIC FIRMWARE_CONFIG_ITEM mFeaturesOkItem; // -// Carries the negotiated SMI features from NegotiateSmiFeatures() to -// AppendFwCfgBootScript(). +// Holds the negotiated SMI features from NegotiateSmiFeatures(). // STATIC UINT64 mSmiFeatures; /** Negotiate SMI features with QEMU. - @retval FALSE If SMI feature negotiation is not supported by QEMU. This is - not an error, it just means that SaveSmiFeatures() should not - be called. + @retval FALSE It is not an error if SMI feature negotiation is not supported + by QEMU. It just means the data cannot be used. @retval TRUE SMI feature negotiation is supported, and it has completed - successfully as well. (Failure to negotiate is a fatal error - and the function never returns in that case.) + successfully as well (failure to negotiate is a fatal error + and the function never returns in that case). **/ BOOLEAN NegotiateSmiFeatures ( @@ -237,96 +223,3 @@ NegotiateSmiFeatures ( // return FALSE; } - -/** - FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION provided to QemuFwCfgS3Lib. -**/ -STATIC -VOID -EFIAPI -AppendFwCfgBootScript ( - IN OUT VOID *Context OPTIONAL, - IN OUT VOID *ExternalScratchBuffer - ) -{ - SCRATCH_BUFFER *ScratchBuffer; - RETURN_STATUS Status; - - ScratchBuffer = ExternalScratchBuffer; - - // - // Write the negotiated feature bitmap into "etc/smi/requested-features". - // - ScratchBuffer->Features = mSmiFeatures; - Status = QemuFwCfgS3ScriptWriteBytes ( - mRequestedFeaturesItem, - sizeof ScratchBuffer->Features - ); - if (RETURN_ERROR (Status)) { - goto FatalError; - } - - // - // Read back "etc/smi/features-ok". This invokes the feature validation & - // lockdown. (The validation succeeded at first boot.) - // - Status = QemuFwCfgS3ScriptReadBytes ( - mFeaturesOkItem, - sizeof ScratchBuffer->FeaturesOk - ); - if (RETURN_ERROR (Status)) { - goto FatalError; - } - - // - // If "etc/smi/features-ok" read as 1, we're good. Otherwise, hang the S3 - // resume process. - // - Status = QemuFwCfgS3ScriptCheckValue ( - &ScratchBuffer->FeaturesOk, - sizeof ScratchBuffer->FeaturesOk, - MAX_UINT8, - 1 - ); - if (RETURN_ERROR (Status)) { - goto FatalError; - } - - DEBUG (( - DEBUG_VERBOSE, - "%a: SMI feature negotiation boot script saved\n", - __FUNCTION__ - )); - return; - -FatalError: - ASSERT (FALSE); - CpuDeadLoop (); -} - -/** - Append a boot script fragment that will re-select the previously negotiated - SMI features during S3 resume. -**/ -VOID -SaveSmiFeatures ( - VOID - ) -{ - RETURN_STATUS Status; - - // - // We are already running at TPL_CALLBACK, on the stack of - // OnS3SaveStateInstalled(). But that's okay, we can easily queue more - // notification functions while executing a notification function. - // - Status = QemuFwCfgS3CallWhenBootScriptReady ( - AppendFwCfgBootScript, - NULL, - sizeof (SCRATCH_BUFFER) - ); - if (RETURN_ERROR (Status)) { - ASSERT (FALSE); - CpuDeadLoop (); - } -} diff --git a/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmiFeatures.h b/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmiFeatures.h index fd1d50736..24a1773d3 100644 --- a/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmiFeatures.h +++ b/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmiFeatures.h @@ -3,6 +3,7 @@ accordingly. Copyright (C) 2016-2017, Red Hat, Inc. + Copyright (c) Microsoft Corporation SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -10,31 +11,19 @@ #ifndef __SMI_FEATURES_H__ #define __SMI_FEATURES_H__ -#include - /** Negotiate SMI features with QEMU. - @retval FALSE If SMI feature negotiation is not supported by QEMU. This is - not an error, it just means that SaveSmiFeatures() should not - be called. + @retval FALSE It is not an error if SMI feature negotiation is not supported + by QEMU. It just means the data cannot be used. @retval TRUE SMI feature negotiation is supported, and it has completed - successfully as well. (Failure to negotiate is a fatal error - and the function never returns in that case.) + successfully as well (failure to negotiate is a fatal error + and the function never returns in that case). **/ BOOLEAN NegotiateSmiFeatures ( VOID ); -/** - Append a boot script fragment that will re-select the previously negotiated - SMI features during S3 resume. -**/ -VOID -SaveSmiFeatures ( - VOID - ); - #endif diff --git a/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.c b/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.c index d2ca21c62..d4206be54 100644 --- a/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.c +++ b/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.c @@ -14,6 +14,7 @@ Copyright (C) 2013, 2015, Red Hat, Inc.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation SPDX-License-Identifier: BSD-2-Clause-Patent @@ -26,42 +27,20 @@ #include #include #include -#include #include #include "SmiFeatures.h" // -// Forward declaration. -// -STATIC -VOID -EFIAPI -OnS3SaveStateInstalled ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -// -// The absolute IO port address of the SMI Control and Enable Register. It is -// only used to carry information from the entry point function to the -// S3SaveState protocol installation callback, strictly before the runtime -// phase. +// The absolute IO port address of the SMI Control and Enable Register. // STATIC UINTN mSmiEnable; // -// Captures whether SMI feature negotiation is supported. The variable is only -// used to carry this information from the entry point function to the -// S3SaveState protocol installation callback. +// Captures whether SMI feature negotiation is supported. // STATIC BOOLEAN mSmiFeatureNegotiation; -// -// Event signaled when an S3SaveState protocol interface is installed. -// -STATIC EFI_EVENT mS3SaveStateInstalled; - /** Invokes SMI activation from either the preboot or runtime environment. @@ -249,54 +228,11 @@ SmmControl2DxeEntryPoint ( // // QEMU can inject SMIs in different ways, negotiate our preferences. + // Note: Negotiated features are not actually used for anything right now. But, the function is called + // to test negotiation in case it is need in the future. // mSmiFeatureNegotiation = NegotiateSmiFeatures (); - if (PcdGetBool (PcdAcpiS3Enable)) { - VOID *Registration; - - // - // On S3 resume the above register settings have to be repeated. Register a - // protocol notify callback that, when boot script saving becomes - // available, saves operations equivalent to the above to the boot script. - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - OnS3SaveStateInstalled, - NULL /* Context */, - &mS3SaveStateInstalled - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: CreateEvent: %r\n", __FUNCTION__, Status)); - goto FatalError; - } - - Status = gBS->RegisterProtocolNotify ( - &gEfiS3SaveStateProtocolGuid, - mS3SaveStateInstalled, - &Registration - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: RegisterProtocolNotify: %r\n", - __FUNCTION__, - Status - )); - goto ReleaseEvent; - } - - // - // Kick the event right now -- maybe the boot script is already saveable. - // - Status = gBS->SignalEvent (mS3SaveStateInstalled); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: SignalEvent: %r\n", __FUNCTION__, Status)); - goto ReleaseEvent; - } - } - // // We have no pointers to convert to virtual addresses. The handle itself // doesn't matter, as protocol services are not accessible at runtime. @@ -314,16 +250,11 @@ SmmControl2DxeEntryPoint ( __FUNCTION__, Status )); - goto ReleaseEvent; + goto FatalError; } return EFI_SUCCESS; -ReleaseEvent: - if (mS3SaveStateInstalled != NULL) { - gBS->CloseEvent (mS3SaveStateInstalled); - } - FatalError: // // We really don't want to continue in this case. @@ -332,98 +263,3 @@ SmmControl2DxeEntryPoint ( CpuDeadLoop (); return EFI_UNSUPPORTED; } - -/** - Notification callback for S3SaveState installation. - - @param[in] Event Event whose notification function is being invoked. - - @param[in] Context The pointer to the notification function's context, which - is implementation-dependent. -**/ -STATIC -VOID -EFIAPI -OnS3SaveStateInstalled ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState; - UINT32 SmiEnOrMask, SmiEnAndMask; - UINT64 GenPmCon1Address; - UINT16 GenPmCon1OrMask, GenPmCon1AndMask; - - ASSERT (Event == mS3SaveStateInstalled); - - Status = gBS->LocateProtocol ( - &gEfiS3SaveStateProtocolGuid, - NULL /* Registration */, - (VOID **)&S3SaveState - ); - if (EFI_ERROR (Status)) { - return; - } - - // - // These operations were originally done, verified and explained in the entry - // point function of the driver. - // - SmiEnOrMask = ICH9_SMI_EN_APMC_EN | ICH9_SMI_EN_GBL_SMI_EN; - SmiEnAndMask = MAX_UINT32; - Status = S3SaveState->Write ( - S3SaveState, - EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE, - EfiBootScriptWidthUint32, - (UINT64)mSmiEnable, - &SmiEnOrMask, - &SmiEnAndMask - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE: %r\n", - __FUNCTION__, - Status - )); - ASSERT (FALSE); - CpuDeadLoop (); - } - - GenPmCon1Address = POWER_MGMT_REGISTER_Q35_EFI_PCI_ADDRESS ( - ICH9_GEN_PMCON_1 - ); - GenPmCon1OrMask = ICH9_GEN_PMCON_1_SMI_LOCK; - GenPmCon1AndMask = MAX_UINT16; - Status = S3SaveState->Write ( - S3SaveState, - EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE, - EfiBootScriptWidthUint16, - GenPmCon1Address, - &GenPmCon1OrMask, - &GenPmCon1AndMask - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE: %r\n", - __FUNCTION__, - Status - )); - ASSERT (FALSE); - CpuDeadLoop (); - } - - DEBUG ((DEBUG_VERBOSE, "%a: chipset boot script saved\n", __FUNCTION__)); - - // - // Append a boot script fragment that re-selects the negotiated SMI features. - // - if (mSmiFeatureNegotiation) { - SaveSmiFeatures (); - } - - gBS->CloseEvent (Event); - mS3SaveStateInstalled = NULL; -} diff --git a/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.inf b/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.inf index ffc76571a..be68b5a0d 100644 --- a/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.inf +++ b/Platforms/QemuQ35Pkg/SmmControl2Dxe/SmmControl2Dxe.inf @@ -12,6 +12,7 @@ # configuring it. # # Copyright (C) 2013, 2015, Red Hat, Inc. +# Copyright (c) Microsoft Corporation # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -53,18 +54,15 @@ PcdLib PciLib QemuFwCfgLib - QemuFwCfgS3Lib UefiBootServicesTableLib UefiDriverEntryPoint [Protocols] - gEfiS3SaveStateProtocolGuid ## SOMETIMES_CONSUMES gEfiSmmControl2ProtocolGuid ## PRODUCES [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## SOMETIMES_PRODUCES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## SOMETIMES_PRODUCES - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable [FeaturePcd] gQemuPkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc b/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc index 25b002bd1..6757374d5 100644 --- a/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc +++ b/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc @@ -122,6 +122,7 @@ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf + LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf # # Ramdisk Requirements @@ -208,7 +209,6 @@ PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf # Security Libraries - LockBoxLib |QemuPkg/Library/LockBoxLib/LockBoxBaseLib.inf PasswordStoreLib |MsCorePkg/Library/PasswordStoreLibNull/PasswordStoreLibNull.inf PasswordPolicyLib |OemPkg/Library/PasswordPolicyLib/PasswordPolicyLib.inf SecureBootKeyStoreLib |MsCorePkg/Library/BaseSecureBootKeyStoreLib/BaseSecureBootKeyStoreLib.inf @@ -455,7 +455,6 @@ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf PcdDatabaseLoaderLib|MdeModulePkg/Library/PcdDatabaseLoaderLib/Dxe/PcdDatabaseLoaderLibDxe.inf UpdateFacsHardwareSignatureLib|OemPkg/Library/UpdateFacsHardwareSignatureLib/UpdateFacsHardwareSignatureLib.inf - LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf PolicyLib|PolicyServicePkg/Library/DxePolicyLib/DxePolicyLib.inf !if $(TPM2_ENABLE) == TRUE diff --git a/QemuPkg/Library/LockBoxLib/LockBoxBase.c b/QemuPkg/Library/LockBoxLib/LockBoxBase.c deleted file mode 100644 index 00f03525c..000000000 --- a/QemuPkg/Library/LockBoxLib/LockBoxBase.c +++ /dev/null @@ -1,36 +0,0 @@ -/** @file - - Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include - -/** - Allocates a buffer of type EfiACPIMemoryNVS. - - Allocates the number bytes specified by AllocationSize of type - EfiACPIMemoryNVS and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy - the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAcpiNvsPool ( - IN UINTN AllocationSize - ) -{ - ASSERT_EFI_ERROR (RETURN_UNSUPPORTED); - return NULL; -} diff --git a/QemuPkg/Library/LockBoxLib/LockBoxBaseLib.inf b/QemuPkg/Library/LockBoxLib/LockBoxBaseLib.inf deleted file mode 100644 index 7a7bab346..000000000 --- a/QemuPkg/Library/LockBoxLib/LockBoxBaseLib.inf +++ /dev/null @@ -1,41 +0,0 @@ -## @file -# -# Library implementing the LockBox interface for OVMF -# -# Copyright (C) 2013, Red Hat, Inc. -# Copyright (c) 2014, Intel Corporation. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = LockBoxBaseLib - FILE_GUID = 17CA9B37-5BAB-492C-A09C-7121FBE34CE6 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = LockBoxLib - - CONSTRUCTOR = LockBoxLibInitialize - -[Sources] - LockBoxBase.c - LockBoxLib.c - LockBoxLib.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - QemuPkg/QemuPkg.dec - -[LibraryClasses] - BaseMemoryLib - DebugLib - -[Pcd] - gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase - gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize - -[FeaturePcd] - gQemuPkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/QemuPkg/Library/LockBoxLib/LockBoxDxe.c b/QemuPkg/Library/LockBoxLib/LockBoxDxe.c deleted file mode 100644 index c9d679cb8..000000000 --- a/QemuPkg/Library/LockBoxLib/LockBoxDxe.c +++ /dev/null @@ -1,137 +0,0 @@ -/** @file - - Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include -#include -#include - -/** - Allocate memory below 4G memory address. - - This function allocates memory below 4G memory address. - - @param MemoryType Memory type of memory to allocate. - @param Size Size of memory to allocate. - - @return Allocated address for output. - -**/ -STATIC -VOID * -AllocateMemoryBelow4G ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Size - ) -{ - UINTN Pages; - EFI_PHYSICAL_ADDRESS Address; - EFI_STATUS Status; - VOID *Buffer; - UINTN AllocRemaining; - - Pages = EFI_SIZE_TO_PAGES (Size); - Address = 0xffffffff; - - // - // Since we need to use gBS->AllocatePages to get a buffer below - // 4GB, there is a good chance that space will be wasted for very - // small allocation. We keep track of unused portions of the page - // allocations, and use these to allocate memory for small buffers. - // - ASSERT (mLockBoxGlobal->Signature == LOCK_BOX_GLOBAL_SIGNATURE); - if ((UINTN)mLockBoxGlobal->SubPageRemaining >= Size) { - Buffer = (VOID *)(UINTN)mLockBoxGlobal->SubPageBuffer; - mLockBoxGlobal->SubPageBuffer += (UINT32)Size; - mLockBoxGlobal->SubPageRemaining -= (UINT32)Size; - return Buffer; - } - - Status = gBS->AllocatePages ( - AllocateMaxAddress, - MemoryType, - Pages, - &Address - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - Buffer = (VOID *)(UINTN)Address; - ZeroMem (Buffer, EFI_PAGES_TO_SIZE (Pages)); - - AllocRemaining = EFI_PAGES_TO_SIZE (Pages) - Size; - if (AllocRemaining > (UINTN)mLockBoxGlobal->SubPageRemaining) { - mLockBoxGlobal->SubPageBuffer = (UINT32)(Address + Size); - mLockBoxGlobal->SubPageRemaining = (UINT32)AllocRemaining; - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiACPIMemoryNVS. - - Allocates the number bytes specified by AllocationSize of type - EfiACPIMemoryNVS and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy - the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAcpiNvsPool ( - IN UINTN AllocationSize - ) -{ - return AllocateMemoryBelow4G (EfiACPIMemoryNVS, AllocationSize); -} - -EFI_STATUS -EFIAPI -LockBoxDxeLibInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - VOID *Interface; - - Status = LockBoxLibInitialize (); - if (!EFI_ERROR (Status)) { - if (PcdGetBool (PcdAcpiS3Enable)) { - // - // When S3 enabled, the first driver run with this library linked will - // have this library constructor to install LockBox protocol on the - // ImageHandle. As other drivers may have gEfiLockBoxProtocolGuid - // dependency, the first driver should run before them. - // - Status = gBS->LocateProtocol (&gEfiLockBoxProtocolGuid, NULL, &Interface); - if (EFI_ERROR (Status)) { - Status = gBS->InstallProtocolInterface ( - &ImageHandle, - &gEfiLockBoxProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - ASSERT_EFI_ERROR (Status); - } - } - } - - return Status; -} diff --git a/QemuPkg/Library/LockBoxLib/LockBoxDxeLib.inf b/QemuPkg/Library/LockBoxLib/LockBoxDxeLib.inf deleted file mode 100644 index ebe7b9842..000000000 --- a/QemuPkg/Library/LockBoxLib/LockBoxDxeLib.inf +++ /dev/null @@ -1,46 +0,0 @@ -## @file -# -# Library implementing the LockBox interface for OVMF -# -# Copyright (C) 2013, Red Hat, Inc. -# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = LockBoxDxeLib - FILE_GUID = f61c9a34-2e18-44ce-af2f-21a998e64fda - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = LockBoxLib - - CONSTRUCTOR = LockBoxDxeLibInitialize - -[Sources] - LockBoxDxe.c - LockBoxLib.c - LockBoxLib.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - QemuPkg/QemuPkg.dec - -[LibraryClasses] - BaseMemoryLib - DebugLib - UefiBootServicesTableLib - -[Protocols] - gEfiLockBoxProtocolGuid ## SOMETIMES_PRODUCES - -[Pcd] - gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase - gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable - -[FeaturePcd] - gQemuPkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/QemuPkg/Library/LockBoxLib/LockBoxLib.c b/QemuPkg/Library/LockBoxLib/LockBoxLib.c deleted file mode 100644 index 2000afeeb..000000000 --- a/QemuPkg/Library/LockBoxLib/LockBoxLib.c +++ /dev/null @@ -1,408 +0,0 @@ -/** @file - - Library implementing the LockBox interface for OVMF - - Copyright (C) 2013, Red Hat, Inc. - Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include -#include -#include - -#pragma pack(1) -typedef struct { - EFI_GUID Guid; - EFI_PHYSICAL_ADDRESS OrigAddress; - EFI_PHYSICAL_ADDRESS CopyAddress; - UINT32 Size; - UINT64 Attributes; -} LOCK_BOX_ENTRY; -#pragma pack() - -LOCK_BOX_GLOBAL *mLockBoxGlobal = NULL; -STATIC LOCK_BOX_ENTRY *StartOfEntries = NULL; -STATIC LOCK_BOX_ENTRY *EndOfEntries = NULL; - -RETURN_STATUS -EFIAPI -LockBoxLibInitialize ( - VOID - ) -{ - UINTN NumEntries; - - ASSERT (!FeaturePcdGet (PcdSmmSmramRequire)); - - if (PcdGet32 (PcdOvmfLockBoxStorageSize) < sizeof (LOCK_BOX_GLOBAL)) { - return RETURN_UNSUPPORTED; - } - - mLockBoxGlobal = (LOCK_BOX_GLOBAL *)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase); - StartOfEntries = ((LOCK_BOX_ENTRY *)(mLockBoxGlobal + 1)); - NumEntries = ((PcdGet32 (PcdOvmfLockBoxStorageSize) - sizeof (LOCK_BOX_GLOBAL)) / - sizeof (LOCK_BOX_ENTRY)); - EndOfEntries = StartOfEntries + NumEntries; - if (mLockBoxGlobal->Signature != LOCK_BOX_GLOBAL_SIGNATURE) { - // - // Note: This code depends on the lock box being cleared in early - // PEI before usage, so the SubPageBuffer and SubPageRemaining - // fields don't need to be set to 0. - // - mLockBoxGlobal->Signature = LOCK_BOX_GLOBAL_SIGNATURE; - } - - return RETURN_SUCCESS; -} - -/** - Find LockBox entry based on GUID. - - @param[in] Guid The GUID to search for. - - @return Address of the LOCK_BOX_ENTRY found. - - If NULL, then the item was not found, and there is no space - left to store a new item. - - If non-NULL and LOCK_BOX_ENTRY.Size == 0, then the item was not - found, but a new item can be inserted at the returned location. - - If non-NULL and LOCK_BOX_ENTRY.Size > 0, then the item was found. -**/ -STATIC -LOCK_BOX_ENTRY * -EFIAPI -FindHeaderByGuid ( - IN CONST EFI_GUID *Guid - ) -{ - LOCK_BOX_ENTRY *Header; - - for (Header = StartOfEntries; Header < EndOfEntries; Header++) { - if ((Header->Size == 0) || CompareGuid (Guid, &Header->Guid)) { - return Header; - } - } - - return NULL; -} - -/** - This function will save confidential information to lockbox. - - @param Guid the guid to identify the confidential information - @param Buffer the address of the confidential information - @param Length the length of the confidential information - - @retval RETURN_SUCCESS the information is saved successfully. - @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or - Length is 0 - @retval RETURN_ALREADY_STARTED the requested GUID already exist. - @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information. - @retval RETURN_ACCESS_DENIED it is too late to invoke this interface - @retval RETURN_NOT_STARTED it is too early to invoke this interface - @retval RETURN_UNSUPPORTED the service is not supported by - implementaion. -**/ -RETURN_STATUS -EFIAPI -SaveLockBox ( - IN GUID *Guid, - IN VOID *Buffer, - IN UINTN Length - ) -{ - LOCK_BOX_ENTRY *Header; - VOID *CopyBuffer; - - DEBUG (( - DEBUG_VERBOSE, - "%a: Guid=%g Buffer=%p Length=0x%x\n", - __FUNCTION__, - Guid, - Buffer, - (UINT32)Length - )); - - if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) { - return RETURN_INVALID_PARAMETER; - } - - if (Length > 0xFFFFFFFF) { - return RETURN_OUT_OF_RESOURCES; - } - - Header = FindHeaderByGuid (Guid); - if (Header == NULL) { - return RETURN_OUT_OF_RESOURCES; - } - - if (Header->Size > 0) { - return RETURN_ALREADY_STARTED; - } - - CopyBuffer = AllocateAcpiNvsPool (Length); - if (CopyBuffer == NULL) { - return RETURN_OUT_OF_RESOURCES; - } - - // - // overwrite the current terminator header with new metadata - // - CopyGuid (&Header->Guid, Guid); - Header->OrigAddress = (UINTN)Buffer; - Header->CopyAddress = (UINTN)CopyBuffer; - Header->Size = (UINT32)Length; - Header->Attributes = 0; - - // - // copy contents - // - CopyMem (CopyBuffer, Buffer, Length); - - return RETURN_SUCCESS; -} - -/** - This function will set lockbox attributes. - - @param Guid the guid to identify the confidential information - @param Attributes the attributes of the lockbox - - @retval RETURN_SUCCESS the information is saved successfully. - @retval RETURN_INVALID_PARAMETER attributes is invalid. - @retval RETURN_NOT_FOUND the requested GUID not found. - @retval RETURN_ACCESS_DENIED it is too late to invoke this interface - @retval RETURN_NOT_STARTED it is too early to invoke this interface - @retval RETURN_UNSUPPORTED the service is not supported by - implementaion. -**/ -RETURN_STATUS -EFIAPI -SetLockBoxAttributes ( - IN GUID *Guid, - IN UINT64 Attributes - ) -{ - LOCK_BOX_ENTRY *Header; - - DEBUG (( - DEBUG_VERBOSE, - "%a: Guid=%g Attributes=0x%Lx\n", - __FUNCTION__, - Guid, - Attributes - )); - - if (Guid == NULL) { - return RETURN_INVALID_PARAMETER; - } - - Header = FindHeaderByGuid (Guid); - if (!Header || (Header->Size == 0)) { - return RETURN_NOT_FOUND; - } - - Header->Attributes = Attributes; - - return RETURN_SUCCESS; -} - -/** - This function will update confidential information to lockbox. - - @param Guid the guid to identify the original confidential information - @param Offset the offset of the original confidential information - @param Buffer the address of the updated confidential information - @param Length the length of the updated confidential information - - @retval RETURN_SUCCESS the information is saved successfully. - @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or - Length is 0. - @retval RETURN_NOT_FOUND the requested GUID not found. - @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute - LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY, the - original buffer to too small to hold new - information. - @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute - LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY, no - enough resource to save the information. - @retval RETURN_ACCESS_DENIED it is too late to invoke this interface - @retval RETURN_NOT_STARTED it is too early to invoke this interface - @retval RETURN_UNSUPPORTED the service is not supported by - implementaion. -**/ -RETURN_STATUS -EFIAPI -UpdateLockBox ( - IN GUID *Guid, - IN UINTN Offset, - IN VOID *Buffer, - IN UINTN Length - ) -{ - LOCK_BOX_ENTRY *Header; - - DEBUG (( - DEBUG_VERBOSE, - "%a: Guid=%g Offset=0x%x Length=0x%x\n", - __FUNCTION__, - Guid, - (UINT32)Offset, - (UINT32)Length - )); - - if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) { - return RETURN_INVALID_PARAMETER; - } - - Header = FindHeaderByGuid (Guid); - if (!Header || (Header->Size == 0)) { - return RETURN_NOT_FOUND; - } - - if ((Header->Size < Offset) || - (Length > Header->Size - Offset)) - { - return RETURN_BUFFER_TOO_SMALL; - } - - CopyMem ((UINT8 *)(UINTN)(Header->CopyAddress) + Offset, Buffer, Length); - - return RETURN_SUCCESS; -} - -/** - This function will restore confidential information from lockbox. - - @param Guid the guid to identify the confidential information - @param Buffer the address of the restored confidential information - NULL means restored to original address, Length MUST be NULL at - same time. - @param Length the length of the restored confidential information - - @retval RETURN_SUCCESS the information is restored successfully. - @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and - Length is NULL. - @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox - has no LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE - attribute. - @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the - confidential information. - @retval RETURN_NOT_FOUND the requested GUID not found. - @retval RETURN_NOT_STARTED it is too early to invoke this interface - @retval RETURN_ACCESS_DENIED not allow to restore to the address - @retval RETURN_UNSUPPORTED the service is not supported by - implementaion. -**/ -RETURN_STATUS -EFIAPI -RestoreLockBox ( - IN GUID *Guid, - IN VOID *Buffer OPTIONAL, - IN OUT UINTN *Length OPTIONAL - ) -{ - LOCK_BOX_ENTRY *Header; - - DEBUG (( - DEBUG_VERBOSE, - "%a: Guid=%g Buffer=%p\n", - __FUNCTION__, - Guid, - Buffer - )); - - if ((Guid == NULL) || - ((Buffer == NULL) && (Length != NULL)) || - ((Buffer != NULL) && (Length == NULL))) - { - return EFI_INVALID_PARAMETER; - } - - Header = FindHeaderByGuid (Guid); - if (!Header || (Header->Size == 0)) { - return RETURN_NOT_FOUND; - } - - if (Buffer == NULL) { - if (!(Header->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE)) { - return RETURN_WRITE_PROTECTED; - } - - if (Header->OrigAddress + (Header->Size - 1) > MAX_ADDRESS) { - return RETURN_UNSUPPORTED; - } - - Buffer = (VOID *)(UINTN)Header->OrigAddress; - } - - // - // Set RestoreLength - // - if (Length != NULL) { - if (Header->Size > *Length) { - // - // Input buffer is too small to hold all data. - // - *Length = Header->Size; - return EFI_BUFFER_TOO_SMALL; - } - - *Length = Header->Size; - } - - CopyMem (Buffer, (VOID *)(UINTN)Header->CopyAddress, Header->Size); - - return RETURN_SUCCESS; -} - -/** - This function will restore confidential information from all lockbox which - have RestoreInPlace attribute. - - @retval RETURN_SUCCESS the information is restored successfully. - @retval RETURN_NOT_STARTED it is too early to invoke this interface - @retval RETURN_UNSUPPORTED the service is not supported by - implementaion. -**/ -RETURN_STATUS -EFIAPI -RestoreAllLockBoxInPlace ( - VOID - ) -{ - LOCK_BOX_ENTRY *Header; - - for (Header = StartOfEntries; - Header < EndOfEntries && Header->Size > 0; - Header++) - { - if (Header->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) { - VOID *Buffer; - - if (Header->OrigAddress + (Header->Size - 1) > MAX_ADDRESS) { - return RETURN_UNSUPPORTED; - } - - Buffer = (VOID *)(UINTN)Header->OrigAddress; - CopyMem (Buffer, (VOID *)(UINTN)Header->CopyAddress, Header->Size); - DEBUG (( - DEBUG_VERBOSE, - "%a: Guid=%g Buffer=%p\n", - __FUNCTION__, - &Header->Guid, - Buffer - )); - } - } - - return RETURN_SUCCESS; -} diff --git a/QemuPkg/Library/LockBoxLib/LockBoxLib.h b/QemuPkg/Library/LockBoxLib/LockBoxLib.h deleted file mode 100644 index a5392c912..000000000 --- a/QemuPkg/Library/LockBoxLib/LockBoxLib.h +++ /dev/null @@ -1,52 +0,0 @@ -/** @file - - Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __LOCK_BOX_LIB_IMPL_H__ -#define __LOCK_BOX_LIB_IMPL_H__ - -#pragma pack(1) - -typedef struct { - UINT32 Signature; - UINT32 SubPageBuffer; - UINT32 SubPageRemaining; -} LOCK_BOX_GLOBAL; - -#define LOCK_BOX_GLOBAL_SIGNATURE SIGNATURE_32('L', 'B', 'G', 'S') - -extern LOCK_BOX_GLOBAL *mLockBoxGlobal; - -#pragma pack() - -/** - Allocates a buffer of type EfiACPIMemoryNVS. - - Allocates the number bytes specified by AllocationSize of type - EfiACPIMemoryNVS and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy - the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAcpiNvsPool ( - IN UINTN AllocationSize - ); - -RETURN_STATUS -EFIAPI -LockBoxLibInitialize ( - VOID - ); - -#endif diff --git a/QemuPkg/QemuPkg.dec b/QemuPkg/QemuPkg.dec index e29ae4de0..1e9652da3 100644 --- a/QemuPkg/QemuPkg.dec +++ b/QemuPkg/QemuPkg.dec @@ -66,9 +66,6 @@ gQemuPkgTokenSpaceGuid.PcdVirtioScsiMaxTargetLimit|31|UINT16|0x2 gQemuPkgTokenSpaceGuid.PcdVirtioScsiMaxLunLimit|7|UINT32|0x3 - gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|0x0|UINT32|0x4 - gQemuPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize|0x0|UINT32|0x5 - [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx] gQemuPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0|UINT16|0x10 diff --git a/QemuPkg/QemuPkg.dsc b/QemuPkg/QemuPkg.dsc index 9d32a1e7e..f86410df5 100644 --- a/QemuPkg/QemuPkg.dsc +++ b/QemuPkg/QemuPkg.dsc @@ -127,8 +127,6 @@ QemuPkg/Library/ConfigSystemModeLibQemu/ConfigSystemModeLib.inf QemuPkg/Library/DfciDeviceIdSupportLib/DfciDeviceIdSupportLib.inf QemuPkg/Library/DfciUiSupportLib/DfciUiSupportLib.inf - QemuPkg/Library/LockBoxLib/LockBoxBaseLib.inf - QemuPkg/Library/LockBoxLib/LockBoxDxeLib.inf QemuPkg/Library/MsBootOptionsLibQemu/MsBootOptionsLib.inf QemuPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf QemuPkg/Library/PlatformSecureLib/PlatformSecureLib.inf