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 - 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.
21 #include <Guid/Performance.h>
23 #include <Library/PerformanceLib.h>
24 #include <Library/DebugLib.h>
25 #include <Library/SmmServicesTableLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/BaseMemoryLib.h>
30 // The cached SMM Performance Protocol and SMM PerformanceEx Protocol interface.
32 PERFORMANCE_PROTOCOL
*mPerformance
= NULL
;
33 PERFORMANCE_EX_PROTOCOL
*mPerformanceEx
= NULL
;
34 BOOLEAN mPerformanceMeasurementEnabled
;
37 The constructor function initializes the Performance Measurement Enable flag
39 @param ImageHandle The firmware allocated handle for the EFI image.
40 @param SystemTable A pointer to the EFI System Table.
42 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
47 SmmPerformanceLibConstructor (
48 IN EFI_HANDLE ImageHandle
,
49 IN EFI_SYSTEM_TABLE
*SystemTable
53 mPerformanceMeasurementEnabled
= (BOOLEAN
) ((PcdGet8(PcdPerformanceLibraryPropertyMask
) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED
) != 0);
59 The function caches the pointers to SMM PerformanceEx protocol and Performance Protocol.
61 The function locates SMM PerformanceEx protocol and Performance Protocol from protocol database.
63 @retval EFI_SUCCESS SMM PerformanceEx protocol or Performance Protocol is successfully located.
64 @retval EFI_NOT_FOUND Both SMM PerformanceEx protocol and Performance Protocol are not located to log performance.
68 GetPerformanceProtocol (
73 PERFORMANCE_PROTOCOL
*Performance
;
74 PERFORMANCE_EX_PROTOCOL
*PerformanceEx
;
76 if (mPerformanceEx
!= NULL
|| mPerformance
!= NULL
) {
80 Status
= gSmst
->SmmLocateProtocol (&gSmmPerformanceExProtocolGuid
, NULL
, (VOID
**) &PerformanceEx
);
81 if (!EFI_ERROR (Status
)) {
82 ASSERT (PerformanceEx
!= NULL
);
84 // Cache PerformanceEx Protocol.
86 mPerformanceEx
= PerformanceEx
;
90 Status
= gSmst
->SmmLocateProtocol (&gSmmPerformanceProtocolGuid
, NULL
, (VOID
**) &Performance
);
91 if (!EFI_ERROR (Status
)) {
92 ASSERT (Performance
!= NULL
);
94 // Cache performance protocol.
96 mPerformance
= Performance
;
100 return EFI_NOT_FOUND
;
104 Creates a record for the beginning of a performance measurement.
106 Creates a record that contains the Handle, Token, Module and Identifier.
107 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
108 If TimeStamp is zero, then this function reads the current time stamp
109 and adds that time stamp value to the record as the start time.
111 @param Handle Pointer to environment specific context used
112 to identify the component being measured.
113 @param Token Pointer to a Null-terminated ASCII string
114 that identifies the component being measured.
115 @param Module Pointer to a Null-terminated ASCII string
116 that identifies the module being measured.
117 @param TimeStamp 64-bit time stamp.
118 @param Identifier 32-bit identifier. If the value is 0, the created record
119 is same as the one created by StartPerformanceMeasurement.
121 @retval RETURN_SUCCESS The start of the measurement was recorded.
122 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
127 StartPerformanceMeasurementEx (
128 IN CONST VOID
*Handle
, OPTIONAL
129 IN CONST CHAR8
*Token
, OPTIONAL
130 IN CONST CHAR8
*Module
, OPTIONAL
137 Status
= GetPerformanceProtocol ();
138 if (EFI_ERROR (Status
)) {
139 return RETURN_OUT_OF_RESOURCES
;
142 if (mPerformanceEx
!= NULL
) {
143 Status
= mPerformanceEx
->StartGaugeEx (Handle
, Token
, Module
, TimeStamp
, Identifier
);
144 } else if (mPerformance
!= NULL
) {
145 Status
= mPerformance
->StartGauge (Handle
, Token
, Module
, TimeStamp
);
150 return (RETURN_STATUS
) Status
;
154 Fills in the end time of a performance measurement.
156 Looks up the record that matches Handle, Token, Module and Identifier.
157 If the record can not be found then return RETURN_NOT_FOUND.
158 If the record is found and TimeStamp is not zero,
159 then TimeStamp is added to the record as the end time.
160 If the record is found and TimeStamp is zero, then this function reads
161 the current time stamp and adds that time stamp value to the record as the end time.
163 @param Handle Pointer to environment specific context used
164 to identify the component being measured.
165 @param Token Pointer to a Null-terminated ASCII string
166 that identifies the component being measured.
167 @param Module Pointer to a Null-terminated ASCII string
168 that identifies the module being measured.
169 @param TimeStamp 64-bit time stamp.
170 @param Identifier 32-bit identifier. If the value is 0, the found record
171 is same as the one found by EndPerformanceMeasurement.
173 @retval RETURN_SUCCESS The end of the measurement was recorded.
174 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
179 EndPerformanceMeasurementEx (
180 IN CONST VOID
*Handle
, OPTIONAL
181 IN CONST CHAR8
*Token
, OPTIONAL
182 IN CONST CHAR8
*Module
, OPTIONAL
189 Status
= GetPerformanceProtocol ();
190 if (EFI_ERROR (Status
)) {
191 return RETURN_NOT_FOUND
;
194 if (mPerformanceEx
!= NULL
) {
195 Status
= mPerformanceEx
->EndGaugeEx (Handle
, Token
, Module
, TimeStamp
, Identifier
);
196 } else if (mPerformance
!= NULL
) {
197 Status
= mPerformance
->EndGauge (Handle
, Token
, Module
, TimeStamp
);
202 return (RETURN_STATUS
) Status
;
206 Attempts to retrieve a performance measurement log entry from the performance measurement log.
207 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
208 and then assign the Identifier with 0.
210 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
211 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
212 and the key for the second entry in the log is returned. If the performance log is empty,
213 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
214 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
215 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
216 retrieved and an implementation specific non-zero key value that specifies the end of the performance
217 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
218 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
219 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
220 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
221 If Handle is NULL, then ASSERT().
222 If Token is NULL, then ASSERT().
223 If Module is NULL, then ASSERT().
224 If StartTimeStamp is NULL, then ASSERT().
225 If EndTimeStamp is NULL, then ASSERT().
226 If Identifier is NULL, then ASSERT().
228 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
229 0, then the first performance measurement log entry is retrieved.
230 On exit, the key of the next performance log entry.
231 @param Handle Pointer to environment specific context used to identify the component
233 @param Token Pointer to a Null-terminated ASCII string that identifies the component
235 @param Module Pointer to a Null-terminated ASCII string that identifies the module
237 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
239 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
241 @param Identifier Pointer to the 32-bit identifier that was recorded.
243 @return The key for the next performance log entry (in general case).
248 GetPerformanceMeasurementEx (
249 IN UINTN LogEntryKey
,
250 OUT CONST VOID
**Handle
,
251 OUT CONST CHAR8
**Token
,
252 OUT CONST CHAR8
**Module
,
253 OUT UINT64
*StartTimeStamp
,
254 OUT UINT64
*EndTimeStamp
,
255 OUT UINT32
*Identifier
259 GAUGE_DATA_ENTRY_EX
*GaugeData
;
263 ASSERT (Handle
!= NULL
);
264 ASSERT (Token
!= NULL
);
265 ASSERT (Module
!= NULL
);
266 ASSERT (StartTimeStamp
!= NULL
);
267 ASSERT (EndTimeStamp
!= NULL
);
268 ASSERT (Identifier
!= NULL
);
270 Status
= GetPerformanceProtocol ();
271 if (EFI_ERROR (Status
)) {
275 if (mPerformanceEx
!= NULL
) {
276 Status
= mPerformanceEx
->GetGaugeEx (LogEntryKey
++, &GaugeData
);
277 } else if (mPerformance
!= NULL
) {
278 Status
= mPerformance
->GetGauge (LogEntryKey
++, (GAUGE_DATA_ENTRY
**) &GaugeData
);
285 // Make sure that LogEntryKey is a valid log entry key,
287 ASSERT (Status
!= EFI_INVALID_PARAMETER
);
289 if (EFI_ERROR (Status
)) {
291 // The LogEntryKey is the last entry (equals to the total entry number).
296 ASSERT (GaugeData
!= NULL
);
298 *Handle
= (VOID
*) (UINTN
) GaugeData
->Handle
;
299 *Token
= GaugeData
->Token
;
300 *Module
= GaugeData
->Module
;
301 *StartTimeStamp
= GaugeData
->StartTimeStamp
;
302 *EndTimeStamp
= GaugeData
->EndTimeStamp
;
303 if (mPerformanceEx
!= NULL
) {
304 *Identifier
= GaugeData
->Identifier
;
313 Creates a record for the beginning of a performance measurement.
315 Creates a record that contains the Handle, Token, and Module.
316 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
317 If TimeStamp is zero, then this function reads the current time stamp
318 and adds that time stamp value to the record as the start time.
320 @param Handle Pointer to environment specific context used
321 to identify the component being measured.
322 @param Token Pointer to a Null-terminated ASCII string
323 that identifies the component being measured.
324 @param Module Pointer to a Null-terminated ASCII string
325 that identifies the module being measured.
326 @param TimeStamp 64-bit time stamp.
328 @retval RETURN_SUCCESS The start of the measurement was recorded.
329 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
334 StartPerformanceMeasurement (
335 IN CONST VOID
*Handle
, OPTIONAL
336 IN CONST CHAR8
*Token
, OPTIONAL
337 IN CONST CHAR8
*Module
, OPTIONAL
341 return StartPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
345 Fills in the end time of a performance measurement.
347 Looks up the record that matches Handle, Token, and Module.
348 If the record can not be found then return RETURN_NOT_FOUND.
349 If the record is found and TimeStamp is not zero,
350 then TimeStamp is added to the record as the end time.
351 If the record is found and TimeStamp is zero, then this function reads
352 the current time stamp and adds that time stamp value to the record as the end time.
354 @param Handle Pointer to environment specific context used
355 to identify the component being measured.
356 @param Token Pointer to a Null-terminated ASCII string
357 that identifies the component being measured.
358 @param Module Pointer to a Null-terminated ASCII string
359 that identifies the module being measured.
360 @param TimeStamp 64-bit time stamp.
362 @retval RETURN_SUCCESS The end of the measurement was recorded.
363 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
368 EndPerformanceMeasurement (
369 IN CONST VOID
*Handle
, OPTIONAL
370 IN CONST CHAR8
*Token
, OPTIONAL
371 IN CONST CHAR8
*Module
, OPTIONAL
375 return EndPerformanceMeasurementEx (Handle
, Token
, Module
, TimeStamp
, 0);
379 Attempts to retrieve a performance measurement log entry from the performance measurement log.
380 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
381 and then eliminate the Identifier.
383 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
384 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
385 and the key for the second entry in the log is returned. If the performance log is empty,
386 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
387 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
388 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
389 retrieved and an implementation specific non-zero key value that specifies the end of the performance
390 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
391 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
392 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
393 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
394 If Handle is NULL, then ASSERT().
395 If Token is NULL, then ASSERT().
396 If Module is NULL, then ASSERT().
397 If StartTimeStamp is NULL, then ASSERT().
398 If EndTimeStamp is NULL, then ASSERT().
400 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
401 0, then the first performance measurement log entry is retrieved.
402 On exit, the key of the next performance log entry.
403 @param Handle Pointer to environment specific context used to identify the component
405 @param Token Pointer to a Null-terminated ASCII string that identifies the component
407 @param Module Pointer to a Null-terminated ASCII string that identifies the module
409 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
411 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
414 @return The key for the next performance log entry (in general case).
419 GetPerformanceMeasurement (
420 IN UINTN LogEntryKey
,
421 OUT CONST VOID
**Handle
,
422 OUT CONST CHAR8
**Token
,
423 OUT CONST CHAR8
**Module
,
424 OUT UINT64
*StartTimeStamp
,
425 OUT UINT64
*EndTimeStamp
429 return GetPerformanceMeasurementEx (LogEntryKey
, Handle
, Token
, Module
, StartTimeStamp
, EndTimeStamp
, &Identifier
);
433 Returns TRUE if the performance measurement macros are enabled.
435 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
436 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
438 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
439 PcdPerformanceLibraryPropertyMask is set.
440 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
441 PcdPerformanceLibraryPropertyMask is clear.
446 PerformanceMeasurementEnabled (
450 return mPerformanceMeasurementEnabled
;