Hi Pierre,

I have some minor feedback inline marked [SAMI].

With that fixed,
Reviewed-by: Sami Mujawar <[email protected]>

Regards,

Sami Mujawar

On 12/12/2023, 09:30, "Pierre Gondois" <[email protected] 
<mailto:[email protected]>> wrote:


The SCP holds some power information that could be advertised
through the _CPC object. The communication with the SCP is done
through SCMI protocols (c.f. ArmScmiDxe).


Use the SCMI protocols to query information and feed it to
the DynamicTablesPkg.


Acked-by: Leif Lindholm <[email protected] 
<mailto:[email protected]>>
Signed-off-by: Pierre Gondois <[email protected] 
<mailto:[email protected]>>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 1 +
DynamicTablesPkg/DynamicTablesPkg.dec | 3 +
DynamicTablesPkg/DynamicTablesPkg.dsc | 1 +
.../Library/DynamicTablesScmiInfoLib.h | 33 ++
.../DynamicTablesScmiInfoLib.c | 297 ++++++++++++++++++
.../DynamicTablesScmiInfoLib.inf | 31 ++
6 files changed, 366 insertions(+)
create mode 100644 DynamicTablesPkg/Include/Library/DynamicTablesScmiInfoLib.h
create mode 100644 
DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.c
create mode 100644 
DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf


diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc 
b/DynamicTablesPkg/DynamicTables.dsc.inc
index 9d4312c4e87d..41947012b92b 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -15,6 +15,7 @@ [BuildOptions]
[LibraryClasses.common]


AcpiHelperLib|DynamicTablesPkg/Library/Common/AcpiHelperLib/AcpiHelperLib.inf


AmlLib|DynamicTablesPkg/Library/Common/AmlLib/AmlLib.inf


+ 
DynamicTablesScmiInfoLib|DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf


SsdtPcieSupportLib|DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.inf


SsdtSerialPortFixupLib|DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf


TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf


diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec 
b/DynamicTablesPkg/DynamicTablesPkg.dec
index cfbcbb9569f1..aa422ce9f6fd 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dec
+++ b/DynamicTablesPkg/DynamicTablesPkg.dec
@@ -42,6 +42,9 @@ [LibraryClasses]
## @libraryclass Defines a set of SMBIOS string helper methods.


SmbiosStringTableLib|Include/Library/SmbiosStringTableLib.h






+ ## @libraryclass Defines a set of APIs to populate CmObj using SCMI.


+ DynamicTablesScmiInfoLib|Include/Library/DynamicTablesScmiInfoLib.h


+


[Protocols]


# Configuration Manager Protocol GUID


gEdkiiConfigurationManagerProtocolGuid = { 0xd85a4835, 0x5a82, 0x4894, { 0xac, 
0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } }


diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc 
b/DynamicTablesPkg/DynamicTablesPkg.dsc
index bd5084a9008f..853ea2a1e4c2 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dsc
+++ b/DynamicTablesPkg/DynamicTablesPkg.dsc
@@ -39,6 +39,7 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64]
PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf






[Components.common]


+ DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf
[SAMI] DynamicTablesScmiInfoLib is specific for Arm architecture. 
Can you check if this and other changes in this patch need to go in a 
Components.[ARM|AARCH64) section, please?
[/SAMI]


DynamicTablesPkg/Library/Common/AcpiHelperLib/AcpiHelperLib.inf


DynamicTablesPkg/Library/Common/AmlLib/AmlLib.inf


DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.inf


diff --git a/DynamicTablesPkg/Include/Library/DynamicTablesScmiInfoLib.h 
b/DynamicTablesPkg/Include/Library/DynamicTablesScmiInfoLib.h
new file mode 100644
index 000000000000..ff6b47d51fe8
--- /dev/null
+++ b/DynamicTablesPkg/Include/Library/DynamicTablesScmiInfoLib.h
@@ -0,0 +1,33 @@
+/** @file


+ Arm SCMI Info Library.


+


+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>


+


+ SPDX-License-Identifier: BSD-2-Clause-Patent


+**/


+


+#ifndef ARM_SCMI_INFO_LIB_H_


+#define ARM_SCMI_INFO_LIB_H_


+


+#include <ConfigurationManagerObject.h>


+


+/** Populate a AML_CPC_INFO object based on SCMI information.


+


+ @param[in] DomainId Identifier for the performance domain.


+ @param[out] CpcInfo If success, this structure was populated from


+ information queried to the SCP.


+


+ @retval EFI_SUCCESS Success.


+ @retval EFI_DEVICE_ERROR Device error.


+ @retval EFI_INVALID_PARAMETER Invalid parameter.


+ @retval EFI_TIMEOUT Time out.


+ @retval EFI_UNSUPPORTED Unsupported.


+**/


+EFI_STATUS


+EFIAPI


+DynamicTablesScmiInfoGetFastChannel (


+ IN UINT32 DomainId,


+ OUT AML_CPC_INFO *CpcInfo


+ );


+


+#endif // ARM_SCMI_INFO_LIB_H_


diff --git 
a/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.c 
b/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.c
new file mode 100644
index 000000000000..da5bc1895778
--- /dev/null
+++ 
b/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.c
@@ -0,0 +1,297 @@
+/** @file


+ Arm SCMI Info Library.


+


+ Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.<BR>


+


+ Arm Functional Fixed Hardware Specification:


+ - https://developer.arm.com/documentation/den0048/latest/ 
<https://developer.arm.com/documentation/den0048/latest/>


+


+ SPDX-License-Identifier: BSD-2-Clause-Patent


+**/


+


+#include <Library/AcpiLib.h>


+#include <Library/DynamicTablesScmiInfoLib.h>


+#include <Library/DebugLib.h>


+#include <Library/MemoryAllocationLib.h>


+#include <Library/UefiBootServicesTableLib.h>


+#include <Protocol/ArmScmi.h>


+#include <Protocol/ArmScmiPerformanceProtocol.h>


+


+/** Arm FFH registers


+


+ Cf. Arm Functional Fixed Hardware Specification


+ s3.2 Performance management and Collaborative Processor Performance Control


+*/


+#define ARM_FFH_DELIVERED_PERF_COUNTER_REGISTER 0x0


+#define ARM_FFH_REFERENCE_PERF_COUNTER_REGISTER 0x1


+


+/// Arm SCMI performance protocol.


+STATIC SCMI_PERFORMANCE_PROTOCOL *ScmiPerfProtocol;


+


+/** Arm SCMI Info Library constructor.


+


+ @param ImageHandle Image of the loaded driver.


+ @param SystemTable Pointer to the System Table.


+


+ @retval EFI_SUCCESS Success.


+ @retval EFI_DEVICE_ERROR Device error.


+ @retval EFI_INVALID_PARAMETER Invalid parameter.


+ @retval EFI_NOT_FOUND Not Found


+ @retval EFI_TIMEOUT Timeout.


+ @retval EFI_UNSUPPORTED Unsupported.


+**/


+EFI_STATUS


+EFIAPI


+DynamicTablesScmiInfoLibConstructor (


+ IN EFI_HANDLE ImageHandle,


+ IN EFI_SYSTEM_TABLE *SystemTable


+ )


+{


+ EFI_STATUS Status;


+ UINT32 Version;


+


+ Status = gBS->LocateProtocol (


+ &gArmScmiPerformanceProtocolGuid,


+ NULL,


+ (VOID **)&ScmiPerfProtocol


+ );


+ if (EFI_ERROR (Status)) {


+ return Status;


+ }


+


+ Status = ScmiPerfProtocol->GetVersion (ScmiPerfProtocol, &Version);


+ if (EFI_ERROR (Status)) {


+ return Status;


+ }


+


+ // FastChannels were added in SCMI v2.0 spec.


+ if (Version < PERFORMANCE_PROTOCOL_VERSION_V2) {


+ DEBUG ((


+ DEBUG_ERROR,


+ "DynamicTablesScmiInfoLib requires SCMI version > 2.0\n"


+ ));


+ return EFI_UNSUPPORTED;


+ }


+


+ return Status;


+}


+


+/** Get the OPPs/performance states of a power domain.


+


+ This function is a wrapper around the SCMI PERFORMANCE_DESCRIBE_LEVELS


+ command. The list of discrete performance states is returned in a buffer


+ that must be freed by the caller.


+


+ @param[in] DomainId Identifier for the performance domain.


+ @param[out] LevelArray If success, pointer to the list of list of


+ performance state. This memory must be freed by


+ the caller.


+ @param[out] LevelArrayCount If success, contains the number of states in


+ LevelArray.


+


+ @retval EFI_SUCCESS Success.


+ @retval EFI_DEVICE_ERROR Device error.


+ @retval EFI_INVALID_PARAMETER Invalid parameter.


+ @retval EFI_TIMEOUT Time out.


+ @retval EFI_UNSUPPORTED Unsupported.


+**/


+STATIC


+EFI_STATUS


+EFIAPI


+DynamicTablesScmiInfoDescribeLevels (


+ IN UINT32 DomainId,


+ OUT SCMI_PERFORMANCE_LEVEL **LevelArray,


+ OUT UINT32 *LevelArrayCount


+ )


+{


+ EFI_STATUS Status;


+ SCMI_PERFORMANCE_LEVEL *Array;


+ UINT32 Count;


+ UINT32 Size;


+


+ if ((ScmiPerfProtocol == NULL) ||


+ (LevelArray == NULL) ||


+ (LevelArrayCount == NULL))


+ {


+ return EFI_INVALID_PARAMETER;


+ }


+


+ // First call to get the number of levels.


+ Size = 0;


+ Status = ScmiPerfProtocol->DescribeLevels (


+ ScmiPerfProtocol,


+ DomainId,


+ &Count,


+ &Size,


+ NULL


+ );


+ if (Status != EFI_BUFFER_TOO_SMALL) {


+ // EFI_SUCCESS is not a valid option.


+ if (Status == EFI_SUCCESS) {


+ return EFI_INVALID_PARAMETER;


+ } else {


+ return Status;


+ }


+ }


+


+ Array = AllocateZeroPool (Size);


+ if (Array == NULL) {


+ return EFI_OUT_OF_RESOURCES;


+ }


+


+ // Second call to get the descriptions of the levels.


+ Status = ScmiPerfProtocol->DescribeLevels (


+ ScmiPerfProtocol,


+ DomainId,


+ &Count,


+ &Size,


+ Array


+ );


+ if (EFI_ERROR (Status)) {


+ return Status;


+ }


+


+ *LevelArray = Array;


+ *LevelArrayCount = Count;


+


+ return Status;


+}


+


+/** Populate a AML_CPC_INFO object based on SCMI information.


+


+ @param[in] DomainId Identifier for the performance domain.


+ @param[out] CpcInfo If success, this structure was populated from


+ information queried to the SCP.


+


+ @retval EFI_SUCCESS Success.


+ @retval EFI_DEVICE_ERROR Device error.


+ @retval EFI_INVALID_PARAMETER Invalid parameter.


+ @retval EFI_TIMEOUT Time out.


+ @retval EFI_UNSUPPORTED Unsupported.


+**/


+EFI_STATUS


+EFIAPI


+DynamicTablesScmiInfoGetFastChannel (


+ IN UINT32 DomainId,


+ OUT AML_CPC_INFO *CpcInfo


+ )


+{


+ EFI_STATUS Status;


+ SCMI_PERFORMANCE_FASTCHANNEL FcLevelGet;


+ SCMI_PERFORMANCE_FASTCHANNEL FcLimitsSet;


+ SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES DomainAttributes;


+


+ SCMI_PERFORMANCE_LEVEL *LevelArray;


+ UINT32 LevelCount;


+


+ UINT64 FcLevelGetAddr;


+ UINT64 FcLimitsMaxSetAddr;


+ UINT64 FcLimitsMinSetAddr;


+


+ if ((ScmiPerfProtocol == NULL) ||


+ (CpcInfo == NULL))


+ {


+ return EFI_INVALID_PARAMETER;


+ }


+


+ Status = ScmiPerfProtocol->DescribeFastchannel (


+ ScmiPerfProtocol,


+ DomainId,


+ ScmiMessageIdPerformanceLevelSet,


+ &FcLevelGet


+ );


+ if (EFI_ERROR (Status)) {


+ return Status;


+ }


+


+ Status = ScmiPerfProtocol->DescribeFastchannel (


+ ScmiPerfProtocol,


+ DomainId,


+ ScmiMessageIdPerformanceLimitsSet,


+ &FcLimitsSet


+ );


+ if (EFI_ERROR (Status)) {


+ return Status;


+ }


+


+ Status = ScmiPerfProtocol->GetDomainAttributes (


+ ScmiPerfProtocol,


+ DomainId,


+ &DomainAttributes


+ );


+ if (EFI_ERROR (Status)) {


+ return Status;


+ }


+


+ Status = DynamicTablesScmiInfoDescribeLevels (DomainId, &LevelArray, 
&LevelCount);


+ if (EFI_ERROR (Status)) {


+ return Status;


+ }


+


+ /* Do some safety checks.


+ Only support FastChannels (and not doorbells) as this is


+ the only mechanism supported by SCP.


+ FcLimits[Get|Set] require 2 UINT32 values (max, then min) and


+ FcLimits[Get|Set] require 1 UINT32 value (level).


+ */


+ if ((FcLevelGet.ChanSize != sizeof (UINT32)) ||


+ ((FcLevelGet.Attributes & SCMI_PERF_FC_ATTRIB_HAS_DOORBELL) ==


+ SCMI_PERF_FC_ATTRIB_HAS_DOORBELL) ||


+ (FcLimitsSet.ChanSize != 2 * sizeof (UINT32)) ||


+ ((FcLimitsSet.Attributes & SCMI_PERF_FC_ATTRIB_HAS_DOORBELL) ==


+ SCMI_PERF_FC_ATTRIB_HAS_DOORBELL))


+ {


+ Status = EFI_INVALID_PARAMETER;


+ goto exit_handler;


+ }


+


+ FcLevelGetAddr = ((UINT64)FcLevelGet.ChanAddrHigh << 32) |


+ FcLevelGet.ChanAddrLow;


+ FcLimitsMaxSetAddr = ((UINT64)FcLimitsSet.ChanAddrHigh << 32) |


+ FcLimitsSet.ChanAddrLow;


+ FcLimitsMinSetAddr = FcLimitsMaxSetAddr + 0x4;


+


+ CpcInfo->Revision = EFI_ACPI_6_5_AML_CPC_REVISION;


+ CpcInfo->HighestPerformanceInteger = LevelArray[LevelCount - 1].Level;


+ CpcInfo->NominalPerformanceInteger = DomainAttributes.SustainedPerfLevel;


+ CpcInfo->LowestNonlinearPerformanceInteger = LevelArray[0].Level;


+ CpcInfo->LowestPerformanceInteger = LevelArray[0].Level;


+


+ CpcInfo->DesiredPerformanceRegister.AddressSpaceId = 
EFI_ACPI_6_5_SYSTEM_MEMORY;


+ CpcInfo->DesiredPerformanceRegister.RegisterBitWidth = 32;


+ CpcInfo->DesiredPerformanceRegister.RegisterBitOffset = 0;


+ CpcInfo->DesiredPerformanceRegister.AccessSize = EFI_ACPI_6_5_DWORD;


+ CpcInfo->DesiredPerformanceRegister.Address = FcLevelGetAddr;
[SAMI] Can we use ARM_GAS32() to populate the DesiredPerformanceRegister and 
other registers below, please?


+


+ CpcInfo->MinimumPerformanceRegister.AddressSpaceId = 
EFI_ACPI_6_5_SYSTEM_MEMORY;


+ CpcInfo->MinimumPerformanceRegister.RegisterBitWidth = 32;


+ CpcInfo->MinimumPerformanceRegister.RegisterBitOffset = 0;


+ CpcInfo->MinimumPerformanceRegister.AccessSize = EFI_ACPI_6_5_DWORD;


+ CpcInfo->MinimumPerformanceRegister.Address = FcLimitsMinSetAddr;


+


+ CpcInfo->MaximumPerformanceRegister.AddressSpaceId = 
EFI_ACPI_6_5_SYSTEM_MEMORY;


+ CpcInfo->MaximumPerformanceRegister.RegisterBitWidth = 32;


+ CpcInfo->MaximumPerformanceRegister.RegisterBitOffset = 0;


+ CpcInfo->MaximumPerformanceRegister.AccessSize = EFI_ACPI_6_5_DWORD;


+ CpcInfo->MaximumPerformanceRegister.Address = FcLimitsMaxSetAddr;


+


+ CpcInfo->ReferencePerformanceCounterRegister.AddressSpaceId = 
EFI_ACPI_6_5_FUNCTIONAL_FIXED_HARDWARE;


+ CpcInfo->ReferencePerformanceCounterRegister.RegisterBitWidth = 0x40;


+ CpcInfo->ReferencePerformanceCounterRegister.RegisterBitOffset = 0;


+ CpcInfo->ReferencePerformanceCounterRegister.AccessSize = 
ARM_FFH_REFERENCE_PERF_COUNTER_REGISTER;


+ CpcInfo->ReferencePerformanceCounterRegister.Address = 0x4;


+


+ CpcInfo->DeliveredPerformanceCounterRegister.AddressSpaceId = 
EFI_ACPI_6_5_FUNCTIONAL_FIXED_HARDWARE;


+ CpcInfo->DeliveredPerformanceCounterRegister.RegisterBitWidth = 0x40;


+ CpcInfo->DeliveredPerformanceCounterRegister.RegisterBitOffset = 0;


+ CpcInfo->DeliveredPerformanceCounterRegister.AccessSize = 
ARM_FFH_DELIVERED_PERF_COUNTER_REGISTER;


+ CpcInfo->DeliveredPerformanceCounterRegister.Address = 0x4;


+


+ // SCMI should advertise performance values on a unified scale. So frequency


+ // values are not available. LowestFrequencyInteger and


+ // NominalFrequencyInteger are populated in the ConfigurationManager.


+


+exit_handler:


+ FreePool (LevelArray);


+ return Status;


+}


diff --git 
a/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf
 
b/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf
new file mode 100644
index 000000000000..d49277f82bc3
--- /dev/null
+++ 
b/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf
@@ -0,0 +1,31 @@
+## @file


+# Arm SCMI Info Library.


+#


+# Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.


+#


+# SPDX-License-Identifier: BSD-2-Clause-Patent


+##


+


+[Defines]


+ INF_VERSION = 0x0001001B


+ BASE_NAME = DynamicTablesScmiInfoLib


+ FILE_GUID = 1A7CDB04-9FFC-40DA-A87C-A5ACADAF8136


+ VERSION_STRING = 1.0


+ MODULE_TYPE = DXE_DRIVER


+ LIBRARY_CLASS = DynamicTablesScmiInfoLib


+ CONSTRUCTOR = DynamicTablesScmiInfoLibConstructor


+


+[Sources]


+ DynamicTablesScmiInfoLib.c


+


+[Packages]


+ ArmPkg/ArmPkg.dec


+ DynamicTablesPkg/DynamicTablesPkg.dec


+ EmbeddedPkg/EmbeddedPkg.dec


+ MdePkg/MdePkg.dec


+


+[Protocols]


+ gArmScmiPerformanceProtocolGuid ## CONSUMES


+


+[Depex]


+ gArmScmiPerformanceProtocolGuid


-- 
2.25.1







-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114386): https://edk2.groups.io/g/devel/message/114386
Mute This Topic: https://groups.io/mt/103127055/21656
Group Owner: [email protected]
Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to