]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Library / SmmPerformanceLib / SmmPerformanceLib.c
CommitLineData
d042c6e8 1/** @file\r
2 Performance Library used in SMM phase.\r
3\r
4 This library instance provides infrastructure for SMM drivers to log performance\r
f0da4d7d
SZ
5 data. It consumes SMM PerformanceEx or Performance Protocol published by SmmCorePerformanceLib\r
6 to log performance data. If both SMM PerformanceEx and Performance Protocol are not available, it does not log any\r
d042c6e8 7 performance information.\r
8\r
d1102dba 9 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
d042c6e8 10This program and the accompanying materials\r
11are licensed and made available under the terms and conditions of the BSD License\r
12which accompanies this distribution. The full text of the license may be found at\r
13http://opensource.org/licenses/bsd-license.php\r
14\r
15THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
16WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
17\r
18**/\r
19\r
20\r
137fb13d 21#include <Guid/PerformanceMeasurement.h>\r
d042c6e8 22\r
23#include <Library/PerformanceLib.h>\r
24#include <Library/DebugLib.h>\r
25#include <Library/SmmServicesTableLib.h>\r
26#include <Library/PcdLib.h>\r
27#include <Library/BaseMemoryLib.h>\r
28\r
d042c6e8 29//\r
f0da4d7d 30// The cached SMM Performance Protocol and SMM PerformanceEx Protocol interface.\r
137fb13d
BD
31EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL *mPerformanceMeasurement = NULL;\r
32BOOLEAN mPerformanceMeasurementEnabled;\r
d042c6e8 33\r
34/**\r
f0da4d7d 35 The constructor function initializes the Performance Measurement Enable flag\r
d042c6e8 36\r
37 @param ImageHandle The firmware allocated handle for the EFI image.\r
38 @param SystemTable A pointer to the EFI System Table.\r
39\r
40 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
41\r
42**/\r
43EFI_STATUS\r
44EFIAPI\r
45SmmPerformanceLibConstructor (\r
46 IN EFI_HANDLE ImageHandle,\r
47 IN EFI_SYSTEM_TABLE *SystemTable\r
48 )\r
49{\r
d1102dba 50\r
d042c6e8 51 mPerformanceMeasurementEnabled = (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);\r
52\r
53 return EFI_SUCCESS;\r
54}\r
55\r
56/**\r
f0da4d7d 57 The function caches the pointers to SMM PerformanceEx protocol and Performance Protocol.\r
d042c6e8 58\r
f0da4d7d 59 The function locates SMM PerformanceEx protocol and Performance Protocol from protocol database.\r
d042c6e8 60\r
f0da4d7d
SZ
61 @retval EFI_SUCCESS SMM PerformanceEx protocol or Performance Protocol is successfully located.\r
62 @retval EFI_NOT_FOUND Both SMM PerformanceEx protocol and Performance Protocol are not located to log performance.\r
d042c6e8 63\r
64**/\r
65EFI_STATUS\r
137fb13d 66GetPerformanceMeasurementProtocol (\r
d042c6e8 67 VOID\r
68 )\r
69{\r
f0da4d7d 70 EFI_STATUS Status;\r
137fb13d 71 EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL *PerformanceMeasurement;\r
d042c6e8 72\r
137fb13d 73 if (mPerformanceMeasurement != NULL) {\r
f0da4d7d
SZ
74 return EFI_SUCCESS;\r
75 }\r
76\r
137fb13d 77 Status = gSmst->SmmLocateProtocol (&gEdkiiSmmPerformanceMeasurementProtocolGuid, NULL, (VOID **) &PerformanceMeasurement);\r
f0da4d7d 78 if (!EFI_ERROR (Status)) {\r
137fb13d 79 ASSERT (PerformanceMeasurement != NULL);\r
f0da4d7d 80 //\r
137fb13d 81 // Cache PerformanceMeasurement Protocol.\r
f0da4d7d 82 //\r
137fb13d 83 mPerformanceMeasurement = PerformanceMeasurement;\r
d042c6e8 84 return EFI_SUCCESS;\r
85 }\r
f0da4d7d 86 return EFI_NOT_FOUND;\r
d042c6e8 87}\r
88\r
89/**\r
90 Creates a record for the beginning of a performance measurement.\r
91\r
f0da4d7d 92 Creates a record that contains the Handle, Token, Module and Identifier.\r
d042c6e8 93 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
94 If TimeStamp is zero, then this function reads the current time stamp\r
95 and adds that time stamp value to the record as the start time.\r
96\r
97 @param Handle Pointer to environment specific context used\r
98 to identify the component being measured.\r
99 @param Token Pointer to a Null-terminated ASCII string\r
100 that identifies the component being measured.\r
101 @param Module Pointer to a Null-terminated ASCII string\r
102 that identifies the module being measured.\r
103 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
104 @param Identifier 32-bit identifier. If the value is 0, the created record\r
105 is same as the one created by StartPerformanceMeasurement.\r
d042c6e8 106\r
107 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
108 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
109\r
110**/\r
111RETURN_STATUS\r
112EFIAPI\r
f0da4d7d 113StartPerformanceMeasurementEx (\r
d042c6e8 114 IN CONST VOID *Handle, OPTIONAL\r
115 IN CONST CHAR8 *Token, OPTIONAL\r
116 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
117 IN UINT64 TimeStamp,\r
118 IN UINT32 Identifier\r
d042c6e8 119 )\r
120{\r
137fb13d
BD
121 EFI_STATUS Status;\r
122 CONST CHAR8* String;\r
d042c6e8 123\r
137fb13d 124 Status = GetPerformanceMeasurementProtocol ();\r
d042c6e8 125 if (EFI_ERROR (Status)) {\r
137fb13d 126 return RETURN_NOT_FOUND;\r
d042c6e8 127 }\r
128\r
137fb13d
BD
129 if (Token != NULL) {\r
130 String = Token;\r
131 } else if (Module != NULL) {\r
132 String = Module;\r
133 } else {\r
134 String = NULL;\r
135 }\r
136\r
137 if (mPerformanceMeasurement != NULL) {\r
138 Status = mPerformanceMeasurement->CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfStartEntry);\r
f0da4d7d
SZ
139 } else {\r
140 ASSERT (FALSE);\r
141 }\r
d042c6e8 142\r
143 return (RETURN_STATUS) Status;\r
144}\r
145\r
146/**\r
147 Fills in the end time of a performance measurement.\r
148\r
7a9395cd 149 Looks up the record that matches Handle, Token and Module.\r
d042c6e8 150 If the record can not be found then return RETURN_NOT_FOUND.\r
151 If the record is found and TimeStamp is not zero,\r
152 then TimeStamp is added to the record as the end time.\r
153 If the record is found and TimeStamp is zero, then this function reads\r
154 the current time stamp and adds that time stamp value to the record as the end time.\r
d042c6e8 155\r
156 @param Handle Pointer to environment specific context used\r
157 to identify the component being measured.\r
158 @param Token Pointer to a Null-terminated ASCII string\r
159 that identifies the component being measured.\r
160 @param Module Pointer to a Null-terminated ASCII string\r
161 that identifies the module being measured.\r
162 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
163 @param Identifier 32-bit identifier. If the value is 0, the found record\r
164 is same as the one found by EndPerformanceMeasurement.\r
d042c6e8 165\r
166 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
167 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
168\r
169**/\r
170RETURN_STATUS\r
171EFIAPI\r
f0da4d7d 172EndPerformanceMeasurementEx (\r
d042c6e8 173 IN CONST VOID *Handle, OPTIONAL\r
174 IN CONST CHAR8 *Token, OPTIONAL\r
175 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
176 IN UINT64 TimeStamp,\r
177 IN UINT32 Identifier\r
d042c6e8 178 )\r
179{\r
137fb13d
BD
180 EFI_STATUS Status;\r
181 CONST CHAR8* String;\r
d042c6e8 182\r
137fb13d 183 Status = GetPerformanceMeasurementProtocol ();\r
d042c6e8 184 if (EFI_ERROR (Status)) {\r
185 return RETURN_NOT_FOUND;\r
186 }\r
187\r
137fb13d
BD
188 if (Token != NULL) {\r
189 String = Token;\r
190 } else if (Module != NULL) {\r
191 String = Module;\r
192 } else {\r
193 String = NULL;\r
194 }\r
195\r
196 if (mPerformanceMeasurement != NULL) {\r
197 Status = mPerformanceMeasurement->CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfEndEntry);\r
f0da4d7d
SZ
198 } else {\r
199 ASSERT (FALSE);\r
200 }\r
d042c6e8 201\r
202 return (RETURN_STATUS) Status;\r
203}\r
204\r
205/**\r
206 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
f0da4d7d
SZ
207 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
208 and then assign the Identifier with 0.\r
d042c6e8 209\r
210 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
211 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
212 and the key for the second entry in the log is returned. If the performance log is empty,\r
213 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
214 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
215 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
216 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
217 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
218 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
f0da4d7d 219 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
d042c6e8 220 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
221 If Handle is NULL, then ASSERT().\r
222 If Token is NULL, then ASSERT().\r
223 If Module is NULL, then ASSERT().\r
224 If StartTimeStamp is NULL, then ASSERT().\r
225 If EndTimeStamp is NULL, then ASSERT().\r
f0da4d7d 226 If Identifier is NULL, then ASSERT().\r
d042c6e8 227\r
228 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
229 0, then the first performance measurement log entry is retrieved.\r
230 On exit, the key of the next performance log entry.\r
231 @param Handle Pointer to environment specific context used to identify the component\r
232 being measured.\r
233 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
234 being measured.\r
235 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
236 being measured.\r
237 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
238 was started.\r
239 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
240 was ended.\r
f0da4d7d 241 @param Identifier Pointer to the 32-bit identifier that was recorded.\r
d042c6e8 242\r
243 @return The key for the next performance log entry (in general case).\r
244\r
245**/\r
246UINTN\r
247EFIAPI\r
f0da4d7d 248GetPerformanceMeasurementEx (\r
d1102dba 249 IN UINTN LogEntryKey,\r
d042c6e8 250 OUT CONST VOID **Handle,\r
251 OUT CONST CHAR8 **Token,\r
252 OUT CONST CHAR8 **Module,\r
253 OUT UINT64 *StartTimeStamp,\r
f0da4d7d
SZ
254 OUT UINT64 *EndTimeStamp,\r
255 OUT UINT32 *Identifier\r
d042c6e8 256 )\r
257{\r
137fb13d 258 return 0;\r
d042c6e8 259}\r
260\r
f0da4d7d
SZ
261/**\r
262 Creates a record for the beginning of a performance measurement.\r
263\r
264 Creates a record that contains the Handle, Token, and Module.\r
265 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
266 If TimeStamp is zero, then this function reads the current time stamp\r
267 and adds that time stamp value to the record as the start time.\r
268\r
269 @param Handle Pointer to environment specific context used\r
270 to identify the component being measured.\r
271 @param Token Pointer to a Null-terminated ASCII string\r
272 that identifies the component being measured.\r
273 @param Module Pointer to a Null-terminated ASCII string\r
274 that identifies the module being measured.\r
275 @param TimeStamp 64-bit time stamp.\r
276\r
277 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
278 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
279\r
280**/\r
281RETURN_STATUS\r
282EFIAPI\r
283StartPerformanceMeasurement (\r
284 IN CONST VOID *Handle, OPTIONAL\r
285 IN CONST CHAR8 *Token, OPTIONAL\r
286 IN CONST CHAR8 *Module, OPTIONAL\r
287 IN UINT64 TimeStamp\r
288 )\r
289{\r
290 return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
291}\r
292\r
293/**\r
294 Fills in the end time of a performance measurement.\r
295\r
296 Looks up the record that matches Handle, Token, and Module.\r
297 If the record can not be found then return RETURN_NOT_FOUND.\r
298 If the record is found and TimeStamp is not zero,\r
299 then TimeStamp is added to the record as the end time.\r
300 If the record is found and TimeStamp is zero, then this function reads\r
301 the current time stamp and adds that time stamp value to the record as the end time.\r
302\r
303 @param Handle Pointer to environment specific context used\r
304 to identify the component being measured.\r
305 @param Token Pointer to a Null-terminated ASCII string\r
306 that identifies the component being measured.\r
307 @param Module Pointer to a Null-terminated ASCII string\r
308 that identifies the module being measured.\r
309 @param TimeStamp 64-bit time stamp.\r
310\r
311 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
312 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
313\r
314**/\r
315RETURN_STATUS\r
316EFIAPI\r
317EndPerformanceMeasurement (\r
318 IN CONST VOID *Handle, OPTIONAL\r
319 IN CONST CHAR8 *Token, OPTIONAL\r
320 IN CONST CHAR8 *Module, OPTIONAL\r
321 IN UINT64 TimeStamp\r
322 )\r
323{\r
324 return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
325}\r
326\r
327/**\r
328 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
329 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
330 and then eliminate the Identifier.\r
331\r
332 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
333 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
334 and the key for the second entry in the log is returned. If the performance log is empty,\r
335 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
336 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
337 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
338 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
339 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
340 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
341 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
342 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
343 If Handle is NULL, then ASSERT().\r
344 If Token is NULL, then ASSERT().\r
345 If Module is NULL, then ASSERT().\r
346 If StartTimeStamp is NULL, then ASSERT().\r
347 If EndTimeStamp is NULL, then ASSERT().\r
348\r
349 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
350 0, then the first performance measurement log entry is retrieved.\r
351 On exit, the key of the next performance log entry.\r
352 @param Handle Pointer to environment specific context used to identify the component\r
353 being measured.\r
354 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
355 being measured.\r
356 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
357 being measured.\r
358 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
359 was started.\r
360 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
361 was ended.\r
362\r
363 @return The key for the next performance log entry (in general case).\r
364\r
365**/\r
366UINTN\r
367EFIAPI\r
368GetPerformanceMeasurement (\r
369 IN UINTN LogEntryKey,\r
370 OUT CONST VOID **Handle,\r
371 OUT CONST CHAR8 **Token,\r
372 OUT CONST CHAR8 **Module,\r
373 OUT UINT64 *StartTimeStamp,\r
374 OUT UINT64 *EndTimeStamp\r
375 )\r
376{\r
137fb13d 377 return 0;\r
f0da4d7d
SZ
378}\r
379\r
d042c6e8 380/**\r
381 Returns TRUE if the performance measurement macros are enabled.\r
382\r
383 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
384 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.\r
385\r
386 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
387 PcdPerformanceLibraryPropertyMask is set.\r
388 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
389 PcdPerformanceLibraryPropertyMask is clear.\r
390\r
391**/\r
392BOOLEAN\r
393EFIAPI\r
394PerformanceMeasurementEnabled (\r
395 VOID\r
396 )\r
397{\r
398 return mPerformanceMeasurementEnabled;\r
399}\r
6b4d58a1
BD
400\r
401/**\r
402 Create performance record with event description and a timestamp.\r
403\r
404 @param CallerIdentifier - Image handle or pointer to caller ID GUID\r
405 @param Guid - Pointer to a GUID\r
406 @param String - Pointer to a string describing the measurement\r
407 @param Address - Pointer to a location in memory relevant to the measurement\r
408 @param Identifier - Performance identifier describing the type of measurement\r
409\r
410 @retval RETURN_SUCCESS - Successfully created performance record\r
411 @retval RETURN_OUT_OF_RESOURCES - Ran out of space to store the records\r
412 @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL\r
413 pointer or invalid PerfId\r
414\r
415**/\r
416RETURN_STATUS\r
417EFIAPI\r
418LogPerformanceMeasurement (\r
419 IN CONST VOID *CallerIdentifier,\r
420 IN CONST VOID *Guid, OPTIONAL\r
421 IN CONST CHAR8 *String, OPTIONAL\r
422 IN UINT64 Address, OPTIONAL\r
423 IN UINT32 Identifier\r
424 )\r
425{\r
426 EFI_STATUS Status;\r
427\r
428 Status = GetPerformanceMeasurementProtocol ();\r
429 if (EFI_ERROR (Status)) {\r
430 return RETURN_OUT_OF_RESOURCES;\r
431 }\r
432\r
433 if (mPerformanceMeasurement != NULL) {\r
434 Status = mPerformanceMeasurement->CreatePerformanceMeasurement (CallerIdentifier, Guid, String, 0, Address, Identifier, PerfEntry);\r
435 } else {\r
436 ASSERT (FALSE);\r
437 }\r
438\r
439 return (RETURN_STATUS) Status;\r
440}\r
441\r
442/**\r
443 Check whether the specified performance measurement can be logged.\r
444\r
445 This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set\r
446 and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.\r
447\r
448 @param Type - Type of the performance measurement entry.\r
449\r
450 @retval TRUE The performance measurement can be logged.\r
451 @retval FALSE The performance measurement can NOT be logged.\r
452\r
453**/\r
454BOOLEAN\r
455EFIAPI\r
456LogPerformanceMeasurementEnabled (\r
457 IN CONST UINTN Type\r
458 )\r
459{\r
460 //\r
461 // When Performance measurement is enabled and the type is not filtered, the performance can be logged.\r
462 //\r
463 if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask) & Type) == 0) {\r
464 return TRUE;\r
465 }\r
466 return FALSE;\r
467}\r