]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
Add new extension PerformanceLib APIs to store ID info.
[mirror_edk2.git] / MdeModulePkg / Library / SmmCorePerformanceLib / SmmCorePerformanceLib.c
1 /** @file
2 Performance library instance used by SMM Core.
3
4 This library provides the performance measurement interfaces and initializes performance
5 logging for the SMM phase.
6 It initializes SMM phase performance logging by publishing the Performance Protocol,
7 which is consumed by SmmPerformanceLib to logging performance data in SMM phase.
8
9 This library is mainly used by SMM Core to start performance logging to ensure that
10 SMM Performance Protocol is installed at the very beginning of SMM phase.
11
12 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
13 This program and the accompanying materials
14 are licensed and made available under the terms and conditions of the BSD License
15 which accompanies this distribution. The full text of the license may be found at
16 http://opensource.org/licenses/bsd-license.php
17
18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20
21 **/
22
23
24 #include "SmmCorePerformanceLibInternal.h"
25
26 //
27 // The data structure to hold global performance data.
28 //
29 GAUGE_DATA_HEADER *mGaugeData;
30
31 //
32 // The current maximum number of logging entries. If current number of
33 // entries exceeds this value, it will re-allocate a larger array and
34 // migration the old data to the larger array.
35 //
36 UINT32 mMaxGaugeRecords;
37
38 //
39 // The handle to install Performance Protocol instance.
40 //
41 EFI_HANDLE mHandle = NULL;
42
43 BOOLEAN mPerformanceMeasurementEnabled;
44
45 SPIN_LOCK mSmmPerfLock;
46
47 EFI_SMRAM_DESCRIPTOR *mSmramRanges;
48 UINTN mSmramRangeCount;
49
50 //
51 // Interfaces for performance protocol.
52 //
53 PERFORMANCE_PROTOCOL mPerformanceInterface = {
54 StartGauge,
55 EndGauge,
56 GetGauge
57 };
58
59 /**
60 Searches in the gauge array with keyword Handle, Token and Module.
61
62 This internal function searches for the gauge entry in the gauge array.
63 If there is an entry that exactly matches the given key word triple
64 and its end time stamp is zero, then the index of that gauge entry is returned;
65 otherwise, the the number of gauge entries in the array is returned.
66
67 @param Handle Pointer to environment specific context used
68 to identify the component being measured.
69 @param Token Pointer to a Null-terminated ASCII string
70 that identifies the component being measured.
71 @param Module Pointer to a Null-terminated ASCII string
72 that identifies the module being measured.
73
74 @retval The index of gauge entry in the array.
75
76 **/
77 UINT32
78 SmmSearchForGaugeEntry (
79 IN CONST VOID *Handle, OPTIONAL
80 IN CONST CHAR8 *Token, OPTIONAL
81 IN CONST CHAR8 *Module OPTIONAL
82 )
83 {
84 UINT32 Index;
85 UINT32 NumberOfEntries;
86 GAUGE_DATA_ENTRY *GaugeEntryArray;
87
88 if (Token == NULL) {
89 Token = "";
90 }
91 if (Module == NULL) {
92 Module = "";
93 }
94
95 NumberOfEntries = mGaugeData->NumberOfEntries;
96 GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);
97
98 for (Index = 0; Index < NumberOfEntries; Index++) {
99 if ((GaugeEntryArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&
100 AsciiStrnCmp (GaugeEntryArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&
101 AsciiStrnCmp (GaugeEntryArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&
102 GaugeEntryArray[Index].EndTimeStamp == 0) {
103 break;
104 }
105 }
106
107 return Index;
108 }
109
110 /**
111 Adds a record at the end of the performance measurement log
112 that records the start time of a performance measurement.
113
114 Adds a record to the end of the performance measurement log
115 that contains the Handle, Token, and Module.
116 The end time of the new record must be set to zero.
117 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
118 If TimeStamp is zero, the start time in the record is filled in with the value
119 read from the current time stamp.
120
121 @param Handle Pointer to environment specific context used
122 to identify the component being measured.
123 @param Token Pointer to a Null-terminated ASCII string
124 that identifies the component being measured.
125 @param Module Pointer to a Null-terminated ASCII string
126 that identifies the module being measured.
127 @param TimeStamp 64-bit time stamp.
128
129 @retval EFI_SUCCESS The data was read correctly from the device.
130 @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement.
131
132 **/
133 EFI_STATUS
134 EFIAPI
135 StartGauge (
136 IN CONST VOID *Handle, OPTIONAL
137 IN CONST CHAR8 *Token, OPTIONAL
138 IN CONST CHAR8 *Module, OPTIONAL
139 IN UINT64 TimeStamp
140 )
141 {
142 GAUGE_DATA_ENTRY *GaugeEntryArray;
143 UINTN GaugeDataSize;
144 UINTN OldGaugeDataSize;
145 GAUGE_DATA_HEADER *OldGaugeData;
146 UINT32 Index;
147
148 AcquireSpinLock (&mSmmPerfLock);
149
150 Index = mGaugeData->NumberOfEntries;
151 if (Index >= mMaxGaugeRecords) {
152 //
153 // Try to enlarge the scale of gauge array.
154 //
155 OldGaugeData = mGaugeData;
156 OldGaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;
157
158 mMaxGaugeRecords *= 2;
159 GaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;
160
161 mGaugeData = AllocateZeroPool (GaugeDataSize);
162 if (mGaugeData == NULL) {
163 return EFI_OUT_OF_RESOURCES;
164 }
165 //
166 // Initialize new data array and migrate old data one.
167 //
168 mGaugeData = CopyMem (mGaugeData, OldGaugeData, OldGaugeDataSize);
169
170 FreePool (OldGaugeData);
171 }
172
173 GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);
174 GaugeEntryArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;
175
176 if (Token != NULL) {
177 AsciiStrnCpy (GaugeEntryArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH);
178 }
179 if (Module != NULL) {
180 AsciiStrnCpy (GaugeEntryArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH);
181 }
182
183 if (TimeStamp == 0) {
184 TimeStamp = GetPerformanceCounter ();
185 }
186 GaugeEntryArray[Index].StartTimeStamp = TimeStamp;
187
188 mGaugeData->NumberOfEntries++;
189
190 ReleaseSpinLock (&mSmmPerfLock);
191
192 return EFI_SUCCESS;
193 }
194
195 /**
196 Searches the performance measurement log from the beginning of the log
197 for the first matching record that contains a zero end time and fills in a valid end time.
198
199 Searches the performance measurement log from the beginning of the log
200 for the first record that matches Handle, Token, and Module and has an end time value of zero.
201 If the record can not be found then return EFI_NOT_FOUND.
202 If the record is found and TimeStamp is not zero,
203 then the end time in the record is filled in with the value specified by TimeStamp.
204 If the record is found and TimeStamp is zero, then the end time in the matching record
205 is filled in with the current time stamp value.
206
207 @param Handle Pointer to environment specific context used
208 to identify the component being measured.
209 @param Token Pointer to a Null-terminated ASCII string
210 that identifies the component being measured.
211 @param Module Pointer to a Null-terminated ASCII string
212 that identifies the module being measured.
213 @param TimeStamp 64-bit time stamp.
214
215 @retval EFI_SUCCESS The end of the measurement was recorded.
216 @retval EFI_NOT_FOUND The specified measurement record could not be found.
217
218 **/
219 EFI_STATUS
220 EFIAPI
221 EndGauge (
222 IN CONST VOID *Handle, OPTIONAL
223 IN CONST CHAR8 *Token, OPTIONAL
224 IN CONST CHAR8 *Module, OPTIONAL
225 IN UINT64 TimeStamp
226 )
227 {
228 GAUGE_DATA_ENTRY *GaugeEntryArray;
229 UINT32 Index;
230
231 if (TimeStamp == 0) {
232 TimeStamp = GetPerformanceCounter ();
233 }
234
235 Index = SmmSearchForGaugeEntry (Handle, Token, Module);
236 if (Index >= mGaugeData->NumberOfEntries) {
237 return EFI_NOT_FOUND;
238 }
239 GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);
240 GaugeEntryArray[Index].EndTimeStamp = TimeStamp;
241
242 return EFI_SUCCESS;
243 }
244
245 /**
246 Retrieves a previously logged performance measurement.
247
248 Retrieves the performance log entry from the performance log specified by LogEntryKey.
249 If it stands for a valid entry, then EFI_SUCCESS is returned and
250 GaugeDataEntry stores the pointer to that entry.
251
252 @param LogEntryKey The key for the previous performance measurement log entry.
253 If 0, then the first performance measurement log entry is retrieved.
254 @param GaugeDataEntry The indirect pointer to the gauge data entry specified by LogEntryKey
255 if the retrieval is successful.
256
257 @retval EFI_SUCCESS The GuageDataEntry is successfully found based on LogEntryKey.
258 @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number).
259 @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number).
260 @retval EFI_INVALIDE_PARAMETER GaugeDataEntry is NULL.
261
262 **/
263 EFI_STATUS
264 EFIAPI
265 GetGauge (
266 IN UINTN LogEntryKey,
267 OUT GAUGE_DATA_ENTRY **GaugeDataEntry
268 )
269 {
270 UINTN NumberOfEntries;
271 GAUGE_DATA_ENTRY *LogEntryArray;
272
273 NumberOfEntries = (UINTN) (mGaugeData->NumberOfEntries);
274 if (LogEntryKey > NumberOfEntries) {
275 return EFI_INVALID_PARAMETER;
276 }
277 if (LogEntryKey == NumberOfEntries) {
278 return EFI_NOT_FOUND;
279 }
280
281 LogEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);
282
283 if (GaugeDataEntry == NULL) {
284 return EFI_INVALID_PARAMETER;
285 }
286 *GaugeDataEntry = &LogEntryArray[LogEntryKey];
287
288 return EFI_SUCCESS;
289 }
290
291
292 /**
293 This function check if the address is in SMRAM.
294
295 @param Buffer the buffer address to be checked.
296 @param Length the buffer length to be checked.
297
298 @retval TRUE this address is in SMRAM.
299 @retval FALSE this address is NOT in SMRAM.
300 **/
301 BOOLEAN
302 IsAddressInSmram (
303 IN EFI_PHYSICAL_ADDRESS Buffer,
304 IN UINT64 Length
305 )
306 {
307 UINTN Index;
308
309 for (Index = 0; Index < mSmramRangeCount; Index ++) {
310 if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||
311 ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {
312 return TRUE;
313 }
314 }
315
316 return FALSE;
317 }
318
319 /**
320 Communication service SMI Handler entry.
321
322 This SMI handler provides services for the variable wrapper driver.
323
324 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
325 @param[in] RegisterContext Points to an optional handler context which was specified when the
326 handler was registered.
327 @param[in, out] CommBuffer A pointer to a collection of data in memory that will
328 be conveyed from a non-SMM environment into an SMM environment.
329 @param[in, out] CommBufferSize The size of the CommBuffer.
330
331 @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
332 should still be called.
333 @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
334 still be called.
335 @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
336 be called.
337 @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
338 **/
339 EFI_STATUS
340 EFIAPI
341 SmmPerformanceHandler (
342 IN EFI_HANDLE DispatchHandle,
343 IN CONST VOID *RegisterContext,
344 IN OUT VOID *CommBuffer,
345 IN OUT UINTN *CommBufferSize
346 )
347 {
348 EFI_STATUS Status;
349 SMM_PERF_COMMUNICATE *SmmPerfCommData;
350 GAUGE_DATA_ENTRY *GaugeData;
351 UINTN DataSize;
352
353 GaugeData = NULL;
354
355 ASSERT (CommBuffer != NULL);
356
357 SmmPerfCommData = (SMM_PERF_COMMUNICATE*)CommBuffer;
358
359 switch (SmmPerfCommData->Function) {
360 case SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER :
361 SmmPerfCommData->NumberOfEntries = mGaugeData->NumberOfEntries;
362 return Status = EFI_SUCCESS;
363 break;
364
365 case SMM_PERF_FUNCTION_GET_GAUGE_DATA :
366 if ( SmmPerfCommData->GaugeData == NULL || SmmPerfCommData->NumberOfEntries <= 0 ||
367 (SmmPerfCommData->LogEntryKey + SmmPerfCommData->NumberOfEntries) > mGaugeData->NumberOfEntries) {
368 Status = EFI_INVALID_PARAMETER;
369 break;
370 }
371
372 Status = GetGauge(SmmPerfCommData->LogEntryKey, &GaugeData);
373 if (EFI_ERROR(Status)) {
374 break;
375 }
376
377 //
378 // Sanity check
379 //
380 DataSize = SmmPerfCommData->NumberOfEntries * sizeof(GAUGE_DATA_ENTRY);
381 if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)SmmPerfCommData->GaugeData, DataSize)) {
382 DEBUG ((EFI_D_ERROR, "Smm Performance Data buffer is in SMRAM!\n"));
383 Status = EFI_ACCESS_DENIED;
384 break ;
385 }
386
387 CopyMem(
388 (UINT8*)SmmPerfCommData->GaugeData,
389 (UINT8*)GaugeData,
390 DataSize
391 );
392 break;
393
394 default:
395 ASSERT (FALSE);
396 Status = EFI_UNSUPPORTED;
397 }
398
399 SmmPerfCommData->ReturnStatus = Status;
400 return EFI_SUCCESS;
401 }
402
403 /**
404 SmmBase2 protocol notify callback function, when SMST and SMM memory service get initialized
405 this function is callbacked to to initialize the Smm Performance Lib
406
407 @param Event The event of notify protocol.
408 @param Context Notify event context.
409
410 **/
411 VOID
412 EFIAPI
413 InitializeSmmCorePerformanceLib (
414 IN EFI_EVENT Event,
415 IN VOID *Context
416 )
417 {
418 EFI_STATUS Status;
419 EFI_HANDLE Handle;
420 EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
421 UINTN Size;
422
423
424 //
425 // Initialize spin lock
426 //
427 InitializeSpinLock (&mSmmPerfLock);
428
429 mMaxGaugeRecords = INIT_SMM_GAUGE_DATA_ENTRIES + PcdGet8 (PcdMaxPeiPerformanceLogEntries);
430
431 mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords));
432 ASSERT (mGaugeData != NULL);
433
434 //
435 // Get SMRAM information
436 //
437 Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
438 ASSERT_EFI_ERROR (Status);
439
440 Size = 0;
441 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
442 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
443
444 Status = gSmst->SmmAllocatePool (
445 EfiRuntimeServicesData,
446 Size,
447 (VOID **)&mSmramRanges
448 );
449 ASSERT_EFI_ERROR (Status);
450
451 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);
452 ASSERT_EFI_ERROR (Status);
453
454 mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
455
456 //
457 // Install the protocol interfaces.
458 //
459 Status = gSmst->SmmInstallProtocolInterface (
460 &mHandle,
461 &gSmmPerformanceProtocolGuid,
462 EFI_NATIVE_INTERFACE,
463 &mPerformanceInterface
464 );
465 ASSERT_EFI_ERROR (Status);
466
467 ///
468 /// Register SMM Performance SMI handler
469 ///
470 Handle = NULL;
471 Status = gSmst->SmiHandlerRegister (SmmPerformanceHandler, &gSmmPerformanceProtocolGuid, &Handle);
472 ASSERT_EFI_ERROR (Status);
473 }
474
475 /**
476 The constructor function initializes Performance infrastructure for DXE phase.
477
478 The constructor function publishes Performance protocol, allocates memory to log DXE performance
479 and merges PEI performance data to DXE performance log.
480 It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.
481
482 @param ImageHandle The firmware allocated handle for the EFI image.
483 @param SystemTable A pointer to the EFI System Table.
484
485 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
486
487 **/
488 EFI_STATUS
489 EFIAPI
490 SmmCorePerformanceLibConstructor (
491 IN EFI_HANDLE ImageHandle,
492 IN EFI_SYSTEM_TABLE *SystemTable
493 )
494 {
495 EFI_STATUS Status;
496 EFI_EVENT Event;
497 VOID *Registration;
498
499 mPerformanceMeasurementEnabled = (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
500 if (!mPerformanceMeasurementEnabled) {
501 //
502 // Do not initialize performance infrastructure if not required.
503 //
504 return EFI_SUCCESS;
505 }
506
507 //
508 // Create the events to do the library init.
509 //
510 Status = gBS->CreateEvent (
511 EVT_NOTIFY_SIGNAL,
512 TPL_CALLBACK,
513 InitializeSmmCorePerformanceLib,
514 NULL,
515 &Event
516 );
517 ASSERT_EFI_ERROR (Status);
518
519 //
520 // Register for protocol notifications on this event
521 //
522 Status = gBS->RegisterProtocolNotify (
523 &gEfiSmmBase2ProtocolGuid,
524 Event,
525 &Registration
526 );
527
528 ASSERT_EFI_ERROR (Status);
529
530 return EFI_SUCCESS;
531 }
532
533 /**
534 Adds a record at the end of the performance measurement log
535 that records the start time of a performance measurement.
536
537 Adds a record to the end of the performance measurement log
538 that contains the Handle, Token, and Module.
539 The end time of the new record must be set to zero.
540 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
541 If TimeStamp is zero, the start time in the record is filled in with the value
542 read from the current time stamp.
543
544 @param Handle Pointer to environment specific context used
545 to identify the component being measured.
546 @param Token Pointer to a Null-terminated ASCII string
547 that identifies the component being measured.
548 @param Module Pointer to a Null-terminated ASCII string
549 that identifies the module being measured.
550 @param TimeStamp 64-bit time stamp.
551
552 @retval RETURN_SUCCESS The start of the measurement was recorded.
553 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
554
555 **/
556 RETURN_STATUS
557 EFIAPI
558 StartPerformanceMeasurement (
559 IN CONST VOID *Handle, OPTIONAL
560 IN CONST CHAR8 *Token, OPTIONAL
561 IN CONST CHAR8 *Module, OPTIONAL
562 IN UINT64 TimeStamp
563 )
564 {
565 EFI_STATUS Status;
566
567 Status = StartGauge (Handle, Token, Module, TimeStamp);
568 return (RETURN_STATUS) Status;
569 }
570
571 /**
572 Searches the performance measurement log from the beginning of the log
573 for the first matching record that contains a zero end time and fills in a valid end time.
574
575 Searches the performance measurement log from the beginning of the log
576 for the first record that matches Handle, Token, and Module and has an end time value of zero.
577 If the record can not be found then return RETURN_NOT_FOUND.
578 If the record is found and TimeStamp is not zero,
579 then the end time in the record is filled in with the value specified by TimeStamp.
580 If the record is found and TimeStamp is zero, then the end time in the matching record
581 is filled in with the current time stamp value.
582
583 @param Handle Pointer to environment specific context used
584 to identify the component being measured.
585 @param Token Pointer to a Null-terminated ASCII string
586 that identifies the component being measured.
587 @param Module Pointer to a Null-terminated ASCII string
588 that identifies the module being measured.
589 @param TimeStamp 64-bit time stamp.
590
591 @retval RETURN_SUCCESS The end of the measurement was recorded.
592 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
593
594 **/
595 RETURN_STATUS
596 EFIAPI
597 EndPerformanceMeasurement (
598 IN CONST VOID *Handle, OPTIONAL
599 IN CONST CHAR8 *Token, OPTIONAL
600 IN CONST CHAR8 *Module, OPTIONAL
601 IN UINT64 TimeStamp
602 )
603 {
604 EFI_STATUS Status;
605
606 Status = EndGauge (Handle, Token, Module, TimeStamp);
607 return (RETURN_STATUS) Status;
608 }
609
610 /**
611 Attempts to retrieve a performance measurement log entry from the performance measurement log.
612
613 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
614 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
615 and the key for the second entry in the log is returned. If the performance log is empty,
616 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
617 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
618 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
619 retrieved and an implementation specific non-zero key value that specifies the end of the performance
620 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
621 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
622 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
623 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
624 If Handle is NULL, then ASSERT().
625 If Token is NULL, then ASSERT().
626 If Module is NULL, then ASSERT().
627 If StartTimeStamp is NULL, then ASSERT().
628 If EndTimeStamp is NULL, then ASSERT().
629
630 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
631 0, then the first performance measurement log entry is retrieved.
632 On exit, the key of the next performance log entry.
633 @param Handle Pointer to environment specific context used to identify the component
634 being measured.
635 @param Token Pointer to a Null-terminated ASCII string that identifies the component
636 being measured.
637 @param Module Pointer to a Null-terminated ASCII string that identifies the module
638 being measured.
639 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
640 was started.
641 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
642 was ended.
643
644 @return The key for the next performance log entry (in general case).
645
646 **/
647 UINTN
648 EFIAPI
649 GetPerformanceMeasurement (
650 IN UINTN LogEntryKey,
651 OUT CONST VOID **Handle,
652 OUT CONST CHAR8 **Token,
653 OUT CONST CHAR8 **Module,
654 OUT UINT64 *StartTimeStamp,
655 OUT UINT64 *EndTimeStamp
656 )
657 {
658 EFI_STATUS Status;
659 GAUGE_DATA_ENTRY *GaugeData;
660
661 GaugeData = NULL;
662
663 ASSERT (Handle != NULL);
664 ASSERT (Token != NULL);
665 ASSERT (Module != NULL);
666 ASSERT (StartTimeStamp != NULL);
667 ASSERT (EndTimeStamp != NULL);
668
669 Status = GetGauge (LogEntryKey++, &GaugeData);
670
671 //
672 // Make sure that LogEntryKey is a valid log entry key,
673 //
674 ASSERT (Status != EFI_INVALID_PARAMETER);
675
676 if (EFI_ERROR (Status)) {
677 //
678 // The LogEntryKey is the last entry (equals to the total entry number).
679 //
680 return 0;
681 }
682
683 ASSERT (GaugeData != NULL);
684
685 *Handle = (VOID *) (UINTN) GaugeData->Handle;
686 *Token = GaugeData->Token;
687 *Module = GaugeData->Module;
688 *StartTimeStamp = GaugeData->StartTimeStamp;
689 *EndTimeStamp = GaugeData->EndTimeStamp;
690
691 return LogEntryKey;
692 }
693
694 /**
695 Returns TRUE if the performance measurement macros are enabled.
696
697 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
698 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
699
700 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
701 PcdPerformanceLibraryPropertyMask is set.
702 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
703 PcdPerformanceLibraryPropertyMask is clear.
704
705 **/
706 BOOLEAN
707 EFIAPI
708 PerformanceMeasurementEnabled (
709 VOID
710 )
711 {
712 return mPerformanceMeasurementEnabled;
713 }
714
715