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.
9 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
10 This program and the accompanying materials
11 are licensed and made available under the terms and conditions of the BSD License
12 which accompanies this distribution. The full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 #include <Guid/Performance.h>
25 #include <Library/PerformanceLib.h>
26 #include <Library/DebugLib.h>
27 #include <Library/HobLib.h>
28 #include <Library/BaseLib.h>
29 #include <Library/TimerLib.h>
30 #include <Library/PcdLib.h>
31 #include <Library/BaseMemoryLib.h>
35 Gets the GUID HOB for PEI performance.
37 This internal function searches for the GUID HOB for PEI performance.
38 If that GUID HOB is not found, it will build a new one.
39 It outputs the data area of that GUID HOB to record performance log.
41 @param PeiPerformanceLog Pointer to Pointer to PEI performance log header.
42 @param PeiPerformanceIdArray Pointer to Pointer to PEI performance identifier array.
46 InternalGetPerformanceHobLog (
47 OUT PEI_PERFORMANCE_LOG_HEADER
**PeiPerformanceLog
,
48 OUT UINT32
**PeiPerformanceIdArray
51 EFI_HOB_GUID_TYPE
*GuidHob
;
52 UINTN PeiPerformanceSize
;
54 ASSERT (PeiPerformanceLog
!= NULL
);
55 ASSERT (PeiPerformanceIdArray
!= NULL
);
57 GuidHob
= GetFirstGuidHob (&gPerformanceProtocolGuid
);
59 if (GuidHob
!= NULL
) {
61 // PEI Performance HOB was found, then return the existing one.
63 *PeiPerformanceLog
= GET_GUID_HOB_DATA (GuidHob
);
65 GuidHob
= GetFirstGuidHob (&gPerformanceExProtocolGuid
);
66 ASSERT (GuidHob
!= NULL
);
67 *PeiPerformanceIdArray
= GET_GUID_HOB_DATA (GuidHob
);
70 // PEI Performance HOB was not found, then build one.
72 PeiPerformanceSize
= sizeof (PEI_PERFORMANCE_LOG_HEADER
) +
73 sizeof (PEI_PERFORMANCE_LOG_ENTRY
) * PcdGet8 (PcdMaxPeiPerformanceLogEntries
);
74 *PeiPerformanceLog
= BuildGuidHob (&gPerformanceProtocolGuid
, PeiPerformanceSize
);
75 *PeiPerformanceLog
= ZeroMem (*PeiPerformanceLog
, PeiPerformanceSize
);
77 PeiPerformanceSize
= sizeof (UINT32
) * PcdGet8 (PcdMaxPeiPerformanceLogEntries
);
78 *PeiPerformanceIdArray
= BuildGuidHob (&gPerformanceExProtocolGuid
, PeiPerformanceSize
);
79 *PeiPerformanceIdArray
= ZeroMem (*PeiPerformanceIdArray
, PeiPerformanceSize
);
84 Searches in the log array with keyword Handle, Token, Module and Identifier.
86 This internal function searches for the log entry in the log array.
87 If there is an entry that exactly matches the given keywords
88 and its end time stamp is zero, then the index of that log entry is returned;
89 otherwise, the the number of log entries in the array is returned.
91 @param PeiPerformanceLog Pointer to the data structure containing PEI
93 @param Handle Pointer to environment specific context used
94 to identify the component being measured.
95 @param Token Pointer to a Null-terminated ASCII string
96 that identifies the component being measured.
97 @param Module Pointer to a Null-terminated ASCII string
98 that identifies the module being measured.
99 @param Identifier 32-bit identifier.
101 @retval The index of log entry in the array.
105 InternalSearchForLogEntry (
106 IN PEI_PERFORMANCE_LOG_HEADER
*PeiPerformanceLog
,
107 IN UINT32
*PeiPerformanceIdArray
,
108 IN CONST VOID
*Handle
, OPTIONAL
109 IN CONST CHAR8
*Token
, OPTIONAL
110 IN CONST CHAR8
*Module
, OPTIONAL
115 UINT32 NumberOfEntries
;
116 PEI_PERFORMANCE_LOG_ENTRY
*LogEntryArray
;
122 if (Module
== NULL
) {
125 NumberOfEntries
= PeiPerformanceLog
->NumberOfEntries
;
126 LogEntryArray
= (PEI_PERFORMANCE_LOG_ENTRY
*) (PeiPerformanceLog
+ 1);
128 for (Index
= 0; Index
< NumberOfEntries
; Index
++) {
129 if ((LogEntryArray
[Index
].Handle
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Handle
) &&
130 AsciiStrnCmp (LogEntryArray
[Index
].Token
, Token
, PEI_PERFORMANCE_STRING_LENGTH
) == 0 &&
131 AsciiStrnCmp (LogEntryArray
[Index
].Module
, Module
, PEI_PERFORMANCE_STRING_LENGTH
) == 0 &&
132 (PeiPerformanceIdArray
[Index
] == Identifier
) &&
133 LogEntryArray
[Index
].EndTimeStamp
== 0
142 Creates a record for the beginning of a performance measurement.
144 Creates a record that contains the Handle, Token, Module and Identifier.
145 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
146 If TimeStamp is zero, then this function reads the current time stamp
147 and adds that time stamp value to the record as the start time.
149 @param Handle Pointer to environment specific context used
150 to identify the component being measured.
151 @param Token Pointer to a Null-terminated ASCII string
152 that identifies the component being measured.
153 @param Module Pointer to a Null-terminated ASCII string
154 that identifies the module being measured.
155 @param TimeStamp 64-bit time stamp.
156 @param Identifier 32-bit identifier. If the value is 0, the created record
157 is same as the one created by StartPerformanceMeasurement.
159 @retval RETURN_SUCCESS The start of the measurement was recorded.
160 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
165 StartPerformanceMeasurementEx (
166 IN CONST VOID
*Handle
, OPTIONAL
167 IN CONST CHAR8
*Token
, OPTIONAL
168 IN CONST CHAR8
*Module
, OPTIONAL
173 PEI_PERFORMANCE_LOG_HEADER
*PeiPerformanceLog
;
174 UINT32
*PeiPerformanceIdArray
;
175 PEI_PERFORMANCE_LOG_ENTRY
*LogEntryArray
;
178 InternalGetPerformanceHobLog (&PeiPerformanceLog
, &PeiPerformanceIdArray
);
180 if (PeiPerformanceLog
->NumberOfEntries
>= PcdGet8 (PcdMaxPeiPerformanceLogEntries
)) {
181 return RETURN_OUT_OF_RESOURCES
;
183 Index
= PeiPerformanceLog
->NumberOfEntries
++;
184 LogEntryArray
= (PEI_PERFORMANCE_LOG_ENTRY
*) (PeiPerformanceLog
+ 1);
185 LogEntryArray
[Index
].Handle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Handle
;
188 AsciiStrnCpy (LogEntryArray
[Index
].Token
, Token
, PEI_PERFORMANCE_STRING_LENGTH
);
190 if (Module
!= NULL
) {
191 AsciiStrnCpy (LogEntryArray
[Index
].Module
, Module
, PEI_PERFORMANCE_STRING_LENGTH
);
194 LogEntryArray
[Index
].EndTimeStamp
= 0;
195 PeiPerformanceIdArray
[Index
] = Identifier
;
197 if (TimeStamp
== 0) {
198 TimeStamp
= GetPerformanceCounter ();
200 LogEntryArray
[Index
].StartTimeStamp
= TimeStamp
;
202 return RETURN_SUCCESS
;
206 Fills in the end time of a performance measurement.
208 Looks up the record that matches Handle, Token, Module and Identifier.
209 If the record can not be found then return RETURN_NOT_FOUND.
210 If the record is found and TimeStamp is not zero,
211 then TimeStamp is added to the record as the end time.
212 If the record is found and TimeStamp is zero, then this function reads
213 the current time stamp and adds that time stamp value to the record as the end time.
215 @param Handle Pointer to environment specific context used
216 to identify the component being measured.
217 @param Token Pointer to a Null-terminated ASCII string
218 that identifies the component being measured.
219 @param Module Pointer to a Null-terminated ASCII string
220 that identifies the module being measured.
221 @param TimeStamp 64-bit time stamp.
222 @param Identifier 32-bit identifier. If the value is 0, the found record
223 is same as the one found by EndPerformanceMeasurement.
225 @retval RETURN_SUCCESS The end of the measurement was recorded.
226 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
231 EndPerformanceMeasurementEx (
232 IN CONST VOID
*Handle
, OPTIONAL
233 IN CONST CHAR8
*Token
, OPTIONAL
234 IN CONST CHAR8
*Module
, OPTIONAL
239 PEI_PERFORMANCE_LOG_HEADER
*PeiPerformanceLog
;
240 UINT32
*PeiPerformanceIdArray
;
241 PEI_PERFORMANCE_LOG_ENTRY
*LogEntryArray
;
244 if (TimeStamp
== 0) {
245 TimeStamp
= GetPerformanceCounter ();
248 InternalGetPerformanceHobLog (&PeiPerformanceLog
, &PeiPerformanceIdArray
);
249 Index
= InternalSearchForLogEntry (PeiPerformanceLog
, PeiPerformanceIdArray
, Handle
, Token
, Module
, Identifier
);
250 if (Index
>= PeiPerformanceLog
->NumberOfEntries
) {
251 return RETURN_NOT_FOUND
;
253 LogEntryArray
= (PEI_PERFORMANCE_LOG_ENTRY
*) (PeiPerformanceLog
+ 1);
254 LogEntryArray
[Index
].EndTimeStamp
= TimeStamp
;
256 return RETURN_SUCCESS
;
260 Attempts to retrieve a performance measurement log entry from the performance measurement log.
261 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
262 and then assign the Identifier with 0.
264 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
265 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
266 and the key for the second entry in the log is returned. If the performance log is empty,
267 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
268 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
269 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
270 retrieved and an implementation specific non-zero key value that specifies the end of the performance
271 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
272 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
273 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
274 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
275 If Handle is NULL, then ASSERT().
276 If Token is NULL, then ASSERT().
277 If Module is NULL, then ASSERT().
278 If StartTimeStamp is NULL, then ASSERT().
279 If EndTimeStamp is NULL, then ASSERT().
280 If Identifier is NULL, then ASSERT().
282 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
283 0, then the first performance measurement log entry is retrieved.
284 On exit, the key of the next performance of entry entry.
285 @param Handle Pointer to environment specific context used to identify the component
287 @param Token Pointer to a Null-terminated ASCII string that identifies the component
289 @param Module Pointer to a Null-terminated ASCII string that identifies the module
291 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
293 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
295 @param Identifier Pointer to the 32-bit identifier that was recorded.
297 @return The key for the next performance log entry (in general case).
302 GetPerformanceMeasurementEx (
303 IN UINTN LogEntryKey
,
304 OUT CONST VOID
**Handle
,
305 OUT CONST CHAR8
**Token
,
306 OUT CONST CHAR8
**Module
,
307 OUT UINT64
*StartTimeStamp
,
308 OUT UINT64
*EndTimeStamp
,
309 OUT UINT32
*Identifier
312 PEI_PERFORMANCE_LOG_HEADER
*PeiPerformanceLog
;
313 UINT32
*PeiPerformanceIdArray
;
314 PEI_PERFORMANCE_LOG_ENTRY
*CurrentLogEntry
;
315 PEI_PERFORMANCE_LOG_ENTRY
*LogEntryArray
;
316 UINTN NumberOfEntries
;
318 ASSERT (Handle
!= NULL
);
319 ASSERT (Token
!= NULL
);
320 ASSERT (Module
!= NULL
);
321 ASSERT (StartTimeStamp
!= NULL
);
322 ASSERT (EndTimeStamp
!= NULL
);
323 ASSERT (Identifier
!= NULL
);
325 InternalGetPerformanceHobLog (&PeiPerformanceLog
, &PeiPerformanceIdArray
);
327 NumberOfEntries
= (UINTN
) (PeiPerformanceLog
->NumberOfEntries
);
328 LogEntryArray
= (PEI_PERFORMANCE_LOG_ENTRY
*) (PeiPerformanceLog
+ 1);
330 // Make sure that LogEntryKey is a valid log entry key.
332 ASSERT (LogEntryKey
<= NumberOfEntries
);
334 if (LogEntryKey
== NumberOfEntries
) {
338 CurrentLogEntry
= &(LogEntryArray
[LogEntryKey
]);
340 *Handle
= (VOID
*) (UINTN
) (CurrentLogEntry
->Handle
);
341 *Token
= CurrentLogEntry
->Token
;
342 *Module
= CurrentLogEntry
->Module
;
343 *StartTimeStamp
= CurrentLogEntry
->StartTimeStamp
;
344 *EndTimeStamp
= CurrentLogEntry
->EndTimeStamp
;
345 *Identifier
= PeiPerformanceIdArray
[LogEntryKey
++];
351 Creates a record for the beginning of a performance measurement.
353 Creates a record that contains the Handle, Token, and Module.
354 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
355 If TimeStamp is zero, then this function reads the current time stamp
356 and adds that time stamp value to the record as the start time.
358 @param Handle Pointer to environment specific context used
359 to identify the component being measured.
360 @param Token Pointer to a Null-terminated ASCII string
361 that identifies the component being measured.
362 @param Module Pointer to a Null-terminated ASCII string
363 that identifies the module being measured.
364 @param TimeStamp 64-bit time stamp.
366 @retval RETURN_SUCCESS The start of the measurement was recorded.
367 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
372 StartPerformanceMeasurement (
373 IN CONST VOID
*Handle
, OPTIONAL
374 IN CONST CHAR8
*Token
, OPTIONAL
375 IN CONST CHAR8
*Module
, OPTIONAL
379 return StartPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
383 Fills in the end time of a performance measurement.
385 Looks up the record that matches Handle, Token, and Module.
386 If the record can not be found then return RETURN_NOT_FOUND.
387 If the record is found and TimeStamp is not zero,
388 then TimeStamp is added to the record as the end time.
389 If the record is found and TimeStamp is zero, then this function reads
390 the current time stamp and adds that time stamp value to the record as the end time.
392 @param Handle Pointer to environment specific context used
393 to identify the component being measured.
394 @param Token Pointer to a Null-terminated ASCII string
395 that identifies the component being measured.
396 @param Module Pointer to a Null-terminated ASCII string
397 that identifies the module being measured.
398 @param TimeStamp 64-bit time stamp.
400 @retval RETURN_SUCCESS The end of the measurement was recorded.
401 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
406 EndPerformanceMeasurement (
407 IN CONST VOID
*Handle
, OPTIONAL
408 IN CONST CHAR8
*Token
, OPTIONAL
409 IN CONST CHAR8
*Module
, OPTIONAL
413 return EndPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
417 Attempts to retrieve a performance measurement log entry from the performance measurement log.
418 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
419 and then eliminate the Identifier.
421 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
422 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
423 and the key for the second entry in the log is returned. If the performance log is empty,
424 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
425 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
426 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
427 retrieved and an implementation specific non-zero key value that specifies the end of the performance
428 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
429 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
430 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
431 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
432 If Handle is NULL, then ASSERT().
433 If Token is NULL, then ASSERT().
434 If Module is NULL, then ASSERT().
435 If StartTimeStamp is NULL, then ASSERT().
436 If EndTimeStamp is NULL, then ASSERT().
438 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
439 0, then the first performance measurement log entry is retrieved.
440 On exit, the key of the next performance of entry entry.
441 @param Handle Pointer to environment specific context used to identify the component
443 @param Token Pointer to a Null-terminated ASCII string that identifies the component
445 @param Module Pointer to a Null-terminated ASCII string that identifies the module
447 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
449 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
452 @return The key for the next performance log entry (in general case).
457 GetPerformanceMeasurement (
458 IN UINTN LogEntryKey
,
459 OUT CONST VOID
**Handle
,
460 OUT CONST CHAR8
**Token
,
461 OUT CONST CHAR8
**Module
,
462 OUT UINT64
*StartTimeStamp
,
463 OUT UINT64
*EndTimeStamp
467 return GetPerformanceMeasurementEx (LogEntryKey
, Handle
, Token
, Module
, StartTimeStamp
, EndTimeStamp
, &Identifier
);
471 Returns TRUE if the performance measurement macros are enabled.
473 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
474 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
476 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
477 PcdPerformanceLibraryPropertyMask is set.
478 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
479 PcdPerformanceLibraryPropertyMask is clear.
484 PerformanceMeasurementEnabled (
488 return (BOOLEAN
) ((PcdGet8(PcdPerformanceLibraryPropertyMask
) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED
) != 0);