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