]>
Commit | Line | Data |
---|---|---|
a642e2b4 SZ |
1 | /** @file\r |
2 | A shell application to dump dynamic PCD settings.\r | |
3 | \r | |
4 | Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r | |
5 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
6 | \r | |
7 | **/\r | |
8 | \r | |
9 | #include <Uefi.h>\r | |
10 | #include <PiDxe.h>\r | |
11 | #include <Library/BaseLib.h>\r | |
12 | #include <Library/DebugLib.h>\r | |
13 | #include <Library/MemoryAllocationLib.h>\r | |
14 | #include <Library/UefiBootServicesTableLib.h>\r | |
15 | #include <Library/UefiLib.h>\r | |
16 | \r | |
17 | \r | |
18 | #include <Protocol/UnicodeCollation.h>\r | |
19 | #include <Protocol/PiPcd.h>\r | |
20 | #include <Protocol/Pcd.h>\r | |
21 | #include <Protocol/PiPcdInfo.h>\r | |
22 | #include <Protocol/PcdInfo.h>\r | |
23 | #include <Protocol/ShellParameters.h>\r | |
24 | #include <Protocol/Shell.h>\r | |
25 | \r | |
26 | \r | |
27 | //\r | |
28 | // String token ID of help message text.\r | |
29 | // Shell supports to find help message in the resource section of an application image if\r | |
30 | // .MAN file is not found. This global variable is added to make build tool recognizes\r | |
31 | // that the help string is consumed by user and then build tool will add the string into\r | |
32 | // the resource section. Thus the application can use '-?' option to show help message in\r | |
33 | // Shell.\r | |
34 | //\r | |
35 | GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStrDumpDynPcdHelpTokenId = STRING_TOKEN (STR_DUMP_DYN_PCD_HELP_INFORMATION);\r | |
36 | \r | |
37 | #define MAJOR_VERSION 1\r | |
38 | #define MINOR_VERSION 0\r | |
39 | \r | |
40 | static EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r | |
41 | static EFI_PCD_PROTOCOL *mPiPcd = NULL;\r | |
42 | static PCD_PROTOCOL *mPcd = NULL;\r | |
43 | static EFI_GET_PCD_INFO_PROTOCOL *mPiPcdInfo = NULL;\r | |
44 | static GET_PCD_INFO_PROTOCOL *mPcdInfo = NULL;\r | |
45 | static CHAR16 *mTempPcdNameBuffer = NULL;\r | |
46 | static UINTN mTempPcdNameBufferSize = 0;\r | |
47 | \r | |
48 | static CONST CHAR8 mHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};\r | |
49 | \r | |
50 | static UINTN Argc;\r | |
51 | static CHAR16 **Argv;\r | |
52 | \r | |
53 | \r | |
54 | /**\r | |
55 | \r | |
56 | This function parse application ARG.\r | |
57 | \r | |
58 | @return Status\r | |
59 | **/\r | |
60 | static\r | |
61 | EFI_STATUS\r | |
62 | GetArg (\r | |
63 | VOID\r | |
64 | )\r | |
65 | {\r | |
66 | EFI_STATUS Status;\r | |
67 | EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;\r | |
68 | \r | |
69 | Status = gBS->HandleProtocol (\r | |
70 | gImageHandle,\r | |
71 | &gEfiShellParametersProtocolGuid,\r | |
72 | (VOID**)&ShellParameters\r | |
73 | );\r | |
74 | if (EFI_ERROR(Status)) {\r | |
75 | return Status;\r | |
76 | }\r | |
77 | \r | |
78 | Argc = ShellParameters->Argc;\r | |
79 | Argv = ShellParameters->Argv;\r | |
80 | return EFI_SUCCESS;\r | |
81 | }\r | |
82 | \r | |
83 | /**\r | |
84 | Display current version.\r | |
85 | **/\r | |
86 | static\r | |
87 | VOID\r | |
88 | ShowVersion (\r | |
89 | )\r | |
90 | {\r | |
91 | Print (L"DumpDynPcd Version %d.%02d\n", MAJOR_VERSION, MINOR_VERSION);\r | |
92 | }\r | |
93 | \r | |
94 | /**\r | |
95 | Display Usage and Help information.\r | |
96 | **/\r | |
97 | static\r | |
98 | VOID\r | |
99 | ShowHelp (\r | |
100 | )\r | |
101 | {\r | |
102 | Print (L"Dump dynamic[ex] PCD info.\n");\r | |
103 | Print (L"\n");\r | |
104 | Print (L"DumpDynPcd [PcdName]\n");\r | |
105 | Print (L"\n");\r | |
106 | Print (L" PcdName Specifies the name of PCD.\n");\r | |
107 | Print (L" A literal[or partial] name or a pattern as specified in\n");\r | |
108 | Print (L" the MetaiMatch() function of the EFI_UNICODE_COLLATION2_PROCOOL.\n");\r | |
109 | Print (L" If it is absent, dump all PCDs' info.\n");\r | |
110 | Print (L"The PCD data is printed as hexadecimal dump.\n");\r | |
111 | }\r | |
112 | \r | |
113 | /**\r | |
114 | Dump some hexadecimal data to the screen.\r | |
115 | \r | |
116 | @param[in] Indent How many spaces to indent the output.\r | |
117 | @param[in] Offset The offset of the printing.\r | |
118 | @param[in] DataSize The size in bytes of UserData.\r | |
119 | @param[in] UserData The data to print out.\r | |
120 | **/\r | |
121 | static\r | |
122 | VOID\r | |
123 | DumpHex (\r | |
124 | IN UINTN Indent,\r | |
125 | IN UINTN Offset,\r | |
126 | IN UINTN DataSize,\r | |
127 | IN VOID *UserData\r | |
128 | )\r | |
129 | {\r | |
130 | UINT8 *Data;\r | |
131 | \r | |
132 | CHAR8 Val[50];\r | |
133 | \r | |
134 | CHAR8 Str[20];\r | |
135 | \r | |
136 | UINT8 TempByte;\r | |
137 | UINTN Size;\r | |
138 | UINTN Index;\r | |
139 | \r | |
140 | Data = UserData;\r | |
141 | while (DataSize != 0) {\r | |
142 | Size = 16;\r | |
143 | if (Size > DataSize) {\r | |
144 | Size = DataSize;\r | |
145 | }\r | |
146 | \r | |
147 | for (Index = 0; Index < Size; Index += 1) {\r | |
148 | TempByte = Data[Index];\r | |
149 | Val[Index * 3 + 0] = mHex[TempByte >> 4];\r | |
150 | Val[Index * 3 + 1] = mHex[TempByte & 0xF];\r | |
151 | Val[Index * 3 + 2] = (CHAR8) ((Index == 7) ? '-' : ' ');\r | |
152 | Str[Index] = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r | |
153 | }\r | |
154 | \r | |
155 | Val[Index * 3] = 0;\r | |
156 | Str[Index] = 0;\r | |
157 | Print (L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);\r | |
158 | \r | |
159 | Data += Size;\r | |
160 | Offset += Size;\r | |
161 | DataSize -= Size;\r | |
162 | }\r | |
163 | }\r | |
164 | \r | |
165 | \r | |
166 | /**\r | |
167 | Safely append with automatic string resizing given length of Destination and\r | |
168 | desired length of copy from Source.\r | |
169 | \r | |
170 | append the first D characters of Source to the end of Destination, where D is\r | |
171 | the lesser of Count and the StrLen() of Source. If appending those D characters\r | |
172 | will fit within Destination (whose Size is given as CurrentSize) and\r | |
173 | still leave room for a NULL terminator, then those characters are appended,\r | |
174 | starting at the original terminating NULL of Destination, and a new terminating\r | |
175 | NULL is appended.\r | |
176 | \r | |
177 | If appending D characters onto Destination will result in a overflow of the size\r | |
178 | given in CurrentSize the string will be grown such that the copy can be performed\r | |
179 | and CurrentSize will be updated to the new size.\r | |
180 | \r | |
181 | If Source is NULL, there is nothing to append, just return the current buffer in\r | |
182 | Destination.\r | |
183 | \r | |
184 | if Destination is NULL, then ASSERT()\r | |
185 | if Destination's current length (including NULL terminator) is already more then\r | |
186 | CurrentSize, then ASSERT()\r | |
187 | \r | |
188 | @param[in, out] Destination The String to append onto\r | |
189 | @param[in, out] CurrentSize on call the number of bytes in Destination. On\r | |
190 | return possibly the new size (still in bytes). if NULL\r | |
191 | then allocate whatever is needed.\r | |
192 | @param[in] Source The String to append from\r | |
193 | \r | |
194 | @return Destination return the resultant string.\r | |
195 | **/\r | |
196 | static\r | |
197 | CHAR16*\r | |
198 | InternalStrnCatGrow (\r | |
199 | IN OUT CHAR16 **Destination,\r | |
200 | IN OUT UINTN *CurrentSize,\r | |
201 | IN CONST CHAR16 *Source\r | |
202 | )\r | |
203 | {\r | |
204 | UINTN DestinationStartSize;\r | |
205 | UINTN NewSize;\r | |
206 | UINTN SourceLen;\r | |
207 | \r | |
208 | SourceLen = StrLen(Source);\r | |
209 | \r | |
210 | //\r | |
211 | // ASSERTs\r | |
212 | //\r | |
213 | ASSERT(Destination != NULL);\r | |
214 | \r | |
215 | //\r | |
216 | // If there's nothing to do then just return Destination\r | |
217 | //\r | |
218 | if (Source == NULL) {\r | |
219 | return (*Destination);\r | |
220 | }\r | |
221 | \r | |
222 | //\r | |
223 | // allow for un-initialized pointers, based on size being 0\r | |
224 | //\r | |
225 | if (CurrentSize != NULL && *CurrentSize == 0) {\r | |
226 | *Destination = NULL;\r | |
227 | }\r | |
228 | \r | |
229 | //\r | |
230 | // allow for NULL pointers address as Destination\r | |
231 | //\r | |
232 | if (*Destination != NULL) {\r | |
233 | ASSERT(CurrentSize != 0);\r | |
234 | DestinationStartSize = StrSize(*Destination);\r | |
235 | ASSERT(DestinationStartSize <= *CurrentSize);\r | |
236 | } else {\r | |
237 | DestinationStartSize = 0;\r | |
238 | }\r | |
239 | \r | |
240 | //\r | |
241 | // Test and grow if required\r | |
242 | //\r | |
243 | if (CurrentSize != NULL) {\r | |
244 | NewSize = *CurrentSize;\r | |
245 | if (NewSize < DestinationStartSize + (SourceLen * sizeof(CHAR16))) {\r | |
246 | while (NewSize < (DestinationStartSize + (SourceLen*sizeof(CHAR16)))) {\r | |
247 | NewSize += 2 * SourceLen * sizeof(CHAR16);\r | |
248 | }\r | |
249 | *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);\r | |
250 | *CurrentSize = NewSize;\r | |
251 | }\r | |
252 | } else {\r | |
253 | NewSize = (SourceLen + 1)*sizeof(CHAR16);\r | |
254 | *Destination = AllocateZeroPool(NewSize);\r | |
255 | }\r | |
256 | \r | |
257 | //\r | |
258 | // Now use standard StrnCat on a big enough buffer\r | |
259 | //\r | |
260 | if (*Destination == NULL) {\r | |
261 | return (NULL);\r | |
262 | }\r | |
263 | \r | |
264 | StrnCatS(*Destination, NewSize/sizeof(CHAR16), Source, SourceLen);\r | |
265 | return *Destination;\r | |
266 | }\r | |
267 | \r | |
268 | /**\r | |
269 | Get PCD type string based on input PCD type.\r | |
270 | \r | |
271 | @param[in] TokenSpace PCD Token Space.\r | |
272 | @param[in] PcdType The input PCD type.\r | |
273 | \r | |
274 | @return Pointer to PCD type string.\r | |
275 | **/\r | |
276 | static\r | |
277 | CHAR16 *\r | |
278 | GetPcdTypeString (\r | |
279 | IN CONST EFI_GUID *TokenSpace,\r | |
280 | IN EFI_PCD_TYPE PcdType\r | |
281 | )\r | |
282 | {\r | |
283 | UINTN BufLen;\r | |
284 | CHAR16 *RetString;\r | |
285 | \r | |
286 | BufLen = 0;\r | |
287 | RetString = NULL;\r | |
288 | \r | |
289 | switch (PcdType) {\r | |
290 | case EFI_PCD_TYPE_8:\r | |
291 | InternalStrnCatGrow (&RetString, &BufLen, L"UINT8");\r | |
292 | break;\r | |
293 | case EFI_PCD_TYPE_16:\r | |
294 | InternalStrnCatGrow (&RetString, &BufLen, L"UINT16");\r | |
295 | break;\r | |
296 | case EFI_PCD_TYPE_32:\r | |
297 | InternalStrnCatGrow (&RetString, &BufLen, L"UINT32");\r | |
298 | break;\r | |
299 | case EFI_PCD_TYPE_64:\r | |
300 | InternalStrnCatGrow (&RetString, &BufLen, L"UINT64");\r | |
301 | break;\r | |
302 | case EFI_PCD_TYPE_BOOL:\r | |
303 | InternalStrnCatGrow (&RetString, &BufLen, L"BOOLEAN");\r | |
304 | break;\r | |
305 | case EFI_PCD_TYPE_PTR:\r | |
306 | InternalStrnCatGrow (&RetString, &BufLen, L"POINTER");\r | |
307 | break;\r | |
308 | default:\r | |
309 | InternalStrnCatGrow (&RetString, &BufLen, L"UNKNOWN");\r | |
310 | break;\r | |
311 | }\r | |
312 | \r | |
313 | if (TokenSpace == NULL) {\r | |
314 | InternalStrnCatGrow (&RetString, &BufLen, L":DYNAMIC");\r | |
315 | } else {\r | |
316 | InternalStrnCatGrow (&RetString, &BufLen, L":DYNAMICEX");\r | |
317 | }\r | |
318 | \r | |
319 | return RetString;\r | |
320 | }\r | |
321 | \r | |
322 | /**\r | |
323 | Dump PCD info.\r | |
324 | \r | |
325 | @param[in] TokenSpace PCD Token Space.\r | |
326 | @param[in] TokenNumber PCD Token Number.\r | |
327 | @param[in] PcdInfo Pointer to PCD info.\r | |
328 | **/\r | |
329 | static\r | |
330 | VOID\r | |
331 | DumpPcdInfo (\r | |
332 | IN CONST EFI_GUID *TokenSpace,\r | |
333 | IN UINTN TokenNumber,\r | |
334 | IN EFI_PCD_INFO *PcdInfo\r | |
335 | )\r | |
336 | {\r | |
337 | CHAR16 *RetString;\r | |
338 | UINT8 Uint8;\r | |
339 | UINT16 Uint16;\r | |
340 | UINT32 Uint32;\r | |
341 | UINT64 Uint64;\r | |
342 | BOOLEAN Boolean;\r | |
343 | VOID *PcdData;\r | |
344 | \r | |
345 | RetString = NULL;\r | |
346 | \r | |
347 | if (PcdInfo->PcdName != NULL) {\r | |
348 | Print (L"%a\n", PcdInfo->PcdName);\r | |
349 | } else {\r | |
350 | if (TokenSpace == NULL) {\r | |
351 | Print (L"Default Token Space\n");\r | |
352 | } else {\r | |
353 | Print (L"%g\n", TokenSpace);\r | |
354 | }\r | |
355 | }\r | |
356 | \r | |
357 | RetString = GetPcdTypeString (TokenSpace, PcdInfo->PcdType);\r | |
358 | \r | |
359 | switch (PcdInfo->PcdType) {\r | |
360 | case EFI_PCD_TYPE_8:\r | |
361 | if (TokenSpace == NULL) {\r | |
362 | Uint8 = mPcd->Get8 (TokenNumber);\r | |
363 | } else {\r | |
364 | Uint8 = mPiPcd->Get8 (TokenSpace, TokenNumber);\r | |
365 | }\r | |
366 | Print (L" Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint8);\r | |
367 | break;\r | |
368 | case EFI_PCD_TYPE_16:\r | |
369 | if (TokenSpace == NULL) {\r | |
370 | Uint16 = mPcd->Get16 (TokenNumber);\r | |
371 | } else {\r | |
372 | Uint16 = mPiPcd->Get16 (TokenSpace, TokenNumber);\r | |
373 | }\r | |
374 | Print (L" Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint16);\r | |
375 | break;\r | |
376 | case EFI_PCD_TYPE_32:\r | |
377 | if (TokenSpace == NULL) {\r | |
378 | Uint32 = mPcd->Get32 (TokenNumber);\r | |
379 | } else {\r | |
380 | Uint32 = mPiPcd->Get32 (TokenSpace, TokenNumber);\r | |
381 | }\r | |
382 | Print (L" Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint32);\r | |
383 | break;\r | |
384 | case EFI_PCD_TYPE_64:\r | |
385 | if (TokenSpace == NULL) {\r | |
386 | Uint64 = mPcd->Get64 (TokenNumber);\r | |
387 | } else {\r | |
388 | Uint64 = mPiPcd->Get64 (TokenSpace, TokenNumber);\r | |
389 | }\r | |
390 | Print (L" Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = 0x%lx\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint64);\r | |
391 | break;\r | |
392 | case EFI_PCD_TYPE_BOOL:\r | |
393 | if (TokenSpace == NULL) {\r | |
394 | Boolean = mPcd->GetBool (TokenNumber);\r | |
395 | } else {\r | |
396 | Boolean = mPiPcd->GetBool (TokenSpace, TokenNumber);\r | |
397 | }\r | |
398 | Print (L" Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x - Value = %a\n", TokenNumber, RetString, PcdInfo->PcdSize, Boolean ? "TRUE" : "FALSE");\r | |
399 | break;\r | |
400 | case EFI_PCD_TYPE_PTR:\r | |
401 | if (TokenSpace == NULL) {\r | |
402 | PcdData = mPcd->GetPtr (TokenNumber);\r | |
403 | } else {\r | |
404 | PcdData = mPiPcd->GetPtr (TokenSpace, TokenNumber);\r | |
405 | }\r | |
406 | Print (L" Token = 0x%08x - Type = %H%-17s%N - Size = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize);\r | |
407 | DumpHex (2, 0, PcdInfo->PcdSize, PcdData);\r | |
408 | break;\r | |
409 | default:\r | |
410 | return;\r | |
411 | }\r | |
412 | \r | |
413 | if (RetString != NULL) {\r | |
414 | FreePool (RetString);\r | |
415 | }\r | |
416 | Print (L"\n");\r | |
417 | }\r | |
418 | \r | |
419 | /**\r | |
420 | Show one or all PCDs' info.\r | |
421 | \r | |
422 | @param[in] InputPcdName Pointer to PCD name to show. If NULL, show all PCDs' info.\r | |
423 | \r | |
424 | @retval EFI_SUCCESS Command completed successfully.\r | |
425 | @retval EFI_OUT_OF_RESOURCES Not enough resources were available to run the command.\r | |
426 | @retval EFI_ABORTED Aborted by user.\r | |
427 | @retval EFI_NOT_FOUND The specified PCD is not found.\r | |
428 | **/\r | |
429 | static\r | |
430 | EFI_STATUS\r | |
431 | ProcessPcd (\r | |
432 | IN CHAR16 *InputPcdName\r | |
433 | )\r | |
434 | {\r | |
435 | EFI_STATUS Status;\r | |
436 | EFI_GUID *TokenSpace;\r | |
437 | UINTN TokenNumber;\r | |
438 | EFI_PCD_INFO PcdInfo;\r | |
439 | BOOLEAN Found;\r | |
440 | UINTN PcdNameSize;\r | |
441 | \r | |
442 | PcdInfo.PcdName = NULL;\r | |
443 | PcdInfo.PcdSize = 0;\r | |
444 | PcdInfo.PcdType = 0xFF;\r | |
445 | Found = FALSE;\r | |
446 | \r | |
447 | Print (L"Current system SKU ID: 0x%x\n\n", mPiPcdInfo->GetSku ());\r | |
448 | \r | |
449 | TokenSpace = NULL;\r | |
450 | do {\r | |
451 | TokenNumber = 0;\r | |
452 | do {\r | |
453 | Status = mPiPcd->GetNextToken (TokenSpace, &TokenNumber);\r | |
454 | if (!EFI_ERROR (Status) && TokenNumber != 0) {\r | |
455 | if (TokenSpace == NULL) {\r | |
456 | //\r | |
457 | // PCD in default Token Space.\r | |
458 | //\r | |
459 | mPcdInfo->GetInfo (TokenNumber, &PcdInfo);\r | |
460 | } else {\r | |
461 | mPiPcdInfo->GetInfo (TokenSpace, TokenNumber, &PcdInfo);\r | |
462 | }\r | |
463 | if (InputPcdName != NULL) {\r | |
464 | if (PcdInfo.PcdName == NULL) {\r | |
465 | continue;\r | |
466 | }\r | |
467 | PcdNameSize = AsciiStrSize (PcdInfo.PcdName) * sizeof (CHAR16);\r | |
468 | if (mTempPcdNameBuffer == NULL) {\r | |
469 | mTempPcdNameBufferSize = PcdNameSize;\r | |
470 | mTempPcdNameBuffer = AllocatePool (mTempPcdNameBufferSize);\r | |
471 | } else if (mTempPcdNameBufferSize < PcdNameSize) {\r | |
472 | mTempPcdNameBuffer = ReallocatePool (mTempPcdNameBufferSize, PcdNameSize, mTempPcdNameBuffer);\r | |
473 | mTempPcdNameBufferSize = PcdNameSize;\r | |
474 | }\r | |
475 | if (mTempPcdNameBuffer == NULL) {\r | |
476 | return EFI_OUT_OF_RESOURCES;\r | |
477 | }\r | |
478 | AsciiStrToUnicodeStrS (PcdInfo.PcdName, mTempPcdNameBuffer, mTempPcdNameBufferSize / sizeof (CHAR16));\r | |
479 | //\r | |
480 | // Compare the input PCD name with the PCD name in PCD database.\r | |
481 | //\r | |
482 | if ((StrStr (mTempPcdNameBuffer, InputPcdName) != NULL) ||\r | |
483 | (mUnicodeCollation != NULL && mUnicodeCollation->MetaiMatch (mUnicodeCollation, mTempPcdNameBuffer, InputPcdName))) {\r | |
484 | //\r | |
485 | // Found matched PCD.\r | |
486 | //\r | |
487 | DumpPcdInfo (TokenSpace, TokenNumber, &PcdInfo);\r | |
488 | Found = TRUE;\r | |
489 | }\r | |
490 | } else {\r | |
491 | DumpPcdInfo (TokenSpace, TokenNumber, &PcdInfo);\r | |
492 | }\r | |
493 | }\r | |
494 | } while (!EFI_ERROR (Status) && TokenNumber != 0);\r | |
495 | \r | |
496 | Status = mPiPcd->GetNextTokenSpace ((CONST EFI_GUID **) &TokenSpace);\r | |
497 | } while (!EFI_ERROR (Status) && TokenSpace != NULL);\r | |
498 | \r | |
499 | if ((InputPcdName != NULL) && !Found) {\r | |
500 | //\r | |
501 | // The specified PCD is not found, print error.\r | |
502 | //\r | |
503 | Print (L"%EError. %NNo matching PCD found: %s.\n", InputPcdName);\r | |
504 | return EFI_NOT_FOUND;\r | |
505 | }\r | |
506 | return EFI_SUCCESS;\r | |
507 | }\r | |
508 | \r | |
509 | /**\r | |
510 | Main entrypoint for DumpDynPcd shell application.\r | |
511 | \r | |
512 | @param[in] ImageHandle The image handle.\r | |
513 | @param[in] SystemTable The system table.\r | |
514 | \r | |
515 | @retval EFI_SUCCESS Command completed successfully.\r | |
516 | @retval EFI_INVALID_PARAMETER Command usage error.\r | |
517 | @retval EFI_OUT_OF_RESOURCES Not enough resources were available to run the command.\r | |
518 | @retval EFI_ABORTED Aborted by user.\r | |
519 | @retval EFI_NOT_FOUND The specified PCD is not found.\r | |
520 | @retval Others Error status returned from gBS->LocateProtocol.\r | |
521 | **/\r | |
522 | EFI_STATUS\r | |
523 | EFIAPI\r | |
524 | DumpDynPcdMain (\r | |
525 | IN EFI_HANDLE ImageHandle,\r | |
526 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
527 | )\r | |
528 | {\r | |
529 | EFI_STATUS Status;\r | |
530 | CHAR16 *InputPcdName;\r | |
531 | \r | |
532 | InputPcdName = NULL;\r | |
533 | \r | |
534 | Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID **) &mUnicodeCollation);\r | |
535 | if (EFI_ERROR (Status)) {\r | |
536 | mUnicodeCollation = NULL;\r | |
537 | }\r | |
538 | \r | |
539 | Status = gBS->LocateProtocol (&gEfiPcdProtocolGuid, NULL, (VOID **) &mPiPcd);\r | |
540 | if (EFI_ERROR (Status)) {\r | |
541 | Print (L"DumpDynPcd: %EError. %NPI PCD protocol is not present.\n");\r | |
542 | return Status;\r | |
543 | }\r | |
544 | \r | |
545 | Status = gBS->LocateProtocol (&gEfiGetPcdInfoProtocolGuid, NULL, (VOID **) &mPiPcdInfo);\r | |
546 | if (EFI_ERROR (Status)) {\r | |
547 | Print (L"DumpDynPcd: %EError. %NPI PCD info protocol is not present.\n");\r | |
548 | return Status;\r | |
549 | }\r | |
550 | \r | |
551 | Status = gBS->LocateProtocol (&gPcdProtocolGuid, NULL, (VOID **) &mPcd);\r | |
552 | if (EFI_ERROR (Status)) {\r | |
553 | Print (L"DumpDynPcd: %EError. %NPCD protocol is not present.\n");\r | |
554 | return Status;\r | |
555 | }\r | |
556 | \r | |
557 | Status = gBS->LocateProtocol (&gGetPcdInfoProtocolGuid, NULL, (VOID **) &mPcdInfo);\r | |
558 | if (EFI_ERROR (Status)) {\r | |
559 | Print (L"DumpDynPcd: %EError. %NPCD info protocol is not present.\n");\r | |
560 | return Status;\r | |
561 | }\r | |
562 | \r | |
563 | //\r | |
564 | // get the command line arguments\r | |
565 | //\r | |
566 | Status = GetArg();\r | |
567 | if (EFI_ERROR(Status)){\r | |
568 | Print (L"DumpDynPcd: %EError. %NThe input parameters are not recognized.\n");\r | |
569 | Status = EFI_INVALID_PARAMETER;\r | |
570 | return Status;\r | |
571 | }\r | |
572 | \r | |
573 | if (Argc > 2){\r | |
574 | Print (L"DumpDynPcd: %EError. %NToo many arguments specified.\n");\r | |
575 | Status = EFI_INVALID_PARAMETER;\r | |
576 | return Status;\r | |
577 | }\r | |
578 | \r | |
579 | if (Argc == 1){\r | |
580 | Status = ProcessPcd (InputPcdName);\r | |
581 | goto Done;\r | |
582 | }\r | |
583 | \r | |
584 | if ((StrCmp(Argv[1], L"-?") == 0)||(StrCmp(Argv[1], L"-h") == 0)||(StrCmp(Argv[1], L"-H") == 0)){\r | |
585 | ShowHelp ();\r | |
586 | goto Done;\r | |
587 | } else {\r | |
588 | if ((StrCmp(Argv[1], L"-v") == 0)||(StrCmp(Argv[1], L"-V") == 0)){\r | |
589 | ShowVersion ();\r | |
590 | goto Done;\r | |
591 | } else {\r | |
592 | if (StrStr(Argv[1], L"-") != NULL){\r | |
593 | Print (L"DumpDynPcd: %EError. %NThe argument '%B%s%N' is invalid.\n", Argv[1]);\r | |
594 | goto Done;\r | |
595 | }\r | |
596 | }\r | |
597 | }\r | |
598 | \r | |
599 | InputPcdName = Argv[1];\r | |
600 | Status = ProcessPcd (InputPcdName);\r | |
601 | \r | |
602 | Done:\r | |
603 | \r | |
604 | if (mTempPcdNameBuffer != NULL) {\r | |
605 | FreePool (mTempPcdNameBuffer);\r | |
606 | }\r | |
607 | \r | |
608 | return Status;\r | |
609 | }\r | |
610 | \r |