public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v4 0/3] DynamicTablesPkg: _CPC support
@ 2022-09-19 22:01 Jeff Brasen
  2022-09-19 22:01 ` [PATCH v4 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Jeff Brasen @ 2022-09-19 22:01 UTC (permalink / raw)
  To: devel
  Cc: ardb+tianocore, Alexei.Fedorov, pierre.gondois, nd, sami.mujawar,
	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.
v3 - Minor review feedback
v4 - Convert CpcInfo to structure and use that for APIs

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             |  60 ++-
 DynamicTablesPkg/Include/Library/AmlCpcInfo.h | 124 +++++
 .../Include/Library/AmlLib/AmlLib.h           |  54 ++
 .../SsdtCpuTopologyGenerator.c                | 133 ++++-
 .../Common/AmlLib/CodeGen/AmlCodeGen.c        | 476 ++++++++++++++++++
 .../ConfigurationManagerObjectParser.c        |  80 +++
 6 files changed, 904 insertions(+), 23 deletions(-)
 create mode 100644 DynamicTablesPkg/Include/Library/AmlCpcInfo.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v4 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object
  2022-09-19 22:01 [PATCH v4 0/3] DynamicTablesPkg: _CPC support Jeff Brasen
@ 2022-09-19 22:01 ` Jeff Brasen
  2022-09-21 14:54   ` PierreGondois
  2022-09-19 22:01 ` [PATCH v4 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries Jeff Brasen
  2022-09-19 22:01 ` [PATCH v4 3/3] DynamicTablesPkg: SSDT CPU _CPC generator Jeff Brasen
  2 siblings, 1 reply; 7+ messages in thread
From: Jeff Brasen @ 2022-09-19 22:01 UTC (permalink / raw)
  To: devel
  Cc: ardb+tianocore, Alexei.Fedorov, pierre.gondois, nd, sami.mujawar,
	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             |  60 ++++++---
 DynamicTablesPkg/Include/Library/AmlCpcInfo.h | 124 ++++++++++++++++++
 .../ConfigurationManagerObjectParser.c        |  80 +++++++++++
 3 files changed, 247 insertions(+), 17 deletions(-)
 create mode 100644 DynamicTablesPkg/Include/Library/AmlCpcInfo.h

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 102e0f96be..ea5bf81070 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -14,6 +14,7 @@
 #define ARM_NAMESPACE_OBJECTS_H_
 
 #include <StandardNameSpaceObjects.h>
+#include <Library/AmlCpcInfo.h>
 
 #pragma pack(1)
 
@@ -63,6 +64,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 +99,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 +1078,24 @@ 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 AML_CPC_INFO CM_ARM_CPC_INFO;
+
 #pragma pack()
 
 #endif // ARM_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Include/Library/AmlCpcInfo.h b/DynamicTablesPkg/Include/Library/AmlCpcInfo.h
new file mode 100644
index 0000000000..8981c22954
--- /dev/null
+++ b/DynamicTablesPkg/Include/Library/AmlCpcInfo.h
@@ -0,0 +1,124 @@
+/** @file
+
+  Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef AML_CPC_INFO_H_
+#define AML_CPC_INFO_H_
+
+#include <IndustryStandard/Acpi.h>
+
+#pragma pack(1)
+
+/** 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)
+
+**/
+
+typedef struct AmlCpcInfo {
+  /// 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;
+} AML_CPC_INFO;
+
+#pragma pack()
+
+#endif //AML_CPC_INFO_H_
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index c1b21d24a4..cda3696557 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
@@ -423,6 +423,84 @@ STATIC CONST CM_OBJ_PARSER  CmPciInterruptMapInfoParser[] = {
     ARRAY_SIZE (CmArmGenericInterruptParser) },
 };
 
+/** A parser for EArmObjCpcInfo.
+*/
+STATIC CONST CM_OBJ_PARSER  CmArmCpcInfoParser[] = {
+  { "Revision",                              4,                                               "0x%lx", NULL },
+  { "HighestPerformanceBuffer",              sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "HighestPerformanceInteger",             4,                                               "0x%lx", NULL },
+  { "NominalPerformanceBuffer",              sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "NominalPerformanceInteger",             4,                                               "0x%lx", NULL },
+  { "LowestNonlinearPerformanceBuffer",      sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "LowestNonlinearPerformanceInteger",     4,                                               "0x%lx", NULL },
+  { "LowestPerformanceBuffer",               sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "LowestPerformanceInteger",              4,                                               "0x%lx", NULL },
+  { "GuaranteedPerformanceRegister",         sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "DesiredPerformanceRegister",            sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "MinimumPerformanceRegister",            sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "MaximumPerformanceRegister",            sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "PerformanceReductionToleranceRegister", sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "TimeWindowRegister",                    sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "CounterWraparoundTimeBuffer",           sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "CounterWraparoundTimeInteger",          4,                                               "0x%lx", NULL },
+  { "ReferencePerformanceCounterRegister",   sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "DeliveredPerformanceCounterRegister",   sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "PerformanceLimitedRegister",            sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "CPPCEnableRegister",                    sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "AutonomousSelectionEnableBuffer",       sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "AutonomousSelectionEnableInteger",      4,                                               "0x%lx", NULL },
+  { "AutonomousActivityWindowRegister",      sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "EnergyPerformancePreferenceRegister",   sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "ReferencePerformanceBuffer",            sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "ReferencePerformanceInteger",           4,                                               "0x%lx", NULL },
+  { "LowestFrequencyBuffer",                 sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "LowestFrequencyInteger",                4,                                               "0x%lx", NULL },
+  { "NominalFrequencyBuffer",                sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
+    NULL, NULL, AcpiGenericAddressParser,
+    ARRAY_SIZE (AcpiGenericAddressParser) },
+  { "NominalFrequencyInteger",               4,                                               "0x%lx", NULL },
+};
+
 /** A parser for Arm namespace objects.
 */
 STATIC CONST CM_OBJ_PARSER_ARRAY  ArmNamespaceObjectParser[] = {
@@ -501,6 +579,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] 7+ messages in thread

* [PATCH v4 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries
  2022-09-19 22:01 [PATCH v4 0/3] DynamicTablesPkg: _CPC support Jeff Brasen
  2022-09-19 22:01 ` [PATCH v4 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
@ 2022-09-19 22:01 ` Jeff Brasen
  2022-09-20 14:54   ` PierreGondois
  2022-09-19 22:01 ` [PATCH v4 3/3] DynamicTablesPkg: SSDT CPU _CPC generator Jeff Brasen
  2 siblings, 1 reply; 7+ messages in thread
From: Jeff Brasen @ 2022-09-19 22:01 UTC (permalink / raw)
  To: devel
  Cc: ardb+tianocore, Alexei.Fedorov, pierre.gondois, nd, sami.mujawar,
	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           |  54 ++
 .../Common/AmlLib/CodeGen/AmlCodeGen.c        | 476 ++++++++++++++++++
 2 files changed, 530 insertions(+)

diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
index 39968660f2..ebaccba811 100644
--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -37,6 +37,7 @@
 */
 
 #include <IndustryStandard/Acpi.h>
+#include <Library/AmlCpcInfo.h>
 
 #ifndef AML_HANDLE
 
@@ -1336,6 +1337,59 @@ 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]  CpcInfo               CpcInfo object
+  @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 (
+  IN  AML_CPC_INFO            *CpcInfo,
+  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..fc85c467ec 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -14,6 +14,7 @@
 #include <AmlEncoding/Aml.h>
 #include <Api/AmlApiHelper.h>
 #include <CodeGen/AmlResourceDataCodeGen.h>
+#include <Library/AmlCpcInfo.h>
 #include <Tree/AmlNode.h>
 #include <Tree/AmlTree.h>
 #include <String/AmlString.h>
@@ -2850,3 +2851,478 @@ 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;
+}
+
+/** 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;
+}
+
+/** 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) && !IsNullGenericAddress (Register)) {
+    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]  CpcInfo               CpcInfo object
+  @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 (
+  IN  AML_CPC_INFO            *CpcInfo,
+  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;
+
+  if ((CpcInfo == NULL) ||
+      ((ParentNode == NULL) && (NewCpcNode == NULL)))
+  {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Revision 3 per ACPI 6.4 specification
+  if (CpcInfo->Revision == 3) {
+    // NumEntries 23 per ACPI 6.4 specification
+    NumberOfEntries = 23;
+  } else {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((CpcInfo == NULL) ||
+      (IsNullGenericAddress (&CpcInfo->HighestPerformanceBuffer) &&
+       (CpcInfo->HighestPerformanceInteger == 0)) ||
+      (IsNullGenericAddress (&CpcInfo->NominalPerformanceBuffer) &&
+       (CpcInfo->NominalPerformanceInteger == 0)) ||
+      (IsNullGenericAddress (&CpcInfo->LowestNonlinearPerformanceBuffer) &&
+       (CpcInfo->LowestNonlinearPerformanceInteger == 0)) ||
+      (IsNullGenericAddress (&CpcInfo->LowestPerformanceBuffer) &&
+       (CpcInfo->LowestPerformanceInteger == 0)) ||
+      IsNullGenericAddress (&CpcInfo->DesiredPerformanceRegister) ||
+      IsNullGenericAddress (&CpcInfo->ReferencePerformanceCounterRegister) ||
+      IsNullGenericAddress (&CpcInfo->DeliveredPerformanceCounterRegister) ||
+      IsNullGenericAddress (&CpcInfo->PerformanceLimitedRegister))
+  {
+    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,
+             CpcInfo->Revision,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->HighestPerformanceBuffer,
+             CpcInfo->HighestPerformanceInteger,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->NominalPerformanceBuffer,
+             CpcInfo->NominalPerformanceInteger,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->LowestNonlinearPerformanceBuffer,
+             CpcInfo->LowestNonlinearPerformanceInteger,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->LowestPerformanceBuffer,
+             CpcInfo->LowestPerformanceInteger,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->GuaranteedPerformanceRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->DesiredPerformanceRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->MinimumPerformanceRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->MaximumPerformanceRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->PerformanceReductionToleranceRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->TimeWindowRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->CounterWraparoundTimeBuffer,
+             CpcInfo->CounterWraparoundTimeInteger,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->ReferencePerformanceCounterRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->DeliveredPerformanceCounterRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->PerformanceLimitedRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->CPPCEnableRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->AutonomousSelectionEnableBuffer,
+             CpcInfo->AutonomousSelectionEnableInteger,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->AutonomousActivityWindowRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterToPackage (&CpcInfo->EnergyPerformancePreferenceRegister, CpcPackage);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->ReferencePerformanceBuffer,
+             CpcInfo->ReferencePerformanceInteger,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->LowestFrequencyBuffer,
+             CpcInfo->LowestFrequencyInteger,
+             CpcPackage
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto error_handler;
+  }
+
+  Status = AmlAddRegisterOrIntegerToPackage (
+             &CpcInfo->NominalFrequencyBuffer,
+             CpcInfo->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] 7+ messages in thread

* [PATCH v4 3/3] DynamicTablesPkg: SSDT CPU _CPC generator
  2022-09-19 22:01 [PATCH v4 0/3] DynamicTablesPkg: _CPC support Jeff Brasen
  2022-09-19 22:01 ` [PATCH v4 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
  2022-09-19 22:01 ` [PATCH v4 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries Jeff Brasen
@ 2022-09-19 22:01 ` Jeff Brasen
  2 siblings, 0 replies; 7+ messages in thread
From: Jeff Brasen @ 2022-09-19 22:01 UTC (permalink / raw)
  To: devel
  Cc: ardb+tianocore, Alexei.Fedorov, pierre.gondois, nd, sami.mujawar,
	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                | 133 +++++++++++++++++-
 1 file changed, 127 insertions(+), 6 deletions(-)

diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
index 8561f48e1f..22422aef75 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,93 @@ WriteAslName (
   return EFI_SUCCESS;
 }
 
+/** 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,
+             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 +678,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 +1044,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 +1072,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);
+        break;
+      }
+    }
   } // for
 
   return Status;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries
  2022-09-19 22:01 ` [PATCH v4 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries Jeff Brasen
@ 2022-09-20 14:54   ` PierreGondois
  2022-09-20 17:48     ` Jeff Brasen
  0 siblings, 1 reply; 7+ messages in thread
From: PierreGondois @ 2022-09-20 14:54 UTC (permalink / raw)
  To: Jeff Brasen, devel; +Cc: ardb+tianocore, Alexei.Fedorov, nd, sami.mujawar

Hello Jeff,
Just 2 minors comments. Maybe Sami will have more.
Otherwise, for the 3 patches:
Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>

Regards,
Pierre

On 9/20/22 00:01, 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           |  54 ++
>   .../Common/AmlLib/CodeGen/AmlCodeGen.c        | 476 ++++++++++++++++++
>   2 files changed, 530 insertions(+)
> 
> diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> index 39968660f2..ebaccba811 100644
> --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h

[snip]

> +
> +/** 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;
> +

I think that with IsNullGenericAddress(), the first
  (Register != NULL)
is not necessary.

> +  if ((Register != NULL) && !IsNullGenericAddress (Register)) {
> +    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]  CpcInfo               CpcInfo object
> +  @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 (
> +  IN  AML_CPC_INFO            *CpcInfo,
> +  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;
> +
> +  if ((CpcInfo == NULL) ||
> +      ((ParentNode == NULL) && (NewCpcNode == NULL)))
> +  {
> +    ASSERT (0);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  // Revision 3 per ACPI 6.4 specification
> +  if (CpcInfo->Revision == 3) {
> +    // NumEntries 23 per ACPI 6.4 specification
> +    NumberOfEntries = 23;
> +  } else {
> +    ASSERT (0);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +

It seems CpcInfo is already checked earlier. It seems the checks below could
be part of the other checks above (where ParentNode is checked).

> +  if ((CpcInfo == NULL) ||
> +      (IsNullGenericAddress (&CpcInfo->HighestPerformanceBuffer) &&
> +       (CpcInfo->HighestPerformanceInteger == 0)) ||
> +      (IsNullGenericAddress (&CpcInfo->NominalPerformanceBuffer) &&
> +       (CpcInfo->NominalPerformanceInteger == 0)) ||
> +      (IsNullGenericAddress (&CpcInfo->LowestNonlinearPerformanceBuffer) &&
> +       (CpcInfo->LowestNonlinearPerformanceInteger == 0)) ||
> +      (IsNullGenericAddress (&CpcInfo->LowestPerformanceBuffer) &&
> +       (CpcInfo->LowestPerformanceInteger == 0)) ||
> +      IsNullGenericAddress (&CpcInfo->DesiredPerformanceRegister) ||
> +      IsNullGenericAddress (&CpcInfo->ReferencePerformanceCounterRegister) ||
> +      IsNullGenericAddress (&CpcInfo->DeliveredPerformanceCounterRegister) ||
> +      IsNullGenericAddress (&CpcInfo->PerformanceLimitedRegister))
> +  {
> +    ASSERT (0);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  CpcPackage = NULL;
> +
> +  Status = AmlCodeGenNamePackage ("_CPC", NULL, &CpcNode);
> +  if (EFI_ERROR (Status)) {
> +    ASSERT_EFI_ERROR (Status);
> +    return Status;
> +  }
> +

[snip]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries
  2022-09-20 14:54   ` PierreGondois
@ 2022-09-20 17:48     ` Jeff Brasen
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Brasen @ 2022-09-20 17:48 UTC (permalink / raw)
  To: Pierre Gondois, devel@edk2.groups.io
  Cc: ardb+tianocore@kernel.org, Alexei.Fedorov@arm.com, nd@arm.com,
	sami.mujawar@arm.com

Thanks will fix those in v5. Will see if Sami has any other comments before pushing these.


-Jeff


> -----Original Message-----
> From: Pierre Gondois <pierre.gondois@arm.com>
> Sent: Tuesday, September 20, 2022 8:54 AM
> To: Jeff Brasen <jbrasen@nvidia.com>; devel@edk2.groups.io
> Cc: ardb+tianocore@kernel.org; Alexei.Fedorov@arm.com; nd@arm.com;
> sami.mujawar@arm.com
> Subject: Re: [PATCH v4 2/3] DynamicTablesPkg: AML Code generation to add
> _CPC entries
> 
> External email: Use caution opening links or attachments
> 
> 
> Hello Jeff,
> Just 2 minors comments. Maybe Sami will have more.
> Otherwise, for the 3 patches:
> Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>
> 
> Regards,
> Pierre
> 
> On 9/20/22 00:01, 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           |  54 ++
> >   .../Common/AmlLib/CodeGen/AmlCodeGen.c        | 476
> ++++++++++++++++++
> >   2 files changed, 530 insertions(+)
> >
> > diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> > b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> > index 39968660f2..ebaccba811 100644
> > --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> > +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
> 
> [snip]
> 
> > +
> > +/** 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;
> > +
> 
> I think that with IsNullGenericAddress(), the first
>   (Register != NULL)
> is not necessary.
> 
> > +  if ((Register != NULL) && !IsNullGenericAddress (Register)) {
> > +    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]  CpcInfo               CpcInfo object
> > +  @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 (
> > +  IN  AML_CPC_INFO            *CpcInfo,
> > +  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;
> > +
> > +  if ((CpcInfo == NULL) ||
> > +      ((ParentNode == NULL) && (NewCpcNode == NULL)))  {
> > +    ASSERT (0);
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  // Revision 3 per ACPI 6.4 specification  if (CpcInfo->Revision ==
> > + 3) {
> > +    // NumEntries 23 per ACPI 6.4 specification
> > +    NumberOfEntries = 23;
> > +  } else {
> > +    ASSERT (0);
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> 
> It seems CpcInfo is already checked earlier. It seems the checks below could
> be part of the other checks above (where ParentNode is checked).
> 
> > +  if ((CpcInfo == NULL) ||
> > +      (IsNullGenericAddress (&CpcInfo->HighestPerformanceBuffer) &&
> > +       (CpcInfo->HighestPerformanceInteger == 0)) ||
> > +      (IsNullGenericAddress (&CpcInfo->NominalPerformanceBuffer) &&
> > +       (CpcInfo->NominalPerformanceInteger == 0)) ||
> > +      (IsNullGenericAddress (&CpcInfo-
> >LowestNonlinearPerformanceBuffer) &&
> > +       (CpcInfo->LowestNonlinearPerformanceInteger == 0)) ||
> > +      (IsNullGenericAddress (&CpcInfo->LowestPerformanceBuffer) &&
> > +       (CpcInfo->LowestPerformanceInteger == 0)) ||
> > +      IsNullGenericAddress (&CpcInfo->DesiredPerformanceRegister) ||
> > +      IsNullGenericAddress (&CpcInfo-
> >ReferencePerformanceCounterRegister) ||
> > +      IsNullGenericAddress (&CpcInfo-
> >DeliveredPerformanceCounterRegister) ||
> > +      IsNullGenericAddress (&CpcInfo->PerformanceLimitedRegister))
> > +  {
> > +    ASSERT (0);
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  CpcPackage = NULL;
> > +
> > +  Status = AmlCodeGenNamePackage ("_CPC", NULL, &CpcNode);  if
> > + (EFI_ERROR (Status)) {
> > +    ASSERT_EFI_ERROR (Status);
> > +    return Status;
> > +  }
> > +
> 
> [snip]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object
  2022-09-19 22:01 ` [PATCH v4 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
@ 2022-09-21 14:54   ` PierreGondois
  0 siblings, 0 replies; 7+ messages in thread
From: PierreGondois @ 2022-09-21 14:54 UTC (permalink / raw)
  To: Jeff Brasen, devel; +Cc: ardb+tianocore, Alexei.Fedorov, nd, sami.mujawar

One last thing:

On 9/20/22 00:01, 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             |  60 ++++++---
>   DynamicTablesPkg/Include/Library/AmlCpcInfo.h | 124 ++++++++++++++++++
>   .../ConfigurationManagerObjectParser.c        |  80 +++++++++++
>   3 files changed, 247 insertions(+), 17 deletions(-)
>   create mode 100644 DynamicTablesPkg/Include/Library/AmlCpcInfo.h
> 
> diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
> index 102e0f96be..ea5bf81070 100644
> --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
> +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
> @@ -14,6 +14,7 @@
>   #define ARM_NAMESPACE_OBJECTS_H_
>   
>   #include <StandardNameSpaceObjects.h>
> +#include <Library/AmlCpcInfo.h>
>   
>   #pragma pack(1)
>   
> @@ -63,6 +64,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 +99,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;

This field should be added to the GicC CmObjectParser.

>   } CM_ARM_GICC_INFO;
>   
>   /** A structure that describes the

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-09-21 14:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-19 22:01 [PATCH v4 0/3] DynamicTablesPkg: _CPC support Jeff Brasen
2022-09-19 22:01 ` [PATCH v4 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object Jeff Brasen
2022-09-21 14:54   ` PierreGondois
2022-09-19 22:01 ` [PATCH v4 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries Jeff Brasen
2022-09-20 14:54   ` PierreGondois
2022-09-20 17:48     ` Jeff Brasen
2022-09-19 22:01 ` [PATCH v4 3/3] DynamicTablesPkg: SSDT CPU _CPC generator Jeff Brasen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox