2021-10-08 16:46:32 +02:00
|
|
|
/** @file
|
|
|
|
SSDT Cpu Topology Table Generator.
|
|
|
|
|
2023-09-22 16:35:13 +02:00
|
|
|
Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.<BR>
|
2021-10-08 16:46:32 +02:00
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
|
|
|
|
@par Reference(s):
|
|
|
|
- ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors
|
2023-09-22 16:35:13 +02:00
|
|
|
- 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.
|
2021-10-08 16:46:32 +02:00
|
|
|
**/
|
|
|
|
|
|
|
|
#ifndef SSDT_CPU_TOPOLOGY_GENERATOR_H_
|
|
|
|
#define SSDT_CPU_TOPOLOGY_GENERATOR_H_
|
|
|
|
|
|
|
|
#pragma pack(1)
|
|
|
|
|
|
|
|
// Mask for the flags that need to be checked.
|
|
|
|
#define PPTT_PROCESSOR_MASK ( \
|
|
|
|
(EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) | \
|
|
|
|
(EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
|
|
|
|
(EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
|
|
|
|
|
|
|
|
// Mask for the cpu flags.
|
|
|
|
#define PPTT_CPU_PROCESSOR_MASK ( \
|
|
|
|
(EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \
|
|
|
|
(EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
|
|
|
|
(EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
|
|
|
|
|
|
|
|
// Mask for the cluster flags.
|
|
|
|
// Even though a _UID is generated for clusters, it is simpler to use
|
|
|
|
// EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID and to not match the cluster id of
|
|
|
|
// the PPTT table (not sure the PPTT table is generated).
|
|
|
|
#define PPTT_CLUSTER_PROCESSOR_MASK ( \
|
|
|
|
(EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \
|
|
|
|
(EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID << 1) | \
|
|
|
|
(EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF << 3))
|
|
|
|
|
2023-03-09 16:32:49 +01:00
|
|
|
// Leaf nodes specific mask.
|
|
|
|
#define PPTT_LEAF_MASK ((EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
|
|
|
|
(EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
|
|
|
|
|
2021-10-08 16:46:32 +02:00
|
|
|
/** LPI states are stored in the ASL namespace at '\_SB_.Lxxx',
|
|
|
|
with xxx being the node index of the LPI state.
|
|
|
|
*/
|
|
|
|
#define SB_SCOPE "\\_SB_"
|
|
|
|
#define SB_SCOPE_PREFIX SB_SCOPE "."
|
|
|
|
/// Size of the SB_SCOPE_PREFIX string.
|
|
|
|
#define SB_SCOPE_PREFIX_SIZE sizeof (SB_SCOPE_PREFIX)
|
|
|
|
|
|
|
|
/// HID for a processor device.
|
|
|
|
#define ACPI_HID_PROCESSOR_DEVICE "ACPI0007"
|
|
|
|
|
2023-09-22 16:35:13 +02:00
|
|
|
/// HID for a ETM/ETE device.
|
|
|
|
#define ACPI_HID_ET_DEVICE "ARMHC500"
|
|
|
|
|
2021-10-08 16:46:32 +02:00
|
|
|
/// HID for a processor container device.
|
|
|
|
#define ACPI_HID_PROCESSOR_CONTAINER_DEVICE "ACPI0010"
|
|
|
|
|
|
|
|
/** Node names of Cpus and Clusters are 'Cxxx', and 'Lxxx' for LPI states.
|
|
|
|
The 'xxx' is an index on 12 bits is given to node name,
|
|
|
|
thus the limitation in the number of nodes.
|
|
|
|
*/
|
|
|
|
#define MAX_NODE_COUNT (1 << 12)
|
|
|
|
|
|
|
|
/** A structure used to handle the Lpi structures referencing.
|
|
|
|
|
2024-03-11 14:36:32 +01:00
|
|
|
A CM_ARCH_COMMON_PROC_HIERARCHY_INFO structure references a CM_ARCH_COMMON_OBJ_REF.
|
2024-03-11 13:59:07 +01:00
|
|
|
This CM_ARCH_COMMON_OBJ_REF references CM_ARCH_COMMON_LPI_INFO structures.
|
2021-10-08 16:46:32 +02:00
|
|
|
|
|
|
|
Example:
|
|
|
|
(Cpu0) (Cpu1)
|
2024-03-11 14:36:32 +01:00
|
|
|
CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM_ARCH_COMMON_PROC_HIERARCHY_INFO
|
2021-10-08 16:46:32 +02:00
|
|
|
| |
|
|
|
|
+----------------------------------------
|
|
|
|
|
|
|
|
|
v
|
|
|
|
(List of references to Lpi states)
|
2024-03-06 17:28:01 +01:00
|
|
|
CM_ARCH_COMMON_OBJ_REF
|
2021-10-08 16:46:32 +02:00
|
|
|
|
|
|
|
|
+----------------------------------------
|
|
|
|
| |
|
|
|
|
v v
|
|
|
|
(A first Lpi state) (A second Lpi state)
|
2024-03-11 13:59:07 +01:00
|
|
|
CM_ARCH_COMMON_LPI_INFO[0] CM_ARCH_COMMON_LPI_INFO[1]
|
2021-10-08 16:46:32 +02:00
|
|
|
|
2024-03-11 14:36:32 +01:00
|
|
|
Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARCH_COMMON_PROC_HIERARCHY_INFO
|
2024-03-06 17:28:01 +01:00
|
|
|
structures reference the same CM_ARCH_COMMON_OBJ_REF. An entry is created in the
|
2021-10-08 16:46:32 +02:00
|
|
|
TokenTable such as:
|
2024-03-06 17:28:01 +01:00
|
|
|
0 <-> CM_ARCH_COMMON_OBJ_REF
|
2021-10-08 16:46:32 +02:00
|
|
|
|
|
|
|
This will lead to the creation of this pseudo-ASL code where Cpu0 and Cpu1
|
|
|
|
return the same object at \_SB.L000:
|
|
|
|
Scope (\_SB) {
|
|
|
|
Device (C000) {
|
|
|
|
[...]
|
|
|
|
Method (_LPI) {
|
|
|
|
Return (\_SB.L000)
|
|
|
|
}
|
|
|
|
} // C000
|
|
|
|
|
|
|
|
Device (C001) {
|
|
|
|
[...]
|
|
|
|
Method (_LPI) {
|
|
|
|
Return (\_SB.L000)
|
|
|
|
}
|
|
|
|
} // C001
|
|
|
|
|
|
|
|
// Lpi states
|
|
|
|
Name (L000, Package (0x05) {
|
|
|
|
[...]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
typedef struct TokenTable {
|
|
|
|
/// TokenTable, a table allowing to map:
|
2024-03-11 13:59:07 +01:00
|
|
|
/// Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures).
|
2021-10-08 16:46:32 +02:00
|
|
|
CM_OBJECT_TOKEN *Table;
|
|
|
|
|
|
|
|
/// Last used index of the TokenTable.
|
|
|
|
/// LastIndex is bound by ProcNodeCount.
|
|
|
|
UINT32 LastIndex;
|
|
|
|
} TOKEN_TABLE;
|
|
|
|
|
|
|
|
/** A structure holding the Cpu topology generator and additional private data.
|
|
|
|
*/
|
|
|
|
typedef struct AcpiCpuTopologyGenerator {
|
|
|
|
/// ACPI Table generator header
|
2024-03-11 14:36:32 +01:00
|
|
|
ACPI_TABLE_GENERATOR Header;
|
2021-10-08 16:46:32 +02:00
|
|
|
|
|
|
|
// Private fields are defined from here.
|
|
|
|
|
|
|
|
/// Private object used to handle token referencing.
|
2024-03-11 14:36:32 +01:00
|
|
|
TOKEN_TABLE TokenTable;
|
|
|
|
/// List of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects.
|
|
|
|
CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNodeList;
|
|
|
|
/// Count of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects.
|
|
|
|
UINT32 ProcNodeCount;
|
2021-10-08 16:46:32 +02:00
|
|
|
} ACPI_CPU_TOPOLOGY_GENERATOR;
|
|
|
|
|
|
|
|
#pragma pack()
|
|
|
|
|
2024-06-10 14:00:00 +02:00
|
|
|
/** 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
|
|
|
|
);
|
|
|
|
|
2021-10-08 16:46:32 +02:00
|
|
|
#endif // SSDT_CPU_TOPOLOGY_GENERATOR_H_
|