2 Performance library instance used by SMM Core.
4 This library provides the performance measurement interfaces and initializes performance
5 logging for the SMM phase.
6 It initializes SMM phase performance logging by publishing the SMM Performance and PerformanceEx Protocol,
7 which is consumed by SmmPerformanceLib to logging performance data in SMM phase.
9 This library is mainly used by SMM Core to start performance logging to ensure that
10 SMM Performance and PerformanceEx Protocol are installed at the very beginning of SMM phase.
12 Caution: This module requires additional review when modified.
13 This driver will have external input - performance data and communicate buffer in SMM mode.
14 This external input must be validated carefully to avoid security issue like
15 buffer overflow, integer overflow.
17 SmmPerformanceHandlerEx(), SmmPerformanceHandler() will receive untrusted input and do basic validation.
19 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
20 This program and the accompanying materials
21 are licensed and made available under the terms and conditions of the BSD License
22 which accompanies this distribution. The full text of the license may be found at
23 http://opensource.org/licenses/bsd-license.php
25 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
26 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
31 #include "SmmCorePerformanceLibInternal.h"
33 #define STRING_SIZE (FPDT_STRING_EVENT_RECORD_NAME_LENGTH * sizeof (CHAR8))
34 #define FIRMWARE_RECORD_BUFFER 0x1000
35 #define CACHE_HANDLE_GUID_COUNT 0x100
37 SMM_BOOT_PERFORMANCE_TABLE
*mSmmBootPerformanceTable
= NULL
;
41 CHAR8 NameString
[FPDT_STRING_EVENT_RECORD_NAME_LENGTH
];
45 HANDLE_GUID_MAP mCacheHandleGuidTable
[CACHE_HANDLE_GUID_COUNT
];
46 UINTN mCachePairCount
= 0;
48 UINT32 mPerformanceLength
= 0;
49 UINT32 mMaxPerformanceLength
= 0;
50 UINT32 mLoadImageCount
= 0;
51 BOOLEAN mFpdtDataIsReported
= FALSE
;
52 BOOLEAN mLackSpaceIsReport
= FALSE
;
53 CHAR8
*mPlatformLanguage
= NULL
;
54 SPIN_LOCK mSmmFpdtLock
;
55 PERFORMANCE_PROPERTY mPerformanceProperty
;
56 UINT32 mCachedLength
= 0;
59 // Interfaces for SMM PerformanceMeasurement Protocol.
61 EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL mPerformanceMeasurementInterface
= {
62 CreatePerformanceMeasurement
,
66 Return the pointer to the FPDT record in the allocated memory.
68 @param RecordSize The size of FPDT record.
69 @param FpdtRecordPtr Pointer the FPDT record in the allocated memory.
71 @retval EFI_SUCCESS Successfully get the pointer to the FPDT record.
72 @retval EFI_OUT_OF_RESOURCES Ran out of space to store the records.
77 IN OUT FPDT_RECORD_PTR
*FpdtRecordPtr
80 if (mFpdtDataIsReported
) {
82 // Append Boot records after Smm boot performance records have been reported.
84 if (mPerformanceLength
+ RecordSize
> mMaxPerformanceLength
) {
85 if (!mLackSpaceIsReport
) {
86 DEBUG ((DEBUG_INFO
, "SmmCorePerformanceLib: No enough space to save boot records\n"));
87 mLackSpaceIsReport
= TRUE
;
89 return EFI_OUT_OF_RESOURCES
;
92 // Covert buffer to FPDT Ptr Union type.
94 FpdtRecordPtr
->RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*)((UINT8
*)mSmmBootPerformanceTable
+ mSmmBootPerformanceTable
->Header
.Length
);
98 // Check if pre-allocated buffer is full
100 if (mPerformanceLength
+ RecordSize
> mMaxPerformanceLength
) {
101 mSmmBootPerformanceTable
= ReallocatePool (
103 mPerformanceLength
+ sizeof (SMM_BOOT_PERFORMANCE_TABLE
) + RecordSize
+ FIRMWARE_RECORD_BUFFER
,
104 mSmmBootPerformanceTable
107 if (mSmmBootPerformanceTable
== NULL
) {
108 return EFI_OUT_OF_RESOURCES
;
110 mSmmBootPerformanceTable
->Header
.Length
= sizeof (SMM_BOOT_PERFORMANCE_TABLE
) + mPerformanceLength
;
111 mMaxPerformanceLength
= mPerformanceLength
+ sizeof (SMM_BOOT_PERFORMANCE_TABLE
) + RecordSize
+ FIRMWARE_RECORD_BUFFER
;
114 // Covert buffer to FPDT Ptr Union type.
116 FpdtRecordPtr
->RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*)((UINT8
*)mSmmBootPerformanceTable
+ mSmmBootPerformanceTable
->Header
.Length
);
118 FpdtRecordPtr
->RecordHeader
->Length
= 0;
124 Check whether the Token is a known one which is uesed by core.
126 @param Token Pointer to a Null-terminated ASCII string
128 @retval TRUE Is a known one used by core.
129 @retval FALSE Not a known one.
134 IN CONST CHAR8
*Token
141 if (AsciiStrCmp (Token
, SEC_TOK
) == 0 ||
142 AsciiStrCmp (Token
, PEI_TOK
) == 0 ||
143 AsciiStrCmp (Token
, DXE_TOK
) == 0 ||
144 AsciiStrCmp (Token
, BDS_TOK
) == 0 ||
145 AsciiStrCmp (Token
, DRIVERBINDING_START_TOK
) == 0 ||
146 AsciiStrCmp (Token
, DRIVERBINDING_SUPPORT_TOK
) == 0 ||
147 AsciiStrCmp (Token
, DRIVERBINDING_STOP_TOK
) == 0 ||
148 AsciiStrCmp (Token
, LOAD_IMAGE_TOK
) == 0 ||
149 AsciiStrCmp (Token
, START_IMAGE_TOK
) == 0 ||
150 AsciiStrCmp (Token
, PEIM_TOK
) == 0) {
158 Check whether the ID is a known one which map to the known Token.
160 @param Identifier 32-bit identifier.
162 @retval TRUE Is a known one used by core.
163 @retval FALSE Not a known one.
171 if (Identifier
== MODULE_START_ID
||
172 Identifier
== MODULE_END_ID
||
173 Identifier
== MODULE_LOADIMAGE_START_ID
||
174 Identifier
== MODULE_LOADIMAGE_END_ID
||
175 Identifier
== MODULE_DB_START_ID
||
176 Identifier
== MODULE_DB_END_ID
||
177 Identifier
== MODULE_DB_SUPPORT_START_ID
||
178 Identifier
== MODULE_DB_SUPPORT_END_ID
||
179 Identifier
== MODULE_DB_STOP_START_ID
||
180 Identifier
== MODULE_DB_STOP_END_ID
) {
188 Get the FPDT record identifier.
190 @param Attribute The attribute of the Record.
191 PerfStartEntry: Start Record.
192 PerfEndEntry: End Record.
193 @param Handle Pointer to environment specific context used to identify the component being measured.
194 @param String Pointer to a Null-terminated ASCII string that identifies the component being measured.
195 @param ProgressID On return, pointer to the ProgressID.
197 @retval EFI_SUCCESS Get record info successfully.
198 @retval EFI_INVALID_PARAMETER No matched FPDT record.
203 IN PERF_MEASUREMENT_ATTRIBUTE Attribute
,
204 IN CONST VOID
*Handle
,
205 IN CONST CHAR8
*String
,
206 OUT UINT16
*ProgressID
212 if (String
!= NULL
) {
213 if (AsciiStrCmp (String
, START_IMAGE_TOK
) == 0) { // "StartImage:"
214 if (Attribute
== PerfStartEntry
) {
215 *ProgressID
= MODULE_START_ID
;
217 *ProgressID
= MODULE_END_ID
;
219 } else if (AsciiStrCmp (String
, LOAD_IMAGE_TOK
) == 0) { // "LoadImage:"
220 if (Attribute
== PerfStartEntry
) {
221 *ProgressID
= MODULE_LOADIMAGE_START_ID
;
223 *ProgressID
= MODULE_LOADIMAGE_END_ID
;
225 } else { // Pref used in Modules
226 if (Attribute
== PerfStartEntry
) {
227 *ProgressID
= PERF_INMODULE_START_ID
;
229 *ProgressID
= PERF_INMODULE_END_ID
;
232 } else if (Handle
!= NULL
) { // Pref used in Modules
233 if (Attribute
== PerfStartEntry
) {
234 *ProgressID
= PERF_INMODULE_START_ID
;
236 *ProgressID
= PERF_INMODULE_END_ID
;
239 return EFI_UNSUPPORTED
;
245 Get a human readable module name and module guid for the given image handle.
246 If module name can't be found, "" string will return.
247 If module guid can't be found, Zero Guid will return.
249 @param Handle Image handle or Controller handle.
250 @param NameString The ascii string will be filled into it. If not found, null string will return.
251 @param BufferSize Size of the input NameString buffer.
252 @param ModuleGuid Point to the guid buffer to store the got module guid value.
254 @retval EFI_SUCCESS Successfully get module name and guid.
255 @retval EFI_INVALID_PARAMETER The input parameter NameString is NULL.
256 @retval other value Module Name can't be got.
260 GetModuleInfoFromHandle (
261 IN EFI_HANDLE Handle
,
262 OUT CHAR8
*NameString
,
264 OUT EFI_GUID
*ModuleGuid OPTIONAL
268 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
269 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
275 BOOLEAN ModuleGuidIsGet
;
278 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
280 if (NameString
== NULL
|| BufferSize
== 0) {
281 return EFI_INVALID_PARAMETER
;
285 // Try to get the ModuleGuid and name string form the caached array.
287 if (mCachePairCount
> 0) {
288 for (Count
= mCachePairCount
- 1; Count
>= 0; Count
--) {
289 if (Handle
== mCacheHandleGuidTable
[Count
].Handle
) {
290 CopyGuid (ModuleGuid
, &mCacheHandleGuidTable
[Count
].ModuleGuid
);
291 AsciiStrCpyS (NameString
, FPDT_STRING_EVENT_RECORD_NAME_LENGTH
, mCacheHandleGuidTable
[Count
].NameString
);
297 Status
= EFI_INVALID_PARAMETER
;
299 ModuleGuidIsGet
= FALSE
;
302 // Initialize GUID as zero value.
304 TempGuid
= &gZeroGuid
;
306 // Initialize it as "" string.
310 if (Handle
!= NULL
) {
312 // Try Handle as ImageHandle.
314 Status
= gBS
->HandleProtocol (
316 &gEfiLoadedImageProtocolGuid
,
317 (VOID
**) &LoadedImage
320 if (EFI_ERROR (Status
)) {
322 // Try Handle as Controller Handle
324 Status
= gBS
->OpenProtocol (
326 &gEfiDriverBindingProtocolGuid
,
327 (VOID
**) &DriverBinding
,
330 EFI_OPEN_PROTOCOL_GET_PROTOCOL
332 if (!EFI_ERROR (Status
)) {
334 // Get Image protocol from ImageHandle
336 Status
= gBS
->HandleProtocol (
337 DriverBinding
->ImageHandle
,
338 &gEfiLoadedImageProtocolGuid
,
339 (VOID
**) &LoadedImage
345 if (!EFI_ERROR (Status
) && LoadedImage
!= NULL
) {
347 // Get Module Guid from DevicePath.
349 if (LoadedImage
->FilePath
!= NULL
&&
350 LoadedImage
->FilePath
->Type
== MEDIA_DEVICE_PATH
&&
351 LoadedImage
->FilePath
->SubType
== MEDIA_PIWG_FW_FILE_DP
354 // Determine GUID associated with module logging performance
356 ModuleGuidIsGet
= TRUE
;
357 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LoadedImage
->FilePath
;
358 TempGuid
= &FvFilePath
->FvFileName
;
362 // Method 1 Get Module Name from PDB string.
364 PdbFileName
= PeCoffLoaderGetPdbPointer (LoadedImage
->ImageBase
);
365 if (PdbFileName
!= NULL
&& BufferSize
> 0) {
367 for (Index
= 0; PdbFileName
[Index
] != 0; Index
++) {
368 if ((PdbFileName
[Index
] == '\\') || (PdbFileName
[Index
] == '/')) {
369 StartIndex
= Index
+ 1;
373 // Copy the PDB file name to our temporary string.
374 // If the length is bigger than BufferSize, trim the redudant characters to avoid overflow in array boundary.
376 for (Index
= 0; Index
< BufferSize
- 1; Index
++) {
377 NameString
[Index
] = PdbFileName
[Index
+ StartIndex
];
378 if (NameString
[Index
] == 0 || NameString
[Index
] == '.') {
379 NameString
[Index
] = 0;
384 if (Index
== BufferSize
- 1) {
385 NameString
[Index
] = 0;
388 // Module Name is got.
394 if (ModuleGuidIsGet
) {
396 // Method 2 Try to get the image's FFS UI section by image GUID
400 Status
= GetSectionFromAnyFv (
402 EFI_SECTION_USER_INTERFACE
,
404 (VOID
**) &StringPtr
,
408 if (!EFI_ERROR (Status
)) {
410 // Method 3. Get the name string from FFS UI section
412 for (Index
= 0; Index
< BufferSize
- 1 && StringPtr
[Index
] != 0; Index
++) {
413 NameString
[Index
] = (CHAR8
) StringPtr
[Index
];
415 NameString
[Index
] = 0;
416 FreePool (StringPtr
);
424 if (ModuleGuid
!= NULL
) {
425 CopyGuid (ModuleGuid
, TempGuid
);
426 if (IsZeroGuid(TempGuid
) && (Handle
!= NULL
) && !ModuleGuidIsGet
) {
428 CopyGuid (ModuleGuid
, (EFI_GUID
*) Handle
);
433 // Cache the Handle and Guid pairs.
435 if (mCachePairCount
< CACHE_HANDLE_GUID_COUNT
) {
436 mCacheHandleGuidTable
[mCachePairCount
].Handle
= Handle
;
437 CopyGuid (&mCacheHandleGuidTable
[mCachePairCount
].ModuleGuid
, ModuleGuid
);
438 AsciiStrCpyS (mCacheHandleGuidTable
[mCachePairCount
].NameString
, FPDT_STRING_EVENT_RECORD_NAME_LENGTH
, NameString
);
446 Copies the string from Source into Destination and updates Length with the
449 @param Destination - destination of the string copy
450 @param Source - pointer to the source string which will get copied
451 @param Length - pointer to a length variable to be updated
455 CopyStringIntoPerfRecordAndUpdateLength (
456 IN OUT CHAR8
*Destination
,
457 IN CONST CHAR8
*Source
,
464 ASSERT (Source
!= NULL
);
466 if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly
)) {
467 DestMax
= STRING_SIZE
;
469 DestMax
= AsciiStrSize (Source
);
470 if (DestMax
> STRING_SIZE
) {
471 DestMax
= STRING_SIZE
;
474 StringLen
= AsciiStrLen (Source
);
475 if (StringLen
>= DestMax
) {
476 StringLen
= DestMax
-1;
479 AsciiStrnCpyS(Destination
, DestMax
, Source
, StringLen
);
480 *Length
+= (UINT8
)DestMax
;
486 Create performance record with event description and a timestamp.
488 @param CallerIdentifier - Image handle or pointer to caller ID GUID.
489 @param Guid - Pointer to a GUID.
490 @param String - Pointer to a string describing the measurement.
491 @param Ticker - 64-bit time stamp.
492 @param Address - Pointer to a location in memory relevant to the measurement.
493 @param PerfId - Performance identifier describing the type of measurement.
494 @param Attribute - The attribute of the measurement. According to attribute can create a start
495 record for PERF_START/PERF_START_EX, or a end record for PERF_END/PERF_END_EX,
496 or a general record for other Perf macros.
498 @retval EFI_SUCCESS - Successfully created performance record.
499 @retval EFI_OUT_OF_RESOURCES - Ran out of space to store the records.
500 @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
501 pointer or invalid PerfId.
503 @retval EFI_SUCCESS - Successfully created performance record
504 @retval EFI_OUT_OF_RESOURCES - Ran out of space to store the records
505 @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
506 pointer or invalid PerfId
511 IN CONST VOID
*CallerIdentifier
, OPTIONAL
512 IN CONST VOID
*Guid
, OPTIONAL
513 IN CONST CHAR8
*String
, OPTIONAL
515 IN UINT64 Address
, OPTIONAL
517 IN PERF_MEASUREMENT_ATTRIBUTE Attribute
523 CHAR8 ModuleName
[FPDT_STRING_EVENT_RECORD_NAME_LENGTH
];
524 FPDT_RECORD_PTR FpdtRecordPtr
;
525 FPDT_RECORD_PTR CachedFpdtRecordPtr
;
527 CONST CHAR8
*StringPtr
;
533 ZeroMem (ModuleName
, sizeof (ModuleName
));
536 // 1. Get the Perf Id for records from PERF_START/PERF_END, PERF_START_EX/PERF_END_EX.
537 // notes: For other Perf macros (Attribute == PerfEntry), their Id is known.
539 if (Attribute
!= PerfEntry
) {
541 // If PERF_START_EX()/PERF_END_EX() have specified the ProgressID,it has high priority.
542 // !!! Note: If the Perf is not the known Token used in the core but have same
543 // ID with the core Token, this case will not be supported.
544 // And in currtnt usage mode, for the unkown ID, there is a general rule:
545 // If it is start pref: the lower 4 bits of the ID should be 0.
546 // If it is end pref: the lower 4 bits of the ID should not be 0.
547 // If input ID doesn't follow the rule, we will adjust it.
549 if ((PerfId
!= 0) && (IsKnownID (PerfId
)) && (!IsKnownTokens (String
))) {
550 return EFI_INVALID_PARAMETER
;
551 } else if ((PerfId
!= 0) && (!IsKnownID (PerfId
)) && (!IsKnownTokens (String
))) {
552 if ((Attribute
== PerfStartEntry
) && ((PerfId
& 0x000F) != 0)) {
554 } else if ((Attribute
== PerfEndEntry
) && ((PerfId
& 0x000F) == 0)) {
560 // Get ProgressID form the String Token.
562 Status
= GetFpdtRecordId (Attribute
, CallerIdentifier
, String
, &ProgressId
);
563 if (EFI_ERROR (Status
)) {
571 // 2. Get the buffer to store the FPDT record.
573 Status
= GetFpdtRecordPtr (FPDT_MAX_PERF_RECORD_SIZE
, &FpdtRecordPtr
);
574 if (EFI_ERROR (Status
)) {
579 // 3. Get the TimeStamp.
582 Ticker
= GetPerformanceCounter ();
583 TimeStamp
= GetTimeInNanoSecond (Ticker
);
584 } else if (Ticker
== 1) {
587 TimeStamp
= GetTimeInNanoSecond (Ticker
);
591 // 4. Fill in the FPDT record according to different Performance Identifier.
594 case MODULE_START_ID
:
596 GetModuleInfoFromHandle ((EFI_HANDLE
*)CallerIdentifier
, ModuleName
, sizeof (ModuleName
), &ModuleGuid
);
597 StringPtr
= ModuleName
;
599 // Cache the offset of start image start record and use to update the start image end record if needed.
601 if (PerfId
== MODULE_START_ID
&& Attribute
== PerfEntry
) {
602 mCachedLength
= mSmmBootPerformanceTable
->Header
.Length
;
604 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly
)) {
605 FpdtRecordPtr
.GuidEvent
->Header
.Type
= FPDT_GUID_EVENT_TYPE
;
606 FpdtRecordPtr
.GuidEvent
->Header
.Length
= sizeof (FPDT_GUID_EVENT_RECORD
);
607 FpdtRecordPtr
.GuidEvent
->Header
.Revision
= FPDT_RECORD_REVISION_1
;
608 FpdtRecordPtr
.GuidEvent
->ProgressID
= PerfId
;
609 FpdtRecordPtr
.GuidEvent
->Timestamp
= TimeStamp
;
610 CopyMem (&FpdtRecordPtr
.GuidEvent
->Guid
, &ModuleGuid
, sizeof (FpdtRecordPtr
.GuidEvent
->Guid
));
611 if (CallerIdentifier
== NULL
&& PerfId
== MODULE_END_ID
&& mCachedLength
!= 0) {
612 CachedFpdtRecordPtr
.RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*)((UINT8
*)mSmmBootPerformanceTable
+ mCachedLength
);
613 CopyMem (&FpdtRecordPtr
.GuidEvent
->Guid
, &CachedFpdtRecordPtr
.GuidEvent
->Guid
, sizeof (FpdtRecordPtr
.GuidEvent
->Guid
));
619 case MODULE_LOADIMAGE_START_ID
:
620 case MODULE_LOADIMAGE_END_ID
:
621 GetModuleInfoFromHandle ((EFI_HANDLE
*)CallerIdentifier
, ModuleName
, sizeof (ModuleName
), &ModuleGuid
);
622 StringPtr
= ModuleName
;
623 if (PerfId
== MODULE_LOADIMAGE_START_ID
) {
626 // Cache the offset of load image start record and use to be updated by the load image end record if needed.
628 if (CallerIdentifier
== NULL
&& Attribute
== PerfEntry
) {
629 mCachedLength
= mSmmBootPerformanceTable
->Header
.Length
;
632 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly
)) {
633 FpdtRecordPtr
.GuidQwordEvent
->Header
.Type
= FPDT_GUID_QWORD_EVENT_TYPE
;
634 FpdtRecordPtr
.GuidQwordEvent
->Header
.Length
= sizeof (FPDT_GUID_QWORD_EVENT_RECORD
);
635 FpdtRecordPtr
.GuidQwordEvent
->Header
.Revision
= FPDT_RECORD_REVISION_1
;
636 FpdtRecordPtr
.GuidQwordEvent
->ProgressID
= PerfId
;
637 FpdtRecordPtr
.GuidQwordEvent
->Timestamp
= TimeStamp
;
638 FpdtRecordPtr
.GuidQwordEvent
->Qword
= mLoadImageCount
;
639 CopyMem (&FpdtRecordPtr
.GuidQwordEvent
->Guid
, &ModuleGuid
, sizeof (FpdtRecordPtr
.GuidQwordEvent
->Guid
));
640 if (PerfId
== MODULE_LOADIMAGE_END_ID
&& mCachedLength
!= 0) {
641 CachedFpdtRecordPtr
.RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*)((UINT8
*)mSmmBootPerformanceTable
+ mCachedLength
);
642 CopyMem (&CachedFpdtRecordPtr
.GuidQwordEvent
->Guid
, &ModuleGuid
, sizeof (CachedFpdtRecordPtr
.GuidQwordEvent
->Guid
));
648 case PERF_EVENTSIGNAL_START_ID
:
649 case PERF_EVENTSIGNAL_END_ID
:
650 case PERF_CALLBACK_START_ID
:
651 case PERF_CALLBACK_END_ID
:
652 if (String
== NULL
) {
653 return EFI_INVALID_PARAMETER
;
656 // Cache the event guid in string event record when PcdEdkiiFpdtStringRecordEnableOnly == TRUE
658 CopyGuid (&ModuleGuid
, Guid
);
660 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly
)) {
661 FpdtRecordPtr
.DualGuidStringEvent
->Header
.Type
= FPDT_DUAL_GUID_STRING_EVENT_TYPE
;
662 FpdtRecordPtr
.DualGuidStringEvent
->Header
.Length
= sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD
);
663 FpdtRecordPtr
.DualGuidStringEvent
->Header
.Revision
= FPDT_RECORD_REVISION_1
;
664 FpdtRecordPtr
.DualGuidStringEvent
->ProgressID
= PerfId
;
665 FpdtRecordPtr
.DualGuidStringEvent
->Timestamp
= TimeStamp
;
666 CopyMem (&FpdtRecordPtr
.DualGuidStringEvent
->Guid1
, CallerIdentifier
, sizeof (FpdtRecordPtr
.DualGuidStringEvent
->Guid1
));
667 CopyMem (&FpdtRecordPtr
.DualGuidStringEvent
->Guid2
, Guid
, sizeof (FpdtRecordPtr
.DualGuidStringEvent
->Guid2
));
668 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr
.DualGuidStringEvent
->String
, StringPtr
, &FpdtRecordPtr
.DualGuidStringEvent
->Header
.Length
);
673 case PERF_FUNCTION_START_ID
:
674 case PERF_FUNCTION_END_ID
:
675 case PERF_INMODULE_START_ID
:
676 case PERF_INMODULE_END_ID
:
677 case PERF_CROSSMODULE_START_ID
:
678 case PERF_CROSSMODULE_END_ID
:
679 GetModuleInfoFromHandle ((EFI_HANDLE
*)CallerIdentifier
, ModuleName
, sizeof (ModuleName
), &ModuleGuid
);
680 if (String
!= NULL
) {
683 StringPtr
= ModuleName
;
685 if (AsciiStrLen (StringPtr
) == 0) {
686 StringPtr
= "unknown name";
688 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly
)) {
689 FpdtRecordPtr
.DynamicStringEvent
->Header
.Type
= FPDT_DYNAMIC_STRING_EVENT_TYPE
;
690 FpdtRecordPtr
.DynamicStringEvent
->Header
.Length
= sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD
);
691 FpdtRecordPtr
.DynamicStringEvent
->Header
.Revision
= FPDT_RECORD_REVISION_1
;
692 FpdtRecordPtr
.DynamicStringEvent
->ProgressID
= PerfId
;
693 FpdtRecordPtr
.DynamicStringEvent
->Timestamp
= TimeStamp
;
694 CopyMem (&FpdtRecordPtr
.DynamicStringEvent
->Guid
, &ModuleGuid
, sizeof (FpdtRecordPtr
.DynamicStringEvent
->Guid
));
695 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr
.DynamicStringEvent
->String
, StringPtr
, &FpdtRecordPtr
.DynamicStringEvent
->Header
.Length
);
700 if (Attribute
!= PerfEntry
) {
701 GetModuleInfoFromHandle ((EFI_HANDLE
*)CallerIdentifier
, ModuleName
, sizeof (ModuleName
), &ModuleGuid
);
702 if (String
!= NULL
) {
705 StringPtr
= ModuleName
;
707 if (AsciiStrLen (StringPtr
) == 0) {
708 StringPtr
= "unknown name";
710 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly
)) {
711 FpdtRecordPtr
.DynamicStringEvent
->Header
.Type
= FPDT_DYNAMIC_STRING_EVENT_TYPE
;
712 FpdtRecordPtr
.DynamicStringEvent
->Header
.Length
= sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD
);
713 FpdtRecordPtr
.DynamicStringEvent
->Header
.Revision
= FPDT_RECORD_REVISION_1
;
714 FpdtRecordPtr
.DynamicStringEvent
->ProgressID
= PerfId
;
715 FpdtRecordPtr
.DynamicStringEvent
->Timestamp
= TimeStamp
;
716 CopyMem (&FpdtRecordPtr
.DynamicStringEvent
->Guid
, &ModuleGuid
, sizeof (FpdtRecordPtr
.DynamicStringEvent
->Guid
));
717 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr
.DynamicStringEvent
->String
, StringPtr
, &FpdtRecordPtr
.DynamicStringEvent
->Header
.Length
);
720 return EFI_INVALID_PARAMETER
;
726 // 4.2 When PcdEdkiiFpdtStringRecordEnableOnly==TRUE, create string record for all Perf entries.
728 if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly
)) {
729 if (StringPtr
== NULL
) {
730 return EFI_INVALID_PARAMETER
;
732 FpdtRecordPtr
.DynamicStringEvent
->Header
.Type
= FPDT_DYNAMIC_STRING_EVENT_TYPE
;
733 FpdtRecordPtr
.DynamicStringEvent
->Header
.Length
= sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD
);
734 FpdtRecordPtr
.DynamicStringEvent
->Header
.Revision
= FPDT_RECORD_REVISION_1
;
735 FpdtRecordPtr
.DynamicStringEvent
->ProgressID
= PerfId
;
736 FpdtRecordPtr
.DynamicStringEvent
->Timestamp
= TimeStamp
;
737 CopyMem (&FpdtRecordPtr
.DynamicStringEvent
->Guid
, &ModuleGuid
, sizeof (FpdtRecordPtr
.DynamicStringEvent
->Guid
));
738 if (AsciiStrLen (StringPtr
) == 0) {
739 StringPtr
= "unknown name";
741 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr
.DynamicStringEvent
->String
, StringPtr
, &FpdtRecordPtr
.DynamicStringEvent
->Header
.Length
);
743 if ((PerfId
== MODULE_LOADIMAGE_START_ID
) || (PerfId
== MODULE_END_ID
)) {
744 FpdtRecordPtr
.DynamicStringEvent
->Header
.Length
= (UINT8
)(sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD
)+ STRING_SIZE
);
746 if ((PerfId
== MODULE_LOADIMAGE_END_ID
|| PerfId
== MODULE_END_ID
) && mCachedLength
!= 0) {
747 CachedFpdtRecordPtr
.RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*)((UINT8
*)mSmmBootPerformanceTable
+ mCachedLength
);
748 if (PerfId
== MODULE_LOADIMAGE_END_ID
) {
749 DestMax
= CachedFpdtRecordPtr
.DynamicStringEvent
->Header
.Length
- sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD
);
750 StringLen
= AsciiStrLen (StringPtr
);
751 if (StringLen
>= DestMax
) {
752 StringLen
= DestMax
-1;
754 CopyMem (&CachedFpdtRecordPtr
.DynamicStringEvent
->Guid
, &ModuleGuid
, sizeof (CachedFpdtRecordPtr
.DynamicStringEvent
->Guid
));
755 AsciiStrnCpyS (CachedFpdtRecordPtr
.DynamicStringEvent
->String
, DestMax
, StringPtr
, StringLen
);
756 } else if (PerfId
== MODULE_END_ID
) {
757 DestMax
= FpdtRecordPtr
.DynamicStringEvent
->Header
.Length
- sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD
);
758 StringLen
= AsciiStrLen (CachedFpdtRecordPtr
.DynamicStringEvent
->String
);
759 if (StringLen
>= DestMax
) {
760 StringLen
= DestMax
-1;
762 CopyMem (&FpdtRecordPtr
.DynamicStringEvent
->Guid
, &CachedFpdtRecordPtr
.DynamicStringEvent
->Guid
, sizeof (CachedFpdtRecordPtr
.DynamicStringEvent
->Guid
));
763 AsciiStrnCpyS (FpdtRecordPtr
.DynamicStringEvent
->String
, DestMax
, CachedFpdtRecordPtr
.DynamicStringEvent
->String
, StringLen
);
770 // 5. Update the length of the used buffer after fill in the record.
772 mPerformanceLength
+= FpdtRecordPtr
.RecordHeader
->Length
;
773 mSmmBootPerformanceTable
->Header
.Length
+= FpdtRecordPtr
.RecordHeader
->Length
;
779 SmmReadyToBoot protocol notification event handler.
781 @param Protocol Points to the protocol's unique identifier
782 @param Interface Points to the interface instance
783 @param Handle The handle on which the interface was installed
785 @retval EFI_SUCCESS SmmReadyToBootCallback runs successfully
790 SmmReportFpdtRecordData (
791 IN CONST EFI_GUID
*Protocol
,
798 if (!mFpdtDataIsReported
&& mSmmBootPerformanceTable
!= NULL
) {
799 SmmBPDTddr
= (UINT64
)(UINTN
)mSmmBootPerformanceTable
;
800 REPORT_STATUS_CODE_EX (
802 EFI_SOFTWARE_SMM_DRIVER
,
805 &gEdkiiFpdtExtendedFirmwarePerformanceGuid
,
810 // Set FPDT report state to TRUE.
812 mFpdtDataIsReported
= TRUE
;
818 SmmBase2 protocol notify callback function, when SMST and SMM memory service get initialized
819 this function is callbacked to initialize the Smm Performance Lib
821 @param Event The event of notify protocol.
822 @param Context Notify event context.
827 InitializeSmmCorePerformanceLib (
834 VOID
*SmmReadyToBootRegistration
;
835 PERFORMANCE_PROPERTY
*PerformanceProperty
;
838 // Initialize spin lock
840 InitializeSpinLock (&mSmmFpdtLock
);
843 // Install the protocol interfaces for SMM performance library instance.
846 Status
= gSmst
->SmmInstallProtocolInterface (
848 &gEdkiiSmmPerformanceMeasurementProtocolGuid
,
849 EFI_NATIVE_INTERFACE
,
850 &mPerformanceMeasurementInterface
852 ASSERT_EFI_ERROR (Status
);
854 Status
= gSmst
->SmmRegisterProtocolNotify (
855 &gEdkiiSmmReadyToBootProtocolGuid
,
856 SmmReportFpdtRecordData
,
857 &SmmReadyToBootRegistration
859 Status
= EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid
, (VOID
**) &PerformanceProperty
);
860 if (EFI_ERROR (Status
)) {
862 // Install configuration table for performance property.
864 mPerformanceProperty
.Revision
= PERFORMANCE_PROPERTY_REVISION
;
865 mPerformanceProperty
.Reserved
= 0;
866 mPerformanceProperty
.Frequency
= GetPerformanceCounterProperties (
867 &mPerformanceProperty
.TimerStartValue
,
868 &mPerformanceProperty
.TimerEndValue
870 Status
= gBS
->InstallConfigurationTable (&gPerformanceProtocolGuid
, &mPerformanceProperty
);
871 ASSERT_EFI_ERROR (Status
);
876 The constructor function initializes the Performance Measurement Enable flag and
877 registers SmmBase2 protocol notify callback.
878 It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.
880 @param ImageHandle The firmware allocated handle for the EFI image.
881 @param SystemTable A pointer to the EFI System Table.
883 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
888 SmmCorePerformanceLibConstructor (
889 IN EFI_HANDLE ImageHandle
,
890 IN EFI_SYSTEM_TABLE
*SystemTable
897 if (!PerformanceMeasurementEnabled ()) {
899 // Do not initialize performance infrastructure if not required.
905 // Create the events to do the library init.
907 Status
= gBS
->CreateEvent (
910 InitializeSmmCorePerformanceLib
,
914 ASSERT_EFI_ERROR (Status
);
917 // Register for protocol notifications on this event
919 Status
= gBS
->RegisterProtocolNotify (
920 &gEfiSmmBase2ProtocolGuid
,
925 ASSERT_EFI_ERROR (Status
);
931 Create performance record with event description and a timestamp.
933 @param CallerIdentifier - Image handle or pointer to caller ID GUID.
934 @param Guid - Pointer to a GUID.
935 @param String - Pointer to a string describing the measurement.
936 @param TimeStamp - 64-bit time stamp.
937 @param Address - Pointer to a location in memory relevant to the measurement.
938 @param Identifier - Performance identifier describing the type of measurement.
939 @param Attribute - The attribute of the measurement. According to attribute can create a start
940 record for PERF_START/PERF_START_EX, or a end record for PERF_END/PERF_END_EX,
941 or a general record for other Perf macros.
943 @retval EFI_SUCCESS - Successfully created performance record.
944 @retval EFI_OUT_OF_RESOURCES - Ran out of space to store the records.
945 @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
946 pointer or invalid PerfId.
950 CreatePerformanceMeasurement(
951 IN CONST VOID
*CallerIdentifier
, OPTIONAL
952 IN CONST VOID
*Guid
, OPTIONAL
953 IN CONST CHAR8
*String
, OPTIONAL
954 IN UINT64 TimeStamp
, OPTIONAL
955 IN UINT64 Address
, OPTIONAL
956 IN UINT32 Identifier
,
957 IN PERF_MEASUREMENT_ATTRIBUTE Attribute
962 Status
= EFI_SUCCESS
;
964 AcquireSpinLock (&mSmmFpdtLock
);
965 Status
= InsertFpdtRecord (CallerIdentifier
, Guid
, String
, TimeStamp
, Address
, (UINT16
)Identifier
, Attribute
);
966 ReleaseSpinLock (&mSmmFpdtLock
);
971 Adds a record at the end of the performance measurement log
972 that records the start time of a performance measurement.
974 Adds a record to the end of the performance measurement log
975 that contains the Handle, Token, Module and Identifier.
976 The end time of the new record must be set to zero.
977 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
978 If TimeStamp is zero, the start time in the record is filled in with the value
979 read from the current time stamp.
981 @param Handle Pointer to environment specific context used
982 to identify the component being measured.
983 @param Token Pointer to a Null-terminated ASCII string
984 that identifies the component being measured.
985 @param Module Pointer to a Null-terminated ASCII string
986 that identifies the module being measured.
987 @param TimeStamp 64-bit time stamp.
988 @param Identifier 32-bit identifier. If the value is 0, the created record
989 is same as the one created by StartPerformanceMeasurement.
991 @retval RETURN_SUCCESS The start of the measurement was recorded.
992 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
997 StartPerformanceMeasurementEx (
998 IN CONST VOID
*Handle
, OPTIONAL
999 IN CONST CHAR8
*Token
, OPTIONAL
1000 IN CONST CHAR8
*Module
, OPTIONAL
1001 IN UINT64 TimeStamp
,
1002 IN UINT32 Identifier
1005 CONST CHAR8
*String
;
1007 if (Token
!= NULL
) {
1009 } else if (Module
!= NULL
) {
1015 return (RETURN_STATUS
)CreatePerformanceMeasurement (Handle
, NULL
, String
, TimeStamp
, 0, Identifier
, PerfStartEntry
);
1019 Searches the performance measurement log from the beginning of the log
1020 for the first matching record that contains a zero end time and fills in a valid end time.
1022 Searches the performance measurement log from the beginning of the log
1023 for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
1024 If the record can not be found then return RETURN_NOT_FOUND.
1025 If the record is found and TimeStamp is not zero,
1026 then the end time in the record is filled in with the value specified by TimeStamp.
1027 If the record is found and TimeStamp is zero, then the end time in the matching record
1028 is filled in with the current time stamp value.
1030 @param Handle Pointer to environment specific context used
1031 to identify the component being measured.
1032 @param Token Pointer to a Null-terminated ASCII string
1033 that identifies the component being measured.
1034 @param Module Pointer to a Null-terminated ASCII string
1035 that identifies the module being measured.
1036 @param TimeStamp 64-bit time stamp.
1037 @param Identifier 32-bit identifier. If the value is 0, the found record
1038 is same as the one found by EndPerformanceMeasurement.
1040 @retval RETURN_SUCCESS The end of the measurement was recorded.
1041 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
1046 EndPerformanceMeasurementEx (
1047 IN CONST VOID
*Handle
, OPTIONAL
1048 IN CONST CHAR8
*Token
, OPTIONAL
1049 IN CONST CHAR8
*Module
, OPTIONAL
1050 IN UINT64 TimeStamp
,
1051 IN UINT32 Identifier
1054 CONST CHAR8
*String
;
1056 if (Token
!= NULL
) {
1058 } else if (Module
!= NULL
) {
1064 return (RETURN_STATUS
)CreatePerformanceMeasurement (Handle
, NULL
, String
, TimeStamp
, 0, Identifier
, PerfEndEntry
);
1068 Attempts to retrieve a performance measurement log entry from the performance measurement log.
1069 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
1070 and then assign the Identifier with 0.
1074 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
1075 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
1076 and the key for the second entry in the log is returned. If the performance log is empty,
1077 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
1078 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
1079 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
1080 retrieved and an implementation specific non-zero key value that specifies the end of the performance
1081 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
1082 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
1083 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
1084 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
1085 If Handle is NULL, then ASSERT().
1086 If Token is NULL, then ASSERT().
1087 If Module is NULL, then ASSERT().
1088 If StartTimeStamp is NULL, then ASSERT().
1089 If EndTimeStamp is NULL, then ASSERT().
1090 If Identifier is NULL, then ASSERT().
1092 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
1093 0, then the first performance measurement log entry is retrieved.
1094 On exit, the key of the next performance log entry.
1095 @param Handle Pointer to environment specific context used to identify the component
1097 @param Token Pointer to a Null-terminated ASCII string that identifies the component
1099 @param Module Pointer to a Null-terminated ASCII string that identifies the module
1101 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
1103 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
1105 @param Identifier Pointer to the 32-bit identifier that was recorded.
1107 @return The key for the next performance log entry (in general case).
1112 GetPerformanceMeasurementEx (
1113 IN UINTN LogEntryKey
,
1114 OUT CONST VOID
**Handle
,
1115 OUT CONST CHAR8
**Token
,
1116 OUT CONST CHAR8
**Module
,
1117 OUT UINT64
*StartTimeStamp
,
1118 OUT UINT64
*EndTimeStamp
,
1119 OUT UINT32
*Identifier
1126 Adds a record at the end of the performance measurement log
1127 that records the start time of a performance measurement.
1129 Adds a record to the end of the performance measurement log
1130 that contains the Handle, Token, and Module.
1131 The end time of the new record must be set to zero.
1132 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
1133 If TimeStamp is zero, the start time in the record is filled in with the value
1134 read from the current time stamp.
1136 @param Handle Pointer to environment specific context used
1137 to identify the component being measured.
1138 @param Token Pointer to a Null-terminated ASCII string
1139 that identifies the component being measured.
1140 @param Module Pointer to a Null-terminated ASCII string
1141 that identifies the module being measured.
1142 @param TimeStamp 64-bit time stamp.
1144 @retval RETURN_SUCCESS The start of the measurement was recorded.
1145 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
1150 StartPerformanceMeasurement (
1151 IN CONST VOID
*Handle
, OPTIONAL
1152 IN CONST CHAR8
*Token
, OPTIONAL
1153 IN CONST CHAR8
*Module
, OPTIONAL
1157 return StartPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
1161 Searches the performance measurement log from the beginning of the log
1162 for the first matching record that contains a zero end time and fills in a valid end time.
1164 Searches the performance measurement log from the beginning of the log
1165 for the first record that matches Handle, Token, and Module and has an end time value of zero.
1166 If the record can not be found then return RETURN_NOT_FOUND.
1167 If the record is found and TimeStamp is not zero,
1168 then the end time in the record is filled in with the value specified by TimeStamp.
1169 If the record is found and TimeStamp is zero, then the end time in the matching record
1170 is filled in with the current time stamp value.
1172 @param Handle Pointer to environment specific context used
1173 to identify the component being measured.
1174 @param Token Pointer to a Null-terminated ASCII string
1175 that identifies the component being measured.
1176 @param Module Pointer to a Null-terminated ASCII string
1177 that identifies the module being measured.
1178 @param TimeStamp 64-bit time stamp.
1180 @retval RETURN_SUCCESS The end of the measurement was recorded.
1181 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
1186 EndPerformanceMeasurement (
1187 IN CONST VOID
*Handle
, OPTIONAL
1188 IN CONST CHAR8
*Token
, OPTIONAL
1189 IN CONST CHAR8
*Module
, OPTIONAL
1193 return EndPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
1197 Attempts to retrieve a performance measurement log entry from the performance measurement log.
1198 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
1199 and then eliminate the Identifier.
1203 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
1204 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
1205 and the key for the second entry in the log is returned. If the performance log is empty,
1206 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
1207 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
1208 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
1209 retrieved and an implementation specific non-zero key value that specifies the end of the performance
1210 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
1211 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
1212 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
1213 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
1214 If Handle is NULL, then ASSERT().
1215 If Token is NULL, then ASSERT().
1216 If Module is NULL, then ASSERT().
1217 If StartTimeStamp is NULL, then ASSERT().
1218 If EndTimeStamp is NULL, then ASSERT().
1220 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
1221 0, then the first performance measurement log entry is retrieved.
1222 On exit, the key of the next performance log entry.
1223 @param Handle Pointer to environment specific context used to identify the component
1225 @param Token Pointer to a Null-terminated ASCII string that identifies the component
1227 @param Module Pointer to a Null-terminated ASCII string that identifies the module
1229 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
1231 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
1234 @return The key for the next performance log entry (in general case).
1239 GetPerformanceMeasurement (
1240 IN UINTN LogEntryKey
,
1241 OUT CONST VOID
**Handle
,
1242 OUT CONST CHAR8
**Token
,
1243 OUT CONST CHAR8
**Module
,
1244 OUT UINT64
*StartTimeStamp
,
1245 OUT UINT64
*EndTimeStamp
1252 Returns TRUE if the performance measurement macros are enabled.
1254 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
1255 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
1257 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
1258 PcdPerformanceLibraryPropertyMask is set.
1259 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
1260 PcdPerformanceLibraryPropertyMask is clear.
1265 PerformanceMeasurementEnabled (
1269 return (BOOLEAN
) ((PcdGet8(PcdPerformanceLibraryPropertyMask
) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED
) != 0);
1273 Create performance record with event description and a timestamp.
1275 @param CallerIdentifier - Image handle or pointer to caller ID GUID
1276 @param Guid - Pointer to a GUID
1277 @param String - Pointer to a string describing the measurement
1278 @param Address - Pointer to a location in memory relevant to the measurement
1279 @param Identifier - Performance identifier describing the type of measurement
1281 @retval RETURN_SUCCESS - Successfully created performance record
1282 @retval RETURN_OUT_OF_RESOURCES - Ran out of space to store the records
1283 @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
1284 pointer or invalid PerfId
1289 LogPerformanceMeasurement (
1290 IN CONST VOID
*CallerIdentifier
,
1291 IN CONST VOID
*Guid
, OPTIONAL
1292 IN CONST CHAR8
*String
, OPTIONAL
1293 IN UINT64 Address
, OPTIONAL
1294 IN UINT32 Identifier
1297 return (RETURN_STATUS
)CreatePerformanceMeasurement (CallerIdentifier
, Guid
, String
, 0, Address
, Identifier
, PerfEntry
);
1301 Check whether the specified performance measurement can be logged.
1303 This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
1304 and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
1306 @param Type - Type of the performance measurement entry.
1308 @retval TRUE The performance measurement can be logged.
1309 @retval FALSE The performance measurement can NOT be logged.
1314 LogPerformanceMeasurementEnabled (
1319 // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
1321 if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask
) & Type
) == 0) {