summaryrefslogtreecommitdiffstats
path: root/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c')
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c601
1 files changed, 601 insertions, 0 deletions
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
new file mode 100644
index 0000000000..3bb142538c
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
@@ -0,0 +1,601 @@
+/**
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+#include "AcpiView.h"
+#include "UefiShellAcpiViewCommandLib.h"
+
+EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;
+
+// Report variables
+STATIC UINT32 mSelectedAcpiTable;
+STATIC CONST CHAR16* mSelectedAcpiTableName;
+STATIC BOOLEAN mSelectedAcpiTableFound;
+STATIC EREPORT_OPTION mReportType;
+STATIC UINT32 mTableCount;
+STATIC UINT32 mBinTableCount;
+STATIC BOOLEAN mVerbose;
+STATIC BOOLEAN mConsistencyCheck;
+STATIC BOOLEAN mColourHighlighting;
+
+/** An array of acpiview command line parameters.
+*/
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"/?", TypeFlag},
+ {L"-c", TypeFlag},
+ {L"-d", TypeFlag},
+ {L"-h", TypeValue},
+ {L"-l", TypeFlag},
+ {L"-s", TypeValue},
+ {L"-v", TypeFlag},
+ {NULL, TypeMax}
+};
+
+/** This function returns the colour highlighting status.
+
+ @retval TRUE if colour highlighting is enabled.
+*/
+BOOLEAN
+GetColourHighlighting (
+ VOID
+ )
+{
+ return mColourHighlighting;
+}
+
+/** This function sets the colour highlighting status.
+
+*/
+VOID
+SetColourHighlighting (
+ BOOLEAN Highlight
+ )
+{
+ mColourHighlighting = Highlight;
+}
+
+/** This function returns the report options.
+
+ @retval Returns the report option.
+*/
+STATIC
+EREPORT_OPTION
+GetReportOption (
+ VOID
+ )
+{
+ return mReportType;
+}
+
+/** This function returns the selected ACPI table.
+
+ @retval Returns signature of the selected ACPI table.
+*/
+STATIC
+UINT32
+GetSelectedAcpiTable (
+ VOID
+ )
+{
+ return mSelectedAcpiTable;
+}
+
+/** This function dumps the ACPI table to a file.
+ @param [in] Ptr Pointer to the ACPI table data.
+ @param [in] Length The length of the ACPI table.
+
+ @retval TRUE Success.
+ @retval FALSE Failure.
+*/
+STATIC
+BOOLEAN
+DumpAcpiTableToFile (
+ IN CONST UINT8* Ptr,
+ IN CONST UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
+ SHELL_FILE_HANDLE DumpFileHandle = NULL;
+ UINTN TransferBytes = Length;
+
+ UnicodeSPrint (
+ FileNameBuffer,
+ sizeof (FileNameBuffer),
+ L".\\%s%04d.bin",
+ mSelectedAcpiTableName,
+ mBinTableCount++
+ );
+
+ Status = ShellOpenFileByName (
+ FileNameBuffer,
+ &DumpFileHandle,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_READONLY_MEDIA),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ return FALSE;
+ }
+
+ Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer);
+
+ Status = ShellWriteFile (
+ DumpFileHandle,
+ &TransferBytes,
+ (VOID*)Ptr
+ );
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: Failed to dump table to binary file.\n");
+ TransferBytes = 0;
+ } else {
+ Print (L"DONE.\n");
+ }
+
+ ShellCloseFile (&DumpFileHandle);
+ return (Length == TransferBytes);
+}
+
+/** This function processes the table reporting options for the ACPI table.
+
+ @param [in] Signature The ACPI table Signature.
+ @param [in] TablePtr Pointer to the ACPI table data.
+ @param [in] Length The length fo the ACPI table.
+
+ @retval Returns TRUE if the ACPI table should be traced.
+*/
+BOOLEAN
+ProcessTableReportOptions (
+ IN CONST UINT32 Signature,
+ IN CONST UINT8* TablePtr,
+ IN CONST UINT32 Length
+ )
+{
+ UINTN OriginalAttribute;
+ UINT8* SignaturePtr = (UINT8*)(UINTN)&Signature;
+ BOOLEAN Log = FALSE;
+ BOOLEAN HighLight = GetColourHighlighting ();
+ switch (GetReportOption ()) {
+ case EREPORT_ALL:
+ Log = TRUE;
+ break;
+ case EREPORT_SELECTED:
+ if (Signature == GetSelectedAcpiTable ()) {
+ Log = TRUE;
+ mSelectedAcpiTableFound = TRUE;
+ }
+ break;
+ case EREPORT_TABLE_LIST:
+ if (mTableCount == 0) {
+ if (HighLight) {
+ OriginalAttribute = gST->ConOut->Mode->Attribute;
+ gST->ConOut->SetAttribute (
+ gST->ConOut,
+ EFI_TEXT_ATTR(EFI_CYAN,
+ ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
+ );
+ }
+ Print (L"\nInstalled Table(s):\n");
+ if (HighLight) {
+ gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
+ }
+ }
+ Print (
+ L"\t%4d. %c%c%c%c\n",
+ ++mTableCount,
+ SignaturePtr[0],
+ SignaturePtr[1],
+ SignaturePtr[2],
+ SignaturePtr[3]
+ );
+ break;
+ case EREPORT_DUMP_BIN_FILE:
+ if (Signature == GetSelectedAcpiTable ()) {
+ mSelectedAcpiTableFound = TRUE;
+ DumpAcpiTableToFile (TablePtr, Length);
+ }
+ break;
+ case EREPORT_MAX:
+ // We should never be here.
+ // This case is only present to prevent compiler warning.
+ break;
+ } // switch
+
+ if (Log) {
+ if (HighLight) {
+ OriginalAttribute = gST->ConOut->Mode->Attribute;
+ gST->ConOut->SetAttribute (
+ gST->ConOut,
+ EFI_TEXT_ATTR(EFI_LIGHTBLUE,
+ ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
+ );
+ }
+ Print (
+ L"\n\n --------------- %c%c%c%c Table --------------- \n\n",
+ SignaturePtr[0],
+ SignaturePtr[1],
+ SignaturePtr[2],
+ SignaturePtr[3]
+ );
+ if (HighLight) {
+ gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
+ }
+ }
+
+ return Log;
+}
+
+/** This function converts a string to ACPI table signature.
+
+ @param [in] Str Pointer to the string to be converted to the
+ ACPI table signature.
+
+ @retval The ACPI table signature.
+*/
+STATIC
+UINT32
+ConvertStrToAcpiSignature (
+ IN CONST CHAR16* Str
+ )
+{
+ UINT8 Index = 0;
+ CHAR8 Ptr[4];
+
+ // Convert to Upper case and convert to ASCII
+ while ((Index < 4) && (Str[Index] != 0)) {
+ if (Str[Index] >= L'a' && Str[Index] <= L'z') {
+ Ptr[Index] = (CHAR8)(Str[Index] - (L'a' - L'A'));
+ } else {
+ Ptr[Index] = (CHAR8)Str[Index];
+ }
+ Index++;
+ }
+ return *(UINT32*)Ptr;
+}
+
+/** This function iterates the configuration table entries in the
+ system table, retrieves the RSDP pointer and starts parsing
+ the ACPI tables.
+
+ @param [in] SystemTable Pointer to the EFI system table.
+
+ @retval Returns EFI_NOT_FOUND if the RSDP pointer is not found.
+ Returns EFI_UNSUPPORTED if the RSDP version is less than 2.
+ Returns EFI_SUCCESS if successful.
+*/
+STATIC
+EFI_STATUS
+EFIAPI
+AcpiView (
+ IN EFI_SYSTEM_TABLE* SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_CONFIGURATION_TABLE* EfiConfigurationTable;
+ BOOLEAN FoundAcpiTable;
+ UINTN OriginalAttribute;
+ UINTN PrintAttribute;
+ EREPORT_OPTION ReportOption;
+ UINT8* RsdpPtr;
+ UINT32 RsdpLength;
+ UINT8 RsdpRevision;
+ PARSE_ACPI_TABLE_PROC RsdpParserProc;
+ BOOLEAN Trace;
+
+ // Search the table for an entry that matches the ACPI Table Guid
+ FoundAcpiTable = FALSE;
+ for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
+ if (CompareGuid (&gEfiAcpiTableGuid,
+ &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
+ EfiConfigurationTable = &SystemTable->ConfigurationTable[Index];
+ FoundAcpiTable = TRUE;
+ break;
+ }
+ }
+
+ if (FoundAcpiTable) {
+ RsdpPtr = (UINT8*)EfiConfigurationTable->VendorTable;
+
+ // The RSDP revision is 1 byte starting at offset 15
+ RsdpRevision = *(RsdpPtr + RSDP_REVISION_OFFSET);
+
+ if (RsdpRevision < 2) {
+ Print (
+ L"ERROR: RSDP version less than 2 is not supported.\n"
+ );
+ return EFI_UNSUPPORTED;
+ }
+
+ // The RSDP length is 4 bytes starting at offset 20
+ RsdpLength = *(UINT32*)(RsdpPtr + RSDP_LENGTH_OFFSET);
+
+ Trace = ProcessTableReportOptions (RSDP_TABLE_INFO, RsdpPtr, RsdpLength);
+
+ Status = GetParser (RSDP_TABLE_INFO, &RsdpParserProc);
+ if (EFI_ERROR (Status)) {
+ Print (
+ L"ERROR: No registered parser found for RSDP.\n"
+ );
+ return Status;
+ }
+
+ RsdpParserProc (
+ Trace,
+ RsdpPtr,
+ RsdpLength,
+ RsdpRevision
+ );
+
+ } else {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Failed to find ACPI Table Guid in System Configuration Table.\n"
+ );
+ return EFI_NOT_FOUND;
+ }
+
+ ReportOption = GetReportOption ();
+ if (EREPORT_TABLE_LIST != ReportOption) {
+ if (((EREPORT_SELECTED == ReportOption) ||
+ (EREPORT_DUMP_BIN_FILE == ReportOption)) &&
+ (!mSelectedAcpiTableFound)) {
+ Print (L"\nRequested ACPI Table not found.\n");
+ } else if (EREPORT_DUMP_BIN_FILE != ReportOption) {
+ OriginalAttribute = gST->ConOut->Mode->Attribute;
+
+ Print (L"\nTable Statistics:\n");
+
+ if (GetColourHighlighting ()) {
+ PrintAttribute = (GetErrorCount () > 0) ?
+ EFI_TEXT_ATTR (
+ EFI_RED,
+ ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
+ ) :
+ OriginalAttribute;
+ gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
+ }
+ Print (L"\t%d Error(s)\n", GetErrorCount ());
+
+ if (GetColourHighlighting ()) {
+ PrintAttribute = (GetWarningCount () > 0) ?
+ EFI_TEXT_ATTR (
+ EFI_RED,
+ ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
+ ) :
+ OriginalAttribute;
+
+ gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
+ }
+ Print (L"\t%d Warning(s)\n", GetWarningCount ());
+
+ if (GetColourHighlighting ()) {
+ gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Function for 'acpiview' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+*/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunAcpiView (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE* SystemTable
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus = SHELL_SUCCESS;
+ LIST_ENTRY* Package = NULL;
+ CHAR16* ProblemParam;
+ CONST CHAR16* Temp;
+ CHAR8 ColourOption[8];
+ SHELL_FILE_HANDLE TmpDumpFileHandle = NULL;
+
+ // Set Defaults
+ mReportType = EREPORT_ALL;
+ mTableCount = 0;
+ mBinTableCount = 0;
+ mSelectedAcpiTable = 0;
+ mSelectedAcpiTableName = NULL;
+ mSelectedAcpiTableFound = FALSE;
+ mVerbose = TRUE;
+ mConsistencyCheck = TRUE;
+
+ // Reset The error/warning counters
+ ResetErrorCount ();
+ ResetWarningCount ();
+
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PROBLEM),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ ProblemParam
+ );
+ FreePool (ProblemParam);
+ } else {
+ Print (L"acpiview: Error processing input parameter(s)\n");
+ }
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ if (ShellCommandLineGetCount (Package) > 1) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_TOO_MANY),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetFlag (Package, L"-?")) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GET_HELP_ACPIVIEW),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ } else if (ShellCommandLineGetFlag (Package, L"-s") &&
+ ShellCommandLineGetValue (Package, L"-s") == NULL) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_NO_VALUE),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ L"-s"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if ((ShellCommandLineGetFlag (Package, L"-s") &&
+ ShellCommandLineGetFlag (Package, L"-l"))) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_TOO_MANY),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetFlag (Package, L"-h") &&
+ ShellCommandLineGetValue (Package, L"-h") == NULL) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_NO_VALUE),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ L"-h"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetFlag (Package, L"-d") &&
+ !ShellCommandLineGetFlag (Package, L"-s")) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_MISSING_OPTION),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ L"-s",
+ L"-d"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ // Check if the colour option is set
+ Temp = ShellCommandLineGetValue (Package, L"-h");
+ if (Temp != NULL) {
+ UnicodeStrToAsciiStrS (Temp, ColourOption, sizeof (ColourOption));
+ if ((AsciiStriCmp (ColourOption, "ON") == 0) ||
+ (AsciiStriCmp (ColourOption, "TRUE") == 0)) {
+ SetColourHighlighting (TRUE);
+ } else if ((AsciiStriCmp (ColourOption, "OFF") == 0) ||
+ (AsciiStriCmp (ColourOption, "FALSE") == 0)) {
+ SetColourHighlighting (FALSE);
+ }
+ }
+
+ if (ShellCommandLineGetFlag (Package, L"-l")) {
+ mReportType = EREPORT_TABLE_LIST;
+ } else {
+ mSelectedAcpiTableName = ShellCommandLineGetValue (Package, L"-s");
+ if (mSelectedAcpiTableName != NULL) {
+ mSelectedAcpiTable = (UINT32)ConvertStrToAcpiSignature (
+ mSelectedAcpiTableName
+ );
+ mReportType = EREPORT_SELECTED;
+
+ if (ShellCommandLineGetFlag (Package, L"-d")) {
+ // Create a temporary file to check if the media is writable.
+ CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
+ mReportType = EREPORT_DUMP_BIN_FILE;
+
+ UnicodeSPrint (
+ FileNameBuffer,
+ sizeof (FileNameBuffer),
+ L".\\%s%04d.tmp",
+ mSelectedAcpiTableName,
+ mBinTableCount
+ );
+
+ Status = ShellOpenFileByName (
+ FileNameBuffer,
+ &TmpDumpFileHandle,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |
+ EFI_FILE_MODE_CREATE,
+ 0
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ TmpDumpFileHandle = NULL;
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_READONLY_MEDIA),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ goto Done;
+ }
+ // Delete Temporary file.
+ ShellDeleteFile (&TmpDumpFileHandle);
+ } // -d
+ } // -s
+ }
+
+ // Parse ACPI Table information
+ Status = AcpiView (SystemTable);
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_NOT_FOUND;
+ }
+ }
+ }
+
+Done:
+ if (Package != NULL) {
+ ShellCommandLineFreeVarList (Package);
+ }
+ return ShellStatus;
+}