From nobody Wed Feb 5 08:55:48 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114419+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114419+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1706195965; cv=none; d=zohomail.com; s=zohoarc; b=bGflCPjXT4yJTRmunFihfPhsICDNEVp/F10w6UYhoZDsHi/Chkpa+cWBRbAZTyuKfuT9FLFsq5HnPCTdbQ2+If851eljeT3BIgY/hp3cHympCB1GShM3CG6JEkVilL3/lKT3qIuyJGgHpqLyVqqPRr4x6JHlzeDbngi/TWDkfcA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706195965; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=cmWX3CAiIDSSAvbFV65zqKLFUu5wdAlb4pi4qUGck94=; b=Xfh7ihBh0EhAXhcsI54wr5PJty3Y91EcQHzttt4+PABUTL7nPPrt+ZgEsSq8JaT6t0gEjW5bryNHV8kOX228cNFz4rput3aLHaI1nfrV+oVY2xux8+iVd/9n+nnTzoKm/NynNkjc8CqXTPTrx+kiRWXFpEYh6RcSIu8fnTRJVrU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114419+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706195965657426.9144625211377; Thu, 25 Jan 2024 07:19:25 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=XzNTjNiO7YYjHX5pzreucWf6i7FOgSlSUd9Y9dULG5w=; 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=1706195965; v=1; b=oJf6Wh/y1q3j9kZvmAi9y4zZ6WGUhA12arbggXxOG9vFoa7+81xdobJ9swapwEc2wd+PblFL KyVk+IuPuuCmFnGlIBC+2AXxVmFR+TJZnpRBy4egVyyvMYjQtuCTjDZWeITAzHI/9n5Jp/Syx0Q fqYqffYDnU2vvtC6YU/gbvZE= X-Received: by 127.0.0.2 with SMTP id xmsbYY1788612xj6x4PuI8LM; Thu, 25 Jan 2024 07:19:25 -0800 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.20315.1706195964812568583 for ; Thu, 25 Jan 2024 07:19:24 -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 0771F1476; Thu, 25 Jan 2024 07:20:09 -0800 (PST) X-Received: from e126645.arm.com (unknown [10.57.47.22]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 676A03F5A1; Thu, 25 Jan 2024 07:19:23 -0800 (PST) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Pierre Gondois Subject: [edk2-devel] [PATCH v5 09/11] DynamicTablesPkg: Add DynamicTablesScmiInfoLib Date: Thu, 25 Jan 2024 16:18:48 +0100 Message-Id: <20240125151850.620749-10-pierre.gondois@arm.com> In-Reply-To: <20240125151850.620749-1-pierre.gondois@arm.com> References: <20240125151850.620749-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: UK38vVd0HX6EDPlMqurvgaA5x1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706195966713100022 Content-Type: text/plain; charset="utf-8" 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 Signed-off-by: Pierre Gondois --- DynamicTablesPkg/DynamicTables.dsc.inc | 3 + DynamicTablesPkg/DynamicTablesPkg.dec | 4 + DynamicTablesPkg/DynamicTablesPkg.dsc | 3 + .../Library/DynamicTablesScmiInfoLib.h | 33 ++ .../DynamicTablesScmiInfoLib.c | 297 ++++++++++++++++++ .../DynamicTablesScmiInfoLib.inf | 31 ++ 6 files changed, 371 insertions(+) create mode 100644 DynamicTablesPkg/Include/Library/DynamicTablesScmiInfoL= ib.h create mode 100644 DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/Dynam= icTablesScmiInfoLib.c create mode 100644 DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/Dynam= icTablesScmiInfoLib.inf diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/Dyna= micTables.dsc.inc index 8c99574097ad..19ca62d6a85c 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -21,6 +21,9 @@ [LibraryClasses.common] TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelpe= rLib.inf SmbiosStringTableLib|DynamicTablesPkg/Library/Common/SmbiosStringTableLi= b/SmbiosStringTableLib.inf =20 +[LibraryClasses.AARCH64] + DynamicTablesScmiInfoLib|DynamicTablesPkg/Library/DynamicTablesScmiInfoL= ib/DynamicTablesScmiInfoLib.inf + [Components.common] # # Dynamic Tables Manager Dxe diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/Dynam= icTablesPkg.dec index cfbcbb9569f1..25355ace884b 100644 --- a/DynamicTablesPkg/DynamicTablesPkg.dec +++ b/DynamicTablesPkg/DynamicTablesPkg.dec @@ -42,6 +42,10 @@ [LibraryClasses] ## @libraryclass Defines a set of SMBIOS string helper methods. SmbiosStringTableLib|Include/Library/SmbiosStringTableLib.h =20 +[LibraryClasses.AARCH64] + ## @libraryclass Defines a set of APIs to populate CmObj using SCMI. + DynamicTablesScmiInfoLib|Include/Library/DynamicTablesScmiInfoLib.h + [Protocols] # Configuration Manager Protocol GUID gEdkiiConfigurationManagerProtocolGuid =3D { 0xd85a4835, 0x5a82, 0x4894,= { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } } diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc b/DynamicTablesPkg/Dynam= icTablesPkg.dsc index 2f35ac82f20b..cf06f0731a23 100644 --- a/DynamicTablesPkg/DynamicTablesPkg.dsc +++ b/DynamicTablesPkg/DynamicTablesPkg.dsc @@ -51,6 +51,9 @@ [Components.common] [Components.ARM, Components.AARCH64] DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf =20 +[Components.AARCH64] + DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoL= ib.inf + [BuildOptions] *_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES =20 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef ARM_SCMI_INFO_LIB_H_ +#define ARM_SCMI_INFO_LIB_H_ + +#include + +/** 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/DynamicTable= sScmiInfoLib.c b/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicT= ablesScmiInfoLib.c new file mode 100644 index 000000000000..da5bc1895778 --- /dev/null +++ b/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiIn= foLib.c @@ -0,0 +1,297 @@ +/** @file + Arm SCMI Info Library. + + Copyright (c) 2022 - 2023, Arm Limited. All rights reserved.
+ + Arm Functional Fixed Hardware Specification: + - https://developer.arm.com/documentation/den0048/latest/ + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include + +/** Arm FFH registers + + Cf. Arm Functional Fixed Hardware Specification + s3.2 Performance management and Collaborative Processor Performance Cont= rol +*/ +#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 =3D gBS->LocateProtocol ( + &gArmScmiPerformanceProtocolGuid, + NULL, + (VOID **)&ScmiPerfProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D 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 =3D=3D NULL) || + (LevelArray =3D=3D NULL) || + (LevelArrayCount =3D=3D NULL)) + { + return EFI_INVALID_PARAMETER; + } + + // First call to get the number of levels. + Size =3D 0; + Status =3D ScmiPerfProtocol->DescribeLevels ( + ScmiPerfProtocol, + DomainId, + &Count, + &Size, + NULL + ); + if (Status !=3D EFI_BUFFER_TOO_SMALL) { + // EFI_SUCCESS is not a valid option. + if (Status =3D=3D EFI_SUCCESS) { + return EFI_INVALID_PARAMETER; + } else { + return Status; + } + } + + Array =3D AllocateZeroPool (Size); + if (Array =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // Second call to get the descriptions of the levels. + Status =3D ScmiPerfProtocol->DescribeLevels ( + ScmiPerfProtocol, + DomainId, + &Count, + &Size, + Array + ); + if (EFI_ERROR (Status)) { + return Status; + } + + *LevelArray =3D Array; + *LevelArrayCount =3D 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 =3D=3D NULL) || + (CpcInfo =3D=3D NULL)) + { + return EFI_INVALID_PARAMETER; + } + + Status =3D ScmiPerfProtocol->DescribeFastchannel ( + ScmiPerfProtocol, + DomainId, + ScmiMessageIdPerformanceLevelSet, + &FcLevelGet + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D ScmiPerfProtocol->DescribeFastchannel ( + ScmiPerfProtocol, + DomainId, + ScmiMessageIdPerformanceLimitsSet, + &FcLimitsSet + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D ScmiPerfProtocol->GetDomainAttributes ( + ScmiPerfProtocol, + DomainId, + &DomainAttributes + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D 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 !=3D sizeof (UINT32)) || + ((FcLevelGet.Attributes & SCMI_PERF_FC_ATTRIB_HAS_DOORBELL) =3D=3D + SCMI_PERF_FC_ATTRIB_HAS_DOORBELL) || + (FcLimitsSet.ChanSize !=3D 2 * sizeof (UINT32)) || + ((FcLimitsSet.Attributes & SCMI_PERF_FC_ATTRIB_HAS_DOORBELL) =3D=3D + SCMI_PERF_FC_ATTRIB_HAS_DOORBELL)) + { + Status =3D EFI_INVALID_PARAMETER; + goto exit_handler; + } + + FcLevelGetAddr =3D ((UINT64)FcLevelGet.ChanAddrHigh << 32) | + FcLevelGet.ChanAddrLow; + FcLimitsMaxSetAddr =3D ((UINT64)FcLimitsSet.ChanAddrHigh << 32) | + FcLimitsSet.ChanAddrLow; + FcLimitsMinSetAddr =3D FcLimitsMaxSetAddr + 0x4; + + CpcInfo->Revision =3D EFI_ACPI_6_5_AML_CPC_REVI= SION; + CpcInfo->HighestPerformanceInteger =3D LevelArray[LevelCount - 1= ].Level; + CpcInfo->NominalPerformanceInteger =3D DomainAttributes.Sustaine= dPerfLevel; + CpcInfo->LowestNonlinearPerformanceInteger =3D LevelArray[0].Level; + CpcInfo->LowestPerformanceInteger =3D LevelArray[0].Level; + + CpcInfo->DesiredPerformanceRegister.AddressSpaceId =3D EFI_ACPI_6_5_S= YSTEM_MEMORY; + CpcInfo->DesiredPerformanceRegister.RegisterBitWidth =3D 32; + CpcInfo->DesiredPerformanceRegister.RegisterBitOffset =3D 0; + CpcInfo->DesiredPerformanceRegister.AccessSize =3D EFI_ACPI_6_5_D= WORD; + CpcInfo->DesiredPerformanceRegister.Address =3D FcLevelGetAddr; + + CpcInfo->MinimumPerformanceRegister.AddressSpaceId =3D EFI_ACPI_6_5_S= YSTEM_MEMORY; + CpcInfo->MinimumPerformanceRegister.RegisterBitWidth =3D 32; + CpcInfo->MinimumPerformanceRegister.RegisterBitOffset =3D 0; + CpcInfo->MinimumPerformanceRegister.AccessSize =3D EFI_ACPI_6_5_D= WORD; + CpcInfo->MinimumPerformanceRegister.Address =3D FcLimitsMinSet= Addr; + + CpcInfo->MaximumPerformanceRegister.AddressSpaceId =3D EFI_ACPI_6_5_S= YSTEM_MEMORY; + CpcInfo->MaximumPerformanceRegister.RegisterBitWidth =3D 32; + CpcInfo->MaximumPerformanceRegister.RegisterBitOffset =3D 0; + CpcInfo->MaximumPerformanceRegister.AccessSize =3D EFI_ACPI_6_5_D= WORD; + CpcInfo->MaximumPerformanceRegister.Address =3D FcLimitsMaxSet= Addr; + + CpcInfo->ReferencePerformanceCounterRegister.AddressSpaceId =3D EFI_A= CPI_6_5_FUNCTIONAL_FIXED_HARDWARE; + CpcInfo->ReferencePerformanceCounterRegister.RegisterBitWidth =3D 0x40; + CpcInfo->ReferencePerformanceCounterRegister.RegisterBitOffset =3D 0; + CpcInfo->ReferencePerformanceCounterRegister.AccessSize =3D ARM_F= FH_REFERENCE_PERF_COUNTER_REGISTER; + CpcInfo->ReferencePerformanceCounterRegister.Address =3D 0x4; + + CpcInfo->DeliveredPerformanceCounterRegister.AddressSpaceId =3D EFI_A= CPI_6_5_FUNCTIONAL_FIXED_HARDWARE; + CpcInfo->DeliveredPerformanceCounterRegister.RegisterBitWidth =3D 0x40; + CpcInfo->DeliveredPerformanceCounterRegister.RegisterBitOffset =3D 0; + CpcInfo->DeliveredPerformanceCounterRegister.AccessSize =3D ARM_F= FH_DELIVERED_PERF_COUNTER_REGISTER; + CpcInfo->DeliveredPerformanceCounterRegister.Address =3D 0x4; + + // SCMI should advertise performance values on a unified scale. So frequ= ency + // values are not available. LowestFrequencyInteger and + // NominalFrequencyInteger are populated in the ConfigurationManager. + +exit_handler: + FreePool (LevelArray); + return Status; +} diff --git a/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTable= sScmiInfoLib.inf b/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/Dynami= cTablesScmiInfoLib.inf new file mode 100644 index 000000000000..d49277f82bc3 --- /dev/null +++ b/DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiIn= foLib.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 =3D 0x0001001B + BASE_NAME =3D DynamicTablesScmiInfoLib + FILE_GUID =3D 1A7CDB04-9FFC-40DA-A87C-A5ACADAF8136 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + LIBRARY_CLASS =3D DynamicTablesScmiInfoLib + CONSTRUCTOR =3D DynamicTablesScmiInfoLibConstructor + +[Sources] + DynamicTablesScmiInfoLib.c + +[Packages] + ArmPkg/ArmPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + +[Protocols] + gArmScmiPerformanceProtocolGuid ## CONSUMES + +[Depex] + gArmScmiPerformanceProtocolGuid --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114419): https://edk2.groups.io/g/devel/message/114419 Mute This Topic: https://groups.io/mt/103955508/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-