From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 021DBD8094F for ; Mon, 29 Jan 2024 12:08:42 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=qkzPhN/b3SsnaOMARw8pgj4t7LQDZxXQRe5kI3m18OE=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1706530121; v=1; b=JjayfpmJdf9FpjXTAKPhM4/IjmanCKdXQLWnIg7Aouf2ZPm+IQKI/MhlZzupH8zVZlOlFD0L sbvKOWxXju0vibi3wluhkiObk3qB9ncel/FYfrtM+WWUthx+Jieh2enCsvRBgZZGcDGhwXqDZBG zCUlqcUOk/LcKPmkbILEmNqs= X-Received: by 127.0.0.2 with SMTP id h0eJYY7687511xL5Dp79fNLf; Mon, 29 Jan 2024 04:08:41 -0800 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web10.13244.1706530120839826237 for ; Mon, 29 Jan 2024 04:08:40 -0800 X-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 4A2BB15DB; Mon, 29 Jan 2024 04:09:24 -0800 (PST) X-Received: from cam-smtp0.cambridge.arm.com (e126645.nice.arm.com [10.34.100.129]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C80CA3F5A1; Mon, 29 Jan 2024 04:08:39 -0800 (PST) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Thomas Abraham , Pierre Gondois Subject: [edk2-devel] [PATCH v6 3/3] Platform/ARM: Juno: Generate _CPC objects for JunoR2 Date: Mon, 29 Jan 2024 13:08:25 +0100 Message-Id: <20240129120825.139755-4-Pierre.Gondois@arm.com> In-Reply-To: <20240129120825.139755-1-Pierre.Gondois@arm.com> References: <20240129120825.139755-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: BHPbPGm76FmWyJBbJZ0Z7JuUx7686176AA= Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=JjayfpmJ; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=arm.com (policy=none) From: Pierre Gondois The SsdtCpuTopologyGenerator can generate _CPC objects. This is done by querying the SCP for the relevant performance state information through SCMI. CM_ARM_CPC_INFO are then populated and used to generate _CPC objects in the Ssdt Cpu topology. Use the DynamicTablesScmiInfoLib and add the handling to generate _CPC information. Note that using _CPC is only possible if SCP is correctly tuned to advertise performance levels on an abstract and unified scale. A basic check is done to prevent the _CPC generation otherwise. Perf level values used for testing: - little CPUs OPPs: [181, 322, 383] * 1000 - big CPUs OPPs: [512, 833, 1024] * 1000 Also make use of the newly added PcdDevelopmentPlatformRelaxations and add a new ENABLE_CPC build parameter ('-D ENABLE_CPC') to enable CPC generation. Signed-off-by: Pierre Gondois --- Platform/ARM/JunoPkg/ArmJuno.dsc | 11 + .../ConfigurationManager.c | 252 +++++++++++++++++- .../ConfigurationManager.h | 7 + .../ConfigurationManagerDxe.inf | 3 + 4 files changed, 270 insertions(+), 3 deletions(-) diff --git a/Platform/ARM/JunoPkg/ArmJuno.dsc b/Platform/ARM/JunoPkg/ArmJ= uno.dsc index 1ea0aba2655f..7fe796a53433 100644 --- a/Platform/ARM/JunoPkg/ArmJuno.dsc +++ b/Platform/ARM/JunoPkg/ArmJuno.dsc @@ -83,6 +83,9 @@ [BuildOptions] !ifdef DYNAMIC_TABLES_FRAMEWORK *_*_*_PLATFORM_FLAGS =3D -DDYNAMIC_TABLES_FRAMEWORK !endif +!ifdef ENABLE_CPC + *_*_*_PLATFORM_FLAGS =3D -DENABLE_CPC +!endif =20 ########################################################################= ######## # @@ -203,6 +206,14 @@ [PcdsFixedAtBuild.common] # gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x20 =20 +!ifdef ENABLE_CPC + # + # Allow some relaxation on some specific points for the platforms that= desire it. + # BIT0: Allow the absence of some registers in the _CPC object. + # + gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdDevelopmentPlatformRelaxations= |0x1 +!endif + [PcdsPatchableInModule] # Console Resolution (Full HD) gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1920 diff --git a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManag= erDxe/ConfigurationManager.c b/Platform/ARM/JunoPkg/ConfigurationManager/= ConfigurationManagerDxe/ConfigurationManager.c index efc4c0ddf87c..636645ed2821 100644 --- a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManager.c +++ b/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManager.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -901,6 +902,173 @@ HandleCmObjectSearchPlatformRepo ( return Status; } =20 +/** Clear Cpc information. + + If populating _CPC information fails, remove GicC tokens pointing + to Cpc CmObj to avoid creating corrupted _CPC objects. + + @param [in] PlatformRepo Platfom Info repository. + + @retval EFI_SUCCESS Success. +**/ +STATIC +EFI_STATUS +EFIAPI +ClearCpcInfo ( + EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo + ) +{ + CM_ARM_GICC_INFO *GicCInfo; + + GicCInfo =3D (CM_ARM_GICC_INFO*)&PlatformRepo->GicCInfo; + + GicCInfo[0].CpcToken =3D CM_NULL_TOKEN; + GicCInfo[1].CpcToken =3D CM_NULL_TOKEN; + GicCInfo[2].CpcToken =3D CM_NULL_TOKEN; + GicCInfo[3].CpcToken =3D CM_NULL_TOKEN; + GicCInfo[4].CpcToken =3D CM_NULL_TOKEN; + GicCInfo[5].CpcToken =3D CM_NULL_TOKEN; + + return EFI_SUCCESS; +} + +/** Use the SCMI protocol to populate CPC objects dynamically. + + @param [in] PlatformRepo Platfom Info repository. + @param [in] DomainId Id of the DVFS domain to probe. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_UNSUPPORTED Not supported. + @retval !(EFI_SUCCESS) An error occured. +**/ +STATIC +EFI_STATUS +EFIAPI +PopulateCpcInfo ( + EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo, + IN UINT32 DomainId + ) +{ + EFI_STATUS Status; + CM_ARM_GICC_INFO *GicCInfo; + AML_CPC_INFO *CpcInfo; + + if ((PlatformRepo =3D=3D NULL) || + ((DomainId !=3D PSD_BIG_DOMAIN_ID) && + (DomainId !=3D PSD_LITTLE_DOMAIN_ID))) { + Status =3D EFI_INVALID_PARAMETER; + ASSERT_EFI_ERROR (Status); + return Status; + } + + CpcInfo =3D &PlatformRepo->CpcInfo[DomainId]; + GicCInfo =3D (CM_ARM_GICC_INFO*)&PlatformRepo->GicCInfo; + + Status =3D DynamicTablesScmiInfoGetFastChannel ( + PlatformRepo->PsdInfo[DomainId].Domain, + CpcInfo + ); + if (EFI_ERROR (Status)) { + return Status; + } + + /* CPPC must advertise performances on a 'continuous, abstract, unit-l= ess + performance scale', i.e. CPU performances on an asymmetric platform + nust be represented on a unified scale. + CPU performance values are obtained from SCP through SCMI and adver= tised + to the OS via the _CPC objects. SCP currently maps performance requ= ests + to frequency requests. + Thus, SCP must be modified to advertise (and correctly handle) + performance values on a unified scale. + + Check that SCP is using a unified scale by checking that the advert= ised + lowest/nominal frequencies are not the default ones. + */ + if (((DomainId =3D=3D PSD_BIG_DOMAIN_ID) && + (CpcInfo->LowestPerformanceInteger =3D=3D 600000000) && + (CpcInfo->NominalPerformanceInteger =3D=3D 1000000000)) || + ((DomainId =3D=3D PSD_LITTLE_DOMAIN_ID) && + (CpcInfo->LowestPerformanceInteger =3D=3D 450000000) && + (CpcInfo->NominalPerformanceInteger =3D=3D 800000000))) { + return EFI_UNSUPPORTED; + } + + // Juno R2's lowest/nominal frequencies. + // Nominal frequency !=3D Highest frequency. + if (DomainId =3D=3D PSD_BIG_DOMAIN_ID) { + CpcInfo->LowestFrequencyInteger =3D 600; + CpcInfo->NominalFrequencyInteger =3D 1000; + } else { + CpcInfo->LowestFrequencyInteger =3D 450; + CpcInfo->NominalFrequencyInteger =3D 800; + } + + // The mapping Psd -> CPUs is available here. + if (DomainId =3D=3D PSD_BIG_DOMAIN_ID) { + GicCInfo[0].CpcToken =3D (CM_OBJECT_TOKEN)CpcInfo; + GicCInfo[1].CpcToken =3D (CM_OBJECT_TOKEN)CpcInfo; + } else { + GicCInfo[2].CpcToken =3D (CM_OBJECT_TOKEN)CpcInfo; + GicCInfo[3].CpcToken =3D (CM_OBJECT_TOKEN)CpcInfo; + GicCInfo[4].CpcToken =3D (CM_OBJECT_TOKEN)CpcInfo; + GicCInfo[5].CpcToken =3D (CM_OBJECT_TOKEN)CpcInfo; + } + + /* + Arm advises to use FFH to the following registers which uses AMU cou= nters: + - ReferencePerformanceCounterRegister + - DeliveredPerformanceCounterRegister + Cf. Arm Functional Fixed Hardware Specification + s3.2 Performance management and Collaborative Processor Performance = Control + + AMU is not supported by the Juno, so clear these registers. + */ + CpcInfo->ReferencePerformanceCounterRegister.AddressSpaceId =3D EFI_AC= PI_6_5_SYSTEM_MEMORY; + CpcInfo->ReferencePerformanceCounterRegister.RegisterBitWidth =3D 0; + CpcInfo->ReferencePerformanceCounterRegister.RegisterBitOffset =3D 0; + CpcInfo->ReferencePerformanceCounterRegister.AccessSize =3D 0; + CpcInfo->ReferencePerformanceCounterRegister.Address =3D 0; + + CpcInfo->DeliveredPerformanceCounterRegister.AddressSpaceId =3D EFI_AC= PI_6_5_SYSTEM_MEMORY; + CpcInfo->DeliveredPerformanceCounterRegister.RegisterBitWidth =3D 0; + CpcInfo->DeliveredPerformanceCounterRegister.RegisterBitOffset =3D 0; + CpcInfo->DeliveredPerformanceCounterRegister.AccessSize =3D 0; + CpcInfo->DeliveredPerformanceCounterRegister.Address =3D 0; + + return Status; +} + +/** Iterate over the PSD Domains and try to populate the Cpc objects. +**/ +STATIC +VOID +EFIAPI +PopulateCpcObjects ( + EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo + ) +{ + EFI_STATUS Status; + UINT32 Index; + BOOLEAN CpcFailed; + + CpcFailed =3D FALSE; + for (Index =3D 0; Index < PSD_DOMAIN_COUNT; Index++) { + Status =3D PopulateCpcInfo (PlatformRepo, Index); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "WARN: Could not populate _CPC.\n")); + CpcFailed =3D TRUE; + break; + } + } + + if (CpcFailed) { + // _CPC information is not mandatory and SCP might not support some + // SCMI requests. Failing should not prevent from booting. + ClearCpcInfo (PlatformRepo); + } +} + /** Initialize the platform configuration repository. =20 @param [in] This Pointer to the Configuration Manager Protocol= . @@ -920,6 +1088,23 @@ InitializePlatformRepository ( =20 GetJunoRevision (PlatformRepo->JunoRevision); DEBUG ((DEBUG_INFO, "Juno Rev =3D 0x%x\n", PlatformRepo->JunoRevision)= ); + + /// + /// 1. + /// _CPC was only tested on Juno R2, so only enable support for this v= ersion. + /// + /// 2. + /// Some _CPC registers cannot be populated for the Juno: + /// - PerformanceLimitedRegister + /// - ReferencePerformanceCounterRegister + /// - DeliveredPerformanceCounterRegister + /// Only build _CPC objects if relaxation regarding these registers + /// is allowed. + if ((PlatformRepo->JunoRevision =3D=3D JUNO_REVISION_R2) && + (PcdGet64(PcdDevelopmentPlatformRelaxations) & BIT0)) { + PopulateCpcObjects (PlatformRepo); + } + return EFI_SUCCESS; } =20 @@ -1212,6 +1397,55 @@ GetPsdInfo ( return EFI_NOT_FOUND; } =20 +/** Return Cpc Info. + + @param [in] This Pointer to the Configuration Manager P= rotocol. + @param [in] CmObjectId The Object ID of the CM object request= ed + @param [in] SearchToken A unique token for identifying the req= uested + CM_ARM_PCI_INTERRUPT_MAP_INFO object. + @param [in, out] CmObject Pointer to the Configuration Manager O= bject + descriptor describing the requested Ob= ject. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object information is not= found. +**/ +EFI_STATUS +EFIAPI +GetCpcInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This, + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN SearchToken, + IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject + ) +{ + EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo; + UINT32 TotalObjCount; + UINT32 ObjIndex; + + if ((This =3D=3D NULL) || (CmObject =3D=3D NULL)) { + ASSERT (This !=3D NULL); + ASSERT (CmObject !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + PlatformRepo =3D This->PlatRepoInfo; + + TotalObjCount =3D ARRAY_SIZE (PlatformRepo->CpcInfo); + + for (ObjIndex =3D 0; ObjIndex < TotalObjCount; ObjIndex++) { + if (SearchToken =3D=3D (CM_OBJECT_TOKEN)&PlatformRepo->CpcInfo[ObjIn= dex]) { + CmObject->ObjectId =3D CmObjectId; + CmObject->Size =3D sizeof (PlatformRepo->CpcInfo[ObjIndex]); + CmObject->Data =3D (VOID*)&PlatformRepo->CpcInfo[ObjIndex]; + CmObject->Count =3D 1; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + /** Return a list of Configuration Manager object references pointed to = by the given input token. =20 @@ -1633,6 +1867,19 @@ GetArmNameSpaceObject ( ); break; =20 + case EArmObjCpcInfo: + Status =3D HandleCmObjectRefByToken ( + This, + CmObjectId, + PlatformRepo->CpcInfo, + sizeof (PlatformRepo->CpcInfo), + ARRAY_SIZE (PlatformRepo->CpcInfo), + Token, + GetCpcInfo, + CmObject + ); + break; + default: { Status =3D EFI_NOT_FOUND; DEBUG (( @@ -1821,7 +2068,7 @@ ConfigurationManagerDxeInitialize ( " Status =3D %r\n", Status )); - goto error_handler; + return Status; } =20 Status =3D InitializePlatformRepository ( @@ -1836,6 +2083,5 @@ ConfigurationManagerDxeInitialize ( )); } =20 -error_handler: - return Status; + return EFI_SUCCESS; } diff --git a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManag= erDxe/ConfigurationManager.h b/Platform/ARM/JunoPkg/ConfigurationManager/= ConfigurationManagerDxe/ConfigurationManager.h index e58e9cbecb23..78452295a180 100644 --- a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManager.h +++ b/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManager.h @@ -303,6 +303,13 @@ typedef struct PlatformRepositoryInfo { // Power domains CM_ARM_PSD_INFO PsdInfo[PSD_DOMAIN_COUNT]; =20 + // + // Dynamically populated fields from here. + // + + // Cpc info (1 for each PSD domain) + CM_ARM_CPC_INFO CpcInfo[PSD_DOMAIN_COUNT]; + /// Juno Board Revision UINT32 JunoRevision; } EDKII_PLATFORM_REPOSITORY_INFO; diff --git a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManag= erDxe/ConfigurationManagerDxe.inf b/Platform/ARM/JunoPkg/ConfigurationMan= ager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf index 91bffe8d5d82..dea475375688 100644 --- a/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManagerDxe.inf +++ b/Platform/ARM/JunoPkg/ConfigurationManager/ConfigurationManagerDxe/C= onfigurationManagerDxe.inf @@ -35,6 +35,7 @@ [Packages] =20 [LibraryClasses] ArmPlatformLib + DynamicTablesScmiInfoLib PrintLib UefiBootServicesTableLib UefiDriverEntryPoint @@ -76,6 +77,8 @@ [FixedPcd] gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate =20 + gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdDevelopmentPlatformRelaxations + [Pcd] =20 [Depex] --=20 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114693): https://edk2.groups.io/g/devel/message/114693 Mute This Topic: https://groups.io/mt/104029703/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-