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 <suni...@ventanamicro.com> Signed-off-by: Pierre Gondois <pierre.gond...@arm.com> --- .../Arm/ArmSsdtCpuTopologyGenerator.c | 408 ++++++++++++++++++ .../SsdtCpuTopologyGenerator.c | 341 ++------------- .../SsdtCpuTopologyGenerator.h | 196 +++++++++ .../SsdtCpuTopologyLib.inf | 3 + 4 files changed, 647 insertions(+), 301 deletions(-) create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c 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 000000000000..140a2e491116 --- /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 2deaa4640c5c..74595131935c 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. @@ -94,16 +83,6 @@ GET_OBJECT_LIST ( CM_ARCH_COMMON_CPC_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 - ); - /** 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 6fb44c7e5887..a5d80177f2fc 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 2d38fb30fb09..93ede691cdf9 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf @@ -20,6 +20,9 @@ [Sources] SsdtCpuTopologyGenerator.c SsdtCpuTopologyGenerator.h +[Sources.ARM, Sources.AARCH64] + Arm/ArmSsdtCpuTopologyGenerator.c + [Packages.ARM, Packages.AARCH64] ArmPlatformPkg/ArmPlatformPkg.dec -- 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#119639): https://edk2.groups.io/g/devel/message/119639 Mute This Topic: https://groups.io/mt/106770160/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-