TianoCore EDK2 master
Loading...
Searching...
No Matches
SmmCorePerformanceLib.c
Go to the documentation of this file.
1
25
26#define STRING_SIZE (FPDT_STRING_EVENT_RECORD_NAME_LENGTH * sizeof (CHAR8))
27#define FIRMWARE_RECORD_BUFFER 0x1000
28#define CACHE_HANDLE_GUID_COUNT 0x100
29
30SMM_BOOT_PERFORMANCE_TABLE *mSmmBootPerformanceTable = NULL;
31
32typedef struct {
33 EFI_HANDLE Handle;
34 CHAR8 NameString[FPDT_STRING_EVENT_RECORD_NAME_LENGTH];
35 EFI_GUID ModuleGuid;
37
38HANDLE_GUID_MAP mCacheHandleGuidTable[CACHE_HANDLE_GUID_COUNT];
39UINTN mCachePairCount = 0;
40
41UINT32 mPerformanceLength = sizeof (SMM_BOOT_PERFORMANCE_TABLE);
42UINT32 mMaxPerformanceLength = 0;
43UINT32 mLoadImageCount = 0;
44BOOLEAN mFpdtDataIsReported = FALSE;
45BOOLEAN mLackSpaceIsReport = FALSE;
46CHAR8 *mPlatformLanguage = NULL;
47SPIN_LOCK mSmmFpdtLock;
48PERFORMANCE_PROPERTY mPerformanceProperty;
49UINT32 mCachedLength = 0;
50UINT32 mBootRecordSize = 0;
51BOOLEAN mPerformanceMeasurementEnabled;
52
53//
54// Interfaces for SMM PerformanceMeasurement Protocol.
55//
56EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL mPerformanceMeasurementInterface = {
58};
59
71 IN UINT8 RecordSize,
72 IN OUT FPDT_RECORD_PTR *FpdtRecordPtr
73 )
74{
75 if (mFpdtDataIsReported) {
76 //
77 // Append Boot records after Smm boot performance records have been reported.
78 //
79 if (mPerformanceLength + RecordSize > mMaxPerformanceLength) {
80 if (!mLackSpaceIsReport) {
81 DEBUG ((DEBUG_INFO, "SmmCorePerformanceLib: No enough space to save boot records\n"));
82 mLackSpaceIsReport = TRUE;
83 }
84
85 return EFI_OUT_OF_RESOURCES;
86 } else {
87 //
88 // Covert buffer to FPDT Ptr Union type.
89 //
90 FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8 *)mSmmBootPerformanceTable + mSmmBootPerformanceTable->Header.Length);
91 }
92 } else {
93 //
94 // Check if pre-allocated buffer is full
95 //
96 if (mPerformanceLength + RecordSize > mMaxPerformanceLength) {
97 mSmmBootPerformanceTable = ReallocatePool (
98 mPerformanceLength,
99 mPerformanceLength + RecordSize + FIRMWARE_RECORD_BUFFER,
100 mSmmBootPerformanceTable
101 );
102
103 if (mSmmBootPerformanceTable == NULL) {
104 return EFI_OUT_OF_RESOURCES;
105 }
106
107 mSmmBootPerformanceTable->Header.Length = mPerformanceLength;
108 mMaxPerformanceLength = mPerformanceLength + RecordSize + FIRMWARE_RECORD_BUFFER;
109 }
110
111 //
112 // Covert buffer to FPDT Ptr Union type.
113 //
114 FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8 *)mSmmBootPerformanceTable + mSmmBootPerformanceTable->Header.Length);
115 }
116
117 FpdtRecordPtr->RecordHeader->Length = 0;
118 return EFI_SUCCESS;
119}
120
130BOOLEAN
132 IN CONST CHAR8 *Token
133 )
134{
135 if (Token == NULL) {
136 return FALSE;
137 }
138
139 if ((AsciiStrCmp (Token, SEC_TOK) == 0) ||
140 (AsciiStrCmp (Token, PEI_TOK) == 0) ||
141 (AsciiStrCmp (Token, DXE_TOK) == 0) ||
142 (AsciiStrCmp (Token, BDS_TOK) == 0) ||
143 (AsciiStrCmp (Token, DRIVERBINDING_START_TOK) == 0) ||
144 (AsciiStrCmp (Token, DRIVERBINDING_SUPPORT_TOK) == 0) ||
145 (AsciiStrCmp (Token, DRIVERBINDING_STOP_TOK) == 0) ||
146 (AsciiStrCmp (Token, LOAD_IMAGE_TOK) == 0) ||
147 (AsciiStrCmp (Token, START_IMAGE_TOK) == 0) ||
148 (AsciiStrCmp (Token, PEIM_TOK) == 0))
149 {
150 return TRUE;
151 } else {
152 return FALSE;
153 }
154}
155
165BOOLEAN
167 IN UINT32 Identifier
168 )
169{
170 if ((Identifier == MODULE_START_ID) ||
171 (Identifier == MODULE_END_ID) ||
172 (Identifier == MODULE_LOADIMAGE_START_ID) ||
173 (Identifier == MODULE_LOADIMAGE_END_ID) ||
174 (Identifier == MODULE_DB_START_ID) ||
175 (Identifier == MODULE_DB_END_ID) ||
176 (Identifier == MODULE_DB_SUPPORT_START_ID) ||
177 (Identifier == MODULE_DB_SUPPORT_END_ID) ||
178 (Identifier == MODULE_DB_STOP_START_ID) ||
179 (Identifier == MODULE_DB_STOP_END_ID))
180 {
181 return TRUE;
182 } else {
183 return FALSE;
184 }
185}
186
203 IN PERF_MEASUREMENT_ATTRIBUTE Attribute,
204 IN CONST VOID *Handle,
205 IN CONST CHAR8 *String,
206 OUT UINT16 *ProgressID
207 )
208{
209 //
210 // Token to Id.
211 //
212 if (String != NULL) {
213 if (AsciiStrCmp (String, START_IMAGE_TOK) == 0) {
214 // "StartImage:"
215 if (Attribute == PerfStartEntry) {
216 *ProgressID = MODULE_START_ID;
217 } else {
218 *ProgressID = MODULE_END_ID;
219 }
220 } else if (AsciiStrCmp (String, LOAD_IMAGE_TOK) == 0) {
221 // "LoadImage:"
222 if (Attribute == PerfStartEntry) {
223 *ProgressID = MODULE_LOADIMAGE_START_ID;
224 } else {
225 *ProgressID = MODULE_LOADIMAGE_END_ID;
226 }
227 } else {
228 // Pref used in Modules
229 if (Attribute == PerfStartEntry) {
230 *ProgressID = PERF_INMODULE_START_ID;
231 } else {
232 *ProgressID = PERF_INMODULE_END_ID;
233 }
234 }
235 } else if (Handle != NULL) {
236 // Pref used in Modules
237 if (Attribute == PerfStartEntry) {
238 *ProgressID = PERF_INMODULE_START_ID;
239 } else {
240 *ProgressID = PERF_INMODULE_END_ID;
241 }
242 } else {
243 return EFI_UNSUPPORTED;
244 }
245
246 return EFI_SUCCESS;
247}
248
264EFIAPI
266 IN EFI_HANDLE Handle,
267 OUT CHAR8 *NameString,
268 IN UINTN BufferSize,
269 OUT EFI_GUID *ModuleGuid OPTIONAL
270 )
271{
272 EFI_STATUS Status;
273 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
274 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
275 CHAR8 *PdbFileName;
276 EFI_GUID *TempGuid;
277 UINTN StartIndex;
278 UINTN Index;
279 INTN Count;
280 BOOLEAN ModuleGuidIsGet;
281 UINTN StringSize;
282 CHAR16 *StringPtr;
284
285 if ((NameString == NULL) || (BufferSize == 0)) {
286 return EFI_INVALID_PARAMETER;
287 }
288
289 //
290 // Try to get the ModuleGuid and name string form the caached array.
291 //
292 if (mCachePairCount > 0) {
293 for (Count = mCachePairCount - 1; Count >= 0; Count--) {
294 if (Handle == mCacheHandleGuidTable[Count].Handle) {
295 CopyGuid (ModuleGuid, &mCacheHandleGuidTable[Count].ModuleGuid);
296 AsciiStrCpyS (NameString, FPDT_STRING_EVENT_RECORD_NAME_LENGTH, mCacheHandleGuidTable[Count].NameString);
297 return EFI_SUCCESS;
298 }
299 }
300 }
301
302 Status = EFI_INVALID_PARAMETER;
303 LoadedImage = NULL;
304 ModuleGuidIsGet = FALSE;
305
306 //
307 // Initialize GUID as zero value.
308 //
309 TempGuid = &gZeroGuid;
310 //
311 // Initialize it as "" string.
312 //
313 NameString[0] = 0;
314
315 if (Handle != NULL) {
316 //
317 // Try Handle as ImageHandle.
318 //
319 Status = gBS->HandleProtocol (
320 Handle,
321 &gEfiLoadedImageProtocolGuid,
322 (VOID **)&LoadedImage
323 );
324
325 if (EFI_ERROR (Status)) {
326 //
327 // Try Handle as Controller Handle
328 //
329 Status = gBS->OpenProtocol (
330 Handle,
331 &gEfiDriverBindingProtocolGuid,
332 (VOID **)&DriverBinding,
333 NULL,
334 NULL,
335 EFI_OPEN_PROTOCOL_GET_PROTOCOL
336 );
337 if (!EFI_ERROR (Status)) {
338 //
339 // Get Image protocol from ImageHandle
340 //
341 Status = gBS->HandleProtocol (
342 DriverBinding->ImageHandle,
343 &gEfiLoadedImageProtocolGuid,
344 (VOID **)&LoadedImage
345 );
346 }
347 }
348 }
349
350 if (!EFI_ERROR (Status) && (LoadedImage != NULL)) {
351 //
352 // Get Module Guid from DevicePath.
353 //
354 if ((LoadedImage->FilePath != NULL) &&
355 (LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH) &&
356 (LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP)
357 )
358 {
359 //
360 // Determine GUID associated with module logging performance
361 //
362 ModuleGuidIsGet = TRUE;
363 FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath;
364 TempGuid = &FvFilePath->FvFileName;
365 }
366
367 //
368 // Method 1 Get Module Name from PDB string.
369 //
370 PdbFileName = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
371 if ((PdbFileName != NULL) && (BufferSize > 0)) {
372 StartIndex = 0;
373 for (Index = 0; PdbFileName[Index] != 0; Index++) {
374 if ((PdbFileName[Index] == '\\') || (PdbFileName[Index] == '/')) {
375 StartIndex = Index + 1;
376 }
377 }
378
379 //
380 // Copy the PDB file name to our temporary string.
381 // If the length is bigger than BufferSize, trim the redudant characters to avoid overflow in array boundary.
382 //
383 for (Index = 0; Index < BufferSize - 1; Index++) {
384 NameString[Index] = PdbFileName[Index + StartIndex];
385 if ((NameString[Index] == 0) || (NameString[Index] == '.')) {
386 NameString[Index] = 0;
387 break;
388 }
389 }
390
391 if (Index == BufferSize - 1) {
392 NameString[Index] = 0;
393 }
394
395 //
396 // Module Name is got.
397 //
398 goto Done;
399 }
400 }
401
402 if (ModuleGuidIsGet) {
403 //
404 // Method 2 Try to get the image's FFS UI section by image GUID
405 //
406 StringPtr = NULL;
407 StringSize = 0;
408 Status = GetSectionFromAnyFv (
409 TempGuid,
410 EFI_SECTION_USER_INTERFACE,
411 0,
412 (VOID **)&StringPtr,
413 &StringSize
414 );
415
416 if (!EFI_ERROR (Status)) {
417 //
418 // Method 3. Get the name string from FFS UI section
419 //
420 for (Index = 0; Index < BufferSize - 1 && StringPtr[Index] != 0; Index++) {
421 NameString[Index] = (CHAR8)StringPtr[Index];
422 }
423
424 NameString[Index] = 0;
425 FreePool (StringPtr);
426 }
427 }
428
429Done:
430 //
431 // Copy Module Guid
432 //
433 if (ModuleGuid != NULL) {
434 CopyGuid (ModuleGuid, TempGuid);
435 if (IsZeroGuid (TempGuid) && (Handle != NULL) && !ModuleGuidIsGet) {
436 // Handle is GUID
437 CopyGuid (ModuleGuid, (EFI_GUID *)Handle);
438 }
439 }
440
441 //
442 // Cache the Handle and Guid pairs.
443 //
444 if (mCachePairCount < CACHE_HANDLE_GUID_COUNT) {
445 mCacheHandleGuidTable[mCachePairCount].Handle = Handle;
446 CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, ModuleGuid);
447 AsciiStrCpyS (mCacheHandleGuidTable[mCachePairCount].NameString, FPDT_STRING_EVENT_RECORD_NAME_LENGTH, NameString);
448 mCachePairCount++;
449 }
450
451 return Status;
452}
453
463VOID
465 IN OUT CHAR8 *Destination,
466 IN CONST CHAR8 *Source,
467 IN OUT UINT8 *Length
468 )
469{
470 UINTN StringLen;
471 UINTN DestMax;
472
473 ASSERT (Source != NULL);
474
475 if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
476 DestMax = STRING_SIZE;
477 } else {
478 DestMax = AsciiStrSize (Source);
479 if (DestMax > STRING_SIZE) {
480 DestMax = STRING_SIZE;
481 }
482 }
483
484 StringLen = AsciiStrLen (Source);
485 if (StringLen >= DestMax) {
486 StringLen = DestMax -1;
487 }
488
489 AsciiStrnCpyS (Destination, DestMax, Source, StringLen);
490 *Length += (UINT8)DestMax;
491
492 return;
493}
494
521 IN CONST VOID *CallerIdentifier OPTIONAL,
522 IN CONST VOID *Guid OPTIONAL,
523 IN CONST CHAR8 *String OPTIONAL,
524 IN UINT64 Ticker,
525 IN UINT64 Address OPTIONAL,
526 IN UINT16 PerfId,
527 IN PERF_MEASUREMENT_ATTRIBUTE Attribute
528 )
529
530{
531 EFI_STATUS Status;
532 EFI_GUID ModuleGuid;
533 CHAR8 ModuleName[FPDT_STRING_EVENT_RECORD_NAME_LENGTH];
534 FPDT_RECORD_PTR FpdtRecordPtr;
535 FPDT_RECORD_PTR CachedFpdtRecordPtr;
536 UINT64 TimeStamp;
537 CONST CHAR8 *StringPtr;
538 UINTN DestMax;
539 UINTN StringLen;
540 UINT16 ProgressId;
541
542 StringPtr = NULL;
543 ZeroMem (ModuleName, sizeof (ModuleName));
544
545 //
546 // 1. Get the Perf Id for records from PERF_START/PERF_END, PERF_START_EX/PERF_END_EX.
547 // notes: For other Perf macros (Attribute == PerfEntry), their Id is known.
548 //
549 if (Attribute != PerfEntry) {
550 //
551 // If PERF_START_EX()/PERF_END_EX() have specified the ProgressID,it has high priority.
552 // !!! Note: If the Perf is not the known Token used in the core but have same
553 // ID with the core Token, this case will not be supported.
554 // And in currtnt usage mode, for the unkown ID, there is a general rule:
555 // If it is start pref: the lower 4 bits of the ID should be 0.
556 // If it is end pref: the lower 4 bits of the ID should not be 0.
557 // If input ID doesn't follow the rule, we will adjust it.
558 //
559 if ((PerfId != 0) && (IsKnownID (PerfId)) && (!IsKnownTokens (String))) {
560 return EFI_INVALID_PARAMETER;
561 } else if ((PerfId != 0) && (!IsKnownID (PerfId)) && (!IsKnownTokens (String))) {
562 if ((Attribute == PerfStartEntry) && ((PerfId & 0x000F) != 0)) {
563 PerfId &= 0xFFF0;
564 } else if ((Attribute == PerfEndEntry) && ((PerfId & 0x000F) == 0)) {
565 PerfId += 1;
566 }
567 }
568
569 if (PerfId == 0) {
570 //
571 // Get ProgressID form the String Token.
572 //
573 Status = GetFpdtRecordId (Attribute, CallerIdentifier, String, &ProgressId);
574 if (EFI_ERROR (Status)) {
575 return Status;
576 }
577
578 PerfId = ProgressId;
579 }
580 }
581
582 //
583 // 2. Get the buffer to store the FPDT record.
584 //
585 Status = GetFpdtRecordPtr (FPDT_MAX_PERF_RECORD_SIZE, &FpdtRecordPtr);
586 if (EFI_ERROR (Status)) {
587 return Status;
588 }
589
590 //
591 // 3. Get the TimeStamp.
592 //
593 if (Ticker == 0) {
594 Ticker = GetPerformanceCounter ();
595 TimeStamp = GetTimeInNanoSecond (Ticker);
596 } else if (Ticker == 1) {
597 TimeStamp = 0;
598 } else {
599 TimeStamp = GetTimeInNanoSecond (Ticker);
600 }
601
602 //
603 // 4. Fill in the FPDT record according to different Performance Identifier.
604 //
605 switch (PerfId) {
606 case MODULE_START_ID:
607 case MODULE_END_ID:
608 GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
609 StringPtr = ModuleName;
610 //
611 // Cache the offset of start image start record and use to update the start image end record if needed.
612 //
613 if ((PerfId == MODULE_START_ID) && (Attribute == PerfEntry)) {
614 mCachedLength = mSmmBootPerformanceTable->Header.Length;
615 }
616
617 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
618 FpdtRecordPtr.GuidEvent->Header.Type = FPDT_GUID_EVENT_TYPE;
619 FpdtRecordPtr.GuidEvent->Header.Length = sizeof (FPDT_GUID_EVENT_RECORD);
620 FpdtRecordPtr.GuidEvent->Header.Revision = FPDT_RECORD_REVISION_1;
621 FpdtRecordPtr.GuidEvent->ProgressID = PerfId;
622 FpdtRecordPtr.GuidEvent->Timestamp = TimeStamp;
623 CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidEvent->Guid));
624 if ((CallerIdentifier == NULL) && (PerfId == MODULE_END_ID) && (mCachedLength != 0)) {
625 CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8 *)mSmmBootPerformanceTable + mCachedLength);
626 CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &CachedFpdtRecordPtr.GuidEvent->Guid, sizeof (FpdtRecordPtr.GuidEvent->Guid));
627 mCachedLength = 0;
628 }
629 }
630
631 break;
632
633 case MODULE_LOADIMAGE_START_ID:
634 case MODULE_LOADIMAGE_END_ID:
635 GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
636 StringPtr = ModuleName;
637 if (PerfId == MODULE_LOADIMAGE_START_ID) {
638 mLoadImageCount++;
639 //
640 // Cache the offset of load image start record and use to be updated by the load image end record if needed.
641 //
642 if ((CallerIdentifier == NULL) && (Attribute == PerfEntry)) {
643 mCachedLength = mSmmBootPerformanceTable->Header.Length;
644 }
645 }
646
647 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
648 FpdtRecordPtr.GuidQwordEvent->Header.Type = FPDT_GUID_QWORD_EVENT_TYPE;
649 FpdtRecordPtr.GuidQwordEvent->Header.Length = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);
650 FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1;
651 FpdtRecordPtr.GuidQwordEvent->ProgressID = PerfId;
652 FpdtRecordPtr.GuidQwordEvent->Timestamp = TimeStamp;
653 FpdtRecordPtr.GuidQwordEvent->Qword = mLoadImageCount;
654 CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid));
655 if ((PerfId == MODULE_LOADIMAGE_END_ID) && (mCachedLength != 0)) {
656 CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8 *)mSmmBootPerformanceTable + mCachedLength);
657 CopyMem (&CachedFpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.GuidQwordEvent->Guid));
658 mCachedLength = 0;
659 }
660 }
661
662 break;
663
664 case PERF_EVENTSIGNAL_START_ID:
665 case PERF_EVENTSIGNAL_END_ID:
666 case PERF_CALLBACK_START_ID:
667 case PERF_CALLBACK_END_ID:
668 if ((String == NULL) || (Guid == NULL)) {
669 return EFI_INVALID_PARAMETER;
670 }
671
672 StringPtr = String;
673 if (AsciiStrLen (String) == 0) {
674 StringPtr = "unknown name";
675 }
676
677 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
678 FpdtRecordPtr.DualGuidStringEvent->Header.Type = FPDT_DUAL_GUID_STRING_EVENT_TYPE;
679 FpdtRecordPtr.DualGuidStringEvent->Header.Length = sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD);
680 FpdtRecordPtr.DualGuidStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
681 FpdtRecordPtr.DualGuidStringEvent->ProgressID = PerfId;
682 FpdtRecordPtr.DualGuidStringEvent->Timestamp = TimeStamp;
683 CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, CallerIdentifier, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1));
684 CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2));
685 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DualGuidStringEvent->String, StringPtr, &FpdtRecordPtr.DualGuidStringEvent->Header.Length);
686 }
687
688 break;
689
690 case PERF_EVENT_ID:
691 case PERF_FUNCTION_START_ID:
692 case PERF_FUNCTION_END_ID:
693 case PERF_INMODULE_START_ID:
694 case PERF_INMODULE_END_ID:
695 case PERF_CROSSMODULE_START_ID:
696 case PERF_CROSSMODULE_END_ID:
697 GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
698 if (String != NULL) {
699 StringPtr = String;
700 } else {
701 StringPtr = ModuleName;
702 }
703
704 if (AsciiStrLen (StringPtr) == 0) {
705 StringPtr = "unknown name";
706 }
707
708 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
709 FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE;
710 FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
711 FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
712 FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId;
713 FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp;
714 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
715 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);
716 }
717
718 break;
719
720 default:
721 if (Attribute != PerfEntry) {
722 GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
723 if (String != NULL) {
724 StringPtr = String;
725 } else {
726 StringPtr = ModuleName;
727 }
728
729 if (AsciiStrLen (StringPtr) == 0) {
730 StringPtr = "unknown name";
731 }
732
733 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
734 FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE;
735 FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
736 FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
737 FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId;
738 FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp;
739 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
740 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);
741 }
742 } else {
743 return EFI_INVALID_PARAMETER;
744 }
745
746 break;
747 }
748
749 //
750 // 4.2 When PcdEdkiiFpdtStringRecordEnableOnly==TRUE, create string record for all Perf entries.
751 //
752 if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
753 if (StringPtr == NULL) {
754 return EFI_INVALID_PARAMETER;
755 }
756
757 FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE;
758 FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
759 FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
760 FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId;
761 FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp;
762 if (Guid != NULL) {
763 //
764 // Cache the event guid in string event record.
765 //
766 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, Guid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
767 } else {
768 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
769 }
770
771 if (AsciiStrLen (StringPtr) == 0) {
772 StringPtr = "unknown name";
773 }
774
775 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);
776
777 if ((PerfId == MODULE_LOADIMAGE_START_ID) || (PerfId == MODULE_END_ID)) {
778 FpdtRecordPtr.DynamicStringEvent->Header.Length = (UINT8)(sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)+ STRING_SIZE);
779 }
780
781 if (((PerfId == MODULE_LOADIMAGE_END_ID) || (PerfId == MODULE_END_ID)) && (mCachedLength != 0)) {
782 CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8 *)mSmmBootPerformanceTable + mCachedLength);
783 if (PerfId == MODULE_LOADIMAGE_END_ID) {
784 DestMax = CachedFpdtRecordPtr.DynamicStringEvent->Header.Length - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
785 StringLen = AsciiStrLen (StringPtr);
786 if (StringLen >= DestMax) {
787 StringLen = DestMax -1;
788 }
789
790 CopyMem (&CachedFpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.DynamicStringEvent->Guid));
791 AsciiStrnCpyS (CachedFpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
792 } else if (PerfId == MODULE_END_ID) {
793 DestMax = FpdtRecordPtr.DynamicStringEvent->Header.Length - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
794 StringLen = AsciiStrLen (CachedFpdtRecordPtr.DynamicStringEvent->String);
795 if (StringLen >= DestMax) {
796 StringLen = DestMax -1;
797 }
798
799 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &CachedFpdtRecordPtr.DynamicStringEvent->Guid, sizeof (CachedFpdtRecordPtr.DynamicStringEvent->Guid));
800 AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, CachedFpdtRecordPtr.DynamicStringEvent->String, StringLen);
801 }
802
803 mCachedLength = 0;
804 }
805 }
806
807 //
808 // 5. Update the length of the used buffer after fill in the record.
809 //
810 mPerformanceLength += FpdtRecordPtr.RecordHeader->Length;
811 mSmmBootPerformanceTable->Header.Length += FpdtRecordPtr.RecordHeader->Length;
812
813 return EFI_SUCCESS;
814}
815
841EFIAPI
843 IN EFI_HANDLE DispatchHandle,
844 IN CONST VOID *RegisterContext,
845 IN OUT VOID *CommBuffer,
846 IN OUT UINTN *CommBufferSize
847 )
848{
849 EFI_STATUS Status;
850 SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;
851 UINTN BootRecordOffset;
852 UINTN BootRecordSize;
853 VOID *BootRecordData;
854 UINTN TempCommBufferSize;
855 UINT8 *BootRecordBuffer;
856
857 //
858 // If input is invalid, stop processing this SMI
859 //
860 if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {
861 return EFI_SUCCESS;
862 }
863
864 TempCommBufferSize = *CommBufferSize;
865
866 if (TempCommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {
867 return EFI_SUCCESS;
868 }
869
870 if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
871 DEBUG ((DEBUG_ERROR, "FpdtSmiHandler: MM communication data buffer in MMRAM or overflow!\n"));
872 return EFI_SUCCESS;
873 }
874
875 SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE *)CommBuffer;
876
877 Status = EFI_SUCCESS;
878
879 switch (SmmCommData->Function) {
880 case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE:
881 if (mSmmBootPerformanceTable != NULL) {
882 mBootRecordSize = mSmmBootPerformanceTable->Header.Length - sizeof (SMM_BOOT_PERFORMANCE_TABLE);
883 }
884
885 SmmCommData->BootRecordSize = mBootRecordSize;
886 break;
887
888 case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA:
889 Status = EFI_UNSUPPORTED;
890 break;
891
892 case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET:
893 BootRecordOffset = SmmCommData->BootRecordOffset;
894 BootRecordData = SmmCommData->BootRecordData;
895 BootRecordSize = SmmCommData->BootRecordSize;
896 if ((BootRecordData == NULL) || (BootRecordOffset >= mBootRecordSize)) {
897 Status = EFI_INVALID_PARAMETER;
898 break;
899 }
900
901 //
902 // Sanity check
903 //
904 if (BootRecordSize > mBootRecordSize - BootRecordOffset) {
905 BootRecordSize = mBootRecordSize - BootRecordOffset;
906 }
907
908 SmmCommData->BootRecordSize = BootRecordSize;
909 if (!SmmIsBufferOutsideSmmValid ((UINTN)BootRecordData, BootRecordSize)) {
910 DEBUG ((DEBUG_ERROR, "FpdtSmiHandler: MM Data buffer in MMRAM or overflow!\n"));
911 Status = EFI_ACCESS_DENIED;
912 break;
913 }
914
915 BootRecordBuffer = ((UINT8 *)(mSmmBootPerformanceTable)) + sizeof (SMM_BOOT_PERFORMANCE_TABLE);
916 CopyMem (
917 (UINT8 *)BootRecordData,
918 BootRecordBuffer + BootRecordOffset,
919 BootRecordSize
920 );
921 mFpdtDataIsReported = TRUE;
922 break;
923
924 default:
925 Status = EFI_UNSUPPORTED;
926 }
927
928 SmmCommData->ReturnStatus = Status;
929
930 return EFI_SUCCESS;
931}
932
944EFIAPI
946 IN CONST EFI_GUID *Protocol,
947 IN VOID *Interface,
948 IN EFI_HANDLE Handle
949 )
950{
951 //
952 // Disable performance measurement after ExitBootServices because
953 // 1. Performance measurement might impact SMI latency at runtime;
954 // 2. Performance log is copied to non SMRAM at ReadyToBoot so runtime performance
955 // log is not useful.
956 //
957 mPerformanceMeasurementEnabled = FALSE;
958
959 return EFI_SUCCESS;
960}
961
970VOID
971EFIAPI
973 IN EFI_EVENT Event,
974 IN VOID *Context
975 )
976{
977 EFI_HANDLE Handle;
978 EFI_HANDLE SmiHandle;
979 EFI_STATUS Status;
980 PERFORMANCE_PROPERTY *PerformanceProperty;
981 VOID *Registration;
982
983 //
984 // Initialize spin lock
985 //
986 InitializeSpinLock (&mSmmFpdtLock);
987
988 //
989 // Install the protocol interfaces for SMM performance library instance.
990 //
991 Handle = NULL;
993 &Handle,
994 &gEdkiiSmmPerformanceMeasurementProtocolGuid,
996 &mPerformanceMeasurementInterface
997 );
998 ASSERT_EFI_ERROR (Status);
999
1000 //
1001 // Register SMI handler.
1002 //
1003 SmiHandle = NULL;
1004 Status = gSmst->SmiHandlerRegister (FpdtSmiHandler, &gEfiFirmwarePerformanceGuid, &SmiHandle);
1005 ASSERT_EFI_ERROR (Status);
1006
1007 Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **)&PerformanceProperty);
1008 if (EFI_ERROR (Status)) {
1009 //
1010 // Install configuration table for performance property.
1011 //
1012 mPerformanceProperty.Revision = PERFORMANCE_PROPERTY_REVISION;
1013 mPerformanceProperty.Reserved = 0;
1014 mPerformanceProperty.Frequency = GetPerformanceCounterProperties (
1015 &mPerformanceProperty.TimerStartValue,
1016 &mPerformanceProperty.TimerEndValue
1017 );
1018 Status = gBS->InstallConfigurationTable (&gPerformanceProtocolGuid, &mPerformanceProperty);
1019 ASSERT_EFI_ERROR (Status);
1020 }
1021
1022 //
1023 // Register callback function for ExitBootServices event.
1024 //
1025 Status = gSmst->SmmRegisterProtocolNotify (
1026 &gEdkiiSmmExitBootServicesProtocolGuid,
1028 &Registration
1029 );
1030 ASSERT_EFI_ERROR (Status);
1031}
1032
1045EFIAPI
1047 IN EFI_HANDLE ImageHandle,
1048 IN EFI_SYSTEM_TABLE *SystemTable
1049 )
1050{
1051 EFI_STATUS Status;
1052 EFI_EVENT Event;
1053 VOID *Registration;
1054
1055 mPerformanceMeasurementEnabled = (BOOLEAN)((PcdGet8 (PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
1056
1058 //
1059 // Do not initialize performance infrastructure if not required.
1060 //
1061 return EFI_SUCCESS;
1062 }
1063
1064 //
1065 // Create the events to do the library init.
1066 //
1067 Status = gBS->CreateEvent (
1068 EVT_NOTIFY_SIGNAL,
1069 TPL_CALLBACK,
1071 NULL,
1072 &Event
1073 );
1074 ASSERT_EFI_ERROR (Status);
1075
1076 //
1077 // Register for protocol notifications on this event
1078 //
1079 Status = gBS->RegisterProtocolNotify (
1080 &gEfiSmmBase2ProtocolGuid,
1081 Event,
1082 &Registration
1083 );
1084
1085 ASSERT_EFI_ERROR (Status);
1086
1087 return EFI_SUCCESS;
1088}
1089
1109EFIAPI
1111 IN CONST VOID *CallerIdentifier OPTIONAL,
1112 IN CONST VOID *Guid OPTIONAL,
1113 IN CONST CHAR8 *String OPTIONAL,
1114 IN UINT64 TimeStamp OPTIONAL,
1115 IN UINT64 Address OPTIONAL,
1116 IN UINT32 Identifier,
1117 IN PERF_MEASUREMENT_ATTRIBUTE Attribute
1118 )
1119{
1120 EFI_STATUS Status;
1121
1122 Status = EFI_SUCCESS;
1123
1124 AcquireSpinLock (&mSmmFpdtLock);
1125 Status = InsertFpdtRecord (CallerIdentifier, Guid, String, TimeStamp, Address, (UINT16)Identifier, Attribute);
1126 ReleaseSpinLock (&mSmmFpdtLock);
1127 return Status;
1128}
1129
1155RETURN_STATUS
1156EFIAPI
1158 IN CONST VOID *Handle OPTIONAL,
1159 IN CONST CHAR8 *Token OPTIONAL,
1160 IN CONST CHAR8 *Module OPTIONAL,
1161 IN UINT64 TimeStamp,
1162 IN UINT32 Identifier
1163 )
1164{
1165 CONST CHAR8 *String;
1166
1167 if (Token != NULL) {
1168 String = Token;
1169 } else if (Module != NULL) {
1170 String = Module;
1171 } else {
1172 String = NULL;
1173 }
1174
1175 return (RETURN_STATUS)CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfStartEntry);
1176}
1177
1204RETURN_STATUS
1205EFIAPI
1207 IN CONST VOID *Handle OPTIONAL,
1208 IN CONST CHAR8 *Token OPTIONAL,
1209 IN CONST CHAR8 *Module OPTIONAL,
1210 IN UINT64 TimeStamp,
1211 IN UINT32 Identifier
1212 )
1213{
1214 CONST CHAR8 *String;
1215
1216 if (Token != NULL) {
1217 String = Token;
1218 } else if (Module != NULL) {
1219 String = Module;
1220 } else {
1221 String = NULL;
1222 }
1223
1224 return (RETURN_STATUS)CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfEndEntry);
1225}
1226
1270UINTN
1271EFIAPI
1273 IN UINTN LogEntryKey,
1274 OUT CONST VOID **Handle,
1275 OUT CONST CHAR8 **Token,
1276 OUT CONST CHAR8 **Module,
1277 OUT UINT64 *StartTimeStamp,
1278 OUT UINT64 *EndTimeStamp,
1279 OUT UINT32 *Identifier
1280 )
1281{
1282 return 0;
1283}
1284
1308RETURN_STATUS
1309EFIAPI
1311 IN CONST VOID *Handle OPTIONAL,
1312 IN CONST CHAR8 *Token OPTIONAL,
1313 IN CONST CHAR8 *Module OPTIONAL,
1314 IN UINT64 TimeStamp
1315 )
1316{
1317 return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);
1318}
1319
1344RETURN_STATUS
1345EFIAPI
1347 IN CONST VOID *Handle OPTIONAL,
1348 IN CONST CHAR8 *Token OPTIONAL,
1349 IN CONST CHAR8 *Module OPTIONAL,
1350 IN UINT64 TimeStamp
1351 )
1352{
1353 return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);
1354}
1355
1397UINTN
1398EFIAPI
1400 IN UINTN LogEntryKey,
1401 OUT CONST VOID **Handle,
1402 OUT CONST CHAR8 **Token,
1403 OUT CONST CHAR8 **Module,
1404 OUT UINT64 *StartTimeStamp,
1405 OUT UINT64 *EndTimeStamp
1406 )
1407{
1408 return 0;
1409}
1410
1423BOOLEAN
1424EFIAPI
1426 VOID
1427 )
1428{
1429 return mPerformanceMeasurementEnabled;
1430}
1431
1447RETURN_STATUS
1448EFIAPI
1450 IN CONST VOID *CallerIdentifier,
1451 IN CONST VOID *Guid OPTIONAL,
1452 IN CONST CHAR8 *String OPTIONAL,
1453 IN UINT64 Address OPTIONAL,
1454 IN UINT32 Identifier
1455 )
1456{
1457 return (RETURN_STATUS)CreatePerformanceMeasurement (CallerIdentifier, Guid, String, 0, Address, Identifier, PerfEntry);
1458}
1459
1472BOOLEAN
1473EFIAPI
1475 IN CONST UINTN Type
1476 )
1477{
1478 //
1479 // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
1480 //
1481 if (PerformanceMeasurementEnabled () && ((PcdGet8 (PcdPerformanceLibraryPropertyMask) & Type) == 0)) {
1482 return TRUE;
1483 }
1484
1485 return FALSE;
1486}
UINT64 UINTN
INT64 INTN
UINT64 EFIAPI GetPerformanceCounterProperties(OUT UINT64 *StartValue OPTIONAL, OUT UINT64 *EndValue OPTIONAL)
UINT64 EFIAPI GetTimeInNanoSecond(IN UINT64 Ticks)
UINT64 EFIAPI GetPerformanceCounter(VOID)
RETURN_STATUS EFIAPI AsciiStrnCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source, IN UINTN Length)
Definition: SafeString.c:1875
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1797
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI IsZeroGuid(IN CONST GUID *Guid)
Definition: MemLibGuid.c:156
#define MEDIA_PIWG_FW_FILE_DP
Definition: DevicePath.h:1130
EFI_STATUS EFIAPI GetSectionFromAnyFv(IN CONST EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, OUT VOID **Buffer, OUT UINTN *Size)
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define DRIVERBINDING_START_TOK
Driver Binding Start() function call.
#define PEI_TOK
PEI Phase.
#define DXE_TOK
DXE Phase.
#define PEIM_TOK
PEIM Modules Entry Point execution.
#define DRIVERBINDING_STOP_TOK
Driver Binding Stop() function call.
#define LOAD_IMAGE_TOK
Load a dispatched module.
#define START_IMAGE_TOK
Dispatched Modules Entry Point execution.
#define BDS_TOK
BDS Phase.
#define DRIVERBINDING_SUPPORT_TOK
Driver Binding Support() function call.
#define SEC_TOK
SEC Phase.
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED
EFI_SMM_SYSTEM_TABLE2 * gSmst
EFI_STATUS EFIAPI GetModuleInfoFromHandle(IN EFI_HANDLE Handle, OUT CHAR8 *NameString, IN UINTN BufferSize, OUT EFI_GUID *ModuleGuid OPTIONAL)
EFI_STATUS GetFpdtRecordPtr(IN UINT8 RecordSize, IN OUT FPDT_RECORD_PTR *FpdtRecordPtr)
RETURN_STATUS EFIAPI EndPerformanceMeasurementEx(IN CONST VOID *Handle OPTIONAL, IN CONST CHAR8 *Token OPTIONAL, IN CONST CHAR8 *Module OPTIONAL, IN UINT64 TimeStamp, IN UINT32 Identifier)
EFI_STATUS EFIAPI SmmCorePerformanceLibExitBootServicesCallback(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
EFI_STATUS EFIAPI FpdtSmiHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *RegisterContext, IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize)
VOID EFIAPI InitializeSmmCorePerformanceLib(IN EFI_EVENT Event, IN VOID *Context)
UINTN EFIAPI GetPerformanceMeasurement(IN UINTN LogEntryKey, OUT CONST VOID **Handle, OUT CONST CHAR8 **Token, OUT CONST CHAR8 **Module, OUT UINT64 *StartTimeStamp, OUT UINT64 *EndTimeStamp)
VOID CopyStringIntoPerfRecordAndUpdateLength(IN OUT CHAR8 *Destination, IN CONST CHAR8 *Source, IN OUT UINT8 *Length)
EFI_STATUS InsertFpdtRecord(IN CONST VOID *CallerIdentifier OPTIONAL, IN CONST VOID *Guid OPTIONAL, IN CONST CHAR8 *String OPTIONAL, IN UINT64 Ticker, IN UINT64 Address OPTIONAL, IN UINT16 PerfId, IN PERF_MEASUREMENT_ATTRIBUTE Attribute)
RETURN_STATUS EFIAPI StartPerformanceMeasurementEx(IN CONST VOID *Handle OPTIONAL, IN CONST CHAR8 *Token OPTIONAL, IN CONST CHAR8 *Module OPTIONAL, IN UINT64 TimeStamp, IN UINT32 Identifier)
EFI_STATUS GetFpdtRecordId(IN PERF_MEASUREMENT_ATTRIBUTE Attribute, IN CONST VOID *Handle, IN CONST CHAR8 *String, OUT UINT16 *ProgressID)
RETURN_STATUS EFIAPI LogPerformanceMeasurement(IN CONST VOID *CallerIdentifier, IN CONST VOID *Guid OPTIONAL, IN CONST CHAR8 *String OPTIONAL, IN UINT64 Address OPTIONAL, IN UINT32 Identifier)
BOOLEAN EFIAPI LogPerformanceMeasurementEnabled(IN CONST UINTN Type)
BOOLEAN IsKnownTokens(IN CONST CHAR8 *Token)
BOOLEAN EFIAPI PerformanceMeasurementEnabled(VOID)
UINTN EFIAPI GetPerformanceMeasurementEx(IN UINTN LogEntryKey, OUT CONST VOID **Handle, OUT CONST CHAR8 **Token, OUT CONST CHAR8 **Module, OUT UINT64 *StartTimeStamp, OUT UINT64 *EndTimeStamp, OUT UINT32 *Identifier)
RETURN_STATUS EFIAPI EndPerformanceMeasurement(IN CONST VOID *Handle OPTIONAL, IN CONST CHAR8 *Token OPTIONAL, IN CONST CHAR8 *Module OPTIONAL, IN UINT64 TimeStamp)
EFI_STATUS EFIAPI CreatePerformanceMeasurement(IN CONST VOID *CallerIdentifier OPTIONAL, IN CONST VOID *Guid OPTIONAL, IN CONST CHAR8 *String OPTIONAL, IN UINT64 TimeStamp OPTIONAL, IN UINT64 Address OPTIONAL, IN UINT32 Identifier, IN PERF_MEASUREMENT_ATTRIBUTE Attribute)
BOOLEAN IsKnownID(IN UINT32 Identifier)
RETURN_STATUS EFIAPI StartPerformanceMeasurement(IN CONST VOID *Handle OPTIONAL, IN CONST CHAR8 *Token OPTIONAL, IN CONST CHAR8 *Module OPTIONAL, IN UINT64 TimeStamp)
EFI_STATUS EFIAPI SmmCorePerformanceLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
BOOLEAN EFIAPI SmmIsBufferOutsideSmmValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
Definition: SmmMemLib.c:114
SPIN_LOCK *EFIAPI AcquireSpinLock(IN OUT SPIN_LOCK *SpinLock)
SPIN_LOCK *EFIAPI InitializeSpinLock(OUT SPIN_LOCK *SpinLock)
volatile UINTN SPIN_LOCK
SPIN_LOCK *EFIAPI ReleaseSpinLock(IN OUT SPIN_LOCK *SpinLock)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
Definition: UefiLib.c:82
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_INSTALL_PROTOCOL_INTERFACE SmmInstallProtocolInterface
Definition: PiSmmCis.h:185
EFI_DEVICE_PATH_PROTOCOL * FilePath
Definition: LoadedImage.h:54
VOID * ImageBase
The base address at which the image was loaded.
Definition: LoadedImage.h:67
Definition: Base.h:213
EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER Header
Common ACPI table header.