]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
ShellPkg: Apply uncrustify changes
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Madt / MadtParser.c
index a704b0c6314d2fa2da1c218f2fc644f464e99a7a..aaa68c99f51457050df0c6af39ab5e4912dc729f 100644 (file)
@@ -1,28 +1,27 @@
 /** @file\r
   MADT table parser\r
 \r
-  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
   @par Reference(s):\r
-    - ACPI 6.2 Specification - Errata A, September 2017\r
+    - ACPI 6.3 Specification - January 2019\r
+    - Arm Generic Interrupt Controller Architecture Specification,\r
+      GIC architecture version 3 and version 4, issue E\r
+    - Arm Server Base System Architecture 5.0\r
 **/\r
 \r
 #include <IndustryStandard/Acpi.h>\r
 #include <Library/UefiLib.h>\r
 #include "AcpiParser.h"\r
 #include "AcpiTableParser.h"\r
+#include "AcpiViewConfig.h"\r
+#include "MadtParser.h"\r
 \r
 // Local Variables\r
-STATIC CONST UINT8MadtInterruptControllerType;\r
-STATIC CONST UINT8MadtInterruptControllerLength;\r
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
+STATIC CONST UINT8                   *MadtInterruptControllerType;\r
+STATIC CONST UINT8                   *MadtInterruptControllerLength;\r
+STATIC ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;\r
 \r
 /**\r
   This function validates the System Vector Base in the GICD.\r
@@ -35,136 +34,223 @@ STATIC
 VOID\r
 EFIAPI\r
 ValidateGICDSystemVectorBase (\r
-  IN UINT8* Ptr,\r
-  IN VOID*  Context\r
-  );\r
+  IN UINT8  *Ptr,\r
+  IN VOID   *Context\r
+  )\r
+{\r
+  if (*(UINT32 *)Ptr != 0) {\r
+    IncrementErrorCount ();\r
+    Print (\r
+      L"\nERROR: System Vector Base must be zero."\r
+      );\r
+  }\r
+}\r
+\r
+/**\r
+  This function validates the SPE Overflow Interrupt in the GICC.\r
+\r
+  @param [in] Ptr     Pointer to the start of the field data.\r
+  @param [in] Context Pointer to context specific information e.g. this\r
+                      could be a pointer to the ACPI table header.\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+ValidateSpeOverflowInterrupt (\r
+  IN UINT8  *Ptr,\r
+  IN VOID   *Context\r
+  )\r
+{\r
+  UINT16  SpeOverflowInterrupt;\r
+\r
+  SpeOverflowInterrupt = *(UINT16 *)Ptr;\r
+\r
+  // SPE not supported by this processor\r
+  if (SpeOverflowInterrupt == 0) {\r
+    return;\r
+  }\r
+\r
+  if ((SpeOverflowInterrupt < ARM_PPI_ID_MIN) ||\r
+      ((SpeOverflowInterrupt > ARM_PPI_ID_MAX) &&\r
+       (SpeOverflowInterrupt < ARM_PPI_ID_EXTENDED_MIN)) ||\r
+      (SpeOverflowInterrupt > ARM_PPI_ID_EXTENDED_MAX))\r
+  {\r
+    IncrementErrorCount ();\r
+    Print (\r
+      L"\nERROR: SPE Overflow Interrupt ID of %d is not in the allowed PPI ID "\r
+      L"ranges of %d-%d or %d-%d (for GICv3.1 or later).",\r
+      SpeOverflowInterrupt,\r
+      ARM_PPI_ID_MIN,\r
+      ARM_PPI_ID_MAX,\r
+      ARM_PPI_ID_EXTENDED_MIN,\r
+      ARM_PPI_ID_EXTENDED_MAX\r
+      );\r
+  } else if (SpeOverflowInterrupt != ARM_PPI_ID_PMBIRQ) {\r
+    IncrementWarningCount ();\r
+    Print (\r
+      L"\nWARNING: SPE Overflow Interrupt ID of %d is not compliant with SBSA "\r
+      L"Level 3 PPI ID assignment: %d.",\r
+      SpeOverflowInterrupt,\r
+      ARM_PPI_ID_PMBIRQ\r
+      );\r
+  }\r
+}\r
 \r
 /**\r
   An ACPI_PARSER array describing the GICC Interrupt Controller Structure.\r
 **/\r
-STATIC CONST ACPI_PARSER GicCParser[] = {\r
-  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},\r
-  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
-\r
-  {L"CPU Interface Number", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"ACPI Processor UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Parking Protocol Version", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},\r
-\r
-  {L"Performance Interrupt GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Parked Address", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"Physical Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"GICV", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"GICH", 8, 48, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"VGIC Maintenance interrupt", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"GICR Base Address", 8, 60, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"MPIDR", 8, 68, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"Processor Power Efficiency Class", 1, 76, L"0x%x", NULL, NULL, NULL,\r
-   NULL},\r
-  {L"Reserved", 3, 77, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}\r
+STATIC CONST ACPI_PARSER  GicCParser[] = {\r
+  { L"Type",                             1, 0,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Length",                           1, 1,  L"%d",    NULL, NULL, NULL, NULL },\r
+  { L"Reserved",                         2, 2,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+\r
+  { L"CPU Interface Number",             4, 4,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"ACPI Processor UID",               4, 8,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Flags",                            4, 12, L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Parking Protocol Version",         4, 16, L"0x%x",  NULL, NULL, NULL, NULL },\r
+\r
+  { L"Performance Interrupt GSIV",       4, 20, L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Parked Address",                   8, 24, L"0x%lx", NULL, NULL, NULL, NULL },\r
+  { L"Physical Base Address",            8, 32, L"0x%lx", NULL, NULL, NULL, NULL },\r
+  { L"GICV",                             8, 40, L"0x%lx", NULL, NULL, NULL, NULL },\r
+  { L"GICH",                             8, 48, L"0x%lx", NULL, NULL, NULL, NULL },\r
+  { L"VGIC Maintenance interrupt",       4, 56, L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"GICR Base Address",                8, 60, L"0x%lx", NULL, NULL, NULL, NULL },\r
+  { L"MPIDR",                            8, 68, L"0x%lx", NULL, NULL, NULL, NULL },\r
+  { L"Processor Power Efficiency Class", 1, 76, L"0x%x",  NULL, NULL, NULL,\r
+    NULL },\r
+  { L"Reserved",                         1, 77, L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"SPE overflow Interrupt",           2, 78, L"0x%x",  NULL, NULL,\r
+    ValidateSpeOverflowInterrupt, NULL }\r
 };\r
 \r
 /**\r
   An ACPI_PARSER array describing the GICD Interrupt Controller Structure.\r
 **/\r
-STATIC CONST ACPI_PARSER GicDParser[] = {\r
-  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},\r
-  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
-\r
-  {L"GIC ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"System Vector Base", 4, 16, L"0x%x", NULL, NULL,\r
-    ValidateGICDSystemVectorBase, NULL},\r
-  {L"GIC Version", 1, 20, L"%d", NULL, NULL, NULL, NULL},\r
-  {L"Reserved", 3, 21, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}\r
+STATIC CONST ACPI_PARSER  GicDParser[] = {\r
+  { L"Type",                  1, 0,  L"0x%x",     NULL,       NULL, NULL, NULL },\r
+  { L"Length",                1, 1,  L"%d",       NULL,       NULL, NULL, NULL },\r
+  { L"Reserved",              2, 2,  L"0x%x",     NULL,       NULL, NULL, NULL },\r
+\r
+  { L"GIC ID",                4, 4,  L"0x%x",     NULL,       NULL, NULL, NULL },\r
+  { L"Physical Base Address", 8, 8,  L"0x%lx",    NULL,       NULL, NULL, NULL },\r
+  { L"System Vector Base",    4, 16, L"0x%x",     NULL,       NULL,\r
+    ValidateGICDSystemVectorBase, NULL },\r
+  { L"GIC Version",           1, 20, L"%d",       NULL,       NULL, NULL, NULL },\r
+  { L"Reserved",              3, 21, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }\r
 };\r
 \r
 /**\r
   An ACPI_PARSER array describing the MSI Frame Interrupt Controller Structure.\r
 **/\r
-STATIC CONST ACPI_PARSER GicMSIFrameParser[] = {\r
-  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},\r
-  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
+STATIC CONST ACPI_PARSER  GicMSIFrameParser[] = {\r
+  { L"Type",                  1, 0,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Length",                1, 1,  L"%d",    NULL, NULL, NULL, NULL },\r
+  { L"Reserved",              2, 2,  L"0x%x",  NULL, NULL, NULL, NULL },\r
 \r
-  {L"MSI Frame ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},\r
+  { L"MSI Frame ID",          4, 4,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Physical Base Address", 8, 8,  L"0x%lx", NULL, NULL, NULL, NULL },\r
+  { L"Flags",                 4, 16, L"0x%x",  NULL, NULL, NULL, NULL },\r
 \r
-  {L"SPI Count", 2, 20, L"%d", NULL, NULL, NULL, NULL},\r
-  {L"SPI Base", 2, 22, L"0x%x", NULL, NULL, NULL, NULL}\r
+  { L"SPI Count",             2, 20, L"%d",    NULL, NULL, NULL, NULL },\r
+  { L"SPI Base",              2, 22, L"0x%x",  NULL, NULL, NULL, NULL }\r
 };\r
 \r
 /**\r
   An ACPI_PARSER array describing the GICR Interrupt Controller Structure.\r
 **/\r
-STATIC CONST ACPI_PARSER GicRParser[] = {\r
-  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},\r
-  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
-\r
-  {L"Discovery Range Base Address", 8, 4, L"0x%lx", NULL, NULL, NULL,\r
-   NULL},\r
-  {L"Discovery Range Length", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}\r
+STATIC CONST ACPI_PARSER  GicRParser[] = {\r
+  { L"Type",                         1, 0,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Length",                       1, 1,  L"%d",    NULL, NULL, NULL, NULL },\r
+  { L"Reserved",                     2, 2,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+\r
+  { L"Discovery Range Base Address", 8, 4,  L"0x%lx", NULL, NULL, NULL,\r
+    NULL },\r
+  { L"Discovery Range Length",       4, 12, L"0x%x",  NULL, NULL, NULL, NULL }\r
 };\r
 \r
 /**\r
   An ACPI_PARSER array describing the GIC ITS Interrupt Controller Structure.\r
 **/\r
-STATIC CONST ACPI_PARSER GicITSParser[] = {\r
-  {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},\r
-  {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
-\r
-  {L"GIC ITS ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},\r
-  {L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}\r
+STATIC CONST ACPI_PARSER  GicITSParser[] = {\r
+  { L"Type",                  1, 0,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Length",                1, 1,  L"%d",    NULL, NULL, NULL, NULL },\r
+  { L"Reserved",              2, 2,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+\r
+  { L"GIC ITS ID",            4, 4,  L"0x%x",  NULL, NULL, NULL, NULL },\r
+  { L"Physical Base Address", 8, 8,  L"0x%lx", NULL, NULL, NULL, NULL },\r
+  { L"Reserved",              4, 16, L"0x%x",  NULL, NULL, NULL, NULL }\r
 };\r
 \r
 /**\r
-  An ACPI_PARSER array describing the ACPI MADT Table.\r
+  An ACPI_PARSER array describing the IO APIC Structure.\r
 **/\r
-STATIC CONST ACPI_PARSER MadtParser[] = {\r
-  PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
-  {L"Local Interrupt Controller Address", 4, 36, L"0x%x", NULL, NULL, NULL,\r
-   NULL},\r
-  {L"Flags", 4, 40, L"0x%x", NULL, NULL, NULL, NULL}\r
+STATIC CONST ACPI_PARSER  IoApic[] = {\r
+  { L"Type",                         1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Length",                       1, 1, L"%d",   NULL, NULL, NULL, NULL },\r
+  { L"I/O APIC ID",                  1, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Reserved",                     1, 3, L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"I/O APIC Address",             4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Global System Interrupt Base", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }\r
 };\r
 \r
 /**\r
-  An ACPI_PARSER array describing the MADT Interrupt Controller Structure Header Structure.\r
+  An ACPI_PARSER array describing the Interrupt Source Override Structure.\r
 **/\r
-STATIC CONST ACPI_PARSER MadtInterruptControllerHeaderParser[] = {\r
-  {NULL, 1, 0, NULL, NULL, (VOID**)&MadtInterruptControllerType, NULL, NULL},\r
-  {L"Length", 1, 1, NULL, NULL, (VOID**)&MadtInterruptControllerLength, NULL,\r
-   NULL},\r
-  {L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL}\r
+STATIC CONST ACPI_PARSER  InterruptSourceOverride[] = {\r
+  { L"Type",                    1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Length",                  1, 1, L"%d",   NULL, NULL, NULL, NULL },\r
+  { L"Bus",                     1, 2, L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Source",                  1, 3, L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Global System Interrupt", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Flags",                   2, 8, L"0x%x", NULL, NULL, NULL, NULL }\r
 };\r
 \r
 /**\r
-  This function validates the System Vector Base in the GICD.\r
+  An ACPI_PARSER array describing the Processor Local x2APIC Structure.\r
+**/\r
+STATIC CONST ACPI_PARSER  ProcessorLocalX2Apic[] = {\r
+  { L"Type",               1, 0,  L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Length",             1, 1,  L"%d",   NULL, NULL, NULL, NULL },\r
+  { L"Reserved",           2, 2,  L"0x%x", NULL, NULL, NULL, NULL },\r
+\r
+  { L"X2APIC ID",          4, 4,  L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"Flags",              4, 8,  L"0x%x", NULL, NULL, NULL, NULL },\r
+  { L"ACPI Processor UID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }\r
+};\r
 \r
-  @param [in] Ptr     Pointer to the start of the field data.\r
-  @param [in] Context Pointer to context specific information e.g. this\r
-                      could be a pointer to the ACPI table header.\r
+/**\r
+  An ACPI_PARSER array describing the Local x2APIC NMI Structure.\r
 **/\r
-STATIC\r
-VOID\r
-EFIAPI\r
-ValidateGICDSystemVectorBase (\r
-  IN UINT8* Ptr,\r
-  IN VOID*  Context\r
-)\r
-{\r
-  if (*(UINT32*)Ptr != 0) {\r
-    IncrementErrorCount ();\r
-    Print (\r
-      L"\nERROR: System Vector Base must be zero."\r
-    );\r
-  }\r
-}\r
+STATIC CONST ACPI_PARSER  LocalX2ApicNmi[] = {\r
+  { L"Type",               1, 0, L"0x%x",     NULL,       NULL, NULL, NULL },\r
+  { L"Length",             1, 1, L"%d",       NULL,       NULL, NULL, NULL },\r
+  { L"Flags",              2, 2, L"0x%x",     NULL,       NULL, NULL, NULL },\r
+\r
+  { L"ACPI Processor UID", 4, 4, L"0x%x",     NULL,       NULL, NULL, NULL },\r
+  { L"Local x2APIC LINT#", 1, 8, L"0x%x",     NULL,       NULL, NULL, NULL },\r
+  { L"Reserved",           3, 9, L"0x%x%x%x", Dump3Chars, NULL, NULL, NULL }\r
+};\r
+\r
+/**\r
+  An ACPI_PARSER array describing the ACPI MADT Table.\r
+**/\r
+STATIC CONST ACPI_PARSER  MadtParser[] = {\r
+  PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
+  { L"Local Interrupt Controller Address",4,         36, L"0x%x", NULL, NULL, NULL,\r
+    NULL },\r
+  { L"Flags",                      4,         40, L"0x%x", NULL, NULL, NULL,NULL}\r
+};\r
+\r
+/**\r
+  An ACPI_PARSER array describing the MADT Interrupt Controller Structure Header Structure.\r
+**/\r
+STATIC CONST ACPI_PARSER  MadtInterruptControllerHeaderParser[] = {\r
+  { NULL,        1, 0, NULL, NULL, (VOID **)&MadtInterruptControllerType,   NULL, NULL },\r
+  { L"Length",   1, 1, NULL, NULL, (VOID **)&MadtInterruptControllerLength, NULL,\r
+    NULL },\r
+  { L"Reserved", 2, 2, NULL, NULL, NULL,                                    NULL, NULL }\r
+};\r
 \r
 /**\r
   This function parses the ACPI MADT table.\r
@@ -189,15 +275,15 @@ ValidateGICDSystemVectorBase (
 VOID\r
 EFIAPI\r
 ParseAcpiMadt (\r
-  IN BOOLEAN Trace,\r
-  IN UINT8*  Ptr,\r
-  IN UINT32  AcpiTableLength,\r
-  IN UINT8   AcpiTableRevision\r
+  IN BOOLEAN  Trace,\r
+  IN UINT8    *Ptr,\r
+  IN UINT32   AcpiTableLength,\r
+  IN UINT8    AcpiTableRevision\r
   )\r
 {\r
-  UINT32 Offset;\r
-  UINT8InterruptContollerPtr;\r
-  UINT32 GICDCount;\r
+  UINT32  Offset;\r
+  UINT8   *InterruptContollerPtr;\r
+  UINT32  GICDCount;\r
 \r
   GICDCount = 0;\r
 \r
@@ -222,24 +308,42 @@ ParseAcpiMadt (
       0,\r
       NULL,\r
       InterruptContollerPtr,\r
-      2,  //  Length is 1 byte at offset 1\r
+      AcpiTableLength - Offset,\r
       PARSER_PARAMS (MadtInterruptControllerHeaderParser)\r
       );\r
 \r
-    if (((Offset + (*MadtInterruptControllerLength)) > AcpiTableLength) ||\r
-        (*MadtInterruptControllerLength < 4)) {\r
+    // Check if the values used to control the parsing logic have been\r
+    // successfully read.\r
+    if ((MadtInterruptControllerType == NULL) ||\r
+        (MadtInterruptControllerLength == NULL))\r
+    {\r
       IncrementErrorCount ();\r
       Print (\r
-         L"ERROR: Invalid Interrupt Controller Length,"\r
-          " Type = %d, Length = %d\n",\r
-         *MadtInterruptControllerType,\r
-         *MadtInterruptControllerLength\r
-         );\r
-      break;\r
+        L"ERROR: Insufficient remaining table buffer length to read the " \\r
+        L"Interrupt Controller Structure header. Length = %d.\n",\r
+        AcpiTableLength - Offset\r
+        );\r
+      return;\r
+    }\r
+\r
+    // Validate Interrupt Controller Structure length\r
+    if ((*MadtInterruptControllerLength == 0) ||\r
+        ((Offset + (*MadtInterruptControllerLength)) > AcpiTableLength))\r
+    {\r
+      IncrementErrorCount ();\r
+      Print (\r
+        L"ERROR: Invalid Interrupt Controller Structure length. " \\r
+        L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",\r
+        *MadtInterruptControllerLength,\r
+        Offset,\r
+        AcpiTableLength\r
+        );\r
+      return;\r
     }\r
 \r
     switch (*MadtInterruptControllerType) {\r
-      case EFI_ACPI_6_2_GIC: {\r
+      case EFI_ACPI_6_3_GIC:\r
+      {\r
         ParseAcpi (\r
           TRUE,\r
           2,\r
@@ -251,15 +355,17 @@ ParseAcpiMadt (
         break;\r
       }\r
 \r
-      case EFI_ACPI_6_2_GICD: {\r
+      case EFI_ACPI_6_3_GICD:\r
+      {\r
         if (++GICDCount > 1) {\r
           IncrementErrorCount ();\r
           Print (\r
             L"ERROR: Only one GICD must be present,"\r
-              " GICDCount = %d\n",\r
+            L" GICDCount = %d\n",\r
             GICDCount\r
             );\r
         }\r
+\r
         ParseAcpi (\r
           TRUE,\r
           2,\r
@@ -271,7 +377,8 @@ ParseAcpiMadt (
         break;\r
       }\r
 \r
-      case EFI_ACPI_6_2_GIC_MSI_FRAME: {\r
+      case EFI_ACPI_6_3_GIC_MSI_FRAME:\r
+      {\r
         ParseAcpi (\r
           TRUE,\r
           2,\r
@@ -283,7 +390,8 @@ ParseAcpiMadt (
         break;\r
       }\r
 \r
-      case EFI_ACPI_6_2_GICR: {\r
+      case EFI_ACPI_6_3_GICR:\r
+      {\r
         ParseAcpi (\r
           TRUE,\r
           2,\r
@@ -295,7 +403,8 @@ ParseAcpiMadt (
         break;\r
       }\r
 \r
-      case EFI_ACPI_6_2_GIC_ITS: {\r
+      case EFI_ACPI_6_3_GIC_ITS:\r
+      {\r
         ParseAcpi (\r
           TRUE,\r
           2,\r
@@ -307,11 +416,64 @@ ParseAcpiMadt (
         break;\r
       }\r
 \r
-      default: {\r
+      case EFI_ACPI_6_3_IO_APIC:\r
+      {\r
+        ParseAcpi (\r
+          TRUE,\r
+          2,\r
+          "IO APIC",\r
+          InterruptContollerPtr,\r
+          *MadtInterruptControllerLength,\r
+          PARSER_PARAMS (IoApic)\r
+          );\r
+        break;\r
+      }\r
+\r
+      case EFI_ACPI_6_3_INTERRUPT_SOURCE_OVERRIDE:\r
+      {\r
+        ParseAcpi (\r
+          TRUE,\r
+          2,\r
+          "INTERRUPT SOURCE OVERRIDE",\r
+          InterruptContollerPtr,\r
+          *MadtInterruptControllerLength,\r
+          PARSER_PARAMS (InterruptSourceOverride)\r
+          );\r
+        break;\r
+      }\r
+\r
+      case EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC:\r
+      {\r
+        ParseAcpi (\r
+          TRUE,\r
+          2,\r
+          "PROCESSOR LOCAL X2APIC",\r
+          InterruptContollerPtr,\r
+          *MadtInterruptControllerLength,\r
+          PARSER_PARAMS (ProcessorLocalX2Apic)\r
+          );\r
+        break;\r
+      }\r
+\r
+      case EFI_ACPI_6_3_LOCAL_X2APIC_NMI:\r
+      {\r
+        ParseAcpi (\r
+          TRUE,\r
+          2,\r
+          "LOCAL x2APIC NMI",\r
+          InterruptContollerPtr,\r
+          *MadtInterruptControllerLength,\r
+          PARSER_PARAMS (LocalX2ApicNmi)\r
+          );\r
+        break;\r
+      }\r
+\r
+      default:\r
+      {\r
         IncrementErrorCount ();\r
         Print (\r
           L"ERROR: Unknown Interrupt Controller Structure,"\r
-            " Type = %d, Length = %d\n",\r
+          L" Type = %d, Length = %d\n",\r
           *MadtInterruptControllerType,\r
           *MadtInterruptControllerLength\r
           );\r
@@ -319,6 +481,6 @@ ParseAcpiMadt (
     } // switch\r
 \r
     InterruptContollerPtr += *MadtInterruptControllerLength;\r
-    Offset += *MadtInterruptControllerLength;\r
+    Offset                += *MadtInterruptControllerLength;\r
   } // while\r
 }\r