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
15 #include <Guid/PerformanceMeasurement.h>
17 #include <Library/PerformanceLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/SmmServicesTableLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/BaseMemoryLib.h>
24 // The cached SMM Performance Protocol and SMM PerformanceEx Protocol interface.
25 EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL
*mPerformanceMeasurement
= NULL
;
26 BOOLEAN mPerformanceMeasurementEnabled
;
29 The constructor function initializes the Performance Measurement Enable flag
31 @param ImageHandle The firmware allocated handle for the EFI image.
32 @param SystemTable A pointer to the EFI System Table.
34 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
39 SmmPerformanceLibConstructor (
40 IN EFI_HANDLE ImageHandle
,
41 IN EFI_SYSTEM_TABLE
*SystemTable
45 mPerformanceMeasurementEnabled
= (BOOLEAN
) ((PcdGet8(PcdPerformanceLibraryPropertyMask
) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED
) != 0);
51 The function caches the pointers to SMM PerformanceEx protocol and Performance Protocol.
53 The function locates SMM PerformanceEx protocol and Performance Protocol from protocol database.
55 @retval EFI_SUCCESS SMM PerformanceEx protocol or Performance Protocol is successfully located.
56 @retval EFI_NOT_FOUND Both SMM PerformanceEx protocol and Performance Protocol are not located to log performance.
60 GetPerformanceMeasurementProtocol (
65 EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL
*PerformanceMeasurement
;
67 if (mPerformanceMeasurement
!= NULL
) {
71 Status
= gSmst
->SmmLocateProtocol (&gEdkiiSmmPerformanceMeasurementProtocolGuid
, NULL
, (VOID
**) &PerformanceMeasurement
);
72 if (!EFI_ERROR (Status
)) {
73 ASSERT (PerformanceMeasurement
!= NULL
);
75 // Cache PerformanceMeasurement Protocol.
77 mPerformanceMeasurement
= PerformanceMeasurement
;
84 Creates a record for the beginning of a performance measurement.
86 Creates a record that contains the Handle, Token, Module and Identifier.
87 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
88 If TimeStamp is zero, then this function reads the current time stamp
89 and adds that time stamp value to the record as the start time.
91 @param Handle Pointer to environment specific context used
92 to identify the component being measured.
93 @param Token Pointer to a Null-terminated ASCII string
94 that identifies the component being measured.
95 @param Module Pointer to a Null-terminated ASCII string
96 that identifies the module being measured.
97 @param TimeStamp 64-bit time stamp.
98 @param Identifier 32-bit identifier. If the value is 0, the created record
99 is same as the one created by StartPerformanceMeasurement.
101 @retval RETURN_SUCCESS The start of the measurement was recorded.
102 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
107 StartPerformanceMeasurementEx (
108 IN CONST VOID
*Handle
, OPTIONAL
109 IN CONST CHAR8
*Token
, OPTIONAL
110 IN CONST CHAR8
*Module
, OPTIONAL
118 Status
= GetPerformanceMeasurementProtocol ();
119 if (EFI_ERROR (Status
)) {
120 return RETURN_NOT_FOUND
;
125 } else if (Module
!= NULL
) {
131 if (mPerformanceMeasurement
!= NULL
) {
132 Status
= mPerformanceMeasurement
->CreatePerformanceMeasurement (Handle
, NULL
, String
, TimeStamp
, 0, Identifier
, PerfStartEntry
);
137 return (RETURN_STATUS
) Status
;
141 Fills in the end time of a performance measurement.
143 Looks up the record that matches Handle, Token and Module.
144 If the record can not be found then return RETURN_NOT_FOUND.
145 If the record is found and TimeStamp is not zero,
146 then TimeStamp is added to the record as the end time.
147 If the record is found and TimeStamp is zero, then this function reads
148 the current time stamp and adds that time stamp value to the record as the end time.
150 @param Handle Pointer to environment specific context used
151 to identify the component being measured.
152 @param Token Pointer to a Null-terminated ASCII string
153 that identifies the component being measured.
154 @param Module Pointer to a Null-terminated ASCII string
155 that identifies the module being measured.
156 @param TimeStamp 64-bit time stamp.
157 @param Identifier 32-bit identifier. If the value is 0, the found record
158 is same as the one found by EndPerformanceMeasurement.
160 @retval RETURN_SUCCESS The end of the measurement was recorded.
161 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
166 EndPerformanceMeasurementEx (
167 IN CONST VOID
*Handle
, OPTIONAL
168 IN CONST CHAR8
*Token
, OPTIONAL
169 IN CONST CHAR8
*Module
, OPTIONAL
177 Status
= GetPerformanceMeasurementProtocol ();
178 if (EFI_ERROR (Status
)) {
179 return RETURN_NOT_FOUND
;
184 } else if (Module
!= NULL
) {
190 if (mPerformanceMeasurement
!= NULL
) {
191 Status
= mPerformanceMeasurement
->CreatePerformanceMeasurement (Handle
, NULL
, String
, TimeStamp
, 0, Identifier
, PerfEndEntry
);
196 return (RETURN_STATUS
) Status
;
200 Attempts to retrieve a performance measurement log entry from the performance measurement log.
201 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
202 and then assign the Identifier with 0.
204 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
205 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
206 and the key for the second entry in the log is returned. If the performance log is empty,
207 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
208 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
209 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
210 retrieved and an implementation specific non-zero key value that specifies the end of the performance
211 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
212 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
213 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
214 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
215 If Handle is NULL, then ASSERT().
216 If Token is NULL, then ASSERT().
217 If Module is NULL, then ASSERT().
218 If StartTimeStamp is NULL, then ASSERT().
219 If EndTimeStamp is NULL, then ASSERT().
220 If Identifier is NULL, then ASSERT().
222 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
223 0, then the first performance measurement log entry is retrieved.
224 On exit, the key of the next performance log entry.
225 @param Handle Pointer to environment specific context used to identify the component
227 @param Token Pointer to a Null-terminated ASCII string that identifies the component
229 @param Module Pointer to a Null-terminated ASCII string that identifies the module
231 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
233 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
235 @param Identifier Pointer to the 32-bit identifier that was recorded.
237 @return The key for the next performance log entry (in general case).
242 GetPerformanceMeasurementEx (
243 IN UINTN LogEntryKey
,
244 OUT CONST VOID
**Handle
,
245 OUT CONST CHAR8
**Token
,
246 OUT CONST CHAR8
**Module
,
247 OUT UINT64
*StartTimeStamp
,
248 OUT UINT64
*EndTimeStamp
,
249 OUT UINT32
*Identifier
256 Creates a record for the beginning of a performance measurement.
258 Creates a record that contains the Handle, Token, and Module.
259 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
260 If TimeStamp is zero, then this function reads the current time stamp
261 and adds that time stamp value to the record as the start time.
263 @param Handle Pointer to environment specific context used
264 to identify the component being measured.
265 @param Token Pointer to a Null-terminated ASCII string
266 that identifies the component being measured.
267 @param Module Pointer to a Null-terminated ASCII string
268 that identifies the module being measured.
269 @param TimeStamp 64-bit time stamp.
271 @retval RETURN_SUCCESS The start of the measurement was recorded.
272 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
277 StartPerformanceMeasurement (
278 IN CONST VOID
*Handle
, OPTIONAL
279 IN CONST CHAR8
*Token
, OPTIONAL
280 IN CONST CHAR8
*Module
, OPTIONAL
284 return StartPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
288 Fills in the end time of a performance measurement.
290 Looks up the record that matches Handle, Token, and Module.
291 If the record can not be found then return RETURN_NOT_FOUND.
292 If the record is found and TimeStamp is not zero,
293 then TimeStamp is added to the record as the end time.
294 If the record is found and TimeStamp is zero, then this function reads
295 the current time stamp and adds that time stamp value to the record as the end time.
297 @param Handle Pointer to environment specific context used
298 to identify the component being measured.
299 @param Token Pointer to a Null-terminated ASCII string
300 that identifies the component being measured.
301 @param Module Pointer to a Null-terminated ASCII string
302 that identifies the module being measured.
303 @param TimeStamp 64-bit time stamp.
305 @retval RETURN_SUCCESS The end of the measurement was recorded.
306 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
311 EndPerformanceMeasurement (
312 IN CONST VOID
*Handle
, OPTIONAL
313 IN CONST CHAR8
*Token
, OPTIONAL
314 IN CONST CHAR8
*Module
, OPTIONAL
318 return EndPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
322 Attempts to retrieve a performance measurement log entry from the performance measurement log.
323 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
324 and then eliminate the Identifier.
326 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
327 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
328 and the key for the second entry in the log is returned. If the performance log is empty,
329 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
330 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
331 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
332 retrieved and an implementation specific non-zero key value that specifies the end of the performance
333 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
334 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
335 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
336 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
337 If Handle is NULL, then ASSERT().
338 If Token is NULL, then ASSERT().
339 If Module is NULL, then ASSERT().
340 If StartTimeStamp is NULL, then ASSERT().
341 If EndTimeStamp is NULL, then ASSERT().
343 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
344 0, then the first performance measurement log entry is retrieved.
345 On exit, the key of the next performance log entry.
346 @param Handle Pointer to environment specific context used to identify the component
348 @param Token Pointer to a Null-terminated ASCII string that identifies the component
350 @param Module Pointer to a Null-terminated ASCII string that identifies the module
352 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
354 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
357 @return The key for the next performance log entry (in general case).
362 GetPerformanceMeasurement (
363 IN UINTN LogEntryKey
,
364 OUT CONST VOID
**Handle
,
365 OUT CONST CHAR8
**Token
,
366 OUT CONST CHAR8
**Module
,
367 OUT UINT64
*StartTimeStamp
,
368 OUT UINT64
*EndTimeStamp
375 Returns TRUE if the performance measurement macros are enabled.
377 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
378 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
380 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
381 PcdPerformanceLibraryPropertyMask is set.
382 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
383 PcdPerformanceLibraryPropertyMask is clear.
388 PerformanceMeasurementEnabled (
392 return mPerformanceMeasurementEnabled
;
396 Create performance record with event description and a timestamp.
398 @param CallerIdentifier - Image handle or pointer to caller ID GUID
399 @param Guid - Pointer to a GUID
400 @param String - Pointer to a string describing the measurement
401 @param Address - Pointer to a location in memory relevant to the measurement
402 @param Identifier - Performance identifier describing the type of measurement
404 @retval RETURN_SUCCESS - Successfully created performance record
405 @retval RETURN_OUT_OF_RESOURCES - Ran out of space to store the records
406 @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
407 pointer or invalid PerfId
412 LogPerformanceMeasurement (
413 IN CONST VOID
*CallerIdentifier
,
414 IN CONST VOID
*Guid
, OPTIONAL
415 IN CONST CHAR8
*String
, OPTIONAL
416 IN UINT64 Address
, OPTIONAL
422 Status
= GetPerformanceMeasurementProtocol ();
423 if (EFI_ERROR (Status
)) {
424 return RETURN_OUT_OF_RESOURCES
;
427 if (mPerformanceMeasurement
!= NULL
) {
428 Status
= mPerformanceMeasurement
->CreatePerformanceMeasurement (CallerIdentifier
, Guid
, String
, 0, Address
, Identifier
, PerfEntry
);
433 return (RETURN_STATUS
) Status
;
437 Check whether the specified performance measurement can be logged.
439 This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
440 and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
442 @param Type - Type of the performance measurement entry.
444 @retval TRUE The performance measurement can be logged.
445 @retval FALSE The performance measurement can NOT be logged.
450 LogPerformanceMeasurementEnabled (
455 // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
457 if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask
) & Type
) == 0) {