diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c new file mode 100644 index 0000000000..bc1a67e171 --- /dev/null +++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c @@ -0,0 +1,659 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. 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. + +Module Name: + + DxeCorePerformance.c + +Abstract: + + Support for measurement of DXE performance + +--*/ + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Interface declarations for Performance Protocol. +// +/** + Adds a record at the end of the performance measurement log + that records the start time of a performance measurement. + + Adds a record to the end of the performance measurement log + that contains the Handle, Token, and Module. + The end time of the new record must be set to zero. + If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record. + If TimeStamp is zero, the start time in the record is filled in with the value + read from the current time stamp. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement. + +**/ +STATIC +EFI_STATUS +EFIAPI +StartGauge ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ); + +/** + Searches the performance measurement log from the beginning of the log + for the first matching record that contains a zero end time and fills in a valid end time. + + Searches the performance measurement log from the beginning of the log + for the first record that matches Handle, Token, and Module and has an end time value of zero. + If the record can not be found then return EFI_NOT_FOUND. + If the record is found and TimeStamp is not zero, + then the end time in the record is filled in with the value specified by TimeStamp. + If the record is found and TimeStamp is zero, then the end time in the matching record + is filled in with the current time stamp value. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval EFI_SUCCESS The end of the measurement was recorded. + @retval EFI_NOT_FOUND The specified measurement record could not be found. + +**/ +STATIC +EFI_STATUS +EFIAPI +EndGauge ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ); + +/** + Retrieves a previously logged performance measurement. + + Retrieves the performance log entry from the performance log specified by LogEntryKey. + If it stands for a valid entry, then EFI_SUCCESS is returned and + GaugeDataEntry stores the pointer to that entry. + + @param LogEntryKey The key for the previous performance measurement log entry. + If 0, then the first performance measurement log entry is retrieved. + @param GaugeDataEntry The indirect pointer to the gauge data entry specified by LogEntryKey + if the retrieval is successful. + + @retval EFI_SUCCESS The GuageDataEntry is successfuly found based on LogEntryKey. + @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number). + @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number). + @retval EFI_INVALIDE_PARAMETER GaugeDataEntry is NULL. + +**/ +STATIC +EFI_STATUS +EFIAPI +GetGauge ( + IN UINTN LogEntryKey, + OUT GAUGE_DATA_ENTRY **GaugeDataEntry + ); + +// +// Definition for global variables. +// +STATIC GAUGE_DATA_HEADER *mGaugeData; +STATIC UINT32 mMaxGaugeRecords; + +EFI_HANDLE mHandle = NULL; +PERFORMANCE_PROTOCOL mPerformanceInterface = { + StartGauge, + EndGauge, + GetGauge + }; + + +/** + Searches in the gauge array with keyword Handle, Token and Module. + + This internal function searches for the gauge entry in the gauge array. + If there is an entry that exactly matches the given key word triple + and its end time stamp is zero, then the index of that gauge entry is returned; + otherwise, the the number of gauge entries in the array is returned. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + + @retval The index of gauge entry in the array. + +**/ +STATIC +UINT32 +InternalSearchForGaugeEntry ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module OPTIONAL + ) +{ + UINT32 Index; + UINT32 NumberOfEntries; + GAUGE_DATA_ENTRY *GaugeEntryArray; + + if (Token == NULL) { + Token = ""; + } + if (Module == NULL) { + Module = ""; + } + + NumberOfEntries = mGaugeData->NumberOfEntries; + GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1); + + for (Index = 0; Index < NumberOfEntries; Index++) { + if ((GaugeEntryArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) && + AsciiStrnCmp (GaugeEntryArray[Index].Token, Token, PEI_PERFORMANCE_STRING_LENGTH) == 0 && + AsciiStrnCmp (GaugeEntryArray[Index].Module, Module, PEI_PERFORMANCE_STRING_LENGTH) == 0 && + GaugeEntryArray[Index].EndTimeStamp == 0 + ) { + break; + } + } + + return Index; +} + +/** + Adds a record at the end of the performance measurement log + that records the start time of a performance measurement. + + Adds a record to the end of the performance measurement log + that contains the Handle, Token, and Module. + The end time of the new record must be set to zero. + If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record. + If TimeStamp is zero, the start time in the record is filled in with the value + read from the current time stamp. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement. + +**/ +STATIC +EFI_STATUS +EFIAPI +StartGauge ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ) +{ + GAUGE_DATA_ENTRY *GaugeEntryArray; + UINTN GaugeDataSize; + UINTN OldGaugeDataSize; + GAUGE_DATA_HEADER *OldGaugeData; + UINT32 Index; + + Index = mGaugeData->NumberOfEntries; + if (Index >= mMaxGaugeRecords) { + // + // Try to enlarge the scale of gauge arrary. + // + OldGaugeData = mGaugeData; + OldGaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords; + + mMaxGaugeRecords *= 2; + GaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords; + + mGaugeData = AllocateZeroPool (GaugeDataSize); + if (mGaugeData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Initialize new data arry and migrate old data one. + // + mGaugeData = CopyMem (mGaugeData, OldGaugeData, OldGaugeDataSize); + + FreePool (OldGaugeData); + } + + GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1); + GaugeEntryArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle; + + if (Token != NULL) { + AsciiStrnCpy (GaugeEntryArray[Index].Token, Token, DXE_PERFORMANCE_STRING_LENGTH); + } + if (Module != NULL) { + AsciiStrnCpy (GaugeEntryArray[Index].Module, Module, DXE_PERFORMANCE_STRING_LENGTH); + } + + if (TimeStamp == 0) { + TimeStamp = GetPerformanceCounter (); + } + GaugeEntryArray[Index].StartTimeStamp = TimeStamp; + + mGaugeData->NumberOfEntries++; + + return EFI_SUCCESS; +} + +/** + Searches the performance measurement log from the beginning of the log + for the first matching record that contains a zero end time and fills in a valid end time. + + Searches the performance measurement log from the beginning of the log + for the first record that matches Handle, Token, and Module and has an end time value of zero. + If the record can not be found then return EFI_NOT_FOUND. + If the record is found and TimeStamp is not zero, + then the end time in the record is filled in with the value specified by TimeStamp. + If the record is found and TimeStamp is zero, then the end time in the matching record + is filled in with the current time stamp value. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval EFI_SUCCESS The end of the measurement was recorded. + @retval EFI_NOT_FOUND The specified measurement record could not be found. + +**/ +STATIC +EFI_STATUS +EFIAPI +EndGauge ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ) +{ + GAUGE_DATA_ENTRY *GaugeEntryArray; + UINT32 Index; + + if (TimeStamp == 0) { + TimeStamp = GetPerformanceCounter (); + } + + Index = InternalSearchForGaugeEntry (Handle, Token, Module); + if (Index >= mGaugeData->NumberOfEntries) { + return EFI_NOT_FOUND; + } + GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1); + GaugeEntryArray[Index].EndTimeStamp = TimeStamp; + + return EFI_SUCCESS; +} + +/** + Retrieves a previously logged performance measurement. + + Retrieves the performance log entry from the performance log specified by LogEntryKey. + If it stands for a valid entry, then EFI_SUCCESS is returned and + GaugeDataEntry stores the pointer to that entry. + + @param LogEntryKey The key for the previous performance measurement log entry. + If 0, then the first performance measurement log entry is retrieved. + @param GaugeDataEntry The indirect pointer to the gauge data entry specified by LogEntryKey + if the retrieval is successful. + + @retval EFI_SUCCESS The GuageDataEntry is successfuly found based on LogEntryKey. + @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number). + @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number). + @retval EFI_INVALIDE_PARAMETER GaugeDataEntry is NULL. + +**/ +STATIC +EFI_STATUS +EFIAPI +GetGauge ( + IN UINTN LogEntryKey, + OUT GAUGE_DATA_ENTRY **GaugeDataEntry + ) +{ + UINTN NumberOfEntries; + GAUGE_DATA_ENTRY *LogEntryArray; + + NumberOfEntries = (UINTN) (mGaugeData->NumberOfEntries); + if (LogEntryKey > NumberOfEntries) { + return EFI_INVALID_PARAMETER; + } + if (LogEntryKey == NumberOfEntries) { + return EFI_NOT_FOUND; + } + + LogEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1); + + if (GaugeDataEntry == NULL) { + return EFI_INVALID_PARAMETER; + } + *GaugeDataEntry = &LogEntryArray[LogEntryKey]; + + return EFI_SUCCESS; +} + +/** + Dumps all the PEI performance log to DXE performance gauge array. + + This internal function dumps all the PEI performance log to the DXE performance gauge array. + It retrieves the optional GUID HOB for PEI performance and then saves the performance data + to DXE performance data structures. + +**/ +STATIC +VOID +InternalGetPeiPerformance ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + PEI_PERFORMANCE_LOG_HEADER *LogHob; + PEI_PERFORMANCE_LOG_ENTRY *LogEntryArray; + GAUGE_DATA_ENTRY *GaugeEntryArray; + UINT32 Index; + UINT32 NumberOfEntries; + + NumberOfEntries = 0; + GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1); + + // + // Dump PEI Log Entries to DXE Guage Data structure. + // + GuidHob = GetFirstGuidHob (&gPeiPerformanceHobGuid); + if (GuidHob != NULL) { + LogHob = GET_GUID_HOB_DATA (GuidHob); + LogEntryArray = (PEI_PERFORMANCE_LOG_ENTRY *) (LogHob + 1); + GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1); + + NumberOfEntries = LogHob->NumberOfEntries; + for (Index = 0; Index < NumberOfEntries; Index++) { + GaugeEntryArray[Index].Handle = LogEntryArray[Index].Handle; + AsciiStrnCpy (GaugeEntryArray[Index].Token, LogEntryArray[Index].Token, DXE_PERFORMANCE_STRING_LENGTH); + AsciiStrnCpy (GaugeEntryArray[Index].Module, LogEntryArray[Index].Module, DXE_PERFORMANCE_STRING_LENGTH); + GaugeEntryArray[Index].StartTimeStamp = LogEntryArray[Index].StartTimeStamp; + GaugeEntryArray[Index].EndTimeStamp = LogEntryArray[Index].EndTimeStamp; + } + } + mGaugeData->NumberOfEntries = NumberOfEntries; +} + +/** + The constructor function initializes Performance infrastructure for DXE phase. + + The constructor function publishes Performance protocol, allocates memory to log DXE performance + and merges PEI performance data to DXE performance log. + It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeCorePerformanceLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + if (!PerformanceMeasurementEnabled ()) { + // + // Do not initialize performance infrastructure if not required. + // + return EFI_SUCCESS; + } + // + // Install the protocol interfaces. + // + Status = gBS->InstallProtocolInterface ( + &mHandle, + &gPerformanceProtocolGuid, + EFI_NATIVE_INTERFACE, + &mPerformanceInterface + ); + ASSERT_EFI_ERROR (Status); + + mMaxGaugeRecords = INIT_DXE_GAUGE_DATA_ENTRIES + PcdGet8 (PcdMaxPeiPerformanceLogEntries); + + mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords)); + ASSERT (mGaugeData != NULL); + + InternalGetPeiPerformance (); + + return Status; +} + +/** + Adds a record at the end of the performance measurement log + that records the start time of a performance measurement. + + Adds a record to the end of the performance measurement log + that contains the Handle, Token, and Module. + The end time of the new record must be set to zero. + If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record. + If TimeStamp is zero, the start time in the record is filled in with the value + read from the current time stamp. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval RETURN_SUCCESS The start of the measurement was recorded. + @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement. + +**/ +RETURN_STATUS +EFIAPI +StartPerformanceMeasurement ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ) +{ + EFI_STATUS Status; + + Status = StartGauge (Handle, Token, Module, TimeStamp); + return (RETURN_STATUS) Status; +} + +/** + Searches the performance measurement log from the beginning of the log + for the first matching record that contains a zero end time and fills in a valid end time. + + Searches the performance measurement log from the beginning of the log + for the first record that matches Handle, Token, and Module and has an end time value of zero. + If the record can not be found then return RETURN_NOT_FOUND. + If the record is found and TimeStamp is not zero, + then the end time in the record is filled in with the value specified by TimeStamp. + If the record is found and TimeStamp is zero, then the end time in the matching record + is filled in with the current time stamp value. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval RETURN_SUCCESS The end of the measurement was recorded. + @retval RETURN_NOT_FOUND The specified measurement record could not be found. + +**/ +RETURN_STATUS +EFIAPI +EndPerformanceMeasurement ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ) +{ + EFI_STATUS Status; + + Status = EndGauge (Handle, Token, Module, TimeStamp); + return (RETURN_STATUS) Status; +} + +/** + Attempts to retrieve a performance measurement log entry from the performance measurement log. + + Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is + zero on entry, then an attempt is made to retrieve the first entry from the performance log, + and the key for the second entry in the log is returned. If the performance log is empty, + then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance + log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is + returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is + retrieved and an implementation specific non-zero key value that specifies the end of the performance + log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry + is retrieved and zero is returned. In the cases where a performance log entry can be returned, + the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp. + If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT(). + If Handle is NULL, then ASSERT(). + If Token is NULL, then ASSERT(). + If Module is NULL, then ASSERT(). + If StartTimeStamp is NULL, then ASSERT(). + If EndTimeStamp is NULL, then ASSERT(). + + @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve. + 0, then the first performance measurement log entry is retrieved. + On exit, the key of the next performance lof entry entry. + @param Handle Pointer to environment specific context used to identify the component + being measured. + @param Token Pointer to a Null-terminated ASCII string that identifies the component + being measured. + @param Module Pointer to a Null-terminated ASCII string that identifies the module + being measured. + @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement + was started. + @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement + was ended. + + @return The key for the next performance log entry (in general case). + +**/ +UINTN +EFIAPI +GetPerformanceMeasurement ( + IN UINTN LogEntryKey, + OUT CONST VOID **Handle, + OUT CONST CHAR8 **Token, + OUT CONST CHAR8 **Module, + OUT UINT64 *StartTimeStamp, + OUT UINT64 *EndTimeStamp + ) +{ + EFI_STATUS Status; + GAUGE_DATA_ENTRY *GaugeData; + + ASSERT (Handle != NULL); + ASSERT (Token != NULL); + ASSERT (Module != NULL); + ASSERT (StartTimeStamp != NULL); + ASSERT (EndTimeStamp != NULL); + + Status = GetGauge (LogEntryKey++, &GaugeData); + + // + // Make sure that LogEntryKey is a valid log entry key, + // + ASSERT (Status != EFI_INVALID_PARAMETER); + + if (EFI_ERROR (Status)) { + // + // The LogEntryKey is the last entry (equals to the total entry number). + // + return 0; + } + + ASSERT (GaugeData != NULL); + + *Handle = (VOID *) (UINTN) GaugeData->Handle; + *Token = GaugeData->Token; + *Module = GaugeData->Module; + *StartTimeStamp = GaugeData->StartTimeStamp; + *EndTimeStamp = GaugeData->EndTimeStamp; + + return LogEntryKey; +} + +/** + Returns TRUE if the performance measurement macros are enabled. + + This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned. + + @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is set. + @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is clear. + +**/ +BOOLEAN +EFIAPI +PerformanceMeasurementEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0); +} diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf new file mode 100644 index 0000000000..df9f15a9ab --- /dev/null +++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf @@ -0,0 +1,118 @@ +#/** @file +# Component description file for DxeCore Performance Library +# +# This library provides intrastructure for DxeCore to log performance. +# Copyright (c) 2006, Intel Corporation. +# +# All rights reserved. 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeCorePerformanceLib + FILE_GUID = D0F78BBF-0A30-4c63-8A48-0F618A4AFACD + MODULE_TYPE = DXE_CORE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PerformanceLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + CONSTRUCTOR = DxeCorePerformanceLibConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + DxeCorePerformanceLib.c + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + MemoryAllocationLib + UefiBootServicesTableLib + PcdLib + TimerLib + BaseMemoryLib + BaseLib + HobLib + DebugLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gPeiPerformanceHobGuid # ALWAYS_CONSUMED + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gPerformanceProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild.common] + PcdPerformanceLibraryPropertyMask|gEfiMdePkgTokenSpaceGuid + + +################################################################################ +# +# Pcd DYNAMIC - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsDynamic.common] + PcdMaxPeiPerformanceLogEntries|gEfiEdkModulePkgTokenSpaceGuid + diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.msa b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.msa new file mode 100644 index 0000000000..444867af86 --- /dev/null +++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.msa @@ -0,0 +1,90 @@ + + + + DxeCorePerformanceLib + DXE_CORE + D0F78BBF-0A30-4c63-8A48-0F618A4AFACD + 1.0 + Component description file for DxeCore Performance Library + This library provides intrastructure for DxeCore to log performance. + Copyright (c) 2006, Intel Corporation. + All rights reserved. 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + DxeCorePerformanceLib + + + + PerformanceLib + + + DebugLib + + + HobLib + + + BaseLib + + + BaseMemoryLib + + + TimerLib + + + PcdLib + + + UefiBootServicesTableLib + + + MemoryAllocationLib + + + + DxeCorePerformanceLib.c + + + + + + + + gPerformanceProtocolGuid + + + + + gPeiPerformanceHobGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + DxeCorePerformanceLibConstructor + + + + + PcdPerformanceLibraryPropertyMask + gEfiMdePkgTokenSpaceGuid + The bitmask of flags that specify the enable/disable of + Performance Measurement. + + + PcdMaxPeiPerformanceLogEntries + gEfiEdkModulePkgTokenSpaceGuid + Maximun number of performance log entries during PEI phase. + + + \ No newline at end of file diff --git a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c new file mode 100644 index 0000000000..fbfba26c68 --- /dev/null +++ b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c @@ -0,0 +1,266 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. 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. + +Module Name: + + DxePerformanceLib.c + +Abstract: + + Performance Library + +--*/ + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include + +STATIC PERFORMANCE_PROTOCOL *mPerformance = NULL; + +/** + The constructor function caches the pointer to Performance protocol. + + The constructor function locates Performance protocol from protocol database. + It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. + + @retval EFI_SUCCESS Performance protocol is successfully located. + @retval Other Performance protocol is not located to log performance. + +**/ +STATIC +EFI_STATUS +GetPerformanceProtocol ( + VOID + ) +{ + EFI_STATUS Status; + PERFORMANCE_PROTOCOL *Performance; + + if (mPerformance != NULL) { + return EFI_SUCCESS; + } + + Status = gBS->LocateProtocol (&gPerformanceProtocolGuid, NULL, (VOID **) &Performance); + if (!EFI_ERROR (Status)) { + ASSERT (Performance != NULL); + // + // Cache performance protocol. + // + mPerformance = Performance; + } + + return Status; +} + +/** + Creates a record for the beginning of a performance measurement. + + Creates a record that contains the Handle, Token, and Module. + If TimeStamp is not zero, then TimeStamp is added to the record as the start time. + If TimeStamp is zero, then this function reads the current time stamp + and adds that time stamp value to the record as the start time. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval RETURN_SUCCESS The start of the measurement was recorded. + @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement. + +**/ +RETURN_STATUS +EFIAPI +StartPerformanceMeasurement ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ) +{ + EFI_STATUS Status; + + Status = GetPerformanceProtocol (); + if (EFI_ERROR (Status)) { + return RETURN_OUT_OF_RESOURCES; + } + + Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp); + + return (RETURN_STATUS) Status; +} + +/** + Fills in the end time of a performance measurement. + + Looks up the record that matches Handle, Token, and Module. + If the record can not be found then return RETURN_NOT_FOUND. + If the record is found and TimeStamp is not zero, + then TimeStamp is added to the record as the end time. + If the record is found and TimeStamp is zero, then this function reads + the current time stamp and adds that time stamp value to the record as the end time. + If this function is called multiple times for the same record, then the end time is overwritten. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval RETURN_SUCCESS The end of the measurement was recorded. + @retval RETURN_NOT_FOUND The specified measurement record could not be found. + +**/ +RETURN_STATUS +EFIAPI +EndPerformanceMeasurement ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ) +{ + EFI_STATUS Status; + + Status = GetPerformanceProtocol (); + if (EFI_ERROR (Status)) { + return RETURN_NOT_FOUND; + } + + Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp); + + return (RETURN_STATUS) Status; +} + +/** + Attempts to retrieve a performance measurement log entry from the performance measurement log. + + Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is + zero on entry, then an attempt is made to retrieve the first entry from the performance log, + and the key for the second entry in the log is returned. If the performance log is empty, + then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance + log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is + returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is + retrieved and an implementation specific non-zero key value that specifies the end of the performance + log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry + is retrieved and zero is returned. In the cases where a performance log entry can be returned, + the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp. + If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT(). + If Handle is NULL, then ASSERT(). + If Token is NULL, then ASSERT(). + If Module is NULL, then ASSERT(). + If StartTimeStamp is NULL, then ASSERT(). + If EndTimeStamp is NULL, then ASSERT(). + + @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve. + 0, then the first performance measurement log entry is retrieved. + On exit, the key of the next performance lof entry entry. + @param Handle Pointer to environment specific context used to identify the component + being measured. + @param Token Pointer to a Null-terminated ASCII string that identifies the component + being measured. + @param Module Pointer to a Null-terminated ASCII string that identifies the module + being measured. + @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement + was started. + @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement + was ended. + + @return The key for the next performance log entry (in general case). + +**/ +UINTN +EFIAPI +GetPerformanceMeasurement ( + IN UINTN LogEntryKey, + OUT CONST VOID **Handle, + OUT CONST CHAR8 **Token, + OUT CONST CHAR8 **Module, + OUT UINT64 *StartTimeStamp, + OUT UINT64 *EndTimeStamp + ) +{ + EFI_STATUS Status; + GAUGE_DATA_ENTRY *GaugeData; + + ASSERT (Handle != NULL); + ASSERT (Token != NULL); + ASSERT (Module != NULL); + ASSERT (StartTimeStamp != NULL); + ASSERT (EndTimeStamp != NULL); + + Status = GetPerformanceProtocol (); + if (EFI_ERROR (Status)) { + return 0; + } + + Status = mPerformance->GetGauge (LogEntryKey++, &GaugeData); + + // + // Make sure that LogEntryKey is a valid log entry key, + // + ASSERT (Status != EFI_INVALID_PARAMETER); + + if (EFI_ERROR (Status)) { + // + // The LogEntryKey is the last entry (equals to the total entry number). + // + return 0; + } + + ASSERT (GaugeData != NULL); + + *Handle = (VOID *) (UINTN) GaugeData->Handle; + *Token = GaugeData->Token; + *Module = GaugeData->Module; + *StartTimeStamp = GaugeData->StartTimeStamp; + *EndTimeStamp = GaugeData->EndTimeStamp; + + return LogEntryKey; +} + +/** + Returns TRUE if the performance measurement macros are enabled. + + This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned. + + @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is set. + @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is clear. + +**/ +BOOLEAN +EFIAPI +PerformanceMeasurementEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0); +} diff --git a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf new file mode 100644 index 0000000000..95500f38a1 --- /dev/null +++ b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf @@ -0,0 +1,93 @@ +#/** @file +# Component description file for Dxe Performance Library +# +# This library provides intrastructure for Dxe driver to log performance. +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxePerformanceLib + FILE_GUID = 8B8B4CCC-65FC-41a5-8067-308B8E42CCF2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PerformanceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + DxePerformanceLib.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + PcdLib + UefiBootServicesTableLib + DebugLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gPerformanceProtocolGuid # PROTOCOL ALWAYS_CONSUMED + + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild.common] + PcdPerformanceLibraryPropertyMask|gEfiMdePkgTokenSpaceGuid + diff --git a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.msa b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.msa new file mode 100644 index 0000000000..3555a24da0 --- /dev/null +++ b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.msa @@ -0,0 +1,62 @@ + + + + DxePerformanceLib + DXE_DRIVER + 8B8B4CCC-65FC-41a5-8067-308B8E42CCF2 + 1.0 + Component description file for Dxe Performance Library + This library provides intrastructure for Dxe driver to log performance. + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + DxePerformanceLib + + + + PerformanceLib + + + DebugLib + + + UefiBootServicesTableLib + + + PcdLib + + + + DxePerformanceLib.c + + + + + + + + gPerformanceProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + + + PcdPerformanceLibraryPropertyMask + gEfiMdePkgTokenSpaceGuid + The bitmask of flags that specify the enable/disable of + Performance Measurement. + + + \ No newline at end of file diff --git a/MdeModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.inf b/MdeModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.inf new file mode 100644 index 0000000000..89f4e31c75 --- /dev/null +++ b/MdeModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.inf @@ -0,0 +1,81 @@ +#/** @file +# DXE Print library +# +# Print Library based on EFI_PRINT_PROTOCOL +# Copyright (c) 2006 - 2007, Intel Corporation. +# +# All rights reserved. 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EdkDxePrintLib + FILE_GUID = 50bcb105-6634-441d-b403-659110a03ad2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PrintLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + PrintLib.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + UefiBootServicesTableLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiPrintProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/MdeModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.msa b/MdeModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.msa new file mode 100644 index 0000000000..d302a8bae6 --- /dev/null +++ b/MdeModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.msa @@ -0,0 +1,48 @@ + + + + EdkDxePrintLib + DXE_DRIVER + 50bcb105-6634-441d-b403-659110a03ad2 + 1.0 + DXE Print library + Print Library based on EFI_PRINT_PROTOCOL + Copyright (c) 2006 - 2007, Intel Corporation. + All rights reserved. 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + EdkDxePrintLib + + + + PrintLib + + + UefiBootServicesTableLib + + + + PrintLib.c + + + + + + + + gEfiPrintProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + \ No newline at end of file diff --git a/MdeModulePkg/Library/EdkDxePrintLib/PrintLib.c b/MdeModulePkg/Library/EdkDxePrintLib/PrintLib.c new file mode 100644 index 0000000000..7dbbcb7d73 --- /dev/null +++ b/MdeModulePkg/Library/EdkDxePrintLib/PrintLib.c @@ -0,0 +1,159 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. 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. + +Module Name: + + PrintLib.c + +Abstract: + + Print Library + +--*/ + + + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include + +static EFI_PRINT_PROTOCOL *gPrintProtocol = NULL; + +UINTN +UnicodeVSPrint ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN const CHAR16 *FormatString, + IN VA_LIST Marker + ) +/*++ + +Routine Description: + + VSPrint function to process format and place the results in Buffer. Since a + VA_LIST is used this rountine allows the nesting of Vararg routines. Thus + this is the main print working routine + +Arguments: + + StartOfBuffer - Unicode buffer to print the results of the parsing of Format into. + + BufferSize - Maximum number of characters to put into buffer. Zero means + no limit. + + FormatString - Unicode format string see file header for more details. + + Marker - Vararg list consumed by processing Format. + +Returns: + + Number of characters printed. + +--*/ +{ + EFI_STATUS Status; + + if (gPrintProtocol == NULL) { + Status = gBS->LocateProtocol ( + &gEfiPrintProtocolGuid, + NULL, + (VOID **)&gPrintProtocol + ); + if (EFI_ERROR (Status)) { + gPrintProtocol = NULL; + } + if (gPrintProtocol == NULL) { + return 0; + } + } + return gPrintProtocol->VSPrint (StartOfBuffer, BufferSize, FormatString, Marker); +} + +UINTN +UnicodeSPrint ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN const CHAR16 *FormatString, + ... + ) + +{ + UINTN Return; + VA_LIST Marker; + + VA_START (Marker, FormatString); + Return = UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); + VA_END (Marker); + return Return; +} + +UINTN +AsciiVSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN const CHAR8 *FormatString, + IN VA_LIST Marker + ) +/*++ + +Routine Description: + + VSPrint function to process format and place the results in Buffer. Since a + VA_LIST is used this rountine allows the nesting of Vararg routines. Thus + this is the main print working routine + +Arguments: + + StartOfBuffer - Unicode buffer to print the results of the parsing of Format into. + + BufferSize - Maximum number of characters to put into buffer. Zero means + no limit. + + FormatString - Unicode format string see file header for more details. + + Marker - Vararg list consumed by processing Format. + +Returns: + + Number of characters printed. + +--*/ +{ + return 0; +} + +UINTN +AsciiSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN const CHAR8 *FormatString, + ... + ) + +{ + UINTN Return; + VA_LIST Marker; + + VA_START (Marker, FormatString); + Return = AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); + VA_END (Marker); + return Return; +} diff --git a/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c new file mode 100644 index 0000000000..aa231849f6 --- /dev/null +++ b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c @@ -0,0 +1,352 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. 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. + +Module Name: + + PeiPerformanceLib.c + +Abstract: + + Performance Library + +--*/ + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include + + +/** + Gets PEI the GUID HOB for PEI performance. + + This internal function searches for the GUID HOB for PEI performance. + If that GUID HOB is not found, it will build a new one. + It returns the data area of that GUID HOB to record performance log. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + + @retval The index of log entry in the array. + +**/ +STATIC +PEI_PERFORMANCE_LOG_HEADER * +InternalGetPerformanceHobLog ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog; + UINTN PeiPerformanceLogSize; + + GuidHob = GetFirstGuidHob (&gPeiPerformanceHobGuid); + + if (GuidHob != NULL) { + // + // PEI Performance HOB was found, then return the existing one. + // + PeiPerformanceLog = GET_GUID_HOB_DATA (GuidHob); + } else { + // + // PEI Performance HOB was not found, then build one. + // + PeiPerformanceLogSize = sizeof (PEI_PERFORMANCE_LOG_HEADER) + + sizeof (PEI_PERFORMANCE_LOG_ENTRY) * PcdGet8 (PcdMaxPeiPerformanceLogEntries); + PeiPerformanceLog = BuildGuidHob (&gPeiPerformanceHobGuid, PeiPerformanceLogSize); + PeiPerformanceLog = ZeroMem (PeiPerformanceLog, PeiPerformanceLogSize); + } + + return PeiPerformanceLog; +} + +/** + Searches in the log array with keyword Handle, Token and Module. + + This internal function searches for the log entry in the log array. + If there is an entry that exactly matches the given key word triple + and its end time stamp is zero, then the index of that log entry is returned; + otherwise, the the number of log entries in the array is returned. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + + @retval The index of log entry in the array. + +**/ +STATIC +UINT32 +InternalSearchForLogEntry ( + IN PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog, + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module OPTIONAL + ) +{ + UINT32 Index; + UINT32 NumberOfEntries; + PEI_PERFORMANCE_LOG_ENTRY *LogEntryArray; + + + if (Token == NULL) { + Token = ""; + } + if (Module == NULL) { + Module = ""; + } + NumberOfEntries = PeiPerformanceLog->NumberOfEntries; + LogEntryArray = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1); + + for (Index = 0; Index < NumberOfEntries; Index++) { + if ((LogEntryArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) && + AsciiStrnCmp (LogEntryArray[Index].Token, Token, PEI_PERFORMANCE_STRING_LENGTH) == 0 && + AsciiStrnCmp (LogEntryArray[Index].Module, Module, PEI_PERFORMANCE_STRING_LENGTH) == 0 && + LogEntryArray[Index].EndTimeStamp == 0 + ) { + break; + } + } + return Index; +} + +/** + Creates a record for the beginning of a performance measurement. + + Creates a record that contains the Handle, Token, and Module. + If TimeStamp is not zero, then TimeStamp is added to the record as the start time. + If TimeStamp is zero, then this function reads the current time stamp + and adds that time stamp value to the record as the start time. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval RETURN_SUCCESS The start of the measurement was recorded. + @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement. + +**/ +RETURN_STATUS +EFIAPI +StartPerformanceMeasurement ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ) +{ + PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog; + PEI_PERFORMANCE_LOG_ENTRY *LogEntryArray; + UINT32 Index; + + PeiPerformanceLog = InternalGetPerformanceHobLog (); + + if (PeiPerformanceLog->NumberOfEntries >= PcdGet8 (PcdMaxPeiPerformanceLogEntries)) { + return RETURN_OUT_OF_RESOURCES; + } + Index = PeiPerformanceLog->NumberOfEntries++; + LogEntryArray = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1); + LogEntryArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle; + + if (Token != NULL) { + AsciiStrnCpy (LogEntryArray[Index].Token, Token, PEI_PERFORMANCE_STRING_LENGTH); + } + if (Module != NULL) { + AsciiStrnCpy (LogEntryArray[Index].Module, Module, PEI_PERFORMANCE_STRING_LENGTH); + } + + if (TimeStamp == 0) { + TimeStamp = GetPerformanceCounter (); + } + LogEntryArray[Index].StartTimeStamp = TimeStamp; + + return RETURN_SUCCESS; +} + +/** + Fills in the end time of a performance measurement. + + Looks up the record that matches Handle, Token, and Module. + If the record can not be found then return RETURN_NOT_FOUND. + If the record is found and TimeStamp is not zero, + then TimeStamp is added to the record as the end time. + If the record is found and TimeStamp is zero, then this function reads + the current time stamp and adds that time stamp value to the record as the end time. + If this function is called multiple times for the same record, then the end time is overwritten. + + @param Handle Pointer to environment specific context used + to identify the component being measured. + @param Token Pointer to a Null-terminated ASCII string + that identifies the component being measured. + @param Module Pointer to a Null-terminated ASCII string + that identifies the module being measured. + @param TimeStamp 64-bit time stamp. + + @retval RETURN_SUCCESS The end of the measurement was recorded. + @retval RETURN_NOT_FOUND The specified measurement record could not be found. + +**/ +RETURN_STATUS +EFIAPI +EndPerformanceMeasurement ( + IN CONST VOID *Handle, OPTIONAL + IN CONST CHAR8 *Token, OPTIONAL + IN CONST CHAR8 *Module, OPTIONAL + IN UINT64 TimeStamp + ) +{ + PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog; + PEI_PERFORMANCE_LOG_ENTRY *LogEntryArray; + UINT32 Index; + + if (TimeStamp == 0) { + TimeStamp = GetPerformanceCounter (); + } + + PeiPerformanceLog = InternalGetPerformanceHobLog (); + Index = InternalSearchForLogEntry (PeiPerformanceLog, Handle, Token, Module); + if (Index >= PeiPerformanceLog->NumberOfEntries) { + return RETURN_NOT_FOUND; + } + LogEntryArray = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1); + LogEntryArray[Index].EndTimeStamp = TimeStamp; + + return RETURN_SUCCESS; +} + +/** + Attempts to retrieve a performance measurement log entry from the performance measurement log. + + Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is + zero on entry, then an attempt is made to retrieve the first entry from the performance log, + and the key for the second entry in the log is returned. If the performance log is empty, + then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance + log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is + returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is + retrieved and an implementation specific non-zero key value that specifies the end of the performance + log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry + is retrieved and zero is returned. In the cases where a performance log entry can be returned, + the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp. + If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT(). + If Handle is NULL, then ASSERT(). + If Token is NULL, then ASSERT(). + If Module is NULL, then ASSERT(). + If StartTimeStamp is NULL, then ASSERT(). + If EndTimeStamp is NULL, then ASSERT(). + + @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve. + 0, then the first performance measurement log entry is retrieved. + On exit, the key of the next performance lof entry entry. + @param Handle Pointer to environment specific context used to identify the component + being measured. + @param Token Pointer to a Null-terminated ASCII string that identifies the component + being measured. + @param Module Pointer to a Null-terminated ASCII string that identifies the module + being measured. + @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement + was started. + @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement + was ended. + + @return The key for the next performance log entry (in general case). + +**/ +UINTN +EFIAPI +GetPerformanceMeasurement ( + IN UINTN LogEntryKey, + OUT CONST VOID **Handle, + OUT CONST CHAR8 **Token, + OUT CONST CHAR8 **Module, + OUT UINT64 *StartTimeStamp, + OUT UINT64 *EndTimeStamp + ) +{ + PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog; + PEI_PERFORMANCE_LOG_ENTRY *CurrentLogEntry; + PEI_PERFORMANCE_LOG_ENTRY *LogEntryArray; + UINTN NumberOfEntries; + + ASSERT (Handle != NULL); + ASSERT (Token != NULL); + ASSERT (Module != NULL); + ASSERT (StartTimeStamp != NULL); + ASSERT (EndTimeStamp != NULL); + + PeiPerformanceLog = InternalGetPerformanceHobLog (); + + NumberOfEntries = (UINTN) (PeiPerformanceLog->NumberOfEntries); + LogEntryArray = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1); + // + // Make sure that LogEntryKey is a valid log entry key. + // + ASSERT (LogEntryKey <= NumberOfEntries); + + if (LogEntryKey == NumberOfEntries) { + return 0; + } + + CurrentLogEntry = &(LogEntryArray[LogEntryKey++]); + + *Handle = (VOID *) (UINTN) (CurrentLogEntry->Handle); + *Token = CurrentLogEntry->Token; + *Module = CurrentLogEntry->Module; + *StartTimeStamp = CurrentLogEntry->StartTimeStamp; + *EndTimeStamp = CurrentLogEntry->EndTimeStamp; + + return LogEntryKey; +} + +/** + Returns TRUE if the performance measurement macros are enabled. + + This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned. + + @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is set. + @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of + PcdPerformanceLibraryPropertyMask is clear. + +**/ +BOOLEAN +EFIAPI +PerformanceMeasurementEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0); +} diff --git a/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf new file mode 100644 index 0000000000..07c08413d6 --- /dev/null +++ b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf @@ -0,0 +1,105 @@ +#/** @file +# Memory-only library functions with no library constructor/destructor +# +# This module provides the performance measurement interfaces in PEI phase, it is one instance of Performance Libarary. +# Copyright (c) 2006, Intel Corporation +# +# All rights reserved. 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiPerformanceLib + FILE_GUID = F72DE735-B24F-4ef6-897F-70A85D01A047 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PerformanceLib|PEIM PEI_CORE + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + PeiPerformanceLib.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + BaseMemoryLib + PcdLib + TimerLib + BaseLib + HobLib + DebugLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gPeiPerformanceHobGuid # SOMETIMES_CONSUMED + + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild.common] + PcdPerformanceLibraryPropertyMask|gEfiMdePkgTokenSpaceGuid + + +################################################################################ +# +# Pcd DYNAMIC - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsDynamic.common] + PcdMaxPeiPerformanceLogEntries|gEfiEdkModulePkgTokenSpaceGuid + diff --git a/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.msa b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.msa new file mode 100644 index 0000000000..85ce0ad520 --- /dev/null +++ b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.msa @@ -0,0 +1,76 @@ + + + + PeiPerformanceLib + PEIM + F72DE735-B24F-4ef6-897F-70A85D01A047 + 1.0 + Memory-only library functions with no library constructor/destructor + This module provides the performance measurement interfaces in PEI phase, it is one instance of Performance Libarary. + Copyright (c) 2006, Intel Corporation + All rights reserved. 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + PeiPerformanceLib + + + + PerformanceLib + + + DebugLib + + + HobLib + + + BaseLib + + + TimerLib + + + PcdLib + + + BaseMemoryLib + + + + PeiPerformanceLib.c + + + + + + + + gPeiPerformanceHobGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + + + PcdPerformanceLibraryPropertyMask + gEfiMdePkgTokenSpaceGuid + The bitmask of flags that specify the enable/disable of + Performance Measurement. + + + PcdMaxPeiPerformanceLogEntries + gEfiEdkModulePkgTokenSpaceGuid + Maximun number of performance log entries during PEI phase. + + + \ No newline at end of file diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index cfc2b8970e..31ec78dd4f 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -316,6 +316,7 @@ PcdFlashNvStorageFtwWorkingSize|gEfiGenericPlatformTokenSpaceGuid|0x0 PcdFlashNvStorageVariableBase|gEfiGenericPlatformTokenSpaceGuid|0x0 PcdFlashNvStorageVariableSize|gEfiGenericPlatformTokenSpaceGuid|0x0 + PcdMaxPeiPerformanceLogEntries|gEfiEdkModulePkgTokenSpaceGuid|28 [PcdsPatchableInModule.common] PcdDebugPrintErrorLevel|gEfiMdePkgTokenSpaceGuid|0x80000000 @@ -332,6 +333,10 @@ [Components.Ia32] ${WORKSPACE}/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf + ${WORKSPACE}/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf + ${WORKSPACE}/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + ${WORKSPACE}/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf + ${WORKSPACE}/MdeModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.inf ${WORKSPACE}/MdeModulePkg/Application/HelloWorld/HelloWorld.inf ${WORKSPACE}/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf ${WORKSPACE}/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.inf