3 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
4 SPDX-License-Identifier: BSD-2-Clause-Patent
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"
17 #include "UefiShellAcpiViewCommandLib.h"
19 EFI_HII_HANDLE gShellAcpiViewHiiHandle
= NULL
;
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 STATIC BOOLEAN mMandatoryTableValidate
;
31 STATIC UINTN mMandatoryTableSpec
;
34 An array of acpiview command line parameters.
36 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
47 This function returns the colour highlighting status.
49 @retval TRUE if colour highlighting is enabled.
52 GetColourHighlighting (
56 return mColourHighlighting
;
60 This function sets the colour highlighting status.
62 @param Highlight The Highlight status.
66 SetColourHighlighting (
70 mColourHighlighting
= Highlight
;
74 This function returns the consistency checking status.
76 @retval TRUE if consistency checking is enabled.
79 GetConsistencyChecking (
83 return mConsistencyCheck
;
87 This function sets the consistency checking status.
89 @param ConsistencyChecking The consistency checking status.
93 SetConsistencyChecking (
94 BOOLEAN ConsistencyChecking
97 mConsistencyCheck
= ConsistencyChecking
;
101 This function returns the ACPI table requirements validation flag.
103 @retval TRUE if check for mandatory table presence should be performed.
106 GetMandatoryTableValidate (
110 return mMandatoryTableValidate
;
114 This function sets the ACPI table requirements validation flag.
116 @param Validate Enable/Disable ACPI table requirements validation.
119 SetMandatoryTableValidate (
123 mMandatoryTableValidate
= Validate
;
127 This function returns the identifier of specification to validate ACPI table
128 requirements against.
130 @return ID of specification listing mandatory tables.
133 GetMandatoryTableSpec (
137 return mMandatoryTableSpec
;
141 This function sets the identifier of specification to validate ACPI table
142 requirements against.
144 @param Spec ID of specification listing mandatory tables.
147 SetMandatoryTableSpec (
151 mMandatoryTableSpec
= Spec
;
155 This function returns the report options.
157 @retval Returns the report option.
169 This function returns the selected ACPI table.
171 @retval Returns signature of the selected ACPI table.
175 GetSelectedAcpiTable (
179 return mSelectedAcpiTable
;
183 This function dumps the ACPI table to a file.
185 @param [in] Ptr Pointer to the ACPI table data.
186 @param [in] Length The length of the ACPI table.
188 @retval TRUE Success.
189 @retval FALSE Failure.
193 DumpAcpiTableToFile (
195 IN CONST UINTN Length
199 CHAR16 FileNameBuffer
[MAX_FILE_NAME_LEN
];
200 SHELL_FILE_HANDLE DumpFileHandle
;
203 DumpFileHandle
= NULL
;
204 TransferBytes
= Length
;
208 sizeof (FileNameBuffer
),
210 mSelectedAcpiTableName
,
214 Status
= ShellOpenFileByName (
217 EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
,
220 if (EFI_ERROR (Status
)) {
225 STRING_TOKEN (STR_GEN_READONLY_MEDIA
),
226 gShellAcpiViewHiiHandle
,
232 Print (L
"Dumping ACPI table to : %s ... ", FileNameBuffer
);
234 Status
= ShellWriteFile (
239 if (EFI_ERROR (Status
)) {
240 Print (L
"ERROR: Failed to dump table to binary file.\n");
246 ShellCloseFile (&DumpFileHandle
);
247 return (Length
== TransferBytes
);
251 This function processes the table reporting options for the ACPI table.
253 @param [in] Signature The ACPI table Signature.
254 @param [in] TablePtr Pointer to the ACPI table data.
255 @param [in] Length The length fo the ACPI table.
257 @retval Returns TRUE if the ACPI table should be traced.
260 ProcessTableReportOptions (
261 IN CONST UINT32 Signature
,
262 IN CONST UINT8
* TablePtr
,
263 IN CONST UINT32 Length
266 UINTN OriginalAttribute
;
272 // set local variables to suppress incorrect compiler/analyzer warnings
274 OriginalAttribute
= 0;
275 SignaturePtr
= (UINT8
*)(UINTN
)&Signature
;
277 HighLight
= GetColourHighlighting ();
279 switch (GetReportOption ()) {
284 if (Signature
== GetSelectedAcpiTable ()) {
286 mSelectedAcpiTableFound
= TRUE
;
289 case ReportTableList
:
290 if (mTableCount
== 0) {
292 OriginalAttribute
= gST
->ConOut
->Mode
->Attribute
;
293 gST
->ConOut
->SetAttribute (
295 EFI_TEXT_ATTR(EFI_CYAN
,
296 ((OriginalAttribute
&(BIT4
|BIT5
|BIT6
))>>4))
299 Print (L
"\nInstalled Table(s):\n");
301 gST
->ConOut
->SetAttribute (gST
->ConOut
, OriginalAttribute
);
305 L
"\t%4d. %c%c%c%c\n",
313 case ReportDumpBinFile
:
314 if (Signature
== GetSelectedAcpiTable ()) {
315 mSelectedAcpiTableFound
= TRUE
;
316 DumpAcpiTableToFile (TablePtr
, Length
);
320 // We should never be here.
321 // This case is only present to prevent compiler warning.
327 OriginalAttribute
= gST
->ConOut
->Mode
->Attribute
;
328 gST
->ConOut
->SetAttribute (
330 EFI_TEXT_ATTR(EFI_LIGHTBLUE
,
331 ((OriginalAttribute
&(BIT4
|BIT5
|BIT6
))>>4))
335 L
"\n\n --------------- %c%c%c%c Table --------------- \n\n",
342 gST
->ConOut
->SetAttribute (gST
->ConOut
, OriginalAttribute
);
350 This function converts a string to ACPI table signature.
352 @param [in] Str Pointer to the string to be converted to the
353 ACPI table signature.
355 @retval The ACPI table signature.
359 ConvertStrToAcpiSignature (
366 ZeroMem (Ptr
, sizeof (Ptr
));
369 // Convert to Upper case and convert to ASCII
370 while ((Index
< 4) && (Str
[Index
] != 0)) {
371 if (Str
[Index
] >= L
'a' && Str
[Index
] <= L
'z') {
372 Ptr
[Index
] = (CHAR8
)(Str
[Index
] - (L
'a' - L
'A'));
374 Ptr
[Index
] = (CHAR8
)Str
[Index
];
378 return *(UINT32
*)Ptr
;
382 This function iterates the configuration table entries in the
383 system table, retrieves the RSDP pointer and starts parsing the ACPI tables.
385 @param [in] SystemTable Pointer to the EFI system table.
387 @retval Returns EFI_NOT_FOUND if the RSDP pointer is not found.
388 Returns EFI_UNSUPPORTED if the RSDP version is less than 2.
389 Returns EFI_SUCCESS if successful.
395 IN EFI_SYSTEM_TABLE
* SystemTable
400 EFI_CONFIGURATION_TABLE
* EfiConfigurationTable
;
401 BOOLEAN FoundAcpiTable
;
402 UINTN OriginalAttribute
;
403 UINTN PrintAttribute
;
404 EREPORT_OPTION ReportOption
;
408 PARSE_ACPI_TABLE_PROC RsdpParserProc
;
412 // set local variables to suppress incorrect compiler/analyzer warnings
414 EfiConfigurationTable
= NULL
;
415 OriginalAttribute
= 0;
417 // Search the table for an entry that matches the ACPI Table Guid
418 FoundAcpiTable
= FALSE
;
419 for (Index
= 0; Index
< SystemTable
->NumberOfTableEntries
; Index
++) {
420 if (CompareGuid (&gEfiAcpiTableGuid
,
421 &(SystemTable
->ConfigurationTable
[Index
].VendorGuid
))) {
422 EfiConfigurationTable
= &SystemTable
->ConfigurationTable
[Index
];
423 FoundAcpiTable
= TRUE
;
428 if (FoundAcpiTable
) {
429 RsdpPtr
= (UINT8
*)EfiConfigurationTable
->VendorTable
;
431 // The RSDP revision is 1 byte starting at offset 15
432 RsdpRevision
= *(RsdpPtr
+ RSDP_REVISION_OFFSET
);
434 if (RsdpRevision
< 2) {
436 L
"ERROR: RSDP version less than 2 is not supported.\n"
438 return EFI_UNSUPPORTED
;
441 // The RSDP length is 4 bytes starting at offset 20
442 RsdpLength
= *(UINT32
*)(RsdpPtr
+ RSDP_LENGTH_OFFSET
);
444 Trace
= ProcessTableReportOptions (RSDP_TABLE_INFO
, RsdpPtr
, RsdpLength
);
446 Status
= GetParser (RSDP_TABLE_INFO
, &RsdpParserProc
);
447 if (EFI_ERROR (Status
)) {
449 L
"ERROR: No registered parser found for RSDP.\n"
462 IncrementErrorCount ();
464 L
"ERROR: Failed to find ACPI Table Guid in System Configuration Table.\n"
466 return EFI_NOT_FOUND
;
469 ReportOption
= GetReportOption ();
470 if (ReportTableList
!= ReportOption
) {
471 if (((ReportSelected
== ReportOption
) ||
472 (ReportDumpBinFile
== ReportOption
)) &&
473 (!mSelectedAcpiTableFound
)) {
474 Print (L
"\nRequested ACPI Table not found.\n");
475 } else if (GetConsistencyChecking () &&
476 (ReportDumpBinFile
!= ReportOption
)) {
477 OriginalAttribute
= gST
->ConOut
->Mode
->Attribute
;
479 Print (L
"\nTable Statistics:\n");
481 if (GetColourHighlighting ()) {
482 PrintAttribute
= (GetErrorCount () > 0) ?
485 ((OriginalAttribute
&(BIT4
|BIT5
|BIT6
))>>4)
488 gST
->ConOut
->SetAttribute (gST
->ConOut
, PrintAttribute
);
490 Print (L
"\t%d Error(s)\n", GetErrorCount ());
492 if (GetColourHighlighting ()) {
493 PrintAttribute
= (GetWarningCount () > 0) ?
496 ((OriginalAttribute
&(BIT4
|BIT5
|BIT6
))>>4)
500 gST
->ConOut
->SetAttribute (gST
->ConOut
, PrintAttribute
);
502 Print (L
"\t%d Warning(s)\n", GetWarningCount ());
504 if (GetColourHighlighting ()) {
505 gST
->ConOut
->SetAttribute (gST
->ConOut
, OriginalAttribute
);
513 Function for 'acpiview' command.
515 @param[in] ImageHandle Handle to the Image (NULL if Internal).
516 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
520 ShellCommandRunAcpiView (
521 IN EFI_HANDLE ImageHandle
,
522 IN EFI_SYSTEM_TABLE
* SystemTable
526 SHELL_STATUS ShellStatus
;
528 CHAR16
* ProblemParam
;
529 SHELL_FILE_HANDLE TmpDumpFileHandle
;
530 CONST CHAR16
* MandatoryTableSpecStr
;
533 mReportType
= ReportAll
;
536 mSelectedAcpiTable
= 0;
537 mSelectedAcpiTableName
= NULL
;
538 mSelectedAcpiTableFound
= FALSE
;
539 mConsistencyCheck
= TRUE
;
540 mMandatoryTableValidate
= FALSE
;
541 mMandatoryTableSpec
= 0;
543 ShellStatus
= SHELL_SUCCESS
;
545 TmpDumpFileHandle
= NULL
;
547 // Reset The error/warning counters
549 ResetWarningCount ();
551 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
552 if (EFI_ERROR (Status
)) {
553 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
558 STRING_TOKEN (STR_GEN_PROBLEM
),
559 gShellAcpiViewHiiHandle
,
563 FreePool (ProblemParam
);
565 Print (L
"acpiview: Error processing input parameter(s)\n");
567 ShellStatus
= SHELL_INVALID_PARAMETER
;
569 if (ShellCommandLineGetCount (Package
) > 1) {
574 STRING_TOKEN (STR_GEN_TOO_MANY
),
575 gShellAcpiViewHiiHandle
,
578 ShellStatus
= SHELL_INVALID_PARAMETER
;
579 } else if (ShellCommandLineGetFlag (Package
, L
"-?")) {
584 STRING_TOKEN (STR_GET_HELP_ACPIVIEW
),
585 gShellAcpiViewHiiHandle
,
588 } else if (ShellCommandLineGetFlag (Package
, L
"-s") &&
589 ShellCommandLineGetValue (Package
, L
"-s") == NULL
) {
594 STRING_TOKEN (STR_GEN_NO_VALUE
),
595 gShellAcpiViewHiiHandle
,
599 ShellStatus
= SHELL_INVALID_PARAMETER
;
600 } else if (ShellCommandLineGetFlag (Package
, L
"-r") &&
601 ShellCommandLineGetValue (Package
, L
"-r") == NULL
) {
606 STRING_TOKEN (STR_GEN_NO_VALUE
),
607 gShellAcpiViewHiiHandle
,
611 ShellStatus
= SHELL_INVALID_PARAMETER
;
612 } else if ((ShellCommandLineGetFlag (Package
, L
"-s") &&
613 ShellCommandLineGetFlag (Package
, L
"-l"))) {
618 STRING_TOKEN (STR_GEN_TOO_MANY
),
619 gShellAcpiViewHiiHandle
,
622 ShellStatus
= SHELL_INVALID_PARAMETER
;
623 } else if (ShellCommandLineGetFlag (Package
, L
"-d") &&
624 !ShellCommandLineGetFlag (Package
, L
"-s")) {
629 STRING_TOKEN (STR_GEN_MISSING_OPTION
),
630 gShellAcpiViewHiiHandle
,
635 ShellStatus
= SHELL_INVALID_PARAMETER
;
637 // Turn on colour highlighting if requested
638 SetColourHighlighting (ShellCommandLineGetFlag (Package
, L
"-h"));
640 // Surpress consistency checking if requested
641 SetConsistencyChecking (!ShellCommandLineGetFlag (Package
, L
"-q"));
643 // Evaluate the parameters for mandatory ACPI table presence checks
644 SetMandatoryTableValidate (ShellCommandLineGetFlag (Package
, L
"-r"));
645 MandatoryTableSpecStr
= ShellCommandLineGetValue (Package
, L
"-r");
647 if (MandatoryTableSpecStr
!= NULL
) {
648 SetMandatoryTableSpec (ShellHexStrToUintn (MandatoryTableSpecStr
));
651 if (ShellCommandLineGetFlag (Package
, L
"-l")) {
652 mReportType
= ReportTableList
;
654 mSelectedAcpiTableName
= ShellCommandLineGetValue (Package
, L
"-s");
655 if (mSelectedAcpiTableName
!= NULL
) {
656 mSelectedAcpiTable
= (UINT32
)ConvertStrToAcpiSignature (
657 mSelectedAcpiTableName
659 mReportType
= ReportSelected
;
661 if (ShellCommandLineGetFlag (Package
, L
"-d")) {
662 // Create a temporary file to check if the media is writable.
663 CHAR16 FileNameBuffer
[MAX_FILE_NAME_LEN
];
664 mReportType
= ReportDumpBinFile
;
668 sizeof (FileNameBuffer
),
670 mSelectedAcpiTableName
,
674 Status
= ShellOpenFileByName (
677 EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
|
678 EFI_FILE_MODE_CREATE
,
682 if (EFI_ERROR (Status
)) {
683 ShellStatus
= SHELL_INVALID_PARAMETER
;
684 TmpDumpFileHandle
= NULL
;
689 STRING_TOKEN (STR_GEN_READONLY_MEDIA
),
690 gShellAcpiViewHiiHandle
,
695 // Delete Temporary file.
696 ShellDeleteFile (&TmpDumpFileHandle
);
701 // Parse ACPI Table information
702 Status
= AcpiView (SystemTable
);
703 if (EFI_ERROR (Status
)) {
704 ShellStatus
= SHELL_NOT_FOUND
;
710 if (Package
!= NULL
) {
711 ShellCommandLineFreeVarList (Package
);