public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Ni, Ruiyu" <ruiyu.ni@intel.com>
To: "evan.lloyd@arm.com" <evan.lloyd@arm.com>,
	"edk2-devel@ml01.01.org" <edk2-devel@ml01.01.org>
Cc: "Carsey, Jaben" <jaben.carsey@intel.com>,
	Leif Lindholm <leif.lindholm@linaro.org>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: Re: [PATCH] ShellPkg: Add acpiview tool to dump ACPI tables
Date: Mon, 19 Dec 2016 09:48:42 +0000	[thread overview]
Message-ID: <734D49CCEBEEF84792F5B80ED585239D5B836C04@SHSMSX103.ccr.corp.intel.com> (raw)
In-Reply-To: <20161216182547.616-1-evan.lloyd@arm.com>

I happened to find another version of acpi dump tool in shell.
Binary can be downloaded from: https://acpica.org/downloads/uefi-support
Source can be downloaded from: https://github.com/acpica/acpica

Are there any differences between the above one and yours?


Thanks/Ray

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> evan.lloyd@arm.com
> Sent: Saturday, December 17, 2016 2:26 AM
> To: edk2-devel@ml01.01.org
> Cc: Carsey, Jaben <jaben.carsey@intel.com>; Ni, Ruiyu <ruiyu.ni@intel.com>;
> Leif Lindholm <leif.lindholm@linaro.org>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>
> Subject: [edk2] [PATCH] ShellPkg: Add acpiview tool to dump ACPI tables
> 
> From: Sami Mujawar <sami.mujawar@arm.com>
> 
> This program is provided to allow examination of ACPI table contents
> from the UEFI Shell.  This can help with investigations, especially at
> that stage where the tables are not enabling an OS to boot.
> The program is not exhaustive, and only encapsulates detailed knowledge
> of a limited number of table types.
> 
> Default behaviour is to display the content of all tables installed.
> 'Known' table types will be parsed and displayed with descriptions and
> field values.  Where appropriate a degree of consistency checking is
> done and errors may be reported in the output.
> Other table types will be displayed as an array of Hexadecimal bytes.
> 
> To facilitate debugging, the -t and -b options can be used to generate a
> binary file image of a table that can be copied elsewhere for
> investigation using tools such as those provided by acpica.org.  This is
> especially relevant for AML type tables like DSDT and SSDT.
> 
> The inspiration for this is the existing smbiosview Debug1 Shell
> command, and the command is also intended for Debug1.
> 
> Many tables are not explicitly handled, in part because no examples are
> available for our testing.
> 
> The program is designed to be extended to new tables with minimal
> effort, and contributions are invited.
> 
> The code is available for examination at:
> https://github.com/EvanLloyd/tianocore/tree/651_acpiview_v1
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
> ---
>  ShellPkg/ShellPkg.dec                                                        |   2 +
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComman
> dLib.inf |  72 +++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h                    |
> 385 ++++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h               |
> 339 +++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h                      |  84
> +++
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComman
> dLib.h   |  34 ++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c                    |
> 571 ++++++++++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c               |
> 165 +++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c                      | 592
> ++++++++++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Dbg2Parser.c                    |
> 240 ++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/DsdtParser.c                    |  45
> ++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/FadtParser.c                    |
> 140 +++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/GtdtParser.c                    |
> 290 +++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/IortParser.c                    | 633
> ++++++++++++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/MadtParser.c                    |
> 273 +++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/McfgParser.c                    |
> 86 +++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/RsdpParser.c                    |
> 173 ++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/SlitParser.c                    | 141
> +++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/SpcrParser.c                    |
> 148 +++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/SratParser.c                    | 301
> ++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/SsdtParser.c                    |  43
> ++
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComman
> dLib.c   | 105 ++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/XsdtParser.c                    |  97
> +++
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComman
> dLib.uni | 124 ++++
>  24 files changed, 5083 insertions(+)
> 
> diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec
> index
> bb31c2df8cb33bdea0ac46035429d6e36a77e25d..c651358355a96ccc09614c67a
> 8fb31d62d0b8c21 100644
> --- a/ShellPkg/ShellPkg.dec
> +++ b/ShellPkg/ShellPkg.dec
> @@ -3,6 +3,7 @@
>  #
>  # (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR>
>  # Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2016, ARM Limited. All rights reserved.<BR>
>  #
>  # This program and the accompanying materials are licensed and made
> available under
>  # the terms and conditions of the BSD License which accompanies this
> distribution.
> @@ -56,6 +57,7 @@ [Guids]
>    gShellNetwork2HiiGuid           = {0x174b2b5, 0xf505, 0x4b12, {0xaa, 0x60,
> 0x59, 0xdf, 0xf8, 0xd6, 0xea, 0x37}}
>    gShellTftpHiiGuid               = {0x738a9314, 0x82c1, 0x4592, {0x8f, 0xf7, 0xc1,
> 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}}
>    gShellBcfgHiiGuid               = {0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2, 0xeb,
> 0x12, 0xda, 0xb4, 0xa2, 0xb6}}
> +  gShellAcpiViewHiiGuid           = {0xda8ccdf4, 0xed8f, 0x4ffc, {0xb5, 0xef,
> 0x2e, 0xf5, 0x5e, 0x24, 0x93, 0x2a}}
> 
>  [Protocols]
>    gEfiShellEnvironment2Guid           = {0x47c7b221, 0xc42a, 0x11d2, {0x8e, 0x57,
> 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}}
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.inf
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.inf
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..0c88085e40c117daec4db9b99
> e267ee0c56048b3
> --- /dev/null
> +++
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.inf
> @@ -0,0 +1,72 @@
> +##  @file
> +# Provides Shell 'acpiview' command functions
> +#
> +# Copyright (c) 2016, ARM Limited. All rights reserved.<BR>
> +#
> +#  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.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010006
> +  BASE_NAME                      = UefiShellAcpiViewCommandLib
> +  FILE_GUID                      = FB5B305E-84F5-461F-940D-82D345757AFA
> +  MODULE_TYPE                    = UEFI_APPLICATION
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = NULL|UEFI_APPLICATION UEFI_DRIVER
> +  CONSTRUCTOR                    = ShellAcpiViewCommandLibConstructor
> +  DESTRUCTOR                     = ShellAcpiViewCommandLibDestructor
> +
> +[Sources.common]
> +  UefiShellAcpiViewCommandLib.uni
> +  UefiShellAcpiViewCommandLib.c
> +  UefiShellAcpiViewCommandLib.h
> +  AcpiView.c
> +  AcpiParser.c
> +  AcpiTableParser.c
> +  Dbg2Parser.c
> +  DsdtParser.c
> +  FadtParser.c
> +  GtdtParser.c
> +  IortParser.c
> +  MadtParser.c
> +  McfgParser.c
> +  RsdpParser.c
> +  SlitParser.c
> +  SpcrParser.c
> +  SratParser.c
> +  SsdtParser.c
> +  XsdtParser.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  ShellPkg/ShellPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> +  MemoryAllocationLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  ShellCommandLib
> +  ShellLib
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +  UefiBootServicesTableLib
> +  PcdLib
> +  HiiLib
> +  PrintLib
> +  FileHandleLib
> +
> +[FixedPcd]
> +  gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES
> +
> +[Guids]
> +  gShellAcpiViewHiiGuid           ## CONSUMES ## HII
> +  gEfiAcpiTableGuid               ## SOMETIMES_CONSUMES ## SystemTable
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..803ebf3653fff81e83f788ed99
> 25fd6e90ea0f2d
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> @@ -0,0 +1,385 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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.
> +*
> +**/
> +
> +#ifndef ACPIPARSER_H_
> +#define ACPIPARSER_H_
> +
> +
> +/** This function prints a GUID to STDOUT.
> +
> +  @params [in] Guid    Pointer to a GUID to print.
> +
> +  @retval EFI_SUCCESS             The GUID was printed.
> +  @retval EFI_INVALID_PARAMETER   The input was NULL.
> +**/
> +EFI_STATUS
> +PrintGuid (
> +  IN EFI_GUID* Guid
> +  );
> +
> +/** This function verifies the ACPI table checksum.
> +
> +  This function verifies the checksum for the ACPI table and optionally
> +  prints the status.
> +
> +  @params [in] Log     If TRUE log the status of the checksum.
> +  @params [in] Ptr     Pointer to the start of the table buffer.
> +  @params [in] Length  The length of the buffer.
> +
> +  @retval TRUE         The checksum is OK.
> +  @retval FALSE        The checksum failed.
> +**/
> +BOOLEAN
> +VerifyChecksum (
> +  IN BOOLEAN Log,
> +  IN UINT8*  Ptr,
> +  IN UINT32  Length
> +  );
> +
> +/** This function performs a raw data dump of the ACPI table.
> +
> +  @params [in] Ptr     Pointer to the start of the table buffer.
> +  @params [in] Length  The length of the buffer.
> +
> +**/
> +VOID
> +DumpRaw (
> +  IN UINT8* Ptr,
> +  IN UINT32 Length
> +  );
> +
> +/** This function traces 1 byte of datum as specified in the
> +    format string.
> +
> +  @params [in] Format  The format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +DumpUint8 (
> +  IN CONST CHAR16* Format,
> +  IN UINT8*        Ptr
> +  );
> +
> +
> +/** This function traces 2 bytes of data as specified in the
> +    format string.
> +
> +  @params [in] Format  The format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +DumpUint16 (
> +  IN CONST CHAR16* Format,
> +  IN UINT8*        Ptr
> +  );
> +
> +/** This function traces 4 bytes of data as specified in the
> +    format string.
> +
> +  @params [in] Format  The format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +
> +VOID
> +DumpUint32 (
> +  IN CONST CHAR16* Format,
> +  IN UINT8*        Ptr
> +  );
> +
> +/** This function traces 8 bytes of data as specified by the
> +    format string.
> +
> +  @params [in] Format  The format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +DumpUint64 (
> +  IN CONST CHAR16* Format,
> +  IN UINT8*        Ptr
> +  );
> +
> +
> +/** This function traces 3 characters which can be optionally
> +   formated using the format string if specified.
> +
> +  If no format string is specified the Format must be NULL.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +Dump3Chars (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  );
> +
> +/** This function traces 4 characters which can be optionally
> +   formated using the format string if specified.
> +
> +  If no format string is specified the Format must be NULL.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +Dump4Chars (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  );
> +
> +/** This function traces 6 characters which can be optionally
> +   formated using the format string if specified.
> +
> +  If no format string is specified the Format must be NULL.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +Dump6Chars (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  );
> +
> +/** This function traces 8 characters which can be optionally
> +   formated using the format string if specified.
> +
> +  If no format string is specified the Format must be NULL.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +Dump8Chars (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  );
> +
> +/** This function pointer is the template for customizing the trace output
> +
> +  @params [in] Format  Format string for tracing the data as specified by
> +                       the 'Format' member of ACPI_PARSER.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +
> +typedef VOID (*FNPTR_PRINT_FORMATTER)(CONST CHAR16* Format,
> UINT8* Ptr);
> +
> +/** This function pointer is the template for validating an ACPI table field.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information as specified
> by
> +                       the 'Context' member of the ACPI_PARSER.
> +                       e.g. this could be a pointer to the ACPI table header.
> +
> +**/
> +typedef VOID (*FNPTR_FIELD_VALIDATOR)(UINT8* Ptr, VOID* Context);
> +
> +/** The ACPI_PARSER structure describes the fields of an ACPI table and
> +    provides means for the parser to interpret and trace appropriately.
> +
> +  The first three members are populated based on information present in
> +  in the ACPI table specifications. The remaining members describe how
> +  the parser should report the field information, validate the field data
> +  and/or update an external pointer to the field (ItemPtr).
> +
> +  ParseAcpi() uses the format string specified by 'Format' for tracing
> +  the field data. If the field is more complex and requires additional
> +  processing for formatting and representation a print formatter function
> +  can be specified in 'PrintFormatter'.
> +  The PrintFormatter function may choose to use the format string
> +  specified by 'Format' or use its own internal format string.
> +
> +  The 'Format' and 'PrintFormatter' members allow flexibility for
> +  representing the field data.
> +
> +**/
> +typedef struct AcpiParser {
> +
> +  /// String describing the ACPI table field
> +  /// (Field column from ACPI table spec)
> +  CONST CHAR16*         NameStr;
> +
> +  /// The length of the field.
> +  /// (Byte Length column from ACPI table spec)
> +  UINT32                Length;
> +
> +  /// The offset of the field from the start of the table.
> +  /// (Byte Offset column from ACPI table spec)
> +  UINT32                Offset;
> +
> +  /// Optional Print() style format string for tracing the data. If not
> +  /// used this must be set to NULL.
> +  CONST CHAR16*         Format;
> +
> +  /// Optional pointer to a print formatter function which
> +  /// is typically used to trace complex field information.
> +  /// If not used this must be set to NULL.
> +  /// The Format string is passed to the PrintFormatter function
> +  /// but may be ignored by the implementation code.
> +  FNPTR_PRINT_FORMATTER PrintFormatter;
> +
> +  /// Optional pointer which may be set to request the parser to update
> +  /// a pointer to the field data. If unused this must be set to NULL.
> +  VOID**                ItemPtr;
> +
> +  /// Optional pointer to a field validator function.
> +  /// The function should directly report any appropriate error or warning
> +  /// and invoke the appropriate counter update function.
> +  /// If not used this parameter must be set to NULL.
> +  FNPTR_FIELD_VALIDATOR FieldValidator;
> +
> +  /// Optional pointer to context specific information,
> +  /// which the Field Validator function can use to determine
> +  /// additional information about the ACPI table and make
> +  /// decisions about the field being validated.
> +  /// e.g. this could be a pointer to the ACPI table header
> +  VOID*                 Context;
> +} ACPI_PARSER;
> +
> +/** This function is used to parse an ACPI table buffer.
> +
> +  The ACPI table buffer is parsed using the ACPI table parser information
> +  specified by a pointer to an array of ACPI_PARSER elements. This parser
> +  function iterates through each item on the ACPI_PARSER array and logs
> the
> +  ACPI table fields.
> +
> +  This function can optionally be used to parse ACPI tables and fetch specific
> +  field values. The ItemPtr member of the ACPI_PARSER structure (where
> used)
> +  is updated by this parser function to point to the selected field data
> +  (e.g. useful for variable length nested fields).
> +
> +  @params [in] Trace        Trace the ACPI fields TRUE else only parse the
> +                            table.
> +  @params [in] AsciiName    Optional pointer to an ASCII string that describes
> +                            the table being parsed.
> +  @params [in] Ptr          Pointer to the start of the buffer.
> +  @params [in] Length       Length of the buffer pointed by Ptr.
> +  @params [in] Parser       Pointer to an array of ACPI_PARSER structure that
> +                            describes the table being parsed.
> +  @params [in] ParserItems  Number of items in the ACPI_PARSER array.
> +
> +  @retval Number of bytes parsed.
> +**/
> +UINT32
> +ParseAcpi (
> +  IN BOOLEAN            Trace,
> +  IN CONST CHAR8*       AsciiName OPTIONAL,
> +  IN UINT8*             Ptr,
> +  IN UINT32             Length,
> +  IN CONST ACPI_PARSER* Parser,
> +  IN UINT32             ParserItems
> +);
> +
> +/** This is a helper macro to pass parameters to the Parser functions.
> +
> +  @params [in] Parser The name of the ACPI_PARSER array describing the
> +               ACPI table fields.
> +**/
> +
> +#define PARSER_PARAMS(Parser) Parser, sizeof (Parser) / sizeof (Parser[0])
> +
> +
> +/** This is a helper macro for describing the ACPI header fields.
> +
> +  @params [out] Signature  Pointer to retrieve the ACPI table signature.
> +  @params [out] Length     Pointer to retrieve the ACPI table length.
> +  @params [out] Revision   Pointer to retrieve the ACPI table revision.
> +**/
> +
> +#define PARSE_ACPI_HEADER(Signature, Length, Revision)                        \
> +  { L"Signature", 4, 0, NULL, Dump4Chars, (VOID**)Signature , NULL, NULL },
> \
> +  { L"Length", 4, 4, L"%d", NULL, (VOID**)Length, NULL, NULL },             \
> +  { L"Revision", 1, 8, L"%d", NULL, (VOID**)Revision, NULL, NULL },         \
> +  { L"Checksum", 1, 9, L"0x%X", NULL, NULL, NULL, NULL },                   \
> +  { L"Oem ID", 6, 10, NULL, Dump6Chars, NULL, NULL, NULL },                 \
> +  { L"Oem Table ID", 8, 16, NULL, Dump8Chars, NULL, NULL, NULL },           \
> +  { L"Oem Revision", 4, 24, L"%d", NULL, NULL, NULL, NULL },                \
> +  { L"Creator ID", 4, 28, NULL, Dump4Chars, NULL, NULL, NULL },             \
> +  { L"Creator Revision", 4, 32, L"0x%x", NULL, NULL, NULL, NULL }
> +
> +
> +/** Length of the ACPI GAS structure.
> +
> +  NOTE: This might normally be defined as
> +            sizeof (EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE).
> +        However, we deliberately minimise any reference to the EDK2 ACPI
> +        headers in an attempt to provide cross checking.
> +**/
> +#define GAS_LENGTH                     12
> +
> +
> +/** Length of the ACPI Header structure.
> +
> +  NOTE: This might normally be defined as
> +            sizeof (EFI_ACPI_DESCRIPTION_HEADER).
> +        However, we deliberately minimise any reference to the EDK2 ACPI
> +        headers in an attempt to provide cross checking.
> +**/
> +#define ACPI_DESCRIPTION_HEADER_LENGTH  36
> +
> +
> +/** This function traces the GAS structure as described by the GasParser.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +**/
> +
> +VOID
> +DumpGas (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  );
> +
> +
> +/** This function traces the ACPI header as described by the
> AcpiHeaderParser.
> +
> +  @params [in] Ptr          Pointer to the start of the buffer.
> +
> +  @retval Number of bytes parsed.
> +**/
> +UINT32
> +DumpAcpiHeader (
> +  IN UINT8* Ptr
> +  );
> +
> +/** This function parses the ACPI header as described by the
> AcpiHeaderParser.
> +
> +  This function optionally returns the Signature, Length and revision of the
> +  ACPI table.
> +
> +  @params [in]  Ptr        Pointer to the start of the buffer.
> +  @params [out] Signature  Gets location of the ACPI table signature.
> +  @params [out] Length     Gets location of the length of the ACPI table.
> +  @params [out] Revision   Gets location of the revision of the ACPI table.
> +
> +  @retval Number of bytes parsed.
> +**/
> +UINT32
> +ParseAcpiHeader (
> +  IN  UINT8*         Ptr,
> +  OUT CONST UINT32** Signature,
> +  OUT CONST UINT32** Length,
> +  OUT CONST UINT8**  Revision
> +  );
> +
> +#endif // ACPIPARSER_H_
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..ec3863610a0ef28cb01f81ac51
> 306d6d32dac4a2
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> @@ -0,0 +1,339 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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.
> +*
> +**/
> +
> +#ifndef ACPITABLEPARSER_H_
> +#define ACPITABLEPARSER_H_
> +
> +// ACPI Table Parsers
> +
> +/** This function parses the ACPI SPCR table.
> +  This function parses the SPCR table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also performs validations of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiSpcr (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +/** This function parses the ACPI GTDT table.
> +  This function parses the GTDT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also parses the following platform timer structures:
> +    - GT Block timer
> +    - Watchdog timer
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiGtdt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +/** This function parses the ACPI FADT table.
> +  This function parses the FADT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also parses the ACPI header for the DSDT table and
> +  invokes the parser for the ACPI DSDT table.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiFadt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +/** This function parses the ACPI DSDT table.
> +  This function parses the DSDT table and optionally traces the ACPI
> +  table fields. For the DSDT table only the ACPI header fields are
> +  parsed and traced.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiDsdt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +/** This function parses the ACPI SSDT table.
> +  This function parses the SSDT table and optionally traces the ACPI
> +  table fields. For the SSDT table only the ACPI header fields are
> +  parsed and traced.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiSsdt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +/** This function parses the ACPI DBG2 table.
> +  This function parses the DBG2 table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiDbg2 (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +/** This function parses the ACPI MCFG table.
> +  This function parses the MCFG table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiMcfg (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +/** This function parses the ACPI MADT table.
> +  This function parses the MADT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function currently parses the following Interrupt Controller
> +  Structures:
> +    - GICC
> +    - GICD
> +    - GIC MSI Frame
> +    - GICR
> +    - GIC ITS
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiMadt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +
> +/** This function parses the ACPI SRAT table.
> +  This function parses the SRAT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function parses the following Resource Allocation Structures:
> +    - Processor Local APIC/SAPIC Affinity Structure
> +    - Memory Affinity Structure
> +    - Processor Local x2APIC Affinity Structure
> +    - GICC Affinity Structure
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiSrat (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +/** This function parses the ACPI SLIT table.
> +  This function parses the SLIT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also validates System Localities for the following:
> +    - Diagonal elements have a normalized value of 10
> +    - Relative distance from System Locality at i*N+j is same as
> +      j*N+i
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiSlit (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +/** This function parses the ACPI IORT table.
> +  This function parses the IORT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also parses the following nodes:
> +    - ITS Group
> +    - Named Component
> +    - Root Complex
> +    - SMMUv1/2
> +    - SMMUv3
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiIort (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +/** This function parses the ACPI XSDT table.
> +  This function parses the XSDT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function invokes the parsers for the following ACPI tables:
> +    - FADT
> +    - GTDT
> +    - SPCR
> +    - MADT
> +    - DBG2
> +    - MCFG
> +    - SSDT
> +    - SRAT
> +    - SLIT
> +    - IORT
> +
> +  This function also performs validation of the XSDT table.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiXsdt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +
> +/** This function processes the ACPI tables.
> +  This function calls ProcessTableReportOptions() to list the ACPI
> +  tables, perform binary dump of the tables and determine if the
> +  ACPI fields should be traced.
> +
> +  This function also invokes the parser for the ACPI tables.
> +
> +  This function also performs a RAW dump of the ACPI table including
> +  the unknown/unparsed ACPI tables and validates the checksum.
> +
> +  @params [in] Ptr                Pointer to the start of the ACPI
> +                                  table data buffer.
> +**/
> +VOID
> +ProcessAcpiTable (
> +  IN UINT8* Ptr
> +  );
> +
> +
> +/** This function parses the ACPI RSDP table.
> +  This function parses the RSDP table and optionally traces the ACPI
> +  table fields. ProcessTableReportOptions() is called to determine if
> +  the ACPI fields should be traced.
> +
> +  This function invokes the parser for the XSDT table.
> +  * Note - This function does not support parsing of RSDT table.
> +
> +  This function also performs a RAW dump of the ACPI table and
> +  validates the checksum.
> +
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +
> +  @retval EFI_SUCCESS             Success.
> +  @retval EFI_NOT_FOUND           Valid XSDT pointer not found.
> +**/
> +EFI_STATUS
> +ParseRsdp (
> +  IN UINT8* Ptr
> +  );
> +
> +#endif // ACPITABLEPARSER_H_
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..2d939f95ce8328e18c69a823d0
> 582812b4500a82
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h
> @@ -0,0 +1,84 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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.
> +*
> +**/
> +
> +#ifndef ACPIVIEW_H_
> +#define ACPIVIEW_H_
> +
> +/** The EREPORT_OPTION enum describes ACPI table Reporting options.
> +**/
> +typedef enum ReportOption {
> +  EREPORT_ALL,            ///< Report All tables.
> +  EREPORT_SELECTED,       ///< Report Selected table.
> +  EREPORT_TABLE_LIST,     ///< Report List of tables.
> +  EREPORT_DUMP_BIN_FILE,  ///< Dump selected table to a file.
> +  EREPORT_MAX
> +}EREPORT_OPTION;
> +
> +/** This function increments the ACPI table error counter.
> +
> +**/
> +VOID
> +IncrementErrorCount (
> +  );
> +
> +
> +/** This function returns the ACPI table error count.
> +
> +  @retval Returns the count of errors detected in the ACPI tables.
> +**/
> +UINT32
> +GetErrorCount (
> +  );
> +
> +
> +/** This function increments the ACPI table warning counter.
> +
> +**/
> +VOID
> +IncrementWarningCount (
> +  );
> +
> +/** This function returns the ACPI table warning count.
> +
> +  @retval Returns the count of warning detected in the ACPI tables.
> +**/
> +UINT32
> +GetWarningCount (
> +  );
> +
> +/** This function returns the colour highlighting status.
> +
> +  @retval TRUE if colour highlighting is enabled.
> +**/
> +BOOLEAN
> +GetColourHighlighting (
> +  );
> +
> +/** 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
> +  );
> +
> +#endif // ACPIVIEW_H_
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.h
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..d8bf0e603a2ed50e204dcbbf3
> 55707353da07982
> --- /dev/null
> +++
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.h
> @@ -0,0 +1,34 @@
> +/** @file
> +  Header file for 'acpiview' Shell command functions.
> +
> +  Copyright (c) 2016, ARM Limited. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef UEFI_SHELL_ACPIVIEW_COMMAND_LIB_H_
> +#define UEFI_SHELL_ACPIVIEW_COMMAND_LIB_H_
> +
> +extern EFI_HANDLE gShellAcpiViewHiiHandle;
> +
> +/**
> +  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
> +  );
> +
> +#endif // UEFI_SHELL_ACPIVIEW_COMMAND_LIB_H_
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..150f1ab2d97898b98c9b33d93
> 3a39eafcd6098d7
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
> @@ -0,0 +1,571 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +/** This function prints a GUID to STDOUT.
> +
> +  @params [in] Guid    Pointer to a GUID to print.
> +
> +  @retval EFI_SUCCESS             The GUID was printed.
> +  @retval EFI_INVALID_PARAMETER   The input was NULL.
> +**/
> +EFI_STATUS
> +PrintGuid (
> +  IN EFI_GUID* Guid
> +  )
> +{
> +  if (Guid == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Print (
> +    L"%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
> +    Guid->Data1,
> +    Guid->Data2,
> +    Guid->Data3,
> +    Guid->Data4[0],
> +    Guid->Data4[1],
> +    Guid->Data4[2],
> +    Guid->Data4[3],
> +    Guid->Data4[4],
> +    Guid->Data4[5],
> +    Guid->Data4[6],
> +    Guid->Data4[7]
> +    );
> +  return EFI_SUCCESS;
> +}
> +
> +/** This function verifies the ACPI table checksum.
> +
> +  This function verifies the checksum for the ACPI table and optionally
> +  prints the status.
> +
> +  @params [in] Log     If TRUE log the status of the checksum.
> +  @params [in] Ptr     Pointer to the start of the table buffer.
> +  @params [in] Length  The length of the buffer.
> +
> +  @retval TRUE         The checksum is OK.
> +  @retval FALSE        The checksum failed.
> +**/
> +BOOLEAN
> +VerifyChecksum (
> +  IN BOOLEAN Log,
> +  IN UINT8*  Ptr,
> +  IN UINT32  Length
> +  )
> +{
> +  UINTN ByteCount;
> +  UINT8 Checksum;
> +  UINTN OriginalAttribute;
> +
> +  ByteCount = 0;
> +  Checksum = 0;
> +
> +  while (ByteCount < Length) {
> +    Checksum += *(Ptr++);
> +    ByteCount++;
> +  }
> +
> +  if (Log) {
> +    OriginalAttribute = gST->ConOut->Mode->Attribute;
> +    if (0 == Checksum) {
> +      if (GetColourHighlighting ()) {
> +        gST->ConOut->SetAttribute (
> +                       gST->ConOut,
> +                       EFI_TEXT_ATTR (EFI_GREEN,
> +                         ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
> +                       );
> +      }
> +      Print (L"\n\nTable Checksum : OK\n\n");
> +    } else {
> +      IncrementErrorCount ();
> +      if (GetColourHighlighting ()) {
> +        gST->ConOut->SetAttribute (
> +                       gST->ConOut,
> +                       EFI_TEXT_ATTR (EFI_RED,
> +                         ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
> +                       );
> +      }
> +      Print (L"\n\nTable Checksum : FAILED (0x%X)\n\n", Checksum);
> +    }
> +    if (GetColourHighlighting ()) {
> +      gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
> +    }
> +  }
> +
> +  return (0 == Checksum);
> +}
> +
> +
> +/** This function performs a raw data dump of the ACPI table.
> +
> +  @params [in] Ptr     Pointer to the start of the table buffer.
> +  @params [in] Length  The length of the buffer.
> +
> +**/
> +VOID
> +DumpRaw (
> +  IN UINT8* Ptr,
> +  IN UINT32 Length
> +  )
> +{
> +  UINTN ByteCount = 0;
> +  UINTN PartLineChars;
> +  UINTN AsciiBufferIndex = 0;
> +  CHAR8 AsciiBuffer[17];
> +
> +  Print (L"Address  : 0x%p\n", Ptr);
> +  Print (L"Length   : %d\n", Length);
> +
> +  while (ByteCount < Length) {
> +    if ((ByteCount & 0x0F) == 0) {
> +      AsciiBuffer[AsciiBufferIndex] = '\0';
> +      Print (L"  %a\n%08X : ", AsciiBuffer, ByteCount);
> +      AsciiBufferIndex = 0;
> +    } else if ((ByteCount & 0x07) == 0) {
> +      Print (L"- ");
> +    }
> +
> +    if ((*Ptr >= ' ') && (*Ptr < 0x7F)) {
> +      AsciiBuffer[AsciiBufferIndex++] = *Ptr;
> +    } else {
> +      AsciiBuffer[AsciiBufferIndex++] = '.';
> +    }
> +
> +    Print (L"%02X ", *Ptr++);
> +
> +    ByteCount++;
> +  }
> +
> +  // Justify the final line using spaces before printing
> +  // the ASCII data.
> +  PartLineChars = (Length & 0x0F);
> +  if (PartLineChars != 0) {
> +    PartLineChars = 48 - (PartLineChars * 3);
> +    if ((Length & 8) == 0) {
> +      PartLineChars += 2;
> +    }
> +    while (PartLineChars > 0) {
> +      Print (L" ");
> +      PartLineChars--;
> +    }
> +  }
> +
> +  // Print ASCII data for the final line.
> +  AsciiBuffer[AsciiBufferIndex] = '\0';
> +  Print (L"  %a", AsciiBuffer);
> +}
> +
> +
> +
> +/** This function traces 1 byte of datum as specified in the
> +    format string.
> +
> +  @params [in] Format  The format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +DumpUint8 (
> +  IN CONST CHAR16* Format,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  Print (Format, *Ptr);
> +}
> +
> +
> +/** This function traces 2 bytes of data as specified in the
> +    format string.
> +
> +  @params [in] Format  The format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +DumpUint16 (
> +  IN CONST CHAR16* Format,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  Print (Format, *(UINT16*)Ptr);
> +}
> +
> +/** This function traces 4 bytes of data as specified in the
> +    format string.
> +
> +  @params [in] Format  The format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +
> +VOID
> +DumpUint32 (
> +  IN CONST CHAR16* Format,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  Print (Format, *(UINT32*)Ptr);
> +}
> +
> +/** This function traces 8 bytes of data as specified by the
> +    format string.
> +
> +  @params [in] Format  The format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +DumpUint64 (
> +  IN CONST CHAR16* Format,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  UINT64 Val;
> +  // Some fields are not aligned and this causes alignment faults
> +  // on ARM platforms if the compiler generates LDRD instructions.
> +  // Perform word access so that LDRD instructions are not generated.
> +  Val = *(UINT32*)(Ptr + sizeof (UINT32));
> +  Val <<= 32;
> +  Val |= *(UINT32*)Ptr;
> +
> +  Print (Format, Val);
> +}
> +
> +
> +/** This function traces 3 characters which can be optionally
> +   formated using the format string if specified.
> +
> +  If no format string is specified the Format must be NULL.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +Dump3Chars (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  Print (
> +    (NULL != Format) ? Format : L"%c%c%c",
> +    Ptr[0],
> +    Ptr[1],
> +    Ptr[2]
> +    );
> +}
> +
> +/** This function traces 4 characters which can be optionally
> +   formated using the format string if specified.
> +
> +  If no format string is specified the Format must be NULL.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +Dump4Chars (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  Print (
> +    (NULL != Format) ? Format : L"%c%c%c%c",
> +    Ptr[0],
> +    Ptr[1],
> +    Ptr[2],
> +    Ptr[3]
> +    );
> +}
> +
> +/** This function traces 6 characters which can be optionally
> +   formated using the format string if specified.
> +
> +  If no format string is specified the Format must be NULL.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +Dump6Chars (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  Print (
> +    (NULL != Format) ? Format : L"%c%c%c%c%c%c",
> +    Ptr[0],
> +    Ptr[1],
> +    Ptr[2],
> +    Ptr[3],
> +    Ptr[4],
> +    Ptr[5]
> +    );
> +}
> +
> +/** This function traces 8 characters which can be optionally
> +   formated using the format string if specified.
> +
> +  If no format string is specified the Format must be NULL.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +VOID
> +Dump8Chars (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  Print (
> +    (NULL != Format) ? Format : L"%c%c%c%c%c%c%c%c",
> +    Ptr[0],
> +    Ptr[1],
> +    Ptr[2],
> +    Ptr[3],
> +    Ptr[4],
> +    Ptr[5],
> +    Ptr[6],
> +    Ptr[7]
> +    );
> +}
> +
> +
> +/** This function is used to parse an ACPI table buffer.
> +
> +  The ACPI table buffer is parsed using the ACPI table parser information
> +  specified by a pointer to an array of ACPI_PARSER elements. This parser
> +  function iterates through each item on the ACPI_PARSER array and logs
> the
> +  ACPI table fields.
> +
> +  This function can optionally be used to parse ACPI tables and fetch specific
> +  field values. The ItemPtr member of the ACPI_PARSER structure (where
> used)
> +  is updated by this parser function to point to the selected field data
> +  (e.g. useful for variable length nested fields).
> +
> +  @params [in] Trace        Trace the ACPI fields TRUE else only parse the
> +                            table.
> +  @params [in] AsciiName    Optional pointer to an ASCII string that describes
> +                            the table being parsed.
> +  @params [in] Ptr          Pointer to the start of the buffer.
> +  @params [in] Length       Length of the buffer pointed by Ptr.
> +  @params [in] Parser       Pointer to an array of ACPI_PARSER structure that
> +                            describes the table being parsed.
> +  @params [in] ParserItems  Number of items in the ACPI_PARSER array.
> +
> +  @retval Number of bytes parsed.
> +**/
> +UINT32
> +ParseAcpi (
> +  IN BOOLEAN            Trace,
> +  IN CONST CHAR8*       AsciiName OPTIONAL,
> +  IN UINT8*             Ptr,
> +  IN UINT32             Length,
> +  IN CONST ACPI_PARSER* Parser,
> +  IN UINT32             ParserItems
> +)
> +{
> +  UINT32  Index;
> +  UINT32  Offset = 0;
> +
> +  if (Trace) {
> +    BOOLEAN HighLight = GetColourHighlighting ();
> +    UINTN   OriginalAttribute;
> +
> +    if (HighLight) {
> +      OriginalAttribute = gST->ConOut->Mode->Attribute;
> +      gST->ConOut->SetAttribute (
> +                     gST->ConOut,
> +                     EFI_TEXT_ATTR(EFI_YELLOW,
> +                       ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
> +                     );
> +    }
> +    Print (L"%-36a :\n", AsciiName);
> +    if (HighLight) {
> +      gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
> +    }
> +  }
> +
> +  for (Index = 0; Index < ParserItems; Index++) {
> +    if ((Offset + Parser[Index].Length) > Length) {
> +      // We don't parse past the end of the max length specified
> +      break;
> +    }
> +
> +    if (Offset != Parser[Index].Offset) {
> +      IncrementErrorCount ();
> +      Print (
> +        L"\nERROR: %a: Offset Mismatch for %s\n"
> +          "CurrentOffset = %d FieldOffset = %d\n",
> +        AsciiName,
> +        Parser[Index].NameStr,
> +        Offset,
> +        Parser[Index].Offset
> +        );
> +    }
> +
> +    if (Trace) {
> +      // if there is a Formatter function let the function handle
> +      // the printing else if a Format is specified in the table use
> +      // the Format for printing
> +      if (NULL != Parser[Index].PrintFormatter) {
> +        Print (L"%-36s : ", Parser[Index].NameStr);
> +        Parser[Index].PrintFormatter (Parser[Index].Format, Ptr);
> +        Print (L"\n");
> +      } else if (NULL != Parser[Index].Format) {
> +        Print (L"%-36s : ", Parser[Index].NameStr);
> +        switch (Parser[Index].Length) {
> +          case 1:
> +            DumpUint8 (Parser[Index].Format, Ptr);
> +            break;
> +          case 2:
> +            DumpUint16 (Parser[Index].Format, Ptr);
> +            break;
> +          case 4:
> +            DumpUint32 (Parser[Index].Format, Ptr);
> +            break;
> +          case 8:
> +            DumpUint64 (Parser[Index].Format, Ptr);
> +            break;
> +          default:
> +            Print (
> +              L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n",
> +              AsciiName,
> +              Parser[Index].Length
> +              );
> +        } // switch
> +
> +        // Validating only makes sense if we are Tracing
> +        // the parsed table entries, to report by table name.
> +        if (NULL != Parser[Index].FieldValidator) {
> +          Parser[Index].FieldValidator (Ptr, Parser[Index].Context);
> +        }
> +
> +        Print (L"\n");
> +      }
> +    } // if (Trace)
> +
> +
> +    if (NULL != Parser[Index].ItemPtr) {
> +      *Parser[Index].ItemPtr = (VOID*)Ptr;
> +    }
> +
> +    Ptr += Parser[Index].Length;
> +    Offset += Parser[Index].Length;
> +  } // for
> +
> +  return Offset;
> +}
> +
> +
> +/** An array describing the ACPI Generic Address Structure.
> +  The GasParser array is used by the ParseAcpi function to parse and/or
> trace
> +  the GAS structure.
> +**/
> +
> +STATIC CONST ACPI_PARSER GasParser[] = {
> +  {L"    Address Space ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"    Register Bit Width", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"    Register Bit Offset", 1, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"    Address Size", 1, 3, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"    Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** This function traces the GAS structure as described by the GasParser.
> +
> +  @params [in] Format  Optional format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +**/
> +
> +VOID
> +DumpGas (
> +  IN CONST CHAR16* Format OPTIONAL,
> +  IN UINT8*        Ptr
> +  )
> +{
> +  Print (L"\n");
> +  ParseAcpi (
> +    TRUE,
> +    "  GAS",
> +    Ptr,
> +    GAS_LENGTH,
> +    PARSER_PARAMS (GasParser)
> +    );
> +}
> +
> +/** This function traces the ACPI header as described by the
> AcpiHeaderParser.
> +
> +  @params [in] Ptr          Pointer to the start of the buffer.
> +
> +  @retval Number of bytes parsed.
> +**/
> +UINT32
> +DumpAcpiHeader (
> +  IN UINT8* Ptr
> +  )
> +{
> +  ACPI_PARSER AcpiHeaderParser[] = {
> +    PARSE_ACPI_HEADER (NULL, NULL, NULL)
> +  };
> +
> +  return ParseAcpi (
> +           TRUE,
> +           "ACPI Table Header",
> +           Ptr,
> +           ACPI_DESCRIPTION_HEADER_LENGTH,
> +           PARSER_PARAMS (AcpiHeaderParser)
> +           );
> +}
> +
> +/** This function parses the ACPI header as described by the
> AcpiHeaderParser.
> +
> +  This function optionally returns the Signature, Length and revision of the
> +  ACPI table.
> +
> +  @params [in]  Ptr        Pointer to the start of the buffer.
> +  @params [out] Signature  Gets location of the ACPI table signature.
> +  @params [out] Length     Gets location of the length of the ACPI table.
> +  @params [out] Revision   Gets location of the revision of the ACPI table.
> +
> +  @retval Number of bytes parsed.
> +**/
> +UINT32
> +ParseAcpiHeader (
> +  IN  UINT8*         Ptr,
> +  OUT CONST UINT32** Signature,
> +  OUT CONST UINT32** Length,
> +  OUT CONST UINT8**  Revision
> +  )
> +{
> +  ACPI_PARSER AcpiHeaderParser[] = {
> +    PARSE_ACPI_HEADER (Signature, Length, Revision)
> +  };
> +
> +  return ParseAcpi (
> +             FALSE,
> +             NULL,
> +             Ptr,
> +             ACPI_DESCRIPTION_HEADER_LENGTH,
> +             PARSER_PARAMS (AcpiHeaderParser)
> +             );
> +}
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..ff6e00a5cb254478ab34f6dcab
> b05cfae69b9cfa
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
> @@ -0,0 +1,165 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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 <IndustryStandard/Acpi.h>
> +#include <Library/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +#include "AcpiTableParser.h"
> +
> +/** This function processes the ACPI tables.
> +  This function calls ProcessTableReportOptions() to list the ACPI
> +  tables, perform binary dump of the tables and determine if the
> +  ACPI fields should be traced.
> +
> +  This function also invokes the parser for the ACPI tables.
> +
> +  This function also performs a RAW dump of the ACPI table including
> +  the unknown/unparsed ACPI tables and validates the checksum.
> +
> +  @params [in] Ptr                Pointer to the start of the ACPI
> +                                  table data buffer.
> +**/
> +VOID
> +ProcessAcpiTable (
> +  IN UINT8* Ptr
> +  )
> +{
> +  BOOLEAN       Trace;
> +  CONST UINT32* AcpiTableSignature;
> +  CONST UINT32* AcpiTableLength;
> +  CONST UINT8*  AcpiTableRevision;
> +
> +  ParseAcpiHeader (
> +    Ptr,
> +    &AcpiTableSignature,
> +    &AcpiTableLength,
> +    &AcpiTableRevision
> +    );
> +
> +  Trace = ProcessTableReportOptions (
> +            *AcpiTableSignature,
> +            Ptr,
> +            *AcpiTableLength
> +            );
> +
> +  if (Trace) {
> +    DumpRaw (Ptr, *AcpiTableLength);
> +    VerifyChecksum (TRUE, Ptr, *AcpiTableLength);
> +  }
> +
> +  switch (*AcpiTableSignature) {
> +    case
> EFI_ACPI_6_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
> +      ParseAcpiXsdt (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
> +      ParseAcpiFadt (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case
> EFI_ACPI_6_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
> +      ParseAcpiDsdt (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE:
> +      ParseAcpiGtdt (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case
> EFI_ACPI_6_1_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
> +      ParseAcpiSpcr (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
> +      ParseAcpiMadt (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case EFI_ACPI_6_1_DEBUG_PORT_2_TABLE_SIGNATURE:
> +      ParseAcpiDbg2 (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case
> EFI_ACPI_6_1_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE
> _BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
> +      ParseAcpiMcfg (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case
> EFI_ACPI_6_1_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
> +      ParseAcpiSsdt (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case EFI_ACPI_6_1_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE:
> +      ParseAcpiSrat (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case
> EFI_ACPI_6_1_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
> +      ParseAcpiSlit (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    case EFI_ACPI_6_1_INTERRUPT_SOURCE_OVERRIDE_SIGNATURE:
> +      ParseAcpiIort (
> +        Trace,
> +        Ptr,
> +        *AcpiTableLength,
> +        *AcpiTableRevision
> +        );
> +      break;
> +    default:
> +      if (Trace) {
> +        DumpAcpiHeader (Ptr);
> +      }
> +    } // switch
> +}
> +
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..2e8b4dc09b08a3b5d96f59920
> fe22913ce771107
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
> @@ -0,0 +1,592 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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 "UefiShellAcpiViewCommandLib.h"
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +#include "AcpiTableParser.h"
> +
> +// Local variables
> +STATIC UINT32             gSelectedAcpiTable;
> +STATIC CONST CHAR16*      gSelectedAcpiTableName;
> +STATIC BOOLEAN            gSelectedAcpiTableFound;
> +STATIC EREPORT_OPTION     gReportType;
> +STATIC UINT32             gTableCount;
> +STATIC UINT32             gBinTableCount;
> +STATIC UINT32             gTableErrorCount;
> +STATIC UINT32             gTableWarningCount;
> +STATIC BOOLEAN            gColourHighlighting;
> +
> +/** An array of acpiview command line parameters.
> +**/
> +STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
> +  {L"/?", TypeFlag},
> +  {L"-l", TypeFlag},
> +  {L"-t", TypeValue},
> +  {L"-b", TypeFlag},
> +  {L"-c", TypeValue},
> +  {NULL, TypeMax}
> +};
> +
> +
> +/** This function increments the ACPI table error counter.
> +
> +**/
> +VOID
> +IncrementErrorCount (
> +  )
> +{
> +  gTableErrorCount++;
> +}
> +
> +/** This function returns the ACPI table error count.
> +
> +  @retval Returns the count of errors detected in the ACPI tables.
> +**/
> +UINT32
> +GetErrorCount (
> +  )
> +{
> +  return gTableErrorCount;
> +}
> +
> +/** This function increments the ACPI table warning counter.
> +
> +**/
> +VOID
> +IncrementWarningCount (
> +  )
> +{
> +  gTableWarningCount++;
> +}
> +
> +/** This function returns the ACPI table warning count.
> +
> +  @retval Returns the count of warning detected in the ACPI tables.
> +**/
> +UINT32
> +GetWarningCount (
> +  )
> +{
> +  return gTableWarningCount;
> +}
> +
> +
> +/** This function returns the colour highlighting status.
> +
> +  @retval TRUE if colour highlighting is enabled.
> +**/
> +BOOLEAN
> +GetColourHighlighting (
> +  )
> +{
> +  return gColourHighlighting;
> +}
> +
> +/** This function returns the report options.
> +
> +  @retval Returns the report option.
> +
> +**/
> +STATIC
> +EREPORT_OPTION
> +GetReportOption (
> +  )
> +{
> +  return gReportType;
> +}
> +
> +/** This function returns the selected ACPI table.
> +
> +  @retval Returns the selected ACPI table.
> +
> +**/
> +STATIC
> +UINT32
> +GetSelectedAcpiTable (
> +  )
> +{
> +  return gSelectedAcpiTable;
> +}
> +
> +
> +/** 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.
> +
> +**/
> +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",
> +    gSelectedAcpiTableName,
> +    gBinTableCount++
> +    );
> +
> +  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");
> +  }
> +
> +  ShellCloseFile (&DumpFileHandle);
> +  Print (L"DONE.\n");
> +
> +  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;
> +        gSelectedAcpiTableFound = TRUE;
> +      }
> +      break;
> +    case EREPORT_TABLE_LIST:
> +      if (0 == gTableCount) {
> +        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",
> +        ++gTableCount,
> +        SignaturePtr[0],
> +        SignaturePtr[1],
> +        SignaturePtr[2],
> +        SignaturePtr[3]
> +        );
> +      break;
> +    case EREPORT_DUMP_BIN_FILE:
> +      if (Signature == GetSelectedAcpiTable ()) {
> +        gSelectedAcpiTableFound = 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;
> +  CHAR8 Ptr[4];
> +
> +  Index = 0;
> +  // Convert to Upper case and convert to ASCII
> +  while ((Index < 4) && (0 != Str[Index])) {
> +    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 and to retrieve the RSDP pointer and start 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_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;
> +
> +  // 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) {
> +    Status = ParseRsdp ((UINT8*)EfiConfigurationTable->VendorTable);
> +  } else {
> +    IncrementErrorCount ();
> +    Print (
> +      L"ERROR: Failed to find ACPI Table Guid in System Configuration
> Table.\n"
> +      );
> +    Status = EFI_NOT_FOUND;
> +  }
> +
> +  ReportOption = GetReportOption ();
> +  if (EREPORT_TABLE_LIST != ReportOption) {
> +    if (((EREPORT_SELECTED == ReportOption)  ||
> +         (EREPORT_DUMP_BIN_FILE == ReportOption)) &&
> +        (!gSelectedAcpiTableFound)) {
> +      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 Status;
> +}
> +
> +
> +/**
> +  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
> +  gReportType = EREPORT_ALL;
> +  gTableCount = 0;
> +  gBinTableCount = 0;
> +  gSelectedAcpiTable = 0;
> +  gSelectedAcpiTableName = NULL;
> +  gTableErrorCount = 0;
> +  gTableWarningCount = 0;
> +  gSelectedAcpiTableFound = FALSE;
> +
> +  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);
> +      ShellStatus = SHELL_INVALID_PARAMETER;
> +    } else {
> +      ASSERT (FALSE);
> +    }
> +  } 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"-t") &&
> +               ShellCommandLineGetValue (Package, L"-t") == NULL) {
> +      ShellPrintHiiEx (
> +        -1,
> +        -1,
> +        NULL,
> +        STRING_TOKEN (STR_GEN_NO_VALUE),
> +        gShellAcpiViewHiiHandle,
> +        L"acpiview",
> +        L"-t"
> +        );
> +      ShellStatus = SHELL_INVALID_PARAMETER;
> +    } else if ((ShellCommandLineGetFlag (Package, L"-t") &&
> +                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"-c") &&
> +               ShellCommandLineGetValue (Package, L"-c") == NULL) {
> +        ShellPrintHiiEx (
> +          -1,
> +          -1,
> +          NULL,
> +          STRING_TOKEN (STR_GEN_NO_VALUE),
> +          gShellAcpiViewHiiHandle,
> +          L"acpiview",
> +          L"-c"
> +          );
> +        ShellStatus = SHELL_INVALID_PARAMETER;
> +    } else if (ShellCommandLineGetFlag (Package, L"-b") &&
> +               !ShellCommandLineGetFlag (Package, L"-t")) {
> +        ShellPrintHiiEx (
> +          -1,
> +          -1,
> +          NULL,
> +          STRING_TOKEN (STR_GEN_MISSING_OPTION),
> +          gShellAcpiViewHiiHandle,
> +          L"acpiview",
> +          L"-t",
> +          L"-b"
> +          );
> +        ShellStatus = SHELL_INVALID_PARAMETER;
> +    } else {
> +      // Check if the colour option is set
> +      Temp = ShellCommandLineGetValue (Package, L"-c");
> +      if (NULL != Temp) {
> +        UnicodeStrToAsciiStrS (Temp, ColourOption, sizeof (ColourOption));
> +        if ((0 == AsciiStriCmp (ColourOption, "ON")) ||
> +            (0 == AsciiStriCmp (ColourOption, "TRUE"))) {
> +          gColourHighlighting = TRUE;
> +        } else if ((0 == AsciiStriCmp (ColourOption, "OFF")) ||
> +                   (0 == AsciiStriCmp (ColourOption, "FALSE"))) {
> +          gColourHighlighting = FALSE;
> +        }
> +      }
> +
> +      if (ShellCommandLineGetFlag (Package, L"-l")) {
> +        gReportType = EREPORT_TABLE_LIST;
> +      } else {
> +        gSelectedAcpiTableName = ShellCommandLineGetValue (Package, L"-
> t");
> +        if (gSelectedAcpiTableName != NULL) {
> +          gSelectedAcpiTable = (UINT32)ConvertStrToAcpiSignature
> (gSelectedAcpiTableName);
> +          gReportType = EREPORT_SELECTED;
> +
> +          if (ShellCommandLineGetFlag (Package, L"-b"))  {
> +            // Create a temporary file to check if the media is writable.
> +            CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
> +            gReportType = EREPORT_DUMP_BIN_FILE;
> +
> +            UnicodeSPrint (
> +              FileNameBuffer,
> +              sizeof (FileNameBuffer),
> +              L".\\%s%04d.tmp",
> +              gSelectedAcpiTableName,
> +              gBinTableCount
> +              );
> +
> +            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);
> +          } // -b
> +        } // -t
> +      }
> +
> +      // Parse ACPI Table information
> +      Status = AcpiView (SystemTable);
> +      if (EFI_ERROR (Status)) {
> +        ShellStatus = SHELL_NOT_FOUND;
> +        goto Done;
> +      }
> +    }
> +  }
> +
> +Done:
> +  if (Package != NULL) {
> +    ShellCommandLineFreeVarList (Package);
> +  }
> +  return ShellStatus;
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Dbg2Parser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Dbg2Parser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..09c9c9daa7caca4d9e111f034e
> da54d02b634c33
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Dbg2Parser.c
> @@ -0,0 +1,240 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +// Local variables pointing to the table fields
> +STATIC CONST UINT32* OffsetDbgDeviceInfo;
> +STATIC CONST UINT32* NumberDbgDeviceInfo;
> +STATIC CONST UINT16* DbgDevInfoLen;
> +STATIC CONST UINT8*  GasCount;
> +STATIC CONST UINT16* NameSpaceStringLength;
> +STATIC CONST UINT16* NameSpaceStringOffset;
> +STATIC CONST UINT16* OEMDataLength;
> +STATIC CONST UINT16* OEMDataOffset;
> +STATIC CONST UINT16* BaseAddrRegOffset;
> +STATIC CONST UINT16* AddrSizeOffset;
> +
> +/** This function Validates the NameSpace string length.
> +
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +
> +STATIC
> +VOID
> +ValidateNameSpaceStrLen (
> +  IN  UINT8* Ptr,
> +  IN  VOID*  Context
> +  );
> +
> +/** This function parses the debug device information structure.
> +
> +  @params [in]  Ptr     Pointer to the start of the buffer.
> +  @params [out] Ptr     Pointer in which the length of the debug
> +                        device information is returned.
> +**/
> +
> +STATIC
> +VOID
> +DumpDbgDeviceInfo (
> +  IN  UINT8*  Ptr,
> +  OUT UINT32* Length
> +  );
> +
> +
> +/// An ACPI_PARSER array describing the ACPI DBG2 table.
> +
> +STATIC CONST ACPI_PARSER Dbg2Parser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"OffsetDbgDeviceInfo", 4, 36, L"0x%x", NULL,
> +   (VOID**)&OffsetDbgDeviceInfo, NULL, NULL},
> +  {L"NumberDbgDeviceInfo", 4, 40, L"%d", NULL,
> +   (VOID**)&NumberDbgDeviceInfo, NULL, NULL}
> +};
> +
> +
> +/// An ACPI_PARSER array describing the debug device information.
> +
> +STATIC CONST ACPI_PARSER DbgDevInfoParser[] = {
> +  {L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 2, 1, L"%d", NULL, (VOID**)&DbgDevInfoLen, NULL, NULL},
> +
> +  {L"Generic Address Registers Count", 1, 3, L"0x%x", NULL,
> +   (VOID**)&GasCount, NULL, NULL},
> +  {L"NameSpace String Length", 2, 4, L"%d", NULL,
> +   (VOID**)&NameSpaceStringLength, ValidateNameSpaceStrLen, NULL},
> +  {L"NameSpace String Offset", 2, 6, L"0x%x", NULL,
> +   (VOID**)&NameSpaceStringOffset, NULL, NULL},
> +  {L"OEM Data Length", 2, 8, L"%d", NULL, (VOID**)&OEMDataLength,
> +   NULL, NULL},
> +  {L"OEM Data Offset", 2, 10, L"0x%x", NULL, (VOID**)&OEMDataOffset,
> +   NULL, NULL},
> +
> +  {L"Port Type", 2, 12, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Port SubType", 2, 14, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 2, 16, L"%x", NULL, NULL, NULL, NULL},
> +
> +  {L"Base Address Register Offset", 2, 18, L"0x%x", NULL,
> +   (VOID**)&BaseAddrRegOffset, NULL, NULL},
> +  {L"Address Size Offset", 2, 20, L"0x%x", NULL,
> +   (VOID**)&AddrSizeOffset, NULL, NULL}
> +};
> +
> +
> +/** This function Validates the NameSpace string length.
> +
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +
> +STATIC
> +VOID
> +ValidateNameSpaceStrLen (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  UINT16 NameSpaceStrLen = *(UINT16*)Ptr;
> +  if (NameSpaceStrLen < 2) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nERROR: NamespaceString Length = %d. If no Namespace device
> exists,\n"
> +       "    then NamespaceString[] must contain a period '.'",
> +      NameSpaceStrLen
> +      );
> +  }
> +}
> +
> +/** This function parses the debug device information structure.
> +
> +  @params [in]  Ptr     Pointer to the start of the buffer.
> +  @params [out] Ptr     Pointer in which the length of the debug
> +                        device information is returned.
> +**/
> +
> +STATIC
> +VOID
> +DumpDbgDeviceInfo (
> +  IN  UINT8*  Ptr,
> +  OUT UINT32* Length
> +  )
> +{
> +  UINT16  Index;
> +  UINT8*  DataPtr;
> +  UINT32* AddrSize;
> +
> +  // Parse the debug device info to get the Length
> +  ParseAcpi (
> +    FALSE,
> +    "Debug Device Info",
> +    Ptr,
> +    3,  // Length is 2 bytes starting at offset 1
> +    PARSER_PARAMS (DbgDevInfoParser)
> +    );
> +
> +  ParseAcpi (
> +    TRUE,
> +    "Debug Device Info",
> +    Ptr,
> +    *DbgDevInfoLen,
> +    PARSER_PARAMS (DbgDevInfoParser)
> +    );
> +
> +  // GAS and Address Size
> +  Index = 0;
> +  DataPtr = Ptr + (*BaseAddrRegOffset);
> +  AddrSize = (UINT32*)(Ptr + (*AddrSizeOffset));
> +  while (Index < (*GasCount)) {
> +    Print (L"%-36s : ", L"BaseAddressRegister");
> +    DumpGas (NULL, DataPtr);
> +    Print (L"%-36s : 0x%x\n", L"Address Size", AddrSize[Index]);
> +    DataPtr += GAS_LENGTH;
> +    Index++;
> +  }
> +
> +  // NameSpace String
> +  Index = 0;
> +  DataPtr = Ptr + (*NameSpaceStringOffset);
> +  Print (L"%-36s : ", L"NameSpace String");
> +  while (Index < (*NameSpaceStringLength)) {
> +    Print (L"%c", DataPtr[Index++]);
> +  }
> +  Print (L"\n");
> +
> +  // OEM Data
> +  Index = 0;
> +  DataPtr = Ptr + (*OEMDataOffset);
> +  Print (L"%-36s : ", L"OEM Data");
> +  while (Index < (*OEMDataLength)) {
> +    Print (L"%x ", DataPtr[Index++]);
> +    if (0 == (Index & 7)) {
> +      Print (L"\n%-36s   ", L"");
> +    }
> +  }
> +
> +  *Length = *DbgDevInfoLen;
> +}
> +
> +
> +/** This function parses the ACPI DBG2 table.
> +  This function parses the DBG2 table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiDbg2 (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT32 DbgDeviceInfoLength;
> +  UINT8* DevInfoPtr;
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             "DBG2",
> +             Ptr,
> +             AcpiTableLength,
> +             PARSER_PARAMS (Dbg2Parser)
> +             );
> +  DevInfoPtr = Ptr + Offset;
> +
> +  while (Offset < AcpiTableLength) {
> +    DumpDbgDeviceInfo (
> +      DevInfoPtr,
> +      &DbgDeviceInfoLength
> +      );
> +    Offset += DbgDeviceInfoLength;
> +    DevInfoPtr += DbgDeviceInfoLength;
> +  }
> +
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/DsdtParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DsdtParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..cafc52467c1a2e0a69703446cb
> 2f080e7287b857
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DsdtParser.c
> @@ -0,0 +1,45 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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 <IndustryStandard/Acpi.h>
> +#include <Library/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +/** This function parses the ACPI DSDT table.
> +  This function parses the DSDT table and optionally traces the ACPI
> +  table fields. For the DSDT table only the ACPI header fields are
> +  parsed and traced.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiDsdt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  DumpAcpiHeader (Ptr);
> +
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/FadtParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/FadtParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..49987f877e7b78852b26e9a3e
> c12b79b7f7c6c70
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/FadtParser.c
> @@ -0,0 +1,140 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +#include "AcpiTableParser.h"
> +
> +// Local variables
> +STATIC CONST UINT32* DsdtAddress;
> +STATIC CONST UINT64* X_DsdtAddress;
> +
> +/** An ACPI_PARSER array describing the ACPI FADT Table.
> +
> +**/
> +STATIC CONST ACPI_PARSER FadtParser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"FIRMWARE_CTRL", 4, 36, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"DSDT", 4, 40, L"0x%x", NULL, (VOID**)&DsdtAddress, NULL, NULL},
> +  {L"Reserved", 1, 44, L"%x", NULL, NULL, NULL, NULL},
> +  {L"Preferred_PM_Profile", 1, 45, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"SCI_INT", 2, 46, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"SMI_CMD", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"ACPI_ENABLE", 1, 52, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"ACPI_DISABLE", 1, 53, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"S4BIOS_REQ", 1, 54, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PSTATE_CNT", 1, 55, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM1a_EVT_BLK", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM1b_EVT_BLK", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM1a_CNT_BLK", 4, 64, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM1b_CNT_BLK", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM2_CNT_BLK", 4, 72, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM_TMR_BLK", 4, 76, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"GPE0_BLK", 4, 80, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"GPE1_BLK", 4, 84, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM1_EVT_LEN", 1, 88, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM1_CNT_LEN", 1, 89, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM2_CNT_LEN", 1, 90, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PM_TMR_LEN", 1, 91, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"GPE0_BLK_LEN", 1, 92, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"GPE1_BLK_LEN", 1, 93, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"GPE1_BASE", 1, 94, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"CST_CNT", 1, 95, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"P_LVL2_LAT", 2, 96, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"P_LVL3_LAT", 2, 98, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"FLUSH_SIZE", 2, 100, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"FLUSH_STRIDE", 2, 102, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"DUTY_OFFSET", 1, 104, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"DUTY_WIDTH", 1, 105, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"DAY_ALRM", 1, 106, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"MON_ALRM", 1, 107, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"CENTURY", 1, 108, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"IAPC_BOOT_ARCH", 2, 109, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 111, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 112, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"RESET_REG", 12, 116, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"RESET_VALUE", 1, 128, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"ARM_BOOT_ARCH", 2, 129, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"FADT Minor Version", 1, 131, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"X_FIRMWARE_CTRL", 8, 132, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"X_DSDT", 8, 140, L"0x%lx", NULL, (VOID**)&X_DsdtAddress, NULL,
> NULL},
> +  {L"X_PM1a_EVT_BLK", 12, 148, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"X_PM1b_EVT_BLK", 12, 160, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"X_PM1a_CNT_BLK", 12, 172, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"X_PM1b_CNT_BLK", 12, 184, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"X_PM2_CNT_BLK", 12, 196, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"X_PM_TMR_BLK", 12, 208, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"X_GPE0_BLK", 12, 220, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"X_GPE1_BLK", 12, 232, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"SLEEP_CONTROL_REG", 12, 244, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"SLEEP_STATUS_REG", 12, 256, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"Hypervisor VendorIdentity", 8, 268, L"%lx", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** This function parses the ACPI FADT table.
> +  This function parses the FADT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also parses the ACPI header for the DSDT table and
> +  invokes the parser for the ACPI DSDT table.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiFadt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT8*  DsdtPtr;
> +
> +  ParseAcpi (Trace, "FADT", Ptr, AcpiTableLength, PARSER_PARAMS
> (FadtParser));
> +
> +  if (Trace) {
> +    if ((0 != *X_DsdtAddress) && (0 != *DsdtAddress)) {
> +      // If the X_DSDT is non-zero the DSDT must be zero
> +      // and vice - versa
> +      IncrementErrorCount ();
> +      Print (L"ERROR: Both X_DSDT and DSDT are set.\n");
> +    }
> +  }
> +
> +  if (0 != *DsdtAddress) {
> +    DsdtPtr = (UINT8*)(UINTN)(*DsdtAddress);
> +  } else if (0 != *X_DsdtAddress) {
> +    DsdtPtr = (UINT8*)(UINTN)(*X_DsdtAddress);
> +  } else {
> +#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
> +    if (Trace) {
> +      // The DSDT Table is mandatory for ARM systems
> +      // as the CPU information MUST be presented in
> +      // the DSDT.
> +      IncrementErrorCount ();
> +      Print (L"ERROR: Both X_DSDT and DSDT are NULL.\n");
> +    }
> +#endif
> +    return;
> +  }
> +
> +  ProcessAcpiTable (DsdtPtr);
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/GtdtParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/GtdtParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..b6c8c91cd9d758ee066d514a4
> 9499209cf7df3ed
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/GtdtParser.c
> @@ -0,0 +1,290 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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 <IndustryStandard/Acpi.h>
> +#include <Library/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +// Local variables
> +STATIC CONST UINT32* GtdtPlatformTimerCount;
> +STATIC CONST UINT32* GtdtPlatformTimerOffset;
> +STATIC CONST UINT8*  PlatformTimerType;
> +STATIC CONST UINT16* PlatformTimerLength;
> +STATIC CONST UINT32* GtBlockTimerCount;
> +STATIC CONST UINT32* GtBlockTimerOffset;
> +STATIC CONST UINT16* GtBlockLength;
> +
> +/** This function validates the GT Block timer count.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateGtBlockTimerCount (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  );
> +
> +/** An ACPI_PARSER array describing the ACPI GTDT Table.
> +
> +**/
> +STATIC CONST ACPI_PARSER GtdtParser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"CntControlBase Physical Address", 8, 36, L"0x%lx", NULL, NULL,
> +   NULL, NULL},
> +  {L"Reserved", 4, 44, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Secure EL1 timer GSIV", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Secure EL1 timer FLAGS", 4, 52, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"Non-Secure EL1 timer GSIV", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Non-Secure EL1 timer FLAGS", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +
> +  {L"Virtual timer GSIV", 4, 64, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Virtual timer FLAGS", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"Non-Secure EL2 timer GSIV", 4, 72, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Non-Secure EL2 timer FLAGS", 4, 76, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"CntReadBase Physical address", 8, 80, L"0x%lx", NULL, NULL, NULL,
> NULL},
> +  {L"Platform Timer Count", 4, 88, L"%d", NULL,
> +   (VOID**)&GtdtPlatformTimerCount, NULL, NULL},
> +  {L"Platform Timer Offset", 4, 92, L"0x%x", NULL,
> +   (VOID**)&GtdtPlatformTimerOffset, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the Platform timer header.
> +
> +**/
> +STATIC CONST ACPI_PARSER GtPlatformTimerHeaderParser[] = {
> +  {L"Type", 1, 0, NULL, NULL, (VOID**)&PlatformTimerType, NULL, NULL},
> +  {L"Length", 2, 1, NULL, NULL, (VOID**)&PlatformTimerLength, NULL,
> NULL},
> +  {L"Reserved", 1, 3, NULL, NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the Platform GT Block.
> +
> +**/
> +STATIC CONST ACPI_PARSER GtBlockParser[] = {
> +  {L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Length", 2, 1, L"%d", NULL, (VOID**)&GtBlockLength, NULL, NULL},
> +  {L"Reserved", 1, 3, L"%x", NULL, NULL, NULL, NULL},
> +  {L"Physical address (CntCtlBase)", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Timer Count", 4, 12, L"%d", NULL, (VOID**)&GtBlockTimerCount,
> +   ValidateGtBlockTimerCount, NULL},
> +  {L"Timer Offset", 4, 16, L"%d", NULL, (VOID**)&GtBlockTimerOffset, NULL,
> +    NULL}
> +};
> +
> +
> +/** An ACPI_PARSER array describing the GT Block timer.
> +
> +**/
> +STATIC CONST ACPI_PARSER GtBlockTimerParser[] = {
> +  {L"Frame Number", 1, 0, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL},
> +  {L"Physical address (CntBaseX)", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Physical address (CntEL0BaseX)", 8, 12, L"0x%lx", NULL, NULL, NULL,
> +    NULL},
> +  {L"Physical Timer GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Physical Timer Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Virtual Timer GSIV", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Virtual Timer Flags", 4, 32, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Common Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** An ACPI_PARSER array describing the Platform Watchdog.
> +
> +**/
> +STATIC CONST ACPI_PARSER SBSAGenericWatchdogParser[] = {
> +  {L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Length", 2, 1, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 3, L"%x", NULL, NULL, NULL, NULL},
> +  {L"RefreshFrame Physical address", 8, 4, L"0x%lx", NULL, NULL, NULL,
> NULL},
> +  {L"ControlFrame Physical address", 8, 12, L"0x%lx", NULL, NULL, NULL,
> NULL},
> +  {L"Watchdog Timer GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Watchdog Timer Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** This function validates the GT Block timer count.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateGtBlockTimerCount (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  UINT32 BlockTimerCount = *(UINT32*)Ptr;
> +  if (BlockTimerCount > 8) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nERROR: Timer Count = %d. Max Timer Count is 8.",
> +      BlockTimerCount
> +      );
> +  }
> +}
> +
> +/** This function parses the Platform GT Block.
> +
> +  @params [in] Ptr     Pointer to the start of the GT Block data.
> +  @params [in] Length  Length of the GT Block structure.
> +**/
> +
> +STATIC
> +VOID
> +DumpGTBlock (
> +  IN UINT8* Ptr,
> +  IN UINT16 Length
> +  )
> +{
> +  UINT32 Index;
> +  UINT32 Offset;
> +  UINT16 GTBlockTimerLength;
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             "GT Block",
> +             Ptr,
> +             Length,
> +             PARSER_PARAMS (GtBlockParser)
> +             );
> +  GTBlockTimerLength = (*GtBlockLength - Offset) / (*GtBlockTimerCount);
> +  Length -= Offset;
> +
> +  if (0 != *GtBlockTimerCount) {
> +    Ptr += (*GtBlockTimerOffset);
> +    Index = 0;
> +    while ((Index < (*GtBlockTimerCount)) && (Length >=
> GTBlockTimerLength)) {
> +      Offset = ParseAcpi (
> +                 TRUE,
> +                 "GT Block Timer",
> +                 Ptr,
> +                 GTBlockTimerLength,
> +                 PARSER_PARAMS (GtBlockTimerParser)
> +                 );
> +      // Increment by GT Block Timer structure size
> +      Ptr += Offset;
> +      Length -= Offset;
> +      Index++;
> +    }
> +  if (0 != Length) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"ERROR:GT Block Timer length mismatch. Unparsed %d bytes.\n",
> +      Length
> +    );
> +  }
> +  }
> +}
> +
> +/** This function parses the Platform Watchdog timer.
> +
> +  @params [in] Ptr     Pointer to the start of the watchdog timer data.
> +  @params [in] Length  Length of the watchdog timer structure.
> +**/
> +
> +STATIC
> +VOID
> +DumpWatchdogTimer (
> +  IN UINT8* Ptr,
> +  IN UINT16 Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    "SBSA Generic Watchdog",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (SBSAGenericWatchdogParser)
> +    );
> +}
> +
> +
> +/** This function parses the ACPI GTDT table.
> +  This function parses the GTDT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also parses the following platform timer structures:
> +    - GT Block timer
> +    - Watchdog timer
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiGtdt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Index;
> +  UINT8* TimerPtr;
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  ParseAcpi (
> +    TRUE,
> +    "GTDT",
> +    Ptr,
> +    AcpiTableLength,
> +    PARSER_PARAMS (GtdtParser)
> +    );
> +
> +  if (0 != *GtdtPlatformTimerCount) {
> +    TimerPtr = Ptr + (*GtdtPlatformTimerOffset);
> +    Index = 0;
> +    do {
> +      // Parse the Platform Timer Header
> +      ParseAcpi (
> +        FALSE,
> +        NULL,
> +        TimerPtr,
> +        4,  // GT Platform Timer structure header length.
> +        PARSER_PARAMS (GtPlatformTimerHeaderParser)
> +        );
> +      switch (*PlatformTimerType) {
> +        case EFI_ACPI_6_1_GTDT_GT_BLOCK:
> +          DumpGTBlock (TimerPtr, *PlatformTimerLength);
> +          break;
> +        case EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG:
> +          DumpWatchdogTimer (TimerPtr, *PlatformTimerLength);
> +          break;
> +        default:
> +          IncrementErrorCount ();
> +          Print (L"ERROR: INVALID Platform Timer Type\n");
> +          break;
> +      } // switch
> +      TimerPtr += (*PlatformTimerLength);
> +      Index++;
> +    } while (Index < *GtdtPlatformTimerCount);
> +  }
> +
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/IortParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/IortParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..2ed046d2f23bac82e127398f10
> 5d412d676b967c
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/IortParser.c
> @@ -0,0 +1,633 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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 "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +
> +/** The EIORT_NODE enum describes the IORT Node types.
> +**/
> +typedef enum IortNode {
> +  EIORT_NODE_ITS_GROUP,        ///< ITS Group node
> +  EIORT_NODE_NAMED_COMPONENT,  ///< Named Component node
> +  EIORT_NODE_ROOT_COMPLEX,     ///< Root Complex node
> +  EIORT_NODE_SMMUV1_V2,        ///< SMMU v1/v2 node
> +  EIORT_NODE_SMMUV3,           ///< SMMU v3 node
> +  EIORT_NODE_MAX
> +} EIORT_NODE;
> +
> +
> +// Local Variables
> +STATIC CONST UINT32* IortNodeCount;
> +STATIC CONST UINT32* IortNodeOffset;
> +
> +STATIC CONST UINT8* IortNodeType;
> +STATIC CONST UINT16* IortNodeLength;
> +STATIC CONST UINT32* IortIdMappingCount;
> +STATIC CONST UINT32* IortIdMappingOffset;
> +
> +STATIC CONST UINT32* InterruptContextCount;
> +STATIC CONST UINT32* InterruptContextOffset;
> +STATIC CONST UINT32* PmuInterruptCount;
> +STATIC CONST UINT32* PmuInterruptOffset;
> +
> +STATIC CONST UINT32* ItsCount;
> +
> +
> +/** This function validates the ID Mapping array count for the ITS node.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateItsIdMappingCount (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  );
> +
> +/** This function validates the ID Mapping array offset for the ITS node.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateItsIdArrayReference (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  );
> +
> +/** Helper Macro for populating the IORT Node header in the ACPI_PARSER
> +    array.
> +
> +  @params [out] ValidateIdMappingCount    Optional pointer to a function
> for
> +                                          validating the ID Mapping count.
> +  @params [out] ValidateIdArrayReference  Optional pointer to a function
> for
> +                                          validating the ID Array reference.
> +
> +**/
> +#define PARSE_IORT_NODE_HEADER(ValidateIdMappingCount,                   \
> +                               ValidateIdArrayReference)                 \
> +  { L"Type", 1, 0, L"%d", NULL, (VOID**)&IortNodeType, NULL, NULL },     \
> +  { L"Length", 2, 1, L"%d", NULL, (VOID**)&IortNodeLength, NULL, NULL }, \
> +  { L"Revision", 1, 3, L"%d", NULL, NULL, NULL, NULL },                  \
> +  { L"Reserved", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },                \
> +  { L"Number of ID mappings", 4, 8, L"%d", NULL,                         \
> +    (VOID**)&IortIdMappingCount, ValidateIdMappingCount, NULL },         \
> +  { L"Reference to ID Array", 4, 12, L"0x%x", NULL,                      \
> +    (VOID**)&IortIdMappingOffset, ValidateIdArrayReference, NULL }
> +
> +/** An ACPI_PARSER array describing the ACPI IORT Table
> +
> +**/
> +STATIC CONST ACPI_PARSER IortParser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"Number of IORT Nodes", 4, 36, L"%d", NULL,
> +   (VOID**)&IortNodeCount, NULL, NULL},
> +  {L"Offset to Array of IORT Nodes", 4, 40, L"0x%x", NULL,
> +   (VOID**)&IortNodeOffset, NULL, NULL},
> +  {L"Reserved", 4, 44, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the IORT node header structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER IortNodeHeaderParser[] = {
> +  PARSE_IORT_NODE_HEADER (NULL, NULL)
> +};
> +
> +/** An ACPI_PARSER array describing the IORT SMMUv1/2 node.
> +
> +**/
> +STATIC CONST ACPI_PARSER IortNodeSmmuV1V2Parser[] = {
> +  PARSE_IORT_NODE_HEADER (NULL, NULL),
> +  {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Span", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Model", 4, 32, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reference to Global Interrupt Array", 4, 40, L"0x%x", NULL, NULL, NULL,
> +   NULL},
> +  {L"Number of context interrupts", 4, 44, L"%d", NULL,
> +   (VOID**)&InterruptContextCount, NULL, NULL},
> +  {L"Reference to Context Interrupt Array", 4, 48, L"0x%x", NULL,
> +   (VOID**)&InterruptContextOffset, NULL, NULL},
> +  {L"Number of PMU Interrupts", 4, 52, L"%d", NULL,
> +   (VOID**)&PmuInterruptCount, NULL, NULL},
> +  {L"Reference to PMU Interrupt Array", 4, 56, L"0x%x", NULL,
> +   (VOID**)&PmuInterruptOffset, NULL, NULL},
> +
> +  // Interrupt Array
> +  {L"SMMU_NSgIrpt", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"SMMU_NSgIrpt interrupt flags", 4, 64, L"0x%x", NULL, NULL, NULL,
> NULL},
> +  {L"SMMU_NSgCfgIrpt", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"SMMU_NSgCfgIrpt interrupt flags", 4, 72, L"0x%x", NULL, NULL, NULL,
> NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the SMMUv1/2 Node Interrupt Array.
> +
> +**/
> +STATIC CONST ACPI_PARSER InterruptArrayParser[] = {
> +  {L"  Interrupt GSIV", 4, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"  Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the IORT ID Mapping.
> +
> +**/
> +STATIC CONST ACPI_PARSER IortNodeIdMappingParser[] = {
> +  {L"  Input base", 4, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"  Number of IDs", 4, 4, L"%d", NULL, NULL, NULL, NULL},
> +  {L"  Output base", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"  Output reference", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"  Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** An ACPI_PARSER array describing the IORT SMMUv3 node.
> +
> +**/
> +STATIC CONST ACPI_PARSER IortNodeSmmuV3Parser[] = {
> +  PARSE_IORT_NODE_HEADER (NULL, NULL),
> +  {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"VATOS Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Model", 4, 40, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Event", 4, 44, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PRI", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"GERR", 4, 52, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Sync", 4, 56, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the IORT ITS node.
> +
> +**/
> +STATIC CONST ACPI_PARSER IortNodeItsParser[] = {
> +  PARSE_IORT_NODE_HEADER (
> +    ValidateItsIdMappingCount,
> +    ValidateItsIdArrayReference
> +    ),
> +  {L"  Number of ITSs", 4, 16, L"%d", NULL, (VOID**)&ItsCount, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the ITS ID.
> +
> +**/
> +STATIC CONST ACPI_PARSER ItsIdParser[] = {
> +  { L"  GIC ITS Identifier", 4, 0, L"%d", NULL, NULL, NULL }
> +};
> +
> +
> +/** An ACPI_PARSER array describing the IORT Names Component node.
> +
> +**/
> +STATIC CONST ACPI_PARSER IortNodeNamedComponentParser[] = {
> +  PARSE_IORT_NODE_HEADER (NULL, NULL),
> +  {L"Node Flags", 4, 16, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Memory access properties", 8, 20, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Device memory address size limit", 1, 28, L"%d", NULL, NULL, NULL,
> NULL}
> +};
> +
> +
> +/** An ACPI_PARSER array describing the IORT Root Complex node.
> +
> +**/
> +STATIC CONST ACPI_PARSER IortNodeRootComplexParser[] = {
> +  PARSE_IORT_NODE_HEADER (NULL, NULL),
> +  {L"Memory access properties", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"ATS Attribute", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PCI Segment number", 4, 28, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** This function validates the ID Mapping array count for the ITS node.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateItsIdMappingCount (
> +  IN UINT8* Ptr,
> +  VOID*     Context
> +  )
> +{
> +  if (0 != *(UINT32*)Ptr) {
> +    IncrementErrorCount ();
> +    Print (L"\nERROR: IORT ID Mapping count must be zero.");
> +  }
> +}
> +
> +
> +/** This function validates the ID Mapping array offset for the ITS node.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateItsIdArrayReference (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (0 != *(UINT32*)Ptr) {
> +    IncrementErrorCount ();
> +    Print (L"\nERROR: IORT ID Mapping offset must be zero.");
> +  }
> +}
> +
> +
> +/** This function parses the IORT Node Id Mapping array.
> +
> +  @params [in] Ptr            Pointer to the start of the IORT Table.
> +  @params [in] MappingCount   The ID Mapping count.
> +  @params [in] MappingOffset  The offset of the ID Mapping array
> +                              from the start of the IORT table.
> +**/
> +
> +STATIC
> +VOID
> +DumpIortNodeIdMappings (
> +  IN UINT8* Ptr,
> +  IN UINT32 MappingCount,
> +  IN UINT32 MappingOffset
> +  )
> +{
> +  UINT8* IdMappingPtr;
> +  UINT32 Index;
> +  UINT32 Offset;
> +  CHAR8  Buffer[40];  // Used for AsciiName param of ParseAcpi
> +
> +  IdMappingPtr = Ptr + MappingOffset;
> +  Index = 0;
> +  while (Index < MappingCount) {
> +    AsciiSPrint (
> +      Buffer,
> +      sizeof (Buffer),
> +      "ID Mapping [%d]",
> +      Index
> +      );
> +    Offset = ParseAcpi (
> +               TRUE,
> +               Buffer,
> +               IdMappingPtr,
> +               20,
> +               PARSER_PARAMS (IortNodeIdMappingParser)
> +               );
> +    IdMappingPtr += Offset;
> +    Index++;
> +  }
> +}
> +
> +/** This function parses the IORT SMMUv1/2 node.
> +
> +  @params [in] Ptr            Pointer to the start of the buffer.
> +  @params [in] Length         Length of the buffer.
> +  @params [in] MappingCount   The ID Mapping count.
> +  @params [in] MappingOffset  The offset of the ID Mapping array
> +                              from the start of the IORT table.
> +
> +**/
> +STATIC
> +VOID
> +DumpIortNodeSmmuV1V2 (
> +  IN UINT8* Ptr,
> +  IN UINT16 Length,
> +  IN UINT32 MappingCount,
> +  IN UINT32 MappingOffset
> +  )
> +{
> +  UINT32 Index;
> +  UINT32 Offset;
> +  CHAR8  Buffer[50];  // Used for AsciiName param of ParseAcpi
> +
> +  UINT8* ArrayPtr;
> +
> +  ParseAcpi (
> +    TRUE,
> +    "SMMUv1 or SMMUv2 Node",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (IortNodeSmmuV1V2Parser)
> +    );
> +
> +  ArrayPtr = Ptr + *InterruptContextOffset;
> +  Index = 0;
> +  while (Index < *InterruptContextCount) {
> +    AsciiSPrint (
> +      Buffer,
> +      sizeof (Buffer),
> +      "Context Interrupts Array [%d]",
> +      Index
> +      );
> +    Offset = ParseAcpi (
> +               TRUE,
> +               Buffer,
> +               ArrayPtr,
> +               8,
> +               PARSER_PARAMS (InterruptArrayParser)
> +               );
> +    ArrayPtr += Offset;
> +    Index++;
> +  }
> +
> +  ArrayPtr = Ptr + *PmuInterruptOffset;
> +  Index = 0;
> +  while (Index < *PmuInterruptCount) {
> +    AsciiSPrint (
> +      Buffer,
> +      sizeof (Buffer),
> +      "PMU Interrupts Array [%d]",
> +      Index
> +      );
> +    Offset = ParseAcpi (
> +               TRUE,
> +               Buffer,
> +               ArrayPtr,
> +               8,
> +               PARSER_PARAMS (InterruptArrayParser)
> +               );
> +    ArrayPtr += Offset;
> +    Index++;
> +  }
> +
> +  if (0 != *IortIdMappingCount) {
> +    DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
> +  }
> +}
> +
> +/** This function parses the IORT SMMUv3 node.
> +
> +  @params [in] Ptr            Pointer to the start of the buffer.
> +  @params [in] Length         Length of the buffer.
> +  @params [in] MappingCount   The ID Mapping count.
> +  @params [in] MappingOffset  The offset of the ID Mapping array
> +                              from the start of the IORT table.
> +
> +**/
> +STATIC
> +VOID
> +DumpIortNodeSmmuV3 (
> +  IN UINT8* Ptr,
> +  IN UINT16 Length,
> +  IN UINT32 MappingCount,
> +  IN UINT32 MappingOffset
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    "SMMUV3 Node",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (IortNodeSmmuV3Parser)
> +    );
> +
> +  if (0 != *IortIdMappingCount) {
> +    DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
> +  }
> +}
> +
> +/** This function parses the IORT ITS node.
> +
> +  @params [in] Ptr            Pointer to the start of the buffer.
> +  @params [in] Length         Length of the buffer.
> +
> +**/
> +STATIC
> +VOID
> +DumpIortNodeIts (
> +  IN UINT8* Ptr,
> +  IN UINT16 Length
> +  )
> +{
> +  UINT32 Offset;
> +  UINT32 Index;
> +  UINT8* ItsIdPtr;
> +  CHAR8  Buffer[80];  // Used for AsciiName param of ParseAcpi
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             "ITS Node",
> +             Ptr,
> +             Length,
> +             PARSER_PARAMS (IortNodeItsParser)
> +             );
> +
> +  ItsIdPtr = Ptr + Offset;
> +  Index = 0;
> +  while (Index < *ItsCount) {
> +    AsciiSPrint (
> +      Buffer,
> +      sizeof (Buffer),
> +      "GIC ITS Identifier Array [%d]",
> +      Index
> +      );
> +    Offset = ParseAcpi (
> +               TRUE,
> +               Buffer,
> +               ItsIdPtr,
> +               4,
> +               PARSER_PARAMS (ItsIdParser)
> +               );
> +    ItsIdPtr += Offset;
> +    Index++;
> +  }
> +
> +  // Note: ITS does not have the ID Mappings Array
> +
> +}
> +
> +/** This function parses the IORT Named Component node.
> +
> +  @params [in] Ptr            Pointer to the start of the buffer.
> +  @params [in] Length         Length of the buffer.
> +  @params [in] MappingCount   The ID Mapping count.
> +  @params [in] MappingOffset  The offset of the ID Mapping array
> +                              from the start of the IORT table.
> +
> +**/
> +STATIC
> +VOID
> +DumpIortNodeNamedComponent (
> +  IN UINT8* Ptr,
> +  IN UINT16 Length,
> +  IN UINT32 MappingCount,
> +  IN UINT32 MappingOffset
> +  )
> +{
> +  UINT32 Offset;
> +  UINT32 Index;
> +  UINT8* DeviceNamePtr;
> +  UINT32 DeviceNameLength;
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             "Named Component Node",
> +             Ptr,
> +             Length,
> +             PARSER_PARAMS (IortNodeNamedComponentParser)
> +             );
> +
> +  DeviceNamePtr = Ptr + Offset;
> +  // Estimate the Device Name length
> +  DeviceNameLength = Length - Offset - (MappingCount * 20);
> +  Print (L"%-36s : ", L"Device Object Name");
> +  Index = 0;
> +  while ((Index < DeviceNameLength) && (0 != DeviceNamePtr[Index])) {
> +    Print (L"%c", DeviceNamePtr[Index++]);
> +  }
> +  Print (L"\n");
> +
> +  if (0 != *IortIdMappingCount) {
> +    DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
> +  }
> +}
> +
> +/** This function parses the IORT Root Complex node.
> +
> +  @params [in] Ptr            Pointer to the start of the buffer.
> +  @params [in] Length         Length of the buffer.
> +  @params [in] MappingCount   The ID Mapping count.
> +  @params [in] MappingOffset  The offset of the ID Mapping array
> +                              from the start of the IORT table.
> +
> +**/
> +STATIC
> +VOID
> +DumpIortNodeRootComplex (
> +  IN UINT8* Ptr,
> +  IN UINT16 Length,
> +  IN UINT32 MappingCount,
> +  IN UINT32 MappingOffset
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    "Root Complex Node",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (IortNodeRootComplexParser)
> +    );
> +
> +  if (0 != *IortIdMappingCount) {
> +    DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
> +  }
> +}
> +
> +
> +/** This function parses the ACPI IORT table.
> +  This function parses the IORT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also parses the following nodes:
> +    - ITS Group
> +    - Named Component
> +    - Root Complex
> +    - SMMUv1/2
> +    - SMMUv3
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiIort (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT32 Index;
> +  UINT8* NodePtr;
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  ParseAcpi (TRUE, "IORT", Ptr, AcpiTableLength, PARSER_PARAMS
> (IortParser));
> +  Offset = *IortNodeOffset;
> +  NodePtr = Ptr + Offset;
> +  Index = 0;
> +
> +  while ((Index < *IortNodeCount) && (Offset < AcpiTableLength)) {
> +    // Parse the IORT Node Header
> +    ParseAcpi (
> +      FALSE,
> +      "IORT Node Header",
> +      NodePtr,
> +      16,
> +      PARSER_PARAMS (IortNodeHeaderParser)
> +      );
> +    switch (*IortNodeType) {
> +      case EIORT_NODE_ITS_GROUP:
> +        DumpIortNodeIts (
> +          NodePtr,
> +          *IortNodeLength
> +          );
> +        break;
> +      case EIORT_NODE_NAMED_COMPONENT:
> +        DumpIortNodeNamedComponent (
> +          NodePtr,
> +          *IortNodeLength,
> +          *IortIdMappingCount,
> +          *IortIdMappingOffset
> +          );
> +        break;
> +      case EIORT_NODE_ROOT_COMPLEX:
> +        DumpIortNodeRootComplex (
> +          NodePtr,
> +          *IortNodeLength,
> +          *IortIdMappingCount,
> +          *IortIdMappingOffset
> +          );
> +        break;
> +      case EIORT_NODE_SMMUV1_V2:
> +        DumpIortNodeSmmuV1V2 (
> +          NodePtr,
> +          *IortNodeLength,
> +          *IortIdMappingCount,
> +          *IortIdMappingOffset
> +          );
> +        break;
> +      case EIORT_NODE_SMMUV3:
> +        DumpIortNodeSmmuV3 (
> +          NodePtr,
> +          *IortNodeLength,
> +          *IortIdMappingCount,
> +          *IortIdMappingOffset
> +          );
> +        break;
> +      default:
> +        IncrementErrorCount ();
> +        Print (L"ERROR: Unsupported IORT Node type = %d\n", *IortNodeType);
> +    } // switch
> +
> +    NodePtr += (*IortNodeLength);
> +    Offset += (*IortNodeLength);
> +  } // while
> +
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/MadtParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/MadtParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..552d6edb9e1de39c4ed173f8a
> 06e7092e8b713a7
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/MadtParser.c
> @@ -0,0 +1,273 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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 <IndustryStandard/Acpi.h>
> +#include <Library/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +// Local Variables
> +STATIC CONST UINT8* MadtInterruptControllerType;
> +STATIC CONST UINT8* MadtInterruptControllerLength;
> +
> +
> +/** An ACPI_PARSER array describing the GICC Interrupt
> +    Controller Structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER GicCParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"CPU Interface Number", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"ACPI Processor UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Parking Protocol Version", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +
> +  {L"Performance Interrupt GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Parked Address", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Physical Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"GICV", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"GICH", 8, 48, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"VGIC Maintenance interrupt", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"GICR Base Address", 8, 60, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"MPIDR", 8, 68, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Processor Power Efficiency Class", 1, 76, L"0x%x", NULL, NULL, NULL,
> +   NULL},
> +  {L"Reserved", 3, 77, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the GICD Interrupt
> +    Controller Structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER GicDParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"GIC ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"System Vector Base", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"GIC Version", 1, 20, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 3, 21, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}
> +};
> +
> +
> +/** An ACPI_PARSER array describing the MSI Frame Interrupt
> +    Controller Structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER GicMSIFrameParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"MSI Frame ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"SPI Count", 2, 20, L"%d", NULL, NULL, NULL, NULL},
> +  {L"SPI Base", 2, 22, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the GICR Interrupt
> +    Controller Structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER GicRParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"Discovery Range Base Address", 8, 4, L"0x%lx", NULL, NULL, NULL,
> +   NULL},
> +  {L"Discovery Range Length", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the GIC ITS Interrupt
> +    Controller Structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER GicITSParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"GIC ITS ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** An ACPI_PARSER array describing the ACPI MADT Table.
> +
> +**/
> +STATIC CONST ACPI_PARSER MadtParser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"Local Interrupt Controller Address", 4, 36, L"0x%x", NULL, NULL, NULL,
> +   NULL},
> +  {L"Flags", 4, 40, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** An ACPI_PARSER array describing the MADT Interrupt
> +    Controller Structure Header Structure.
> +**/
> +STATIC CONST ACPI_PARSER MadtInterruptControllerHeaderParser[] = {
> +  {NULL, 1, 0, NULL, NULL, (VOID**)&MadtInterruptControllerType, NULL,
> NULL},
> +  {L"Length", 1, 1, NULL, NULL, (VOID**)&MadtInterruptControllerLength,
> NULL,
> +   NULL},
> +  {L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** This function parses the ACPI MADT table.
> +  This function parses the MADT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function currently parses the following Interrupt Controller
> +  Structures:
> +    - GICC
> +    - GICD
> +    - GIC MSI Frame
> +    - GICR
> +    - GIC ITS
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiMadt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT8* InterruptContollerPtr;
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             "MADT",
> +             Ptr,
> +             AcpiTableLength,
> +             PARSER_PARAMS (MadtParser)
> +             );
> +  InterruptContollerPtr = Ptr + Offset;
> +
> +  while (Offset < AcpiTableLength) {
> +    // Parse Interrupt Controller Structure to obtain Length.
> +    ParseAcpi (
> +      FALSE,
> +      NULL,
> +      InterruptContollerPtr,
> +      2,  //  Length is 1 byte at offset 1
> +      PARSER_PARAMS (MadtInterruptControllerHeaderParser)
> +      );
> +
> +    if (((Offset + (*MadtInterruptControllerLength)) > AcpiTableLength) ||
> +        (*MadtInterruptControllerLength < 4)) {
> +      IncrementErrorCount ();
> +      Print (
> +         L"ERROR: Invalid Interrupt Controller Length,"
> +          " Type = %d, Length = %d",
> +         *MadtInterruptControllerType,
> +         *MadtInterruptControllerLength
> +         );
> +      break;
> +    }
> +
> +    switch (*MadtInterruptControllerType) {
> +      case EFI_ACPI_6_1_GIC: {
> +        ParseAcpi (
> +          TRUE,
> +          "GICC",
> +          InterruptContollerPtr,
> +          *MadtInterruptControllerLength,
> +          PARSER_PARAMS (GicCParser)
> +          );
> +        break;
> +      }
> +
> +      case EFI_ACPI_6_1_GICD: {
> +        ParseAcpi (
> +          TRUE,
> +          "GICD",
> +          InterruptContollerPtr,
> +          *MadtInterruptControllerLength,
> +          PARSER_PARAMS (GicDParser)
> +          );
> +        break;
> +      }
> +
> +      case EFI_ACPI_6_1_GIC_MSI_FRAME: {
> +        ParseAcpi (
> +          TRUE,
> +          "GIC MSI Frame",
> +          InterruptContollerPtr,
> +          *MadtInterruptControllerLength,
> +          PARSER_PARAMS (GicMSIFrameParser)
> +          );
> +        break;
> +      }
> +
> +      case EFI_ACPI_6_1_GICR: {
> +        ParseAcpi (
> +          TRUE,
> +          "GICR",
> +          InterruptContollerPtr,
> +          *MadtInterruptControllerLength,
> +          PARSER_PARAMS (GicRParser)
> +          );
> +        break;
> +      }
> +
> +      case EFI_ACPI_6_1_GIC_ITS: {
> +        ParseAcpi (
> +          TRUE,
> +          "GIC ITS",
> +          InterruptContollerPtr,
> +          *MadtInterruptControllerLength,
> +          PARSER_PARAMS (GicITSParser)
> +          );
> +        break;
> +      }
> +
> +      default: {
> +        IncrementErrorCount ();
> +        Print (
> +          L"ERROR: Unknown Interrupt Controller Structure,"
> +            " Type = %d, Length = %d",
> +          *MadtInterruptControllerType,
> +          *MadtInterruptControllerLength
> +          );
> +      }
> +    } // switch
> +    InterruptContollerPtr += *MadtInterruptControllerLength;
> +    Offset += *MadtInterruptControllerLength;
> +  } // while
> +
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/McfgParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/McfgParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..01a53b9a020a69b491f499b91
> 7289254d8071f6c
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/McfgParser.c
> @@ -0,0 +1,86 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +/** An ACPI_PARSER array describing the ACPI MCFG Table.
> +**/
> +STATIC CONST ACPI_PARSER McfgParser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"Reserved", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +};
> +
> +/** An ACPI_PARSER array describing the PCI configuration Space
> +    Base Address structure.
> +**/
> +STATIC CONST ACPI_PARSER PciCfgSpaceBaseAddrParser[] = {
> +  {L"Base Address", 8, 0, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"PCI Segment Group No.", 2, 8, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Start Bus No.", 1, 10, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"End Bus No.", 1, 11, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** This function parses the ACPI MCFG table.
> +  This function parses the MCFG table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiMcfg (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT32 PciCfgOffset;
> +  UINT8* PciCfgSpacePtr;
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             "MCFG",
> +             Ptr,
> +             AcpiTableLength,
> +             PARSER_PARAMS (McfgParser)
> +             );
> +
> +  PciCfgSpacePtr = Ptr + Offset;
> +
> +  while (Offset < AcpiTableLength) {
> +    PciCfgOffset = ParseAcpi (
> +                     TRUE,
> +                     "PCI Configuration Space",
> +                     PciCfgSpacePtr,
> +                     (AcpiTableLength - Offset),
> +                     PARSER_PARAMS (PciCfgSpaceBaseAddrParser)
> +                     );
> +    PciCfgSpacePtr += PciCfgOffset;
> +    Offset += PciCfgOffset;
> +  }
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/RsdpParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/RsdpParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..070d519c923421894eb90c8db
> ca22a6ad09c0cad
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/RsdpParser.c
> @@ -0,0 +1,173 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +#include "AcpiTableParser.h"
> +
> +/// The RSDP table signature is "RSD PTR " (8 bytes)
> +/// However The signature for ACPI tables is 4 bytes.
> +/// To work around this oddity define a signature type
> +/// that allows us to process the log options.
> +#define RSDP_TABLE_INFO  SIGNATURE_32('R', 'S', 'D', 'P')
> +
> +// Local Variables
> +STATIC CONST UINT64* XsdtAddress;
> +STATIC CONST UINT32* RsdpLength;
> +
> +
> +/** This function validates the RSDT Address.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateRsdtAddress (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  );
> +
> +/** This function validates the XSDT Address.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateXsdtAddress (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  );
> +
> +/** An array describing the ACPI RSDP Table.
> +
> +**/
> +STATIC CONST ACPI_PARSER RsdpParser[] = {
> +  {L"Signature", 8, 0, NULL, Dump8Chars, NULL, NULL, NULL},
> +  {L"Checksum", 1, 8, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Oem ID", 6, 9, NULL, Dump6Chars, NULL, NULL, NULL},
> +  {L"Revision", 1, 15, L"%d", NULL, NULL, NULL, NULL},
> +  {L"RSDT Address", 4, 16, L"0x%x", NULL, NULL, ValidateRsdtAddress, NULL},
> +  {L"Length", 4, 20, L"%d", NULL, (VOID**)&RsdpLength, NULL, NULL},
> +  {L"XSDT Address", 8, 24, L"0x%lx", NULL, (VOID**)&XsdtAddress,
> +   ValidateXsdtAddress, NULL},
> +  {L"Extended Checksum", 1, 32, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}
> +};
> +
> +/** This function validates the RSDT Address.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateRsdtAddress (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
> +  UINT32 RsdtAddr;
> +  RsdtAddr = *(UINT32*)Ptr;
> +  if (0 != RsdtAddr) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nERROR: Rsdt Address = 0x%p. This must be NULL on ARM Platforms",
> +      RsdtAddr
> +      );
> +  }
> +#endif
> +}
> +
> +/** This function validates the XSDT Address.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateXsdtAddress (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
> +  UINT64 XsdtAddr;
> +  XsdtAddr = *(UINT64*)Ptr;
> +  if (0 == XsdtAddr) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nERROR: Xsdt Address = 0x%p. This must not be NULL on ARM
> Platforms",
> +      XsdtAddr
> +      );
> +  }
> +#endif
> +}
> +
> +
> +/** This function parses the ACPI RSDP table.
> +  This function parses the RSDP table and optionally traces the ACPI
> +  table fields. ProcessTableReportOptions() is called to determine if
> +  the ACPI fields should be traced.
> +
> +  This function invokes the parser for the XSDT table.
> +  * Note - This function does not support parsing of RSDT table.
> +
> +  This function also performs a RAW dump of the ACPI table and
> +  validates the checksum.
> +
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +
> +  @retval EFI_SUCCESS             Success.
> +  @retval EFI_NOT_FOUND           Valid XSDT pointer not found.
> +**/
> +EFI_STATUS
> +ParseRsdp (
> +  IN UINT8* Ptr
> +  )
> +{
> +  BOOLEAN  Trace;
> +
> +  // The length is 4 bytes starting at offset 20
> +  ParseAcpi (FALSE, "RSDP", Ptr, 24, PARSER_PARAMS (RsdpParser));
> +
> +  Trace = ProcessTableReportOptions (RSDP_TABLE_INFO, Ptr,
> *RsdpLength);
> +
> +  if (Trace) {
> +    DumpRaw (Ptr, *RsdpLength);
> +    VerifyChecksum (TRUE, Ptr, *RsdpLength);
> +  }
> +
> +  ParseAcpi (Trace, "RSDP", Ptr, *RsdpLength, PARSER_PARAMS
> (RsdpParser));
> +
> +  // This code currently supports parsing of XSDT table only
> +  // and does not parse the RSDT table. Platforms provide the
> +  // RSDT to enable compatibility with ACPI 1.0 operating systems.
> +  // Therefore the RSDT should not be used on ARM platforms.
> +  if (0 == (*XsdtAddress)) {
> +    IncrementErrorCount ();
> +    Print (L"ERROR: XSDT Pointer is not set.\n");
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  ProcessAcpiTable ((UINT8*)(UINTN)(*XsdtAddress));
> +  return EFI_SUCCESS;
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/SlitParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/SlitParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..ee779b12930b35021d332ee73
> a1d1ead92dcd7da
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/SlitParser.c
> @@ -0,0 +1,141 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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 "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +// Local Variables
> +STATIC CONST UINT64* SlitSystemLocalityCount;
> +
> +
> +/** An ACPI_PARSER array describing the ACPI SLIT table.
> +
> +**/
> +STATIC CONST ACPI_PARSER SlitParser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"Number of System Localities", 8, 36, L"0x%lx", NULL,
> +   (VOID**)&SlitSystemLocalityCount, NULL, NULL}
> +};
> +
> +
> +/** Macro to get the value of a System Locality
> +
> +**/
> +#define SLIT_ELEMENT(Ptr, i, j) *(Ptr + (i * LocalityCount) + j)
> +
> +
> +/** This function parses the ACPI SLIT table.
> +  This function parses the SLIT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also validates System Localities for the following:
> +    - Diagonal elements have a normalized value of 10
> +    - Relative distance from System Locality at i*N+j is same as
> +      j*N+i
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiSlit (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT64 i;
> +  UINT64 j;
> +  UINT64 LocalityCount;
> +  UINT8* LocalityPtr;
> +  CHAR8  Buffer[80];  // Used for AsciiName param of ParseAcpi
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             "SLIT",
> +             Ptr,
> +             AcpiTableLength,
> +             PARSER_PARAMS (SlitParser)
> +             );
> +  LocalityPtr = Ptr + Offset;
> +
> +  LocalityCount = *SlitSystemLocalityCount;
> +  // We only print the Localities if the count is less than 16
> +  // If the locality count is more than 16 then refer to the
> +  // raw data dump.
> +  if (LocalityCount < 16) {
> +    AsciiSPrint (
> +      Buffer,
> +      sizeof (Buffer),
> +      "Entry[0x%lx][0x%lx]",
> +      LocalityCount,
> +      LocalityCount
> +      );
> +    Print (L"%-36a : ", Buffer);
> +    Print (L"\n");
> +    Print (L"       ");
> +    for (j = 0; j < LocalityCount; j++) {
> +      Print (L" (%3d) ", j);
> +    }
> +    Print (L"\n");
> +    for (i = 0; i < LocalityCount; i++) {
> +      Print (L" (%3d) ", i);
> +      for (j = 0; j < LocalityCount; j++) {
> +        Print (L"  %3d  ", SLIT_ELEMENT (LocalityPtr, i, j));
> +      }
> +      Print (L"\n");
> +    }
> +  }
> +  // Validate
> +  for (i = 0; i < LocalityCount; i++) {
> +    for (j = 0; j < LocalityCount; j++) {
> +      // Element[x][x] must be equal to 10
> +      if ((i == j) && (SLIT_ELEMENT (LocalityPtr, i, j) != 10)) {
> +        IncrementErrorCount ();
> +        Print (
> +          L"ERROR: Diagonal Element[0x%lx][0x%lx] (%3d)."
> +            " Normalized Value is not 10\n",
> +          i,
> +          j,
> +          SLIT_ELEMENT (LocalityPtr, i, j)
> +          );
> +      }
> +      // Element[i][j] must be equal to Element[j][i]
> +      if (SLIT_ELEMENT (LocalityPtr, i, j) !=
> +          SLIT_ELEMENT (LocalityPtr, j, i)) {
> +        IncrementErrorCount ();
> +        Print (
> +          L"ERROR: Relative distances for Element[0x%lx][0x%lx] (%3d) and \n"
> +           "Element[0x%lx][0x%lx] (%3d) do not match.\n",
> +          i,
> +          j,
> +          SLIT_ELEMENT (LocalityPtr, i, j),
> +          j,
> +          i,
> +          SLIT_ELEMENT (LocalityPtr, j, i)
> +          );
> +      }
> +    }
> +  }
> +
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/SpcrParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/SpcrParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..b7dcaa585a84553fb98a12e07
> 6c122d081c3d6d2
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/SpcrParser.c
> @@ -0,0 +1,148 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +/** This function validates the Interrupt Type.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateInterruptType (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  );
> +
> +/** This function validates the Irq.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateIrq (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  );
> +
> +/** An ACPI_PARSER array describing the ACPI SPCR Table.
> +
> +**/
> +STATIC CONST ACPI_PARSER SpcrParser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"Interface Type", 1, 36, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 3, 37, L"%x %x %x", Dump3Chars, NULL, NULL, NULL},
> +  {L"Base Address", 12, 40, NULL, DumpGas, NULL, NULL, NULL},
> +  {L"Interrupt Type", 1, 52, L"%d", NULL, NULL, ValidateInterruptType, NULL},
> +  {L"IRQ", 1, 53, L"%d", NULL, NULL, ValidateIrq, NULL},
> +  {L"Global System Interrupt", 4, 54, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Baud Rate", 1, 58, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Parity", 1, 59, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Stop Bits", 1, 60, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Flow Control", 1, 61, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Terminal Type", 1, 62, L"%d", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 63, L"%x", NULL, NULL, NULL, NULL},
> +
> +  {L"PCI Device ID", 2, 64, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PCI Vendor ID", 2, 66, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PCI Bus Number", 1, 68, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PCI Device Number", 1, 69, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PCI Function Number", 1, 70, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PCI Flags", 4, 71, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"PCI Segment", 1, 75, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 4, 76, L"%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** This function validates the Interrupt Type.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateInterruptType (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
> +  UINT8 InterruptType = *Ptr;
> +  if (8 != InterruptType) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nERROR: InterruptType = %d. This must be 8 on ARM Platforms",
> +      InterruptType
> +      );
> +  }
> +#endif
> +}
> +
> +/** This function validates the Irq.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateIrq (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
> +  UINT8 Irq = *Ptr;
> +  if (0 != Irq) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nERROR: Irq = %d. This must be zero on ARM Platforms",
> +      Irq
> +      );
> +  }
> +#endif
> +}
> +
> +/** This function parses the ACPI SPCR table.
> +  This function parses the SPCR table and optionally traces the ACPI
> +  table fields.
> +
> +  This function also performs validations of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiSpcr (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  // Dump the SPCR
> +  ParseAcpi (TRUE, "SPCR", Ptr, AcpiTableLength, PARSER_PARAMS
> (SpcrParser));
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/SratParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/SratParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..dcc0c896dfa009747e08176b24
> 75e98346a19aa3
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/SratParser.c
> @@ -0,0 +1,301 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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 <IndustryStandard/Acpi.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +// Local Variables
> +STATIC CONST UINT8* SratRAType;
> +STATIC CONST UINT8* SratRALength;
> +
> +/** This function validates the Reserved field in the SRAT table header.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateSratReserved (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  );
> +
> +/** This function traces the APIC Proximity Domain field.
> +
> +  @params [in] Format  Format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +STATIC
> +VOID
> +DumpSratApicProximity (
> +  IN  CONST CHAR16*  Format,
> +  IN  UINT8*         Ptr
> +  );
> +
> +/** An ACPI_PARSER array describing the SRAT Table.
> +
> +**/
> +STATIC CONST ACPI_PARSER SratParser[] = {
> +  PARSE_ACPI_HEADER (NULL, NULL, NULL),
> +  {L"Reserved", 4, 36, L"0x%x", NULL, NULL, ValidateSratReserved, NULL},
> +  {L"Reserved", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the Resource Allocation
> +    structure header.
> +
> +**/
> +STATIC CONST ACPI_PARSER SratResourceAllocationParser[] = {
> +  {L"Type", 1, 0, NULL, NULL, (VOID**)&SratRAType, NULL, NULL},
> +  {L"Length", 1, 1, NULL, NULL, (VOID**)&SratRALength, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the GICC Affinity structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER SratGicCAffinityParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"ACPI Processor UID", 4, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 10, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Clock Domain", 4, 14, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the Memory Affinity structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER SratMemAffinityParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 2, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address Low", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address High", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length Low", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length High", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the APIC/SAPIC Affinity structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER SratApciSapicAffinityParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"Proximity Domain [7:0]", 1, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"APIC ID", 1, 3, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Local SAPIC EID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Proximity Domain [31:8]", 3, 9, L"0x%x", DumpSratApicProximity,
> +   NULL, NULL, NULL},
> +  {L"Clock Domain", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +/** An ACPI_PARSER array describing the Processor Local x2APIC
> +    Affinity structure.
> +
> +**/
> +STATIC CONST ACPI_PARSER SratX2ApciAffinityParser[] = {
> +  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
> +
> +  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Proximity Domain", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"X2APIC ID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Clock Domain", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}
> +};
> +
> +
> +/** This function validates the Reserved field in the SRAT table header.
> +
> +  @params [in] Ptr     Pointer to the start of the field data.
> +  @params [in] Context Pointer to context specific information e.g. this
> +                       could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +ValidateSratReserved (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (1 != *(UINT32*)Ptr) {
> +    IncrementErrorCount ();
> +    Print (L"\nERROR: Reserved should be 1 for backward compatibility.");
> +  }
> +}
> +
> +/** This function traces the APIC Proximity Domain field.
> +
> +  @params [in] Format  Format string for tracing the data.
> +  @params [in] Ptr     Pointer to the start of the buffer.
> +
> +**/
> +STATIC
> +VOID
> +DumpSratApicProximity (
> + IN CONST CHAR16* Format,
> + IN UINT8*        Ptr
> + )
> +{
> +  UINT32 ProximityDomain = Ptr[0] | (Ptr[1] << 8) | (Ptr[2] << 16);
> +  Print (Format, ProximityDomain);
> +}
> +
> +
> +
> +/** This function parses the ACPI SRAT table.
> +  This function parses the SRAT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function parses the following Resource Allocation Structures:
> +    - Processor Local APIC/SAPIC Affinity Structure
> +    - Memory Affinity Structure
> +    - Processor Local x2APIC Affinity Structure
> +    - GICC Affinity Structure
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiSrat (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT8* ResourcePtr;
> +  UINT32 GicCAffinityIndex = 0;
> +  UINT32 MemoryAffinityIndex = 0;
> +  UINT32 ApicSapicAffinityIndex = 0;
> +  UINT32 X2ApicAffinityIndex = 0;
> +  CHAR8  Buffer[80];  // Used for AsciiName param of ParseAcpi
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             "SRAT",
> +             Ptr,
> +             AcpiTableLength,
> +             PARSER_PARAMS (SratParser)
> +             );
> +  ResourcePtr = Ptr + Offset;
> +
> +  while (Offset < AcpiTableLength) {
> +    ParseAcpi (
> +      FALSE,
> +      NULL,
> +      ResourcePtr,
> +      2,  // The length is 1 byte at offset 1
> +      PARSER_PARAMS (SratResourceAllocationParser)
> +      );
> +
> +    switch (*SratRAType) {
> +      case EFI_ACPI_6_1_GICC_AFFINITY:
> +        AsciiSPrint (
> +          Buffer,
> +          sizeof (Buffer),
> +          "GICC Affinity Structure [%d]",
> +          GicCAffinityIndex++
> +          );
> +        ParseAcpi (
> +          TRUE,
> +          Buffer,
> +          ResourcePtr,
> +          *SratRALength,
> +          PARSER_PARAMS (SratGicCAffinityParser)
> +          );
> +        break;
> +
> +      case EFI_ACPI_6_1_MEMORY_AFFINITY:
> +        AsciiSPrint (
> +          Buffer,
> +          sizeof (Buffer),
> +          "Memory Affinity Structure [%d]",
> +          MemoryAffinityIndex++
> +          );
> +        ParseAcpi (
> +          TRUE,
> +          Buffer,
> +          ResourcePtr,
> +          *SratRALength,
> +          PARSER_PARAMS (SratMemAffinityParser)
> +          );
> +        break;
> +
> +      case EFI_ACPI_6_1_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY:
> +        AsciiSPrint (
> +          Buffer,
> +          sizeof (Buffer),
> +          "APIC/SAPIC Affinity Structure [%d]",
> +          ApicSapicAffinityIndex++
> +          );
> +        ParseAcpi (
> +          TRUE,
> +          Buffer,
> +          ResourcePtr,
> +          *SratRALength,
> +          PARSER_PARAMS (SratApciSapicAffinityParser)
> +          );
> +        break;
> +
> +      case EFI_ACPI_6_1_PROCESSOR_LOCAL_X2APIC_AFFINITY:
> +        AsciiSPrint (
> +          Buffer,
> +          sizeof (Buffer),
> +          "X2APIC Affinity Structure [%d]",
> +          X2ApicAffinityIndex++
> +          );
> +        ParseAcpi (
> +          TRUE,
> +          Buffer,
> +          ResourcePtr,
> +          *SratRALength,
> +          PARSER_PARAMS (SratX2ApciAffinityParser)
> +          );
> +        break;
> +
> +      default:
> +        IncrementErrorCount ();
> +        Print (L"ERROR: Unknown SRAT Affinity type\n");
> +        break;
> +    }
> +
> +    ResourcePtr += (*SratRALength);
> +    Offset += (*SratRALength);
> +  }
> +
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/SsdtParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/SsdtParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..a5c96f7888af5f8f27bbc8d12e
> 9775c08ffa37b2
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/SsdtParser.c
> @@ -0,0 +1,43 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +
> +
> +/** This function parses the ACPI SSDT table.
> +  This function parses the SSDT table and optionally traces the ACPI
> +  table fields. For the SSDT table only the ACPI header fields are
> +  parsed and traced.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiSsdt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  DumpAcpiHeader (Ptr);
> +}
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..999f78377b76285e3ea7423b4
> 0cf3dffea6d4ea2
> --- /dev/null
> +++
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.c
> @@ -0,0 +1,105 @@
> +/** @file
> +  Main file for 'acpiview' Shell command function.
> +
> +  Copyright (c) 2016, ARM Limited. All rights reserved.<BR>
> +
> +  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 <Uefi.h>
> +#include <Guid/ShellLibHiiGuid.h>
> +#include <Library/ShellCommandLib.h>
> +#include <Library/HiiLib.h>
> +#include "UefiShellAcpiViewCommandLib.h"
> +
> +CONST CHAR16 gShellAcpiViewFileName[] = L"ShellCommand";
> +EFI_HANDLE gShellAcpiViewHiiHandle = NULL;
> +
> +/**
> +  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;
> +}
> +
> +/**
> +  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
> +ShellAcpiViewCommandLibConstructor (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  gShellAcpiViewHiiHandle = NULL;
> +
> +  // Check Shell Profile Debug1 bit of the profiles mask
> +  if ((FixedPcdGet8 (PcdShellProfileMask) & BIT1) == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  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
> +ShellAcpiViewCommandLibDestructor (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  if (gShellAcpiViewHiiHandle != NULL) {
> +    HiiRemovePackages (gShellAcpiViewHiiHandle);
> +  }
> +  return EFI_SUCCESS;
> +}
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/XsdtParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/XsdtParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..4ef9f367253bec72bbd83ba77
> 21e8c520a3ee0f0
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/XsdtParser.c
> @@ -0,0 +1,97 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, 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/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +#include "AcpiTableParser.h"
> +
> +// Local variables
> +STATIC CONST UINT32* TableSignature;
> +STATIC CONST UINT32* XsdtLength;
> +
> +
> +/** An ACPI_PARSER array describing the ACPI XSDT table.
> +
> +**/
> +STATIC CONST ACPI_PARSER XsdtParser[] = {
> +  PARSE_ACPI_HEADER (&TableSignature, &XsdtLength, NULL)
> +};
> +
> +
> +/** This function parses the ACPI XSDT table.
> +  This function parses the XSDT table and optionally traces the ACPI
> +  table fields.
> +
> +  This function invokes the parsers for the following ACPI tables:
> +    - FADT
> +    - GTDT
> +    - SPCR
> +    - MADT
> +    - DBG2
> +    - MCFG
> +    - SSDT
> +    - SRAT
> +    - SLIT
> +    - IORT
> +
> +  This function also performs validation of the XSDT table.
> +
> +  @params [in] Trace              If TRUE, trace the ACPI fields.
> +  @params [in] Ptr                Pointer to the start of the buffer.
> +  @params [in] AcpiTableLength    Length of the ACPI table.
> +  @params [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +ParseAcpiXsdt (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32        Offset;
> +  UINT64*       TablePointer;
> +
> +  // Parse the ACPI header to get the length
> +  ParseAcpi (
> +    FALSE,
> +    "XSDT",
> +    Ptr,
> +    ACPI_DESCRIPTION_HEADER_LENGTH,
> +    PARSER_PARAMS (XsdtParser)
> +    );
> +
> +  Offset = ParseAcpi (
> +             Trace,
> +             "XSDT",
> +             Ptr,
> +             *XsdtLength,
> +             PARSER_PARAMS (XsdtParser)
> +             );
> +
> +  Ptr += Offset;
> +
> +  TablePointer = (UINT64*)Ptr;
> +
> +  while (Offset < (*XsdtLength)) {
> +    Ptr = (UINT8*)(UINTN)(*TablePointer);
> +
> +    ProcessAcpiTable (Ptr);
> +
> +
> +    Offset += sizeof (UINT64);
> +    TablePointer++;
> +  } // while
> +}
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.uni
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.uni
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..6c9f826f714a9f00798d4a24a5
> 13b5b82615854d
> --- /dev/null
> +++
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> andLib.uni
> @@ -0,0 +1,124 @@
> +// /**
> +//
> +// Copyright (c) 2016, ARM Limited. All rights reserved.<BR>
> +// 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.
> +//
> +// Module Name:
> +//
> +// UefiShellAcpiViewCommandLib.uni
> +//
> +// Abstract:
> +//
> +// String definitions for UEFI Shell acpiview command
> +//
> +//
> +// **/
> +
> +/=#
> +
> +#langdef   en-US "english"
> +
> +#string STR_GEN_PROBLEM           #language en-US "%H%s%N: Unknown
> flag - '%H%s%N'\r\n"
> +#string STR_GEN_NO_VALUE          #language en-US "%H%s%N: Missing
> argument for flag - '%H%s%N'\r\n"
> +#string STR_GEN_TOO_MANY          #language en-US "%H%s%N: Too many
> arguments.\r\n"
> +#string STR_GEN_MISSING_OPTION    #language en-US "%H%s%N: Missing
> option '%H%s%N' required by flag - '%H%s%N'\r\n"
> +#string STR_GEN_READONLY_MEDIA    #language en-US "%H%s%N: Unable
> to write to the current directory, check if media is writable.\r\n"
> +
> +#string STR_GET_HELP_ACPIVIEW   #language en-US ""
> +".TH acpiview 0 "Display ACPI information."\r\n"
> +".SH NAME\r\n"
> +"Display ACPI Table information.\r\n"
> +".SH SYNOPSIS\r\n"
> +" \r\n"
> +"ACPIVIEW [[-?] | [[-l] | [-t AcpiTable [-b]]] [-c Highlight]]\r\n"
> +" \r\n"
> +".SH OPTIONS\r\n"
> +" \r\n"
> +"  -l - Display list of installed ACPI Table types.\r\n"
> +"  -t - Display only the specified AcpiTable.\r\n"
> +"         AcpiTable    : The required ACPI Table type.\r\n"
> +"  -b - Generate a binary file dump of the specified AcpiTable.\r\n"
> +"  -c - Enable/Disable Colour Highlighting.\r\n"
> +"         Highlight    : TRUE/ON enables highlighting;\r\n"
> +"                        FALSE/OFF (default) disables highlighting.\r\n"
> +"  -? - Show help.\r\n"
> +" \r\n"
> +".SH DESCRIPTION\r\n"
> +" \r\n"
> +"  This program is provided to allow examination of ACPI table values from
> the\r\n"
> +"  UEFI Shell.  This can help with investigations, especially at that stage
> where\r\n"
> +"  the tables are not enabling an OS to boot.\r\n"
> +"  The program is not exhaustive, and only encapsulates detailed knowledge
> of a\r\n"
> +"  limited number of table types.\r\n"
> +" \r\n"
> +"  Default behaviour is to display the content of all tables installed.\r\n"
> +"  'Known' table types (listed in NOTES below) will be parsed and
> displayed\r\n"
> +"  with descriptions and field values.  Where appropriate a degree of
> consistency\r\n"
> +"  checking is done and errors may be reported in the output.\r\n"
> +"  Other table types will be displayed as an array of Hexadecimal bytes.\r\n"
> +" \r\n"
> +"  To facilitate debugging, the -t and -b options can be used to generate
> a\r\n"
> +"  binary file image of a table that can be copied elsewhere for
> investigation\r\n"
> +"  using tools such as those provided by acpica.org.  This is especially
> relevant\r\n"
> +"  for AML type tables like DSDT and SSDT.\r\n"
> +" \r\n"
> +"NOTES:\r\n"
> +"  1. The AcpiTable parameter can match any installed table type.\r\n"
> +"     Tables without specific handling will be dispayed as a raw hex dump
> (or\r\n"
> +"     dumped to a file if -b is used).\r\n"
> +"  2. Formatted display and checking is provided for these signature
> types:\r\n"
> +"       APIC  - Multiple APIC Description Table (MADT)\r\n"
> +"       DBG2  - Debug Port Table 2\r\n"
> +"       FACP  - Fixed ACPI Description Table (FADT)\r\n"
> +"       GTDT  - Generic Timer Description Table\r\n"
> +"       IORT  - IO Remapping Table\r\n"
> +"       MCFG  - Memory Mapped Config Space Base Address Description
> Table\r\n"
> +"       RSDP  - Root System Description Pointer\r\n"
> +"       SLIT  - System Locality Information Table\r\n"
> +"       SPCR  - Serial Port Concole Redirection Table\r\n"
> +"       SRAT  - System Resource Affinity Table\r\n"
> +"       XSDT  - Extended System Description Table\r\n"
> +" \r\n"
> +".SH STANDARDS\r\n"
> +" \r\n"
> +"  Table details correspond to those in 'Advanced Configuration and
> Power\r\n"
> +"  Interface Specification' Version 6.1 [January, 2016]\r\n"
> +"  (http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf)\r\n"
> +" \r\n"
> +"  NOTE: The nature of the ACPI standard means that almost all tables in 6.1
> will\r\n"
> +"        be 'backwards compatible' with prior version of the specification
> in\r\n"
> +"        terms of structure, so formatted output should be correct.  The
> main\r\n"
> +"        exception will be that previously 'reserved' fields will be reported\r\n"
> +"        with new names, where they have been added in later versions of
> the\r\n"
> +"        specification.\r\n"
> +" \r\n"
> +".SH EXAMPLES\r\n"
> +" \r\n"
> +" \r\n"
> +"EXAMPLES:\r\n"
> +"  * To display a list of the installed table types:\r\n"
> +"    fs0:\> acpiview -l\r\n"
> +" \r\n"
> +"  * To parse and display a specific table type:\r\n"
> +"    fs0:\> acpiview -t GTDT\r\n"
> +" \r\n"
> +"  * To save a binary dump of the contents of a table to a file\r\n"
> +"    in the current working directory:\r\n"
> +"    fs0:\> acpiview -t DSDT -b\r\n"
> +" \r\n"
> +"  * To display contents of all ACPI tables:\r\n"
> +"    fs0:\> acpiview\r\n"
> +" \r\n"
> +".SH RETURNVALUES\r\n"
> +" \r\n"
> +"RETURN VALUES:\r\n"
> +"  SHELL_SUCCESS             Data was displayed as requested.\r\n"
> +"  SHELL_INVALID_PARAMETER   ACPI Table parsing failed.\r\n"
> +" \r\n"
> +
> --
> Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


  reply	other threads:[~2016-12-19  9:48 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-16 18:25 [PATCH] ShellPkg: Add acpiview tool to dump ACPI tables evan.lloyd
2016-12-19  9:48 ` Ni, Ruiyu [this message]
2016-12-19 15:57   ` Evan Lloyd
2016-12-19 18:01     ` Carsey, Jaben
2016-12-20  2:59       ` Ni, Ruiyu
2016-12-20  3:56         ` Carsey, Jaben
2016-12-20  4:49           ` Yao, Jiewen
2016-12-20  5:18             ` Ni, Ruiyu
2016-12-20  5:54               ` Yao, Jiewen
2016-12-20 13:20                 ` Evan Lloyd
2016-12-20 16:35                   ` Yao, Jiewen
2016-12-22 18:25                     ` Evan Lloyd
2016-12-23  1:31                       ` Yao, Jiewen
2017-01-13  8:10                         ` Bhupesh SHARMA
2017-01-13 13:26                           ` Yao, Jiewen
2016-12-23  3:35                     ` How to build commonlib of Basetools in x64 mode wang xiaofeng
     [not found]                       ` <CE7102C6-78B7-4631-8641-AF27FFAB52FE@apple.com>
2016-12-23  4:15                         ` wang xiaofeng
     [not found]                           ` <4A89E2EF3DFEDB4C8BFDE51014F606A14D6C3866@shsmsx102.ccr.corp.intel.com>
2016-12-23  4:54                             ` Andrew Fish
2016-12-23  5:02                               ` wang xiaofeng
2016-12-23  5:09                               ` Gao, Liming
2016-12-20 12:22         ` [PATCH] ShellPkg: Add acpiview tool to dump ACPI tables Evan Lloyd
  -- strict thread matches above, loose matches on Subject: below --
2017-12-15 19:28 evan.lloyd
2017-12-15 19:37 ` Evan Lloyd

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=734D49CCEBEEF84792F5B80ED585239D5B836C04@SHSMSX103.ccr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox