* [PATCH v2 0/3] DynamicTablesPkg: _CPC support
@ 2022-09-14 21:34 Jeff Brasen
2022-09-14 21:34 ` [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Jeff Brasen @ 2022-09-14 21:34 UTC (permalink / raw)
To: devel
Cc: ardb+tianocore, Sami.Mujawar, Alexei.Fedorov, pierre.gondois,
Jeff Brasen
Add generator for creating the _CPC object for CPU nodes.
If viewing this review by a pull request is helpful one exists here:
https://github.com/NVIDIA/edk2/pull/12
Change Log:
v1 - Initial Revision
v2 - Added revision to object, improved error handling, changed to ACPI 6.4 structures.
Jeff Brasen (3):
DynamicTablesPkg: Add CM_ARM_CPC_INFO object
DynamicTablesPkg: AML Code generation to add _CPC entries
DynamicTablesPkg: SSDT CPU _CPC generator
.../Include/ArmNameSpaceObjects.h | 148 ++++-
.../Include/Library/AmlLib/AmlLib.h | 156 +++++
.../SsdtCpuTopologyGenerator.c | 223 ++++++-
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 543 ++++++++++++++++++
.../ConfigurationManagerObjectParser.c | 79 +++
5 files changed, 1126 insertions(+), 23 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object
2022-09-14 21:34 [PATCH v2 0/3] DynamicTablesPkg: _CPC support Jeff Brasen
@ 2022-09-14 21:34 ` Jeff Brasen
2022-09-15 8:02 ` PierreGondois
2022-09-15 14:00 ` Sami Mujawar
2022-09-14 21:34 ` [PATCH v2 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries Jeff Brasen
2022-09-14 21:34 ` [PATCH v2 3/3] DynamicTablesPkg: SSDT CPU _CPC generator Jeff Brasen
2 siblings, 2 replies; 8+ messages in thread
From: Jeff Brasen @ 2022-09-14 21:34 UTC (permalink / raw)
To: devel
Cc: ardb+tianocore, Sami.Mujawar, Alexei.Fedorov, pierre.gondois,
Jeff Brasen
Introduce the CM_ARM_CPC_INFO CmObj in the ArmNameSpaceObjects.
This allows to describe CPC information, as described in ACPI 6.4,
s8.4.7.1 "_CPC (Continuous Performance Control)".
Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
---
.../Include/ArmNameSpaceObjects.h | 148 ++++++++++++++++--
.../ConfigurationManagerObjectParser.c | 79 ++++++++++
2 files changed, 210 insertions(+), 17 deletions(-)
diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 102e0f96be..d76cc08e14 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -63,6 +63,7 @@ typedef enum ArmObjectID {
EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info
EArmObjRmr, ///< 40 - Reserved Memory Range Node
EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor
+ EArmObjCpcInfo, ///< 42 - Continuous Performance Control Info
EArmObjMax
} EARM_OBJECT_ID;
@@ -97,99 +98,105 @@ typedef struct CmArmPowerManagementProfileInfo {
*/
typedef struct CmArmGicCInfo {
/// The GIC CPU Interface number.
- UINT32 CPUInterfaceNumber;
+ UINT32 CPUInterfaceNumber;
/** The ACPI Processor UID. This must match the
_UID of the CPU Device object information described
in the DSDT/SSDT for the CPU.
*/
- UINT32 AcpiProcessorUid;
+ UINT32 AcpiProcessorUid;
/** The flags field as described by the GICC structure
in the ACPI Specification.
*/
- UINT32 Flags;
+ UINT32 Flags;
/** The parking protocol version field as described by
the GICC structure in the ACPI Specification.
*/
- UINT32 ParkingProtocolVersion;
+ UINT32 ParkingProtocolVersion;
/** The Performance Interrupt field as described by
the GICC structure in the ACPI Specification.
*/
- UINT32 PerformanceInterruptGsiv;
+ UINT32 PerformanceInterruptGsiv;
/** The CPU Parked address field as described by
the GICC structure in the ACPI Specification.
*/
- UINT64 ParkedAddress;
+ UINT64 ParkedAddress;
/** The base address for the GIC CPU Interface
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 PhysicalBaseAddress;
+ UINT64 PhysicalBaseAddress;
/** The base address for GICV interface
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 GICV;
+ UINT64 GICV;
/** The base address for GICH interface
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 GICH;
+ UINT64 GICH;
/** The GICV maintenance interrupt
as described by the GICC structure in the
ACPI Specification.
*/
- UINT32 VGICMaintenanceInterrupt;
+ UINT32 VGICMaintenanceInterrupt;
/** The base address for GICR interface
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 GICRBaseAddress;
+ UINT64 GICRBaseAddress;
/** The MPIDR for the CPU
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 MPIDR;
+ UINT64 MPIDR;
/** The Processor Power Efficiency class
as described by the GICC structure in the
ACPI Specification.
*/
- UINT8 ProcessorPowerEfficiencyClass;
+ UINT8 ProcessorPowerEfficiencyClass;
/** Statistical Profiling Extension buffer overflow GSIV. Zero if
unsupported by this processor. This field was introduced in
ACPI 6.3 (MADT revision 5) and is therefore ignored when
generating MADT revision 4 or lower.
*/
- UINT16 SpeOverflowInterrupt;
+ UINT16 SpeOverflowInterrupt;
/** The proximity domain to which the logical processor belongs.
This field is used to populate the GICC affinity structure
in the SRAT table.
*/
- UINT32 ProximityDomain;
+ UINT32 ProximityDomain;
/** The clock domain to which the logical processor belongs.
This field is used to populate the GICC affinity structure
in the SRAT table.
*/
- UINT32 ClockDomain;
+ UINT32 ClockDomain;
/** The GICC Affinity flags field as described by the GICC Affinity structure
in the SRAT table.
*/
- UINT32 AffinityFlags;
+ UINT32 AffinityFlags;
+
+ /** Optional field: Reference Token for the Cpc info of this processor.
+ Token identifying a CM_ARM_OBJ_REF structure, itself referencing
+ CM_ARM_CPC_INFO objects.
+ */
+ CM_OBJECT_TOKEN CpcToken;
} CM_ARM_GICC_INFO;
/** A structure that describes the
@@ -1070,6 +1077,113 @@ typedef struct CmArmRmrDescriptor {
UINT64 Length;
} CM_ARM_MEMORY_RANGE_DESCRIPTOR;
+/** A structure that describes the Cpc information.
+
+ Continuous Performance Control is described in DSDT/SSDT and associated
+ to cpus/clusters in the cpu topology.
+
+ Unsupported Optional registers should be encoded with NULL resource
+ Register {(SystemMemory, 0, 0, 0, 0)}
+
+ For values that support Integer or Buffer, integer will be used
+ if buffer is NULL resource.
+ If resource is not NULL then Integer must be 0
+
+ Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
+
+ ID: EArmObjCpcInfo
+*/
+typedef struct CmArmCpcInfo {
+ /// The revision number of the _CPC package format.
+ UINT32 Revision;
+
+ /// Indicates the highest level of performance the processor
+ /// is theoretically capable of achieving.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE HighestPerformanceBuffer;
+ UINT32 HighestPerformanceInteger;
+
+ /// Indicates the highest sustained performance level of the processor.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE NominalPerformanceBuffer;
+ UINT32 NominalPerformanceInteger;
+
+ /// Indicates the lowest performance level of the processor with non-linear power savings.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestNonlinearPerformanceBuffer;
+ UINT32 LowestNonlinearPerformanceInteger;
+
+ /// Indicates the lowest performance level of the processor..
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestPerformanceBuffer;
+ UINT32 LowestPerformanceInteger;
+
+ /// Guaranteed Performance Register Buffer.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE GuaranteedPerformanceRegister;
+
+ /// Desired Performance Register Buffer.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DesiredPerformanceRegister;
+
+ /// Minimum Performance Register Buffer.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE MinimumPerformanceRegister;
+
+ /// Maximum Performance Register Buffer.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE MaximumPerformanceRegister;
+
+ /// Performance Reduction Tolerance Register.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE PerformanceReductionToleranceRegister;
+
+ /// Time Window Register.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE TimeWindowRegister;
+
+ /// Counter Wraparound Time
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CounterWraparoundTimeBuffer;
+ UINT32 CounterWraparoundTimeInteger;
+
+ /// Reference Performance Counter Register
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ReferencePerformanceCounterRegister;
+
+ /// Delivered Performance Counter Register
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DeliveredPerformanceCounterRegister;
+
+ /// Performance Limited Register
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE PerformanceLimitedRegister;
+
+ /// CPPC EnableRegister
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CPPCEnableRegister;
+
+ /// Autonomous Selection Enable
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE AutonomousSelectionEnableBuffer;
+ UINT32 AutonomousSelectionEnableInteger;
+
+ /// AutonomousActivity-WindowRegister
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE AutonomousActivityWindowRegister;
+
+ /// EnergyPerformance-PreferenceRegister
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE EnergyPerformancePreferenceRegister;
+
+ /// Reference Performance
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ReferencePerformanceBuffer;
+ UINT32 ReferencePerformanceInteger;
+
+ /// Lowest Frequency
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestFrequencyBuffer;
+ UINT32 LowestFrequencyInteger;
+
+ /// Nominal Frequency
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE NominalFrequencyBuffer;
+ UINT32 NominalFrequencyInteger;
+} CM_ARM_CPC_INFO;
+
#pragma pack()
#endif // ARM_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index c1b21d24a4..e2c608443b 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
@@ -423,6 +423,83 @@ STATIC CONST CM_OBJ_PARSER CmPciInterruptMapInfoParser[] = {
ARRAY_SIZE (CmArmGenericInterruptParser) },
};
+/** A parser for EArmObjCpcInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = {
+ { "HighestPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "HighestPerformanceInteger", 4, "0x%llx", NULL },
+ { "NominalPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "NominalPerformanceInteger", 4, "0x%llx", NULL },
+ { "LowestNonlinearPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "LowestNonlinearPerformanceInteger", 4, "0x%llx", NULL },
+ { "LowestPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "LowestPerformanceInteger", 4, "0x%llx", NULL },
+ { "GuaranteedPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "DesiredPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "MinimumPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "MaximumPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "PerformanceReductionToleranceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "TimeWindowRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "CounterWraparoundTimeBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "CounterWraparoundTimeInteger", 4, "0x%llx", NULL },
+ { "ReferencePerformanceCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "DeliveredPerformanceCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "PerformanceLimitedRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "CPPCEnableRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "AutonomousSelectionEnableBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "AutonomousSelectionEnableInteger", 4, "0x%llx", NULL },
+ { "AutonomousActivityWindowRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "EnergyPerformancePreferenceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "ReferencePerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "ReferencePerformanceInteger", 4, "0x%llx", NULL },
+ { "LowestFrequencyBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "LowestFrequencyInteger", 4, "0x%llx", NULL },
+ { "NominalFrequencyBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "NominalFrequencyInteger", 4, "0x%llx", NULL },
+};
+
/** A parser for Arm namespace objects.
*/
STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
@@ -501,6 +578,8 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
ARRAY_SIZE (CmArmPciAddressMapInfoParser) },
{ "EArmObjPciInterruptMapInfo", CmPciInterruptMapInfoParser,
ARRAY_SIZE (CmPciInterruptMapInfoParser) },
+ { "EArmObjCpcInfo", CmArmCpcInfoParser,
+ ARRAY_SIZE (CmArmCpcInfoParser) },
{ "EArmObjMax", NULL, 0 },
};
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries
2022-09-14 21:34 [PATCH v2 0/3] DynamicTablesPkg: _CPC support Jeff Brasen
2022-09-14 21:34 ` [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
@ 2022-09-14 21:34 ` Jeff Brasen
2022-09-15 8:04 ` PierreGondois
2022-09-14 21:34 ` [PATCH v2 3/3] DynamicTablesPkg: SSDT CPU _CPC generator Jeff Brasen
2 siblings, 1 reply; 8+ messages in thread
From: Jeff Brasen @ 2022-09-14 21:34 UTC (permalink / raw)
To: devel
Cc: ardb+tianocore, Sami.Mujawar, Alexei.Fedorov, pierre.gondois,
Jeff Brasen
_CPC entries can describe CPU performance information.
The object is described in ACPI 6.4 s8.4.7.1.
"_CPC (Continuous Performance Control)".
Add AmlCreateCpcNode() helper function to add _CPC entries to an
existing CPU object.
Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
---
.../Include/Library/AmlLib/AmlLib.h | 156 +++++
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 543 ++++++++++++++++++
2 files changed, 699 insertions(+)
diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
index 39968660f2..3fafa6b0e8 100644
--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -1336,6 +1336,162 @@ AmlAddNameIntegerPackage (
IN AML_OBJECT_NODE_HANDLE PackageNode
);
+/** Create a _CPC node.
+
+ Creates and optionally adds the following node
+ 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)
+ })
+
+ If resource buffer is NULL then integer will be used.
+
+ Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
+
+ @ingroup CodeGenApis
+
+ @param [in] HighestPerformanceBuffer If provided, buffer that indicates the highest level
+ of performance the processor.
+ @param [in] HighestPerformanceInteger Indicates the highest level of performance the processor,
+ used if buffer is NULL.
+ @param [in] NominalPerformanceBuffer If provided buffer that indicates the highest sustained
+ performance level of the processor.
+ @param [in] NominalPerformanceInteger Indicates the highest sustained performance level
+ of the processor, used if buffer is NULL.
+ @param [in] LowestNonlinearPerformanceBuffer If provided, buffer that indicates the lowest performance level
+ of the processor with non-linear power savings.
+ @param [in] LowestNonlinearPerformanceInteger Indicates the lowest performance level of the processor with
+ non-linear power savings, used if buffer is NULL.
+ @param [in] LowestPerformanceBuffer If provided, buffer that indicates the
+ lowest performance level of the processor.
+ @param [in] LowestPerformanceInteger Indicates the lowest performance level of the processor,
+ used if buffer is NULL.
+ @param [in] GuaranteedPerformanceRegister If provided, Guaranteed Performance Register Buffer.
+ @param [in] DesiredPerformanceRegister If provided, Desired Performance Register Buffer.
+ @param [in] MinimumPerformanceRegister If provided, Minimum Performance Register Buffer.
+ @param [in] MaximumPerformanceRegister If provided, Maximum Performance Register Buffer.
+ @param [in] PerformanceReductionToleranceRegister If provided, Performance Reduction Tolerance Register.
+ @param [in] TimeWindowRegister If provided, Time Window Register.
+ @param [in] CounterWraparoundTimeBuffer If provided, Counter Wraparound Time buffer.
+ @param [in] CounterWraparoundTimeInteger Counter Wraparound Time, used if buffer is NULL.
+ @param [in] ReferencePerformanceCounterRegister Reference Performance Counter Register.
+ @param [in] DeliveredPerformanceCounterRegister Delivered Performance Counter Register.
+ @param [in] PerformanceLimitedRegister Performance Limited Register.
+ @param [in] CPPCEnableRegister If provided, CPPC EnableRegister.
+ @param [in] AutonomousSelectionEnableBuffer If provided, Autonomous Selection Enable buffer.
+ @param [in] AutonomousSelectionEnableInteger Autonomous Selection Enable, used if buffer is NULL.
+ @param [in] AutonomousActivityWindowRegister If provided, AutonomousActivity-WindowRegister.
+ @param [in] EnergyPerformancePreferenceRegister If provided, EnergyPerformance-PreferenceRegister.
+ @param [in] ReferencePerformanceBuffer If provided, Reference Performance buffer.
+ @param [in] ReferencePerformanceInteger Reference Performance, used if buffer is NULL.
+ @param [in] LowestFrequencyBuffer If provided, Lowest Frequency buffer.
+ @param [in] LowestFrequencyInteger Lowest Frequency, used if buffer is NULL.
+ @param [in] NominalFrequencyBuffer If provided, NominalFrequencyBuffer buffer.
+ @param [in] NominalFrequencyInteger NominalFrequencyBuffer, used if buffer is NULL.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewCpcNode If success and provided, contains the created node.
+
+ @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
+AmlCreateCpcNode (
+ /// The revision number of the _CPC package format.
+ IN UINT32 Revision,
+ /// Indicates the highest level of performance the processor
+ /// is theoretically capable of achieving.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *HighestPerformanceBuffer OPTIONAL,
+ IN UINT32 HighestPerformanceInteger,
+ /// Indicates the highest sustained performance level of the processor.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalPerformanceBuffer OPTIONAL,
+ IN UINT32 NominalPerformanceInteger,
+ /// Indicates the lowest performance level of the processor with non-linear power savings.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestNonlinearPerformanceBuffer OPTIONAL,
+ IN UINT32 LowestNonlinearPerformanceInteger,
+ /// Indicates the lowest performance level of the processor..
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestPerformanceBuffer OPTIONAL,
+ IN UINT32 LowestPerformanceInteger,
+ /// Guaranteed Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *GuaranteedPerformanceRegister OPTIONAL,
+ /// Desired Performance Register Buffer.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DesiredPerformanceRegister,
+ /// Minimum Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MinimumPerformanceRegister OPTIONAL,
+ /// Maximum Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MaximumPerformanceRegister OPTIONAL,
+ /// Performance Reduction Tolerance Register.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceReductionToleranceRegister OPTIONAL,
+ /// Time Window Register.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *TimeWindowRegister OPTIONAL,
+ /// Counter Wraparound Time
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CounterWraparoundTimeBuffer OPTIONAL,
+ IN UINT32 CounterWraparoundTimeInteger,
+ /// Reference Performance Counter Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceCounterRegister,
+ /// Delivered Performance Counter Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DeliveredPerformanceCounterRegister,
+ /// Performance Limited Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceLimitedRegister,
+ /// CPPC EnableRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CPPCEnableRegister OPTIONAL,
+ /// Autonomous Selection Enable
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousSelectionEnableBuffer OPTIONAL,
+ IN UINT32 AutonomousSelectionEnableInteger,
+ /// AutonomousActivity-WindowRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousActivityWindowRegister OPTIONAL,
+ /// EnergyPerformance-PreferenceRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *EnergyPerformancePreferenceRegister OPTIONAL,
+ /// Reference Performance
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceBuffer OPTIONAL,
+ IN UINT32 ReferencePerformanceInteger,
+ /// Lowest Frequency
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestFrequencyBuffer OPTIONAL,
+ IN UINT32 LowestFrequencyInteger,
+ /// Nominal Frequency
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalFrequencyBuffer OPTIONAL,
+ IN UINT32 NominalFrequencyInteger,
+ IN AML_NODE_HANDLE ParentNode OPTIONAL,
+ OUT AML_OBJECT_NODE_HANDLE *NewCpcNode OPTIONAL
+ );
+
// DEPRECATED APIS
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 5fb39d077b..42f0d0002c 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -2850,3 +2850,546 @@ error_handler:
return Status;
}
+
+/** Adds a register to the package
+
+ @ingroup CodeGenApis
+
+ @param [in] Register If provided, register that will be added to package.
+ otherwise NULL register will be added
+ @param [in] PackageNode Package to add value to
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlAddRegisterToPackage (
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *Register OPTIONAL,
+ IN AML_OBJECT_NODE_HANDLE PackageNode
+ )
+{
+ EFI_STATUS Status;
+ AML_DATA_NODE_HANDLE RdNode;
+ AML_OBJECT_NODE_HANDLE ResourceTemplateNode;
+
+ RdNode = NULL;
+
+ Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ if (Register != NULL) {
+ Status = AmlCodeGenRdRegister (
+ Register->AddressSpaceId,
+ Register->RegisterBitWidth,
+ Register->RegisterBitOffset,
+ Register->Address,
+ Register->AccessSize,
+ NULL,
+ &RdNode
+ );
+ } else {
+ Status = AmlCodeGenRdRegister (
+ EFI_ACPI_6_4_SYSTEM_MEMORY,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ &RdNode
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ RdNode = NULL;
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)ResourceTemplateNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ return Status;
+
+error_handler:
+ if (RdNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)RdNode);
+ }
+
+ if (ResourceTemplateNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)ResourceTemplateNode);
+ }
+
+ return Status;
+}
+
+/** Adds an integer or register to the package
+
+ @ingroup CodeGenApis
+
+ @param [in] Register If provided, register that will be added to package
+ @param [in] Integer If Register is NULL, integer that will be added to the package
+ @param [in] PackageNode Package to add value to
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlAddRegisterOrIntegerToPackage (
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *Register OPTIONAL,
+ IN UINT32 Integer,
+ IN AML_OBJECT_NODE_HANDLE PackageNode
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE IntegerNode;
+
+ IntegerNode = NULL;
+
+ if (Register != NULL) {
+ Status = AmlAddRegisterToPackage (Register, PackageNode);
+ } else {
+ Status = AmlCodeGenInteger (Integer, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ if (IntegerNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
+ }
+ }
+
+ return Status;
+}
+
+/** Create a _CPC node.
+
+ Creates and optionally adds the following node
+ 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)
+ })
+
+ If resource buffer is NULL then integer will be used.
+
+ Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
+
+ @ingroup CodeGenApis
+
+ @param [in] HighestPerformanceBuffer If provided, buffer that indicates the highest level
+ of performance the processor.
+ @param [in] HighestPerformanceInteger Indicates the highest level of performance the processor,
+ used if buffer is NULL.
+ @param [in] NominalPerformanceBuffer If provided buffer that indicates the highest sustained
+ performance level of the processor.
+ @param [in] NominalPerformanceInteger Indicates the highest sustained performance level
+ of the processor, used if buffer is NULL.
+ @param [in] LowestNonlinearPerformanceBuffer If provided, buffer that indicates the lowest performance level
+ of the processor with non-linear power savings.
+ @param [in] LowestNonlinearPerformanceInteger Indicates the lowest performance level of the processor with
+ non-linear power savings, used if buffer is NULL.
+ @param [in] LowestPerformanceBuffer If provided, buffer that indicates the
+ lowest performance level of the processor.
+ @param [in] LowestPerformanceInteger Indicates the lowest performance level of the processor,
+ used if buffer is NULL.
+ @param [in] GuaranteedPerformanceRegister If provided, Guaranteed Performance Register Buffer.
+ @param [in] DesiredPerformanceRegister If provided, Desired Performance Register Buffer.
+ @param [in] MinimumPerformanceRegister If provided, Minimum Performance Register Buffer.
+ @param [in] MaximumPerformanceRegister If provided, Maximum Performance Register Buffer.
+ @param [in] PerformanceReductionToleranceRegister If provided, Performance Reduction Tolerance Register.
+ @param [in] TimeWindowRegister If provided, Time Window Register.
+ @param [in] CounterWraparoundTimeBuffer If provided, Counter Wraparound Time buffer.
+ @param [in] CounterWraparoundTimeInteger Counter Wraparound Time, used if buffer is NULL.
+ @param [in] ReferencePerformanceCounterRegister Reference Performance Counter Register.
+ @param [in] DeliveredPerformanceCounterRegister Delivered Performance Counter Register.
+ @param [in] PerformanceLimitedRegister Performance Limited Register.
+ @param [in] CPPCEnableRegister If provided, CPPC EnableRegister.
+ @param [in] AutonomousSelectionEnableBuffer If provided, Autonomous Selection Enable buffer.
+ @param [in] AutonomousSelectionEnableInteger Autonomous Selection Enable, used if buffer is NULL.
+ @param [in] AutonomousActivityWindowRegister If provided, AutonomousActivity-WindowRegister.
+ @param [in] EnergyPerformancePreferenceRegister If provided, EnergyPerformance-PreferenceRegister.
+ @param [in] ReferencePerformanceBuffer If provided, Reference Performance buffer.
+ @param [in] ReferencePerformanceInteger Reference Performance, used if buffer is NULL.
+ @param [in] LowestFrequencyBuffer If provided, Lowest Frequency buffer.
+ @param [in] LowestFrequencyInteger Lowest Frequency, used if buffer is NULL.
+ @param [in] NominalFrequencyBuffer If provided, NominalFrequencyBuffer buffer.
+ @param [in] NominalFrequencyInteger NominalFrequencyBuffer, used if buffer is NULL.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewCpcNode If success and provided, contains the created node.
+
+ @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
+AmlCreateCpcNode (
+ /// The revision number of the _CPC package format.
+ IN UINT32 Revision,
+ /// Indicates the highest level of performance the processor
+ /// is theoretically capable of achieving.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *HighestPerformanceBuffer OPTIONAL,
+ IN UINT32 HighestPerformanceInteger,
+ /// Indicates the highest sustained performance level of the processor.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalPerformanceBuffer OPTIONAL,
+ IN UINT32 NominalPerformanceInteger,
+ /// Indicates the lowest performance level of the processor with non-linear power savings.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestNonlinearPerformanceBuffer OPTIONAL,
+ IN UINT32 LowestNonlinearPerformanceInteger,
+ /// Indicates the lowest performance level of the processor..
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestPerformanceBuffer OPTIONAL,
+ IN UINT32 LowestPerformanceInteger,
+ /// Guaranteed Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *GuaranteedPerformanceRegister OPTIONAL,
+ /// Desired Performance Register Buffer.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DesiredPerformanceRegister,
+ /// Minimum Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MinimumPerformanceRegister OPTIONAL,
+ /// Maximum Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MaximumPerformanceRegister OPTIONAL,
+ /// Performance Reduction Tolerance Register.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceReductionToleranceRegister OPTIONAL,
+ /// Time Window Register.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *TimeWindowRegister OPTIONAL,
+ /// Counter Wraparound Time
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CounterWraparoundTimeBuffer OPTIONAL,
+ IN UINT32 CounterWraparoundTimeInteger,
+ /// Reference Performance Counter Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceCounterRegister,
+ /// Delivered Performance Counter Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DeliveredPerformanceCounterRegister,
+ /// Performance Limited Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceLimitedRegister,
+ /// CPPC EnableRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CPPCEnableRegister OPTIONAL,
+ /// Autonomous Selection Enable
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousSelectionEnableBuffer OPTIONAL,
+ IN UINT32 AutonomousSelectionEnableInteger,
+ /// AutonomousActivity-WindowRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousActivityWindowRegister OPTIONAL,
+ /// EnergyPerformance-PreferenceRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *EnergyPerformancePreferenceRegister OPTIONAL,
+ /// Reference Performance
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceBuffer OPTIONAL,
+ IN UINT32 ReferencePerformanceInteger,
+ /// Lowest Frequency
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestFrequencyBuffer OPTIONAL,
+ IN UINT32 LowestFrequencyInteger,
+ /// Nominal Frequency
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalFrequencyBuffer OPTIONAL,
+ IN UINT32 NominalFrequencyInteger,
+ IN AML_NODE_HANDLE ParentNode OPTIONAL,
+ OUT AML_OBJECT_NODE_HANDLE *NewCpcNode OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE CpcNode;
+ AML_OBJECT_NODE_HANDLE CpcPackage;
+ UINT32 NumberOfEntries;
+
+ // Revision 3 per ACPI 6.4 specification
+ if (Revision == 3) {
+ // NumEntries 23 per ACPI 6.4 specification
+ NumberOfEntries = 23;
+ } else {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((HighestPerformanceBuffer == NULL) && (HighestPerformanceInteger == 0)) ||
+ ((NominalPerformanceBuffer == NULL) && (NominalPerformanceInteger == 0)) ||
+ ((LowestNonlinearPerformanceBuffer == NULL) && (LowestNonlinearPerformanceInteger == 0)) ||
+ ((LowestPerformanceBuffer == NULL) && (LowestPerformanceInteger == 0)) ||
+ (DesiredPerformanceRegister == NULL) ||
+ (ReferencePerformanceCounterRegister == NULL) ||
+ (DeliveredPerformanceCounterRegister == NULL) ||
+ (PerformanceLimitedRegister == NULL) ||
+ ((ParentNode == NULL) && (NewCpcNode == NULL)))
+ {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CpcPackage = NULL;
+
+ Status = AmlCodeGenNamePackage ("_CPC", NULL, &CpcNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ // Get the Package object node of the _CPC node,
+ // which is the 2nd fixed argument (i.e. index 1).
+ CpcPackage = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
+ CpcNode,
+ EAmlParseIndexTerm1
+ );
+ if ((CpcPackage == NULL) ||
+ (AmlGetNodeType ((AML_NODE_HANDLE)CpcPackage) != EAmlNodeObject) ||
+ (!AmlNodeHasOpCode (CpcPackage, AML_PACKAGE_OP, 0)))
+ {
+ ASSERT (0);
+ Status = EFI_INVALID_PARAMETER;
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ NULL,
+ NumberOfEntries,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ NULL,
+ Revision,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ HighestPerformanceBuffer,
+ HighestPerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ NominalPerformanceBuffer,
+ NominalPerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ LowestNonlinearPerformanceBuffer,
+ LowestNonlinearPerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ LowestPerformanceBuffer,
+ LowestPerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (GuaranteedPerformanceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (DesiredPerformanceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (MinimumPerformanceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (MaximumPerformanceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (PerformanceReductionToleranceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (TimeWindowRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ CounterWraparoundTimeBuffer,
+ CounterWraparoundTimeInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (ReferencePerformanceCounterRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (DeliveredPerformanceCounterRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (PerformanceLimitedRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (CPPCEnableRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ AutonomousSelectionEnableBuffer,
+ AutonomousSelectionEnableInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (AutonomousActivityWindowRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (EnergyPerformancePreferenceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ ReferencePerformanceBuffer,
+ ReferencePerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ LowestFrequencyBuffer,
+ LowestFrequencyInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ NominalFrequencyBuffer,
+ NominalFrequencyInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = LinkNode (CpcNode, ParentNode, NewCpcNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ return Status;
+
+error_handler:
+ AmlDeleteTree ((AML_NODE_HANDLE)CpcNode);
+ return Status;
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] DynamicTablesPkg: SSDT CPU _CPC generator
2022-09-14 21:34 [PATCH v2 0/3] DynamicTablesPkg: _CPC support Jeff Brasen
2022-09-14 21:34 ` [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
2022-09-14 21:34 ` [PATCH v2 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries Jeff Brasen
@ 2022-09-14 21:34 ` Jeff Brasen
2022-09-15 8:03 ` PierreGondois
2 siblings, 1 reply; 8+ messages in thread
From: Jeff Brasen @ 2022-09-14 21:34 UTC (permalink / raw)
To: devel
Cc: ardb+tianocore, Sami.Mujawar, Alexei.Fedorov, pierre.gondois,
Jeff Brasen
Add code to use a token attached to GICC to generate _CPC object on cpus.
Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
---
.../SsdtCpuTopologyGenerator.c | 223 +++++++++++++++++-
1 file changed, 217 insertions(+), 6 deletions(-)
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
index 8561f48e1f..56741e7b58 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
@@ -76,6 +76,16 @@ GET_OBJECT_LIST (
CM_ARM_LPI_INFO
);
+/**
+ This macro expands to a function that retrieves the CPC
+ information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjCpcInfo,
+ CM_ARM_CPC_INFO
+ );
+
/** Initialize the TokenTable.
One entry should be allocated for each CM_ARM_PROC_HIERARCHY_INFO
@@ -229,6 +239,183 @@ WriteAslName (
return EFI_SUCCESS;
}
+/** Utility function to check if generic address points to NULL
+
+ @param [in] Address Pointer to the Generic address
+
+ @retval TRUE Address is system memory with an Address of 0.
+ @retval FALSE Address does not point to NULL.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsNullGenericAddress (
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *Address
+ )
+{
+ if ((Address == NULL) ||
+ ((Address->AddressSpaceId == EFI_ACPI_6_4_SYSTEM_MEMORY) &&
+ (Address->Address == 0x0)))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** 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] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_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.
+**/
+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 AML_OBJECT_NODE_HANDLE *Node
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_CPC_INFO *CpcInfo;
+
+ Status = GetEArmObjCpcInfo (
+ CfgMgrProtocol,
+ GicCInfo->CpcToken,
+ &CpcInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCreateCpcNode (
+ CpcInfo->Revision,
+ IsNullGenericAddress (&CpcInfo->HighestPerformanceBuffer) ?
+ NULL :
+ &CpcInfo->HighestPerformanceBuffer,
+ CpcInfo->HighestPerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->NominalPerformanceBuffer) ?
+ NULL :
+ &CpcInfo->NominalPerformanceBuffer,
+ CpcInfo->NominalPerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->LowestNonlinearPerformanceBuffer) ?
+ NULL :
+ &CpcInfo->LowestNonlinearPerformanceBuffer,
+ CpcInfo->LowestNonlinearPerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->LowestPerformanceBuffer) ?
+ NULL :
+ &CpcInfo->LowestPerformanceBuffer,
+ CpcInfo->LowestPerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->GuaranteedPerformanceRegister) ?
+ NULL :
+ &CpcInfo->GuaranteedPerformanceRegister,
+ IsNullGenericAddress (&CpcInfo->DesiredPerformanceRegister) ?
+ NULL :
+ &CpcInfo->DesiredPerformanceRegister,
+ IsNullGenericAddress (&CpcInfo->MinimumPerformanceRegister) ?
+ NULL :
+ &CpcInfo->MinimumPerformanceRegister,
+ IsNullGenericAddress (&CpcInfo->MaximumPerformanceRegister) ?
+ NULL :
+ &CpcInfo->MaximumPerformanceRegister,
+ IsNullGenericAddress (&CpcInfo->PerformanceReductionToleranceRegister) ?
+ NULL :
+ &CpcInfo->PerformanceReductionToleranceRegister,
+ IsNullGenericAddress (&CpcInfo->TimeWindowRegister) ?
+ NULL :
+ &CpcInfo->TimeWindowRegister,
+ IsNullGenericAddress (&CpcInfo->CounterWraparoundTimeBuffer) ?
+ NULL :
+ &CpcInfo->CounterWraparoundTimeBuffer,
+ CpcInfo->CounterWraparoundTimeInteger,
+ &CpcInfo->ReferencePerformanceCounterRegister,
+ &CpcInfo->DeliveredPerformanceCounterRegister,
+ &CpcInfo->PerformanceLimitedRegister,
+ IsNullGenericAddress (&CpcInfo->CPPCEnableRegister) ?
+ NULL :
+ &CpcInfo->CPPCEnableRegister,
+ IsNullGenericAddress (&CpcInfo->AutonomousSelectionEnableBuffer) ?
+ NULL :
+ &CpcInfo->AutonomousSelectionEnableBuffer,
+ CpcInfo->AutonomousSelectionEnableInteger,
+ IsNullGenericAddress (&CpcInfo->AutonomousActivityWindowRegister) ?
+ NULL :
+ &CpcInfo->AutonomousActivityWindowRegister,
+ IsNullGenericAddress (&CpcInfo->EnergyPerformancePreferenceRegister) ?
+ NULL :
+ &CpcInfo->EnergyPerformancePreferenceRegister,
+ IsNullGenericAddress (&CpcInfo->ReferencePerformanceBuffer) ?
+ NULL :
+ &CpcInfo->ReferencePerformanceBuffer,
+ CpcInfo->ReferencePerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->LowestFrequencyBuffer) ?
+ NULL :
+ &CpcInfo->LowestFrequencyBuffer,
+ CpcInfo->LowestFrequencyInteger,
+ IsNullGenericAddress (&CpcInfo->NominalFrequencyBuffer) ?
+ NULL :
+ &CpcInfo->NominalFrequencyBuffer,
+ CpcInfo->NominalFrequencyInteger,
+ Node,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
/** Create and add an _LPI method to Cpu/Cluster Node.
For instance, transform an AML node from:
@@ -581,7 +768,20 @@ CreateAmlCpuFromProcHierarchy (
// CM_ARM_PROC_HIERARCHY_INFO, create an _LPI method returning them.
if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) {
Status = CreateAmlLpiMethod (Generator, ProcHierarchyNodeInfo, CpuNode);
- ASSERT_EFI_ERROR (Status);
+ 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->CpcToken != CM_NULL_TOKEN) {
+ Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
}
return Status;
@@ -934,10 +1134,11 @@ CreateTopologyFromGicC (
IN AML_OBJECT_NODE_HANDLE ScopeNode
)
{
- EFI_STATUS Status;
- CM_ARM_GICC_INFO *GicCInfo;
- UINT32 GicCInfoCount;
- UINT32 Index;
+ EFI_STATUS Status;
+ CM_ARM_GICC_INFO *GicCInfo;
+ UINT32 GicCInfoCount;
+ UINT32 Index;
+ AML_OBJECT_NODE_HANDLE CpuNode;
ASSERT (Generator != NULL);
ASSERT (CfgMgrProtocol != NULL);
@@ -961,12 +1162,22 @@ CreateTopologyFromGicC (
ScopeNode,
&GicCInfo[Index],
Index,
- NULL
+ &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->CpcToken != CM_NULL_TOKEN) {
+ Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, &GicCInfo[Index], CpuNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
} // for
return Status;
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object
2022-09-14 21:34 ` [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
@ 2022-09-15 8:02 ` PierreGondois
2022-09-15 14:00 ` Sami Mujawar
1 sibling, 0 replies; 8+ messages in thread
From: PierreGondois @ 2022-09-15 8:02 UTC (permalink / raw)
To: Jeff Brasen, devel; +Cc: ardb+tianocore, Sami.Mujawar, Alexei.Fedorov
Hello Jeff,
Just one remark:
On 9/14/22 23:34, Jeff Brasen wrote:
> Introduce the CM_ARM_CPC_INFO CmObj in the ArmNameSpaceObjects.
> This allows to describe CPC information, as described in ACPI 6.4,
> s8.4.7.1 "_CPC (Continuous Performance Control)".
>
> Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
> ---
> .../Include/ArmNameSpaceObjects.h | 148 ++++++++++++++++--
> .../ConfigurationManagerObjectParser.c | 79 ++++++++++
> 2 files changed, 210 insertions(+), 17 deletions(-)
>
[snip]
> diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
> index c1b21d24a4..e2c608443b 100644
> --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
> +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
> @@ -423,6 +423,83 @@ STATIC CONST CM_OBJ_PARSER CmPciInterruptMapInfoParser[] = {
> ARRAY_SIZE (CmArmGenericInterruptParser) },
> };
>
> +/** A parser for EArmObjCpcInfo.
> +*/
> +STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = {
> + { "HighestPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
Could it be move to 6_4 aswell ?
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "HighestPerformanceInteger", 4, "0x%llx", NULL },
> + { "NominalPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "NominalPerformanceInteger", 4, "0x%llx", NULL },
> + { "LowestNonlinearPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "LowestNonlinearPerformanceInteger", 4, "0x%llx", NULL },
> + { "LowestPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "LowestPerformanceInteger", 4, "0x%llx", NULL },
> + { "GuaranteedPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "DesiredPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "MinimumPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "MaximumPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "PerformanceReductionToleranceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "TimeWindowRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "CounterWraparoundTimeBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "CounterWraparoundTimeInteger", 4, "0x%llx", NULL },
> + { "ReferencePerformanceCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "DeliveredPerformanceCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "PerformanceLimitedRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "CPPCEnableRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "AutonomousSelectionEnableBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "AutonomousSelectionEnableInteger", 4, "0x%llx", NULL },
> + { "AutonomousActivityWindowRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "EnergyPerformancePreferenceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "ReferencePerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "ReferencePerformanceInteger", 4, "0x%llx", NULL },
> + { "LowestFrequencyBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "LowestFrequencyInteger", 4, "0x%llx", NULL },
> + { "NominalFrequencyBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
> + NULL, NULL, AcpiGenericAddressParser,
> + ARRAY_SIZE (AcpiGenericAddressParser) },
> + { "NominalFrequencyInteger", 4, "0x%llx", NULL },
> +};
> +
> /** A parser for Arm namespace objects.
> */
> STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
> @@ -501,6 +578,8 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
> ARRAY_SIZE (CmArmPciAddressMapInfoParser) },
> { "EArmObjPciInterruptMapInfo", CmPciInterruptMapInfoParser,
> ARRAY_SIZE (CmPciInterruptMapInfoParser) },
> + { "EArmObjCpcInfo", CmArmCpcInfoParser,
> + ARRAY_SIZE (CmArmCpcInfoParser) },
> { "EArmObjMax", NULL, 0 },
> };
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 3/3] DynamicTablesPkg: SSDT CPU _CPC generator
2022-09-14 21:34 ` [PATCH v2 3/3] DynamicTablesPkg: SSDT CPU _CPC generator Jeff Brasen
@ 2022-09-15 8:03 ` PierreGondois
0 siblings, 0 replies; 8+ messages in thread
From: PierreGondois @ 2022-09-15 8:03 UTC (permalink / raw)
To: Jeff Brasen, devel; +Cc: ardb+tianocore, Sami.Mujawar, Alexei.Fedorov
Hello Jeff,
Just one remark:
On 9/14/22 23:34, Jeff Brasen wrote:
> Add code to use a token attached to GICC to generate _CPC object on cpus.
>
> Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
> ---
> .../SsdtCpuTopologyGenerator.c | 223 +++++++++++++++++-
> 1 file changed, 217 insertions(+), 6 deletions(-)
>
> diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
> index 8561f48e1f..56741e7b58 100644
[snip]
> @@ -934,10 +1134,11 @@ CreateTopologyFromGicC (
> IN AML_OBJECT_NODE_HANDLE ScopeNode
> )
> {
> - EFI_STATUS Status;
> - CM_ARM_GICC_INFO *GicCInfo;
> - UINT32 GicCInfoCount;
> - UINT32 Index;
> + EFI_STATUS Status;
> + CM_ARM_GICC_INFO *GicCInfo;
> + UINT32 GicCInfoCount;
> + UINT32 Index;
> + AML_OBJECT_NODE_HANDLE CpuNode;
>
> ASSERT (Generator != NULL);
> ASSERT (CfgMgrProtocol != NULL);
> @@ -961,12 +1162,22 @@ CreateTopologyFromGicC (
> ScopeNode,
> &GicCInfo[Index],
> Index,
> - NULL
> + &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->CpcToken != CM_NULL_TOKEN) {
> + Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, &GicCInfo[Index], CpuNode);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + return Status;
Could it be replaced with a 'break' just to be consistent in the loop ?
> + }
> + }
> } // for
>
> return Status;
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries
2022-09-14 21:34 ` [PATCH v2 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries Jeff Brasen
@ 2022-09-15 8:04 ` PierreGondois
0 siblings, 0 replies; 8+ messages in thread
From: PierreGondois @ 2022-09-15 8:04 UTC (permalink / raw)
To: Jeff Brasen, devel; +Cc: ardb+tianocore, Sami.Mujawar, Alexei.Fedorov
Hello Jeff,
This patch looks good to me:
Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>
On 9/14/22 23:34, Jeff Brasen wrote:
> _CPC entries can describe CPU performance information.
> The object is described in ACPI 6.4 s8.4.7.1.
> "_CPC (Continuous Performance Control)".
>
> Add AmlCreateCpcNode() helper function to add _CPC entries to an
> existing CPU object.
>
> Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
> ---
> .../Include/Library/AmlLib/AmlLib.h | 156 +++++
> .../Common/AmlLib/CodeGen/AmlCodeGen.c | 543 ++++++++++++++++++
> 2 files changed, 699 insertions(+)
>
> diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> index 39968660f2..3fafa6b0e8 100644
> --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> @@ -1336,6 +1336,162 @@ AmlAddNameIntegerPackage (
> IN AML_OBJECT_NODE_HANDLE PackageNode
> );
>
> +/** Create a _CPC node.
> +
> + Creates and optionally adds the following node
> + 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)
> + })
> +
> + If resource buffer is NULL then integer will be used.
> +
> + Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
> +
> + @ingroup CodeGenApis
> +
> + @param [in] HighestPerformanceBuffer If provided, buffer that indicates the highest level
> + of performance the processor.
> + @param [in] HighestPerformanceInteger Indicates the highest level of performance the processor,
> + used if buffer is NULL.
> + @param [in] NominalPerformanceBuffer If provided buffer that indicates the highest sustained
> + performance level of the processor.
> + @param [in] NominalPerformanceInteger Indicates the highest sustained performance level
> + of the processor, used if buffer is NULL.
> + @param [in] LowestNonlinearPerformanceBuffer If provided, buffer that indicates the lowest performance level
> + of the processor with non-linear power savings.
> + @param [in] LowestNonlinearPerformanceInteger Indicates the lowest performance level of the processor with
> + non-linear power savings, used if buffer is NULL.
> + @param [in] LowestPerformanceBuffer If provided, buffer that indicates the
> + lowest performance level of the processor.
> + @param [in] LowestPerformanceInteger Indicates the lowest performance level of the processor,
> + used if buffer is NULL.
> + @param [in] GuaranteedPerformanceRegister If provided, Guaranteed Performance Register Buffer.
> + @param [in] DesiredPerformanceRegister If provided, Desired Performance Register Buffer.
> + @param [in] MinimumPerformanceRegister If provided, Minimum Performance Register Buffer.
> + @param [in] MaximumPerformanceRegister If provided, Maximum Performance Register Buffer.
> + @param [in] PerformanceReductionToleranceRegister If provided, Performance Reduction Tolerance Register.
> + @param [in] TimeWindowRegister If provided, Time Window Register.
> + @param [in] CounterWraparoundTimeBuffer If provided, Counter Wraparound Time buffer.
> + @param [in] CounterWraparoundTimeInteger Counter Wraparound Time, used if buffer is NULL.
> + @param [in] ReferencePerformanceCounterRegister Reference Performance Counter Register.
> + @param [in] DeliveredPerformanceCounterRegister Delivered Performance Counter Register.
> + @param [in] PerformanceLimitedRegister Performance Limited Register.
> + @param [in] CPPCEnableRegister If provided, CPPC EnableRegister.
> + @param [in] AutonomousSelectionEnableBuffer If provided, Autonomous Selection Enable buffer.
> + @param [in] AutonomousSelectionEnableInteger Autonomous Selection Enable, used if buffer is NULL.
> + @param [in] AutonomousActivityWindowRegister If provided, AutonomousActivity-WindowRegister.
> + @param [in] EnergyPerformancePreferenceRegister If provided, EnergyPerformance-PreferenceRegister.
> + @param [in] ReferencePerformanceBuffer If provided, Reference Performance buffer.
> + @param [in] ReferencePerformanceInteger Reference Performance, used if buffer is NULL.
> + @param [in] LowestFrequencyBuffer If provided, Lowest Frequency buffer.
> + @param [in] LowestFrequencyInteger Lowest Frequency, used if buffer is NULL.
> + @param [in] NominalFrequencyBuffer If provided, NominalFrequencyBuffer buffer.
> + @param [in] NominalFrequencyInteger NominalFrequencyBuffer, used if buffer is NULL.
> + @param [in] ParentNode If provided, set ParentNode as the parent
> + of the node created.
> + @param [out] NewCpcNode If success and provided, contains the created node.
> +
> + @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
> +AmlCreateCpcNode (
> + /// The revision number of the _CPC package format.
> + IN UINT32 Revision,
> + /// Indicates the highest level of performance the processor
> + /// is theoretically capable of achieving.
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *HighestPerformanceBuffer OPTIONAL,
> + IN UINT32 HighestPerformanceInteger,
> + /// Indicates the highest sustained performance level of the processor.
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalPerformanceBuffer OPTIONAL,
> + IN UINT32 NominalPerformanceInteger,
> + /// Indicates the lowest performance level of the processor with non-linear power savings.
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestNonlinearPerformanceBuffer OPTIONAL,
> + IN UINT32 LowestNonlinearPerformanceInteger,
> + /// Indicates the lowest performance level of the processor..
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestPerformanceBuffer OPTIONAL,
> + IN UINT32 LowestPerformanceInteger,
> + /// Guaranteed Performance Register Buffer.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *GuaranteedPerformanceRegister OPTIONAL,
> + /// Desired Performance Register Buffer.
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DesiredPerformanceRegister,
> + /// Minimum Performance Register Buffer.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MinimumPerformanceRegister OPTIONAL,
> + /// Maximum Performance Register Buffer.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MaximumPerformanceRegister OPTIONAL,
> + /// Performance Reduction Tolerance Register.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceReductionToleranceRegister OPTIONAL,
> + /// Time Window Register.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *TimeWindowRegister OPTIONAL,
> + /// Counter Wraparound Time
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CounterWraparoundTimeBuffer OPTIONAL,
> + IN UINT32 CounterWraparoundTimeInteger,
> + /// Reference Performance Counter Register
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceCounterRegister,
> + /// Delivered Performance Counter Register
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DeliveredPerformanceCounterRegister,
> + /// Performance Limited Register
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceLimitedRegister,
> + /// CPPC EnableRegister
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CPPCEnableRegister OPTIONAL,
> + /// Autonomous Selection Enable
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousSelectionEnableBuffer OPTIONAL,
> + IN UINT32 AutonomousSelectionEnableInteger,
> + /// AutonomousActivity-WindowRegister
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousActivityWindowRegister OPTIONAL,
> + /// EnergyPerformance-PreferenceRegister
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *EnergyPerformancePreferenceRegister OPTIONAL,
> + /// Reference Performance
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceBuffer OPTIONAL,
> + IN UINT32 ReferencePerformanceInteger,
> + /// Lowest Frequency
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestFrequencyBuffer OPTIONAL,
> + IN UINT32 LowestFrequencyInteger,
> + /// Nominal Frequency
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalFrequencyBuffer OPTIONAL,
> + IN UINT32 NominalFrequencyInteger,
> + IN AML_NODE_HANDLE ParentNode OPTIONAL,
> + OUT AML_OBJECT_NODE_HANDLE *NewCpcNode OPTIONAL
> + );
> +
> // DEPRECATED APIS
> #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
>
> diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
> index 5fb39d077b..42f0d0002c 100644
> --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
> +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
> @@ -2850,3 +2850,546 @@ error_handler:
>
> return Status;
> }
> +
> +/** Adds a register to the package
> +
> + @ingroup CodeGenApis
> +
> + @param [in] Register If provided, register that will be added to package.
> + otherwise NULL register will be added
> + @param [in] PackageNode Package to add value to
> +
> + @retval EFI_SUCCESS The function completed successfully.
> + @retval EFI_INVALID_PARAMETER Invalid parameter.
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +AmlAddRegisterToPackage (
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *Register OPTIONAL,
> + IN AML_OBJECT_NODE_HANDLE PackageNode
> + )
> +{
> + EFI_STATUS Status;
> + AML_DATA_NODE_HANDLE RdNode;
> + AML_OBJECT_NODE_HANDLE ResourceTemplateNode;
> +
> + RdNode = NULL;
> +
> + Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> + }
> +
> + if (Register != NULL) {
> + Status = AmlCodeGenRdRegister (
> + Register->AddressSpaceId,
> + Register->RegisterBitWidth,
> + Register->RegisterBitOffset,
> + Register->Address,
> + Register->AccessSize,
> + NULL,
> + &RdNode
> + );
> + } else {
> + Status = AmlCodeGenRdRegister (
> + EFI_ACPI_6_4_SYSTEM_MEMORY,
> + 0,
> + 0,
> + 0,
> + 0,
> + NULL,
> + &RdNode
> + );
> + }
> +
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + RdNode = NULL;
> +
> + Status = AmlVarListAddTail (
> + (AML_NODE_HANDLE)PackageNode,
> + (AML_NODE_HANDLE)ResourceTemplateNode
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + return Status;
> +
> +error_handler:
> + if (RdNode != NULL) {
> + AmlDeleteTree ((AML_NODE_HANDLE)RdNode);
> + }
> +
> + if (ResourceTemplateNode != NULL) {
> + AmlDeleteTree ((AML_NODE_HANDLE)ResourceTemplateNode);
> + }
> +
> + return Status;
> +}
> +
> +/** Adds an integer or register to the package
> +
> + @ingroup CodeGenApis
> +
> + @param [in] Register If provided, register that will be added to package
> + @param [in] Integer If Register is NULL, integer that will be added to the package
> + @param [in] PackageNode Package to add value to
> +
> + @retval EFI_SUCCESS The function completed successfully.
> + @retval EFI_INVALID_PARAMETER Invalid parameter.
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +AmlAddRegisterOrIntegerToPackage (
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *Register OPTIONAL,
> + IN UINT32 Integer,
> + IN AML_OBJECT_NODE_HANDLE PackageNode
> + )
> +{
> + EFI_STATUS Status;
> + AML_OBJECT_NODE_HANDLE IntegerNode;
> +
> + IntegerNode = NULL;
> +
> + if (Register != NULL) {
> + Status = AmlAddRegisterToPackage (Register, PackageNode);
> + } else {
> + Status = AmlCodeGenInteger (Integer, &IntegerNode);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> + }
> +
> + Status = AmlVarListAddTail (
> + (AML_NODE_HANDLE)PackageNode,
> + (AML_NODE_HANDLE)IntegerNode
> + );
> + }
> +
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + if (IntegerNode != NULL) {
> + AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
> + }
> + }
> +
> + return Status;
> +}
> +
> +/** Create a _CPC node.
> +
> + Creates and optionally adds the following node
> + 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)
> + })
> +
> + If resource buffer is NULL then integer will be used.
> +
> + Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
> +
> + @ingroup CodeGenApis
> +
> + @param [in] HighestPerformanceBuffer If provided, buffer that indicates the highest level
> + of performance the processor.
> + @param [in] HighestPerformanceInteger Indicates the highest level of performance the processor,
> + used if buffer is NULL.
> + @param [in] NominalPerformanceBuffer If provided buffer that indicates the highest sustained
> + performance level of the processor.
> + @param [in] NominalPerformanceInteger Indicates the highest sustained performance level
> + of the processor, used if buffer is NULL.
> + @param [in] LowestNonlinearPerformanceBuffer If provided, buffer that indicates the lowest performance level
> + of the processor with non-linear power savings.
> + @param [in] LowestNonlinearPerformanceInteger Indicates the lowest performance level of the processor with
> + non-linear power savings, used if buffer is NULL.
> + @param [in] LowestPerformanceBuffer If provided, buffer that indicates the
> + lowest performance level of the processor.
> + @param [in] LowestPerformanceInteger Indicates the lowest performance level of the processor,
> + used if buffer is NULL.
> + @param [in] GuaranteedPerformanceRegister If provided, Guaranteed Performance Register Buffer.
> + @param [in] DesiredPerformanceRegister If provided, Desired Performance Register Buffer.
> + @param [in] MinimumPerformanceRegister If provided, Minimum Performance Register Buffer.
> + @param [in] MaximumPerformanceRegister If provided, Maximum Performance Register Buffer.
> + @param [in] PerformanceReductionToleranceRegister If provided, Performance Reduction Tolerance Register.
> + @param [in] TimeWindowRegister If provided, Time Window Register.
> + @param [in] CounterWraparoundTimeBuffer If provided, Counter Wraparound Time buffer.
> + @param [in] CounterWraparoundTimeInteger Counter Wraparound Time, used if buffer is NULL.
> + @param [in] ReferencePerformanceCounterRegister Reference Performance Counter Register.
> + @param [in] DeliveredPerformanceCounterRegister Delivered Performance Counter Register.
> + @param [in] PerformanceLimitedRegister Performance Limited Register.
> + @param [in] CPPCEnableRegister If provided, CPPC EnableRegister.
> + @param [in] AutonomousSelectionEnableBuffer If provided, Autonomous Selection Enable buffer.
> + @param [in] AutonomousSelectionEnableInteger Autonomous Selection Enable, used if buffer is NULL.
> + @param [in] AutonomousActivityWindowRegister If provided, AutonomousActivity-WindowRegister.
> + @param [in] EnergyPerformancePreferenceRegister If provided, EnergyPerformance-PreferenceRegister.
> + @param [in] ReferencePerformanceBuffer If provided, Reference Performance buffer.
> + @param [in] ReferencePerformanceInteger Reference Performance, used if buffer is NULL.
> + @param [in] LowestFrequencyBuffer If provided, Lowest Frequency buffer.
> + @param [in] LowestFrequencyInteger Lowest Frequency, used if buffer is NULL.
> + @param [in] NominalFrequencyBuffer If provided, NominalFrequencyBuffer buffer.
> + @param [in] NominalFrequencyInteger NominalFrequencyBuffer, used if buffer is NULL.
> + @param [in] ParentNode If provided, set ParentNode as the parent
> + of the node created.
> + @param [out] NewCpcNode If success and provided, contains the created node.
> +
> + @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
> +AmlCreateCpcNode (
> + /// The revision number of the _CPC package format.
> + IN UINT32 Revision,
> + /// Indicates the highest level of performance the processor
> + /// is theoretically capable of achieving.
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *HighestPerformanceBuffer OPTIONAL,
> + IN UINT32 HighestPerformanceInteger,
> + /// Indicates the highest sustained performance level of the processor.
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalPerformanceBuffer OPTIONAL,
> + IN UINT32 NominalPerformanceInteger,
> + /// Indicates the lowest performance level of the processor with non-linear power savings.
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestNonlinearPerformanceBuffer OPTIONAL,
> + IN UINT32 LowestNonlinearPerformanceInteger,
> + /// Indicates the lowest performance level of the processor..
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestPerformanceBuffer OPTIONAL,
> + IN UINT32 LowestPerformanceInteger,
> + /// Guaranteed Performance Register Buffer.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *GuaranteedPerformanceRegister OPTIONAL,
> + /// Desired Performance Register Buffer.
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DesiredPerformanceRegister,
> + /// Minimum Performance Register Buffer.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MinimumPerformanceRegister OPTIONAL,
> + /// Maximum Performance Register Buffer.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MaximumPerformanceRegister OPTIONAL,
> + /// Performance Reduction Tolerance Register.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceReductionToleranceRegister OPTIONAL,
> + /// Time Window Register.
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *TimeWindowRegister OPTIONAL,
> + /// Counter Wraparound Time
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CounterWraparoundTimeBuffer OPTIONAL,
> + IN UINT32 CounterWraparoundTimeInteger,
> + /// Reference Performance Counter Register
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceCounterRegister,
> + /// Delivered Performance Counter Register
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DeliveredPerformanceCounterRegister,
> + /// Performance Limited Register
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceLimitedRegister,
> + /// CPPC EnableRegister
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CPPCEnableRegister OPTIONAL,
> + /// Autonomous Selection Enable
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousSelectionEnableBuffer OPTIONAL,
> + IN UINT32 AutonomousSelectionEnableInteger,
> + /// AutonomousActivity-WindowRegister
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousActivityWindowRegister OPTIONAL,
> + /// EnergyPerformance-PreferenceRegister
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *EnergyPerformancePreferenceRegister OPTIONAL,
> + /// Reference Performance
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceBuffer OPTIONAL,
> + IN UINT32 ReferencePerformanceInteger,
> + /// Lowest Frequency
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestFrequencyBuffer OPTIONAL,
> + IN UINT32 LowestFrequencyInteger,
> + /// Nominal Frequency
> + /// Optional
> + IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalFrequencyBuffer OPTIONAL,
> + IN UINT32 NominalFrequencyInteger,
> + IN AML_NODE_HANDLE ParentNode OPTIONAL,
> + OUT AML_OBJECT_NODE_HANDLE *NewCpcNode OPTIONAL
> + )
> +{
> + EFI_STATUS Status;
> + AML_OBJECT_NODE_HANDLE CpcNode;
> + AML_OBJECT_NODE_HANDLE CpcPackage;
> + UINT32 NumberOfEntries;
> +
> + // Revision 3 per ACPI 6.4 specification
> + if (Revision == 3) {
> + // NumEntries 23 per ACPI 6.4 specification
> + NumberOfEntries = 23;
> + } else {
> + ASSERT (0);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (((HighestPerformanceBuffer == NULL) && (HighestPerformanceInteger == 0)) ||
> + ((NominalPerformanceBuffer == NULL) && (NominalPerformanceInteger == 0)) ||
> + ((LowestNonlinearPerformanceBuffer == NULL) && (LowestNonlinearPerformanceInteger == 0)) ||
> + ((LowestPerformanceBuffer == NULL) && (LowestPerformanceInteger == 0)) ||
> + (DesiredPerformanceRegister == NULL) ||
> + (ReferencePerformanceCounterRegister == NULL) ||
> + (DeliveredPerformanceCounterRegister == NULL) ||
> + (PerformanceLimitedRegister == NULL) ||
> + ((ParentNode == NULL) && (NewCpcNode == NULL)))
> + {
> + ASSERT (0);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + CpcPackage = NULL;
> +
> + Status = AmlCodeGenNamePackage ("_CPC", NULL, &CpcNode);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> + }
> +
> + // Get the Package object node of the _CPC node,
> + // which is the 2nd fixed argument (i.e. index 1).
> + CpcPackage = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
> + CpcNode,
> + EAmlParseIndexTerm1
> + );
> + if ((CpcPackage == NULL) ||
> + (AmlGetNodeType ((AML_NODE_HANDLE)CpcPackage) != EAmlNodeObject) ||
> + (!AmlNodeHasOpCode (CpcPackage, AML_PACKAGE_OP, 0)))
> + {
> + ASSERT (0);
> + Status = EFI_INVALID_PARAMETER;
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + NULL,
> + NumberOfEntries,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + NULL,
> + Revision,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + HighestPerformanceBuffer,
> + HighestPerformanceInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + NominalPerformanceBuffer,
> + NominalPerformanceInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + LowestNonlinearPerformanceBuffer,
> + LowestNonlinearPerformanceInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + LowestPerformanceBuffer,
> + LowestPerformanceInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (GuaranteedPerformanceRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (DesiredPerformanceRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (MinimumPerformanceRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (MaximumPerformanceRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (PerformanceReductionToleranceRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (TimeWindowRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + CounterWraparoundTimeBuffer,
> + CounterWraparoundTimeInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (ReferencePerformanceCounterRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (DeliveredPerformanceCounterRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (PerformanceLimitedRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (CPPCEnableRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + AutonomousSelectionEnableBuffer,
> + AutonomousSelectionEnableInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (AutonomousActivityWindowRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterToPackage (EnergyPerformancePreferenceRegister, CpcPackage);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + ReferencePerformanceBuffer,
> + ReferencePerformanceInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + LowestFrequencyBuffer,
> + LowestFrequencyInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = AmlAddRegisterOrIntegerToPackage (
> + NominalFrequencyBuffer,
> + NominalFrequencyInteger,
> + CpcPackage
> + );
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + Status = LinkNode (CpcNode, ParentNode, NewCpcNode);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> + goto error_handler;
> + }
> +
> + return Status;
> +
> +error_handler:
> + AmlDeleteTree ((AML_NODE_HANDLE)CpcNode);
> + return Status;
> +}
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object
2022-09-14 21:34 ` [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
2022-09-15 8:02 ` PierreGondois
@ 2022-09-15 14:00 ` Sami Mujawar
1 sibling, 0 replies; 8+ messages in thread
From: Sami Mujawar @ 2022-09-15 14:00 UTC (permalink / raw)
To: Jeff Brasen, devel
Cc: ardb+tianocore, Alexei.Fedorov, pierre.gondois, nd@arm.com
Hi Jeff,
Apologies for the delay in providing feedback. I was half way through
your patch series when you sent the v3.
For this patch please fine my feedbakc inline marked [SAMI]. I believe
some of these still apply for v3.
I will provide review feedback for the v3 series shortly.
Regards,
Sami Mujawar
On 14/09/2022 10:34 pm, Jeff Brasen wrote:
> Introduce the CM_ARM_CPC_INFO CmObj in the ArmNameSpaceObjects.
>
> This allows to describe CPC information, as described in ACPI 6.4,
>
> s8.4.7.1 "_CPC (Continuous Performance Control)".
>
>
>
> Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
>
> ---
>
> .../Include/ArmNameSpaceObjects.h | 148 ++++++++++++++++--
>
> .../ConfigurationManagerObjectParser.c | 79 ++++++++++
>
> 2 files changed, 210 insertions(+), 17 deletions(-)
>
>
>
> diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
>
> index 102e0f96be..d76cc08e14 100644
>
> --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
>
> +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
>
> @@ -63,6 +63,7 @@ typedef enum ArmObjectID {
>
> EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info
>
> EArmObjRmr, ///< 40 - Reserved Memory Range Node
>
> EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor
>
> + EArmObjCpcInfo, ///< 42 - Continuous Performance Control Info
>
> EArmObjMax
>
> } EARM_OBJECT_ID;
>
>
>
> @@ -97,99 +98,105 @@ typedef struct CmArmPowerManagementProfileInfo {
>
> */
>
> typedef struct CmArmGicCInfo {
>
> /// The GIC CPU Interface number.
>
> - UINT32 CPUInterfaceNumber;
>
> + UINT32 CPUInterfaceNumber;
>
>
>
> /** The ACPI Processor UID. This must match the
>
> _UID of the CPU Device object information described
>
> in the DSDT/SSDT for the CPU.
>
> */
>
> - UINT32 AcpiProcessorUid;
>
> + UINT32 AcpiProcessorUid;
>
>
>
> /** The flags field as described by the GICC structure
>
> in the ACPI Specification.
>
> */
>
> - UINT32 Flags;
>
> + UINT32 Flags;
>
>
>
> /** The parking protocol version field as described by
>
> the GICC structure in the ACPI Specification.
>
> */
>
> - UINT32 ParkingProtocolVersion;
>
> + UINT32 ParkingProtocolVersion;
>
>
>
> /** The Performance Interrupt field as described by
>
> the GICC structure in the ACPI Specification.
>
> */
>
> - UINT32 PerformanceInterruptGsiv;
>
> + UINT32 PerformanceInterruptGsiv;
>
>
>
> /** The CPU Parked address field as described by
>
> the GICC structure in the ACPI Specification.
>
> */
>
> - UINT64 ParkedAddress;
>
> + UINT64 ParkedAddress;
>
>
>
> /** The base address for the GIC CPU Interface
>
> as described by the GICC structure in the
>
> ACPI Specification.
>
> */
>
> - UINT64 PhysicalBaseAddress;
>
> + UINT64 PhysicalBaseAddress;
>
>
>
> /** The base address for GICV interface
>
> as described by the GICC structure in the
>
> ACPI Specification.
>
> */
>
> - UINT64 GICV;
>
> + UINT64 GICV;
>
>
>
> /** The base address for GICH interface
>
> as described by the GICC structure in the
>
> ACPI Specification.
>
> */
>
> - UINT64 GICH;
>
> + UINT64 GICH;
>
>
>
> /** The GICV maintenance interrupt
>
> as described by the GICC structure in the
>
> ACPI Specification.
>
> */
>
> - UINT32 VGICMaintenanceInterrupt;
>
> + UINT32 VGICMaintenanceInterrupt;
>
>
>
> /** The base address for GICR interface
>
> as described by the GICC structure in the
>
> ACPI Specification.
>
> */
>
> - UINT64 GICRBaseAddress;
>
> + UINT64 GICRBaseAddress;
>
>
>
> /** The MPIDR for the CPU
>
> as described by the GICC structure in the
>
> ACPI Specification.
>
> */
>
> - UINT64 MPIDR;
>
> + UINT64 MPIDR;
>
>
>
> /** The Processor Power Efficiency class
>
> as described by the GICC structure in the
>
> ACPI Specification.
>
> */
>
> - UINT8 ProcessorPowerEfficiencyClass;
>
> + UINT8 ProcessorPowerEfficiencyClass;
>
>
>
> /** Statistical Profiling Extension buffer overflow GSIV. Zero if
>
> unsupported by this processor. This field was introduced in
>
> ACPI 6.3 (MADT revision 5) and is therefore ignored when
>
> generating MADT revision 4 or lower.
>
> */
>
> - UINT16 SpeOverflowInterrupt;
>
> + UINT16 SpeOverflowInterrupt;
>
>
>
> /** The proximity domain to which the logical processor belongs.
>
> This field is used to populate the GICC affinity structure
>
> in the SRAT table.
>
> */
>
> - UINT32 ProximityDomain;
>
> + UINT32 ProximityDomain;
>
>
>
> /** The clock domain to which the logical processor belongs.
>
> This field is used to populate the GICC affinity structure
>
> in the SRAT table.
>
> */
>
> - UINT32 ClockDomain;
>
> + UINT32 ClockDomain;
>
>
>
> /** The GICC Affinity flags field as described by the GICC Affinity structure
>
> in the SRAT table.
>
> */
>
> - UINT32 AffinityFlags;
>
> + UINT32 AffinityFlags;
>
> +
>
> + /** Optional field: Reference Token for the Cpc info of this processor.
>
> + Token identifying a CM_ARM_OBJ_REF structure, itself referencing
>
> + CM_ARM_CPC_INFO objects.
>
> + */
>
> + CM_OBJECT_TOKEN CpcToken;
>
> } CM_ARM_GICC_INFO;
>
>
>
> /** A structure that describes the
>
> @@ -1070,6 +1077,113 @@ typedef struct CmArmRmrDescriptor {
>
> UINT64 Length;
>
> } CM_ARM_MEMORY_RANGE_DESCRIPTOR;
>
>
>
> +/** A structure that describes the Cpc information.
>
> +
>
> + Continuous Performance Control is described in DSDT/SSDT and associated
>
> + to cpus/clusters in the cpu topology.
>
> +
>
> + Unsupported Optional registers should be encoded with NULL resource
>
> + Register {(SystemMemory, 0, 0, 0, 0)}
>
> +
>
> + For values that support Integer or Buffer, integer will be used
>
> + if buffer is NULL resource.
>
> + If resource is not NULL then Integer must be 0
>
> +
>
> + Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
>
> +
>
> + ID: EArmObjCpcInfo
>
> +*/
>
> +typedef struct CmArmCpcInfo {
>
> + /// The revision number of the _CPC package format.
>
> + UINT32 Revision;
>
> +
>
> + /// Indicates the highest level of performance the processor
>
> + /// is theoretically capable of achieving.
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE HighestPerformanceBuffer;
>
> + UINT32 HighestPerformanceInteger;
>
> +
>
> + /// Indicates the highest sustained performance level of the processor.
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE NominalPerformanceBuffer;
>
> + UINT32 NominalPerformanceInteger;
>
> +
>
> + /// Indicates the lowest performance level of the processor with non-linear power savings.
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestNonlinearPerformanceBuffer;
>
> + UINT32 LowestNonlinearPerformanceInteger;
>
> +
>
> + /// Indicates the lowest performance level of the processor..
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestPerformanceBuffer;
>
> + UINT32 LowestPerformanceInteger;
>
> +
>
> + /// Guaranteed Performance Register Buffer.
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE GuaranteedPerformanceRegister;
>
> +
>
> + /// Desired Performance Register Buffer.
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DesiredPerformanceRegister;
>
> +
>
> + /// Minimum Performance Register Buffer.
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE MinimumPerformanceRegister;
>
> +
>
> + /// Maximum Performance Register Buffer.
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE MaximumPerformanceRegister;
>
> +
>
> + /// Performance Reduction Tolerance Register.
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE PerformanceReductionToleranceRegister;
>
> +
>
> + /// Time Window Register.
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE TimeWindowRegister;
>
> +
>
> + /// Counter Wraparound Time
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CounterWraparoundTimeBuffer;
>
> + UINT32 CounterWraparoundTimeInteger;
>
> +
>
> + /// Reference Performance Counter Register
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ReferencePerformanceCounterRegister;
>
> +
>
> + /// Delivered Performance Counter Register
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DeliveredPerformanceCounterRegister;
>
> +
>
> + /// Performance Limited Register
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE PerformanceLimitedRegister;
>
> +
>
> + /// CPPC EnableRegister
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CPPCEnableRegister;
>
> +
>
> + /// Autonomous Selection Enable
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE AutonomousSelectionEnableBuffer;
>
> + UINT32 AutonomousSelectionEnableInteger;
>
> +
>
> + /// AutonomousActivity-WindowRegister
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE AutonomousActivityWindowRegister;
>
> +
>
> + /// EnergyPerformance-PreferenceRegister
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE EnergyPerformancePreferenceRegister;
>
> +
>
> + /// Reference Performance
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ReferencePerformanceBuffer;
>
> + UINT32 ReferencePerformanceInteger;
>
> +
>
> + /// Lowest Frequency
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestFrequencyBuffer;
>
> + UINT32 LowestFrequencyInteger;
>
> +
>
> + /// Nominal Frequency
>
> + /// Optional
>
> + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE NominalFrequencyBuffer;
>
> + UINT32 NominalFrequencyInteger;
>
> +} CM_ARM_CPC_INFO;
>
> +
>
> #pragma pack()
>
>
>
> #endif // ARM_NAMESPACE_OBJECTS_H_
>
> diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
>
> index c1b21d24a4..e2c608443b 100644
>
> --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
>
> +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
>
> @@ -423,6 +423,83 @@ STATIC CONST CM_OBJ_PARSER CmPciInterruptMapInfoParser[] = {
>
> ARRAY_SIZE (CmArmGenericInterruptParser) },
>
> };
>
>
>
> +/** A parser for EArmObjCpcInfo.
>
> +*/
>
> +STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = {
[SAMI] I think the Revision field is missing here.
>
> + { "HighestPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "HighestPerformanceInteger", 4, "0x%llx", NULL },
[SAMI] Since this field is 32bit, I think the format specifier should be
"0x%x". Same applies to the other format specifiers below.
>
> + { "NominalPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "NominalPerformanceInteger", 4, "0x%llx", NULL },
>
> + { "LowestNonlinearPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "LowestNonlinearPerformanceInteger", 4, "0x%llx", NULL },
>
> + { "LowestPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "LowestPerformanceInteger", 4, "0x%llx", NULL },
>
> + { "GuaranteedPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "DesiredPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "MinimumPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "MaximumPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "PerformanceReductionToleranceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "TimeWindowRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "CounterWraparoundTimeBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "CounterWraparoundTimeInteger", 4, "0x%llx", NULL },
>
> + { "ReferencePerformanceCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "DeliveredPerformanceCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "PerformanceLimitedRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "CPPCEnableRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "AutonomousSelectionEnableBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "AutonomousSelectionEnableInteger", 4, "0x%llx", NULL },
>
> + { "AutonomousActivityWindowRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "EnergyPerformancePreferenceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "ReferencePerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "ReferencePerformanceInteger", 4, "0x%llx", NULL },
>
> + { "LowestFrequencyBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "LowestFrequencyInteger", 4, "0x%llx", NULL },
>
> + { "NominalFrequencyBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
>
> + NULL, NULL, AcpiGenericAddressParser,
>
> + ARRAY_SIZE (AcpiGenericAddressParser) },
>
> + { "NominalFrequencyInteger", 4, "0x%llx", NULL },
>
> +};
>
> +
>
> /** A parser for Arm namespace objects.
>
> */
>
> STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
>
> @@ -501,6 +578,8 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
>
> ARRAY_SIZE (CmArmPciAddressMapInfoParser) },
>
> { "EArmObjPciInterruptMapInfo", CmPciInterruptMapInfoParser,
>
> ARRAY_SIZE (CmPciInterruptMapInfoParser) },
>
> + { "EArmObjCpcInfo", CmArmCpcInfoParser,
>
> + ARRAY_SIZE (CmArmCpcInfoParser) },
>
> { "EArmObjMax", NULL, 0 },
>
> };
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-09-15 14:00 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-14 21:34 [PATCH v2 0/3] DynamicTablesPkg: _CPC support Jeff Brasen
2022-09-14 21:34 ` [PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
2022-09-15 8:02 ` PierreGondois
2022-09-15 14:00 ` Sami Mujawar
2022-09-14 21:34 ` [PATCH v2 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries Jeff Brasen
2022-09-15 8:04 ` PierreGondois
2022-09-14 21:34 ` [PATCH v2 3/3] DynamicTablesPkg: SSDT CPU _CPC generator Jeff Brasen
2022-09-15 8:03 ` PierreGondois
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox