diff options
author | CoprDistGit <infra@openeuler.org> | 2023-10-30 11:56:48 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-10-30 11:56:48 +0000 |
commit | 1dae37b163e1e08e719ac06fa86b3414b4ddfb2b (patch) | |
tree | d6c29b92e733448b00701f46c85d08ecc4a5fbbb /0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch | |
parent | 8a55803b9ffda4b5bd4f5bbb9767a617620266ae (diff) |
automatic import of edk2openeuler22.03_LTS
Diffstat (limited to '0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch')
-rw-r--r-- | 0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch | 982 |
1 files changed, 982 insertions, 0 deletions
diff --git a/0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch b/0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch new file mode 100644 index 0000000..0917f11 --- /dev/null +++ b/0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch @@ -0,0 +1,982 @@ +From 306307df0e228c73f6ad38ef231db75c4a3478d1 Mon Sep 17 00:00:00 2001 +From: Dandan Bi <dandan.bi@intel.com> +Date: Mon, 28 Jun 2021 19:50:22 +0800 +Subject: [PATCH] MdeModulePkg/FPDT: Lock boot performance table address + variable at EndOfDxe + +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2957 + +1. Allocate performance data table at EndOfDxe and then lock the varible + which store the table address at EndOfDxe. + +2. Enlarge PCD gEfiMdeModulePkgTokenSpaceGuid.PcdExtFpdtBootRecordPadSize + from 0x20000 to 0x30000 in order to hold the Delta performance data + between EndOfDxe and ReadyToBoot. + +3. SMM performance data is collected by DXE modules through SMM communication + at ReadyToBoot before. + Now to do SMM communication twice, one for allocating the performance + size at EndOfDxe, another is at ReadyToBoot to get SMM performance data. + +4. Make SmmCorePerformanceLib rather than FirmwarePerformanceSmm to communicate + with DxeCorePerformanceLib for SMM performance data and size. + +Cc: Liming Gao <gaoliming@byosoft.com.cn> +Cc: Hao A Wu <hao.a.wu@intel.com> +Cc: Jian J Wang <jian.j.wang@intel.com> +Signed-off-by: Dandan Bi <dandan.bi@intel.com> +Reviewed-by: Hao A Wu <hao.a.wu@intel.com> +Signed-off-by: Jinhua Cao <caojinhua1@huawei.com> +--- + .../DxeCorePerformanceLib.c | 132 +++++++++++---- + .../DxeCorePerformanceLib.inf | 3 +- + .../SmmCorePerformanceLib.c | 142 ++++++++++++---- + .../SmmCorePerformanceLib.inf | 5 +- + MdeModulePkg/MdeModulePkg.dec | 4 +- + .../FirmwarePerformanceDxe.c | 90 +++++++++-- + .../FirmwarePerformanceDxe.inf | 6 +- + .../FirmwarePerformanceSmm.c | 151 +----------------- + .../FirmwarePerformanceSmm.inf | 4 +- + 9 files changed, 302 insertions(+), 235 deletions(-) + +diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c +index f500e20b32..bcefac6b6c 100644 +--- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c ++++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c +@@ -10,7 +10,7 @@ + This library is mainly used by DxeCore to start performance logging to ensure that
+ Performance Protocol is installed at the very beginning of DXE phase.
+
+-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
++Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+@@ -64,7 +64,7 @@ UINT32 mLoadImageCount = 0; + UINT32 mPerformanceLength = 0;
+ UINT32 mMaxPerformanceLength = 0;
+ UINT32 mBootRecordSize = 0;
+-UINT32 mBootRecordMaxSize = 0;
++UINTN mBootRecordMaxSize = 0;
+ UINT32 mCachedLength = 0;
+
+ BOOLEAN mFpdtBufferIsReported = FALSE;
+@@ -205,25 +205,26 @@ IsKnownID ( + }
+
+ /**
+- Allocate buffer for Boot Performance table.
++ This internal function dumps all the SMM performance data and size.
+
+- @return Status code.
++ @param SmmPerfData Smm Performance data. The buffer contain the SMM perf data is allocated by this function and caller needs to free it.
++ @param SmmPerfDataSize Smm Performance data size.
++ @param SkipGetPerfData Skip to get performance data, just get the size.
+
+ **/
+-EFI_STATUS
+-AllocateBootPerformanceTable (
++VOID
++InternalGetSmmPerfData (
++ OUT VOID **SmmPerfData,
++ OUT UINTN *SmmPerfDataSize,
++ IN BOOLEAN SkipGetPerfData
+ )
+ {
+ EFI_STATUS Status;
+- UINTN Size;
+ UINT8 *SmmBootRecordCommBuffer;
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader;
+ SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;
+ UINTN CommSize;
+- UINTN BootPerformanceDataSize;
+- UINT8 *BootPerformanceData;
+ EFI_SMM_COMMUNICATION_PROTOCOL *Communication;
+- FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;
+ EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *SmmCommRegionTable;
+ EFI_MEMORY_DESCRIPTOR *SmmCommMemRegion;
+ UINTN Index;
+@@ -237,7 +238,6 @@ AllocateBootPerformanceTable ( + SmmBootRecordCommBuffer = NULL;
+ SmmCommData = NULL;
+ SmmBootRecordData = NULL;
+- SmmBootRecordDataSize = 0;
+ ReservedMemSize = 0;
+ Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &Communication);
+ if (!EFI_ERROR (Status)) {
+@@ -284,6 +284,10 @@ AllocateBootPerformanceTable ( + Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize);
+
+ if (!EFI_ERROR (Status) && !EFI_ERROR (SmmCommData->ReturnStatus) && SmmCommData->BootRecordSize != 0) {
++ if (SkipGetPerfData) {
++ *SmmPerfDataSize = SmmCommData->BootRecordSize;
++ return;
++ }
+ //
+ // Get all boot records
+ //
+@@ -305,19 +309,45 @@ AllocateBootPerformanceTable ( + }
+ SmmCommData->BootRecordOffset = SmmCommData->BootRecordOffset + SmmCommData->BootRecordSize;
+ }
++ *SmmPerfData = SmmBootRecordData;
++ *SmmPerfDataSize = SmmBootRecordDataSize;
+ }
+ }
+ }
+ }
++}
++
++/**
++ Allocate buffer for Boot Performance table.
++
++ @return Status code.
++
++**/
++EFI_STATUS
++AllocateBootPerformanceTable (
++ VOID
++ )
++{
++ EFI_STATUS Status;
++ UINTN Size;
++ UINTN BootPerformanceDataSize;
++ UINT8 *BootPerformanceData;
++ FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;
++ UINTN SmmBootRecordDataSize;
++
++ SmmBootRecordDataSize = 0;
++
++ //
++ // Get SMM performance data size at the point of EndOfDxe in order to allocate the boot performance table.
++ // Will Get all the data at ReadyToBoot.
++ //
++ InternalGetSmmPerfData (NULL, &SmmBootRecordDataSize, TRUE);
+
+ //
+ // Prepare memory for Boot Performance table.
+ // Boot Performance table includes BasicBoot record, and one or more appended Boot Records.
+ //
+- BootPerformanceDataSize = sizeof (BOOT_PERFORMANCE_TABLE) + mPerformanceLength + PcdGet32 (PcdExtFpdtBootRecordPadSize);
+- if (SmmCommData != NULL && SmmBootRecordData != NULL) {
+- BootPerformanceDataSize += SmmBootRecordDataSize;
+- }
++ BootPerformanceDataSize = sizeof (BOOT_PERFORMANCE_TABLE) + mPerformanceLength + SmmBootRecordDataSize + PcdGet32 (PcdExtFpdtBootRecordPadSize);
+
+ //
+ // Try to allocate the same runtime buffer as last time boot.
+@@ -358,9 +388,6 @@ AllocateBootPerformanceTable ( + DEBUG ((DEBUG_INFO, "DxeCorePerformanceLib: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable));
+
+ if (mAcpiBootPerformanceTable == NULL) {
+- if (SmmCommData != NULL && SmmBootRecordData != NULL) {
+- FreePool (SmmBootRecordData);
+- }
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+@@ -385,19 +412,10 @@ AllocateBootPerformanceTable ( + mPerformanceLength = 0;
+ mMaxPerformanceLength = 0;
+ }
+- if (SmmCommData != NULL && SmmBootRecordData != NULL) {
+- //
+- // Fill Boot records from SMM drivers.
+- //
+- CopyMem (BootPerformanceData, SmmBootRecordData, SmmBootRecordDataSize);
+- FreePool (SmmBootRecordData);
+- mAcpiBootPerformanceTable->Header.Length = (UINT32) (mAcpiBootPerformanceTable->Header.Length + SmmBootRecordDataSize);
+- BootPerformanceData = BootPerformanceData + SmmBootRecordDataSize;
+- }
+
+ mBootRecordBuffer = (UINT8 *) mAcpiBootPerformanceTable;
+ mBootRecordSize = mAcpiBootPerformanceTable->Header.Length;
+- mBootRecordMaxSize = mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize);
++ mBootRecordMaxSize = BootPerformanceDataSize;
+
+ return EFI_SUCCESS;
+ }
+@@ -1336,6 +1354,47 @@ ReportFpdtRecordBuffer ( + }
+ }
+
++/**
++ Update Boot Performance table.
++
++ @param Event The event of notify protocol.
++ @param Context Notify event context.
++
++**/
++VOID
++EFIAPI
++UpdateBootPerformanceTable (
++ IN EFI_EVENT Event,
++ IN VOID *Context
++ )
++{
++ VOID *SmmBootRecordData;
++ UINTN SmmBootRecordDataSize;
++ UINTN AppendSize;
++ UINT8 *FirmwarePerformanceTablePtr;
++
++ //
++ // Get SMM performance data.
++ //
++ SmmBootRecordData = NULL;
++ InternalGetSmmPerfData (&SmmBootRecordData, &SmmBootRecordDataSize, FALSE);
++
++ FirmwarePerformanceTablePtr = (UINT8 *) mAcpiBootPerformanceTable + mAcpiBootPerformanceTable->Header.Length;
++
++ if (mAcpiBootPerformanceTable->Header.Length + SmmBootRecordDataSize > mBootRecordMaxSize) {
++ DEBUG ((DEBUG_INFO, "DxeCorePerformanceLib: No enough space to save all SMM boot performance data\n"));
++ AppendSize = mBootRecordMaxSize - mAcpiBootPerformanceTable->Header.Length;
++ } else {
++ AppendSize = SmmBootRecordDataSize;
++ }
++ if (SmmBootRecordData != NULL) {
++ CopyMem (FirmwarePerformanceTablePtr, SmmBootRecordData, AppendSize);
++ mAcpiBootPerformanceTable->Header.Length += (UINT32) AppendSize;
++ mBootRecordSize += (UINT32) AppendSize;
++ FreePool (SmmBootRecordData);
++ }
++}
++
+ /**
+ The constructor function initializes Performance infrastructure for DXE phase.
+
+@@ -1358,6 +1417,7 @@ DxeCorePerformanceLibConstructor ( + {
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
++ EFI_EVENT EndOfDxeEvent;
+ EFI_EVENT ReadyToBootEvent;
+ PERFORMANCE_PROPERTY *PerformanceProperty;
+
+@@ -1386,13 +1446,25 @@ DxeCorePerformanceLibConstructor ( + ASSERT_EFI_ERROR (Status);
+
+ //
+- // Register ReadyToBoot event to report StatusCode data
++ // Register EndOfDxe event to allocate the boot performance table and report the table address through status code.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+- TPL_CALLBACK,
++ TPL_NOTIFY,
+ ReportFpdtRecordBuffer,
+ NULL,
++ &gEfiEndOfDxeEventGroupGuid,
++ &EndOfDxeEvent
++ );
++
++ //
++ // Register ReadyToBoot event to update the boot performance table for SMM performance data.
++ //
++ Status = gBS->CreateEventEx (
++ EVT_NOTIFY_SIGNAL,
++ TPL_CALLBACK,
++ UpdateBootPerformanceTable,
++ NULL,
+ &gEfiEventReadyToBootGuid,
+ &ReadyToBootEvent
+ );
+diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf +index 1c1dcc60a6..599d4dea66 100644 +--- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf ++++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf +@@ -9,7 +9,7 @@ + # This library is mainly used by DxeCore to start performance logging to ensure that
+ # Performance and PerformanceEx Protocol are installed at the very beginning of DXE phase.
+ #
+-# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
++# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
+ # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+ # SPDX-License-Identifier: BSD-2-Clause-Patent
+ #
+@@ -67,6 +67,7 @@ + gZeroGuid ## SOMETIMES_CONSUMES ## GUID
+ gEfiFirmwarePerformanceGuid ## SOMETIMES_PRODUCES ## UNDEFINED # StatusCode Data
+ gEdkiiFpdtExtendedFirmwarePerformanceGuid ## SOMETIMES_CONSUMES ## HOB # StatusCode Data
++ gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
+ gEfiEventReadyToBootGuid ## CONSUMES ## Event
+ gEdkiiPiSmmCommunicationRegionTableGuid ## SOMETIMES_CONSUMES ## SystemTable
+ gEdkiiPerformanceMeasurementProtocolGuid ## PRODUCES ## UNDEFINED # Install protocol
+diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c +index b4f22c14ae..d80f37e520 100644 +--- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c ++++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c +@@ -16,7 +16,7 @@ +
+ SmmPerformanceHandlerEx(), SmmPerformanceHandler() will receive untrusted input and do basic validation.
+
+-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
++Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+@@ -48,6 +48,7 @@ CHAR8 *mPlatformLanguage = NULL; + SPIN_LOCK mSmmFpdtLock;
+ PERFORMANCE_PROPERTY mPerformanceProperty;
+ UINT32 mCachedLength = 0;
++UINT32 mBootRecordSize = 0;
+
+ //
+ // Interfaces for SMM PerformanceMeasurement Protocol.
+@@ -776,41 +777,116 @@ InsertFpdtRecord ( + }
+
+ /**
+- SmmReadyToBoot protocol notification event handler.
++ Communication service SMI Handler entry.
+
+- @param Protocol Points to the protocol's unique identifier
+- @param Interface Points to the interface instance
+- @param Handle The handle on which the interface was installed
++ This SMI handler provides services for report MM boot records.
+
+- @retval EFI_SUCCESS SmmReadyToBootCallback runs successfully
++ Caution: This function may receive untrusted input.
++ Communicate buffer and buffer size are external input, so this function will do basic validation.
++
++ @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
++ @param[in] RegisterContext Points to an optional handler context which was specified when the
++ handler was registered.
++ @param[in, out] CommBuffer A pointer to a collection of data in memory that will
++ be conveyed from a non-MM environment into an MM environment.
++ @param[in, out] CommBufferSize The size of the CommBuffer.
++
++ @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
++ should still be called.
++ @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
++ still be called.
++ @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
++ be called.
++ @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
+
+ **/
+ EFI_STATUS
+ EFIAPI
+-SmmReportFpdtRecordData (
+- IN CONST EFI_GUID *Protocol,
+- IN VOID *Interface,
+- IN EFI_HANDLE Handle
++FpdtSmiHandler (
++ IN EFI_HANDLE DispatchHandle,
++ IN CONST VOID *RegisterContext,
++ IN OUT VOID *CommBuffer,
++ IN OUT UINTN *CommBufferSize
+ )
+ {
+- UINT64 SmmBPDTddr;
+-
+- if (!mFpdtDataIsReported && mSmmBootPerformanceTable != NULL) {
+- SmmBPDTddr = (UINT64)(UINTN)mSmmBootPerformanceTable;
+- REPORT_STATUS_CODE_EX (
+- EFI_PROGRESS_CODE,
+- EFI_SOFTWARE_SMM_DRIVER,
+- 0,
+- NULL,
+- &gEdkiiFpdtExtendedFirmwarePerformanceGuid,
+- &SmmBPDTddr,
+- sizeof (UINT64)
++ EFI_STATUS Status;
++ SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;
++ UINTN BootRecordOffset;
++ UINTN BootRecordSize;
++ VOID *BootRecordData;
++ UINTN TempCommBufferSize;
++ UINT8 *BootRecordBuffer;
++
++ //
++ // If input is invalid, stop processing this SMI
++ //
++ if (CommBuffer == NULL || CommBufferSize == NULL) {
++ return EFI_SUCCESS;
++ }
++
++ TempCommBufferSize = *CommBufferSize;
++
++ if(TempCommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {
++ return EFI_SUCCESS;
++ }
++
++ if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
++ DEBUG ((DEBUG_ERROR, "FpdtSmiHandler: MM communication data buffer in MMRAM or overflow!\n"));
++ return EFI_SUCCESS;
++ }
++
++ SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)CommBuffer;
++
++ Status = EFI_SUCCESS;
++
++ switch (SmmCommData->Function) {
++ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE :
++ if (mSmmBootPerformanceTable != NULL) {
++ mBootRecordSize = mSmmBootPerformanceTable->Header.Length - sizeof (SMM_BOOT_PERFORMANCE_TABLE);
++ }
++ SmmCommData->BootRecordSize = mBootRecordSize;
++ break;
++
++ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA :
++ Status = EFI_UNSUPPORTED;
++ break;
++
++ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET :
++ BootRecordOffset = SmmCommData->BootRecordOffset;
++ BootRecordData = SmmCommData->BootRecordData;
++ BootRecordSize = SmmCommData->BootRecordSize;
++ if (BootRecordData == NULL || BootRecordOffset >= mBootRecordSize) {
++ Status = EFI_INVALID_PARAMETER;
++ break;
++ }
++
++ //
++ // Sanity check
++ //
++ if (BootRecordSize > mBootRecordSize - BootRecordOffset) {
++ BootRecordSize = mBootRecordSize - BootRecordOffset;
++ }
++ SmmCommData->BootRecordSize = BootRecordSize;
++ if (!SmmIsBufferOutsideSmmValid ((UINTN)BootRecordData, BootRecordSize)) {
++ DEBUG ((DEBUG_ERROR, "FpdtSmiHandler: MM Data buffer in MMRAM or overflow!\n"));
++ Status = EFI_ACCESS_DENIED;
++ break;
++ }
++ BootRecordBuffer = ((UINT8 *) (mSmmBootPerformanceTable)) + sizeof (SMM_BOOT_PERFORMANCE_TABLE);
++ CopyMem (
++ (UINT8*)BootRecordData,
++ BootRecordBuffer + BootRecordOffset,
++ BootRecordSize
+ );
+- //
+- // Set FPDT report state to TRUE.
+- //
+- mFpdtDataIsReported = TRUE;
++ mFpdtDataIsReported = TRUE;
++ break;
++
++ default:
++ Status = EFI_UNSUPPORTED;
+ }
++
++ SmmCommData->ReturnStatus = Status;
++
+ return EFI_SUCCESS;
+ }
+
+@@ -830,8 +906,8 @@ InitializeSmmCorePerformanceLib ( + )
+ {
+ EFI_HANDLE Handle;
++ EFI_HANDLE SmiHandle;
+ EFI_STATUS Status;
+- VOID *SmmReadyToBootRegistration;
+ PERFORMANCE_PROPERTY *PerformanceProperty;
+
+ //
+@@ -851,11 +927,13 @@ InitializeSmmCorePerformanceLib ( + );
+ ASSERT_EFI_ERROR (Status);
+
+- Status = gSmst->SmmRegisterProtocolNotify (
+- &gEdkiiSmmReadyToBootProtocolGuid,
+- SmmReportFpdtRecordData,
+- &SmmReadyToBootRegistration
+- );
++ //
++ // Register SMI handler.
++ //
++ SmiHandle = NULL;
++ Status = gSmst->SmiHandlerRegister (FpdtSmiHandler, &gEfiFirmwarePerformanceGuid, &SmiHandle);
++ ASSERT_EFI_ERROR (Status);
++
+ Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **) &PerformanceProperty);
+ if (EFI_ERROR (Status)) {
+ //
+diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf +index 6b013b8557..9eecc4b58c 100644 +--- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf ++++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf +@@ -8,7 +8,7 @@ + # This library is mainly used by SMM Core to start performance logging to ensure that
+ # SMM Performance and PerformanceEx Protocol are installed at the very beginning of SMM phase.
+ #
+-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
++# Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
+ # SPDX-License-Identifier: BSD-2-Clause-Patent
+ #
+ ##
+@@ -58,14 +58,13 @@ +
+ [Protocols]
+ gEfiSmmBase2ProtocolGuid ## CONSUMES
+- gEdkiiSmmReadyToBootProtocolGuid ## NOTIFY
+
+ [Guids]
+ ## PRODUCES ## SystemTable
+ gPerformanceProtocolGuid
+- gEdkiiFpdtExtendedFirmwarePerformanceGuid ## SOMETIMES_PRODUCES ## UNDEFINED # StatusCode Data
+ gZeroGuid ## SOMETIMES_CONSUMES ## GUID
+ gEdkiiSmmPerformanceMeasurementProtocolGuid ## PRODUCES ## UNDEFINED # Install protocol
++ gEfiFirmwarePerformanceGuid ## SOMETIMES_PRODUCES ## UNDEFINED # SmiHandlerRegister
+
+ [Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask ## CONSUMES
+diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec +index 5d9e2b8d3d..b139f1668c 100644 +--- a/MdeModulePkg/MdeModulePkg.dec ++++ b/MdeModulePkg/MdeModulePkg.dec +@@ -1822,9 +1822,9 @@ + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x3|UINT32|0x00010069
+
+ ## This PCD specifies the additional pad size in FPDT Basic Boot Performance Table for
+- # the extension FPDT boot records received after ReadyToBoot and before ExitBootService.
++ # the extension FPDT boot records received after EndOfDxe and before ExitBootService.
+ # @Prompt Pad size for extension FPDT boot records.
+- gEfiMdeModulePkgTokenSpaceGuid.PcdExtFpdtBootRecordPadSize|0x20000|UINT32|0x0001005F
++ gEfiMdeModulePkgTokenSpaceGuid.PcdExtFpdtBootRecordPadSize|0x30000|UINT32|0x0001005F
+
+ ## Indicates if ConIn device are connected on demand.<BR><BR>
+ # TRUE - ConIn device are not connected during BDS and ReadKeyStroke/ReadKeyStrokeEx produced
+diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c +index 61a7704b37..68755554ad 100644 +--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c ++++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c +@@ -5,7 +5,7 @@ + for Firmware Basic Boot Performance Record and other boot performance records,
+ and install FPDT to ACPI table.
+
+- Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
++ Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+@@ -16,6 +16,7 @@ + #include <Protocol/AcpiTable.h>
+ #include <Protocol/LockBox.h>
+ #include <Protocol/Variable.h>
++#include <Protocol/VariablePolicy.h>
+
+ #include <Guid/Acpi.h>
+ #include <Guid/FirmwarePerformance.h>
+@@ -32,6 +33,8 @@ + #include <Library/HobLib.h>
+ #include <Library/LockBoxLib.h>
+ #include <Library/UefiLib.h>
++#include <Library/VariablePolicyHelperLib.h>
++#include <Library/PerformanceLib.h>
+
+ #define SMM_BOOT_RECORD_COMM_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof(SMM_BOOT_RECORD_COMMUNICATE))
+
+@@ -278,11 +281,12 @@ InstallFirmwarePerformanceDataTable ( + VOID
+ )
+ {
+- EFI_STATUS Status;
+- EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+- UINTN BootPerformanceDataSize;
+- FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;
+- UINTN Size;
++ EFI_STATUS Status;
++ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
++ UINTN BootPerformanceDataSize;
++ FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;
++ UINTN Size;
++ EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicyProtocol;
+
+ //
+ // Get AcpiTable Protocol.
+@@ -292,6 +296,14 @@ InstallFirmwarePerformanceDataTable ( + return Status;
+ }
+
++ //
++ // Get VariablePolicy Protocol.
++ //
++ Status = gBS->LocateProtocol(&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicyProtocol);
++ if (EFI_ERROR (Status)) {
++ return Status;
++ }
++
+ if (mReceivedAcpiBootPerformanceTable != NULL) {
+ mAcpiBootPerformanceTable = mReceivedAcpiBootPerformanceTable;
+ mAcpiBootPerformanceTable->BasicBoot.ResetEnd = mBootPerformanceTableTemplate.BasicBoot.ResetEnd;
+@@ -369,6 +381,24 @@ InstallFirmwarePerformanceDataTable ( + &PerformanceVariable
+ );
+
++ //
++ // Lock the variable which stores the Performance Table pointers.
++ //
++ Status = RegisterBasicVariablePolicy (
++ VariablePolicyProtocol,
++ &gEfiFirmwarePerformanceGuid,
++ EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
++ VARIABLE_POLICY_NO_MIN_SIZE,
++ VARIABLE_POLICY_NO_MAX_SIZE,
++ VARIABLE_POLICY_NO_MUST_ATTR,
++ VARIABLE_POLICY_NO_CANT_ATTR,
++ VARIABLE_POLICY_TYPE_LOCK_NOW
++ );
++ if (EFI_ERROR(Status)) {
++ DEBUG((DEBUG_ERROR, "[FirmwarePerformanceDxe] Error when lock variable %s, Status = %r\n", EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, Status));
++ ASSERT_EFI_ERROR(Status);
++ }
++
+ //
+ // Publish Firmware Performance Data Table.
+ //
+@@ -501,18 +531,12 @@ FpdtStatusCodeListenerDxe ( + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));
+ DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = 0\n"));
+ DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesExit = 0\n"));
+- } else if (Value == (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)) {
+- if (mAcpiBootPerformanceTable == NULL) {
+- //
+- // ACPI Firmware Performance Data Table not installed yet, install it now.
+- //
+- InstallFirmwarePerformanceDataTable ();
+- }
+ } else if (Data != NULL && CompareGuid (&Data->Type, &gEdkiiFpdtExtendedFirmwarePerformanceGuid)) {
+ //
+ // Get the Boot performance table and then install it to ACPI table.
+ //
+ CopyMem (&mReceivedAcpiBootPerformanceTable, Data + 1, Data->Size);
++ InstallFirmwarePerformanceDataTable ();
+ } else if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {
+ DEBUG ((DEBUG_ERROR, "FpdtStatusCodeListenerDxe: Performance data reported through gEfiFirmwarePerformanceGuid will not be collected by FirmwarePerformanceDataTableDxe\n"));
+ Status = EFI_UNSUPPORTED;
+@@ -526,6 +550,32 @@ FpdtStatusCodeListenerDxe ( + return Status;
+ }
+
++/**
++ Notify function for event EndOfDxe.
++
++ This is used to install ACPI Firmware Performance Data Table for basic boot records.
++
++ @param[in] Event The Event that is being processed.
++ @param[in] Context The Event Context.
++
++**/
++VOID
++EFIAPI
++FpdtEndOfDxeEventNotify (
++ IN EFI_EVENT Event,
++ IN VOID *Context
++ )
++{
++ //
++ // When performance is enabled, the FPDT will be installed when DxeCorePerformanceLib report the data to FimwarePerformanceDxe.
++ // This is used to install the FPDT for the basic boot recods when performance infrastructure is not enabled.
++ //
++ if ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0) {
++ return;
++ }
++ ASSERT (mReceivedAcpiBootPerformanceTable == NULL);
++ InstallFirmwarePerformanceDataTable ();
++}
+
+ /**
+ Notify function for event EVT_SIGNAL_EXIT_BOOT_SERVICES. This is used to record
+@@ -596,6 +646,7 @@ FirmwarePerformanceDxeEntryPoint ( + FIRMWARE_SEC_PERFORMANCE *Performance;
+ VOID *Registration;
+ UINT64 OemTableId;
++ EFI_EVENT EndOfDxeEvent;
+
+ CopyMem (
+ mFirmwarePerformanceTableTemplate.Header.OemId,
+@@ -620,6 +671,19 @@ FirmwarePerformanceDxeEntryPoint ( + Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerDxe, TPL_HIGH_LEVEL);
+ ASSERT_EFI_ERROR (Status);
+
++ //
++ // Register the notify function to install FPDT at EndOfDxe.
++ //
++ Status = gBS->CreateEventEx (
++ EVT_NOTIFY_SIGNAL,
++ TPL_NOTIFY,
++ FpdtEndOfDxeEventNotify,
++ NULL,
++ &gEfiEndOfDxeEventGroupGuid,
++ &EndOfDxeEvent
++ );
++ ASSERT_EFI_ERROR (Status);
++
+ //
+ // Register the notify function to update FPDT on ExitBootServices Event.
+ //
+diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf +index 1debb0193e..0411a22e66 100644 +--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf ++++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf +@@ -5,7 +5,7 @@ + # for Firmware Basic Boot Performance Record and other boot performance records,
+ # and install FPDT to ACPI table.
+ #
+-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
++# Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
+ # SPDX-License-Identifier: BSD-2-Clause-Patent
+ #
+ ##
+@@ -46,12 +46,14 @@ + HobLib
+ LockBoxLib
+ UefiLib
++ VariablePolicyHelperLib
+
+ [Protocols]
+ gEfiAcpiTableProtocolGuid ## CONSUMES
+ gEfiRscHandlerProtocolGuid ## CONSUMES
+ gEfiVariableArchProtocolGuid ## CONSUMES
+ gEfiLockBoxProtocolGuid ## CONSUMES
++ gEdkiiVariablePolicyProtocolGuid ## CONSUMES
+
+ [Guids]
+ gEfiEventExitBootServicesGuid ## CONSUMES ## Event
+@@ -63,6 +65,7 @@ + gEfiFirmwarePerformanceGuid
+ gEdkiiFpdtExtendedFirmwarePerformanceGuid ## SOMETIMES_CONSUMES ## UNDEFINED # StatusCode Data
+ gFirmwarePerformanceS3PointerGuid ## PRODUCES ## UNDEFINED # SaveLockBox
++ gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
+
+ [Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad ## CONSUMES
+@@ -72,6 +75,7 @@ + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUMES
++ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask ## CONSUMES
+
+ [FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwarePerformanceDataTableS3Support ## CONSUMES
+diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c +index d6c6e7693e..dbd9fe1842 100644 +--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c ++++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c +@@ -11,7 +11,7 @@ +
+ FpdtSmiHandler() will receive untrusted input and do basic validation.
+
+- Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
++ Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+@@ -29,21 +29,12 @@ + #include <Library/LockBoxLib.h>
+ #include <Library/PcdLib.h>
+ #include <Library/BaseMemoryLib.h>
+-#include <Library/MemoryAllocationLib.h>
+ #include <Library/UefiBootServicesTableLib.h>
+-#include <Library/SynchronizationLib.h>
+ #include <Library/SmmMemLib.h>
+
+-SMM_BOOT_PERFORMANCE_TABLE *mSmmBootPerformanceTable = NULL;
+-
+ EFI_SMM_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
+ UINT64 mSuspendStartTime = 0;
+ BOOLEAN mS3SuspendLockBoxSaved = FALSE;
+-UINT32 mBootRecordSize = 0;
+-UINT8 *mBootRecordBuffer = NULL;
+-
+-SPIN_LOCK mSmmFpdtLock;
+-BOOLEAN mSmramIsOutOfResource = FALSE;
+
+ /**
+ Report status code listener for SMM. This is used to record the performance
+@@ -85,21 +76,6 @@ FpdtStatusCodeListenerSmm ( + return EFI_UNSUPPORTED;
+ }
+
+- //
+- // Collect one or more Boot records in boot time
+- //
+- if (Data != NULL && CompareGuid (&Data->Type, &gEdkiiFpdtExtendedFirmwarePerformanceGuid)) {
+- AcquireSpinLock (&mSmmFpdtLock);
+- //
+- // Get the boot performance data.
+- //
+- CopyMem (&mSmmBootPerformanceTable, Data + 1, Data->Size);
+- mBootRecordBuffer = ((UINT8 *) (mSmmBootPerformanceTable)) + sizeof (SMM_BOOT_PERFORMANCE_TABLE);
+-
+- ReleaseSpinLock (&mSmmFpdtLock);
+- return EFI_SUCCESS;
+- }
+-
+ if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {
+ DEBUG ((DEBUG_ERROR, "FpdtStatusCodeListenerSmm: Performance data reported through gEfiFirmwarePerformanceGuid will not be collected by FirmwarePerformanceDataTableSmm\n"));
+ return EFI_UNSUPPORTED;
+@@ -154,118 +130,6 @@ FpdtStatusCodeListenerSmm ( + return EFI_SUCCESS;
+ }
+
+-/**
+- Communication service SMI Handler entry.
+-
+- This SMI handler provides services for report SMM boot records.
+-
+- Caution: This function may receive untrusted input.
+- Communicate buffer and buffer size are external input, so this function will do basic validation.
+-
+- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
+- @param[in] RegisterContext Points to an optional handler context which was specified when the
+- handler was registered.
+- @param[in, out] CommBuffer A pointer to a collection of data in memory that will
+- be conveyed from a non-SMM environment into an SMM environment.
+- @param[in, out] CommBufferSize The size of the CommBuffer.
+-
+- @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
+- should still be called.
+- @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
+- still be called.
+- @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
+- be called.
+- @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
+-
+-**/
+-EFI_STATUS
+-EFIAPI
+-FpdtSmiHandler (
+- IN EFI_HANDLE DispatchHandle,
+- IN CONST VOID *RegisterContext,
+- IN OUT VOID *CommBuffer,
+- IN OUT UINTN *CommBufferSize
+- )
+-{
+- EFI_STATUS Status;
+- SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;
+- UINTN BootRecordOffset;
+- UINTN BootRecordSize;
+- VOID *BootRecordData;
+- UINTN TempCommBufferSize;
+-
+- //
+- // If input is invalid, stop processing this SMI
+- //
+- if (CommBuffer == NULL || CommBufferSize == NULL) {
+- return EFI_SUCCESS;
+- }
+-
+- TempCommBufferSize = *CommBufferSize;
+-
+- if(TempCommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {
+- return EFI_SUCCESS;
+- }
+-
+- if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+- DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM communication data buffer in SMRAM or overflow!\n"));
+- return EFI_SUCCESS;
+- }
+-
+- SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)CommBuffer;
+-
+- Status = EFI_SUCCESS;
+-
+- switch (SmmCommData->Function) {
+- case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE :
+- if (mSmmBootPerformanceTable != NULL) {
+- mBootRecordSize = mSmmBootPerformanceTable->Header.Length - sizeof (SMM_BOOT_PERFORMANCE_TABLE);
+- }
+- SmmCommData->BootRecordSize = mBootRecordSize;
+- break;
+-
+- case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA :
+- Status = EFI_UNSUPPORTED;
+- break;
+-
+- case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET :
+- BootRecordOffset = SmmCommData->BootRecordOffset;
+- BootRecordData = SmmCommData->BootRecordData;
+- BootRecordSize = SmmCommData->BootRecordSize;
+- if (BootRecordData == NULL || BootRecordOffset >= mBootRecordSize) {
+- Status = EFI_INVALID_PARAMETER;
+- break;
+- }
+-
+- //
+- // Sanity check
+- //
+- if (BootRecordSize > mBootRecordSize - BootRecordOffset) {
+- BootRecordSize = mBootRecordSize - BootRecordOffset;
+- }
+- SmmCommData->BootRecordSize = BootRecordSize;
+- if (!SmmIsBufferOutsideSmmValid ((UINTN)BootRecordData, BootRecordSize)) {
+- DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM Data buffer in SMRAM or overflow!\n"));
+- Status = EFI_ACCESS_DENIED;
+- break;
+- }
+-
+- CopyMem (
+- (UINT8*)BootRecordData,
+- mBootRecordBuffer + BootRecordOffset,
+- BootRecordSize
+- );
+- break;
+-
+- default:
+- Status = EFI_UNSUPPORTED;
+- }
+-
+- SmmCommData->ReturnStatus = Status;
+-
+- return EFI_SUCCESS;
+-}
+-
+ /**
+ The module Entry Point of the Firmware Performance Data Table SMM driver.
+
+@@ -284,12 +148,6 @@ FirmwarePerformanceSmmEntryPoint ( + )
+ {
+ EFI_STATUS Status;
+- EFI_HANDLE Handle;
+-
+- //
+- // Initialize spin lock
+- //
+- InitializeSpinLock (&mSmmFpdtLock);
+
+ //
+ // Get SMM Report Status Code Handler Protocol.
+@@ -307,12 +165,5 @@ FirmwarePerformanceSmmEntryPoint ( + Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerSmm);
+ ASSERT_EFI_ERROR (Status);
+
+- //
+- // Register SMI handler.
+- //
+- Handle = NULL;
+- Status = gSmst->SmiHandlerRegister (FpdtSmiHandler, &gEfiFirmwarePerformanceGuid, &Handle);
+- ASSERT_EFI_ERROR (Status);
+-
+ return Status;
+ }
+diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf +index 618cbd56ca..6be57553f0 100644 +--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf ++++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf +@@ -4,7 +4,7 @@ + # This module registers report status code listener to collect performance data
+ # for SMM boot performance records and S3 Suspend Performance Record.
+ #
+-# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
++# Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
+ # SPDX-License-Identifier: BSD-2-Clause-Patent
+ #
+ ##
+@@ -51,10 +51,8 @@ +
+ [Guids]
+ ## SOMETIMES_PRODUCES ## UNDEFINED # SaveLockBox
+- ## PRODUCES ## UNDEFINED # SmiHandlerRegister
+ ## SOMETIMES_CONSUMES ## UNDEFINED # StatusCode Data
+ gEfiFirmwarePerformanceGuid
+- gEdkiiFpdtExtendedFirmwarePerformanceGuid ## SOMETIMES_PRODUCES ## UNDEFINED # StatusCode Data
+
+ [Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeS3SuspendStart ## CONSUMES
+-- +2.27.0 + |