TianoCore EDK2 master
Loading...
Searching...
No Matches
Dp.c
Go to the documentation of this file.
1
21#include "Dp.h"
22#include "Literals.h"
23#include "DpInternal.h"
24
25#pragma pack(1)
26
27typedef struct {
29 UINT32 Entry;
31
32typedef struct {
34 UINT64 Entry;
36
37#pragma pack()
38
40
41typedef struct {
42 EFI_HANDLE Handle;
43 EFI_GUID ModuleGuid;
45
46HANDLE_GUID_MAP *mCacheHandleGuidTable;
47UINTN mCachePairCount = 0;
48
49//
52CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
53CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
54UINT64 mInterestThreshold;
55BOOLEAN mShowId = FALSE;
56UINT8 *mBootPerformanceTable;
57UINTN mBootPerformanceTableSize;
58BOOLEAN mPeiPhase = FALSE;
59BOOLEAN mDxePhase = FALSE;
60UINT64 mResetEnd = 0;
61
63MEASUREMENT_RECORD *mMeasurementList = NULL;
64UINTN mMeasurementNum = 0;
65
73};
74
76UINT32 const NumCum = sizeof (CumData) / sizeof (PERF_CUM_DATA);
77
78STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
79 { L"-v", TypeFlag }, // -v Verbose Mode
80 { L"-A", TypeFlag }, // -A All, Cooked
81 { L"-R", TypeFlag }, // -R RAW All
82 { L"-s", TypeFlag }, // -s Summary
83 { L"-x", TypeFlag }, // -x eXclude Cumulative Items
84 { L"-i", TypeFlag }, // -i Display Identifier
85 { L"-c", TypeValue }, // -c Display cumulative data.
86 { L"-n", TypeValue }, // -n # Number of records to display for A and R
87 { L"-t", TypeValue }, // -t # Threshold of interest
88 { NULL, TypeMax }
89};
90
92
96VOID
98 void
99 )
100{
101 EFI_STRING StringPtr;
102 EFI_STRING StringPtrUnknown;
103
104 StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
105 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
107 -1,
108 -1,
109 NULL,
110 STRING_TOKEN (STR_DP_SECTION_HEADER),
112 (StringPtr == NULL) ? StringPtrUnknown : StringPtr
113 );
114 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), mDpHiiHandle, SummaryData.NumTrace);
115 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), mDpHiiHandle, SummaryData.NumIncomplete);
116 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), mDpHiiHandle, SummaryData.NumSummary);
118 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), mDpHiiHandle, SummaryData.NumPEIMs);
119 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), mDpHiiHandle, SummaryData.NumGlobal);
120 SHELL_FREE_NON_NULL (StringPtr);
121 SHELL_FREE_NON_NULL (StringPtrUnknown);
122}
123
130 )
131{
132 EFI_STATUS Status;
133 FIRMWARE_PERFORMANCE_TABLE *FirmwarePerformanceTable;
134
135 FirmwarePerformanceTable = (FIRMWARE_PERFORMANCE_TABLE *)EfiLocateFirstAcpiTable (
137 );
138 if (FirmwarePerformanceTable == NULL) {
139 Status = EfiGetSystemConfigurationTable (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, (VOID **)&mBootPerformanceTable);
140 if (EFI_ERROR (Status)) {
141 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL), mDpHiiHandle);
142 return EFI_NOT_FOUND;
143 }
144 } else {
145 mBootPerformanceTable = (UINT8 *)(UINTN)FirmwarePerformanceTable->BootPointerRecord.BootPerformanceTablePointer;
146 }
147
148 mBootPerformanceTableSize = ((BOOT_PERFORMANCE_TABLE *)mBootPerformanceTable)->Header.Length;
149
150 return EFI_SUCCESS;
151}
152
160VOID
162 IN EFI_GUID *ModuleGuid,
163 IN OUT EFI_HANDLE *Handle
164 )
165{
166 UINTN Index;
167
168 if (IsZeroGuid (ModuleGuid)) {
169 *Handle = NULL;
170 }
171
172 //
173 // Try to get the Handle from the cached array.
174 //
175 for (Index = 0; Index < mCachePairCount; Index++) {
176 if (CompareGuid (ModuleGuid, &mCacheHandleGuidTable[Index].ModuleGuid)) {
177 *Handle = mCacheHandleGuidTable[Index].Handle;
178 break;
179 }
180 }
181
182 if (Index >= mCachePairCount) {
183 *Handle = NULL;
184 }
185}
186
193 VOID
194 )
195{
196 EFI_STATUS Status;
197 EFI_HANDLE *HandleBuffer;
198 UINTN HandleCount;
199 UINTN Index;
200 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
201 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
202 EFI_GUID *TempGuid;
204
205 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
206 if (EFI_ERROR (Status)) {
207 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);
208 return Status;
209 }
210
211 mCacheHandleGuidTable = AllocateZeroPool (HandleCount * sizeof (HANDLE_GUID_MAP));
212 if (mCacheHandleGuidTable == NULL) {
213 return EFI_OUT_OF_RESOURCES;
214 }
215
216 for (Index = 0; Index < HandleCount; Index++) {
217 //
218 // Try Handle as ImageHandle.
219 //
220 Status = gBS->HandleProtocol (
221 HandleBuffer[Index],
222 &gEfiLoadedImageProtocolGuid,
223 (VOID **)&LoadedImage
224 );
225 if (EFI_ERROR (Status)) {
226 //
227 // Try Handle as Controller Handle
228 //
229 Status = gBS->OpenProtocol (
230 HandleBuffer[Index],
231 &gEfiDriverBindingProtocolGuid,
232 (VOID **)&DriverBinding,
233 NULL,
234 NULL,
235 EFI_OPEN_PROTOCOL_GET_PROTOCOL
236 );
237 if (!EFI_ERROR (Status)) {
238 //
239 // Get Image protocol from ImageHandle
240 //
241 Status = gBS->HandleProtocol (
242 DriverBinding->ImageHandle,
243 &gEfiLoadedImageProtocolGuid,
244 (VOID **)&LoadedImage
245 );
246 }
247 }
248
249 if (!EFI_ERROR (Status) && (LoadedImage != NULL)) {
250 //
251 // Get Module Guid from DevicePath.
252 //
253 if ((LoadedImage->FilePath != NULL) &&
254 (LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH) &&
255 (LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP)
256 )
257 {
258 FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath;
259 TempGuid = &FvFilePath->FvFileName;
260
261 mCacheHandleGuidTable[mCachePairCount].Handle = HandleBuffer[Index];
262 CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, TempGuid);
263 mCachePairCount++;
264 }
265 }
266 }
267
268 if (HandleBuffer != NULL) {
269 FreePool (HandleBuffer);
270 HandleBuffer = NULL;
271 }
272
273 return EFI_SUCCESS;
274}
275
284VOID
287 IN BOOLEAN IsStart,
288 IN OUT MEASUREMENT_RECORD *Measurement
289 )
290{
291 VOID *ModuleGuid;
292 EFI_HANDLE StartHandle;
293
294 switch (RecordHeader->Type) {
295 case FPDT_GUID_EVENT_TYPE:
296 ModuleGuid = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);
297 Measurement->Identifier = ((UINT32)((FPDT_GUID_EVENT_RECORD *)RecordHeader)->ProgressID);
298 if (IsStart) {
299 Measurement->StartTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
300 } else {
301 Measurement->EndTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
302 }
303
304 switch (Measurement->Identifier) {
305 case MODULE_START_ID:
306 case MODULE_END_ID:
307 if (mPeiPhase) {
308 Measurement->Token = ALit_PEIM;
309 Measurement->Module = ALit_PEIM;
310 } else if (mDxePhase) {
311 Measurement->Token = ALit_START_IMAGE;
312 Measurement->Module = ALit_START_IMAGE;
313 }
314
315 break;
316 default:
317 ASSERT (FALSE);
318 }
319
320 if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) {
321 Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
322 } else {
323 GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
324 Measurement->Handle = StartHandle;
325 //
326 // When no perf entry to record the PEI and DXE phase,
327 // For start image, we need detect the PEIM and non PEIM here.
328 //
329 if (Measurement->Token == NULL) {
330 if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) {
331 Measurement->Token = ALit_PEIM;
332 Measurement->Module = ALit_PEIM;
333 Measurement->Handle = ModuleGuid;
334 } else {
335 Measurement->Token = ALit_START_IMAGE;
336 Measurement->Module = ALit_START_IMAGE;
337 }
338 }
339 }
340
341 break;
342
343 case FPDT_DYNAMIC_STRING_EVENT_TYPE:
344 ModuleGuid = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
345 Measurement->Identifier = ((UINT32)((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
346 if (IsStart) {
347 Measurement->StartTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
348 } else {
349 Measurement->EndTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
350 }
351
352 switch (Measurement->Identifier) {
353 case MODULE_START_ID:
354 case MODULE_END_ID:
355 if (mPeiPhase) {
356 Measurement->Token = ALit_PEIM;
357 } else if (mDxePhase) {
358 Measurement->Token = ALit_START_IMAGE;
359 }
360
361 break;
362
363 case MODULE_LOADIMAGE_START_ID:
364 case MODULE_LOADIMAGE_END_ID:
365 Measurement->Token = ALit_LOAD_IMAGE;
366 break;
367
368 case MODULE_DB_START_ID:
369 case MODULE_DB_END_ID:
370 Measurement->Token = ALit_DB_START;
371 break;
372
373 case MODULE_DB_SUPPORT_START_ID:
374 case MODULE_DB_SUPPORT_END_ID:
375 Measurement->Token = ALit_DB_SUPPORT;
376 break;
377
378 case MODULE_DB_STOP_START_ID:
379 case MODULE_DB_STOP_END_ID:
380 Measurement->Token = ALit_DB_STOP;
381 break;
382
383 default:
384 Measurement->Token = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
385 break;
386 }
387
388 Measurement->Module = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
389
390 if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) {
391 Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
392 } else {
393 GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
394 Measurement->Handle = StartHandle;
395 //
396 // When no perf entry to record the PEI and DXE phase,
397 // For start image, we need detect the PEIM and non PEIM here.
398 //
399 if ((Measurement->Token == NULL) && ((Measurement->Identifier == MODULE_START_ID) || (Measurement->Identifier == MODULE_END_ID))) {
400 if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) {
401 Measurement->Token = ALit_PEIM;
402 Measurement->Handle = ModuleGuid;
403 } else {
404 Measurement->Token = ALit_START_IMAGE;
405 }
406 }
407 }
408
409 break;
410
411 case FPDT_GUID_QWORD_EVENT_TYPE:
412 ModuleGuid = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid);
413 Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->ProgressID);
414 if (IsStart) {
415 Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
416 } else {
417 Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
418 }
419
420 switch (Measurement->Identifier) {
421 case MODULE_DB_START_ID:
422 Measurement->Token = ALit_DB_START;
423 Measurement->Module = ALit_DB_START;
424 break;
425
426 case MODULE_DB_SUPPORT_START_ID:
427 case MODULE_DB_SUPPORT_END_ID:
428 Measurement->Token = ALit_DB_SUPPORT;
429 Measurement->Module = ALit_DB_SUPPORT;
430 break;
431
432 case MODULE_DB_STOP_START_ID:
433 case MODULE_DB_STOP_END_ID:
434 Measurement->Token = ALit_DB_STOP;
435 Measurement->Module = ALit_DB_STOP;
436 break;
437
438 case MODULE_LOADIMAGE_START_ID:
439 case MODULE_LOADIMAGE_END_ID:
440 Measurement->Token = ALit_LOAD_IMAGE;
441 Measurement->Module = ALit_LOAD_IMAGE;
442 break;
443
444 default:
445 ASSERT (FALSE);
446 }
447
448 GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
449 Measurement->Handle = StartHandle;
450 break;
451
452 case FPDT_GUID_QWORD_STRING_EVENT_TYPE:
453 ModuleGuid = &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Guid);
454 Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
455 if (IsStart) {
456 Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
457 } else {
458 Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
459 }
460
461 //
462 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
463 //
464 switch (Measurement->Identifier) {
465 case MODULE_DB_END_ID:
466 Measurement->Token = ALit_DB_START;
467 Measurement->Module = ALit_DB_START;
468 break;
469 default:
470 ASSERT (FALSE);
471 }
472
473 GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
474 Measurement->Handle = StartHandle;
475 break;
476
477 case FPDT_DUAL_GUID_STRING_EVENT_TYPE:
478 ModuleGuid = &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Guid1);
479 Measurement->Identifier = ((UINT32)((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
480 if (IsStart) {
481 Measurement->StartTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
482 } else {
483 Measurement->EndTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
484 }
485
486 Measurement->Token = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
487 Measurement->Module = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
488 GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
489 Measurement->Handle = StartHandle;
490 break;
491
492 default:
493 break;
494 }
495}
496
503VOID
505 IN MEASUREMENT_RECORD *EndMeasureMent
506 )
507{
508 INTN Index;
509
510 for (Index = mMeasurementNum - 1; Index >= 0; Index--) {
511 if (AsciiStrCmp (EndMeasureMent->Token, ALit_PEIM) == 0) {
512 if ((mMeasurementList[Index].EndTimeStamp == 0) && (EndMeasureMent->Handle != NULL) && (mMeasurementList[Index].Handle != NULL) &&
513 CompareGuid (mMeasurementList[Index].Handle, EndMeasureMent->Handle) &&
514 (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
515 (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0))
516 {
517 mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
518 break;
519 }
520 } else if (EndMeasureMent->Identifier == PERF_CROSSMODULE_END_ID) {
521 if ((mMeasurementList[Index].EndTimeStamp == 0) &&
522 (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
523 (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0) &&
524 (mMeasurementList[Index].Identifier == PERF_CROSSMODULE_START_ID))
525 {
526 mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
527 break;
528 }
529 } else {
530 if ((mMeasurementList[Index].EndTimeStamp == 0) && (mMeasurementList[Index].Handle == EndMeasureMent->Handle) &&
531 (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
532 (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0))
533 {
534 mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
535 break;
536 }
537 }
538 }
539}
540
547 )
548{
550 UINT8 *PerformanceTablePtr;
551 UINT8 *BasicBootTablePtr;
552 UINT64 ResetEnd;
553 UINT16 StartProgressId;
554 UINTN TableLength;
555 UINT8 *StartRecordEvent;
556 MEASUREMENT_RECORD MeasureMent;
557
558 mMeasurementList = AllocateZeroPool (mBootPerformanceTableSize);
559 if (mMeasurementList == NULL) {
560 return EFI_OUT_OF_RESOURCES;
561 }
562
563 //
564 // Update the ResetEnd which was logged at the beginning of firmware image execution
565 //
566 TableLength = sizeof (EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER);
567 BasicBootTablePtr = (mBootPerformanceTable + TableLength);
568 ResetEnd = ((EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD *)BasicBootTablePtr)->ResetEnd;
569
570 if (ResetEnd > 0) {
571 mResetEnd = ResetEnd;
572 }
573
574 TableLength = sizeof (BOOT_PERFORMANCE_TABLE);
575 PerformanceTablePtr = (mBootPerformanceTable + TableLength);
576
577 while (TableLength < mBootPerformanceTableSize) {
578 RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)PerformanceTablePtr;
579 StartRecordEvent = (UINT8 *)RecordHeader;
580 StartProgressId = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID;
581
582 //
583 // If the record with ProgressId 0, the record doesn't appear in pairs. The timestamp in the record is the EndTimeStamp, its StartTimeStamp is 0.
584 // If the record is the start record, fill the info to the measurement in the mMeasurementList.
585 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
586 //
587 if (StartProgressId == 0) {
588 GetMeasurementInfo (RecordHeader, FALSE, &(mMeasurementList[mMeasurementNum]));
589 mMeasurementNum++;
590 } else if ((((StartProgressId >= PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x000F) == 0)) ||
591 ((StartProgressId < PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x0001) != 0))))
592 {
593 //
594 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
595 // So we need to identify these two kinds of record through different phase.
596 //
597 if (StartProgressId == PERF_CROSSMODULE_START_ID ) {
598 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {
599 mPeiPhase = TRUE;
600 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {
601 mDxePhase = TRUE;
602 mPeiPhase = FALSE;
603 }
604 }
605
606 // Get measurement info form the start record to the mMeasurementList.
607 GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum]));
608 mMeasurementNum++;
609 } else {
610 ZeroMem (&MeasureMent, sizeof (MEASUREMENT_RECORD));
611 GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent);
612 SearchMeasurement (&MeasureMent);
613 }
614
615 TableLength += RecordHeader->Length;
616 PerformanceTablePtr += RecordHeader->Length;
617 }
618
619 return EFI_SUCCESS;
620}
621
626VOID
628 VOID
629 )
630{
631 UINTN Index;
632
633 for (Index = 0; Index < NumCum; ++Index) {
634 CumData[Index].Count = 0;
635 CumData[Index].MinDur = PERF_MAXDUR;
636 CumData[Index].MaxDur = 0;
637 CumData[Index].Duration = 0;
638 }
639}
640
645VOID
647 VOID
648 )
649{
656}
657
671 IN EFI_HANDLE ImageHandle,
672 IN EFI_SYSTEM_TABLE *SystemTable
673 )
674{
675 LIST_ENTRY *ParamPackage;
676 CONST CHAR16 *CmdLineArg;
677 EFI_STATUS Status;
678
679 PERFORMANCE_PROPERTY *PerformanceProperty;
680 UINTN Number2Display;
681
682 EFI_STRING StringPtr;
683 BOOLEAN SummaryMode;
684 BOOLEAN VerboseMode;
685 BOOLEAN AllMode;
686 BOOLEAN RawMode;
687 BOOLEAN ExcludeMode;
688 BOOLEAN CumulativeMode;
689 CONST CHAR16 *CustomCumulativeToken;
690 PERF_CUM_DATA *CustomCumulativeData;
691 UINTN NameSize;
692 SHELL_STATUS ShellStatus;
693 TIMER_INFO TimerInfo;
694 UINT64 Intermediate;
695
696 StringPtr = NULL;
697 SummaryMode = FALSE;
698 VerboseMode = FALSE;
699 AllMode = FALSE;
700 RawMode = FALSE;
701 ExcludeMode = FALSE;
702 CumulativeMode = FALSE;
703 CustomCumulativeData = NULL;
704 ShellStatus = SHELL_SUCCESS;
705
706 //
707 // initialize the shell lib (we must be in non-auto-init...)
708 //
709 Status = ShellInitialize ();
710 ASSERT_EFI_ERROR (Status);
711
712 //
713 // Process Command Line arguments
714 //
715 Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
716 if (EFI_ERROR (Status)) {
717 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), mDpHiiHandle);
719 } else if (ShellCommandLineGetCount (ParamPackage) > 1) {
720 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_MANY), mDpHiiHandle);
722 }
723
724 //
725 // Boolean options
726 //
727 VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");
728 SummaryMode = (BOOLEAN)(ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));
729 AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");
730 RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");
731 ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");
732 mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");
733 CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");
734
735 if (AllMode && RawMode) {
736 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CONFLICT_ARG), mDpHiiHandle, L"-A", L"-R");
738 }
739
740 // Options with Values
741 if (ShellCommandLineGetFlag (ParamPackage, L"-n")) {
742 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");
743 if (CmdLineArg == NULL) {
744 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
746 } else {
747 if (!(RawMode || AllMode)) {
748 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_NO_RAW_ALL), mDpHiiHandle);
750 }
751
752 Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE);
753 if (EFI_ERROR (Status)) {
754 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-n");
756 } else {
757 Number2Display = (UINTN)Intermediate;
758 if ((Number2Display == 0) || (Number2Display > MAXIMUM_DISPLAYCOUNT)) {
759 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_RANGE), mDpHiiHandle, L"-n", 0, MAXIMUM_DISPLAYCOUNT);
761 }
762 }
763 }
764 } else {
765 Number2Display = DEFAULT_DISPLAYCOUNT;
766 }
767
768 if (ShellCommandLineGetFlag (ParamPackage, L"-t")) {
769 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");
770 if (CmdLineArg == NULL) {
771 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
773 } else {
774 Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE);
775 if (EFI_ERROR (Status)) {
776 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-t");
778 } else {
779 mInterestThreshold = Intermediate;
780 }
781 }
782 } else {
783 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
784 }
785
786 if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {
787 CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c");
788 if (CustomCumulativeToken == NULL) {
789 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
791 } else {
792 CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));
793 if (CustomCumulativeData == NULL) {
794 ShellStatus = SHELL_OUT_OF_RESOURCES;
795 goto Done;
796 }
797
798 CustomCumulativeData->MinDur = PERF_MAXDUR;
799 CustomCumulativeData->MaxDur = 0;
800 CustomCumulativeData->Count = 0;
801 CustomCumulativeData->Duration = 0;
802 NameSize = StrLen (CustomCumulativeToken) + 1;
803 CustomCumulativeData->Name = AllocateZeroPool (NameSize);
804 if (CustomCumulativeData->Name == NULL) {
805 ShellStatus = SHELL_OUT_OF_RESOURCES;
806 goto Done;
807 }
808
809 UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize);
810 }
811 }
812
813 //
814 // DP dump performance data by parsing FPDT table in ACPI table.
815 // Folloing 3 steps are to get the measurement form the FPDT table.
816 //
817
818 //
819 // 1. Get FPDT from ACPI table.
820 //
821 Status = GetBootPerformanceTable ();
822 if (EFI_ERROR (Status)) {
823 ShellStatus = Status;
824 goto Done;
825 }
826
827 //
828 // 2. Cache the ModuleGuid and hanlde mapping table.
829 //
830 Status = BuildCachedGuidHandleTable ();
831 if (EFI_ERROR (Status)) {
832 ShellStatus = Status;
833 goto Done;
834 }
835
836 //
837 // 3. Build the measurement array form the FPDT records.
838 //
839 Status = BuildMeasurementList ();
840 if (EFI_ERROR (Status)) {
841 ShellStatus = SHELL_OUT_OF_RESOURCES;
842 goto Done;
843 }
844
845 //
846 // Initialize the pre-defined cumulative data.
847 //
849
850 //
851 // Initialize the Summary data.
852 //
854
855 //
856 // Timer specific processing
857 //
858 // Get the Performance counter characteristics:
859 // Freq = Frequency in Hz
860 // StartCount = Value loaded into the counter when it starts counting
861 // EndCount = Value counter counts to before it needs to be reset
862 //
863 Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **)&PerformanceProperty);
864 if (EFI_ERROR (Status) || (PerformanceProperty == NULL)) {
865 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND), mDpHiiHandle);
866 goto Done;
867 }
868
869 TimerInfo.Frequency = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000);
870 TimerInfo.StartCount = 0;
871 TimerInfo.EndCount = 0xFFFF;
872 TimerInfo.CountUp = TRUE;
873
874 //
875 // Print header
876 //
877 // print DP's build version
878 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), mDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);
879
880 // print performance timer characteristics
881 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), mDpHiiHandle, TimerInfo.Frequency);
882
883 if (VerboseMode && !RawMode) {
884 StringPtr = HiiGetString (
886 (EFI_STRING_ID)(TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)),
887 NULL
888 );
889 ASSERT (StringPtr != NULL);
890 // Print Timer count range and direction
892 -1,
893 -1,
894 NULL,
895 STRING_TOKEN (STR_DP_TIMER_PROPERTIES),
897 StringPtr,
898 TimerInfo.StartCount,
899 TimerInfo.EndCount
900 );
901 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mDpHiiHandle, mInterestThreshold);
902 }
903
904 /****************************************************************************
905 **** Print Sections based on command line options
906 ****
907 **** Option modes have the following priority:
908 **** v Verbose -- Valid in combination with any other options
909 **** t Threshold -- Modifies All, Raw, and Cooked output
910 **** Default is 0 for All and Raw mode
911 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
912 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
913 **** A All -- R and S options are ignored
914 **** R Raw -- S option is ignored
915 **** s Summary -- Modifies "Cooked" output only
916 **** Cooked (Default)
917 ****************************************************************************/
918 GatherStatistics (CustomCumulativeData);
919 if (CumulativeMode) {
920 ProcessCumulative (CustomCumulativeData);
921 } else if (AllMode) {
922 Status = DumpAllTrace (Number2Display, ExcludeMode);
923 if (Status == EFI_ABORTED) {
924 ShellStatus = SHELL_ABORTED;
925 goto Done;
926 }
927 } else if (RawMode) {
928 Status = DumpRawTrace (Number2Display, ExcludeMode);
929 if (Status == EFI_ABORTED) {
930 ShellStatus = SHELL_ABORTED;
931 goto Done;
932 }
933 } else {
934 // ------------- Begin Cooked Mode Processing
935 ProcessPhases ();
936 if ( !SummaryMode) {
937 Status = ProcessHandles (ExcludeMode);
938 if (Status == EFI_ABORTED) {
939 ShellStatus = SHELL_ABORTED;
940 goto Done;
941 }
942
943 Status = ProcessPeims ();
944 if (Status == EFI_ABORTED) {
945 ShellStatus = SHELL_ABORTED;
946 goto Done;
947 }
948
949 Status = ProcessGlobal ();
950 if (Status == EFI_ABORTED) {
951 ShellStatus = SHELL_ABORTED;
952 goto Done;
953 }
954
956 }
957 } // ------------- End of Cooked Mode Processing
958
959 if ( VerboseMode || SummaryMode) {
961 }
962
963Done:
964 if (ParamPackage != NULL) {
965 ShellCommandLineFreeVarList (ParamPackage);
966 }
967
968 SHELL_FREE_NON_NULL (StringPtr);
969 if (CustomCumulativeData != NULL) {
970 SHELL_FREE_NON_NULL (CustomCumulativeData->Name);
971 }
972
973 SHELL_FREE_NON_NULL (CustomCumulativeData);
974
975 SHELL_FREE_NON_NULL (mMeasurementList);
976
977 SHELL_FREE_NON_NULL (mCacheHandleGuidTable);
978
979 mMeasurementNum = 0;
980 mCachePairCount = 0;
981 return ShellStatus;
982}
983
993 EFI_HANDLE ImageHandle
994 )
995{
996 EFI_STATUS Status;
997 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
998 EFI_HII_HANDLE HiiHandle;
999
1000 //
1001 // Retrieve HII package list from ImageHandle
1002 //
1003 Status = gBS->OpenProtocol (
1004 ImageHandle,
1005 &gEfiHiiPackageListProtocolGuid,
1006 (VOID **)&PackageList,
1007 ImageHandle,
1008 NULL,
1009 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1010 );
1011 ASSERT_EFI_ERROR (Status);
1012 if (EFI_ERROR (Status)) {
1013 return NULL;
1014 }
1015
1016 //
1017 // Publish HII package list to HII Database.
1018 //
1019 Status = gHiiDatabase->NewPackageList (
1021 PackageList,
1022 NULL,
1023 &HiiHandle
1024 );
1025 ASSERT_EFI_ERROR (Status);
1026 if (EFI_ERROR (Status)) {
1027 return NULL;
1028 }
1029
1030 return HiiHandle;
1031}
UINT64 UINTN
INT64 INTN
#define EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
Definition: Acpi50.h:1940
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
RETURN_STATUS EFIAPI UnicodeStrToAsciiStrS(IN CONST CHAR16 *Source, OUT CHAR8 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2650
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
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
PERF_CUM_DATA CumData[]
Items for which to gather cumulative statistics.
Definition: Dp.c:67
VOID InitSummaryData(VOID)
Definition: Dp.c:646
EFI_HII_HANDLE InitializeHiiPackage(EFI_HANDLE ImageHandle)
Definition: Dp.c:992
VOID SearchMeasurement(IN MEASUREMENT_RECORD *EndMeasureMent)
Definition: Dp.c:504
PERF_SUMMARY_DATA SummaryData
Create the SummaryData structure and init. to ZERO.
Definition: Dp.c:62
EFI_STATUS BuildCachedGuidHandleTable(VOID)
Definition: Dp.c:192
CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH+1]
Definition: Dp.c:52
SHELL_STATUS RunDp(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: Dp.c:670
VOID GetHandleFormModuleGuid(IN EFI_GUID *ModuleGuid, IN OUT EFI_HANDLE *Handle)
Definition: Dp.c:161
EFI_STATUS BuildMeasurementList()
Definition: Dp.c:546
EFI_STATUS GetBootPerformanceTable()
Definition: Dp.c:129
UINT32 const NumCum
Number of items for which we are gathering cumulative statistics.
Definition: Dp.c:76
VOID DumpStatistics(void)
Definition: Dp.c:97
VOID GetMeasurementInfo(IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader, IN BOOLEAN IsStart, IN OUT MEASUREMENT_RECORD *Measurement)
Definition: Dp.c:285
VOID InitCumulativeData(VOID)
Definition: Dp.c:627
EFI_HII_HANDLE mDpHiiHandle
Definition: Dp.c:39
#define DEFAULT_THRESHOLD
One millisecond.
Definition: Dp.h:49
#define MAXIMUM_DISPLAYCOUNT
Arbitrary maximum reasonable number.
Definition: Dp.h:51
#define PERF_INIT_CUM_DATA(t)
Definition: Dp.h:75
VOID GatherStatistics(IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL)
Definition: DpTrace.c:92
EFI_STATUS ProcessGlobal(VOID)
Definition: DpTrace.c:853
EFI_STATUS DumpRawTrace(IN UINTN Limit, IN BOOLEAN ExcludeFlag)
Definition: DpTrace.c:363
EFI_STATUS ProcessPeims(VOID)
Definition: DpTrace.c:747
EFI_STATUS DumpAllTrace(IN UINTN Limit, IN BOOLEAN ExcludeFlag)
Definition: DpTrace.c:188
VOID ProcessPhases(VOID)
Definition: DpTrace.c:478
EFI_STATUS ProcessHandles(IN BOOLEAN ExcludeFlag)
Definition: DpTrace.c:610
VOID ProcessCumulative(IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL)
Definition: DpTrace.c:966
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define DRIVERBINDING_START_TOK
Driver Binding Start() function call.
#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 DRIVERBINDING_SUPPORT_TOK
Driver Binding Support() function call.
EFI_STRING EFIAPI HiiGetString(IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID StringId, IN CONST CHAR8 *Language OPTIONAL)
Definition: HiiString.c:211
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#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
SHELL_STATUS
Definition: Shell.h:21
@ SHELL_OUT_OF_RESOURCES
Definition: Shell.h:73
@ SHELL_ABORTED
Definition: Shell.h:128
@ SHELL_SUCCESS
Definition: Shell.h:25
@ SHELL_INVALID_PARAMETER
Definition: Shell.h:35
CONST CHAR16 *EFIAPI ShellCommandLineGetValue(IN CONST LIST_ENTRY *CheckPackage, IN CHAR16 *KeyString)
#define ShellCommandLineParse(CheckList, CheckPackage, ProblemParam, AutoPageBreak)
Make it easy to upgrade from older versions of the shell library.
Definition: ShellLib.h:755
EFI_STATUS EFIAPI ShellPrintHiiEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR8 *Language OPTIONAL, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle,...)
BOOLEAN EFIAPI ShellCommandLineGetFlag(IN CONST LIST_ENTRY *CONST CheckPackage, IN CONST CHAR16 *CONST KeyString)
@ TypeValue
A flag that has some data following it with a space (IE "-a 1").
Definition: ShellLib.h:700
@ TypeFlag
A flag that is present or not present only (IE "-a").
Definition: ShellLib.h:699
VOID EFIAPI ShellCommandLineFreeVarList(IN LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellInitialize(VOID)
Definition: UefiShellLib.c:532
UINTN EFIAPI ShellCommandLineGetCount(IN CONST LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellConvertStringToUint64(IN CONST CHAR16 *String, OUT UINT64 *Value, IN CONST BOOLEAN ForceHex, IN CONST BOOLEAN StopAtSpace)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_HII_DATABASE_PROTOCOL * gHiiDatabase
#define STRING_TOKEN(t)
VOID * EFI_HII_HANDLE
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
Definition: UefiLib.c:82
EFI_ACPI_COMMON_HEADER *EFIAPI EfiLocateFirstAcpiTable(IN UINT32 Signature)
Definition: Acpi.c:441
@ AllHandles
Definition: UefiSpec.h:1509
EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD BootPointerRecord
Basic Boot Performance Table Pointer record.
Definition: Base.h:213
UINT32 Identifier
Identifier.
Definition: Dp.h:100
CONST CHAR8 * Module
Module string name.
Definition: Dp.h:97
CONST CHAR8 * Token
Measured token string name.
Definition: Dp.h:96
UINT64 EndTimeStamp
End time point.
Definition: Dp.h:99
UINT64 MaxDur
Largest duration encountered.
Definition: Dp.h:80
UINT64 MinDur
Smallest duration encountered.
Definition: Dp.h:79
UINT64 Duration
Cumulative duration for this item.
Definition: Dp.h:78
UINT32 Count
Total number of measurements accumulated.
Definition: Dp.h:82
CHAR8 * Name
ASCII name of this item.
Definition: Dp.h:81
UINT32 NumSummary
Number of summary section measurements.
Definition: Dp.h:88
UINT32 NumHandles
Number of measurements with handles.
Definition: Dp.h:89
UINT32 NumPEIMs
Number of measurements of PEIMs.
Definition: Dp.h:90
UINT32 NumTrace
Number of recorded TRACE performance measurements.
Definition: Dp.h:86
UINT32 NumGlobal
Number of measurements with END value and NULL handle.
Definition: Dp.h:91
UINT32 NumIncomplete
Number of measurements with no END value.
Definition: Dp.h:87
Definition: Dp.c:27
Structure for storing Timer specific information.
Definition: Dp.h:59
UINT64 StartCount
Value timer is initialized with.
Definition: Dp.h:60
UINT32 Frequency
Timer count frequency in KHz.
Definition: Dp.h:62
UINT64 EndCount
Value timer has just before it wraps.
Definition: Dp.h:61
BOOLEAN CountUp
TRUE if the counter counts up.
Definition: Dp.h:63
Definition: Dp.c:32