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>
ACPI Specification.\r
*/\r
UINT8 ProcessorPowerEfficiencyClass;\r
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
} CM_ARM_GICC_INFO;\r
\r
/** A structure that describes the\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
@par Reference(s):\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
);\r
\r
/** This function updates the GIC CPU Interface Information in the\r
);\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
- @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
**/\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
)\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
- 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
// UINT16 Reserved\r
Gicc->Reserved = EFI_ACPI_RESERVED_WORD;\r
\r
// UINT8 ProcessorPowerEfficiencyClass\r
Gicc->ProcessorPowerEfficiencyClass =\r
GicCInfo->ProcessorPowerEfficiencyClass;\r
// 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
@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] 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
\r
@retval EFI_SUCCESS GIC CPU Interface Information was added\r
successfully.\r
STATIC\r
EFI_STATUS\r
AddGICCList (\r
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 CONST CM_ARM_GICC_INFO * GicCInfo,\r
+ IN UINT32 GicCCount,\r
+ IN CONST UINT8 MadtRev\r
)\r
{\r
BOOLEAN IsAcpiProcUidDuplicated;\r
)\r
{\r
BOOLEAN IsAcpiProcUidDuplicated;\r
}\r
\r
while (GicCCount-- != 0) {\r
}\r
\r
while (GicCCount-- != 0) {\r
- AddGICC (Gicc++, GicCInfo++);\r
+ AddGICC (Gicc++, GicCInfo++, MadtRev);\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
return EFI_SUCCESS;\r
STATIC\r
VOID\r
AddGICD (\r
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
CONST CM_ARM_GICD_INFO * CONST GicDInfo\r
)\r
{\r
ASSERT (GicDInfo != NULL);\r
\r
// UINT8 Type\r
ASSERT (GicDInfo != NULL);\r
\r
// UINT8 Type\r
- Gicd->Type = EFI_ACPI_6_2_GICD;\r
+ Gicd->Type = EFI_ACPI_6_3_GICD;\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
// UINT16 Reserved\r
Gicd->Reserved1 = EFI_ACPI_RESERVED_WORD;\r
// UINT32 Identifier\r
STATIC\r
VOID\r
AddGICMsiFrame (\r
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
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
GicMsiFrame->Reserved1 = EFI_ACPI_RESERVED_WORD;\r
GicMsiFrame->GicMsiFrameId = GicMsiFrameInfo->GicMsiFrameId;\r
GicMsiFrame->PhysicalBaseAddress = GicMsiFrameInfo->PhysicalBaseAddress;\r
STATIC\r
VOID\r
AddGICMsiFrameInfoList (\r
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
IN CONST CM_ARM_GIC_MSI_FRAME_INFO * GicMsiFrameInfo,\r
IN UINT32 GicMsiFrameCount\r
)\r
STATIC\r
VOID\r
AddGICRedistributor (\r
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
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
Gicr->Reserved = EFI_ACPI_RESERVED_WORD;\r
Gicr->DiscoveryRangeBaseAddress =\r
GicRedisributorInfo->DiscoveryRangeBaseAddress;\r
STATIC\r
VOID\r
AddGICRedistributorList (\r
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
IN CONST CM_ARM_GIC_REDIST_INFO * GicRInfo,\r
IN UINT32 GicRCount\r
)\r
STATIC\r
VOID\r
AddGICInterruptTranslationService (\r
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
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
GicIts->Reserved = EFI_ACPI_RESERVED_WORD;\r
GicIts->GicItsId = GicItsInfo->GicItsId;\r
GicIts->PhysicalBaseAddress = GicItsInfo->PhysicalBaseAddress;\r
STATIC\r
VOID\r
AddGICItsList (\r
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
IN CONST CM_ARM_GIC_ITS_INFO * GicItsInfo,\r
IN UINT32 GicItsCount\r
)\r
UINT32 GicRedistOffset;\r
UINT32 GicItsOffset;\r
\r
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
\r
ASSERT (This != NULL);\r
ASSERT (AcpiTableInfo != NULL);\r
goto error_handler;\r
}\r
\r
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
\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
\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
\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
\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
\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
\r
// Allocate the Buffer for MADT table\r
*Table = (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize);\r
goto error_handler;\r
}\r
\r
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
\r
DEBUG ((\r
DEBUG_INFO,\r
}\r
\r
Status = AddGICCList (\r
}\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
+ GicCCount,\r
+ Madt->Header.Revision\r
);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((\r
);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((\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
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
GicMSIInfo,\r
GicMSICount\r
);\r
\r
if (GicRedistCount != 0) {\r
AddGICRedistributorList (\r
\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
GicRedistInfo,\r
GicRedistCount\r
);\r
\r
if (GicItsCount != 0) {\r
AddGICItsList (\r
\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
GicItsInfo,\r
GicItsCount\r
);\r
// Generator Description\r
L"ACPI.STD.MADT.GENERATOR",\r
// ACPI Table Signature\r
// 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
// 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
// Minimum supported ACPI Table Revision\r
EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,\r
// Creator ID\r