The UefiShellAcpiViewCommandLib is converted from NULL library to a named library so that it may be used in modules other than shell. The library interface exposes the main method for to AcpiView functionality as well as a helper method to dump a buffer to a file. The Shell module is still built by pulling UefiShellAcpiViewCommandLib as a NULL library to preserve the modularity of shell builds. Cc: Ray Ni <ray.ni@intel.com> Cc: Zhichao Gao <zhichao.gao@intel.com> Reviewed-by: Zhichao Gao <zhichao.gao@intel.com> Signed-off-by: Tomas Pilar <tomas.pilar@arm.com>
		
			
				
	
	
		
			443 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			443 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Main file for 'acpiview' Shell command function.
 | 
						|
 | 
						|
  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
**/
 | 
						|
 | 
						|
#include <Guid/ShellLibHiiGuid.h>
 | 
						|
#include <IndustryStandard/Acpi.h>
 | 
						|
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/HiiLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/PrintLib.h>
 | 
						|
#include <Library/ShellCommandLib.h>
 | 
						|
#include <Library/ShellLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Library/UefiLib.h>
 | 
						|
#include <Library/AcpiViewCommandLib.h>
 | 
						|
#include <Uefi.h>
 | 
						|
 | 
						|
#include "AcpiParser.h"
 | 
						|
#include "AcpiTableParser.h"
 | 
						|
#include "AcpiView.h"
 | 
						|
#include "AcpiViewConfig.h"
 | 
						|
 | 
						|
CONST CHAR16 gShellAcpiViewFileName[] = L"ShellCommand";
 | 
						|
EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;
 | 
						|
 | 
						|
/**
 | 
						|
  An array of acpiview command line parameters.
 | 
						|
**/
 | 
						|
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
 | 
						|
  {L"-q", TypeFlag},
 | 
						|
  {L"-d", TypeFlag},
 | 
						|
  {L"-h", TypeFlag},
 | 
						|
  {L"-l", TypeFlag},
 | 
						|
  {L"-s", TypeValue},
 | 
						|
  {L"-r", TypeValue},
 | 
						|
  {NULL, TypeMax}
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  A list of available table parsers.
 | 
						|
*/
 | 
						|
STATIC
 | 
						|
CONST
 | 
						|
ACPI_TABLE_PARSER ParserList[] = {
 | 
						|
  {EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE, ParseAcpiBgrt},
 | 
						|
  {EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, ParseAcpiDbg2},
 | 
						|
  {EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
 | 
						|
   ParseAcpiDsdt},
 | 
						|
  {EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs},
 | 
						|
  {EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt},
 | 
						|
  {EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt},
 | 
						|
  {EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, ParseAcpiIort},
 | 
						|
  {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt},
 | 
						|
  {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
 | 
						|
   ParseAcpiMcfg},
 | 
						|
  {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
 | 
						|
   ParseAcpiPptt},
 | 
						|
  {RSDP_TABLE_INFO, ParseAcpiRsdp},
 | 
						|
  {EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, ParseAcpiSlit},
 | 
						|
  {EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, ParseAcpiSpcr},
 | 
						|
  {EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, ParseAcpiSrat},
 | 
						|
  {EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiSsdt},
 | 
						|
  {EFI_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiXsdt}
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  This function registers all the available table parsers.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The parser is registered.
 | 
						|
  @retval EFI_ALREADY_STARTED   The parser for the ACPI Table
 | 
						|
                                was already registered.
 | 
						|
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  No space to register the
 | 
						|
                                parser.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
RegisterAllParsers (
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
  UINTN Count;
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  Count = sizeof (ParserList) / sizeof (ParserList[0]);
 | 
						|
 | 
						|
  while (Count-- != 0) {
 | 
						|
    Status = RegisterParser (
 | 
						|
               ParserList[Count].Signature,
 | 
						|
               ParserList[Count].Parser
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dump a buffer to a file. Print error message if a file cannot be created.
 | 
						|
 | 
						|
  @param[in] FileName   The filename that shall be created to contain the buffer.
 | 
						|
  @param[in] Buffer     Pointer to buffer that shall be dumped.
 | 
						|
  @param[in] BufferSize The size of buffer to be dumped in bytes.
 | 
						|
 | 
						|
  @return The number of bytes that were written
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
ShellDumpBufferToFile (
 | 
						|
  IN CONST CHAR16* FileNameBuffer,
 | 
						|
  IN CONST VOID*   Buffer,
 | 
						|
  IN CONST UINTN   BufferSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  SHELL_FILE_HANDLE   DumpFileHandle;
 | 
						|
  UINTN               TransferBytes;
 | 
						|
 | 
						|
  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 0;
 | 
						|
  }
 | 
						|
 | 
						|
  TransferBytes = BufferSize;
 | 
						|
  Status = ShellWriteFile (
 | 
						|
             DumpFileHandle,
 | 
						|
             &TransferBytes,
 | 
						|
             (VOID *) Buffer
 | 
						|
             );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    Print (L"ERROR: Failed to write binary file.\n");
 | 
						|
    TransferBytes = 0;
 | 
						|
  } else {
 | 
						|
    Print (L"DONE.\n");
 | 
						|
  }
 | 
						|
 | 
						|
  ShellCloseFile (&DumpFileHandle);
 | 
						|
  return TransferBytes;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return the file name of the help text file if not using HII.
 | 
						|
 | 
						|
  @return The string pointer to the file name.
 | 
						|
**/
 | 
						|
CONST CHAR16*
 | 
						|
EFIAPI
 | 
						|
ShellCommandGetManFileNameAcpiView (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  return gShellAcpiViewFileName;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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).
 | 
						|
 | 
						|
  @retval SHELL_INVALID_PARAMETER The command line invocation could not be parsed
 | 
						|
  @retval SHELL_NOT_FOUND         The command failed
 | 
						|
  @retval SHELL_SUCCESS           The command was successful
 | 
						|
**/
 | 
						|
SHELL_STATUS
 | 
						|
EFIAPI
 | 
						|
ShellCommandRunAcpiView (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE* SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS         Status;
 | 
						|
  SHELL_STATUS       ShellStatus;
 | 
						|
  LIST_ENTRY*        Package;
 | 
						|
  CHAR16*            ProblemParam;
 | 
						|
  SHELL_FILE_HANDLE  TmpDumpFileHandle;
 | 
						|
  CONST CHAR16*      MandatoryTableSpecStr;
 | 
						|
  CONST CHAR16*      SelectedTableName;
 | 
						|
 | 
						|
  // Set configuration defaults
 | 
						|
  AcpiConfigSetDefaults ();
 | 
						|
 | 
						|
  ShellStatus = SHELL_SUCCESS;
 | 
						|
  Package = NULL;
 | 
						|
  TmpDumpFileHandle = NULL;
 | 
						|
 | 
						|
  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"-r") &&
 | 
						|
               ShellCommandLineGetValue (Package, L"-r") == NULL) {
 | 
						|
      ShellPrintHiiEx (
 | 
						|
        -1,
 | 
						|
        -1,
 | 
						|
        NULL,
 | 
						|
        STRING_TOKEN (STR_GEN_NO_VALUE),
 | 
						|
        gShellAcpiViewHiiHandle,
 | 
						|
        L"acpiview",
 | 
						|
        L"-r"
 | 
						|
        );
 | 
						|
      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"-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 {
 | 
						|
      // Turn on colour highlighting if requested
 | 
						|
      SetColourHighlighting (ShellCommandLineGetFlag (Package, L"-h"));
 | 
						|
 | 
						|
      // Surpress consistency checking if requested
 | 
						|
      SetConsistencyChecking (!ShellCommandLineGetFlag (Package, L"-q"));
 | 
						|
 | 
						|
      // Evaluate the parameters for mandatory ACPI table presence checks
 | 
						|
      SetMandatoryTableValidate (ShellCommandLineGetFlag (Package, L"-r"));
 | 
						|
      MandatoryTableSpecStr = ShellCommandLineGetValue (Package, L"-r");
 | 
						|
 | 
						|
      if (MandatoryTableSpecStr != NULL) {
 | 
						|
        SetMandatoryTableSpec (ShellHexStrToUintn (MandatoryTableSpecStr));
 | 
						|
      }
 | 
						|
 | 
						|
      if (ShellCommandLineGetFlag (Package, L"-l")) {
 | 
						|
        SetReportOption (ReportTableList);
 | 
						|
      } else {
 | 
						|
        SelectedTableName = ShellCommandLineGetValue (Package, L"-s");
 | 
						|
        if (SelectedTableName != NULL) {
 | 
						|
          SelectAcpiTable (SelectedTableName);
 | 
						|
          SetReportOption (ReportSelected);
 | 
						|
 | 
						|
          if (ShellCommandLineGetFlag (Package, L"-d"))  {
 | 
						|
            // Create a temporary file to check if the media is writable.
 | 
						|
            CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
 | 
						|
            SetReportOption (ReportDumpBinFile);
 | 
						|
 | 
						|
            UnicodeSPrint (
 | 
						|
              FileNameBuffer,
 | 
						|
              sizeof (FileNameBuffer),
 | 
						|
              L".\\%s0000.tmp",
 | 
						|
              SelectedTableName
 | 
						|
              );
 | 
						|
 | 
						|
            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;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Constructor for the Shell AcpiView Command library.
 | 
						|
 | 
						|
  Install the handlers for acpiview UEFI Shell command.
 | 
						|
 | 
						|
  @param ImageHandle            The image handle of the process.
 | 
						|
  @param SystemTable            The EFI System Table pointer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The Shell command handlers were installed
 | 
						|
                                successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR      Hii package failed to install.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UefiShellAcpiViewCommandLibConstructor (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
  gShellAcpiViewHiiHandle = NULL;
 | 
						|
 | 
						|
  // Check Shell Profile Debug1 bit of the profiles mask
 | 
						|
  if ((PcdGet8 (PcdShellProfileMask) & BIT1) == 0) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = RegisterAllParsers ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    Print (L"acpiview: Error failed to register parser.\n");
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  gShellAcpiViewHiiHandle = HiiAddPackages (
 | 
						|
                              &gShellAcpiViewHiiGuid,
 | 
						|
                              gImageHandle,
 | 
						|
                              UefiShellAcpiViewCommandLibStrings,
 | 
						|
                              NULL
 | 
						|
                              );
 | 
						|
  if (gShellAcpiViewHiiHandle == NULL) {
 | 
						|
    return EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
  // Install our Shell command handler
 | 
						|
  ShellCommandRegisterCommandName (
 | 
						|
    L"acpiview",
 | 
						|
    ShellCommandRunAcpiView,
 | 
						|
    ShellCommandGetManFileNameAcpiView,
 | 
						|
    0,
 | 
						|
    L"acpiview",
 | 
						|
    TRUE,
 | 
						|
    gShellAcpiViewHiiHandle,
 | 
						|
    STRING_TOKEN (STR_GET_HELP_ACPIVIEW)
 | 
						|
    );
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Destructor for the library. free any resources.
 | 
						|
 | 
						|
  @param ImageHandle            The image handle of the process.
 | 
						|
  @param SystemTable            The EFI System Table pointer.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UefiShellAcpiViewCommandLibDestructor (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (gShellAcpiViewHiiHandle != NULL) {
 | 
						|
    HiiRemovePackages (gShellAcpiViewHiiHandle);
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |