summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c408
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c341
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h196
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf3
4 files changed, 647 insertions, 301 deletions
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c
new file mode 100644
index 0000000000..140a2e4911
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c
@@ -0,0 +1,408 @@
+/** @file
+ ARM SSDT Cpu Topology Table Generator Helpers.
+
+ Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors
+ - ACPI for CoreSight version 1.2 Platform Design Document
+ (https://developer.arm.com/documentation/den0067/a/?lang=en)
+
+ @par Glossary:
+ - ETE - Embedded Trace Extension.
+ - ETM - Embedded Trace Macrocell.
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/TableHelperLib.h>
+#include <Library/AmlLib/AmlLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "SsdtCpuTopologyGenerator.h"
+
+/** ARM SSDT Cpu Topology Table Generator.
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjGicCInfo
+ - EArmObjEtInfo (OPTIONAL)
+*/
+
+/** This macro expands to a function that retrieves the GIC
+ CPU interface Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicCInfo,
+ CM_ARM_GICC_INFO
+ );
+
+/**
+ This macro expands to a function that retrieves the ET device
+ information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjEtInfo,
+ CM_ARM_ET_INFO
+ );
+
+/** Create an embedded trace device and add it to the Cpu Node in the
+ AML namespace.
+
+ This generates the following ASL code:
+ Device (E002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ARMHC500")
+ }
+
+ Note: Currently we only support generating ETE nodes. Unlike ETM,
+ ETE has a system register interface and therefore does not need
+ the MMIO range to be described.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] ParentNode Parent node to attach the Cpu node to.
+ @param [in] AcpiProcessorUid ACPI Processor UID of the CPU.
+ @param [in] CpuName Value used to generate the node name.
+ @param [out] EtNodePtr If not NULL, return the created Cpu node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateAmlEtd (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN AML_NODE_HANDLE ParentNode,
+ IN UINT32 AcpiProcessorUid,
+ IN UINT32 CpuName,
+ OUT AML_OBJECT_NODE_HANDLE *EtNodePtr OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE EtNode;
+ CHAR8 AslName[AML_NAME_SEG_SIZE + 1];
+
+ ASSERT (Generator != NULL);
+ ASSERT (ParentNode != NULL);
+
+ Status = WriteAslName ('E', CpuName, AslName);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCodeGenDevice (AslName, ParentNode, &EtNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCodeGenNameInteger (
+ "_UID",
+ AcpiProcessorUid,
+ EtNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCodeGenNameString (
+ "_HID",
+ ACPI_HID_ET_DEVICE,
+ EtNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // If requested, return the handle to the EtNode.
+ if (EtNodePtr != NULL) {
+ *EtNodePtr = EtNode;
+ }
+
+ return Status;
+}
+
+/** Create and add an Embedded trace device to the Cpu Node.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiProcessorUid ACPI processor Uid of the local intc (gicc, other)
+ describing the Cpu.
+ @param [in] EtToken Embedded Trace Token of the CPU.
+ @param [in] CpuName Value used to generate the CPU node name.
+ @param [in] CpuNode CPU Node to which the ET device node is
+ attached.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_UNSUPPORTED Feature Unsupported.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateAmlEtNode (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN UINT32 AcpiProcessorUid,
+ IN CM_OBJECT_TOKEN EtToken,
+ IN UINT32 CpuName,
+ IN AML_OBJECT_NODE_HANDLE *CpuNode
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_ET_INFO *EtInfo;
+
+ Status = GetEArmObjEtInfo (
+ CfgMgrProtocol,
+ EtToken,
+ &EtInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Currently we only support creation of a ETE Node.
+ if (EtInfo->EtType != ArmEtTypeEte) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = CreateAmlEtd (
+ Generator,
+ CpuNode,
+ AcpiProcessorUid,
+ CpuName,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Create the processor hierarchy AML tree from arch specific CM objects.
+
+ The Arm architecture will use the CM_ARM_GICC_INFO CM objects for instance.
+ A processor container is by extension any non-leave device in the cpu topology.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] ScopeNode Scope node handle ('\_SB' scope).
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+CreateTopologyFromIntC (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN AML_OBJECT_NODE_HANDLE ScopeNode
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_GICC_INFO *GicCInfo;
+ UINT32 GicCInfoCount;
+ UINT32 Index;
+ AML_OBJECT_NODE_HANDLE CpuNode;
+
+ ASSERT (Generator != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (ScopeNode != NULL);
+
+ Status = GetEArmObjGicCInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &GicCInfo,
+ &GicCInfoCount
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // For each CM_ARM_GICC_INFO object, create an AML node.
+ for (Index = 0; Index < GicCInfoCount; Index++) {
+ Status = CreateAmlCpu (
+ Generator,
+ ScopeNode,
+ GicCInfo[Index].AcpiProcessorUid,
+ Index,
+ &CpuNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ break;
+ }
+
+ // If a CPC info is associated with the
+ // GicCinfo, create an _CPC method returning them.
+ if (GicCInfo[Index].CpcToken != CM_NULL_TOKEN) {
+ Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo[Index].CpcToken, CpuNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ break;
+ }
+ }
+
+ if (GicCInfo[Index].EtToken != CM_NULL_TOKEN) {
+ Status = CreateAmlEtNode (
+ Generator,
+ CfgMgrProtocol,
+ GicCInfo[Index].AcpiProcessorUid,
+ GicCInfo[Index].EtToken,
+ Index,
+ CpuNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+ } // for
+
+ return Status;
+}
+
+/** Get generic interrupt information from arch specific CM objects.
+
+ The AcpiProcessorUid, CpcToken, etc. are held in arch specific CM objects,
+ in the CM_ARM_GICC_INFO CM object for Arm for instance.
+ This wrapper allows to get this information from each arch object.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the
+ other fields from.
+ @param [out] AcpiProcessorUid AcpiProcessorUid of the CPU identified by
+ the AcpiIdObjectToken.
+ @param [out] CpcToken CpcToken of the CPU identified by
+ the AcpiIdObjectToken.
+ @param [out] PsdToken PsdToken of the CPU identified by
+ the AcpiIdObjectToken.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+**/
+EFI_STATUS
+EFIAPI
+GetIntCInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN AcpiIdObjectToken,
+ OUT UINT32 *AcpiProcessorUid,
+ OUT CM_OBJECT_TOKEN *CpcToken,
+ OUT CM_OBJECT_TOKEN *PsdToken
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_GICC_INFO *GicCInfo;
+
+ Status = GetEArmObjGicCInfo (
+ CfgMgrProtocol,
+ AcpiIdObjectToken,
+ &GicCInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (AcpiProcessorUid != NULL) {
+ *AcpiProcessorUid = GicCInfo->AcpiProcessorUid;
+ }
+
+ if (CpcToken != NULL) {
+ *CpcToken = GicCInfo->CpcToken;
+ }
+
+ if (PsdToken != NULL) {
+ *PsdToken = GicCInfo->PsdToken;
+ }
+
+ return Status;
+}
+
+/** Add arch specific information to a CPU node in the asl description.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the
+ other fields from.
+ @param [in] CpuName Value used to generate the CPU node name.
+ @param [out] CpuNode CPU Node to which the ET device node is
+ attached.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Feature Unsupported.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AddArchAmlCpuInfo (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN AcpiIdObjectToken,
+ IN UINT32 CpuName,
+ OUT AML_OBJECT_NODE_HANDLE *CpuNode
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_GICC_INFO *GicCInfo;
+
+ Status = GetEArmObjGicCInfo (
+ CfgMgrProtocol,
+ AcpiIdObjectToken,
+ &GicCInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Add an Embedded Trace node if present.
+ if (GicCInfo->EtToken != CM_NULL_TOKEN) {
+ Status = CreateAmlEtNode (
+ Generator,
+ CfgMgrProtocol,
+ GicCInfo->AcpiProcessorUid,
+ GicCInfo->EtToken,
+ CpuName,
+ CpuNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c
index 2deaa4640c..7459513193 100644
--- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c
@@ -32,28 +32,17 @@
#include "SsdtCpuTopologyGenerator.h"
-/** ARM standard SSDT Cpu Topology Table Generator.
+/** SSDT Cpu Topology Table Generator.
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjGicCInfo
- EArchCommonObjProcHierarchyInfo (OPTIONAL) along with
- EArchCommonObjCmRef (OPTIONAL)
- EArchCommonObjLpiInfo (OPTIONAL)
- - GetEArmObjEtInfo (OPTIONAL)
- EArchCommonObjPsdInfo (OPTIONAL)
*/
-/** This macro expands to a function that retrieves the GIC
- CPU interface Information from the Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjGicCInfo,
- CM_ARM_GICC_INFO
- );
-
/**
This macro expands to a function that retrieves the Processor Hierarchy
information from the Configuration Manager.
@@ -95,16 +84,6 @@ GET_OBJECT_LIST (
);
/**
- This macro expands to a function that retrieves the ET device
- information from the Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjEtInfo,
- CM_ARM_ET_INFO
- );
-
-/**
This macro expands to a function that retrieves the PSD
information from the Configuration Manager.
*/
@@ -238,7 +217,6 @@ TokenTableAdd (
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER Invalid parameter.
**/
-STATIC
EFI_STATUS
EFIAPI
WriteAslName (
@@ -294,8 +272,7 @@ WriteAslName (
@param [in] Generator The SSDT Cpu Topology generator.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
Protocol Interface.
- @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object
- describing the Cpu.
+ @param [in] PsdToken Token to identify the Psd information.
@param [in] Node CPU Node to which the _CPC node is
attached.
@@ -309,7 +286,7 @@ EFIAPI
CreateAmlPsdNode (
IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CM_ARM_GICC_INFO *GicCInfo,
+ IN CM_OBJECT_TOKEN PsdToken,
IN AML_OBJECT_NODE_HANDLE *Node
)
{
@@ -318,7 +295,7 @@ CreateAmlPsdNode (
Status = GetEArchCommonObjPsdInfo (
CfgMgrProtocol,
- GicCInfo->PsdToken,
+ PsdToken,
&PsdInfo,
NULL
);
@@ -381,7 +358,7 @@ CreateAmlPsdNode (
@param [in] Generator The SSDT Cpu Topology generator.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
Protocol Interface.
- @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object
+ @param [in] CpcToken CPC token of the INTC info
describing the Cpu.
@param [in] Node CPU Node to which the _CPC node is
attached.
@@ -390,13 +367,12 @@ CreateAmlPsdNode (
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
**/
-STATIC
EFI_STATUS
EFIAPI
CreateAmlCpcNode (
IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CM_ARM_GICC_INFO *GicCInfo,
+ IN CM_OBJECT_TOKEN CpcToken,
IN AML_OBJECT_NODE_HANDLE *Node
)
{
@@ -405,7 +381,7 @@ CreateAmlCpcNode (
Status = GetEArchCommonObjCpcInfo (
CfgMgrProtocol,
- GicCInfo->CpcToken,
+ CpcToken,
&CpcInfo,
NULL
);
@@ -423,147 +399,6 @@ CreateAmlCpcNode (
return Status;
}
-/** Create an embedded trace device and add it to the Cpu Node in the
- AML namespace.
-
- This generates the following ASL code:
- Device (E002)
- {
- Name (_UID, 2)
- Name (_HID, "ARMHC500")
- }
-
- Note: Currently we only support generating ETE nodes. Unlike ETM,
- ETE has a system register interface and therefore does not need
- the MMIO range to be described.
-
- @param [in] Generator The SSDT Cpu Topology generator.
- @param [in] ParentNode Parent node to attach the Cpu node to.
- @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node.
- @param [in] CpuName Value used to generate the node name.
- @param [out] EtNodePtr If not NULL, return the created Cpu node.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CreateAmlEtd (
- IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
- IN AML_NODE_HANDLE ParentNode,
- IN CM_ARM_GICC_INFO *GicCInfo,
- IN UINT32 CpuName,
- OUT AML_OBJECT_NODE_HANDLE *EtNodePtr OPTIONAL
- )
-{
- EFI_STATUS Status;
- AML_OBJECT_NODE_HANDLE EtNode;
- CHAR8 AslName[AML_NAME_SEG_SIZE + 1];
-
- ASSERT (Generator != NULL);
- ASSERT (ParentNode != NULL);
-
- Status = WriteAslName ('E', CpuName, AslName);
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- Status = AmlCodeGenDevice (AslName, ParentNode, &EtNode);
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- Status = AmlCodeGenNameInteger (
- "_UID",
- GicCInfo->AcpiProcessorUid,
- EtNode,
- NULL
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- Status = AmlCodeGenNameString (
- "_HID",
- ACPI_HID_ET_DEVICE,
- EtNode,
- NULL
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- // If requested, return the handle to the EtNode.
- if (EtNodePtr != NULL) {
- *EtNodePtr = EtNode;
- }
-
- return Status;
-}
-
-/** Create and add an Embedded trace device to the Cpu Node.
-
- @param [in] Generator The SSDT Cpu Topology generator.
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object
- describing the Cpu.
- @param [in] CpuName Value used to generate the CPU node name.
- @param [in] Node CPU Node to which the ET device node is
- attached.
-
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_UNSUPPORTED Feature Unsupported.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CreateAmlEtNode (
- IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CM_ARM_GICC_INFO *GicCInfo,
- IN UINT32 CpuName,
- IN AML_OBJECT_NODE_HANDLE *Node
- )
-{
- EFI_STATUS Status;
- CM_ARM_ET_INFO *EtInfo;
-
- Status = GetEArmObjEtInfo (
- CfgMgrProtocol,
- GicCInfo->EtToken,
- &EtInfo,
- NULL
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- // Currently we only support creation of a ETE Node.
- if (EtInfo->EtType != ArmEtTypeEte) {
- return EFI_UNSUPPORTED;
- }
-
- Status = CreateAmlEtd (
- Generator,
- Node,
- GicCInfo,
- CpuName,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
-}
-
/** Create and add an _LPI method to Cpu/Cluster Node.
For instance, transform an AML node from:
@@ -789,23 +624,22 @@ GenerateLpiStates (
Name (_HID, "ACPI0007")
}
- @param [in] Generator The SSDT Cpu Topology generator.
- @param [in] ParentNode Parent node to attach the Cpu node to.
- @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node.
- @param [in] CpuName Value used to generate the node name.
- @param [out] CpuNodePtr If not NULL, return the created Cpu node.
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] ParentNode Parent node to attach the Cpu node to.
+ @param [in] AcpiProcessorUid ACPI processor UID of the CPU.
+ @param [in] CpuName Value used to generate the node name.
+ @param [out] CpuNodePtr If not NULL, return the created Cpu node.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
**/
-STATIC
EFI_STATUS
EFIAPI
CreateAmlCpu (
IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
IN AML_NODE_HANDLE ParentNode,
- IN CM_ARM_GICC_INFO *GicCInfo,
+ IN UINT32 AcpiProcessorUid,
IN UINT32 CpuName,
OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL
)
@@ -816,7 +650,6 @@ CreateAmlCpu (
ASSERT (Generator != NULL);
ASSERT (ParentNode != NULL);
- ASSERT (GicCInfo != NULL);
Status = WriteAslName ('C', CpuName, AslName);
if (EFI_ERROR (Status)) {
@@ -832,7 +665,7 @@ CreateAmlCpu (
Status = AmlCodeGenNameInteger (
"_UID",
- GicCInfo->AcpiProcessorUid,
+ AcpiProcessorUid,
CpuNode,
NULL
);
@@ -887,8 +720,10 @@ CreateAmlCpuFromProcHierarchy (
)
{
EFI_STATUS Status;
- CM_ARM_GICC_INFO *GicCInfo;
AML_OBJECT_NODE_HANDLE CpuNode;
+ UINT32 AcpiProcessorUid;
+ CM_OBJECT_TOKEN CpcToken;
+ CM_OBJECT_TOKEN PsdToken;
ASSERT (Generator != NULL);
ASSERT (CfgMgrProtocol != NULL);
@@ -896,18 +731,19 @@ CreateAmlCpuFromProcHierarchy (
ASSERT (ProcHierarchyNodeInfo != NULL);
ASSERT (ProcHierarchyNodeInfo->AcpiIdObjectToken != CM_NULL_TOKEN);
- Status = GetEArmObjGicCInfo (
+ Status = GetIntCInfo (
CfgMgrProtocol,
ProcHierarchyNodeInfo->AcpiIdObjectToken,
- &GicCInfo,
- NULL
+ &AcpiProcessorUid,
+ &CpcToken,
+ &PsdToken
);
if (EFI_ERROR (Status)) {
ASSERT (0);
return Status;
}
- Status = CreateAmlCpu (Generator, ParentNode, GicCInfo, CpuName, &CpuNode);
+ Status = CreateAmlCpu (Generator, ParentNode, AcpiProcessorUid, CpuName, &CpuNode);
if (EFI_ERROR (Status)) {
ASSERT (0);
return Status;
@@ -923,8 +759,8 @@ CreateAmlCpuFromProcHierarchy (
}
}
- if (GicCInfo->PsdToken != CM_NULL_TOKEN) {
- Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode);
+ if (PsdToken != CM_NULL_TOKEN) {
+ Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, PsdToken, CpuNode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
@@ -932,28 +768,26 @@ CreateAmlCpuFromProcHierarchy (
}
// If a CPC info is associated with the
- // GicCinfo, create an _CPC method returning them.
- if (GicCInfo->CpcToken != CM_NULL_TOKEN) {
- Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode);
+ // IntcInfo, create an _CPC method returning them.
+ if (CpcToken != CM_NULL_TOKEN) {
+ Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, CpcToken, CpuNode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
}
- // Add an Embedded Trace node if present.
- if (GicCInfo->EtToken != CM_NULL_TOKEN) {
- Status = CreateAmlEtNode (
- Generator,
- CfgMgrProtocol,
- GicCInfo,
- CpuName,
- CpuNode
- );
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
+ // Add arch specific information if necessary.
+ Status = AddArchAmlCpuInfo (
+ Generator,
+ CfgMgrProtocol,
+ ProcHierarchyNodeInfo->AcpiIdObjectToken,
+ CpuName,
+ CpuNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
}
return Status;
@@ -1342,100 +1176,6 @@ exit_handler:
return Status;
}
-/** Create the processor hierarchy AML tree from CM_ARM_GICC_INFO
- CM objects.
-
- A processor container is by extension any non-leave device in the cpu topology.
-
- @param [in] Generator The SSDT Cpu Topology generator.
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] ScopeNode Scope node handle ('\_SB' scope).
-
- @retval EFI_SUCCESS Success.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CreateTopologyFromGicC (
- IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN AML_OBJECT_NODE_HANDLE ScopeNode
- )
-{
- EFI_STATUS Status;
- CM_ARM_GICC_INFO *GicCInfo;
- UINT32 GicCInfoCount;
- UINT32 Index;
- AML_OBJECT_NODE_HANDLE CpuNode;
-
- ASSERT (Generator != NULL);
- ASSERT (CfgMgrProtocol != NULL);
- ASSERT (ScopeNode != NULL);
-
- Status = GetEArmObjGicCInfo (
- CfgMgrProtocol,
- CM_NULL_TOKEN,
- &GicCInfo,
- &GicCInfoCount
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- // For each CM_ARM_GICC_INFO object, create an AML node.
- for (Index = 0; Index < GicCInfoCount; Index++) {
- Status = CreateAmlCpu (
- Generator,
- ScopeNode,
- &GicCInfo[Index],
- Index,
- &CpuNode
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- break;
- }
-
- if (GicCInfo->PsdToken != CM_NULL_TOKEN) {
- Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- }
-
- // If a CPC info is associated with the
- // GicCinfo, create an _CPC method returning them.
- if (GicCInfo[Index].CpcToken != CM_NULL_TOKEN) {
- Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, &GicCInfo[Index], CpuNode);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- break;
- }
- }
-
- if (GicCInfo[Index].EtToken != CM_NULL_TOKEN) {
- Status = CreateAmlEtNode (
- Generator,
- CfgMgrProtocol,
- &GicCInfo[Index],
- Index,
- CpuNode
- );
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- }
- } // for
-
- return Status;
-}
-
/** Construct the SSDT Cpu Topology ACPI table.
This function invokes the Configuration Manager protocol interface
@@ -1514,9 +1254,8 @@ BuildSsdtCpuTopologyTable (
}
if (Status == EFI_NOT_FOUND) {
- // If hierarchy information is not found generate a flat topology
- // using CM_ARM_GICC_INFO objects.
- Status = CreateTopologyFromGicC (
+ // If hierarchy information is not found generate a flat topology.
+ Status = CreateTopologyFromIntC (
Generator,
CfgMgrProtocol,
ScopeNode
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h
index 6fb44c7e58..a5d80177f2 100644
--- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h
@@ -144,4 +144,200 @@ typedef struct AcpiCpuTopologyGenerator {
#pragma pack()
+/** Write a string 'Xxxx\0' in AslName (5 bytes long),
+ with 'X' being the leading char of the name, and
+ with 'xxx' being Value in hexadecimal.
+
+ As 'xxx' in hexadecimal represents a number on 12 bits,
+ we have Value < (1 << 12).
+
+ @param [in] LeadChar Leading char of the name.
+ @param [in] Value Hex value of the name.
+ Must be lower than (2 << 12).
+ @param [in, out] AslName Pointer to write the 'Xxxx' string to.
+ Must be at least 5 bytes long.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+WriteAslName (
+ IN CHAR8 LeadChar,
+ IN UINT32 Value,
+ IN OUT CHAR8 *AslName
+ );
+
+/** Get generic interrupt information from arch specific CM objects.
+
+ The AcpiProcessorUid, CpcToken, etc. are held in arch specific CM objects,
+ in the CM_ARM_GICC_INFO CM object for Arm for instance.
+ This wrapper allows to get this information from each arch object.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiProcessorUid ACPI processor Uid of the local intc (gicc, other)
+ other fields from.
+ @param [out] AcpiProcessorUid AcpiProcessorUid of the CPU identified by
+ the AcpiIdObjectToken.
+ @param [out] CpcToken CpcToken of the CPU identified by
+ the AcpiIdObjectToken.
+ @param [out] PsdToken PsdToken of the CPU identified by
+ the AcpiIdObjectToken.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+**/
+EFI_STATUS
+EFIAPI
+GetIntCInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN AcpiIdObjectToken,
+ OUT UINT32 *AcpiProcessorUid,
+ OUT CM_OBJECT_TOKEN *CpcToken,
+ OUT CM_OBJECT_TOKEN *PsdToken
+ );
+
+/** Create and add an _CPC Node to Cpu Node.
+
+ For instance, transform an AML node from:
+ Device (C002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ACPI0007")
+ }
+
+ To:
+ Device (C002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ACPI0007")
+ Name(_CPC, Package()
+ {
+ NumEntries, // Integer
+ Revision, // Integer
+ HighestPerformance, // Integer or Buffer (Resource Descriptor)
+ NominalPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestNonlinearPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestPerformance, // Integer or Buffer (Resource Descriptor)
+ GuaranteedPerformanceRegister, // Buffer (Resource Descriptor)
+ DesiredPerformanceRegister , // Buffer (Resource Descriptor)
+ MinimumPerformanceRegister , // Buffer (Resource Descriptor)
+ MaximumPerformanceRegister , // Buffer (Resource Descriptor)
+ PerformanceReductionToleranceRegister, // Buffer (Resource Descriptor)
+ TimeWindowRegister, // Buffer (Resource Descriptor)
+ CounterWraparoundTime, // Integer or Buffer (Resource Descriptor)
+ ReferencePerformanceCounterRegister, // Buffer (Resource Descriptor)
+ DeliveredPerformanceCounterRegister, // Buffer (Resource Descriptor)
+ PerformanceLimitedRegister, // Buffer (Resource Descriptor)
+ CPPCEnableRegister // Buffer (Resource Descriptor)
+ AutonomousSelectionEnable, // Integer or Buffer (Resource Descriptor)
+ AutonomousActivityWindowRegister, // Buffer (Resource Descriptor)
+ EnergyPerformancePreferenceRegister, // Buffer (Resource Descriptor)
+ ReferencePerformance // Integer or Buffer (Resource Descriptor)
+ LowestFrequency, // Integer or Buffer (Resource Descriptor)
+ NominalFrequency // Integer or Buffer (Resource Descriptor)
+ })
+ }
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] CpcToken CPC token of the INTC info
+ describing the Cpu.
+ @param [in] Node CPU Node to which the _CPC node is
+ attached.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+CreateAmlCpcNode (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN CpcToken,
+ IN AML_OBJECT_NODE_HANDLE *Node
+ );
+
+/** Create a Cpu in the AML namespace.
+
+ This generates the following ASL code:
+ Device (C002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ACPI0007")
+ }
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] ParentNode Parent node to attach the Cpu node to.
+ @param [in] AcpiProcessorUid ACPI processor UID of the CPU.
+ @param [in] CpuName Value used to generate the node name.
+ @param [out] CpuNodePtr If not NULL, return the created Cpu node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+CreateAmlCpu (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN AML_NODE_HANDLE ParentNode,
+ IN UINT32 AcpiProcessorUid,
+ IN UINT32 CpuName,
+ OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL
+ );
+
+/** Create the processor hierarchy AML tree from arch specific CM objects.
+
+ The Arm architecture will use the CM_ARM_GICC_INFO CM objects for instance.
+ A processor container is by extension any non-leave device in the cpu topology.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] ScopeNode Scope node handle ('\_SB' scope).
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+CreateTopologyFromIntC (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN AML_OBJECT_NODE_HANDLE ScopeNode
+ );
+
+/** Add arch specific information to a CPU node in the asl description.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the
+ other fields from.
+ @param [in] CpuName Value used to generate the CPU node name.
+ @param [out] CpuNode CPU Node to which the ET device node is
+ attached.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Feature Unsupported.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AddArchAmlCpuInfo (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN AcpiIdObjectToken,
+ IN UINT32 CpuName,
+ OUT AML_OBJECT_NODE_HANDLE *CpuNode
+ );
+
#endif // SSDT_CPU_TOPOLOGY_GENERATOR_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf
index 2d38fb30fb..93ede691cd 100644
--- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf
@@ -20,6 +20,9 @@
SsdtCpuTopologyGenerator.c
SsdtCpuTopologyGenerator.h
+[Sources.ARM, Sources.AARCH64]
+ Arm/ArmSsdtCpuTopologyGenerator.c
+
[Packages.ARM, Packages.AARCH64]
ArmPlatformPkg/ArmPlatformPkg.dec