]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
ShellPkg: acpiview: Remove '-v' flag from allowed command line args
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / AcpiView.c
1 /** @file
2
3 Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5 **/
6
7 #include <Library/PrintLib.h>
8 #include <Library/UefiLib.h>
9 #include <Library/ShellLib.h>
10 #include <Library/UefiBootServicesTableLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/MemoryAllocationLib.h>
14 #include "AcpiParser.h"
15 #include "AcpiTableParser.h"
16 #include "AcpiView.h"
17 #include "UefiShellAcpiViewCommandLib.h"
18
19 EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;
20
21 // Report variables
22 STATIC UINT32 mSelectedAcpiTable;
23 STATIC CONST CHAR16* mSelectedAcpiTableName;
24 STATIC BOOLEAN mSelectedAcpiTableFound;
25 STATIC EREPORT_OPTION mReportType;
26 STATIC UINT32 mTableCount;
27 STATIC UINT32 mBinTableCount;
28 STATIC BOOLEAN mConsistencyCheck;
29 STATIC BOOLEAN mColourHighlighting;
30
31 /**
32 An array of acpiview command line parameters.
33 **/
34 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
35 {L"-q", TypeFlag},
36 {L"-d", TypeFlag},
37 {L"-h", TypeValue},
38 {L"-l", TypeFlag},
39 {L"-s", TypeValue},
40 {NULL, TypeMax}
41 };
42
43 /**
44 This function returns the colour highlighting status.
45
46 @retval TRUE if colour highlighting is enabled.
47 **/
48 BOOLEAN
49 GetColourHighlighting (
50 VOID
51 )
52 {
53 return mColourHighlighting;
54 }
55
56 /**
57 This function sets the colour highlighting status.
58
59 @param Highlight The Highlight status.
60
61 **/
62 VOID
63 SetColourHighlighting (
64 BOOLEAN Highlight
65 )
66 {
67 mColourHighlighting = Highlight;
68 }
69
70 /**
71 This function returns the consistency checking status.
72
73 @retval TRUE if consistency checking is enabled.
74 **/
75 BOOLEAN
76 GetConsistencyChecking (
77 VOID
78 )
79 {
80 return mConsistencyCheck;
81 }
82
83 /**
84 This function sets the consistency checking status.
85
86 @param ConsistencyChecking The consistency checking status.
87
88 **/
89 VOID
90 SetConsistencyChecking (
91 BOOLEAN ConsistencyChecking
92 )
93 {
94 mConsistencyCheck = ConsistencyChecking;
95 }
96
97 /**
98 This function returns the report options.
99
100 @retval Returns the report option.
101 **/
102 STATIC
103 EREPORT_OPTION
104 GetReportOption (
105 VOID
106 )
107 {
108 return mReportType;
109 }
110
111 /**
112 This function returns the selected ACPI table.
113
114 @retval Returns signature of the selected ACPI table.
115 **/
116 STATIC
117 UINT32
118 GetSelectedAcpiTable (
119 VOID
120 )
121 {
122 return mSelectedAcpiTable;
123 }
124
125 /**
126 This function dumps the ACPI table to a file.
127
128 @param [in] Ptr Pointer to the ACPI table data.
129 @param [in] Length The length of the ACPI table.
130
131 @retval TRUE Success.
132 @retval FALSE Failure.
133 **/
134 STATIC
135 BOOLEAN
136 DumpAcpiTableToFile (
137 IN CONST UINT8* Ptr,
138 IN CONST UINTN Length
139 )
140 {
141 EFI_STATUS Status;
142 CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
143 SHELL_FILE_HANDLE DumpFileHandle;
144 UINTN TransferBytes;
145
146 DumpFileHandle = NULL;
147 TransferBytes = Length;
148
149 UnicodeSPrint (
150 FileNameBuffer,
151 sizeof (FileNameBuffer),
152 L".\\%s%04d.bin",
153 mSelectedAcpiTableName,
154 mBinTableCount++
155 );
156
157 Status = ShellOpenFileByName (
158 FileNameBuffer,
159 &DumpFileHandle,
160 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
161 0
162 );
163 if (EFI_ERROR (Status)) {
164 ShellPrintHiiEx (
165 -1,
166 -1,
167 NULL,
168 STRING_TOKEN (STR_GEN_READONLY_MEDIA),
169 gShellAcpiViewHiiHandle,
170 L"acpiview"
171 );
172 return FALSE;
173 }
174
175 Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer);
176
177 Status = ShellWriteFile (
178 DumpFileHandle,
179 &TransferBytes,
180 (VOID*)Ptr
181 );
182 if (EFI_ERROR (Status)) {
183 Print (L"ERROR: Failed to dump table to binary file.\n");
184 TransferBytes = 0;
185 } else {
186 Print (L"DONE.\n");
187 }
188
189 ShellCloseFile (&DumpFileHandle);
190 return (Length == TransferBytes);
191 }
192
193 /**
194 This function processes the table reporting options for the ACPI table.
195
196 @param [in] Signature The ACPI table Signature.
197 @param [in] TablePtr Pointer to the ACPI table data.
198 @param [in] Length The length fo the ACPI table.
199
200 @retval Returns TRUE if the ACPI table should be traced.
201 **/
202 BOOLEAN
203 ProcessTableReportOptions (
204 IN CONST UINT32 Signature,
205 IN CONST UINT8* TablePtr,
206 IN CONST UINT32 Length
207 )
208 {
209 UINTN OriginalAttribute;
210 UINT8* SignaturePtr;
211 BOOLEAN Log;
212 BOOLEAN HighLight;
213
214 SignaturePtr = (UINT8*)(UINTN)&Signature;
215 Log = FALSE;
216 HighLight = GetColourHighlighting ();
217
218 switch (GetReportOption ()) {
219 case ReportAll:
220 Log = TRUE;
221 break;
222 case ReportSelected:
223 if (Signature == GetSelectedAcpiTable ()) {
224 Log = TRUE;
225 mSelectedAcpiTableFound = TRUE;
226 }
227 break;
228 case ReportTableList:
229 if (mTableCount == 0) {
230 if (HighLight) {
231 OriginalAttribute = gST->ConOut->Mode->Attribute;
232 gST->ConOut->SetAttribute (
233 gST->ConOut,
234 EFI_TEXT_ATTR(EFI_CYAN,
235 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
236 );
237 }
238 Print (L"\nInstalled Table(s):\n");
239 if (HighLight) {
240 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
241 }
242 }
243 Print (
244 L"\t%4d. %c%c%c%c\n",
245 ++mTableCount,
246 SignaturePtr[0],
247 SignaturePtr[1],
248 SignaturePtr[2],
249 SignaturePtr[3]
250 );
251 break;
252 case ReportDumpBinFile:
253 if (Signature == GetSelectedAcpiTable ()) {
254 mSelectedAcpiTableFound = TRUE;
255 DumpAcpiTableToFile (TablePtr, Length);
256 }
257 break;
258 case ReportMax:
259 // We should never be here.
260 // This case is only present to prevent compiler warning.
261 break;
262 } // switch
263
264 if (Log) {
265 if (HighLight) {
266 OriginalAttribute = gST->ConOut->Mode->Attribute;
267 gST->ConOut->SetAttribute (
268 gST->ConOut,
269 EFI_TEXT_ATTR(EFI_LIGHTBLUE,
270 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
271 );
272 }
273 Print (
274 L"\n\n --------------- %c%c%c%c Table --------------- \n\n",
275 SignaturePtr[0],
276 SignaturePtr[1],
277 SignaturePtr[2],
278 SignaturePtr[3]
279 );
280 if (HighLight) {
281 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
282 }
283 }
284
285 return Log;
286 }
287
288 /**
289 This function converts a string to ACPI table signature.
290
291 @param [in] Str Pointer to the string to be converted to the
292 ACPI table signature.
293
294 @retval The ACPI table signature.
295 **/
296 STATIC
297 UINT32
298 ConvertStrToAcpiSignature (
299 IN CONST CHAR16* Str
300 )
301 {
302 UINT8 Index;
303 CHAR8 Ptr[4];
304
305 ZeroMem (Ptr, sizeof (Ptr));
306 Index = 0;
307
308 // Convert to Upper case and convert to ASCII
309 while ((Index < 4) && (Str[Index] != 0)) {
310 if (Str[Index] >= L'a' && Str[Index] <= L'z') {
311 Ptr[Index] = (CHAR8)(Str[Index] - (L'a' - L'A'));
312 } else {
313 Ptr[Index] = (CHAR8)Str[Index];
314 }
315 Index++;
316 }
317 return *(UINT32*)Ptr;
318 }
319
320 /**
321 This function iterates the configuration table entries in the
322 system table, retrieves the RSDP pointer and starts parsing the ACPI tables.
323
324 @param [in] SystemTable Pointer to the EFI system table.
325
326 @retval Returns EFI_NOT_FOUND if the RSDP pointer is not found.
327 Returns EFI_UNSUPPORTED if the RSDP version is less than 2.
328 Returns EFI_SUCCESS if successful.
329 **/
330 STATIC
331 EFI_STATUS
332 EFIAPI
333 AcpiView (
334 IN EFI_SYSTEM_TABLE* SystemTable
335 )
336 {
337 EFI_STATUS Status;
338 UINTN Index;
339 EFI_CONFIGURATION_TABLE* EfiConfigurationTable;
340 BOOLEAN FoundAcpiTable;
341 UINTN OriginalAttribute;
342 UINTN PrintAttribute;
343 EREPORT_OPTION ReportOption;
344 UINT8* RsdpPtr;
345 UINT32 RsdpLength;
346 UINT8 RsdpRevision;
347 PARSE_ACPI_TABLE_PROC RsdpParserProc;
348 BOOLEAN Trace;
349
350 // Search the table for an entry that matches the ACPI Table Guid
351 FoundAcpiTable = FALSE;
352 for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
353 if (CompareGuid (&gEfiAcpiTableGuid,
354 &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
355 EfiConfigurationTable = &SystemTable->ConfigurationTable[Index];
356 FoundAcpiTable = TRUE;
357 break;
358 }
359 }
360
361 if (FoundAcpiTable) {
362 RsdpPtr = (UINT8*)EfiConfigurationTable->VendorTable;
363
364 // The RSDP revision is 1 byte starting at offset 15
365 RsdpRevision = *(RsdpPtr + RSDP_REVISION_OFFSET);
366
367 if (RsdpRevision < 2) {
368 Print (
369 L"ERROR: RSDP version less than 2 is not supported.\n"
370 );
371 return EFI_UNSUPPORTED;
372 }
373
374 // The RSDP length is 4 bytes starting at offset 20
375 RsdpLength = *(UINT32*)(RsdpPtr + RSDP_LENGTH_OFFSET);
376
377 Trace = ProcessTableReportOptions (RSDP_TABLE_INFO, RsdpPtr, RsdpLength);
378
379 Status = GetParser (RSDP_TABLE_INFO, &RsdpParserProc);
380 if (EFI_ERROR (Status)) {
381 Print (
382 L"ERROR: No registered parser found for RSDP.\n"
383 );
384 return Status;
385 }
386
387 RsdpParserProc (
388 Trace,
389 RsdpPtr,
390 RsdpLength,
391 RsdpRevision
392 );
393
394 } else {
395 IncrementErrorCount ();
396 Print (
397 L"ERROR: Failed to find ACPI Table Guid in System Configuration Table.\n"
398 );
399 return EFI_NOT_FOUND;
400 }
401
402 ReportOption = GetReportOption ();
403 if (ReportTableList != ReportOption) {
404 if (((ReportSelected == ReportOption) ||
405 (ReportDumpBinFile == ReportOption)) &&
406 (!mSelectedAcpiTableFound)) {
407 Print (L"\nRequested ACPI Table not found.\n");
408 } else if (GetConsistencyChecking () &&
409 (ReportDumpBinFile != ReportOption)) {
410 OriginalAttribute = gST->ConOut->Mode->Attribute;
411
412 Print (L"\nTable Statistics:\n");
413
414 if (GetColourHighlighting ()) {
415 PrintAttribute = (GetErrorCount () > 0) ?
416 EFI_TEXT_ATTR (
417 EFI_RED,
418 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
419 ) :
420 OriginalAttribute;
421 gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
422 }
423 Print (L"\t%d Error(s)\n", GetErrorCount ());
424
425 if (GetColourHighlighting ()) {
426 PrintAttribute = (GetWarningCount () > 0) ?
427 EFI_TEXT_ATTR (
428 EFI_RED,
429 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
430 ) :
431 OriginalAttribute;
432
433 gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
434 }
435 Print (L"\t%d Warning(s)\n", GetWarningCount ());
436
437 if (GetColourHighlighting ()) {
438 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
439 }
440 }
441 }
442 return EFI_SUCCESS;
443 }
444
445 /**
446 Function for 'acpiview' command.
447
448 @param[in] ImageHandle Handle to the Image (NULL if Internal).
449 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
450 **/
451 SHELL_STATUS
452 EFIAPI
453 ShellCommandRunAcpiView (
454 IN EFI_HANDLE ImageHandle,
455 IN EFI_SYSTEM_TABLE* SystemTable
456 )
457 {
458 EFI_STATUS Status;
459 SHELL_STATUS ShellStatus;
460 LIST_ENTRY* Package;
461 CHAR16* ProblemParam;
462 CONST CHAR16* Temp;
463 CHAR8 ColourOption[8];
464 SHELL_FILE_HANDLE TmpDumpFileHandle;
465
466 // Set Defaults
467 mReportType = ReportAll;
468 mTableCount = 0;
469 mBinTableCount = 0;
470 mSelectedAcpiTable = 0;
471 mSelectedAcpiTableName = NULL;
472 mSelectedAcpiTableFound = FALSE;
473 mConsistencyCheck = TRUE;
474
475 ShellStatus = SHELL_SUCCESS;
476 Package = NULL;
477 TmpDumpFileHandle = NULL;
478
479 // Reset The error/warning counters
480 ResetErrorCount ();
481 ResetWarningCount ();
482
483 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
484 if (EFI_ERROR (Status)) {
485 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
486 ShellPrintHiiEx (
487 -1,
488 -1,
489 NULL,
490 STRING_TOKEN (STR_GEN_PROBLEM),
491 gShellAcpiViewHiiHandle,
492 L"acpiview",
493 ProblemParam
494 );
495 FreePool (ProblemParam);
496 } else {
497 Print (L"acpiview: Error processing input parameter(s)\n");
498 }
499 ShellStatus = SHELL_INVALID_PARAMETER;
500 } else {
501 if (ShellCommandLineGetCount (Package) > 1) {
502 ShellPrintHiiEx (
503 -1,
504 -1,
505 NULL,
506 STRING_TOKEN (STR_GEN_TOO_MANY),
507 gShellAcpiViewHiiHandle,
508 L"acpiview"
509 );
510 ShellStatus = SHELL_INVALID_PARAMETER;
511 } else if (ShellCommandLineGetFlag (Package, L"-?")) {
512 ShellPrintHiiEx (
513 -1,
514 -1,
515 NULL,
516 STRING_TOKEN (STR_GET_HELP_ACPIVIEW),
517 gShellAcpiViewHiiHandle,
518 L"acpiview"
519 );
520 } else if (ShellCommandLineGetFlag (Package, L"-s") &&
521 ShellCommandLineGetValue (Package, L"-s") == NULL) {
522 ShellPrintHiiEx (
523 -1,
524 -1,
525 NULL,
526 STRING_TOKEN (STR_GEN_NO_VALUE),
527 gShellAcpiViewHiiHandle,
528 L"acpiview",
529 L"-s"
530 );
531 ShellStatus = SHELL_INVALID_PARAMETER;
532 } else if ((ShellCommandLineGetFlag (Package, L"-s") &&
533 ShellCommandLineGetFlag (Package, L"-l"))) {
534 ShellPrintHiiEx (
535 -1,
536 -1,
537 NULL,
538 STRING_TOKEN (STR_GEN_TOO_MANY),
539 gShellAcpiViewHiiHandle,
540 L"acpiview"
541 );
542 ShellStatus = SHELL_INVALID_PARAMETER;
543 } else if (ShellCommandLineGetFlag (Package, L"-h") &&
544 ShellCommandLineGetValue (Package, L"-h") == NULL) {
545 ShellPrintHiiEx (
546 -1,
547 -1,
548 NULL,
549 STRING_TOKEN (STR_GEN_NO_VALUE),
550 gShellAcpiViewHiiHandle,
551 L"acpiview",
552 L"-h"
553 );
554 ShellStatus = SHELL_INVALID_PARAMETER;
555 } else if (ShellCommandLineGetFlag (Package, L"-d") &&
556 !ShellCommandLineGetFlag (Package, L"-s")) {
557 ShellPrintHiiEx (
558 -1,
559 -1,
560 NULL,
561 STRING_TOKEN (STR_GEN_MISSING_OPTION),
562 gShellAcpiViewHiiHandle,
563 L"acpiview",
564 L"-s",
565 L"-d"
566 );
567 ShellStatus = SHELL_INVALID_PARAMETER;
568 } else {
569 // Check if the colour option is set
570 Temp = ShellCommandLineGetValue (Package, L"-h");
571 if (Temp != NULL) {
572 UnicodeStrToAsciiStrS (Temp, ColourOption, sizeof (ColourOption));
573 if ((AsciiStriCmp (ColourOption, "ON") == 0) ||
574 (AsciiStriCmp (ColourOption, "TRUE") == 0)) {
575 SetColourHighlighting (TRUE);
576 } else if ((AsciiStriCmp (ColourOption, "OFF") == 0) ||
577 (AsciiStriCmp (ColourOption, "FALSE") == 0)) {
578 SetColourHighlighting (FALSE);
579 }
580 }
581
582 // Surpress consistency checking if requested
583 SetConsistencyChecking (!ShellCommandLineGetFlag (Package, L"-q"));
584
585 if (ShellCommandLineGetFlag (Package, L"-l")) {
586 mReportType = ReportTableList;
587 } else {
588 mSelectedAcpiTableName = ShellCommandLineGetValue (Package, L"-s");
589 if (mSelectedAcpiTableName != NULL) {
590 mSelectedAcpiTable = (UINT32)ConvertStrToAcpiSignature (
591 mSelectedAcpiTableName
592 );
593 mReportType = ReportSelected;
594
595 if (ShellCommandLineGetFlag (Package, L"-d")) {
596 // Create a temporary file to check if the media is writable.
597 CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
598 mReportType = ReportDumpBinFile;
599
600 UnicodeSPrint (
601 FileNameBuffer,
602 sizeof (FileNameBuffer),
603 L".\\%s%04d.tmp",
604 mSelectedAcpiTableName,
605 mBinTableCount
606 );
607
608 Status = ShellOpenFileByName (
609 FileNameBuffer,
610 &TmpDumpFileHandle,
611 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |
612 EFI_FILE_MODE_CREATE,
613 0
614 );
615
616 if (EFI_ERROR (Status)) {
617 ShellStatus = SHELL_INVALID_PARAMETER;
618 TmpDumpFileHandle = NULL;
619 ShellPrintHiiEx (
620 -1,
621 -1,
622 NULL,
623 STRING_TOKEN (STR_GEN_READONLY_MEDIA),
624 gShellAcpiViewHiiHandle,
625 L"acpiview"
626 );
627 goto Done;
628 }
629 // Delete Temporary file.
630 ShellDeleteFile (&TmpDumpFileHandle);
631 } // -d
632 } // -s
633 }
634
635 // Parse ACPI Table information
636 Status = AcpiView (SystemTable);
637 if (EFI_ERROR (Status)) {
638 ShellStatus = SHELL_NOT_FOUND;
639 }
640 }
641 }
642
643 Done:
644 if (Package != NULL) {
645 ShellCommandLineFreeVarList (Package);
646 }
647 return ShellStatus;
648 }