]> git.proxmox.com Git - mirror_edk2.git/blob - PerformancePkg/Dp_App/Dp.c
PerformancePkg Dp_App: Delete InitCumulativeData()
[mirror_edk2.git] / PerformancePkg / Dp_App / Dp.c
1 /** @file
2 Shell application for Displaying Performance Metrics.
3
4 The Dp application reads performance data and presents it in several
5 different formats depending upon the needs of the user. Both
6 Trace and Measured Profiling information is processed and presented.
7
8 Dp uses the "PerformanceLib" to read the measurement records.
9 The "TimerLib" provides information about the timer, such as frequency,
10 beginning, and ending counter values.
11 Measurement records contain identifying information (Handle, Token, Module)
12 and start and end time values.
13 Dp uses this information to group records in different ways. It also uses
14 timer information to calculate elapsed time for each measurement.
15
16 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
17 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
18 This program and the accompanying materials
19 are licensed and made available under the terms and conditions of the BSD License
20 which accompanies this distribution. The full text of the license may be found at
21 http://opensource.org/licenses/bsd-license.php
22
23 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
24 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 **/
26
27 #include <Library/UefiApplicationEntryPoint.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/ShellLib.h>
30 #include <Library/BaseLib.h>
31 #include <Library/MemoryAllocationLib.h>
32 #include <Library/DebugLib.h>
33 #include <Library/TimerLib.h>
34 #include <Library/UefiLib.h>
35 #include <Library/UefiHiiServicesLib.h>
36 #include <Library/HiiLib.h>
37 #include <Library/PcdLib.h>
38
39 #include <Guid/Performance.h>
40
41 #include <PerformanceTokens.h>
42 #include "Dp.h"
43 #include "Literals.h"
44 #include "DpInternal.h"
45
46 //
47 // String token ID of help message text.
48 // Shell supports to find help message in the resource section of an application image if
49 // .MAN file is not found. This global variable is added to make build tool recognizes
50 // that the help string is consumed by user and then build tool will add the string into
51 // the resource section. Thus the application can use '-?' option to show help message in
52 // Shell.
53 //
54 GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mDpStrEngHelpTokenId = STRING_TOKEN (STR_DP_HELP_INFORMATION);
55
56 //
57 /// Module-Global Variables
58 ///@{
59 EFI_HII_HANDLE gHiiHandle;
60 SHELL_PARAM_ITEM *DpParamList = NULL;
61 CHAR16 *mPrintTokenBuffer = NULL;
62 CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
63 CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
64 UINT64 mInterestThreshold;
65 BOOLEAN mShowId = FALSE;
66
67 PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
68
69 /// Timer Specific Information.
70 TIMER_INFO TimerInfo;
71
72 /// Items for which to gather cumulative statistics.
73 PERF_CUM_DATA CumData[] = {
74 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),
75 PERF_INIT_CUM_DATA (START_IMAGE_TOK),
76 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),
77 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK)
78 };
79
80 /// Number of items for which we are gathering cumulative statistics.
81 UINT32 const NumCum = sizeof(CumData) / sizeof(PERF_CUM_DATA);
82
83 PARAM_ITEM_LIST ParamList[] = {
84 {STRING_TOKEN (STR_DP_OPTION_QH), TypeFlag}, // -? Help
85 {STRING_TOKEN (STR_DP_OPTION_LH), TypeFlag}, // -h Help
86 {STRING_TOKEN (STR_DP_OPTION_UH), TypeFlag}, // -H Help
87 {STRING_TOKEN (STR_DP_OPTION_LV), TypeFlag}, // -v Verbose Mode
88 {STRING_TOKEN (STR_DP_OPTION_UA), TypeFlag}, // -A All, Cooked
89 {STRING_TOKEN (STR_DP_OPTION_UR), TypeFlag}, // -R RAW All
90 {STRING_TOKEN (STR_DP_OPTION_LS), TypeFlag}, // -s Summary
91 #if PROFILING_IMPLEMENTED
92 {STRING_TOKEN (STR_DP_OPTION_UP), TypeFlag}, // -P Dump Profile Data
93 {STRING_TOKEN (STR_DP_OPTION_UT), TypeFlag}, // -T Dump Trace Data
94 #endif
95 {STRING_TOKEN (STR_DP_OPTION_LX), TypeFlag}, // -x eXclude Cumulative Items
96 {STRING_TOKEN (STR_DP_OPTION_LI), TypeFlag}, // -i Display Identifier
97 {STRING_TOKEN (STR_DP_OPTION_LC), TypeValue}, // -c Display cumulative data.
98 {STRING_TOKEN (STR_DP_OPTION_LN), TypeValue}, // -n # Number of records to display for A and R
99 {STRING_TOKEN (STR_DP_OPTION_LT), TypeValue} // -t # Threshold of interest
100 };
101
102 ///@}
103
104 /**
105 Transfer the param list value and get the command line parse.
106
107 **/
108 VOID
109 InitialShellParamList( void )
110 {
111 UINT32 ListIndex;
112 UINT32 ListLength;
113
114 //
115 // Allocate one more for the end tag.
116 //
117 ListLength = sizeof (ParamList) / sizeof (ParamList[0]) + 1;
118 DpParamList = AllocatePool (sizeof (SHELL_PARAM_ITEM) * ListLength);
119 ASSERT (DpParamList != NULL);
120
121 for (ListIndex = 0; ListIndex < ListLength - 1; ListIndex ++)
122 {
123 DpParamList[ListIndex].Name = HiiGetString (gHiiHandle, ParamList[ListIndex].Token, NULL);
124 DpParamList[ListIndex].Type = ParamList[ListIndex].Type;
125 }
126 DpParamList[ListIndex].Name = NULL;
127 DpParamList[ListIndex].Type = TypeMax;
128 }
129
130 /**
131 Display Usage and Help information.
132 **/
133 VOID
134 ShowHelp( void )
135 {
136 PrintToken (STRING_TOKEN (STR_DP_HELP_HEAD));
137 #if PROFILING_IMPLEMENTED
138 PrintToken (STRING_TOKEN (STR_DP_HELP_FLAGS));
139 #else
140 PrintToken (STRING_TOKEN (STR_DP_HELP_FLAGS_2));
141 #endif // PROFILING_IMPLEMENTED
142 PrintToken (STRING_TOKEN (STR_DP_HELP_PAGINATE));
143 PrintToken (STRING_TOKEN (STR_DP_HELP_VERBOSE));
144 PrintToken (STRING_TOKEN (STR_DP_HELP_EXCLUDE));
145 PrintToken (STRING_TOKEN (STR_DP_HELP_STAT));
146 PrintToken (STRING_TOKEN (STR_DP_HELP_ALL));
147 PrintToken (STRING_TOKEN (STR_DP_HELP_RAW));
148 #if PROFILING_IMPLEMENTED
149 PrintToken (STRING_TOKEN (STR_DP_HELP_TRACE));
150 PrintToken (STRING_TOKEN (STR_DP_HELP_PROFILE));
151 #endif // PROFILING_IMPLEMENTED
152 PrintToken (STRING_TOKEN (STR_DP_HELP_THRESHOLD));
153 PrintToken (STRING_TOKEN (STR_DP_HELP_COUNT));
154 PrintToken (STRING_TOKEN (STR_DP_HELP_ID));
155 PrintToken (STRING_TOKEN (STR_DP_HELP_CUM_DATA));
156 PrintToken (STRING_TOKEN (STR_DP_HELP_HELP));
157 Print(L"\n");
158 }
159
160 /**
161 Display the trailing Verbose information.
162 **/
163 VOID
164 DumpStatistics( void )
165 {
166 EFI_STRING StringPtr;
167 EFI_STRING StringPtrUnknown;
168 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
169 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
170 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
171 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
172
173 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMTRACE), SummaryData.NumTrace);
174 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), SummaryData.NumIncomplete);
175 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPHASES), SummaryData.NumSummary);
176 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMHANDLES), SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);
177 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPEIMS), SummaryData.NumPEIMs);
178 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), SummaryData.NumGlobal);
179 #if PROFILING_IMPLEMENTED
180 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPROFILE), SummaryData.NumProfile);
181 #endif // PROFILING_IMPLEMENTED
182 FreePool (StringPtr);
183 FreePool (StringPtrUnknown);
184 }
185
186 /**
187 Dump performance data.
188
189 @param[in] ImageHandle The image handle.
190 @param[in] SystemTable The system table.
191
192 @retval EFI_SUCCESS Command completed successfully.
193 @retval EFI_INVALID_PARAMETER Command usage error.
194 @retval EFI_ABORTED The user aborts the operation.
195 @retval value Unknown error.
196 **/
197 EFI_STATUS
198 EFIAPI
199 InitializeDp (
200 IN EFI_HANDLE ImageHandle,
201 IN EFI_SYSTEM_TABLE *SystemTable
202 )
203 {
204 UINT64 Freq;
205 UINT64 Ticker;
206 UINT32 ListIndex;
207
208 LIST_ENTRY *ParamPackage;
209 CONST CHAR16 *CmdLineArg;
210 EFI_STRING StringPtr;
211 UINTN Number2Display;
212
213 EFI_STATUS Status;
214 BOOLEAN SummaryMode;
215 BOOLEAN VerboseMode;
216 BOOLEAN AllMode;
217 BOOLEAN RawMode;
218 BOOLEAN TraceMode;
219 BOOLEAN ProfileMode;
220 BOOLEAN ExcludeMode;
221 BOOLEAN CumulativeMode;
222 CONST CHAR16 *CustomCumulativeToken;
223 PERF_CUM_DATA *CustomCumulativeData;
224 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
225
226 EFI_STRING StringDpOptionQh;
227 EFI_STRING StringDpOptionLh;
228 EFI_STRING StringDpOptionUh;
229 EFI_STRING StringDpOptionLv;
230 EFI_STRING StringDpOptionUs;
231 EFI_STRING StringDpOptionLs;
232 EFI_STRING StringDpOptionUa;
233 EFI_STRING StringDpOptionUr;
234 EFI_STRING StringDpOptionUt;
235 EFI_STRING StringDpOptionUp;
236 EFI_STRING StringDpOptionLx;
237 EFI_STRING StringDpOptionLn;
238 EFI_STRING StringDpOptionLt;
239 EFI_STRING StringDpOptionLi;
240 EFI_STRING StringDpOptionLc;
241
242 SummaryMode = FALSE;
243 VerboseMode = FALSE;
244 AllMode = FALSE;
245 RawMode = FALSE;
246 TraceMode = FALSE;
247 ProfileMode = FALSE;
248 ExcludeMode = FALSE;
249 CumulativeMode = FALSE;
250 CustomCumulativeData = NULL;
251
252 StringDpOptionQh = NULL;
253 StringDpOptionLh = NULL;
254 StringDpOptionUh = NULL;
255 StringDpOptionLv = NULL;
256 StringDpOptionUs = NULL;
257 StringDpOptionLs = NULL;
258 StringDpOptionUa = NULL;
259 StringDpOptionUr = NULL;
260 StringDpOptionUt = NULL;
261 StringDpOptionUp = NULL;
262 StringDpOptionLx = NULL;
263 StringDpOptionLn = NULL;
264 StringDpOptionLt = NULL;
265 StringDpOptionLi = NULL;
266 StringDpOptionLc = NULL;
267 StringPtr = NULL;
268
269 // Get DP's entry time as soon as possible.
270 // This is used as the Shell-Phase end time.
271 //
272 Ticker = GetPerformanceCounter ();
273
274 //
275 // Retrieve HII package list from ImageHandle
276 //
277 Status = gBS->OpenProtocol (
278 ImageHandle,
279 &gEfiHiiPackageListProtocolGuid,
280 (VOID **) &PackageList,
281 ImageHandle,
282 NULL,
283 EFI_OPEN_PROTOCOL_GET_PROTOCOL
284 );
285 if (EFI_ERROR (Status)) {
286 return Status;
287 }
288
289 //
290 // Publish HII package list to HII Database.
291 //
292 Status = gHiiDatabase->NewPackageList (
293 gHiiDatabase,
294 PackageList,
295 NULL,
296 &gHiiHandle
297 );
298 if (EFI_ERROR (Status)) {
299 return Status;
300 }
301 ASSERT (gHiiHandle != NULL);
302
303
304 // Initial the command list
305 //
306 InitialShellParamList ();
307
308 /****************************************************************************
309 **** Process Command Line arguments ****
310 ****************************************************************************/
311 Status = ShellCommandLineParse (DpParamList, &ParamPackage, NULL, TRUE);
312
313 if (EFI_ERROR(Status)) {
314 PrintToken (STRING_TOKEN (STR_DP_INVALID_ARG));
315 ShowHelp();
316 }
317 else {
318 StringDpOptionQh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_QH), NULL);
319 StringDpOptionLh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LH), NULL);
320 StringDpOptionUh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UH), NULL);
321
322 if (ShellCommandLineGetFlag (ParamPackage, StringDpOptionQh) ||
323 ShellCommandLineGetFlag (ParamPackage, StringDpOptionLh) ||
324 ShellCommandLineGetFlag (ParamPackage, StringDpOptionUh))
325 {
326 ShowHelp();
327 }
328 else {
329 StringDpOptionLv = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LV), NULL);
330 StringDpOptionUs = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_US), NULL);
331 StringDpOptionLs = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LS), NULL);
332 StringDpOptionUa = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UA), NULL);
333 StringDpOptionUr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UR), NULL);
334 StringDpOptionUt = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UT), NULL);
335 StringDpOptionUp = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UP), NULL);
336 StringDpOptionLx = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LX), NULL);
337 StringDpOptionLn = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LN), NULL);
338 StringDpOptionLt = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LT), NULL);
339 StringDpOptionLi = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LI), NULL);
340 StringDpOptionLc = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LC), NULL);
341
342 // Boolean Options
343 //
344 VerboseMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLv);
345 SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, StringDpOptionUs) ||
346 ShellCommandLineGetFlag (ParamPackage, StringDpOptionLs));
347 AllMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUa);
348 RawMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUr);
349 #if PROFILING_IMPLEMENTED
350 TraceMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUt);
351 ProfileMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUp);
352 #endif // PROFILING_IMPLEMENTED
353 ExcludeMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLx);
354 mShowId = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLi);
355 CumulativeMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLc);
356
357 // Options with Values
358 CmdLineArg = ShellCommandLineGetValue (ParamPackage, StringDpOptionLn);
359 if (CmdLineArg == NULL) {
360 Number2Display = DEFAULT_DISPLAYCOUNT;
361 }
362 else {
363 Number2Display = StrDecimalToUintn(CmdLineArg);
364 if (Number2Display == 0) {
365 Number2Display = MAXIMUM_DISPLAYCOUNT;
366 }
367 }
368 CmdLineArg = ShellCommandLineGetValue (ParamPackage, StringDpOptionLt);
369 if (CmdLineArg == NULL) {
370 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
371 }
372 else {
373 mInterestThreshold = StrDecimalToUint64(CmdLineArg);
374 }
375 // Handle Flag combinations and default behaviors
376 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE
377 if ((! TraceMode) && (! ProfileMode)) {
378 TraceMode = TRUE;
379 #if PROFILING_IMPLEMENTED
380 ProfileMode = TRUE;
381 #endif // PROFILING_IMPLEMENTED
382 }
383
384 //
385 // Init the custom cumulative data.
386 //
387 CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, StringDpOptionLc);
388 if (CustomCumulativeToken != NULL) {
389 CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));
390 ASSERT (CustomCumulativeData != NULL);
391 CustomCumulativeData->MinDur = 0;
392 CustomCumulativeData->MaxDur = 0;
393 CustomCumulativeData->Count = 0;
394 CustomCumulativeData->Duration = 0;
395 CustomCumulativeData->Name = AllocateZeroPool (StrLen (CustomCumulativeToken) + 1);
396 UnicodeStrToAsciiStr (CustomCumulativeToken, CustomCumulativeData->Name);
397 }
398
399 /****************************************************************************
400 **** Timer specific processing ****
401 ****************************************************************************/
402 // Get the Performance counter characteristics:
403 // Freq = Frequency in Hz
404 // StartCount = Value loaded into the counter when it starts counting
405 // EndCount = Value counter counts to before it needs to be reset
406 //
407 Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);
408
409 // Convert the Frequency from Hz to KHz
410 TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);
411
412 // Determine in which direction the performance counter counts.
413 TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);
414
415 /****************************************************************************
416 **** Print heading ****
417 ****************************************************************************/
418 // print DP's build version
419 PrintToken (STRING_TOKEN (STR_DP_BUILD_REVISION), DP_MAJOR_VERSION, DP_MINOR_VERSION);
420
421 // print performance timer characteristics
422 PrintToken (STRING_TOKEN (STR_DP_KHZ), TimerInfo.Frequency); // Print Timer frequency in KHz
423
424 if ((VerboseMode) &&
425 (! RawMode)
426 ) {
427 StringPtr = HiiGetString (gHiiHandle,
428 (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)),
429 NULL);
430 ASSERT (StringPtr != NULL);
431 PrintToken (STRING_TOKEN (STR_DP_TIMER_PROPERTIES), // Print Timer count range and direction
432 StringPtr,
433 TimerInfo.StartCount,
434 TimerInfo.EndCount
435 );
436 PrintToken (STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mInterestThreshold);
437 }
438
439 /* **************************************************************************
440 **** Print Sections based on command line options
441 ****
442 **** Option modes have the following priority:
443 **** v Verbose -- Valid in combination with any other options
444 **** t Threshold -- Modifies All, Raw, and Cooked output
445 **** Default is 0 for All and Raw mode
446 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
447 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
448 **** A All -- R and S options are ignored
449 **** R Raw -- S option is ignored
450 **** s Summary -- Modifies "Cooked" output only
451 **** Cooked (Default)
452 ****
453 **** The All, Raw, and Cooked modes are modified by the Trace and Profile
454 **** options.
455 **** !T && !P := (0) Default, Both are displayed
456 **** T && !P := (1) Only Trace records are displayed
457 **** !T && P := (2) Only Profile records are displayed
458 **** T && P := (3) Same as Default, both are displayed
459 ****************************************************************************/
460 GatherStatistics (CustomCumulativeData);
461 if (CumulativeMode) {
462 ProcessCumulative (CustomCumulativeData);
463 } else if (AllMode) {
464 if (TraceMode) {
465 Status = DumpAllTrace( Number2Display, ExcludeMode);
466 if (Status == EFI_ABORTED) {
467 goto Done;
468 }
469 }
470 if (ProfileMode) {
471 DumpAllProfile( Number2Display, ExcludeMode);
472 }
473 }
474 else if (RawMode) {
475 if (TraceMode) {
476 Status = DumpRawTrace( Number2Display, ExcludeMode);
477 if (Status == EFI_ABORTED) {
478 goto Done;
479 }
480 }
481 if (ProfileMode) {
482 DumpRawProfile( Number2Display, ExcludeMode);
483 }
484 }
485 else {
486 //------------- Begin Cooked Mode Processing
487 if (TraceMode) {
488 ProcessPhases ( Ticker );
489 if ( ! SummaryMode) {
490 Status = ProcessHandles ( ExcludeMode);
491 if (Status == EFI_ABORTED) {
492 goto Done;
493 }
494
495 Status = ProcessPeims ();
496 if (Status == EFI_ABORTED) {
497 goto Done;
498 }
499
500 Status = ProcessGlobal ();
501 if (Status == EFI_ABORTED) {
502 goto Done;
503 }
504
505 ProcessCumulative (NULL);
506 }
507 }
508 if (ProfileMode) {
509 DumpAllProfile( Number2Display, ExcludeMode);
510 }
511 } //------------- End of Cooked Mode Processing
512 if ( VerboseMode || SummaryMode) {
513 DumpStatistics();
514 }
515 }
516 }
517
518 Done:
519
520 //
521 // Free the memory allocate from HiiGetString
522 //
523 ListIndex = 0;
524 while (DpParamList[ListIndex].Name != NULL) {
525 FreePool (DpParamList[ListIndex].Name);
526 ListIndex ++;
527 }
528 FreePool (DpParamList);
529
530 SafeFreePool (StringDpOptionQh);
531 SafeFreePool (StringDpOptionLh);
532 SafeFreePool (StringDpOptionUh);
533 SafeFreePool (StringDpOptionLv);
534 SafeFreePool (StringDpOptionUs);
535 SafeFreePool (StringDpOptionLs);
536 SafeFreePool (StringDpOptionUa);
537 SafeFreePool (StringDpOptionUr);
538 SafeFreePool (StringDpOptionUt);
539 SafeFreePool (StringDpOptionUp);
540 SafeFreePool (StringDpOptionLx);
541 SafeFreePool (StringDpOptionLn);
542 SafeFreePool (StringDpOptionLt);
543 SafeFreePool (StringDpOptionLi);
544 SafeFreePool (StringDpOptionLc);
545 SafeFreePool (StringPtr);
546 SafeFreePool (mPrintTokenBuffer);
547
548 if (ParamPackage != NULL) {
549 ShellCommandLineFreeVarList (ParamPackage);
550 }
551 if (CustomCumulativeData != NULL) {
552 SafeFreePool (CustomCumulativeData->Name);
553 }
554 SafeFreePool (CustomCumulativeData);
555
556 HiiRemovePackages (gHiiHandle);
557 return Status;
558 }