mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-29 16:44:10 +02:00
DynamicTablesPkg: Add DynamicTablesScmiInfoLib
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 <quic_llindhol@quicinc.com> Signed-off-by: Pierre Gondois <pierre.gondois@arm.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
This commit is contained in:
parent
fc04cfd119
commit
b2c4916344
@ -21,6 +21,9 @@
|
|||||||
TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
|
TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
|
||||||
SmbiosStringTableLib|DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf
|
SmbiosStringTableLib|DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.AARCH64]
|
||||||
|
DynamicTablesScmiInfoLib|DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf
|
||||||
|
|
||||||
[Components.common]
|
[Components.common]
|
||||||
#
|
#
|
||||||
# Dynamic Tables Manager Dxe
|
# Dynamic Tables Manager Dxe
|
||||||
|
@ -42,6 +42,10 @@
|
|||||||
## @libraryclass Defines a set of SMBIOS string helper methods.
|
## @libraryclass Defines a set of SMBIOS string helper methods.
|
||||||
SmbiosStringTableLib|Include/Library/SmbiosStringTableLib.h
|
SmbiosStringTableLib|Include/Library/SmbiosStringTableLib.h
|
||||||
|
|
||||||
|
[LibraryClasses.AARCH64]
|
||||||
|
## @libraryclass Defines a set of APIs to populate CmObj using SCMI.
|
||||||
|
DynamicTablesScmiInfoLib|Include/Library/DynamicTablesScmiInfoLib.h
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
# Configuration Manager Protocol GUID
|
# Configuration Manager Protocol GUID
|
||||||
gEdkiiConfigurationManagerProtocolGuid = { 0xd85a4835, 0x5a82, 0x4894, { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } }
|
gEdkiiConfigurationManagerProtocolGuid = { 0xd85a4835, 0x5a82, 0x4894, { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } }
|
||||||
|
@ -51,6 +51,9 @@
|
|||||||
[Components.ARM, Components.AARCH64]
|
[Components.ARM, Components.AARCH64]
|
||||||
DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
|
DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
|
||||||
|
|
||||||
|
[Components.AARCH64]
|
||||||
|
DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf
|
||||||
|
|
||||||
[BuildOptions]
|
[BuildOptions]
|
||||||
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
|
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
|
||||||
|
|
||||||
|
33
DynamicTablesPkg/Include/Library/DynamicTablesScmiInfoLib.h
Normal file
33
DynamicTablesPkg/Include/Library/DynamicTablesScmiInfoLib.h
Normal file
@ -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_
|
@ -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/
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user