2 Performance Library used in SMM phase.
4 This library instance provides infrastructure for SMM drivers to log performance
5 data. It consumes SMM PerformanceEx or Performance Protocol published by SmmCorePerformanceLib
6 to log performance data. If both SMM PerformanceEx and Performance Protocol are not available, it does not log any
7 performance information.
9 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
10 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #include <Guid/PerformanceMeasurement.h>
16 #include <Library/PerformanceLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/SmmServicesTableLib.h>
19 #include <Library/PcdLib.h>
20 #include <Library/BaseMemoryLib.h>
23 // The cached SMM Performance Protocol and SMM PerformanceEx Protocol interface.
24 EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL
*mPerformanceMeasurement
= NULL
;
25 BOOLEAN mPerformanceMeasurementEnabled
;
28 The constructor function initializes the Performance Measurement Enable flag
30 @param ImageHandle The firmware allocated handle for the EFI image.
31 @param SystemTable A pointer to the EFI System Table.
33 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
38 SmmPerformanceLibConstructor (
39 IN EFI_HANDLE ImageHandle
,
40 IN EFI_SYSTEM_TABLE
*SystemTable
43 mPerformanceMeasurementEnabled
= (BOOLEAN
)((PcdGet8 (PcdPerformanceLibraryPropertyMask
) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED
) != 0);
49 The function caches the pointers to SMM PerformanceEx protocol and Performance Protocol.
51 The function locates SMM PerformanceEx protocol and Performance Protocol from protocol database.
53 @retval EFI_SUCCESS SMM PerformanceEx protocol or Performance Protocol is successfully located.
54 @retval EFI_NOT_FOUND Both SMM PerformanceEx protocol and Performance Protocol are not located to log performance.
58 GetPerformanceMeasurementProtocol (
63 EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL
*PerformanceMeasurement
;
65 if (mPerformanceMeasurement
!= NULL
) {
69 Status
= gSmst
->SmmLocateProtocol (&gEdkiiSmmPerformanceMeasurementProtocolGuid
, NULL
, (VOID
**)&PerformanceMeasurement
);
70 if (!EFI_ERROR (Status
)) {
71 ASSERT (PerformanceMeasurement
!= NULL
);
73 // Cache PerformanceMeasurement Protocol.
75 mPerformanceMeasurement
= PerformanceMeasurement
;
83 Creates a record for the beginning of a performance measurement.
85 Creates a record that contains the Handle, Token, Module and Identifier.
86 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
87 If TimeStamp is zero, then this function reads the current time stamp
88 and adds that time stamp value to the record as the start time.
90 @param Handle Pointer to environment specific context used
91 to identify the component being measured.
92 @param Token Pointer to a Null-terminated ASCII string
93 that identifies the component being measured.
94 @param Module Pointer to a Null-terminated ASCII string
95 that identifies the module being measured.
96 @param TimeStamp 64-bit time stamp.
97 @param Identifier 32-bit identifier. If the value is 0, the created record
98 is same as the one created by StartPerformanceMeasurement.
100 @retval RETURN_SUCCESS The start of the measurement was recorded.
101 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
106 StartPerformanceMeasurementEx (
107 IN CONST VOID
*Handle OPTIONAL
,
108 IN CONST CHAR8
*Token OPTIONAL
,
109 IN CONST CHAR8
*Module OPTIONAL
,
117 Status
= GetPerformanceMeasurementProtocol ();
118 if (EFI_ERROR (Status
)) {
119 return RETURN_NOT_FOUND
;
124 } else if (Module
!= NULL
) {
130 if (mPerformanceMeasurement
!= NULL
) {
131 Status
= mPerformanceMeasurement
->CreatePerformanceMeasurement (Handle
, NULL
, String
, TimeStamp
, 0, Identifier
, PerfStartEntry
);
136 return (RETURN_STATUS
)Status
;
140 Fills in the end time of a performance measurement.
142 Looks up the record that matches Handle, Token and Module.
143 If the record can not be found then return RETURN_NOT_FOUND.
144 If the record is found and TimeStamp is not zero,
145 then TimeStamp is added to the record as the end time.
146 If the record is found and TimeStamp is zero, then this function reads
147 the current time stamp and adds that time stamp value to the record as the end 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 found record
157 is same as the one found by EndPerformanceMeasurement.
159 @retval RETURN_SUCCESS The end of the measurement was recorded.
160 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
165 EndPerformanceMeasurementEx (
166 IN CONST VOID
*Handle OPTIONAL
,
167 IN CONST CHAR8
*Token OPTIONAL
,
168 IN CONST CHAR8
*Module OPTIONAL
,
176 Status
= GetPerformanceMeasurementProtocol ();
177 if (EFI_ERROR (Status
)) {
178 return RETURN_NOT_FOUND
;
183 } else if (Module
!= NULL
) {
189 if (mPerformanceMeasurement
!= NULL
) {
190 Status
= mPerformanceMeasurement
->CreatePerformanceMeasurement (Handle
, NULL
, String
, TimeStamp
, 0, Identifier
, PerfEndEntry
);
195 return (RETURN_STATUS
)Status
;
199 Attempts to retrieve a performance measurement log entry from the performance measurement log.
200 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
201 and then assign the Identifier with 0.
203 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
204 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
205 and the key for the second entry in the log is returned. If the performance log is empty,
206 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
207 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
208 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
209 retrieved and an implementation specific non-zero key value that specifies the end of the performance
210 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
211 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
212 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
213 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
214 If Handle is NULL, then ASSERT().
215 If Token is NULL, then ASSERT().
216 If Module is NULL, then ASSERT().
217 If StartTimeStamp is NULL, then ASSERT().
218 If EndTimeStamp is NULL, then ASSERT().
219 If Identifier is NULL, then ASSERT().
221 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
222 0, then the first performance measurement log entry is retrieved.
223 On exit, the key of the next performance log entry.
224 @param Handle Pointer to environment specific context used to identify the component
226 @param Token Pointer to a Null-terminated ASCII string that identifies the component
228 @param Module Pointer to a Null-terminated ASCII string that identifies the module
230 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
232 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
234 @param Identifier Pointer to the 32-bit identifier that was recorded.
236 @return The key for the next performance log entry (in general case).
241 GetPerformanceMeasurementEx (
242 IN UINTN LogEntryKey
,
243 OUT CONST VOID
**Handle
,
244 OUT CONST CHAR8
**Token
,
245 OUT CONST CHAR8
**Module
,
246 OUT UINT64
*StartTimeStamp
,
247 OUT UINT64
*EndTimeStamp
,
248 OUT UINT32
*Identifier
255 Creates a record for the beginning of a performance measurement.
257 Creates a record that contains the Handle, Token, and Module.
258 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
259 If TimeStamp is zero, then this function reads the current time stamp
260 and adds that time stamp value to the record as the start time.
262 @param Handle Pointer to environment specific context used
263 to identify the component being measured.
264 @param Token Pointer to a Null-terminated ASCII string
265 that identifies the component being measured.
266 @param Module Pointer to a Null-terminated ASCII string
267 that identifies the module being measured.
268 @param TimeStamp 64-bit time stamp.
270 @retval RETURN_SUCCESS The start of the measurement was recorded.
271 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
276 StartPerformanceMeasurement (
277 IN CONST VOID
*Handle OPTIONAL
,
278 IN CONST CHAR8
*Token OPTIONAL
,
279 IN CONST CHAR8
*Module OPTIONAL
,
283 return StartPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
287 Fills in the end time of a performance measurement.
289 Looks up the record that matches Handle, Token, and Module.
290 If the record can not be found then return RETURN_NOT_FOUND.
291 If the record is found and TimeStamp is not zero,
292 then TimeStamp is added to the record as the end time.
293 If the record is found and TimeStamp is zero, then this function reads
294 the current time stamp and adds that time stamp value to the record as the end time.
296 @param Handle Pointer to environment specific context used
297 to identify the component being measured.
298 @param Token Pointer to a Null-terminated ASCII string
299 that identifies the component being measured.
300 @param Module Pointer to a Null-terminated ASCII string
301 that identifies the module being measured.
302 @param TimeStamp 64-bit time stamp.
304 @retval RETURN_SUCCESS The end of the measurement was recorded.
305 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
310 EndPerformanceMeasurement (
311 IN CONST VOID
*Handle OPTIONAL
,
312 IN CONST CHAR8
*Token OPTIONAL
,
313 IN CONST CHAR8
*Module OPTIONAL
,
317 return EndPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
321 Attempts to retrieve a performance measurement log entry from the performance measurement log.
322 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
323 and then eliminate the Identifier.
325 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
326 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
327 and the key for the second entry in the log is returned. If the performance log is empty,
328 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
329 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
330 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
331 retrieved and an implementation specific non-zero key value that specifies the end of the performance
332 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
333 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
334 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
335 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
336 If Handle is NULL, then ASSERT().
337 If Token is NULL, then ASSERT().
338 If Module is NULL, then ASSERT().
339 If StartTimeStamp is NULL, then ASSERT().
340 If EndTimeStamp is NULL, then ASSERT().
342 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
343 0, then the first performance measurement log entry is retrieved.
344 On exit, the key of the next performance log entry.
345 @param Handle Pointer to environment specific context used to identify the component
347 @param Token Pointer to a Null-terminated ASCII string that identifies the component
349 @param Module Pointer to a Null-terminated ASCII string that identifies the module
351 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
353 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
356 @return The key for the next performance log entry (in general case).
361 GetPerformanceMeasurement (
362 IN UINTN LogEntryKey
,
363 OUT CONST VOID
**Handle
,
364 OUT CONST CHAR8
**Token
,
365 OUT CONST CHAR8
**Module
,
366 OUT UINT64
*StartTimeStamp
,
367 OUT UINT64
*EndTimeStamp
374 Returns TRUE if the performance measurement macros are enabled.
376 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
377 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
379 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
380 PcdPerformanceLibraryPropertyMask is set.
381 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
382 PcdPerformanceLibraryPropertyMask is clear.
387 PerformanceMeasurementEnabled (
391 return mPerformanceMeasurementEnabled
;
395 Create performance record with event description and a timestamp.
397 @param CallerIdentifier - Image handle or pointer to caller ID GUID
398 @param Guid - Pointer to a GUID
399 @param String - Pointer to a string describing the measurement
400 @param Address - Pointer to a location in memory relevant to the measurement
401 @param Identifier - Performance identifier describing the type of measurement
403 @retval RETURN_SUCCESS - Successfully created performance record
404 @retval RETURN_OUT_OF_RESOURCES - Ran out of space to store the records
405 @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
406 pointer or invalid PerfId
411 LogPerformanceMeasurement (
412 IN CONST VOID
*CallerIdentifier
,
413 IN CONST VOID
*Guid OPTIONAL
,
414 IN CONST CHAR8
*String OPTIONAL
,
415 IN UINT64 Address OPTIONAL
,
421 Status
= GetPerformanceMeasurementProtocol ();
422 if (EFI_ERROR (Status
)) {
423 return RETURN_OUT_OF_RESOURCES
;
426 if (mPerformanceMeasurement
!= NULL
) {
427 Status
= mPerformanceMeasurement
->CreatePerformanceMeasurement (CallerIdentifier
, Guid
, String
, 0, Address
, Identifier
, PerfEntry
);
432 return (RETURN_STATUS
)Status
;
436 Check whether the specified performance measurement can be logged.
438 This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
439 and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
441 @param Type - Type of the performance measurement entry.
443 @retval TRUE The performance measurement can be logged.
444 @retval FALSE The performance measurement can NOT be logged.
449 LogPerformanceMeasurementEnabled (
454 // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
456 if (PerformanceMeasurementEnabled () && ((PcdGet8 (PcdPerformanceLibraryPropertyMask
) & Type
) == 0)) {