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