ShellPkg/DP: Add more check for input parameters
[mirror_edk2.git] / ShellPkg / DynamicCommand / DpDynamicCommand / Dp.c
CommitLineData
d41bc92c 1/** @file\r
2 Shell command for Displaying Performance Metrics.\r
3\r
4 The Dp command reads performance data and presents it in several\r
5 different formats depending upon the needs of the user. Both\r
6 Trace and Measured Profiling information is processed and presented.\r
7\r
8 Dp uses the "PerformanceLib" to read the measurement records.\r
9 The "TimerLib" provides information about the timer, such as frequency,\r
10 beginning, and ending counter values.\r
11 Measurement records contain identifying information (Handle, Token, Module)\r
12 and start and end time values.\r
13 Dp uses this information to group records in different ways. It also uses\r
14 timer information to calculate elapsed time for each measurement.\r
ba0014b9 15\r
115eae65 16 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.\r
196ccda0 17 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
d41bc92c 18 This program and the accompanying materials\r
19 are licensed and made available under the terms and conditions of the BSD License\r
20 which accompanies this distribution. The full text of the license may be found at\r
21 http://opensource.org/licenses/bsd-license.php\r
ba0014b9 22\r
d41bc92c 23 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
24 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
25**/\r
26\r
d41bc92c 27#include "Dp.h"\r
28#include "Literals.h"\r
29#include "DpInternal.h"\r
30\r
115eae65
DB
31#pragma pack(1)\r
32\r
33typedef struct {\r
34 EFI_ACPI_DESCRIPTION_HEADER Header;\r
35 UINT32 Entry;\r
36} RSDT_TABLE;\r
37\r
38typedef struct {\r
39 EFI_ACPI_DESCRIPTION_HEADER Header;\r
40 UINT64 Entry;\r
41} XSDT_TABLE;\r
42\r
43#pragma pack()\r
44\r
92034c4c
RN
45EFI_HANDLE mDpHiiHandle;\r
46\r
115eae65
DB
47typedef struct {\r
48 EFI_HANDLE Handle;\r
49 EFI_GUID ModuleGuid;\r
50} HANDLE_GUID_MAP;\r
51\r
52HANDLE_GUID_MAP *mCacheHandleGuidTable;\r
53UINTN mCachePairCount = 0;\r
54\r
d41bc92c 55//\r
56/// Module-Global Variables\r
57///@{\r
58CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];\r
59CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];\r
60UINT64 mInterestThreshold;\r
61BOOLEAN mShowId = FALSE;\r
115eae65
DB
62UINT8 *mBootPerformanceTable;\r
63UINTN mBootPerformanceTableSize;\r
64BOOLEAN mPeiPhase = FALSE;\r
65BOOLEAN mDxePhase = FALSE;\r
d41bc92c 66\r
67PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.\r
115eae65
DB
68MEASUREMENT_RECORD *mMeasurementList = NULL;\r
69UINTN mMeasurementNum = 0;\r
d41bc92c 70\r
71/// Items for which to gather cumulative statistics.\r
72PERF_CUM_DATA CumData[] = {\r
73 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),\r
74 PERF_INIT_CUM_DATA (START_IMAGE_TOK),\r
75 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),\r
76 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK)\r
77};\r
78\r
79/// Number of items for which we are gathering cumulative statistics.\r
80UINT32 const NumCum = sizeof(CumData) / sizeof(PERF_CUM_DATA);\r
81\r
82STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
83 {L"-v", TypeFlag}, // -v Verbose Mode\r
84 {L"-A", TypeFlag}, // -A All, Cooked\r
85 {L"-R", TypeFlag}, // -R RAW All\r
86 {L"-s", TypeFlag}, // -s Summary\r
d41bc92c 87 {L"-x", TypeFlag}, // -x eXclude Cumulative Items\r
88 {L"-i", TypeFlag}, // -i Display Identifier\r
a06795c6 89 {L"-c", TypeValue}, // -c Display cumulative data.\r
d41bc92c 90 {L"-n", TypeValue}, // -n # Number of records to display for A and R\r
91 {L"-t", TypeValue}, // -t # Threshold of interest\r
92 {NULL, TypeMax}\r
93 };\r
94\r
95///@}\r
96\r
97/**\r
98 Display the trailing Verbose information.\r
99**/\r
100VOID\r
101DumpStatistics( void )\r
102{\r
103 EFI_STRING StringPtr;\r
104 EFI_STRING StringPtrUnknown;\r
92034c4c
RN
105 StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);\r
106 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
107 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,\r
d41bc92c 108 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
92034c4c
RN
109 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), mDpHiiHandle, SummaryData.NumTrace);\r
110 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), mDpHiiHandle, SummaryData.NumIncomplete);\r
111 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), mDpHiiHandle, SummaryData.NumSummary);\r
112 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), mDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);\r
113 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), mDpHiiHandle, SummaryData.NumPEIMs);\r
114 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), mDpHiiHandle, SummaryData.NumGlobal);\r
d41bc92c 115 SHELL_FREE_NON_NULL (StringPtr);\r
116 SHELL_FREE_NON_NULL (StringPtrUnknown);\r
117}\r
118\r
115eae65
DB
119/**\r
120 This function scan ACPI table in RSDT.\r
121\r
122 @param Rsdt ACPI RSDT\r
123 @param Signature ACPI table signature\r
124\r
125 @return ACPI table\r
126**/\r
127VOID *\r
128ScanTableInRSDT (\r
129 IN RSDT_TABLE *Rsdt,\r
130 IN UINT32 Signature\r
131 )\r
132{\r
133 UINTN Index;\r
134 UINT32 EntryCount;\r
135 UINT32 *EntryPtr;\r
136 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
137\r
138 EntryCount = (Rsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);\r
139\r
140 EntryPtr = &Rsdt->Entry;\r
141 for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {\r
142 Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(*EntryPtr));\r
143 if (Table->Signature == Signature) {\r
144 return Table;\r
145 }\r
146 }\r
147\r
148 return NULL;\r
149}\r
150\r
151/**\r
152 This function scan ACPI table in XSDT.\r
153\r
154 @param Xsdt ACPI XSDT\r
155 @param Signature ACPI table signature\r
156\r
157 @return ACPI table\r
158**/\r
159VOID *\r
160ScanTableInXSDT (\r
161 IN XSDT_TABLE *Xsdt,\r
162 IN UINT32 Signature\r
163 )\r
164{\r
165 UINTN Index;\r
166 UINT32 EntryCount;\r
167 UINT64 EntryPtr;\r
168 UINTN BasePtr;\r
169 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
170\r
171 EntryCount = (Xsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);\r
172\r
173 BasePtr = (UINTN)(&(Xsdt->Entry));\r
174 for (Index = 0; Index < EntryCount; Index ++) {\r
175 CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));\r
176 Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(EntryPtr));\r
177 if (Table->Signature == Signature) {\r
178 return Table;\r
179 }\r
180 }\r
181\r
182 return NULL;\r
183}\r
184\r
185/**\r
186 This function scan ACPI table in RSDP.\r
187\r
188 @param Rsdp ACPI RSDP\r
189 @param Signature ACPI table signature\r
190\r
191 @return ACPI table\r
192**/\r
193VOID *\r
194FindAcpiPtr (\r
195 IN EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp,\r
196 IN UINT32 Signature\r
197 )\r
198{\r
199 EFI_ACPI_DESCRIPTION_HEADER *AcpiTable;\r
200 RSDT_TABLE *Rsdt;\r
201 XSDT_TABLE *Xsdt;\r
202\r
203 AcpiTable = NULL;\r
204\r
205 //\r
206 // Check ACPI2.0 table\r
207 //\r
208 Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;\r
209 Xsdt = NULL;\r
210 if ((Rsdp->Revision >= 2) && (Rsdp->XsdtAddress < (UINT64)(UINTN)-1)) {\r
211 Xsdt = (XSDT_TABLE *)(UINTN)Rsdp->XsdtAddress;\r
212 }\r
213 //\r
214 // Check Xsdt\r
215 //\r
216 if (Xsdt != NULL) {\r
217 AcpiTable = ScanTableInXSDT (Xsdt, Signature);\r
218 }\r
219 //\r
220 // Check Rsdt\r
221 //\r
222 if ((AcpiTable == NULL) && (Rsdt != NULL)) {\r
223 AcpiTable = ScanTableInRSDT (Rsdt, Signature);\r
224 }\r
225\r
226 return AcpiTable;\r
227}\r
228\r
229/**\r
230 Get Boot performance table form Acpi table.\r
231\r
232**/\r
233EFI_STATUS\r
234GetBootPerformanceTable (\r
235 )\r
236{\r
237 EFI_STATUS Status;\r
238 VOID *AcpiTable;\r
239 FIRMWARE_PERFORMANCE_TABLE *FirmwarePerformanceTable;\r
240\r
241 AcpiTable = NULL;\r
242\r
243 Status = EfiGetSystemConfigurationTable (\r
244 &gEfiAcpi20TableGuid,\r
245 &AcpiTable\r
246 );\r
247 if (EFI_ERROR (Status)) {\r
248 Status = EfiGetSystemConfigurationTable (\r
249 &gEfiAcpi10TableGuid,\r
250 &AcpiTable\r
251 );\r
252 }\r
2d70c90d 253 if (EFI_ERROR(Status) || AcpiTable == NULL) {\r
4109d0d7 254 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_TABLE_FAIL), mDpHiiHandle);\r
115eae65
DB
255 return Status;\r
256 }\r
257\r
258 FirmwarePerformanceTable = FindAcpiPtr (\r
259 (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiTable,\r
260 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE\r
261 );\r
262 if (FirmwarePerformanceTable == NULL) {\r
4109d0d7 263 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL), mDpHiiHandle);\r
115eae65
DB
264 return EFI_NOT_FOUND;\r
265 }\r
266\r
267 mBootPerformanceTable = (UINT8*) (UINTN)FirmwarePerformanceTable->BootPointerRecord.BootPerformanceTablePointer;\r
268 mBootPerformanceTableSize = ((BOOT_PERFORMANCE_TABLE *) mBootPerformanceTable)->Header.Length;\r
269\r
270 return EFI_SUCCESS;\r
271}\r
272\r
273/**\r
274 Get Handle form Module Guid.\r
275\r
276 @param ModuleGuid Module Guid.\r
277 @param Handle The handle to be returned.\r
278\r
279**/\r
280VOID\r
281GetHandleFormModuleGuid (\r
282 IN EFI_GUID *ModuleGuid,\r
283 IN OUT EFI_HANDLE *Handle\r
284 )\r
285{\r
286 UINTN Index;\r
287\r
288 if (IsZeroGuid (ModuleGuid)) {\r
289 *Handle = NULL;\r
290 }\r
291 //\r
292 // Try to get the Handle form the caached array.\r
293 //\r
294 for (Index = 0; Index < mCachePairCount; Index++) {\r
295 if (CompareGuid (ModuleGuid, &mCacheHandleGuidTable[Index].ModuleGuid)) {\r
296 *Handle = mCacheHandleGuidTable[Index].Handle;\r
297 break;\r
298 }\r
299 }\r
300 if (Index >= mCachePairCount) {\r
301 *Handle = NULL;\r
302 }\r
303}\r
304\r
305/**\r
306Cache the GUID and handle mapping pairs. In order to save time for searching.\r
307\r
308**/\r
309EFI_STATUS\r
310BuildCachedGuidHandleTable (\r
311 VOID\r
312 )\r
313{\r
314 EFI_STATUS Status;\r
315 EFI_HANDLE *HandleBuffer;\r
316 UINTN HandleCount;\r
317 UINTN Index;\r
318 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
319 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
320 EFI_GUID *TempGuid;\r
321 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;\r
322\r
323 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);\r
324 if (EFI_ERROR (Status)) {\r
325 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);\r
326 return Status;\r
327 }\r
328\r
329 mCacheHandleGuidTable = AllocateZeroPool (HandleCount * sizeof (HANDLE_GUID_MAP));\r
330 if (mCacheHandleGuidTable == NULL) {\r
331 return EFI_OUT_OF_RESOURCES;\r
332 }\r
333\r
334 for (Index = 0; Index < HandleCount; Index++) {\r
335 //\r
336 // Try Handle as ImageHandle.\r
337 //\r
338 Status = gBS->HandleProtocol (\r
339 HandleBuffer[Index],\r
340 &gEfiLoadedImageProtocolGuid,\r
341 (VOID**) &LoadedImage\r
342 );\r
343 if (EFI_ERROR (Status)) {\r
344 //\r
345 // Try Handle as Controller Handle\r
346 //\r
347 Status = gBS->OpenProtocol (\r
348 HandleBuffer[Index],\r
349 &gEfiDriverBindingProtocolGuid,\r
350 (VOID **) &DriverBinding,\r
351 NULL,\r
352 NULL,\r
353 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
354 );\r
355 if (!EFI_ERROR (Status)) {\r
356 //\r
357 // Get Image protocol from ImageHandle\r
358 //\r
359 Status = gBS->HandleProtocol (\r
360 DriverBinding->ImageHandle,\r
361 &gEfiLoadedImageProtocolGuid,\r
362 (VOID**) &LoadedImage\r
363 );\r
364 }\r
365 }\r
366\r
367 if (!EFI_ERROR (Status) && LoadedImage != NULL) {\r
368 //\r
369 // Get Module Guid from DevicePath.\r
370 //\r
371 if (LoadedImage->FilePath != NULL &&\r
372 LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH &&\r
373 LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP\r
374 ) {\r
375 FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LoadedImage->FilePath;\r
376 TempGuid = &FvFilePath->FvFileName;\r
377\r
378 mCacheHandleGuidTable[mCachePairCount].Handle = HandleBuffer[Index];\r
379 CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, TempGuid);\r
380 mCachePairCount ++;\r
381 }\r
382 }\r
383 }\r
384 if (HandleBuffer != NULL) {\r
385 FreePool (HandleBuffer);\r
386 HandleBuffer = NULL;\r
387 }\r
37d533da 388 return EFI_SUCCESS;\r
115eae65
DB
389}\r
390\r
391/**\r
392 Get Measurement form Fpdt records.\r
393\r
394 @param RecordHeader Pointer to the start record.\r
395 @param IsStart Is start record or End record.\r
396 @param Measurement Pointer to the measurement which need to be filled.\r
397\r
398**/\r
399VOID\r
400GetMeasurementInfo (\r
401 IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader,\r
402 IN BOOLEAN IsStart,\r
403 IN OUT MEASUREMENT_RECORD *Measurement\r
404 )\r
405{\r
406 VOID *ModuleGuid;\r
407 EFI_HANDLE StartHandle;\r
408\r
409 switch (RecordHeader->Type) {\r
410 case FPDT_GUID_EVENT_TYPE:\r
411 ModuleGuid = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);\r
412 Measurement->Identifier = ((UINT32)((FPDT_GUID_EVENT_RECORD *)RecordHeader)->ProgressID);\r
413 if (IsStart) {\r
414 Measurement->StartTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;\r
415 } else {\r
416 Measurement->EndTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;\r
417 }\r
418 switch (Measurement->Identifier) {\r
419 case MODULE_START_ID:\r
420 case MODULE_END_ID:\r
421 if (mPeiPhase) {\r
422 Measurement->Token = ALit_PEIM;\r
423 Measurement->Module = ALit_PEIM;\r
424 } else if (mDxePhase) {\r
425 Measurement->Token = ALit_START_IMAGE;\r
426 Measurement->Module = ALit_START_IMAGE;\r
427 }\r
428 break;\r
429 default:\r
430 ASSERT(FALSE);\r
431 }\r
432\r
f45dd2dd
BD
433 if (Measurement->Token != NULL && AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {\r
434 Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);\r
115eae65
DB
435 } else {\r
436 GetHandleFormModuleGuid(ModuleGuid, &StartHandle);\r
f45dd2dd
BD
437 Measurement->Handle = StartHandle;\r
438 //\r
439 // When no perf entry to record the PEI and DXE phase,\r
440 // For start image, we need detect the PEIM and non PEIM here.\r
441 //\r
442 if (Measurement->Token == NULL) {\r
443 if (StartHandle == NULL && !IsZeroGuid (ModuleGuid)) {\r
444 Measurement->Token = ALit_PEIM;\r
445 Measurement->Module = ALit_PEIM;\r
446 Measurement->Handle = ModuleGuid;\r
447 } else {\r
448 Measurement->Token = ALit_START_IMAGE;\r
449 Measurement->Module = ALit_START_IMAGE;\r
450 }\r
451 }\r
115eae65
DB
452 }\r
453 break;\r
454\r
455 case FPDT_DYNAMIC_STRING_EVENT_TYPE:\r
456 ModuleGuid = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);\r
457 Measurement->Identifier = ((UINT32)((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);\r
458 if (IsStart) {\r
459 Measurement->StartTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;\r
460 } else {\r
461 Measurement->EndTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;\r
462 }\r
463 switch (Measurement->Identifier) {\r
464 case MODULE_START_ID:\r
465 case MODULE_END_ID:\r
466 if (mPeiPhase) {\r
467 Measurement->Token = ALit_PEIM;\r
468 } else if (mDxePhase) {\r
469 Measurement->Token = ALit_START_IMAGE;\r
470 }\r
471 break;\r
472\r
473 case MODULE_LOADIMAGE_START_ID:\r
474 case MODULE_LOADIMAGE_END_ID:\r
475 Measurement->Token = ALit_LOAD_IMAGE;\r
476 break;\r
477\r
478 case MODULE_DB_START_ID:\r
479 case MODULE_DB_END_ID:\r
480 Measurement->Token = ALit_DB_START;\r
481 break;\r
482\r
483 case MODULE_DB_SUPPORT_START_ID:\r
484 case MODULE_DB_SUPPORT_END_ID:\r
485 Measurement->Token = ALit_DB_SUPPORT;\r
486 break;\r
487\r
488 case MODULE_DB_STOP_START_ID:\r
489 case MODULE_DB_STOP_END_ID:\r
490 Measurement->Token = ALit_DB_STOP;\r
491 break;\r
492\r
493 default:\r
494 Measurement->Token = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;\r
495 break;\r
496 }\r
497\r
498 Measurement->Module = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;\r
499\r
f45dd2dd 500 if (Measurement->Token != NULL && AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {\r
115eae65
DB
501 Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);\r
502 } else {\r
503 GetHandleFormModuleGuid(ModuleGuid, &StartHandle);\r
504 Measurement->Handle = StartHandle;\r
f45dd2dd
BD
505 //\r
506 // When no perf entry to record the PEI and DXE phase,\r
507 // For start image, we need detect the PEIM and non PEIM here.\r
508 //\r
509 if (Measurement->Token == NULL && (Measurement->Identifier == MODULE_START_ID || Measurement->Identifier == MODULE_END_ID)) {\r
510 if (StartHandle == NULL && !IsZeroGuid (ModuleGuid)) {\r
511 Measurement->Token = ALit_PEIM;\r
512 Measurement->Handle = ModuleGuid;\r
513 } else {\r
514 Measurement->Token = ALit_START_IMAGE;\r
515 }\r
516 }\r
115eae65
DB
517 }\r
518 break;\r
519\r
520 case FPDT_GUID_QWORD_EVENT_TYPE:\r
521 ModuleGuid = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid);\r
522 Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->ProgressID);\r
523 if (IsStart) {\r
524 Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;\r
525 } else {\r
526 Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;\r
527 }\r
528 switch (Measurement->Identifier) {\r
529 case MODULE_DB_START_ID:\r
530 Measurement->Token = ALit_DB_START;\r
531 Measurement->Module = ALit_DB_START;\r
532 break;\r
533\r
534 case MODULE_DB_SUPPORT_START_ID:\r
535 case MODULE_DB_SUPPORT_END_ID:\r
536 Measurement->Token = ALit_DB_SUPPORT;\r
537 Measurement->Module = ALit_DB_SUPPORT;\r
538 break;\r
539\r
540 case MODULE_DB_STOP_START_ID:\r
541 case MODULE_DB_STOP_END_ID:\r
542 Measurement->Token = ALit_DB_STOP;\r
543 Measurement->Module = ALit_DB_STOP;\r
544 break;\r
545\r
546 case MODULE_LOADIMAGE_START_ID:\r
547 case MODULE_LOADIMAGE_END_ID:\r
548 Measurement->Token = ALit_LOAD_IMAGE;\r
549 Measurement->Module = ALit_LOAD_IMAGE;\r
550 break;\r
551\r
552 default:\r
553 ASSERT(FALSE);\r
554 }\r
555 GetHandleFormModuleGuid(ModuleGuid, &StartHandle);\r
556 Measurement->Handle = StartHandle;\r
557 break;\r
558\r
559 case FPDT_GUID_QWORD_STRING_EVENT_TYPE:\r
560 ModuleGuid = &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Guid);\r
561 Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);\r
562 if (IsStart) {\r
563 Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD*)RecordHeader)->Timestamp;\r
564 } else {\r
565 Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;\r
566 }\r
567 //\r
568 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.\r
569 //\r
570 switch (Measurement->Identifier) {\r
571 case MODULE_DB_END_ID:\r
572 Measurement->Token = ALit_DB_START;\r
573 Measurement->Module = ALit_DB_START;\r
574 break;\r
575 default:\r
576 ASSERT(FALSE);\r
577 }\r
578 GetHandleFormModuleGuid(ModuleGuid, &StartHandle);\r
579 Measurement->Handle = StartHandle;\r
580 break;\r
581\r
f45dd2dd
BD
582 case FPDT_DUAL_GUID_STRING_EVENT_TYPE:\r
583 ModuleGuid = &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Guid1);\r
584 Measurement->Identifier = ((UINT32)((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);\r
585 if (IsStart) {\r
586 Measurement->StartTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;\r
587 } else {\r
588 Measurement->EndTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;\r
589 }\r
590 Measurement->Token = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;\r
591 Measurement->Module = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;\r
592 GetHandleFormModuleGuid(ModuleGuid, &StartHandle);\r
593 Measurement->Handle = StartHandle;\r
594 break;\r
595\r
115eae65
DB
596 default:\r
597 break;\r
598 }\r
599}\r
600\r
601/**\r
602 Search the start measurement in the mMeasurementList for the end measurement.\r
603\r
604 @param EndMeasureMent Measurement for end record.\r
605\r
606**/\r
607VOID\r
608SearchMeasurement (\r
609 IN MEASUREMENT_RECORD *EndMeasureMent\r
610 )\r
611{\r
612 INTN Index;\r
613\r
614 for (Index = mMeasurementNum - 1; Index >= 0; Index--) {\r
615 if (AsciiStrCmp (EndMeasureMent->Token, ALit_PEIM) == 0) {\r
616 if (mMeasurementList[Index].EndTimeStamp == 0 && EndMeasureMent->Handle!= NULL && mMeasurementList[Index].Handle != NULL&&\r
617 CompareGuid(mMeasurementList[Index].Handle, EndMeasureMent->Handle) &&\r
618 (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&\r
619 (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) {\r
620 mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;\r
621 break;\r
622 }\r
f45dd2dd
BD
623 } else if (EndMeasureMent->Identifier == PERF_CROSSMODULE_END_ID) {\r
624 if (mMeasurementList[Index].EndTimeStamp == 0 &&\r
625 (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&\r
626 (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0) &&\r
627 mMeasurementList[Index].Identifier == PERF_CROSSMODULE_START_ID) {\r
628 mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;\r
629 break;\r
630 }\r
115eae65
DB
631 } else {\r
632 if (mMeasurementList[Index].EndTimeStamp == 0 && mMeasurementList[Index].Handle == EndMeasureMent->Handle &&\r
633 (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&\r
634 (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) {\r
635 mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;\r
636 break;\r
637 }\r
638 }\r
639 }\r
640}\r
641\r
642/**\r
643 Generate the measure record array.\r
644\r
645**/\r
646EFI_STATUS\r
647BuildMeasurementList (\r
648 )\r
649{\r
650 EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader;\r
651 UINT8 *PerformanceTablePtr;\r
652 UINT16 StartProgressId;\r
653 UINTN TableLength;\r
654 UINT8 *StartRecordEvent;\r
655 MEASUREMENT_RECORD MeasureMent;\r
656\r
657 mMeasurementList = AllocateZeroPool (mBootPerformanceTableSize);\r
658 if (mMeasurementList == NULL) {\r
659 return EFI_OUT_OF_RESOURCES;\r
660 }\r
661\r
662 TableLength = sizeof (BOOT_PERFORMANCE_TABLE);\r
663 PerformanceTablePtr = (mBootPerformanceTable + TableLength);\r
664\r
665 while (TableLength < mBootPerformanceTableSize) {\r
666 RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER*) PerformanceTablePtr;\r
667 StartRecordEvent = (UINT8 *)RecordHeader;\r
668 StartProgressId = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID;\r
669\r
670 //\r
f45dd2dd 671 // 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.\r
115eae65
DB
672 // If the record is the start record, fill the info to the measurement in the mMeasurementList.\r
673 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.\r
674 //\r
f45dd2dd
BD
675 if (StartProgressId == 0) {\r
676 GetMeasurementInfo (RecordHeader, FALSE, &(mMeasurementList[mMeasurementNum]));\r
677 mMeasurementNum ++;\r
678 } else if (((StartProgressId >= PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x000F) == 0)) ||\r
115eae65
DB
679 (StartProgressId < PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x0001) != 0)))) {\r
680 //\r
681 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE\r
682 // So we need to identify these two kinds of record through different phase.\r
683 //\r
f45dd2dd
BD
684 if(StartProgressId == PERF_CROSSMODULE_START_ID ){\r
685 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {\r
686 mPeiPhase = TRUE;\r
687 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {\r
688 mDxePhase = TRUE;\r
689 mPeiPhase = FALSE;\r
690 }\r
115eae65
DB
691 }\r
692 // Get measurement info form the start record to the mMeasurementList.\r
693 GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum]));\r
694 mMeasurementNum ++;\r
695 } else {\r
f45dd2dd 696 ZeroMem(&MeasureMent, sizeof(MEASUREMENT_RECORD));\r
115eae65
DB
697 GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent);\r
698 SearchMeasurement (&MeasureMent);\r
699 }\r
700 TableLength += RecordHeader->Length;\r
701 PerformanceTablePtr += RecordHeader->Length;\r
702 }\r
703 return EFI_SUCCESS;\r
704}\r
705\r
303ec9bc
CS
706/**\r
707 Initialize the cumulative data.\r
708\r
709**/\r
710VOID\r
711InitCumulativeData (\r
712 VOID\r
713 )\r
714{\r
715 UINTN Index;\r
716\r
717 for (Index = 0; Index < NumCum; ++Index) {\r
718 CumData[Index].Count = 0;\r
719 CumData[Index].MinDur = PERF_MAXDUR;\r
720 CumData[Index].MaxDur = 0;\r
721 CumData[Index].Duration = 0;\r
722 }\r
723}\r
724\r
d25cf17c
DB
725/**\r
726 Initialize the Summary data.\r
727\r
728**/\r
729VOID\r
730InitSummaryData (\r
731 VOID\r
732 )\r
733{\r
734 SummaryData.NumTrace = 0;\r
d25cf17c
DB
735 SummaryData.NumIncomplete = 0;\r
736 SummaryData.NumSummary = 0;\r
737 SummaryData.NumHandles = 0;\r
738 SummaryData.NumPEIMs = 0;\r
739 SummaryData.NumGlobal = 0;\r
740}\r
741\r
303ec9bc 742/**\r
d41bc92c 743 Dump performance data.\r
ba0014b9 744\r
d41bc92c 745 @param[in] ImageHandle The image handle.\r
746 @param[in] SystemTable The system table.\r
ba0014b9 747\r
196ccda0
CS
748 @retval SHELL_SUCCESS Command completed successfully.\r
749 @retval SHELL_INVALID_PARAMETER Command usage error.\r
750 @retval SHELL_ABORTED The user aborts the operation.\r
751 @retval value Unknown error.\r
d41bc92c 752**/\r
753SHELL_STATUS\r
92034c4c 754RunDp (\r
d41bc92c 755 IN EFI_HANDLE ImageHandle,\r
756 IN EFI_SYSTEM_TABLE *SystemTable\r
757 )\r
758{\r
759 LIST_ENTRY *ParamPackage;\r
760 CONST CHAR16 *CmdLineArg;\r
761 EFI_STATUS Status;\r
762\r
ef224032 763 PERFORMANCE_PROPERTY *PerformanceProperty;\r
d41bc92c 764 UINTN Number2Display;\r
765\r
a9b4ff8d
ED
766 EFI_STRING StringPtr;\r
767 BOOLEAN SummaryMode;\r
768 BOOLEAN VerboseMode;\r
769 BOOLEAN AllMode;\r
770 BOOLEAN RawMode;\r
a9b4ff8d 771 BOOLEAN ExcludeMode;\r
a06795c6
CS
772 BOOLEAN CumulativeMode;\r
773 CONST CHAR16 *CustomCumulativeToken;\r
774 PERF_CUM_DATA *CustomCumulativeData;\r
46213c8e 775 UINTN NameSize;\r
196ccda0 776 SHELL_STATUS ShellStatus;\r
115eae65 777 TIMER_INFO TimerInfo;\r
728f8950 778 UINT64 Intermediate;\r
a9b4ff8d
ED
779\r
780 StringPtr = NULL;\r
781 SummaryMode = FALSE;\r
782 VerboseMode = FALSE;\r
783 AllMode = FALSE;\r
784 RawMode = FALSE;\r
a9b4ff8d 785 ExcludeMode = FALSE;\r
a06795c6
CS
786 CumulativeMode = FALSE;\r
787 CustomCumulativeData = NULL;\r
196ccda0 788 ShellStatus = SHELL_SUCCESS;\r
d41bc92c 789\r
d41bc92c 790 //\r
791 // initialize the shell lib (we must be in non-auto-init...)\r
792 //\r
793 Status = ShellInitialize();\r
794 ASSERT_EFI_ERROR(Status);\r
795\r
d41bc92c 796 //\r
797 // Process Command Line arguments\r
798 //\r
799 Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);\r
800 if (EFI_ERROR(Status)) {\r
92034c4c 801 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), mDpHiiHandle);\r
d41bc92c 802 return SHELL_INVALID_PARAMETER;\r
728f8950
DB
803 } else if (ShellCommandLineGetCount(ParamPackage) > 1){\r
804 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_MANY), mDpHiiHandle);\r
805 return SHELL_INVALID_PARAMETER;\r
d41bc92c 806 }\r
807\r
808 //\r
809 // Boolean options\r
810 //\r
811 VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");\r
812 SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));\r
813 AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");\r
814 RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");\r
d41bc92c 815 ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");\r
816 mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");\r
a06795c6 817 CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");\r
d41bc92c 818\r
728f8950
DB
819 if (AllMode && RawMode) {\r
820 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CONFLICT_ARG), mDpHiiHandle, L"-A", L"-R");\r
821 return SHELL_INVALID_PARAMETER;\r
822 }\r
823\r
d41bc92c 824 // Options with Values\r
728f8950
DB
825 if (ShellCommandLineGetFlag (ParamPackage, L"-n")) {\r
826 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");\r
827 if (CmdLineArg == NULL) {\r
828 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);\r
829 return SHELL_INVALID_PARAMETER;\r
830 } else {\r
831 if (!(RawMode || AllMode)) {\r
832 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_NO_RAW_ALL), mDpHiiHandle);\r
833 return SHELL_INVALID_PARAMETER;\r
834 }\r
835 Status = ShellConvertStringToUint64(CmdLineArg, &Intermediate, FALSE, TRUE);\r
836 if (EFI_ERROR (Status)) {\r
837 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-n");\r
838 return SHELL_INVALID_PARAMETER;\r
839 } else {\r
840 Number2Display = (UINTN)Intermediate;\r
841 if (Number2Display == 0 || Number2Display > MAXIMUM_DISPLAYCOUNT) {\r
842 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_RANGE), mDpHiiHandle, L"-n", 0, MAXIMUM_DISPLAYCOUNT);\r
843 return SHELL_INVALID_PARAMETER;\r
844 }\r
845 }\r
d41bc92c 846 }\r
728f8950
DB
847 } else {\r
848 Number2Display = DEFAULT_DISPLAYCOUNT;\r
d41bc92c 849 }\r
850\r
728f8950
DB
851 if (ShellCommandLineGetFlag (ParamPackage, L"-t")) {\r
852 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");\r
853 if (CmdLineArg == NULL) {\r
854 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);\r
855 return SHELL_INVALID_PARAMETER;\r
856 } else {\r
857 Status = ShellConvertStringToUint64(CmdLineArg, &Intermediate, FALSE, TRUE);\r
858 if (EFI_ERROR (Status)) {\r
859 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-t");\r
860 return SHELL_INVALID_PARAMETER;\r
861 } else {\r
862 mInterestThreshold = Intermediate;\r
863 }\r
864 }\r
d41bc92c 865 } else {\r
728f8950 866 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us\r
d41bc92c 867 }\r
868\r
728f8950
DB
869 if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {\r
870 CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c");\r
871 if (CustomCumulativeToken == NULL) {\r
872 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);\r
873 return SHELL_INVALID_PARAMETER;\r
874 } else {\r
875 CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));\r
876 if (CustomCumulativeData == NULL) {\r
877 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
878 goto Done;\r
879 }\r
880 CustomCumulativeData->MinDur = PERF_MAXDUR;\r
881 CustomCumulativeData->MaxDur = 0;\r
882 CustomCumulativeData->Count = 0;\r
883 CustomCumulativeData->Duration = 0;\r
884 NameSize = StrLen (CustomCumulativeToken) + 1;\r
885 CustomCumulativeData->Name = AllocateZeroPool (NameSize);\r
886 if (CustomCumulativeData->Name == NULL) {\r
887 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
888 goto Done;\r
889 }\r
890 UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize);\r
891 }\r
892 }\r
d41bc92c 893\r
37d533da
DB
894 //\r
895 // DP dump performance data by parsing FPDT table in ACPI table.\r
896 // Folloing 3 steps are to get the measurement form the FPDT table.\r
897 //\r
898\r
899 //\r
900 //1. Get FPDT from ACPI table.\r
901 //\r
902 Status = GetBootPerformanceTable ();\r
903 if (EFI_ERROR (Status)) {\r
904 ShellStatus = Status;\r
905 goto Done;\r
906 }\r
907\r
908 //\r
909 //2. Cache the ModuleGuid and hanlde mapping table.\r
910 //\r
911 Status = BuildCachedGuidHandleTable();\r
912 if (EFI_ERROR (Status)) {\r
913 ShellStatus = Status;\r
914 goto Done;\r
915 }\r
916\r
917 //\r
918 //3. Build the measurement array form the FPDT records.\r
919 //\r
920 Status = BuildMeasurementList ();\r
921 if (EFI_ERROR (Status)) {\r
922 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
923 goto Done;\r
924 }\r
925\r
303ec9bc
CS
926 //\r
927 // Initialize the pre-defined cumulative data.\r
928 //\r
929 InitCumulativeData ();\r
930\r
d25cf17c
DB
931 //\r
932 // Initialize the Summary data.\r
933 //\r
934 InitSummaryData ();\r
935\r
d41bc92c 936 //\r
937 // Timer specific processing\r
938 //\r
939 // Get the Performance counter characteristics:\r
940 // Freq = Frequency in Hz\r
941 // StartCount = Value loaded into the counter when it starts counting\r
942 // EndCount = Value counter counts to before it needs to be reset\r
943 //\r
37322be5 944 Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **) &PerformanceProperty);\r
24c6962d 945 if (EFI_ERROR (Status) || (PerformanceProperty == NULL)) {\r
92034c4c 946 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND), mDpHiiHandle);\r
ef224032
SZ
947 goto Done;\r
948 }\r
d41bc92c 949\r
ef224032 950 TimerInfo.Frequency = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000);\r
115eae65
DB
951 TimerInfo.StartCount = 0;\r
952 TimerInfo.EndCount = 0xFFFF;\r
953 TimerInfo.CountUp = TRUE;\r
d41bc92c 954\r
955 //\r
956 // Print header\r
957 //\r
958 // print DP's build version\r
92034c4c 959 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), mDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);\r
d41bc92c 960\r
961 // print performance timer characteristics\r
92034c4c 962 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), mDpHiiHandle, TimerInfo.Frequency);\r
d41bc92c 963\r
964 if (VerboseMode && !RawMode) {\r
92034c4c 965 StringPtr = HiiGetString (mDpHiiHandle,\r
d41bc92c 966 (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), NULL);\r
967 ASSERT (StringPtr != NULL);\r
968 // Print Timer count range and direction\r
92034c4c 969 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TIMER_PROPERTIES), mDpHiiHandle,\r
d41bc92c 970 StringPtr,\r
971 TimerInfo.StartCount,\r
972 TimerInfo.EndCount\r
973 );\r
92034c4c 974 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mDpHiiHandle, mInterestThreshold);\r
d41bc92c 975 }\r
976\r
977/****************************************************************************\r
978**** Print Sections based on command line options\r
979****\r
980**** Option modes have the following priority:\r
981**** v Verbose -- Valid in combination with any other options\r
982**** t Threshold -- Modifies All, Raw, and Cooked output\r
983**** Default is 0 for All and Raw mode\r
984**** Default is DEFAULT_THRESHOLD for "Cooked" mode\r
985**** n Number2Display Used by All and Raw mode. Otherwise ignored.\r
986**** A All -- R and S options are ignored\r
987**** R Raw -- S option is ignored\r
988**** s Summary -- Modifies "Cooked" output only\r
989**** Cooked (Default)\r
d41bc92c 990****************************************************************************/\r
a06795c6 991 GatherStatistics (CustomCumulativeData);\r
ba0014b9 992 if (CumulativeMode) {\r
a06795c6
CS
993 ProcessCumulative (CustomCumulativeData);\r
994 } else if (AllMode) {\r
5a56c049
DB
995 Status = DumpAllTrace( Number2Display, ExcludeMode);\r
996 if (Status == EFI_ABORTED) {\r
997 ShellStatus = SHELL_ABORTED;\r
998 goto Done;\r
999 }\r
1000 } else if (RawMode) {\r
1001 Status = DumpRawTrace( Number2Display, ExcludeMode);\r
1002 if (Status == EFI_ABORTED) {\r
1003 ShellStatus = SHELL_ABORTED;\r
1004 goto Done;\r
1005 }\r
1006 } else {\r
1007 //------------- Begin Cooked Mode Processing\r
1008 ProcessPhases ();\r
1009 if ( ! SummaryMode) {\r
1010 Status = ProcessHandles ( ExcludeMode);\r
196ccda0
CS
1011 if (Status == EFI_ABORTED) {\r
1012 ShellStatus = SHELL_ABORTED;\r
1013 goto Done;\r
1014 }\r
5a56c049
DB
1015\r
1016 Status = ProcessPeims ();\r
196ccda0
CS
1017 if (Status == EFI_ABORTED) {\r
1018 ShellStatus = SHELL_ABORTED;\r
1019 goto Done;\r
1020 }\r
5a56c049
DB
1021\r
1022 Status = ProcessGlobal ();\r
1023 if (Status == EFI_ABORTED) {\r
1024 ShellStatus = SHELL_ABORTED;\r
1025 goto Done;\r
d41bc92c 1026 }\r
5a56c049
DB
1027\r
1028 ProcessCumulative (NULL);\r
d41bc92c 1029 }\r
1030 } //------------- End of Cooked Mode Processing\r
1031 if ( VerboseMode || SummaryMode) {\r
1032 DumpStatistics();\r
1033 }\r
1034\r
196ccda0 1035Done:\r
3751a092
CS
1036 if (ParamPackage != NULL) {\r
1037 ShellCommandLineFreeVarList (ParamPackage);\r
1038 }\r
d41bc92c 1039 SHELL_FREE_NON_NULL (StringPtr);\r
a06795c6
CS
1040 if (CustomCumulativeData != NULL) {\r
1041 SHELL_FREE_NON_NULL (CustomCumulativeData->Name);\r
1042 }\r
1043 SHELL_FREE_NON_NULL (CustomCumulativeData);\r
d41bc92c 1044\r
115eae65
DB
1045 SHELL_FREE_NON_NULL (mMeasurementList);\r
1046\r
1047 SHELL_FREE_NON_NULL (mCacheHandleGuidTable);\r
1048\r
1049 mMeasurementNum = 0;\r
1050 mCachePairCount = 0;\r
196ccda0 1051 return ShellStatus;\r
d41bc92c 1052}\r
92034c4c
RN
1053\r
1054\r
1055/**\r
1056 Retrive HII package list from ImageHandle and publish to HII database.\r
1057\r
1058 @param ImageHandle The image handle of the process.\r
1059\r
1060 @return HII handle.\r
1061**/\r
1062EFI_HANDLE\r
1063InitializeHiiPackage (\r
1064 EFI_HANDLE ImageHandle\r
1065 )\r
1066{\r
1067 EFI_STATUS Status;\r
1068 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
1069 EFI_HANDLE HiiHandle;\r
1070\r
1071 //\r
1072 // Retrieve HII package list from ImageHandle\r
1073 //\r
1074 Status = gBS->OpenProtocol (\r
1075 ImageHandle,\r
1076 &gEfiHiiPackageListProtocolGuid,\r
1077 (VOID **)&PackageList,\r
1078 ImageHandle,\r
1079 NULL,\r
1080 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1081 );\r
1082 ASSERT_EFI_ERROR (Status);\r
1083 if (EFI_ERROR (Status)) {\r
1084 return NULL;\r
1085 }\r
1086\r
1087 //\r
1088 // Publish HII package list to HII Database.\r
1089 //\r
1090 Status = gHiiDatabase->NewPackageList (\r
1091 gHiiDatabase,\r
1092 PackageList,\r
1093 NULL,\r
1094 &HiiHandle\r
1095 );\r
1096 ASSERT_EFI_ERROR (Status);\r
1097 if (EFI_ERROR (Status)) {\r
1098 return NULL;\r
1099 }\r
1100 return HiiHandle;\r
1101}\r