diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec
index bb31c2df8cb33bdea0ac46035429d6e36a77e25d..c651358355a96ccc09614c67a8fb31d62d0b8c21 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/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
new file mode 100644
index 0000000000000000000000000000000000000000..0c88085e40c117daec4db9b99e267ee0c56048b3
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.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..803ebf3653fff81e83f788ed9925fd6e90ea0f2d
--- /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..ec3863610a0ef28cb01f81ac51306d6d32dac4a2
--- /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..2d939f95ce8328e18c69a823d0582812b4500a82
--- /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/UefiShellAcpiViewCommandLib.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.h
new file mode 100644
index 0000000000000000000000000000000000000000..d8bf0e603a2ed50e204dcbbf355707353da07982
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.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..150f1ab2d97898b98c9b33d933a39eafcd6098d7
--- /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..ff6e00a5cb254478ab34f6dcabb05cfae69b9cfa
--- /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..2e8b4dc09b08a3b5d96f59920fe22913ce771107
--- /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..09c9c9daa7caca4d9e111f034eda54d02b634c33
--- /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..cafc52467c1a2e0a69703446cb2f080e7287b857
--- /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..49987f877e7b78852b26e9a3ec12b79b7f7c6c70
--- /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..b6c8c91cd9d758ee066d514a49499209cf7df3ed
--- /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..2ed046d2f23bac82e127398f105d412d676b967c
--- /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..552d6edb9e1de39c4ed173f8a06e7092e8b713a7
--- /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..01a53b9a020a69b491f499b917289254d8071f6c
--- /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..070d519c923421894eb90c8dbca22a6ad09c0cad
--- /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..ee779b12930b35021d332ee73a1d1ead92dcd7da
--- /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..b7dcaa585a84553fb98a12e076c122d081c3d6d2
--- /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..dcc0c896dfa009747e08176b2475e98346a19aa3
--- /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..a5c96f7888af5f8f27bbc8d12e9775c08ffa37b2
--- /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/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
new file mode 100644
index 0000000000000000000000000000000000000000..999f78377b76285e3ea7423b40cf3dffea6d4ea2
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.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..4ef9f367253bec72bbd83ba7721e8c520a3ee0f0
--- /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/UefiShellAcpiViewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
new file mode 100644
index 0000000000000000000000000000000000000000..6c9f826f714a9f00798d4a24a513b5b82615854d
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.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"
+
