X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FLibrary%2FDxeCorePerformanceLib%2FDxeCorePerformanceLib.c;h=eb9cea501128453cac9ea4d62294b7332971a3c1;hb=7c7184e201a90a1d2376e615e55e3f4074731468;hp=5798c89fffee60375405b73f6064282835caa98e;hpb=981b7edc0e2f984c62608e9c5c5702ad106fa764;p=mirror_edk2.git diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c index 5798c89fff..eb9cea5011 100644 --- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c +++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c @@ -10,15 +10,9 @@ 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.
+Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -70,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; @@ -211,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; @@ -243,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)) { @@ -290,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 // @@ -311,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. @@ -364,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; } @@ -391,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; } @@ -843,7 +855,7 @@ GetDeviceInfoFromHandleAndUpdateLength ( ControllerNameStringSize = FPDT_MAX_PERF_RECORD_SIZE - (*Length) - 1; } - UnicodeStrToAsciiStrS(StringPtr, ComponentNameString, ControllerNameStringSize); + UnicodeStrnToAsciiStrS(StringPtr, ControllerNameStringSize - 1, ComponentNameString, ControllerNameStringSize, &ControllerNameStringSize); // // Add a space in the end of the ControllerName @@ -885,7 +897,7 @@ GetDeviceInfoFromHandleAndUpdateLength ( AsciiStringPtr = ComponentNameString; } - UnicodeStrToAsciiStrS(StringPtr, AsciiStringPtr, DevicePathStringSize); + UnicodeStrnToAsciiStrS(StringPtr, DevicePathStringSize - 1, AsciiStringPtr, DevicePathStringSize, &DevicePathStringSize); *Length += (UINT8)DevicePathStringSize; return EFI_SUCCESS; } @@ -920,11 +932,11 @@ GetDeviceInfoFromHandleAndUpdateLength ( **/ EFI_STATUS InsertFpdtRecord ( - IN CONST VOID *CallerIdentifier, OPTIONAL - IN CONST VOID *Guid, OPTIONAL - IN CONST CHAR8 *String, OPTIONAL + IN CONST VOID *CallerIdentifier OPTIONAL, + IN CONST VOID *Guid OPTIONAL, + IN CONST CHAR8 *String OPTIONAL, IN UINT64 Ticker, - IN UINT64 Address, OPTIONAL + IN UINT64 Address OPTIONAL, IN UINT16 PerfId, IN PERF_MEASUREMENT_ATTRIBUTE Attribute ) @@ -1004,7 +1016,7 @@ InsertFpdtRecord ( switch (PerfId) { case MODULE_START_ID: case MODULE_END_ID: - GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); + GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); StringPtr = ModuleName; // // Cache the offset of start image start record and use to update the start image end record if needed. @@ -1037,7 +1049,7 @@ InsertFpdtRecord ( case MODULE_LOADIMAGE_START_ID: case MODULE_LOADIMAGE_END_ID: - GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); + GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); StringPtr = ModuleName; if (PerfId == MODULE_LOADIMAGE_START_ID) { mLoadImageCount ++; @@ -1077,7 +1089,7 @@ InsertFpdtRecord ( case MODULE_DB_SUPPORT_END_ID: case MODULE_DB_STOP_START_ID: case MODULE_DB_STOP_END_ID: - GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); + GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); StringPtr = ModuleName; if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) { FpdtRecordPtr.GuidQwordEvent->Header.Type = FPDT_GUID_QWORD_EVENT_TYPE; @@ -1091,7 +1103,7 @@ InsertFpdtRecord ( break; case MODULE_DB_END_ID: - GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); + GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); StringPtr = ModuleName; if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) { FpdtRecordPtr.GuidQwordStringEvent->Header.Type = FPDT_GUID_QWORD_STRING_EVENT_TYPE; @@ -1137,7 +1149,7 @@ InsertFpdtRecord ( case PERF_INMODULE_END_ID: case PERF_CROSSMODULE_START_ID: case PERF_CROSSMODULE_END_ID: - GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); + GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); if (String != NULL) { StringPtr = String; } else { @@ -1159,7 +1171,7 @@ InsertFpdtRecord ( default: if (Attribute != PerfEntry) { - GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); + GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid); if (String != NULL) { StringPtr = String; } else { @@ -1342,6 +1354,49 @@ 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; + + SmmBootRecordDataSize = 0; + + // + // 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. @@ -1364,6 +1419,7 @@ DxeCorePerformanceLibConstructor ( { EFI_STATUS Status; EFI_HANDLE Handle; + EFI_EVENT EndOfDxeEvent; EFI_EVENT ReadyToBootEvent; PERFORMANCE_PROPERTY *PerformanceProperty; @@ -1392,13 +1448,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 ); @@ -1445,10 +1513,10 @@ EFI_STATUS EFIAPI CreatePerformanceMeasurement ( IN CONST VOID *CallerIdentifier, - IN CONST VOID *Guid, OPTIONAL - IN CONST CHAR8 *String, OPTIONAL + IN CONST VOID *Guid OPTIONAL, + IN CONST CHAR8 *String OPTIONAL, IN UINT64 TimeStamp, - IN UINT64 Address, OPTIONAL + IN UINT64 Address OPTIONAL, IN UINT32 Identifier, IN PERF_MEASUREMENT_ATTRIBUTE Attribute ) @@ -1497,9 +1565,9 @@ CreatePerformanceMeasurement ( RETURN_STATUS EFIAPI StartPerformanceMeasurementEx ( - IN CONST VOID *Handle, OPTIONAL - IN CONST CHAR8 *Token, OPTIONAL - IN CONST CHAR8 *Module, OPTIONAL + IN CONST VOID *Handle OPTIONAL, + IN CONST CHAR8 *Token OPTIONAL, + IN CONST CHAR8 *Module OPTIONAL, IN UINT64 TimeStamp, IN UINT32 Identifier ) @@ -1546,9 +1614,9 @@ StartPerformanceMeasurementEx ( RETURN_STATUS EFIAPI EndPerformanceMeasurementEx ( - IN CONST VOID *Handle, OPTIONAL - IN CONST CHAR8 *Token, OPTIONAL - IN CONST CHAR8 *Module, OPTIONAL + IN CONST VOID *Handle OPTIONAL, + IN CONST CHAR8 *Token OPTIONAL, + IN CONST CHAR8 *Module OPTIONAL, IN UINT64 TimeStamp, IN UINT32 Identifier ) @@ -1651,9 +1719,9 @@ GetPerformanceMeasurementEx ( RETURN_STATUS EFIAPI StartPerformanceMeasurement ( - IN CONST VOID *Handle, OPTIONAL - IN CONST CHAR8 *Token, OPTIONAL - IN CONST CHAR8 *Module, OPTIONAL + IN CONST VOID *Handle OPTIONAL, + IN CONST CHAR8 *Token OPTIONAL, + IN CONST CHAR8 *Module OPTIONAL, IN UINT64 TimeStamp ) { @@ -1687,9 +1755,9 @@ StartPerformanceMeasurement ( RETURN_STATUS EFIAPI EndPerformanceMeasurement ( - IN CONST VOID *Handle, OPTIONAL - IN CONST CHAR8 *Token, OPTIONAL - IN CONST CHAR8 *Module, OPTIONAL + IN CONST VOID *Handle OPTIONAL, + IN CONST CHAR8 *Token OPTIONAL, + IN CONST CHAR8 *Module OPTIONAL, IN UINT64 TimeStamp ) { @@ -1791,9 +1859,9 @@ RETURN_STATUS EFIAPI LogPerformanceMeasurement ( IN CONST VOID *CallerIdentifier, - IN CONST VOID *Guid, OPTIONAL - IN CONST CHAR8 *String, OPTIONAL - IN UINT64 Address, OPTIONAL + IN CONST VOID *Guid OPTIONAL, + IN CONST CHAR8 *String OPTIONAL, + IN UINT64 Address OPTIONAL, IN UINT32 Identifier ) {