]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
MdeModulePkg: Update PerformanceLib instances not to check Identifier.
[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
7a9395cd 9 Copyright (c) 2011 - 2016, 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
21#include <Guid/Performance.h>\r
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
d042c6e8 31//\r
f0da4d7d
SZ
32PERFORMANCE_PROTOCOL *mPerformance = NULL;\r
33PERFORMANCE_EX_PROTOCOL *mPerformanceEx = NULL;\r
34BOOLEAN mPerformanceMeasurementEnabled;\r
d042c6e8 35\r
36/**\r
f0da4d7d 37 The constructor function initializes the Performance Measurement Enable flag\r
d042c6e8 38\r
39 @param ImageHandle The firmware allocated handle for the EFI image.\r
40 @param SystemTable A pointer to the EFI System Table.\r
41\r
42 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
43\r
44**/\r
45EFI_STATUS\r
46EFIAPI\r
47SmmPerformanceLibConstructor (\r
48 IN EFI_HANDLE ImageHandle,\r
49 IN EFI_SYSTEM_TABLE *SystemTable\r
50 )\r
51{\r
52 \r
53 mPerformanceMeasurementEnabled = (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);\r
54\r
55 return EFI_SUCCESS;\r
56}\r
57\r
58/**\r
f0da4d7d 59 The function caches the pointers to SMM PerformanceEx protocol and Performance Protocol.\r
d042c6e8 60\r
f0da4d7d 61 The function locates SMM PerformanceEx protocol and Performance Protocol from protocol database.\r
d042c6e8 62\r
f0da4d7d
SZ
63 @retval EFI_SUCCESS SMM PerformanceEx protocol or Performance Protocol is successfully located.\r
64 @retval EFI_NOT_FOUND Both SMM PerformanceEx protocol and Performance Protocol are not located to log performance.\r
d042c6e8 65\r
66**/\r
67EFI_STATUS\r
68GetPerformanceProtocol (\r
69 VOID\r
70 )\r
71{\r
f0da4d7d
SZ
72 EFI_STATUS Status;\r
73 PERFORMANCE_PROTOCOL *Performance;\r
74 PERFORMANCE_EX_PROTOCOL *PerformanceEx;\r
d042c6e8 75\r
f0da4d7d
SZ
76 if (mPerformanceEx != NULL || mPerformance != NULL) {\r
77 return EFI_SUCCESS;\r
78 }\r
79\r
80 Status = gSmst->SmmLocateProtocol (&gSmmPerformanceExProtocolGuid, NULL, (VOID **) &PerformanceEx);\r
81 if (!EFI_ERROR (Status)) {\r
82 ASSERT (PerformanceEx != NULL);\r
83 //\r
84 // Cache PerformanceEx Protocol.\r
85 //\r
86 mPerformanceEx = PerformanceEx;\r
d042c6e8 87 return EFI_SUCCESS;\r
88 }\r
89\r
90 Status = gSmst->SmmLocateProtocol (&gSmmPerformanceProtocolGuid, NULL, (VOID **) &Performance);\r
91 if (!EFI_ERROR (Status)) {\r
92 ASSERT (Performance != NULL);\r
93 //\r
94 // Cache performance protocol.\r
95 //\r
96 mPerformance = Performance;\r
f0da4d7d 97 return EFI_SUCCESS;\r
d042c6e8 98 }\r
99\r
f0da4d7d 100 return EFI_NOT_FOUND;\r
d042c6e8 101}\r
102\r
103/**\r
104 Creates a record for the beginning of a performance measurement.\r
105\r
f0da4d7d 106 Creates a record that contains the Handle, Token, Module and Identifier.\r
d042c6e8 107 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
108 If TimeStamp is zero, then this function reads the current time stamp\r
109 and adds that time stamp value to the record as the start time.\r
110\r
111 @param Handle Pointer to environment specific context used\r
112 to identify the component being measured.\r
113 @param Token Pointer to a Null-terminated ASCII string\r
114 that identifies the component being measured.\r
115 @param Module Pointer to a Null-terminated ASCII string\r
116 that identifies the module being measured.\r
117 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
118 @param Identifier 32-bit identifier. If the value is 0, the created record\r
119 is same as the one created by StartPerformanceMeasurement.\r
d042c6e8 120\r
121 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
122 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
123\r
124**/\r
125RETURN_STATUS\r
126EFIAPI\r
f0da4d7d 127StartPerformanceMeasurementEx (\r
d042c6e8 128 IN CONST VOID *Handle, OPTIONAL\r
129 IN CONST CHAR8 *Token, OPTIONAL\r
130 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
131 IN UINT64 TimeStamp,\r
132 IN UINT32 Identifier\r
d042c6e8 133 )\r
134{\r
135 EFI_STATUS Status;\r
136\r
137 Status = GetPerformanceProtocol ();\r
138 if (EFI_ERROR (Status)) {\r
139 return RETURN_OUT_OF_RESOURCES;\r
140 }\r
141\r
f0da4d7d
SZ
142 if (mPerformanceEx != NULL) {\r
143 Status = mPerformanceEx->StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
144 } else if (mPerformance != NULL) {\r
145 Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);\r
146 } else {\r
147 ASSERT (FALSE);\r
148 }\r
d042c6e8 149\r
150 return (RETURN_STATUS) Status;\r
151}\r
152\r
153/**\r
154 Fills in the end time of a performance measurement.\r
155\r
7a9395cd 156 Looks up the record that matches Handle, Token and Module.\r
d042c6e8 157 If the record can not be found then return RETURN_NOT_FOUND.\r
158 If the record is found and TimeStamp is not zero,\r
159 then TimeStamp is added to the record as the end time.\r
160 If the record is found and TimeStamp is zero, then this function reads\r
161 the current time stamp and adds that time stamp value to the record as the end time.\r
d042c6e8 162\r
163 @param Handle Pointer to environment specific context used\r
164 to identify the component being measured.\r
165 @param Token Pointer to a Null-terminated ASCII string\r
166 that identifies the component being measured.\r
167 @param Module Pointer to a Null-terminated ASCII string\r
168 that identifies the module being measured.\r
169 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
170 @param Identifier 32-bit identifier. If the value is 0, the found record\r
171 is same as the one found by EndPerformanceMeasurement.\r
d042c6e8 172\r
173 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
174 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
175\r
176**/\r
177RETURN_STATUS\r
178EFIAPI\r
f0da4d7d 179EndPerformanceMeasurementEx (\r
d042c6e8 180 IN CONST VOID *Handle, OPTIONAL\r
181 IN CONST CHAR8 *Token, OPTIONAL\r
182 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
183 IN UINT64 TimeStamp,\r
184 IN UINT32 Identifier\r
d042c6e8 185 )\r
186{\r
187 EFI_STATUS Status;\r
188\r
189 Status = GetPerformanceProtocol ();\r
190 if (EFI_ERROR (Status)) {\r
191 return RETURN_NOT_FOUND;\r
192 }\r
193\r
f0da4d7d
SZ
194 if (mPerformanceEx != NULL) {\r
195 Status = mPerformanceEx->EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
196 } else if (mPerformance != NULL) {\r
197 Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);\r
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
SZ
248GetPerformanceMeasurementEx (\r
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
f0da4d7d
SZ
258 EFI_STATUS Status;\r
259 GAUGE_DATA_ENTRY_EX *GaugeData;\r
260\r
d042c6e8 261 GaugeData = NULL;\r
262\r
263 ASSERT (Handle != NULL);\r
264 ASSERT (Token != NULL);\r
265 ASSERT (Module != NULL);\r
266 ASSERT (StartTimeStamp != NULL);\r
267 ASSERT (EndTimeStamp != NULL);\r
f0da4d7d 268 ASSERT (Identifier != NULL);\r
d042c6e8 269\r
270 Status = GetPerformanceProtocol ();\r
271 if (EFI_ERROR (Status)) {\r
272 return 0;\r
273 }\r
274\r
f0da4d7d
SZ
275 if (mPerformanceEx != NULL) {\r
276 Status = mPerformanceEx->GetGaugeEx (LogEntryKey++, &GaugeData);\r
277 } else if (mPerformance != NULL) {\r
278 Status = mPerformance->GetGauge (LogEntryKey++, (GAUGE_DATA_ENTRY **) &GaugeData);\r
279 } else {\r
280 ASSERT (FALSE);\r
281 return 0;\r
282 }\r
d042c6e8 283\r
284 //\r
285 // Make sure that LogEntryKey is a valid log entry key,\r
286 //\r
287 ASSERT (Status != EFI_INVALID_PARAMETER);\r
288\r
289 if (EFI_ERROR (Status)) {\r
290 //\r
291 // The LogEntryKey is the last entry (equals to the total entry number).\r
292 //\r
293 return 0;\r
294 }\r
295\r
296 ASSERT (GaugeData != NULL);\r
297\r
298 *Handle = (VOID *) (UINTN) GaugeData->Handle;\r
299 *Token = GaugeData->Token;\r
300 *Module = GaugeData->Module;\r
301 *StartTimeStamp = GaugeData->StartTimeStamp;\r
302 *EndTimeStamp = GaugeData->EndTimeStamp;\r
f0da4d7d
SZ
303 if (mPerformanceEx != NULL) {\r
304 *Identifier = GaugeData->Identifier;\r
305 } else {\r
306 *Identifier = 0;\r
307 }\r
d042c6e8 308\r
ae373a56 309 return LogEntryKey;\r
d042c6e8 310}\r
311\r
f0da4d7d
SZ
312/**\r
313 Creates a record for the beginning of a performance measurement.\r
314\r
315 Creates a record that contains the Handle, Token, and Module.\r
316 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
317 If TimeStamp is zero, then this function reads the current time stamp\r
318 and adds that time stamp value to the record as the start time.\r
319\r
320 @param Handle Pointer to environment specific context used\r
321 to identify the component being measured.\r
322 @param Token Pointer to a Null-terminated ASCII string\r
323 that identifies the component being measured.\r
324 @param Module Pointer to a Null-terminated ASCII string\r
325 that identifies the module being measured.\r
326 @param TimeStamp 64-bit time stamp.\r
327\r
328 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
329 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
330\r
331**/\r
332RETURN_STATUS\r
333EFIAPI\r
334StartPerformanceMeasurement (\r
335 IN CONST VOID *Handle, OPTIONAL\r
336 IN CONST CHAR8 *Token, OPTIONAL\r
337 IN CONST CHAR8 *Module, OPTIONAL\r
338 IN UINT64 TimeStamp\r
339 )\r
340{\r
341 return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
342}\r
343\r
344/**\r
345 Fills in the end time of a performance measurement.\r
346\r
347 Looks up the record that matches Handle, Token, and Module.\r
348 If the record can not be found then return RETURN_NOT_FOUND.\r
349 If the record is found and TimeStamp is not zero,\r
350 then TimeStamp is added to the record as the end time.\r
351 If the record is found and TimeStamp is zero, then this function reads\r
352 the current time stamp and adds that time stamp value to the record as the end time.\r
353\r
354 @param Handle Pointer to environment specific context used\r
355 to identify the component being measured.\r
356 @param Token Pointer to a Null-terminated ASCII string\r
357 that identifies the component being measured.\r
358 @param Module Pointer to a Null-terminated ASCII string\r
359 that identifies the module being measured.\r
360 @param TimeStamp 64-bit time stamp.\r
361\r
362 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
363 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
364\r
365**/\r
366RETURN_STATUS\r
367EFIAPI\r
368EndPerformanceMeasurement (\r
369 IN CONST VOID *Handle, OPTIONAL\r
370 IN CONST CHAR8 *Token, OPTIONAL\r
371 IN CONST CHAR8 *Module, OPTIONAL\r
372 IN UINT64 TimeStamp\r
373 )\r
374{\r
375 return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
376}\r
377\r
378/**\r
379 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
380 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
381 and then eliminate the Identifier.\r
382\r
383 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
384 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
385 and the key for the second entry in the log is returned. If the performance log is empty,\r
386 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
387 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
388 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
389 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
390 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
391 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
392 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
393 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
394 If Handle is NULL, then ASSERT().\r
395 If Token is NULL, then ASSERT().\r
396 If Module is NULL, then ASSERT().\r
397 If StartTimeStamp is NULL, then ASSERT().\r
398 If EndTimeStamp is NULL, then ASSERT().\r
399\r
400 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
401 0, then the first performance measurement log entry is retrieved.\r
402 On exit, the key of the next performance log entry.\r
403 @param Handle Pointer to environment specific context used to identify the component\r
404 being measured.\r
405 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
406 being measured.\r
407 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
408 being measured.\r
409 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
410 was started.\r
411 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
412 was ended.\r
413\r
414 @return The key for the next performance log entry (in general case).\r
415\r
416**/\r
417UINTN\r
418EFIAPI\r
419GetPerformanceMeasurement (\r
420 IN UINTN LogEntryKey,\r
421 OUT CONST VOID **Handle,\r
422 OUT CONST CHAR8 **Token,\r
423 OUT CONST CHAR8 **Module,\r
424 OUT UINT64 *StartTimeStamp,\r
425 OUT UINT64 *EndTimeStamp\r
426 )\r
427{\r
428 UINT32 Identifier;\r
429 return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
430}\r
431\r
d042c6e8 432/**\r
433 Returns TRUE if the performance measurement macros are enabled.\r
434\r
435 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
436 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.\r
437\r
438 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
439 PcdPerformanceLibraryPropertyMask is set.\r
440 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
441 PcdPerformanceLibraryPropertyMask is clear.\r
442\r
443**/\r
444BOOLEAN\r
445EFIAPI\r
446PerformanceMeasurementEnabled (\r
447 VOID\r
448 )\r
449{\r
450 return mPerformanceMeasurementEnabled;\r
451}\r