DynamicTablesPkg: Add ACPI 6.3 SPE support to MADT generator
authorKrzysztof Koch <krzysztof.koch@arm.com>
Tue, 9 Apr 2019 13:44:37 +0000 (14:44 +0100)
committerSami Mujawar <sami.mujawar@arm.com>
Mon, 10 Jun 2019 20:24:18 +0000 (21:24 +0100)
The Dynamic Tables Framework now supports generating Multiple APIC
Description Table (MADT) revision 5 for ARM platforms while maintaining
backward-compatibility with ACPI 6.2.

The relevant change is the enablement of the Statistical Profiling
Extension (SPE).

Signed-off-by: Krzysztof Koch <krzysztof.koch@arm.com>
Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
DynamicTablesPkg/Include/ArmNameSpaceObjects.h
DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c

index bf70dc7..d9dcca1 100644 (file)
@@ -155,6 +155,13 @@ typedef struct CmArmGicCInfo {
       ACPI Specification.\r
   */\r
   UINT8   ProcessorPowerEfficiencyClass;\r
+\r
+  /** Statistical Profiling Extension buffer overflow GSIV. Zero if\r
+      unsupported by this processor. This field was introduced in\r
+      ACPI 6.3 (MADT revision 5) and is therefore ignored when\r
+      generating MADT revision 4 or lower.\r
+  */\r
+  UINT16  SpeOverflowInterrupt;\r
 } CM_ARM_GICC_INFO;\r
 \r
 /** A structure that describes the\r
index 613bf66..dc52380 100644 (file)
@@ -5,7 +5,7 @@
   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
 \r
 **/\r
 \r
@@ -82,25 +82,27 @@ GET_OBJECT_LIST (
   );\r
 \r
 /** This function updates the GIC CPU Interface Information in the\r
-    EFI_ACPI_6_2_GIC_STRUCTURE structure.\r
+    EFI_ACPI_6_3_GIC_STRUCTURE structure.\r
 \r
-  @param [in]  Gicc      Pointer to GIC CPU Interface structure.\r
-  @param [in]  GicCInfo  Pointer to the GIC CPU Interface Information.\r
+  @param [in]  Gicc       Pointer to GIC CPU Interface structure.\r
+  @param [in]  GicCInfo   Pointer to the GIC CPU Interface Information.\r
+  @param [in]  MadtRev    MADT table revision.\r
 **/\r
 STATIC\r
 VOID\r
 AddGICC (\r
-  IN  EFI_ACPI_6_2_GIC_STRUCTURE  * CONST Gicc,\r
-  IN  CONST CM_ARM_GICC_INFO      * CONST GicCInfo\r
+  IN        EFI_ACPI_6_3_GIC_STRUCTURE  * CONST Gicc,\r
+  IN  CONST CM_ARM_GICC_INFO            * CONST GicCInfo,\r
+  IN  CONST UINT8                               MadtRev\r
   )\r
 {\r
   ASSERT (Gicc != NULL);\r
   ASSERT (GicCInfo != NULL);\r
 \r
   // UINT8 Type\r
-  Gicc->Type = EFI_ACPI_6_2_GIC;\r
+  Gicc->Type = EFI_ACPI_6_3_GIC;\r
   // UINT8 Length\r
-  Gicc->Length = sizeof (EFI_ACPI_6_2_GIC_STRUCTURE);\r
+  Gicc->Length = sizeof (EFI_ACPI_6_3_GIC_STRUCTURE);\r
   // UINT16 Reserved\r
   Gicc->Reserved = EFI_ACPI_RESERVED_WORD;\r
 \r
@@ -134,10 +136,18 @@ AddGICC (
   // UINT8 ProcessorPowerEfficiencyClass\r
   Gicc->ProcessorPowerEfficiencyClass =\r
     GicCInfo->ProcessorPowerEfficiencyClass;\r
-  // UINT8 Reserved2[3]\r
-  Gicc->Reserved2[0] = EFI_ACPI_RESERVED_BYTE;\r
-  Gicc->Reserved2[1] = EFI_ACPI_RESERVED_BYTE;\r
-  Gicc->Reserved2[2] = EFI_ACPI_RESERVED_BYTE;\r
+  // UINT8 Reserved2\r
+  Gicc->Reserved2 = EFI_ACPI_RESERVED_BYTE;\r
+\r
+  // UINT16  SpeOverflowInterrupt\r
+  if (MadtRev > EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) {\r
+    Gicc->SpeOverflowInterrupt = GicCInfo->SpeOverflowInterrupt;\r
+  } else {\r
+    // Setting SpeOverflowInterrupt to 0 ensures backward compatibility with\r
+    // ACPI 6.2 by also clearing the Reserved2[1] and Reserved2[2] fields\r
+    // in EFI_ACPI_6_2_GIC_STRUCTURE.\r
+    Gicc->SpeOverflowInterrupt = 0;\r
+  }\r
 }\r
 \r
 /**\r
@@ -193,6 +203,7 @@ IsAcpiUidEqual (
   @param [in]  Gicc                 Pointer to GIC CPU Interface structure list.\r
   @param [in]  GicCInfo             Pointer to the GIC CPU Information list.\r
   @param [in]  GicCCount            Count of GIC CPU Interfaces.\r
+  @param [in]  MadtRev              MADT table revision.\r
 \r
   @retval EFI_SUCCESS               GIC CPU Interface Information was added\r
                                     successfully.\r
@@ -203,9 +214,10 @@ IsAcpiUidEqual (
 STATIC\r
 EFI_STATUS\r
 AddGICCList (\r
-  IN  EFI_ACPI_6_2_GIC_STRUCTURE  * Gicc,\r
+  IN  EFI_ACPI_6_3_GIC_STRUCTURE  * Gicc,\r
   IN  CONST CM_ARM_GICC_INFO      * GicCInfo,\r
-  IN        UINT32                  GicCCount\r
+  IN        UINT32                  GicCCount,\r
+  IN  CONST UINT8                   MadtRev\r
   )\r
 {\r
   BOOLEAN   IsAcpiProcUidDuplicated;\r
@@ -226,7 +238,7 @@ AddGICCList (
   }\r
 \r
   while (GicCCount-- != 0) {\r
-    AddGICC (Gicc++, GicCInfo++);\r
+    AddGICC (Gicc++, GicCInfo++, MadtRev);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -240,7 +252,7 @@ AddGICCList (
 STATIC\r
 VOID\r
 AddGICD (\r
-  EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE  * CONST Gicd,\r
+  EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE  * CONST Gicd,\r
   CONST CM_ARM_GICD_INFO                  * CONST GicDInfo\r
 )\r
 {\r
@@ -248,9 +260,9 @@ AddGICD (
   ASSERT (GicDInfo != NULL);\r
 \r
   // UINT8 Type\r
-  Gicd->Type = EFI_ACPI_6_2_GICD;\r
+  Gicd->Type = EFI_ACPI_6_3_GICD;\r
   // UINT8 Length\r
-  Gicd->Length = sizeof (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE);\r
+  Gicd->Length = sizeof (EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE);\r
   // UINT16 Reserved\r
   Gicd->Reserved1 = EFI_ACPI_RESERVED_WORD;\r
   // UINT32 Identifier\r
@@ -277,15 +289,15 @@ AddGICD (
 STATIC\r
 VOID\r
 AddGICMsiFrame (\r
-  IN  EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE  * CONST GicMsiFrame,\r
+  IN  EFI_ACPI_6_3_GIC_MSI_FRAME_STRUCTURE  * CONST GicMsiFrame,\r
   IN  CONST CM_ARM_GIC_MSI_FRAME_INFO       * CONST GicMsiFrameInfo\r
 )\r
 {\r
   ASSERT (GicMsiFrame != NULL);\r
   ASSERT (GicMsiFrameInfo != NULL);\r
 \r
-  GicMsiFrame->Type = EFI_ACPI_6_2_GIC_MSI_FRAME;\r
-  GicMsiFrame->Length = sizeof (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE);\r
+  GicMsiFrame->Type = EFI_ACPI_6_3_GIC_MSI_FRAME;\r
+  GicMsiFrame->Length = sizeof (EFI_ACPI_6_3_GIC_MSI_FRAME_STRUCTURE);\r
   GicMsiFrame->Reserved1 = EFI_ACPI_RESERVED_WORD;\r
   GicMsiFrame->GicMsiFrameId = GicMsiFrameInfo->GicMsiFrameId;\r
   GicMsiFrame->PhysicalBaseAddress = GicMsiFrameInfo->PhysicalBaseAddress;\r
@@ -304,7 +316,7 @@ AddGICMsiFrame (
 STATIC\r
 VOID\r
 AddGICMsiFrameInfoList (\r
-  IN  EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE  * GicMsiFrame,\r
+  IN  EFI_ACPI_6_3_GIC_MSI_FRAME_STRUCTURE  * GicMsiFrame,\r
   IN  CONST CM_ARM_GIC_MSI_FRAME_INFO       * GicMsiFrameInfo,\r
   IN        UINT32                            GicMsiFrameCount\r
 )\r
@@ -325,15 +337,15 @@ AddGICMsiFrameInfoList (
 STATIC\r
 VOID\r
 AddGICRedistributor (\r
-  IN  EFI_ACPI_6_2_GICR_STRUCTURE   * CONST Gicr,\r
+  IN  EFI_ACPI_6_3_GICR_STRUCTURE   * CONST Gicr,\r
   IN  CONST CM_ARM_GIC_REDIST_INFO  * CONST GicRedisributorInfo\r
   )\r
 {\r
   ASSERT (Gicr != NULL);\r
   ASSERT (GicRedisributorInfo != NULL);\r
 \r
-  Gicr->Type = EFI_ACPI_6_2_GICR;\r
-  Gicr->Length = sizeof (EFI_ACPI_6_2_GICR_STRUCTURE);\r
+  Gicr->Type = EFI_ACPI_6_3_GICR;\r
+  Gicr->Length = sizeof (EFI_ACPI_6_3_GICR_STRUCTURE);\r
   Gicr->Reserved = EFI_ACPI_RESERVED_WORD;\r
   Gicr->DiscoveryRangeBaseAddress =\r
     GicRedisributorInfo->DiscoveryRangeBaseAddress;\r
@@ -349,7 +361,7 @@ AddGICRedistributor (
 STATIC\r
 VOID\r
 AddGICRedistributorList (\r
-  IN  EFI_ACPI_6_2_GICR_STRUCTURE   * Gicr,\r
+  IN  EFI_ACPI_6_3_GICR_STRUCTURE   * Gicr,\r
   IN  CONST CM_ARM_GIC_REDIST_INFO  * GicRInfo,\r
   IN        UINT32                    GicRCount\r
 )\r
@@ -370,15 +382,15 @@ AddGICRedistributorList (
 STATIC\r
 VOID\r
 AddGICInterruptTranslationService (\r
-  IN  EFI_ACPI_6_2_GIC_ITS_STRUCTURE  * CONST GicIts,\r
+  IN  EFI_ACPI_6_3_GIC_ITS_STRUCTURE  * CONST GicIts,\r
   IN  CONST CM_ARM_GIC_ITS_INFO       * CONST GicItsInfo\r
 )\r
 {\r
   ASSERT (GicIts != NULL);\r
   ASSERT (GicItsInfo != NULL);\r
 \r
-  GicIts->Type = EFI_ACPI_6_2_GIC_ITS;\r
-  GicIts->Length = sizeof (EFI_ACPI_6_2_GIC_ITS_STRUCTURE);\r
+  GicIts->Type = EFI_ACPI_6_3_GIC_ITS;\r
+  GicIts->Length = sizeof (EFI_ACPI_6_3_GIC_ITS_STRUCTURE);\r
   GicIts->Reserved = EFI_ACPI_RESERVED_WORD;\r
   GicIts->GicItsId = GicItsInfo->GicItsId;\r
   GicIts->PhysicalBaseAddress = GicItsInfo->PhysicalBaseAddress;\r
@@ -395,7 +407,7 @@ AddGICInterruptTranslationService (
 STATIC\r
 VOID\r
 AddGICItsList (\r
-  IN  EFI_ACPI_6_2_GIC_ITS_STRUCTURE  * GicIts,\r
+  IN  EFI_ACPI_6_3_GIC_ITS_STRUCTURE  * GicIts,\r
   IN  CONST CM_ARM_GIC_ITS_INFO       * GicItsInfo,\r
   IN        UINT32                      GicItsCount\r
 )\r
@@ -458,7 +470,7 @@ BuildMadtTable (
   UINT32                       GicRedistOffset;\r
   UINT32                       GicItsOffset;\r
 \r
-  EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER  * Madt;\r
+  EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER  * Madt;\r
 \r
   ASSERT (This != NULL);\r
   ASSERT (AcpiTableInfo != NULL);\r
@@ -589,22 +601,22 @@ BuildMadtTable (
     goto error_handler;\r
   }\r
 \r
-  TableSize = sizeof (EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);\r
+  TableSize = sizeof (EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);\r
 \r
   GicCOffset = TableSize;\r
-  TableSize += (sizeof (EFI_ACPI_6_2_GIC_STRUCTURE) * GicCCount);\r
+  TableSize += (sizeof (EFI_ACPI_6_3_GIC_STRUCTURE) * GicCCount);\r
 \r
   GicDOffset = TableSize;\r
-  TableSize += (sizeof (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE) * GicDCount);\r
+  TableSize += (sizeof (EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE) * GicDCount);\r
 \r
   GicMSIOffset = TableSize;\r
-  TableSize += (sizeof (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE) * GicMSICount);\r
+  TableSize += (sizeof (EFI_ACPI_6_3_GIC_MSI_FRAME_STRUCTURE) * GicMSICount);\r
 \r
   GicRedistOffset = TableSize;\r
-  TableSize += (sizeof (EFI_ACPI_6_2_GICR_STRUCTURE) * GicRedistCount);\r
+  TableSize += (sizeof (EFI_ACPI_6_3_GICR_STRUCTURE) * GicRedistCount);\r
 \r
   GicItsOffset = TableSize;\r
-  TableSize += (sizeof (EFI_ACPI_6_2_GIC_ITS_STRUCTURE) * GicItsCount);\r
+  TableSize += (sizeof (EFI_ACPI_6_3_GIC_ITS_STRUCTURE) * GicItsCount);\r
 \r
   // Allocate the Buffer for MADT table\r
   *Table = (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize);\r
@@ -620,7 +632,7 @@ BuildMadtTable (
     goto error_handler;\r
   }\r
 \r
-  Madt = (EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER*)*Table;\r
+  Madt = (EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER*)*Table;\r
 \r
   DEBUG ((\r
     DEBUG_INFO,\r
@@ -646,9 +658,10 @@ BuildMadtTable (
   }\r
 \r
   Status = AddGICCList (\r
-    (EFI_ACPI_6_2_GIC_STRUCTURE*)((UINT8*)Madt + GicCOffset),\r
+    (EFI_ACPI_6_3_GIC_STRUCTURE*)((UINT8*)Madt + GicCOffset),\r
     GicCInfo,\r
-    GicCCount\r
+    GicCCount,\r
+    Madt->Header.Revision\r
     );\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((\r
@@ -660,13 +673,13 @@ BuildMadtTable (
   }\r
 \r
   AddGICD (\r
-    (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE*)((UINT8*)Madt + GicDOffset),\r
+    (EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE*)((UINT8*)Madt + GicDOffset),\r
     GicDInfo\r
     );\r
 \r
   if (GicMSICount != 0) {\r
     AddGICMsiFrameInfoList (\r
-      (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE*)((UINT8*)Madt + GicMSIOffset),\r
+      (EFI_ACPI_6_3_GIC_MSI_FRAME_STRUCTURE*)((UINT8*)Madt + GicMSIOffset),\r
       GicMSIInfo,\r
       GicMSICount\r
       );\r
@@ -674,7 +687,7 @@ BuildMadtTable (
 \r
   if (GicRedistCount != 0) {\r
     AddGICRedistributorList (\r
-      (EFI_ACPI_6_2_GICR_STRUCTURE*)((UINT8*)Madt + GicRedistOffset),\r
+      (EFI_ACPI_6_3_GICR_STRUCTURE*)((UINT8*)Madt + GicRedistOffset),\r
       GicRedistInfo,\r
       GicRedistCount\r
       );\r
@@ -682,7 +695,7 @@ BuildMadtTable (
 \r
   if (GicItsCount != 0) {\r
     AddGICItsList (\r
-      (EFI_ACPI_6_2_GIC_ITS_STRUCTURE*)((UINT8*)Madt + GicItsOffset),\r
+      (EFI_ACPI_6_3_GIC_ITS_STRUCTURE*)((UINT8*)Madt + GicItsOffset),\r
       GicItsInfo,\r
       GicItsCount\r
       );\r
@@ -749,9 +762,9 @@ ACPI_TABLE_GENERATOR MadtGenerator = {
   // Generator Description\r
   L"ACPI.STD.MADT.GENERATOR",\r
   // ACPI Table Signature\r
-  EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,\r
+  EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,\r
   // ACPI Table Revision supported by this Generator\r
-  EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,\r
+  EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,\r
   // Minimum supported ACPI Table Revision\r
   EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,\r
   // Creator ID\r