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
)
{