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