]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c
MdeModulepkg DxeSmmPerformanceLib: Dump all PEI/DXE/SMM performance data.
[mirror_edk2.git] / MdeModulePkg / Library / DxeSmmPerformanceLib / DxeSmmPerformanceLib.c
CommitLineData
d042c6e8 1/** @file\r
dccfb097 2 Performance library instance used in DXE phase to dump both PEI/DXE and SMM performance data.\r
d042c6e8 3\r
dccfb097 4 This library instance allows a DXE driver or UEFI application to dump both PEI/DXE and SMM performance data.\r
f0da4d7d
SZ
5 StartPerformanceMeasurement(), EndPerformanceMeasurement(), StartPerformanceMeasurementEx()\r
6 and EndPerformanceMeasurementEx() are not implemented.\r
d042c6e8 7\r
dccfb097 8 Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
d042c6e8 9This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13\r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18\r
19\r
20#include <PiDxe.h>\r
21\r
22#include <Guid/Performance.h>\r
23\r
24#include <Library/PerformanceLib.h>\r
25#include <Library/DebugLib.h>\r
26#include <Library/UefiBootServicesTableLib.h>\r
27#include <Library/UefiRuntimeServicesTableLib.h>\r
28#include <Library/PcdLib.h>\r
29#include <Library/BaseMemoryLib.h>\r
30#include <Library/BaseLib.h>\r
31#include <Library/MemoryAllocationLib.h>\r
32\r
33#include <Protocol/SmmCommunication.h>\r
34\r
35#define SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof (SMM_PERF_COMMUNICATE))\r
dccfb097 36\r
d042c6e8 37EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;\r
38UINT8 mSmmPerformanceBuffer[SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE];\r
39GAUGE_DATA_ENTRY *mGaugeData = NULL;\r
40UINTN mGaugeNumberOfEntries = 0;\r
f0da4d7d
SZ
41GAUGE_DATA_ENTRY_EX *mGaugeDataEx = NULL;\r
42UINTN mGaugeNumberOfEntriesEx = 0;\r
d042c6e8 43\r
dccfb097
SZ
44//\r
45// The cached Performance Protocol and PerformanceEx Protocol interface.\r
46//\r
47PERFORMANCE_PROTOCOL *mPerformance = NULL;\r
48PERFORMANCE_EX_PROTOCOL *mPerformanceEx = NULL;\r
49\r
d042c6e8 50/**\r
f0da4d7d 51 The function caches the pointer to SMM Communication protocol.\r
d042c6e8 52\r
f0da4d7d 53 The function locates SMM Communication protocol from protocol database.\r
d042c6e8 54\r
f0da4d7d
SZ
55 @retval EFI_SUCCESS SMM Communication protocol is successfully located.\r
56 @retval Other SMM Communication protocol is not located to log performance.\r
d042c6e8 57\r
58**/\r
59EFI_STATUS\r
60GetCommunicationProtocol (\r
61 VOID\r
62 )\r
63{\r
64 EFI_STATUS Status;\r
65 EFI_SMM_COMMUNICATION_PROTOCOL *Communication;\r
66\r
67 if (mSmmCommunication != NULL) {\r
68 return EFI_SUCCESS;\r
69 }\r
70\r
71 Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &Communication);\r
72 if (!EFI_ERROR (Status)) {\r
73 ASSERT (Communication != NULL);\r
74 //\r
75 // Cache SMM Communication protocol.\r
76 //\r
77 mSmmCommunication = Communication;\r
78 }\r
79\r
80 return Status;\r
81}\r
82\r
dccfb097
SZ
83/**\r
84 The function caches the pointers to PerformanceEx protocol and Performance Protocol.\r
85\r
86 The function locates PerformanceEx protocol and Performance Protocol from protocol database.\r
87\r
88 @retval EFI_SUCCESS PerformanceEx protocol or Performance Protocol is successfully located.\r
89 @retval EFI_NOT_FOUND Both PerformanceEx protocol and Performance Protocol are not located to log performance.\r
90\r
91**/\r
92EFI_STATUS\r
93GetPerformanceProtocol (\r
94 VOID\r
95 )\r
96{\r
97 EFI_STATUS Status;\r
98 PERFORMANCE_PROTOCOL *Performance;\r
99 PERFORMANCE_EX_PROTOCOL *PerformanceEx;\r
100\r
101 if (mPerformanceEx != NULL || mPerformance != NULL) {\r
102 return EFI_SUCCESS;\r
103 }\r
104\r
105 Status = gBS->LocateProtocol (&gPerformanceExProtocolGuid, NULL, (VOID **) &PerformanceEx);\r
106 if (!EFI_ERROR (Status)) {\r
107 ASSERT (PerformanceEx != NULL);\r
108 //\r
109 // Cache PerformanceEx Protocol.\r
110 //\r
111 mPerformanceEx = PerformanceEx;\r
112 return EFI_SUCCESS;\r
113 }\r
114\r
115 Status = gBS->LocateProtocol (&gPerformanceProtocolGuid, NULL, (VOID **) &Performance);\r
116 if (!EFI_ERROR (Status)) {\r
117 ASSERT (Performance != NULL);\r
118 //\r
119 // Cache performance protocol.\r
120 //\r
121 mPerformance = Performance;\r
122 return EFI_SUCCESS;\r
123 }\r
124\r
125 return EFI_NOT_FOUND;\r
126}\r
127\r
f0da4d7d
SZ
128/**\r
129 Creates a record for the beginning of a performance measurement.\r
130\r
131 Creates a record that contains the Handle, Token, Module and Identifier.\r
132 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
133 If TimeStamp is zero, then this function reads the current time stamp\r
134 and adds that time stamp value to the record as the start time.\r
135\r
136 @param Handle Pointer to environment specific context used\r
137 to identify the component being measured.\r
138 @param Token Pointer to a Null-terminated ASCII string\r
139 that identifies the component being measured.\r
140 @param Module Pointer to a Null-terminated ASCII string\r
141 that identifies the module being measured.\r
142 @param TimeStamp 64-bit time stamp.\r
143 @param Identifier 32-bit identifier. If the value is 0, the created record\r
144 is same as the one created by StartPerformanceMeasurement.\r
145\r
146 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
147 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
148\r
149**/\r
150RETURN_STATUS\r
151EFIAPI\r
152StartPerformanceMeasurementEx (\r
153 IN CONST VOID *Handle, OPTIONAL\r
154 IN CONST CHAR8 *Token, OPTIONAL\r
155 IN CONST CHAR8 *Module, OPTIONAL\r
156 IN UINT64 TimeStamp,\r
157 IN UINT32 Identifier\r
158 )\r
159{\r
160 return RETURN_SUCCESS;\r
161}\r
162\r
163/**\r
164 Fills in the end time of a performance measurement.\r
165\r
166 Looks up the record that matches Handle, Token, Module and Identifier.\r
167 If the record can not be found then return RETURN_NOT_FOUND.\r
168 If the record is found and TimeStamp is not zero,\r
169 then TimeStamp is added to the record as the end time.\r
170 If the record is found and TimeStamp is zero, then this function reads\r
171 the current time stamp and adds that time stamp value to the record as the end time.\r
172\r
173 @param Handle Pointer to environment specific context used\r
174 to identify the component being measured.\r
175 @param Token Pointer to a Null-terminated ASCII string\r
176 that identifies the component being measured.\r
177 @param Module Pointer to a Null-terminated ASCII string\r
178 that identifies the module being measured.\r
179 @param TimeStamp 64-bit time stamp.\r
180 @param Identifier 32-bit identifier. If the value is 0, the found record\r
181 is same as the one found by EndPerformanceMeasurement.\r
182\r
183 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
184 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
185\r
186**/\r
187RETURN_STATUS\r
188EFIAPI\r
189EndPerformanceMeasurementEx (\r
190 IN CONST VOID *Handle, OPTIONAL\r
191 IN CONST CHAR8 *Token, OPTIONAL\r
192 IN CONST CHAR8 *Module, OPTIONAL\r
193 IN UINT64 TimeStamp,\r
194 IN UINT32 Identifier\r
195 )\r
196{\r
197 return RETURN_SUCCESS;\r
198}\r
199\r
d042c6e8 200/**\r
201 Creates a record for the beginning of a performance measurement.\r
202\r
203 Creates a record that contains the Handle, Token, and Module.\r
204 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
205 If TimeStamp is zero, then this function reads the current time stamp\r
206 and adds that time stamp value to the record as the start time.\r
207\r
208 @param Handle Pointer to environment specific context used\r
209 to identify the component being measured.\r
210 @param Token Pointer to a Null-terminated ASCII string\r
211 that identifies the component being measured.\r
212 @param Module Pointer to a Null-terminated ASCII string\r
213 that identifies the module being measured.\r
214 @param TimeStamp 64-bit time stamp.\r
215\r
216 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
217 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
218\r
219**/\r
220RETURN_STATUS\r
221EFIAPI\r
222StartPerformanceMeasurement (\r
223 IN CONST VOID *Handle, OPTIONAL\r
224 IN CONST CHAR8 *Token, OPTIONAL\r
225 IN CONST CHAR8 *Module, OPTIONAL\r
226 IN UINT64 TimeStamp\r
227 )\r
228{\r
f0da4d7d 229 return RETURN_SUCCESS;\r
d042c6e8 230}\r
231\r
232/**\r
233 Fills in the end time of a performance measurement.\r
234\r
235 Looks up the record that matches Handle, Token, and Module.\r
236 If the record can not be found then return RETURN_NOT_FOUND.\r
237 If the record is found and TimeStamp is not zero,\r
238 then TimeStamp is added to the record as the end time.\r
239 If the record is found and TimeStamp is zero, then this function reads\r
240 the current time stamp and adds that time stamp value to the record as the end time.\r
d042c6e8 241\r
242 @param Handle Pointer to environment specific context used\r
243 to identify the component being measured.\r
244 @param Token Pointer to a Null-terminated ASCII string\r
245 that identifies the component being measured.\r
246 @param Module Pointer to a Null-terminated ASCII string\r
247 that identifies the module being measured.\r
248 @param TimeStamp 64-bit time stamp.\r
249\r
250 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
251 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
252\r
253**/\r
254RETURN_STATUS\r
255EFIAPI\r
256EndPerformanceMeasurement (\r
257 IN CONST VOID *Handle, OPTIONAL\r
258 IN CONST CHAR8 *Token, OPTIONAL\r
259 IN CONST CHAR8 *Module, OPTIONAL\r
260 IN UINT64 TimeStamp\r
261 )\r
262{\r
f0da4d7d 263 return RETURN_SUCCESS;\r
d042c6e8 264}\r
265\r
dccfb097
SZ
266/**\r
267 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
268 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
269 and then assign the Identifier with 0.\r
270\r
271 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
272 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
273 and the key for the second entry in the log is returned. If the performance log is empty,\r
274 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
275 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
276 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
277 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
278 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
279 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
280 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
281 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
282 If Handle is NULL, then ASSERT().\r
283 If Token is NULL, then ASSERT().\r
284 If Module is NULL, then ASSERT().\r
285 If StartTimeStamp is NULL, then ASSERT().\r
286 If EndTimeStamp is NULL, then ASSERT().\r
287 If Identifier is NULL, then ASSERT().\r
288\r
289 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
290 0, then the first performance measurement log entry is retrieved.\r
291 On exit, the key of the next performance log entry.\r
292 @param Handle Pointer to environment specific context used to identify the component\r
293 being measured.\r
294 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
295 being measured.\r
296 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
297 being measured.\r
298 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
299 was started.\r
300 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
301 was ended.\r
302 @param Identifier Pointer to the 32-bit identifier that was recorded.\r
303\r
304 @return The key for the next performance log entry (in general case).\r
305\r
306**/\r
307UINTN\r
308EFIAPI\r
309GetByPerformanceProtocol (\r
310 IN UINTN LogEntryKey, \r
311 OUT CONST VOID **Handle,\r
312 OUT CONST CHAR8 **Token,\r
313 OUT CONST CHAR8 **Module,\r
314 OUT UINT64 *StartTimeStamp,\r
315 OUT UINT64 *EndTimeStamp,\r
316 OUT UINT32 *Identifier\r
317 )\r
318{\r
319 EFI_STATUS Status;\r
320 GAUGE_DATA_ENTRY_EX *GaugeData;\r
321\r
322 Status = GetPerformanceProtocol ();\r
323 if (EFI_ERROR (Status)) {\r
324 return 0;\r
325 }\r
326\r
327 if (mPerformanceEx != NULL) {\r
328 Status = mPerformanceEx->GetGaugeEx (LogEntryKey++, &GaugeData);\r
329 } else if (mPerformance != NULL) {\r
330 Status = mPerformance->GetGauge (LogEntryKey++, (GAUGE_DATA_ENTRY **) &GaugeData);\r
331 } else {\r
332 ASSERT (FALSE);\r
333 return 0;\r
334 }\r
335\r
336 //\r
337 // Make sure that LogEntryKey is a valid log entry key,\r
338 //\r
339 ASSERT (Status != EFI_INVALID_PARAMETER);\r
340\r
341 if (EFI_ERROR (Status)) {\r
342 //\r
343 // The LogEntryKey is the last entry (equals to the total entry number).\r
344 //\r
345 return 0;\r
346 }\r
347\r
348 ASSERT (GaugeData != NULL);\r
349\r
350 *Handle = (VOID *) (UINTN) GaugeData->Handle;\r
351 *Token = GaugeData->Token;\r
352 *Module = GaugeData->Module;\r
353 *StartTimeStamp = GaugeData->StartTimeStamp;\r
354 *EndTimeStamp = GaugeData->EndTimeStamp;\r
355 if (mPerformanceEx != NULL) {\r
356 *Identifier = GaugeData->Identifier;\r
357 } else {\r
358 *Identifier = 0;\r
359 }\r
360\r
361 return LogEntryKey;\r
362}\r
363\r
364\r
d042c6e8 365/**\r
366 Retrieves all previous logged performance measurement.\r
367 Function will use SMM communicate protocol to get all previous SMM performance measurement data.\r
368 If success, data buffer will be returned. If fail function will return NULL.\r
369\r
dccfb097
SZ
370 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
371 0, then the first performance measurement log entry is retrieved.\r
372 On exit, the key of the next performance log entry.\r
373\r
d042c6e8 374 @retval !NULL Get all gauge data success.\r
375 @retval NULL Get all guage data failed.\r
376**/\r
f0da4d7d 377GAUGE_DATA_ENTRY *\r
d042c6e8 378EFIAPI\r
dccfb097
SZ
379GetAllSmmGaugeData (\r
380 IN UINTN LogEntryKey\r
381 )\r
d042c6e8 382{\r
383 EFI_STATUS Status;\r
384 EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader;\r
385 SMM_PERF_COMMUNICATE *SmmPerfCommData;\r
386 UINTN CommSize;\r
387 UINTN DataSize;\r
388\r
dccfb097
SZ
389 if (LogEntryKey != 0) {\r
390 if (mGaugeData != NULL) {\r
391 return mGaugeData;\r
392 }\r
393 } else {\r
394 //\r
395 // Reget the SMM guage data at the first entry get.\r
396 //\r
397 if (mGaugeData != NULL) {\r
398 FreePool (mGaugeData);\r
399 mGaugeData = NULL;\r
400 mGaugeNumberOfEntries = 0;\r
401 }\r
d042c6e8 402 }\r
403\r
404 Status = GetCommunicationProtocol ();\r
405 if (EFI_ERROR (Status)) {\r
406 return NULL;\r
407 }\r
408\r
409 //\r
410 // Initialize communicate buffer \r
411 //\r
f0da4d7d
SZ
412 SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER *)mSmmPerformanceBuffer;\r
413 SmmPerfCommData = (SMM_PERF_COMMUNICATE *)SmmCommBufferHeader->Data;\r
d042c6e8 414 ZeroMem((UINT8*)SmmPerfCommData, sizeof(SMM_PERF_COMMUNICATE));\r
415 \r
416 CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gSmmPerformanceProtocolGuid);\r
417 SmmCommBufferHeader->MessageLength = sizeof(SMM_PERF_COMMUNICATE);\r
f0da4d7d 418 CommSize = SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
d042c6e8 419\r
420 //\r
421 // Get totol number of SMM gauge entries\r
422 //\r
423 SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER;\r
424 Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
f0da4d7d 425 if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus) || SmmPerfCommData->NumberOfEntries == 0) {\r
d042c6e8 426 return NULL;\r
427 }\r
428\r
429 mGaugeNumberOfEntries = SmmPerfCommData->NumberOfEntries;\r
430 \r
431 DataSize = mGaugeNumberOfEntries * sizeof(GAUGE_DATA_ENTRY);\r
432 mGaugeData = AllocateZeroPool(DataSize);\r
f0da4d7d 433 ASSERT (mGaugeData != NULL);\r
d042c6e8 434 \r
435 //\r
436 // Get all SMM gauge data\r
437 // \r
438 SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;\r
439 SmmPerfCommData->LogEntryKey = 0;\r
440 SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries;\r
441 SmmPerfCommData->GaugeData = mGaugeData;\r
442 Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
f0da4d7d
SZ
443 if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
444 FreePool (mGaugeData);\r
445 mGaugeData = NULL;\r
446 mGaugeNumberOfEntries = 0;\r
447 }\r
d042c6e8 448\r
f0da4d7d 449 return mGaugeData;\r
d042c6e8 450}\r
451\r
452/**\r
f0da4d7d
SZ
453 Retrieves all previous logged performance measurement.\r
454 Function will use SMM communicate protocol to get all previous SMM performance measurement data.\r
455 If success, data buffer will be returned. If fail function will return NULL.\r
d042c6e8 456\r
dccfb097
SZ
457 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
458 0, then the first performance measurement log entry is retrieved.\r
459 On exit, the key of the next performance log entry.\r
460\r
f0da4d7d
SZ
461 @retval !NULL Get all gauge data success.\r
462 @retval NULL Get all guage data failed.\r
d042c6e8 463**/\r
f0da4d7d 464GAUGE_DATA_ENTRY_EX *\r
d042c6e8 465EFIAPI\r
dccfb097
SZ
466GetAllSmmGaugeDataEx (\r
467 IN UINTN LogEntryKey\r
468 )\r
d042c6e8 469{\r
f0da4d7d
SZ
470 EFI_STATUS Status;\r
471 EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader;\r
472 SMM_PERF_COMMUNICATE_EX *SmmPerfCommData;\r
473 UINTN CommSize;\r
474 UINTN DataSize;\r
475\r
dccfb097
SZ
476 if (LogEntryKey != 0) {\r
477 if (mGaugeDataEx != NULL) {\r
478 return mGaugeDataEx;\r
479 }\r
480 } else {\r
481 //\r
482 // Reget the SMM guage data at the first entry get.\r
483 //\r
484 if (mGaugeDataEx != NULL) {\r
485 FreePool (mGaugeDataEx);\r
486 mGaugeDataEx = NULL;\r
487 mGaugeNumberOfEntriesEx = 0;\r
488 }\r
d042c6e8 489 }\r
f0da4d7d
SZ
490\r
491 Status = GetCommunicationProtocol ();\r
492 if (EFI_ERROR (Status)) {\r
493 return NULL;\r
d042c6e8 494 }\r
495\r
f0da4d7d
SZ
496 //\r
497 // Initialize communicate buffer \r
498 //\r
499 SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER *)mSmmPerformanceBuffer;\r
500 SmmPerfCommData = (SMM_PERF_COMMUNICATE_EX *)SmmCommBufferHeader->Data;\r
501 ZeroMem((UINT8*)SmmPerfCommData, sizeof(SMM_PERF_COMMUNICATE_EX));\r
502 \r
503 CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gSmmPerformanceExProtocolGuid);\r
504 SmmCommBufferHeader->MessageLength = sizeof(SMM_PERF_COMMUNICATE_EX);\r
505 CommSize = SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
506\r
507 //\r
508 // Get totol number of SMM gauge entries\r
509 //\r
510 SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER;\r
511 Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
512 if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus) || SmmPerfCommData->NumberOfEntries == 0) {\r
513 return NULL;\r
d042c6e8 514 }\r
d042c6e8 515\r
f0da4d7d
SZ
516 mGaugeNumberOfEntriesEx = SmmPerfCommData->NumberOfEntries;\r
517 \r
518 DataSize = mGaugeNumberOfEntriesEx * sizeof(GAUGE_DATA_ENTRY_EX);\r
519 mGaugeDataEx = AllocateZeroPool(DataSize);\r
520 ASSERT (mGaugeDataEx != NULL);\r
521 \r
522 //\r
523 // Get all SMM gauge data\r
524 // \r
525 SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;\r
526 SmmPerfCommData->LogEntryKey = 0;\r
527 SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx;\r
528 SmmPerfCommData->GaugeDataEx = mGaugeDataEx;\r
529 Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
530 if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
531 FreePool (mGaugeDataEx);\r
532 mGaugeDataEx = NULL;\r
533 mGaugeNumberOfEntriesEx = 0;\r
534 }\r
535 \r
536 return mGaugeDataEx;\r
d042c6e8 537}\r
538\r
539/**\r
540 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
f0da4d7d
SZ
541 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
542 and then assign the Identifier with 0.\r
d042c6e8 543\r
544 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
545 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
546 and the key for the second entry in the log is returned. If the performance log is empty,\r
547 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
548 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
549 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
550 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
551 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
552 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
f0da4d7d 553 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
d042c6e8 554 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
555 If Handle is NULL, then ASSERT().\r
556 If Token is NULL, then ASSERT().\r
557 If Module is NULL, then ASSERT().\r
558 If StartTimeStamp is NULL, then ASSERT().\r
559 If EndTimeStamp is NULL, then ASSERT().\r
f0da4d7d 560 If Identifier is NULL, then ASSERT().\r
d042c6e8 561\r
562 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
563 0, then the first performance measurement log entry is retrieved.\r
564 On exit, the key of the next performance log entry.\r
565 @param Handle Pointer to environment specific context used to identify the component\r
566 being measured.\r
567 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
568 being measured.\r
569 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
570 being measured.\r
571 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
572 was started.\r
573 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
574 was ended.\r
f0da4d7d 575 @param Identifier Pointer to the 32-bit identifier that was recorded.\r
d042c6e8 576\r
577 @return The key for the next performance log entry (in general case).\r
578\r
579**/\r
580UINTN\r
581EFIAPI\r
f0da4d7d
SZ
582GetPerformanceMeasurementEx (\r
583 IN UINTN LogEntryKey, \r
d042c6e8 584 OUT CONST VOID **Handle,\r
585 OUT CONST CHAR8 **Token,\r
586 OUT CONST CHAR8 **Module,\r
587 OUT UINT64 *StartTimeStamp,\r
f0da4d7d
SZ
588 OUT UINT64 *EndTimeStamp,\r
589 OUT UINT32 *Identifier\r
d042c6e8 590 )\r
591{\r
f0da4d7d 592 GAUGE_DATA_ENTRY_EX *GaugeData;\r
d042c6e8 593\r
594 GaugeData = NULL;\r
595\r
596 ASSERT (Handle != NULL);\r
597 ASSERT (Token != NULL);\r
598 ASSERT (Module != NULL);\r
599 ASSERT (StartTimeStamp != NULL);\r
600 ASSERT (EndTimeStamp != NULL);\r
f0da4d7d 601 ASSERT (Identifier != NULL);\r
d042c6e8 602\r
dccfb097 603 mGaugeDataEx = GetAllSmmGaugeDataEx (LogEntryKey);\r
f0da4d7d 604 if (mGaugeDataEx != NULL) {\r
dccfb097
SZ
605 if (LogEntryKey >= mGaugeNumberOfEntriesEx) {\r
606 //\r
607 // Try to get the data by Performance Protocol.\r
608 //\r
609 LogEntryKey = LogEntryKey - mGaugeNumberOfEntriesEx;\r
610 LogEntryKey = GetByPerformanceProtocol (\r
611 LogEntryKey,\r
612 Handle,\r
613 Token,\r
614 Module,\r
615 StartTimeStamp,\r
616 EndTimeStamp,\r
617 Identifier\r
618 );\r
619 if (LogEntryKey == 0) {\r
620 //\r
621 // Last entry.\r
622 //\r
623 return LogEntryKey;\r
624 } else {\r
625 return (LogEntryKey + mGaugeNumberOfEntriesEx);\r
626 }\r
f0da4d7d
SZ
627 }\r
628\r
629 GaugeData = &mGaugeDataEx[LogEntryKey++];\r
630 *Identifier = GaugeData->Identifier;\r
631 } else {\r
dccfb097 632 mGaugeData = GetAllSmmGaugeData (LogEntryKey);\r
f0da4d7d 633 if (mGaugeData != NULL) {\r
dccfb097
SZ
634 if (LogEntryKey >= mGaugeNumberOfEntries) {\r
635 //\r
636 // Try to get the data by Performance Protocol.\r
637 //\r
638 LogEntryKey = LogEntryKey - mGaugeNumberOfEntries;\r
639 LogEntryKey = GetByPerformanceProtocol (\r
640 LogEntryKey,\r
641 Handle,\r
642 Token,\r
643 Module,\r
644 StartTimeStamp,\r
645 EndTimeStamp,\r
646 Identifier\r
647 );\r
648 if (LogEntryKey == 0) {\r
649 //\r
650 // Last entry.\r
651 //\r
652 return LogEntryKey;\r
653 } else {\r
654 return (LogEntryKey + mGaugeNumberOfEntries);\r
655 }\r
f0da4d7d
SZ
656 }\r
657\r
658 GaugeData = (GAUGE_DATA_ENTRY_EX *) &mGaugeData[LogEntryKey++];\r
659 *Identifier = 0;\r
660 } else {\r
661 return 0;\r
662 }\r
d042c6e8 663 }\r
664\r
d042c6e8 665 *Handle = (VOID *) (UINTN) GaugeData->Handle;\r
666 *Token = GaugeData->Token;\r
667 *Module = GaugeData->Module;\r
668 *StartTimeStamp = GaugeData->StartTimeStamp;\r
669 *EndTimeStamp = GaugeData->EndTimeStamp;\r
670\r
671 return LogEntryKey;\r
672}\r
673\r
f0da4d7d
SZ
674/**\r
675 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
676 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
677 and then eliminate the Identifier.\r
678\r
679 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
680 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
681 and the key for the second entry in the log is returned. If the performance log is empty,\r
682 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
683 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
684 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
685 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
686 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
687 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
688 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
689 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
690 If Handle is NULL, then ASSERT().\r
691 If Token is NULL, then ASSERT().\r
692 If Module is NULL, then ASSERT().\r
693 If StartTimeStamp is NULL, then ASSERT().\r
694 If EndTimeStamp is NULL, then ASSERT().\r
695\r
696 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
697 0, then the first performance measurement log entry is retrieved.\r
698 On exit, the key of the next performance log entry.\r
699 @param Handle Pointer to environment specific context used to identify the component\r
700 being measured.\r
701 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
702 being measured.\r
703 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
704 being measured.\r
705 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
706 was started.\r
707 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
708 was ended.\r
709\r
710 @return The key for the next performance log entry (in general case).\r
711\r
712**/\r
713UINTN\r
714EFIAPI\r
715GetPerformanceMeasurement (\r
716 IN UINTN LogEntryKey,\r
717 OUT CONST VOID **Handle,\r
718 OUT CONST CHAR8 **Token,\r
719 OUT CONST CHAR8 **Module,\r
720 OUT UINT64 *StartTimeStamp,\r
721 OUT UINT64 *EndTimeStamp\r
722 )\r
723{\r
724 UINT32 Identifier;\r
725 return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
726}\r
727\r
d042c6e8 728/**\r
729 Returns TRUE if the performance measurement macros are enabled.\r
730\r
731 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
732 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.\r
733\r
734 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
735 PcdPerformanceLibraryPropertyMask is set.\r
736 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
737 PcdPerformanceLibraryPropertyMask is clear.\r
738\r
739**/\r
740BOOLEAN\r
741EFIAPI\r
742PerformanceMeasurementEnabled (\r
743 VOID\r
744 )\r
745{\r
746 return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);\r
747}\r