summaryrefslogtreecommitdiffstats
path: root/DynamicTablesPkg
diff options
context:
space:
mode:
authorPierre Gondois <pierre.gondois@arm.com>2024-06-10 14:00:00 +0200
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-07-29 13:44:55 +0000
commitdfd867bd8381d1bc6ee4ea9e6f5ea65116e4b452 (patch)
tree4f19b094867ee355269e3197191780008e5d9e7c /DynamicTablesPkg
parentc6e0eed07264fb5bd92198cf5c9b1c95715a1962 (diff)
downloadedk2-dfd867bd8381d1bc6ee4ea9e6f5ea65116e4b452.tar.gz
edk2-dfd867bd8381d1bc6ee4ea9e6f5ea65116e4b452.tar.bz2
edk2-dfd867bd8381d1bc6ee4ea9e6f5ea65116e4b452.zip
DynamicTablesPkg: AcpiSsdtCpuTopologyLib: Avoid dependency on GICC
The GICC is an ARM specific structure. Other architectures have different local interrupt controller structures from which CPU topology can be created. Avoid the GICC reference in common code by: - creating a wrapper CreateTopologyFromIntC() instead of CreateTopologyFromGicC() so that different archs can implement it differently. - implementing arch specific functions to get the AcpiProcessorUid, CpcToken, EtToken and use them instead of using the GicC CM object directly. Suggested-by: Sunil V L <sunilvl@ventanamicro.com> Signed-off-by: Pierre Gondois <pierre.gondois@arm.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
Diffstat (limited to 'DynamicTablesPkg')
-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