From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web12.7368.1663229091800045303 for ; Thu, 15 Sep 2022 01:04:52 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: pierre.gondois@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D4C551692; Thu, 15 Sep 2022 01:04:57 -0700 (PDT) Received: from [10.34.100.114] (pierre123.nice.arm.com [10.34.100.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 737753F73B; Thu, 15 Sep 2022 01:04:50 -0700 (PDT) Message-ID: <4c1b3cb3-586f-2e79-6a3b-f131a5b0361f@arm.com> Date: Thu, 15 Sep 2022 10:04:46 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.11.0 Subject: Re: [PATCH v2 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries To: Jeff Brasen , devel@edk2.groups.io Cc: ardb+tianocore@kernel.org, Sami.Mujawar@arm.com, Alexei.Fedorov@arm.com References: <7e67444227e4ae3c29da18aded47507c0dbd8603.1663191097.git.jbrasen@nvidia.com> From: "PierreGondois" In-Reply-To: <7e67444227e4ae3c29da18aded47507c0dbd8603.1663191097.git.jbrasen@nvidia.com> Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Hello Jeff, This patch looks good to me: Reviewed-by: Pierre Gondois 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 > --- > .../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; > +}