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