diff --git a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
index 95745db00ff3..2a42d76d4883 100644
--- a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -34,7 +34,7 @@
   Fadt.aslc
   Gtdt.aslc
   Iort.aslc
-  Madt.c
+  Madt.aslc
   Mcfg.aslc
   Pptt.aslc
   Spcr.aslc
@@ -49,6 +49,7 @@
   Silicon/AMD/Styx/AmdStyx.dec
 
 [LibraryClasses]
+  ArmLib
   BaseLib
   BaseMemoryLib
   DebugLib
@@ -92,4 +93,4 @@
   gEfiAcpiTableProtocolGuid                     ## ALWAYS_CONSUMED
 
 [Depex]
-  gEfiAcpiTableProtocolGuid
+  gEfiAcpiTableProtocolGuid AND gAmdMpCoreInfoProtocolGuid
diff --git a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatform.h b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatform.h
index b1864131795a..883dc9df36f9 100644
--- a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatform.h
+++ b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatform.h
@@ -18,7 +18,7 @@
 
 #include <IndustryStandard/Acpi.h>
 
-EFI_ACPI_DESCRIPTION_HEADER *MadtHeader (void);
+#define MAX_CORES                        8
 
 #define EFI_ACPI_AMD_OEM_ID_ARRAY        {'A','M','D','I','N','C'}
 #define EFI_ACPI_AMD_OEM_TABLE_ID        SIGNATURE_64('S','E','A','T','T','L','E',' ')
diff --git a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatform.c b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatform.c
index ff1326982329..f1223ada2444 100644
--- a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatform.c
+++ b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatform.c
@@ -19,8 +19,12 @@
    MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatform.c
 **/
 
+#include <Guid/ArmMpCoreInfo.h>
+
 #include <Protocol/AcpiTable.h>
+#include <Protocol/AmdMpCoreInfo.h>
 
+#include <Library/ArmLib.h>
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
@@ -37,6 +41,7 @@
 #include "AcpiPlatform.h"
 
 STATIC EFI_ACPI_TABLE_PROTOCOL   *mAcpiTableProtocol;
+STATIC AMD_MP_CORE_INFO_PROTOCOL *mAmdMpCoreInfoProtocol;
 
 #if DO_XGBE
 
@@ -89,20 +94,49 @@ PatchAmlPackage (
 
 #endif
 
+STATIC
+VOID
+EnableAvailableCores (
+  EFI_ACPI_5_1_GIC_STRUCTURE            *GicC
+  )
+{
+  ARM_CORE_INFO                         *ArmCoreInfoTable;
+  UINTN                                 CoreCount;
+  UINTN                                 Index;
+
+  CoreCount = 0;
+  ArmCoreInfoTable = mAmdMpCoreInfoProtocol->GetArmCoreInfoTable (&CoreCount);
+  ASSERT (ArmCoreInfoTable != NULL);
+
+  while (CoreCount--) {
+    for (Index = 0; Index < MAX_CORES; Index++) {
+      if (GicC[Index].MPIDR == GET_MPID (ArmCoreInfoTable->ClusterId,
+                                         ArmCoreInfoTable->CoreId)) {
+        GicC[Index].Flags |= EFI_ACPI_5_1_GIC_ENABLED;
+        break;
+      }
+    }
+    ArmCoreInfoTable++;
+  }
+}
+
 STATIC
 VOID
 InstallSystemDescriptionTables (
   VOID
   )
 {
-  EFI_ACPI_DESCRIPTION_HEADER                   *Table;
-  EFI_STATUS                                    Status;
-  UINT32                                        CpuId;
-  UINTN                                         Index;
-  UINTN                                         TableSize;
-  UINTN                                         TableHandle;
-  EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE  *Gtdt;
-  EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort;
+  EFI_ACPI_DESCRIPTION_HEADER                         *Table;
+  EFI_STATUS                                          Status;
+  UINT32                                              CpuId;
+  UINTN                                               Index;
+  UINTN                                               TableSize;
+  UINTN                                               TableHandle;
+  EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE        *Gtdt;
+  EFI_ACPI_6_0_IO_REMAPPING_TABLE                     *Iort;
+  EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
+  EFI_ACPI_5_1_GIC_STRUCTURE                          *GicC;
+
 #if DO_XGBE
   UINT8                         MacPackage[sizeof(mDefaultMacPackageA)];
 #endif
@@ -163,6 +197,13 @@ InstallSystemDescriptionTables (
           Gtdt->PlatformTimerOffset = 0;
         }
         break;
+
+      case EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+        Madt = (EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table;
+        GicC = (EFI_ACPI_5_1_GIC_STRUCTURE *)(Madt + 1);
+
+        EnableAvailableCores (GicC);
+        break;
       }
     }
 
@@ -198,8 +239,6 @@ AcpiPlatformEntryPoint (
   )
 {
   EFI_STATUS                  Status;
-  UINTN                       TableHandle;
-  EFI_ACPI_DESCRIPTION_HEADER *Header;
 
   //
   // Find the AcpiTable protocol
@@ -208,9 +247,8 @@ AcpiPlatformEntryPoint (
                   (VOID**)&mAcpiTableProtocol);
   ASSERT_EFI_ERROR (Status);
 
-  Header = MadtHeader ();
-  Status = mAcpiTableProtocol->InstallAcpiTable (mAcpiTableProtocol, Header,
-                                 Header->Length, &TableHandle);
+  Status = gBS->LocateProtocol (&gAmdMpCoreInfoProtocolGuid, NULL,
+                  (VOID**)&mAmdMpCoreInfoProtocol);
   ASSERT_EFI_ERROR (Status);
 
   InstallSystemDescriptionTables ();
diff --git a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/Madt.c b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/Madt.c
deleted file mode 100644
index b10ae7e1ab74..000000000000
--- a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/Madt.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/** @file
-
-  Multiple APIC Description Table (MADT)
-
-  Copyright (c) 2012 - 2014, ARM Ltd. All rights reserved.<BR>
-  Copyright (c) 2014 - 2016, AMD Inc. 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.
-
-**/
-/**
-
-  Derived from:
-   ArmPlatformPkg/ArmJunoPkg/AcpiTables/Madt.aslc
-
-**/
-
-#include <Uefi.h>
-#include <Library/ArmLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Guid/ArmMpCoreInfo.h>
-
-#include <Protocol/AmdMpCoreInfo.h>
-
-#include "AcpiPlatform.h"
-
-AMD_MP_CORE_INFO_PROTOCOL  *mAmdMpCoreInfoProtocol = NULL;
-
-
-// ARM PL390 General Interrupt Controller
-#define GIC_BASE                             (FixedPcdGet64 (PcdGicInterruptInterfaceBase))
-#define GICD_BASE                            (FixedPcdGet64 (PcdGicDistributorBase))
-#define GICV_BASE                            (FixedPcdGet64 (PcdGicVirtualInterruptInterfaceBase))
-#define GICH_BASE                            (FixedPcdGet64 (PcdGicHypervisorInterruptInterfaceBase))
-#define VGIC_MAINT_INT                       (FixedPcdGet32 (PcdGicVirtualMaintenanceInterrupt))
-#define GICVR_BASE                           (FixedPcdGet64 (PcdGicVirtualRegisterInterfaceBase))
-#define GIC_MSI_FRAME                        (FixedPcdGet64 (PcdGicMSIFrameBase))
-#define GIC_VERSION                          (FixedPcdGet8  (PcdGicVersion))
-
-#define GICD_ID                              ( 0 )
-#define GICD_VECTOR                          ( 0 )
-
-#define GICM_ID                              ( 0 )
-#define GICM_SPI_COUNT                       ( 0x100 )
-#define GICM_SPI_BASE                        ( 0x40 )
-#define GSIV_SPI_OFFSET                      ( 32 )
-
-#if STYX_A0
-  #define MSI_TYPER_FLAG                     ( 1 ) // Ignore TYPER register and use Count/Base fields
-#else
-  #define MSI_TYPER_FLAG                     ( 0 ) // Use TYPER register and ignore Count/Base fields
-#endif
-
-#define CORES_PER_CLUSTER                    (FixedPcdGet32 (PcdSocCoresPerCluster))
-
-
-/* Macro to populate EFI_ACPI_5_1_GIC_STRUCTURE */
-#define AMD_GIC(CpuNum, ClusterId, CoreId, PerfInt)  {                        \
-  EFI_ACPI_5_1_GIC,                     /* UINT8 Type */                      \
-  sizeof (EFI_ACPI_5_1_GIC_STRUCTURE),  /* UINT8 Length */                    \
-  EFI_ACPI_RESERVED_WORD,               /* UINT16 Reserved */                 \
-  CpuNum,                               /* UINT32 CPUInterfaceNumber */       \
-  (ClusterId << 8) | CoreId,            /* UINT32 AcpiProcessorUid */         \
-  EFI_ACPI_5_1_GIC_ENABLED,             /* UINT32 Flags */                    \
-  0,                                    /* UINT32 ParkingProtocolVersion */   \
-  PerfInt,                              /* UINT32 PerformanceInterruptGsiv */ \
-  0,                                    /* UINT64 ParkedAddress */            \
-  GIC_BASE,                             /* UINT64 PhysicalBaseAddress */      \
-  GICV_BASE,                            /* UINT64 GICV */                     \
-  GICH_BASE,                            /* UINT64 GICH */                     \
-  VGIC_MAINT_INT,                       /* UINT32 VGICMaintenanceInterrupt */ \
-  GICVR_BASE,                           /* UINT64 GICRBaseAddress */          \
-  (ClusterId << 8) | CoreId             /* UINT64 MPIDR */                    \
-  }
-
-/* Macro to initialise EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE */
-#define AMD_GICD(Id, Vec) {                                                             \
-  EFI_ACPI_5_1_GICD,                                /* UINT8 Type */                    \
-  sizeof (EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE),  /* UINT8 Length */                  \
-  EFI_ACPI_RESERVED_WORD,                           /* UINT16 Reserved1 */              \
-  Id,                                               /* UINT32 GicId */                  \
-  GICD_BASE,                                        /* UINT64 PhysicalBaseAddress */    \
-  Vec,                                              /* UINT32 SystemVectorBase */       \
-  EFI_ACPI_RESERVED_DWORD                           /* UINT32 Reserved2 */              \
-  }
-
-/* Macro to initialise EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE */
-#define AMD_GICM(Id, SpiCount, SpiBase) {                                               \
-   EFI_ACPI_5_1_GIC_MSI_FRAME,                      /* UINT8 Type */                    \
-   sizeof(EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE),    /* UINT8 Length */                  \
-   EFI_ACPI_RESERVED_WORD,                          /* UINT16 Reserved1 */              \
-   Id,                                              /* UINT32 GicMsiFrameId */          \
-   GIC_MSI_FRAME,                                   /* UINT64 PhysicalBaseAddress */    \
-   MSI_TYPER_FLAG,                                  /* UINT32 Flags */                  \
-   SpiCount,                                        /* UINT16 SPICount */               \
-   SpiBase                                          /* UINT16 SPIBase */                \
-   }
-
-
-//
-// NOTE: NUM_CORES is a pre-processor macro passed in with -D option
-//
-#pragma pack(push, 1)
-typedef struct {
-  EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER Header;
-  EFI_ACPI_5_1_GIC_STRUCTURE                          GicC[NUM_CORES];
-  EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE              GicD;
-  EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE                GicM;
-} EFI_ACPI_5_1_ARM_MADT_STRUCTURE;
-#pragma pack(pop)
-
-
-STATIC EFI_ACPI_5_1_ARM_MADT_STRUCTURE AcpiMadt = {
-  {
-    AMD_ACPI_HEADER (EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
-                     EFI_ACPI_5_1_ARM_MADT_STRUCTURE,
-                     EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION),
-    GIC_BASE,                                 // UINT32  LocalApicAddress
-    0                                         // UINT32  Flags
-  },
-  {
-    /*
-     * GIC Interface for Cluster 0 CPU 0
-     */
-    AMD_GIC(0, 0, 0, 39),                     // EFI_ACPI_5_1_GIC_STRUCTURE
-#if (NUM_CORES > 1)
-    /*
-     * GIC Interface for Cluster 0 CPU 1
-     */
-    AMD_GIC(1, 0, 1, 40),                     // EFI_ACPI_5_1_GIC_STRUCTURE
-#endif
-#if (NUM_CORES > 2)
-    /*
-     * GIC Interface for Cluster 1 CPU 0
-     */
-    AMD_GIC(2, 1, 0, 41),                     // EFI_ACPI_5_1_GIC_STRUCTURE
-#endif
-#if (NUM_CORES > 3)
-    /*
-     * GIC Interface for Cluster 1 CPU 1
-     */
-    AMD_GIC(3, 1, 1, 42),                     // EFI_ACPI_5_1_GIC_STRUCTURE
-#endif
-#if (NUM_CORES > 4)
-    /*
-     * GIC Interface for Cluster 2 CPU 0
-     */
-    AMD_GIC(4, 2, 0, 43),                     // EFI_ACPI_5_1_GIC_STRUCTURE
-#endif
-#if (NUM_CORES > 5)
-    /*
-     * GIC Interface for Cluster 2 CPU 1
-     */
-    AMD_GIC(5, 2, 1, 44),                     // EFI_ACPI_5_1_GIC_STRUCTURE
-#endif
-#if (NUM_CORES > 6)
-    /*
-     * GIC Interface for Cluster 3 CPU 0
-     */
-    AMD_GIC(6, 3, 0, 45),                     // EFI_ACPI_5_1_GIC_STRUCTURE
-#endif
-#if (NUM_CORES > 7)
-    /*
-     * GIC Interface for Cluster 3 CPU 1
-     */
-    AMD_GIC(7, 3, 1, 46),                     // EFI_ACPI_5_1_GIC_STRUCTURE
-#endif
-  },
-  /*
-   * GIC Distributor
-   */
-    AMD_GICD(GICD_ID, GICD_VECTOR),           // EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE
-  /*
-   * GIC MSI Frame
-   */
-  AMD_GICM(GICM_ID, GICM_SPI_COUNT, GICM_SPI_BASE),
-};
-
-
-STATIC
-EFI_STATUS
-BuildGicC (
-  EFI_ACPI_5_1_GIC_STRUCTURE *GicC,
-  UINT32 CpuNum,
-  UINT32 ClusterId,
-  UINT32 CoreId
-  )
-{
-  UINT32 MpId, PmuSpi;
-  EFI_STATUS Status;
-
-  MpId = (UINT32) GET_MPID (ClusterId, CoreId);
-  Status = mAmdMpCoreInfoProtocol->GetPmuSpiFromMpId (MpId, &PmuSpi);
-  if (EFI_ERROR (Status))
-    return Status;
-
-  GicC->Type = EFI_ACPI_5_1_GIC;
-  GicC->Length = sizeof (EFI_ACPI_5_1_GIC_STRUCTURE);
-  GicC->Reserved = EFI_ACPI_RESERVED_WORD;
-  GicC->CPUInterfaceNumber = CpuNum;
-  GicC->AcpiProcessorUid = MpId;
-  GicC->Flags = EFI_ACPI_5_1_GIC_ENABLED;
-  GicC->PhysicalBaseAddress = GIC_BASE;
-  GicC->GICV = GICV_BASE;
-  GicC->GICH = GICH_BASE;
-  GicC->VGICMaintenanceInterrupt = VGIC_MAINT_INT;
-  GicC->GICRBaseAddress = GICVR_BASE;
-  GicC->PerformanceInterruptGsiv = PmuSpi + GSIV_SPI_OFFSET;
-  GicC->MPIDR = MpId;
-
-  return EFI_SUCCESS;
-}
-
-STATIC
-VOID
-BuildGicD (
-  EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE *GicD,
-  UINT32 GicId,
-  UINT32 SystemVectorBase
-  )
-{
-  GicD->Type = EFI_ACPI_5_1_GICD;
-  GicD->Length = sizeof (EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE);
-  GicD->Reserved1 = EFI_ACPI_RESERVED_WORD;
-  GicD->GicId = GicId;
-  GicD->PhysicalBaseAddress = GICD_BASE;
-  GicD->SystemVectorBase = SystemVectorBase;
-#if 0
-  GicD->Reserved2 = EFI_ACPI_RESERVED_DWORD;
-#else
-  GicD->GicVersion = EFI_ACPI_RESERVED_BYTE;
-  GicD->Reserved2[0] = EFI_ACPI_RESERVED_BYTE;
-  GicD->Reserved2[1] = EFI_ACPI_RESERVED_BYTE;
-  GicD->Reserved2[2] = EFI_ACPI_RESERVED_BYTE;
-#endif
-}
-
-
-STATIC
-VOID
-BuildGicM (
-  EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE *GicM,
-  UINT32 MsiFrameId,
-  UINT16 SpiCount,
-  UINT16 SpiBase
-  )
-{
-  GicM->Type = EFI_ACPI_5_1_GIC_MSI_FRAME;
-  GicM->Length = sizeof(EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE);
-  GicM->Reserved1 = EFI_ACPI_RESERVED_WORD;
-  GicM->GicMsiFrameId = MsiFrameId;
-  GicM->PhysicalBaseAddress = GIC_MSI_FRAME;
-  GicM->Flags = MSI_TYPER_FLAG;
-  GicM->SPICount = SpiCount;
-  GicM->SPIBase = SpiBase;
-}
-
-
-EFI_ACPI_DESCRIPTION_HEADER *
-MadtHeader (
-  VOID
-  )
-{
-  EFI_ACPI_5_1_GIC_STRUCTURE             *GicC;
-  EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE *GicD;
-  EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE   *GicM;
-  ARM_CORE_INFO                          *ArmCoreInfoTable;
-  UINTN                                  CoreCount, CpuNum;
-  EFI_STATUS                             Status;
-
-  Status = gBS->LocateProtocol (
-               &gAmdMpCoreInfoProtocolGuid,
-               NULL,
-               (VOID **)&mAmdMpCoreInfoProtocol
-               );
-  ASSERT_EFI_ERROR (Status);
-
-  // Get pointer to ARM core info table
-  ArmCoreInfoTable = mAmdMpCoreInfoProtocol->GetArmCoreInfoTable (&CoreCount);
-  ASSERT (ArmCoreInfoTable != NULL);
-
-  // Make sure SoC's core count does not exceed what we want to build
-  ASSERT (CoreCount <= NUM_CORES);
-  ASSERT (CoreCount <= PcdGet32(PcdSocCoreCount));
-
-  GicC = (EFI_ACPI_5_1_GIC_STRUCTURE *)&AcpiMadt.GicC[0];
-  AcpiMadt.Header.Header.Length = sizeof (EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
-
-  for (CpuNum = 0; CpuNum < CoreCount; ++CpuNum, ++GicC) {
-    DEBUG ((EFI_D_ERROR, "MADT: Core[%d]: ClusterId = %d   CoreId = %d\n",
-            CpuNum, ArmCoreInfoTable[CpuNum].ClusterId, ArmCoreInfoTable[CpuNum].CoreId));
-
-    Status = BuildGicC (GicC, CpuNum,
-                ArmCoreInfoTable[CpuNum].ClusterId,
-                ArmCoreInfoTable[CpuNum].CoreId
-                );
-    ASSERT_EFI_ERROR (Status);
-
-    AcpiMadt.Header.Header.Length += sizeof (EFI_ACPI_5_1_GIC_STRUCTURE);
-  }
-
-  GicD = (EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE *)(UINT8 *)((UINTN)&AcpiMadt + (UINTN)AcpiMadt.Header.Header.Length);
-  BuildGicD (GicD, GICD_ID, GICD_VECTOR);
-  AcpiMadt.Header.Header.Length += sizeof (EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE);
-
-  GicM = (EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE *)(UINT8 *)((UINTN)&AcpiMadt + (UINTN)AcpiMadt.Header.Header.Length);
-  BuildGicM (GicM, GICM_ID, GICM_SPI_COUNT, GICM_SPI_BASE);
-  AcpiMadt.Header.Header.Length += sizeof (EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE);
-
-  return &AcpiMadt.Header.Header;
-}
-
diff --git a/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/Madt.aslc b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/Madt.aslc
new file mode 100644
index 000000000000..d4762bbbae3d
--- /dev/null
+++ b/Silicon/AMD/Styx/Drivers/AcpiPlatformDxe/Madt.aslc
@@ -0,0 +1,117 @@
+/** @file
+
+  Multiple APIC Description Table (MADT)
+
+  Copyright (c) 2012 - 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2014 - 2016, AMD Inc. All rights reserved.<BR>
+  Copyright (c) 2018, Linaro, Ltd. 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 <IndustryStandard/Acpi61.h>
+
+#include "AcpiPlatform.h"
+
+#define GICM_SPI_COUNT      (0x100)
+#define GICM_SPI_BASE       (0x40)
+
+#define GIC_BASE            (FixedPcdGet64 (PcdGicInterruptInterfaceBase))
+#define GICD_BASE           (FixedPcdGet64 (PcdGicDistributorBase))
+#define GICV_BASE           (FixedPcdGet64 (PcdGicVirtualInterruptInterfaceBase))
+#define GICH_BASE           (FixedPcdGet64 (PcdGicHypervisorInterruptInterfaceBase))
+#define VGIC_MAINT_INT      (FixedPcdGet32 (PcdGicVirtualMaintenanceInterrupt))
+#define GICVR_BASE          (FixedPcdGet64 (PcdGicVirtualRegisterInterfaceBase))
+#define GIC_MSI_FRAME       (FixedPcdGet64 (PcdGicMSIFrameBase))
+#define GIC_VERSION         (FixedPcdGet8  (PcdGicVersion))
+#define CORES_PER_CLUSTER   (FixedPcdGet32 (PcdSocCoresPerCluster))
+
+
+/* Macro to populate EFI_ACPI_5_1_GIC_STRUCTURE */
+#define AMD_GIC(CpuNum, ClusterId, CoreId, PerfInt)  {                        \
+  EFI_ACPI_5_1_GIC,                     /* UINT8 Type */                      \
+  sizeof (EFI_ACPI_5_1_GIC_STRUCTURE),  /* UINT8 Length */                    \
+  EFI_ACPI_RESERVED_WORD,               /* UINT16 Reserved */                 \
+  CpuNum,                               /* UINT32 CPUInterfaceNumber */       \
+  (ClusterId << 8) | CoreId,            /* UINT32 AcpiProcessorUid */         \
+  0,                                    /* UINT32 Flags */                    \
+  0,                                    /* UINT32 ParkingProtocolVersion */   \
+  PerfInt,                              /* UINT32 PerformanceInterruptGsiv */ \
+  0,                                    /* UINT64 ParkedAddress */            \
+  GIC_BASE,                             /* UINT64 PhysicalBaseAddress */      \
+  GICV_BASE,                            /* UINT64 GICV */                     \
+  GICH_BASE,                            /* UINT64 GICH */                     \
+  VGIC_MAINT_INT,                       /* UINT32 VGICMaintenanceInterrupt */ \
+  GICVR_BASE,                           /* UINT64 GICRBaseAddress */          \
+  (ClusterId << 8) | CoreId             /* UINT64 MPIDR */                    \
+  }
+
+
+#pragma pack(push, 1)
+typedef struct {
+  EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER Header;
+  EFI_ACPI_5_1_GIC_STRUCTURE                          GicC[MAX_CORES];
+  EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE              GicD;
+  EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE                GicM;
+} EFI_ACPI_5_1_ARM_MADT_STRUCTURE;
+#pragma pack(pop)
+
+
+STATIC EFI_ACPI_5_1_ARM_MADT_STRUCTURE AcpiMadt = {
+  {
+    AMD_ACPI_HEADER (EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+                     EFI_ACPI_5_1_ARM_MADT_STRUCTURE,
+                     EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION),
+    GIC_BASE,                                 // UINT32  LocalApicAddress
+    0                                         // UINT32  Flags
+  },
+  {
+    AMD_GIC (0, 0, 0, 39),
+    AMD_GIC (1, 0, 1, 40),
+    AMD_GIC (2, 1, 0, 41),
+    AMD_GIC (3, 1, 1, 42),
+    AMD_GIC (4, 2, 0, 43),
+    AMD_GIC (5, 2, 1, 44),
+    AMD_GIC (6, 3, 0, 45),
+    AMD_GIC (7, 3, 1, 46),
+  },
+  /*
+   * GIC Distributor
+   */
+  {
+    EFI_ACPI_5_1_GICD,                                // UINT8 Type
+    sizeof (EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE),  // UINT8 Length
+    EFI_ACPI_RESERVED_WORD,                           // UINT16 Reserved1
+    0,                                                // UINT32 GicId
+    GICD_BASE,                                        // UINT64 PhysicalBaseAddress
+    0,                                                // UINT32 SystemVectorBase
+    EFI_ACPI_RESERVED_BYTE,                           // UINT8 GicVersion
+    {                                                 // UINT8 Reserved2[3]
+      EFI_ACPI_RESERVED_BYTE,
+      EFI_ACPI_RESERVED_BYTE,
+      EFI_ACPI_RESERVED_BYTE,
+    }
+  },
+  /*
+   * GIC MSI Frame
+   */
+  {
+    EFI_ACPI_5_1_GIC_MSI_FRAME,                      // UINT8 Type
+    sizeof(EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE),    // UINT8 Length
+    EFI_ACPI_RESERVED_WORD,                          // UINT16 Reserved1
+    0,                                               // UINT32 GicMsiFrameId
+    GIC_MSI_FRAME,                                   // UINT64 PhysicalBaseAddress
+    0,                                               // UINT32 Flags
+    GICM_SPI_COUNT,                                  // UINT16 SPICount
+    GICM_SPI_BASE                                    // UINT16 SPIBase
+  }
+};
+
+VOID* CONST ReferenceAcpiTable = &AcpiMadt;
