2 Performance library instance used in PEI phase.
4 This file implements all APIs in Performance Library class in MdePkg. It creates
5 performance logging GUIDed HOB on the first performance logging and then logs the
6 performance data to the GUIDed HOB. Due to the limitation of temporary RAM, the maximum
7 number of performance logging entry is specified by PcdMaxPeiPerformanceLogEntries or
8 PcdMaxPeiPerformanceLogEntries16.
10 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
11 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
12 This program and the accompanying materials
13 are licensed and made available under the terms and conditions of the BSD License
14 which accompanies this distribution. The full text of the license may be found at
15 http://opensource.org/licenses/bsd-license.php
17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 #include <Guid/Performance.h>
27 #include <Library/PerformanceLib.h>
28 #include <Library/DebugLib.h>
29 #include <Library/HobLib.h>
30 #include <Library/BaseLib.h>
31 #include <Library/TimerLib.h>
32 #include <Library/PcdLib.h>
33 #include <Library/BaseMemoryLib.h>
37 Gets the GUID HOB for PEI performance.
39 This internal function searches for the GUID HOB for PEI performance.
40 If that GUID HOB is not found, it will build a new one.
41 It outputs the data area of that GUID HOB to record performance log.
43 @param PeiPerformanceLog Pointer to Pointer to PEI performance log header.
44 @param PeiPerformanceIdArray Pointer to Pointer to PEI performance identifier array.
48 InternalGetPerformanceHobLog (
49 OUT PEI_PERFORMANCE_LOG_HEADER
**PeiPerformanceLog
,
50 OUT UINT32
**PeiPerformanceIdArray
53 EFI_HOB_GUID_TYPE
*GuidHob
;
54 UINTN PeiPerformanceSize
;
55 UINT16 PeiPerformanceLogEntries
;
57 ASSERT (PeiPerformanceLog
!= NULL
);
58 ASSERT (PeiPerformanceIdArray
!= NULL
);
60 PeiPerformanceLogEntries
= (UINT16
) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16
) != 0 ?
61 PcdGet16 (PcdMaxPeiPerformanceLogEntries16
) :
62 PcdGet8 (PcdMaxPeiPerformanceLogEntries
));
63 GuidHob
= GetFirstGuidHob (&gPerformanceProtocolGuid
);
65 if (GuidHob
!= NULL
) {
67 // PEI Performance HOB was found, then return the existing one.
69 *PeiPerformanceLog
= GET_GUID_HOB_DATA (GuidHob
);
71 GuidHob
= GetFirstGuidHob (&gPerformanceExProtocolGuid
);
72 ASSERT (GuidHob
!= NULL
);
73 *PeiPerformanceIdArray
= GET_GUID_HOB_DATA (GuidHob
);
76 // PEI Performance HOB was not found, then build one.
78 PeiPerformanceSize
= sizeof (PEI_PERFORMANCE_LOG_HEADER
) +
79 sizeof (PEI_PERFORMANCE_LOG_ENTRY
) * PeiPerformanceLogEntries
;
80 *PeiPerformanceLog
= BuildGuidHob (&gPerformanceProtocolGuid
, PeiPerformanceSize
);
81 *PeiPerformanceLog
= ZeroMem (*PeiPerformanceLog
, PeiPerformanceSize
);
83 PeiPerformanceSize
= sizeof (UINT32
) * PeiPerformanceLogEntries
;
84 *PeiPerformanceIdArray
= BuildGuidHob (&gPerformanceExProtocolGuid
, PeiPerformanceSize
);
85 *PeiPerformanceIdArray
= ZeroMem (*PeiPerformanceIdArray
, PeiPerformanceSize
);
90 Searches in the log array with keyword Handle, Token, Module and Identifier.
92 This internal function searches for the log entry in the log array.
93 If there is an entry that exactly matches the given keywords
94 and its end time stamp is zero, then the index of that log entry is returned;
95 otherwise, the the number of log entries in the array is returned.
97 @param PeiPerformanceLog Pointer to the data structure containing PEI
99 @param PeiPerformanceIdArray Pointer to PEI performance identifier array.
100 @param Handle Pointer to environment specific context used
101 to identify the component being measured.
102 @param Token Pointer to a Null-terminated ASCII string
103 that identifies the component being measured.
104 @param Module Pointer to a Null-terminated ASCII string
105 that identifies the module being measured.
106 @param Identifier 32-bit identifier.
108 @retval The index of log entry in the array.
112 InternalSearchForLogEntry (
113 IN PEI_PERFORMANCE_LOG_HEADER
*PeiPerformanceLog
,
114 IN UINT32
*PeiPerformanceIdArray
,
115 IN CONST VOID
*Handle
, OPTIONAL
116 IN CONST CHAR8
*Token
, OPTIONAL
117 IN CONST CHAR8
*Module
, OPTIONAL
123 UINT32 NumberOfEntries
;
124 PEI_PERFORMANCE_LOG_ENTRY
*LogEntryArray
;
130 if (Module
== NULL
) {
133 NumberOfEntries
= PeiPerformanceLog
->NumberOfEntries
;
134 LogEntryArray
= (PEI_PERFORMANCE_LOG_ENTRY
*) (PeiPerformanceLog
+ 1);
138 for (Index
= 0; Index
< NumberOfEntries
; Index
++) {
139 Index2
= NumberOfEntries
- 1 - Index
;
140 if (LogEntryArray
[Index2
].EndTimeStamp
== 0 &&
141 (LogEntryArray
[Index2
].Handle
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Handle
) &&
142 AsciiStrnCmp (LogEntryArray
[Index2
].Token
, Token
, PEI_PERFORMANCE_STRING_LENGTH
) == 0 &&
143 AsciiStrnCmp (LogEntryArray
[Index2
].Module
, Module
, PEI_PERFORMANCE_STRING_LENGTH
) == 0) {
152 Creates a record for the beginning of a performance measurement.
154 Creates a record that contains the Handle, Token, Module and Identifier.
155 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
156 If TimeStamp is zero, then this function reads the current time stamp
157 and adds that time stamp value to the record as the start time.
159 @param Handle Pointer to environment specific context used
160 to identify the component being measured.
161 @param Token Pointer to a Null-terminated ASCII string
162 that identifies the component being measured.
163 @param Module Pointer to a Null-terminated ASCII string
164 that identifies the module being measured.
165 @param TimeStamp 64-bit time stamp.
166 @param Identifier 32-bit identifier. If the value is 0, the created record
167 is same as the one created by StartPerformanceMeasurement.
169 @retval RETURN_SUCCESS The start of the measurement was recorded.
170 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
175 StartPerformanceMeasurementEx (
176 IN CONST VOID
*Handle
, OPTIONAL
177 IN CONST CHAR8
*Token
, OPTIONAL
178 IN CONST CHAR8
*Module
, OPTIONAL
183 PEI_PERFORMANCE_LOG_HEADER
*PeiPerformanceLog
;
184 UINT32
*PeiPerformanceIdArray
;
185 PEI_PERFORMANCE_LOG_ENTRY
*LogEntryArray
;
187 UINT16 PeiPerformanceLogEntries
;
189 PeiPerformanceLogEntries
= (UINT16
) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16
) != 0 ?
190 PcdGet16 (PcdMaxPeiPerformanceLogEntries16
) :
191 PcdGet8 (PcdMaxPeiPerformanceLogEntries
));
193 InternalGetPerformanceHobLog (&PeiPerformanceLog
, &PeiPerformanceIdArray
);
195 if (PeiPerformanceLog
->NumberOfEntries
>= PeiPerformanceLogEntries
) {
196 DEBUG ((DEBUG_ERROR
, "PEI performance log array out of resources\n"));
197 return RETURN_OUT_OF_RESOURCES
;
199 Index
= PeiPerformanceLog
->NumberOfEntries
++;
200 LogEntryArray
= (PEI_PERFORMANCE_LOG_ENTRY
*) (PeiPerformanceLog
+ 1);
201 LogEntryArray
[Index
].Handle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Handle
;
204 AsciiStrnCpyS (LogEntryArray
[Index
].Token
, PEI_PERFORMANCE_STRING_SIZE
, Token
, PEI_PERFORMANCE_STRING_LENGTH
);
206 if (Module
!= NULL
) {
207 AsciiStrnCpyS (LogEntryArray
[Index
].Module
, PEI_PERFORMANCE_STRING_SIZE
, Module
, PEI_PERFORMANCE_STRING_LENGTH
);
210 LogEntryArray
[Index
].EndTimeStamp
= 0;
211 PeiPerformanceIdArray
[Index
] = Identifier
;
213 if (TimeStamp
== 0) {
214 TimeStamp
= GetPerformanceCounter ();
216 LogEntryArray
[Index
].StartTimeStamp
= TimeStamp
;
218 return RETURN_SUCCESS
;
222 Fills in the end time of a performance measurement.
224 Looks up the record that matches Handle, Token and Module.
225 If the record can not be found then return RETURN_NOT_FOUND.
226 If the record is found and TimeStamp is not zero,
227 then TimeStamp is added to the record as the end time.
228 If the record is found and TimeStamp is zero, then this function reads
229 the current time stamp and adds that time stamp value to the record as the end time.
231 @param Handle Pointer to environment specific context used
232 to identify the component being measured.
233 @param Token Pointer to a Null-terminated ASCII string
234 that identifies the component being measured.
235 @param Module Pointer to a Null-terminated ASCII string
236 that identifies the module being measured.
237 @param TimeStamp 64-bit time stamp.
238 @param Identifier 32-bit identifier. If the value is 0, the found record
239 is same as the one found by EndPerformanceMeasurement.
241 @retval RETURN_SUCCESS The end of the measurement was recorded.
242 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
247 EndPerformanceMeasurementEx (
248 IN CONST VOID
*Handle
, OPTIONAL
249 IN CONST CHAR8
*Token
, OPTIONAL
250 IN CONST CHAR8
*Module
, OPTIONAL
255 PEI_PERFORMANCE_LOG_HEADER
*PeiPerformanceLog
;
256 UINT32
*PeiPerformanceIdArray
;
257 PEI_PERFORMANCE_LOG_ENTRY
*LogEntryArray
;
260 if (TimeStamp
== 0) {
261 TimeStamp
= GetPerformanceCounter ();
264 InternalGetPerformanceHobLog (&PeiPerformanceLog
, &PeiPerformanceIdArray
);
265 Index
= InternalSearchForLogEntry (PeiPerformanceLog
, PeiPerformanceIdArray
, Handle
, Token
, Module
, Identifier
);
266 if (Index
>= PeiPerformanceLog
->NumberOfEntries
) {
267 return RETURN_NOT_FOUND
;
269 LogEntryArray
= (PEI_PERFORMANCE_LOG_ENTRY
*) (PeiPerformanceLog
+ 1);
270 LogEntryArray
[Index
].EndTimeStamp
= TimeStamp
;
272 return RETURN_SUCCESS
;
276 Attempts to retrieve a performance measurement log entry from the performance measurement log.
277 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
278 and then assign the Identifier with 0.
280 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
281 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
282 and the key for the second entry in the log is returned. If the performance log is empty,
283 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
284 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
285 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
286 retrieved and an implementation specific non-zero key value that specifies the end of the performance
287 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
288 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
289 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
290 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
291 If Handle is NULL, then ASSERT().
292 If Token is NULL, then ASSERT().
293 If Module is NULL, then ASSERT().
294 If StartTimeStamp is NULL, then ASSERT().
295 If EndTimeStamp is NULL, then ASSERT().
296 If Identifier is NULL, then ASSERT().
298 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
299 0, then the first performance measurement log entry is retrieved.
300 On exit, the key of the next performance of entry entry.
301 @param Handle Pointer to environment specific context used to identify the component
303 @param Token Pointer to a Null-terminated ASCII string that identifies the component
305 @param Module Pointer to a Null-terminated ASCII string that identifies the module
307 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
309 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
311 @param Identifier Pointer to the 32-bit identifier that was recorded.
313 @return The key for the next performance log entry (in general case).
318 GetPerformanceMeasurementEx (
319 IN UINTN LogEntryKey
,
320 OUT CONST VOID
**Handle
,
321 OUT CONST CHAR8
**Token
,
322 OUT CONST CHAR8
**Module
,
323 OUT UINT64
*StartTimeStamp
,
324 OUT UINT64
*EndTimeStamp
,
325 OUT UINT32
*Identifier
328 PEI_PERFORMANCE_LOG_HEADER
*PeiPerformanceLog
;
329 UINT32
*PeiPerformanceIdArray
;
330 PEI_PERFORMANCE_LOG_ENTRY
*CurrentLogEntry
;
331 PEI_PERFORMANCE_LOG_ENTRY
*LogEntryArray
;
332 UINTN NumberOfEntries
;
334 ASSERT (Handle
!= NULL
);
335 ASSERT (Token
!= NULL
);
336 ASSERT (Module
!= NULL
);
337 ASSERT (StartTimeStamp
!= NULL
);
338 ASSERT (EndTimeStamp
!= NULL
);
339 ASSERT (Identifier
!= NULL
);
341 InternalGetPerformanceHobLog (&PeiPerformanceLog
, &PeiPerformanceIdArray
);
343 NumberOfEntries
= (UINTN
) (PeiPerformanceLog
->NumberOfEntries
);
344 LogEntryArray
= (PEI_PERFORMANCE_LOG_ENTRY
*) (PeiPerformanceLog
+ 1);
346 // Make sure that LogEntryKey is a valid log entry key.
348 ASSERT (LogEntryKey
<= NumberOfEntries
);
350 if (LogEntryKey
== NumberOfEntries
) {
354 CurrentLogEntry
= &(LogEntryArray
[LogEntryKey
]);
356 *Handle
= (VOID
*) (UINTN
) (CurrentLogEntry
->Handle
);
357 *Token
= CurrentLogEntry
->Token
;
358 *Module
= CurrentLogEntry
->Module
;
359 *StartTimeStamp
= CurrentLogEntry
->StartTimeStamp
;
360 *EndTimeStamp
= CurrentLogEntry
->EndTimeStamp
;
361 *Identifier
= PeiPerformanceIdArray
[LogEntryKey
++];
367 Creates a record for the beginning of a performance measurement.
369 Creates a record that contains the Handle, Token, and Module.
370 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
371 If TimeStamp is zero, then this function reads the current time stamp
372 and adds that time stamp value to the record as the start time.
374 @param Handle Pointer to environment specific context used
375 to identify the component being measured.
376 @param Token Pointer to a Null-terminated ASCII string
377 that identifies the component being measured.
378 @param Module Pointer to a Null-terminated ASCII string
379 that identifies the module being measured.
380 @param TimeStamp 64-bit time stamp.
382 @retval RETURN_SUCCESS The start of the measurement was recorded.
383 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
388 StartPerformanceMeasurement (
389 IN CONST VOID
*Handle
, OPTIONAL
390 IN CONST CHAR8
*Token
, OPTIONAL
391 IN CONST CHAR8
*Module
, OPTIONAL
395 return StartPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
399 Fills in the end time of a performance measurement.
401 Looks up the record that matches Handle, Token, and Module.
402 If the record can not be found then return RETURN_NOT_FOUND.
403 If the record is found and TimeStamp is not zero,
404 then TimeStamp is added to the record as the end time.
405 If the record is found and TimeStamp is zero, then this function reads
406 the current time stamp and adds that time stamp value to the record as the end time.
408 @param Handle Pointer to environment specific context used
409 to identify the component being measured.
410 @param Token Pointer to a Null-terminated ASCII string
411 that identifies the component being measured.
412 @param Module Pointer to a Null-terminated ASCII string
413 that identifies the module being measured.
414 @param TimeStamp 64-bit time stamp.
416 @retval RETURN_SUCCESS The end of the measurement was recorded.
417 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
422 EndPerformanceMeasurement (
423 IN CONST VOID
*Handle
, OPTIONAL
424 IN CONST CHAR8
*Token
, OPTIONAL
425 IN CONST CHAR8
*Module
, OPTIONAL
429 return EndPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
433 Attempts to retrieve a performance measurement log entry from the performance measurement log.
434 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
435 and then eliminate the Identifier.
437 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
438 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
439 and the key for the second entry in the log is returned. If the performance log is empty,
440 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
441 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
442 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
443 retrieved and an implementation specific non-zero key value that specifies the end of the performance
444 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
445 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
446 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
447 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
448 If Handle is NULL, then ASSERT().
449 If Token is NULL, then ASSERT().
450 If Module is NULL, then ASSERT().
451 If StartTimeStamp is NULL, then ASSERT().
452 If EndTimeStamp is NULL, then ASSERT().
454 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
455 0, then the first performance measurement log entry is retrieved.
456 On exit, the key of the next performance of entry entry.
457 @param Handle Pointer to environment specific context used to identify the component
459 @param Token Pointer to a Null-terminated ASCII string that identifies the component
461 @param Module Pointer to a Null-terminated ASCII string that identifies the module
463 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
465 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
468 @return The key for the next performance log entry (in general case).
473 GetPerformanceMeasurement (
474 IN UINTN LogEntryKey
,
475 OUT CONST VOID
**Handle
,
476 OUT CONST CHAR8
**Token
,
477 OUT CONST CHAR8
**Module
,
478 OUT UINT64
*StartTimeStamp
,
479 OUT UINT64
*EndTimeStamp
483 return GetPerformanceMeasurementEx (LogEntryKey
, Handle
, Token
, Module
, StartTimeStamp
, EndTimeStamp
, &Identifier
);
487 Returns TRUE if the performance measurement macros are enabled.
489 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
490 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
492 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
493 PcdPerformanceLibraryPropertyMask is set.
494 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
495 PcdPerformanceLibraryPropertyMask is clear.
500 PerformanceMeasurementEnabled (
504 return (BOOLEAN
) ((PcdGet8(PcdPerformanceLibraryPropertyMask
) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED
) != 0);