TianoCore EDK2 master
Loading...
Searching...
No Matches
DumpDynPcd.c
Go to the documentation of this file.
1
9#include <Uefi.h>
10#include <PiDxe.h>
11#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
15#include <Library/UefiLib.h>
16
18#include <Protocol/PiPcd.h>
19#include <Protocol/Pcd.h>
20#include <Protocol/PiPcdInfo.h>
21#include <Protocol/PcdInfo.h>
23#include <Protocol/Shell.h>
24
25//
26// String token ID of help message text.
27// Shell supports to find help message in the resource section of an application image if
28// .MAN file is not found. This global variable is added to make build tool recognizes
29// that the help string is consumed by user and then build tool will add the string into
30// the resource section. Thus the application can use '-?' option to show help message in
31// Shell.
32//
33GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStrDumpDynPcdHelpTokenId = STRING_TOKEN (STR_DUMP_DYN_PCD_HELP_INFORMATION);
34
35#define MAJOR_VERSION 1
36#define MINOR_VERSION 0
37
38static EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;
39static EFI_PCD_PROTOCOL *mPiPcd = NULL;
40static PCD_PROTOCOL *mPcd = NULL;
41static EFI_GET_PCD_INFO_PROTOCOL *mPiPcdInfo = NULL;
42static GET_PCD_INFO_PROTOCOL *mPcdInfo = NULL;
43static CHAR16 *mTempPcdNameBuffer = NULL;
44static UINTN mTempPcdNameBufferSize = 0;
45
46static CONST CHAR8 mHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
47
48static UINTN Argc;
49static CHAR16 **Argv;
50
57static
59GetArg (
60 VOID
61 )
62{
63 EFI_STATUS Status;
64 EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;
65
66 Status = gBS->HandleProtocol (
68 &gEfiShellParametersProtocolGuid,
69 (VOID **)&ShellParameters
70 );
71 if (EFI_ERROR (Status)) {
72 return Status;
73 }
74
75 Argc = ShellParameters->Argc;
76 Argv = ShellParameters->Argv;
77 return EFI_SUCCESS;
78}
79
83static
84VOID
85ShowVersion (
86 )
87{
88 Print (L"DumpDynPcd Version %d.%02d\n", MAJOR_VERSION, MINOR_VERSION);
89}
90
94static
95VOID
96ShowHelp (
97 )
98{
99 Print (L"Dump dynamic[ex] PCD info.\n");
100 Print (L"\n");
101 Print (L"DumpDynPcd [PcdName]\n");
102 Print (L"\n");
103 Print (L" PcdName Specifies the name of PCD.\n");
104 Print (L" A literal[or partial] name or a pattern as specified in\n");
105 Print (L" the MetaiMatch() function of the EFI_UNICODE_COLLATION2_PROCOOL.\n");
106 Print (L" If it is absent, dump all PCDs' info.\n");
107 Print (L"The PCD data is printed as hexadecimal dump.\n");
108}
109
118static
119VOID
120DumpHex (
121 IN UINTN Indent,
122 IN UINTN Offset,
123 IN UINTN DataSize,
124 IN VOID *UserData
125 )
126{
127 UINT8 *Data;
128
129 CHAR8 Val[50];
130
131 CHAR8 Str[20];
132
133 UINT8 TempByte;
134 UINTN Size;
135 UINTN Index;
136
137 Data = UserData;
138 while (DataSize != 0) {
139 Size = 16;
140 if (Size > DataSize) {
141 Size = DataSize;
142 }
143
144 for (Index = 0; Index < Size; Index += 1) {
145 TempByte = Data[Index];
146 Val[Index * 3 + 0] = mHex[TempByte >> 4];
147 Val[Index * 3 + 1] = mHex[TempByte & 0xF];
148 Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');
149 Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
150 }
151
152 Val[Index * 3] = 0;
153 Str[Index] = 0;
154 Print (L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);
155
156 Data += Size;
157 Offset += Size;
158 DataSize -= Size;
159 }
160}
161
192static
193CHAR16 *
194InternalStrnCatGrow (
195 IN OUT CHAR16 **Destination,
196 IN OUT UINTN *CurrentSize,
197 IN CONST CHAR16 *Source
198 )
199{
200 UINTN DestinationStartSize;
201 UINTN NewSize;
202 UINTN SourceLen;
203
204 SourceLen = StrLen (Source);
205
206 //
207 // ASSERTs
208 //
209 ASSERT (Destination != NULL);
210
211 //
212 // If there's nothing to do then just return Destination
213 //
214 if (Source == NULL) {
215 return (*Destination);
216 }
217
218 //
219 // allow for un-initialized pointers, based on size being 0
220 //
221 if ((CurrentSize != NULL) && (*CurrentSize == 0)) {
222 *Destination = NULL;
223 }
224
225 //
226 // allow for NULL pointers address as Destination
227 //
228 if (*Destination != NULL) {
229 ASSERT (CurrentSize != 0);
230 DestinationStartSize = StrSize (*Destination);
231 ASSERT (DestinationStartSize <= *CurrentSize);
232 } else {
233 DestinationStartSize = 0;
234 }
235
236 //
237 // Test and grow if required
238 //
239 if (CurrentSize != NULL) {
240 NewSize = *CurrentSize;
241 if (NewSize < DestinationStartSize + (SourceLen * sizeof (CHAR16))) {
242 while (NewSize < (DestinationStartSize + (SourceLen*sizeof (CHAR16)))) {
243 NewSize += 2 * SourceLen * sizeof (CHAR16);
244 }
245
246 *Destination = ReallocatePool (*CurrentSize, NewSize, *Destination);
247 *CurrentSize = NewSize;
248 }
249 } else {
250 NewSize = (SourceLen + 1)*sizeof (CHAR16);
251 *Destination = AllocateZeroPool (NewSize);
252 }
253
254 //
255 // Now use standard StrnCat on a big enough buffer
256 //
257 if (*Destination == NULL) {
258 return (NULL);
259 }
260
261 StrnCatS (*Destination, NewSize/sizeof (CHAR16), Source, SourceLen);
262 return *Destination;
263}
264
273static
274CHAR16 *
275GetPcdTypeString (
276 IN CONST EFI_GUID *TokenSpace,
277 IN EFI_PCD_TYPE PcdType
278 )
279{
280 UINTN BufLen;
281 CHAR16 *RetString;
282
283 BufLen = 0;
284 RetString = NULL;
285
286 switch (PcdType) {
287 case EFI_PCD_TYPE_8:
288 InternalStrnCatGrow (&RetString, &BufLen, L"UINT8");
289 break;
290 case EFI_PCD_TYPE_16:
291 InternalStrnCatGrow (&RetString, &BufLen, L"UINT16");
292 break;
293 case EFI_PCD_TYPE_32:
294 InternalStrnCatGrow (&RetString, &BufLen, L"UINT32");
295 break;
296 case EFI_PCD_TYPE_64:
297 InternalStrnCatGrow (&RetString, &BufLen, L"UINT64");
298 break;
299 case EFI_PCD_TYPE_BOOL:
300 InternalStrnCatGrow (&RetString, &BufLen, L"BOOLEAN");
301 break;
302 case EFI_PCD_TYPE_PTR:
303 InternalStrnCatGrow (&RetString, &BufLen, L"POINTER");
304 break;
305 default:
306 InternalStrnCatGrow (&RetString, &BufLen, L"UNKNOWN");
307 break;
308 }
309
310 if (TokenSpace == NULL) {
311 InternalStrnCatGrow (&RetString, &BufLen, L":DYNAMIC");
312 } else {
313 InternalStrnCatGrow (&RetString, &BufLen, L":DYNAMICEX");
314 }
315
316 return RetString;
317}
318
326static
327VOID
328DumpPcdInfo (
329 IN CONST EFI_GUID *TokenSpace,
330 IN UINTN TokenNumber,
331 IN EFI_PCD_INFO *PcdInfo
332 )
333{
334 CHAR16 *RetString;
335 UINT8 Uint8;
336 UINT16 Uint16;
337 UINT32 Uint32;
338 UINT64 Uint64;
339 BOOLEAN Boolean;
340 VOID *PcdData;
341
342 RetString = NULL;
343
344 if (PcdInfo->PcdName != NULL) {
345 Print (L"%a\n", PcdInfo->PcdName);
346 } else {
347 if (TokenSpace == NULL) {
348 Print (L"Default Token Space\n");
349 } else {
350 Print (L"%g\n", TokenSpace);
351 }
352 }
353
354 RetString = GetPcdTypeString (TokenSpace, PcdInfo->PcdType);
355
356 switch (PcdInfo->PcdType) {
357 case EFI_PCD_TYPE_8:
358 if (TokenSpace == NULL) {
359 Uint8 = mPcd->Get8 (TokenNumber);
360 } else {
361 Uint8 = mPiPcd->Get8 (TokenSpace, TokenNumber);
362 }
363
364 Print (L" Token = 0x%08x - Type = %-17s - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint8);
365 break;
366 case EFI_PCD_TYPE_16:
367 if (TokenSpace == NULL) {
368 Uint16 = mPcd->Get16 (TokenNumber);
369 } else {
370 Uint16 = mPiPcd->Get16 (TokenSpace, TokenNumber);
371 }
372
373 Print (L" Token = 0x%08x - Type = %-17s - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint16);
374 break;
375 case EFI_PCD_TYPE_32:
376 if (TokenSpace == NULL) {
377 Uint32 = mPcd->Get32 (TokenNumber);
378 } else {
379 Uint32 = mPiPcd->Get32 (TokenSpace, TokenNumber);
380 }
381
382 Print (L" Token = 0x%08x - Type = %-17s - Size = 0x%x - Value = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint32);
383 break;
384 case EFI_PCD_TYPE_64:
385 if (TokenSpace == NULL) {
386 Uint64 = mPcd->Get64 (TokenNumber);
387 } else {
388 Uint64 = mPiPcd->Get64 (TokenSpace, TokenNumber);
389 }
390
391 Print (L" Token = 0x%08x - Type = %-17s - Size = 0x%x - Value = 0x%lx\n", TokenNumber, RetString, PcdInfo->PcdSize, Uint64);
392 break;
393 case EFI_PCD_TYPE_BOOL:
394 if (TokenSpace == NULL) {
395 Boolean = mPcd->GetBool (TokenNumber);
396 } else {
397 Boolean = mPiPcd->GetBool (TokenSpace, TokenNumber);
398 }
399
400 Print (L" Token = 0x%08x - Type = %-17s - Size = 0x%x - Value = %a\n", TokenNumber, RetString, PcdInfo->PcdSize, Boolean ? "TRUE" : "FALSE");
401 break;
402 case EFI_PCD_TYPE_PTR:
403 if (TokenSpace == NULL) {
404 PcdData = mPcd->GetPtr (TokenNumber);
405 } else {
406 PcdData = mPiPcd->GetPtr (TokenSpace, TokenNumber);
407 }
408
409 Print (L" Token = 0x%08x - Type = %-17s - Size = 0x%x\n", TokenNumber, RetString, PcdInfo->PcdSize);
410 DumpHex (2, 0, PcdInfo->PcdSize, PcdData);
411 break;
412 default:
413 return;
414 }
415
416 if (RetString != NULL) {
417 FreePool (RetString);
418 }
419
420 Print (L"\n");
421}
422
433static
435ProcessPcd (
436 IN CHAR16 *InputPcdName
437 )
438{
439 EFI_STATUS Status;
440 EFI_GUID *TokenSpace;
441 UINTN TokenNumber;
442 EFI_PCD_INFO PcdInfo;
443 BOOLEAN Found;
444 UINTN PcdNameSize;
445
446 PcdInfo.PcdName = NULL;
447 PcdInfo.PcdSize = 0;
448 PcdInfo.PcdType = 0xFF;
449 Found = FALSE;
450
451 Print (L"Current system SKU ID: 0x%x\n\n", mPiPcdInfo->GetSku ());
452
453 TokenSpace = NULL;
454 do {
455 TokenNumber = 0;
456 do {
457 Status = mPiPcd->GetNextToken (TokenSpace, &TokenNumber);
458 if (!EFI_ERROR (Status) && (TokenNumber != 0)) {
459 if (TokenSpace == NULL) {
460 //
461 // PCD in default Token Space.
462 //
463 mPcdInfo->GetInfo (TokenNumber, &PcdInfo);
464 } else {
465 mPiPcdInfo->GetInfo (TokenSpace, TokenNumber, &PcdInfo);
466 }
467
468 if (InputPcdName != NULL) {
469 if (PcdInfo.PcdName == NULL) {
470 continue;
471 }
472
473 PcdNameSize = AsciiStrSize (PcdInfo.PcdName) * sizeof (CHAR16);
474 if (mTempPcdNameBuffer == NULL) {
475 mTempPcdNameBufferSize = PcdNameSize;
476 mTempPcdNameBuffer = AllocatePool (mTempPcdNameBufferSize);
477 } else if (mTempPcdNameBufferSize < PcdNameSize) {
478 mTempPcdNameBuffer = ReallocatePool (mTempPcdNameBufferSize, PcdNameSize, mTempPcdNameBuffer);
479 mTempPcdNameBufferSize = PcdNameSize;
480 }
481
482 if (mTempPcdNameBuffer == NULL) {
483 return EFI_OUT_OF_RESOURCES;
484 }
485
486 AsciiStrToUnicodeStrS (PcdInfo.PcdName, mTempPcdNameBuffer, mTempPcdNameBufferSize / sizeof (CHAR16));
487 //
488 // Compare the input PCD name with the PCD name in PCD database.
489 //
490 if ((StrStr (mTempPcdNameBuffer, InputPcdName) != NULL) ||
491 ((mUnicodeCollation != NULL) && mUnicodeCollation->MetaiMatch (mUnicodeCollation, mTempPcdNameBuffer, InputPcdName)))
492 {
493 //
494 // Found matched PCD.
495 //
496 DumpPcdInfo (TokenSpace, TokenNumber, &PcdInfo);
497 Found = TRUE;
498 }
499 } else {
500 DumpPcdInfo (TokenSpace, TokenNumber, &PcdInfo);
501 }
502 }
503 } while (!EFI_ERROR (Status) && TokenNumber != 0);
504
505 Status = mPiPcd->GetNextTokenSpace ((CONST EFI_GUID **)&TokenSpace);
506 } while (!EFI_ERROR (Status) && TokenSpace != NULL);
507
508 if ((InputPcdName != NULL) && !Found) {
509 //
510 // The specified PCD is not found, print error.
511 //
512 Print (L"Error. No matching PCD found: %s.\n", InputPcdName);
513 return EFI_NOT_FOUND;
514 }
515
516 return EFI_SUCCESS;
517}
518
533EFIAPI
535 IN EFI_HANDLE ImageHandle,
536 IN EFI_SYSTEM_TABLE *SystemTable
537 )
538{
539 EFI_STATUS Status;
540 CHAR16 *InputPcdName;
541
542 InputPcdName = NULL;
543
544 Status = gBS->LocateProtocol (&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID **)&mUnicodeCollation);
545 if (EFI_ERROR (Status)) {
546 mUnicodeCollation = NULL;
547 }
548
549 Status = gBS->LocateProtocol (&gEfiPcdProtocolGuid, NULL, (VOID **)&mPiPcd);
550 if (EFI_ERROR (Status)) {
551 Print (L"DumpDynPcd: Error. PI PCD protocol is not present.\n");
552 return Status;
553 }
554
555 Status = gBS->LocateProtocol (&gEfiGetPcdInfoProtocolGuid, NULL, (VOID **)&mPiPcdInfo);
556 if (EFI_ERROR (Status)) {
557 Print (L"DumpDynPcd: Error. PI PCD info protocol is not present.\n");
558 return Status;
559 }
560
561 Status = gBS->LocateProtocol (&gPcdProtocolGuid, NULL, (VOID **)&mPcd);
562 if (EFI_ERROR (Status)) {
563 Print (L"DumpDynPcd: Error. PCD protocol is not present.\n");
564 return Status;
565 }
566
567 Status = gBS->LocateProtocol (&gGetPcdInfoProtocolGuid, NULL, (VOID **)&mPcdInfo);
568 if (EFI_ERROR (Status)) {
569 Print (L"DumpDynPcd: Error. PCD info protocol is not present.\n");
570 return Status;
571 }
572
573 //
574 // get the command line arguments
575 //
576 Status = GetArg ();
577 if (EFI_ERROR (Status)) {
578 Print (L"DumpDynPcd: Error. The input parameters are not recognized.\n");
579 Status = EFI_INVALID_PARAMETER;
580 return Status;
581 }
582
583 if (Argc > 2) {
584 Print (L"DumpDynPcd: Error. Too many arguments specified.\n");
585 Status = EFI_INVALID_PARAMETER;
586 return Status;
587 }
588
589 if (Argc == 1) {
590 Status = ProcessPcd (InputPcdName);
591 goto Done;
592 }
593
594 if ((StrCmp (Argv[1], L"-?") == 0) || (StrCmp (Argv[1], L"-h") == 0) || (StrCmp (Argv[1], L"-H") == 0)) {
595 ShowHelp ();
596 goto Done;
597 } else {
598 if ((StrCmp (Argv[1], L"-v") == 0) || (StrCmp (Argv[1], L"-V") == 0)) {
599 ShowVersion ();
600 goto Done;
601 } else {
602 if (StrStr (Argv[1], L"-") != NULL) {
603 Print (L"DumpDynPcd: Error. The argument '%s' is invalid.\n", Argv[1]);
604 goto Done;
605 }
606 }
607 }
608
609 InputPcdName = Argv[1];
610 Status = ProcessPcd (InputPcdName);
611
612Done:
613
614 if (mTempPcdNameBuffer != NULL) {
615 FreePool (mTempPcdNameBuffer);
616 }
617
618 return Status;
619}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
RETURN_STATUS EFIAPI StrnCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:507
RETURN_STATUS EFIAPI AsciiStrToUnicodeStrS(IN CONST CHAR8 *Source, OUT CHAR16 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2873
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR16 *EFIAPI StrStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
Definition: String.c:224
EFI_STATUS EFIAPI DumpDynPcdMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: DumpDynPcd.c:534
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS GetArg(VOID)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
#define STRING_TOKEN(t)
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
Definition: UefiLibPrint.c:113
EFI_GET_PCD_INFO_PROTOCOL_GET_SKU GetSku
Definition: PiPcdInfo.h:73
EFI_GET_PCD_INFO_PROTOCOL_GET_INFO GetInfo
Definition: PiPcdInfo.h:69
GET_PCD_INFO_PROTOCOL_GET_INFO GetInfo
Definition: PcdInfo.h:93
EFI_PCD_TYPE PcdType
Definition: PiMultiPhase.h:173
CHAR8 * PcdName
Definition: PiMultiPhase.h:185
Definition: Base.h:213