Hi Abner,
On 3/22/2023 9:48 AM, Chang, Abner via groups.io wrote:
From: Abner Chang <abner.ch...@amd.com>
The helper functions library facilitates reducing
duplicated code in the manageability transport
library instances.
Signed-off-by: Abner Chang <abner.ch...@amd.com>
Cc: Liming Gao <gaolim...@byosoft.com.cn>
Cc: Isaac Oram <isaac.w.o...@intel.com>
Cc: Nate DeSimone <nathaniel.l.desim...@intel.com>
Cc: Nickle Wang <nick...@nvidia.com>
Cc: Igor Kulchytskyy <ig...@ami.com>
Cc: Abdul Lateef Attar <abdat...@amd.com>
---
.../ManageabilityPkg/ManageabilityPkg.dec | 24 +-
.../Include/Dsc/Manageability.dsc | 2 +
.../BaseManageabilityTransportHelper.inf | 41 +++
.../Library/ManageabilityTransportHelperLib.h | 93 +++++++
.../BaseManageabilityTransportHelper.c | 261 ++++++++++++++++++
.../BaseManageabilityTransportHelper.uni | 13 +
6 files changed, 433 insertions(+), 1 deletion(-)
create mode 100644
Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.inf
create mode 100644
Features/ManageabilityPkg/Include/Library/ManageabilityTransportHelperLib.h
create mode 100644
Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.c
create mode 100644
Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.uni
diff --git a/Features/ManageabilityPkg/ManageabilityPkg.dec
b/Features/ManageabilityPkg/ManageabilityPkg.dec
index 92ba4538c0..ebbb04dc0e 100644
--- a/Features/ManageabilityPkg/ManageabilityPkg.dec
+++ b/Features/ManageabilityPkg/ManageabilityPkg.dec
@@ -22,5 +22,27 @@
# Manageability Transport Library definitions
ManageabilityTransportLib|Include/Library/ManageabilityTransportLib.h
+ ## @libraryclass Manageability Transport Helper Library
+ # Provide the help functions to use ManageabilityTransportLib
+
ManageabilityTransportHelperLib|Include/Library/ManageabilityTransportHelperLib.h
+
[Guids]
- gManageabilityPkgTokenSpaceGuid = { 0xBDEFFF48, 0x1C31, 0x49CD, { 0xA7,
0x6D, 0x92, 0x9E, 0x60, 0xDB, 0xB9, 0xF8 } }
+ gManageabilityPkgTokenSpaceGuid = { 0xBDEFFF48, 0x1C31, 0x49CD, { 0xA7,
0x6D, 0x92, 0x9E, 0x60, 0xDB, 0xB9, 0xF8 } }
+
+ # Manageability Transport Interface type
+ #
+ # Manageability Transport KCS
+ gManageabilityTransportKcsGuid = { 0x5A6E64E9, 0xFD47, 0x4086, { 0xAA,
0xB0, 0x7A, 0x5F, 0xD7, 0x6B, 0x02, 0x2E } }
+ # Manageability Transport I2C
+ gManageabilityTransportI2CGuid = { 0x5B174658, 0x8263, 0x4CB8, { 0xA0,
0x0F, 0xD6, 0x82, 0xE6, 0xBC, 0x74, 0x93 } }
+ # Manageability Transport PCI VDM
+ gManageabilityTransportPciVdmGuid = { 0x388021A7, 0xFB59, 0x4811, { 0x9D,
0xA7, 0xD5, 0x63, 0x7D, 0x04, 0xA7, 0x2F } }
+
+ # Manageability Protocol Specification
+ #
+ # Manageability Protocol IPMI
+ gManageabilityProtocolIpmiGuid = { 0x36ACA47C, 0xCC80, 0x473B, { 0xAB,
0xEC, 0xF3, 0x98, 0xFF, 0x87, 0x74, 0x5B } }
+ # Manageability Protocol MCTP
+ gManageabilityProtocolMctpGuid = { 0x76FED8F1, 0x0BE5, 0x4269, { 0xA3,
0x1A, 0x38, 0x0F, 0x54, 0xF1, 0xA1, 0x8A } }
+ # Manageability Protocol PLDM
+ gManageabilityProtocolPldmGuid = { 0x3958090D, 0x69DD, 0x4868, { 0x9C,
0x41, 0xC9, 0xAC, 0x31, 0xB5, 0x25, 0xC5 } }
diff --git a/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc
b/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc
index 2cb63c1ca6..994c93f17c 100644
--- a/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc
+++ b/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc
@@ -5,6 +5,8 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
+[LibraryClasses]
+
ManageabilityTransportHelperLib|ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
diff --git
a/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.inf
b/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.inf
new file mode 100644
index 0000000000..95c3362ddb
--- /dev/null
+++
b/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.inf
@@ -0,0 +1,41 @@
+## @file
+# Null instance of Manageability Transport Helper Library
+#
+# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = BaseManageabilityTransportHelper
+ MODULE_UNI_FILE = BaseManageabilityTransportHelper.uni
+ FILE_GUID = 52F2DE11-A8FC-4A06-B8C6-10DCF4A7397C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ManageabilityTransportHelperLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ BaseManageabilityTransportHelper.c
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+
+[Packages]
+ ManageabilityPkg/ManageabilityPkg.dec
+ MdePkg/MdePkg.dec
+
+[Guids]
+ gManageabilityTransportKcsGuid
+ gManageabilityTransportI2CGuid
+ gManageabilityTransportPciVdmGuid
+ gManageabilityTransportMctpGuid
Please check here since I am unable to find the definition of
gManageabilityTransportMctpGuid.
+ gManageabilityProtocolIpmiGuid
+ gManageabilityProtocolMctpGuid
+ gManageabilityProtocolPldmGuid
+
diff --git
a/Features/ManageabilityPkg/Include/Library/ManageabilityTransportHelperLib.h
b/Features/ManageabilityPkg/Include/Library/ManageabilityTransportHelperLib.h
new file mode 100644
index 0000000000..718ac34a1f
--- /dev/null
+++
b/Features/ManageabilityPkg/Include/Library/ManageabilityTransportHelperLib.h
@@ -0,0 +1,93 @@
+/** @file
+
+ This file defines the manageability transport interface library and
functions.
+
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef MANAGEABILITY_TRANSPORT_HELPER_LIB_H_
+#define MANAGEABILITY_TRANSPORT_HELPER_LIB_H_
+
+#include <Library/ManageabilityTransportLib.h>
+
+typedef struct _MANAGEABILITY_PROTOCOL_NAME MANAGEABILITY_PROTOCOL_NAME;
+
+/**
+ Helper function returns the human readable name of Manageability
specification.
+
+ @param[out] SpecificationGuid The Manageability specification GUID
+
+ @retval !NULL Human readable name is returned;
+ @retval NULL No string found, the given Manageability specification is
+ not supported.
+**/
+CHAR16 *
+HelperManageabilitySpecName (
+ IN EFI_GUID *SpecificationGuid
+ );
+
+/**
+ Helper function to check if the Manageability specification is supported
+ by transport interface or not.
+
+ @param[in] TransportGuid GUID of the transport
interface.
+ @param[in] SupportedManageabilityProtocolArray The Manageability
protocols supported
+ by the transport interface.
+ @param[in] NumberOfSupportedProtocolInArray Number of protocols in the
array.
+ @param[in] ManageabilityProtocolToCheck The Manageability
specification to check.
+
+ @retval EFI_SUCCESS Token is created successfully.
+ @retval EFI_INVALID_PARAMETER Either NumberOfSupportedProtocolInArray
= 0 or
+ SupportedManageabilityProtocolArray =
NULL.
+ @retval EFI_UNSUPPORTED Out of resource to create a new
transport session.
+ Otherwise Other errors.
+**/
+EFI_STATUS
+HelperManageabilityCheckSupportedSpec (
+ IN EFI_GUID *TransportGuid,
+ IN EFI_GUID **SupportedManageabilityProtocolArray,
+ IN UINT8 NumberOfSupportedProtocolInArray,
+ IN EFI_GUID *ManageabilityProtocolToCheck
+ );
+
+/**
+ Helper function to acquire the Manageability transport token.
+
+ @param[in] ManageabilityProtocolSpec The Manageability protocol
specification.
+ @param[out] TransportToken Pointer to receive Manageability
transport
+ token.
+
+ @retval EFI_SUCCESS Token is created successfully.
+ @retval EFI_OUT_OF_RESOURCES Out of resource to create a new
transport session.
+ @retval EFI_UNSUPPORTED Token is created successfully.
+ @retval EFI_DEVICE_ERROR The transport interface has problems
+ @retval EFI_INVALID_PARAMETER INput parameter is not valid.
+ Otherwise Other errors.
+**/
+EFI_STATUS
+HelperAcquireManageabilityTransport (
+ IN EFI_GUID *ManageabilityProtocolSpec,
+ OUT MANAGEABILITY_TRANSPORT_TOKEN **TransportToken
+ );
+
+/**
+ Helper function to initial the transport interface.
+
+ @param[in] TransportToken Transport token.
+ @param[in] HardwareInfo Optional hardware information of
transport interface.
+ @param[out] TransportAdditionalStatus Transport additional status.
+
+ @retval EFI_SUCCESS Transport interface is initiated
successfully.
+ @retval EFI_DEVICE_ERROR The transport interface has problems
+ @retval EFI_INVALID_PARAMETER INput parameter is not valid.
+ Otherwise Other errors.
+**/
+EFI_STATUS
+HelperInitManageabilityTransport (
+ IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken,
+ IN MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION HardwareInfo OPTIONAL,
+ OUT MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS *TransportAdditionalStatus
OPTIONAL
+ );
+
+#endif
diff --git
a/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.c
b/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.c
new file mode 100644
index 0000000000..81da209764
--- /dev/null
+++
b/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.c
@@ -0,0 +1,261 @@
+/** @file
+ Null instance of Manageability Transport Helper Library
+
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ManageabilityTransportHelperLib.h>
+
+//
+// BaseManageabilityTransportHelper is used by PEI, DXE and SMM.
+// Make sure the global variables added here should be unchangable.
+//
+MANAGEABILITY_SPECIFICATION_NAME ManageabilitySpecNameTable[] = {
+ { &gManageabilityTransportKcsGuid, L"KCS" },
+ { &gManageabilityTransportI2CGuid, L"I2C" },
Should we use SMBUS_I2C instead of I2C? When we use
SmbusLib/SmbusHcProtocol for IPMI SSIF and name it I2C, it causes a lot
of confusion.
The term SMBus is used in the IPMI specification, and the term SMBus/I2c
is used in the MCTP specification.
- Tinh
+ { &gManageabilityTransportPciVdmGuid, L"PCI VDM" },
+ { &gManageabilityTransportMctpGuid, L"MCTP" },
+ { &gManageabilityProtocolIpmiGuid, L"IPMI" },
+ { &gManageabilityProtocolMctpGuid, L"MCTP" },
+ { &gManageabilityProtocolPldmGuid, L"PLDM" }
+};
+
+UINT16 mManageabilitySpecNum = sizeof (ManageabilitySpecNameTable)/ sizeof
(MANAGEABILITY_SPECIFICATION_NAME);
+
+/**
+ Helper function returns the human readable name of Manageability
specification.
+
+ @param[in] SpecificationGuid The Manageability specification GUID
+
+ @retval !NULL Human readable name is returned;
+ @retval NULL No string found, the given Manageability specification is
+ not supported.
+**/
+CHAR16 *
+HelperManageabilitySpecName (
+ IN EFI_GUID *SpecificationGuid
+ )
+{
+ UINT16 Index;
+ MANAGEABILITY_SPECIFICATION_NAME *ThisSpec;
+
+ if (mManageabilitySpecNum == 0) {
+ return NULL;
+ }
+
+ if (SpecificationGuid == NULL || IsZeroGuid (SpecificationGuid)) {
+ DEBUG((DEBUG_ERROR, "%a: Improper input GUIDs, could be NULL or zero
GUID.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ ThisSpec = ManageabilitySpecNameTable;
+ for (Index = 0; Index < mManageabilitySpecNum; Index++) {
+ if (CompareGuid (
+ SpecificationGuid,
+ ThisSpec->SpecificationGuid
+ ))
+ {
+ return ThisSpec->SpecificationName;
+ }
+
+ ThisSpec++;
+ }
+
+ return NULL;
+}
+
+/**
+ Helper function to check if the Manageability specification is supported
+ by transport interface or not.
+
+ @param[in] TransportGuid GUID of the transport
interface.
+ @param[in] SupportedManageabilityProtocolArray The Manageability
protocols supported
+ by the transport interface.
+ @param[in] NumberOfSupportedProtocolInArray Number of protocols in the
array.
+ @param[in] ManageabilityProtocolToCheck The Manageability
specification to check.
+
+ @retval EFI_SUCCESS Token is created successfully.
+ @retval EFI_INVALID_PARAMETER Either NumberOfSupportedProtocolInArray
= 0 or
+ SupportedManageabilityProtocolArray =
NULL.
+ @retval EFI_UNSUPPORTED Out of resource to create a new
transport session.
+ Otherwise Other errors.
+**/
+EFI_STATUS
+HelperManageabilityCheckSupportedSpec (
+ IN EFI_GUID *TransportGuid,
+ IN EFI_GUID **SupportedManageabilityProtocolArray,
+ IN UINT8 NumberOfSupportedProtocolInArray,
+ IN EFI_GUID *ManageabilityProtocolToCheck
+ )
+{
+ UINT16 Index;
+ EFI_GUID **ThisSpecGuid;
+
+ if ((NumberOfSupportedProtocolInArray == 0) ||
(SupportedManageabilityProtocolArray == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TransportGuid == NULL ||
+ IsZeroGuid (TransportGuid) ||
+ ManageabilityProtocolToCheck == NULL ||
+ IsZeroGuid (ManageabilityProtocolToCheck)
+ ) {
+ DEBUG((DEBUG_ERROR, "%a: Improper input GUIDs, could be NULL or zero
GUID.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ThisSpecGuid = SupportedManageabilityProtocolArray;
+ for (Index = 0; Index < NumberOfSupportedProtocolInArray; Index++) {
+ if (CompareGuid (
+ *ThisSpecGuid,
+ ManageabilityProtocolToCheck
+ ))
+ {
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a: Transport interface %s supports %s manageability
specification.\n",
+ __FUNCTION__,
+ HelperManageabilitySpecName (TransportGuid),
+ HelperManageabilitySpecName (ManageabilityProtocolToCheck)
+ ));
+ return EFI_SUCCESS;
+ }
+
+ ThisSpecGuid++;
+ }
+
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Transport interface %s doesn't support %s manageability
specification.\n",
+ __FUNCTION__,
+ HelperManageabilitySpecName (TransportGuid),
+ HelperManageabilitySpecName (ManageabilityProtocolToCheck)
+ ));
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Helper function to acquire the Manageability transport token.
+
+ @param[in] ManageabilityProtocolSpec The Manageability protocol
specification.
+ @param[out] TransportToken Pointer to receive Manageability
transport
+ token.
+
+ @retval EFI_SUCCESS Token is created successfully.
+ @retval EFI_OUT_OF_RESOURCES Out of resource to create a new
transport session.
+ @retval EFI_UNSUPPORTED Token is created successfully.
+ @retval EFI_INVALID_PARAMETER Input parameter is not valid.
+ Otherwise Other errors.
+**/
+EFI_STATUS
+HelperAcquireManageabilityTransport (
+ IN EFI_GUID *ManageabilityProtocolSpec,
+ OUT MANAGEABILITY_TRANSPORT_TOKEN **TransportToken
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *ManageabilityProtocolName;
+ CHAR16 *ManageabilityTransportName;
+
+ DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));
+ if ((TransportToken == NULL) || (ManageabilityProtocolSpec == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a: One of the required input parameters is
NULL.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TransportToken = NULL;
+ ManageabilityProtocolName = HelperManageabilitySpecName
(ManageabilityProtocolSpec);
+ if (ManageabilityProtocolName == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Unsupported Manageability Protocol
Specification.\n", __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((DEBUG_INFO, " Manageability protocol %s is going to acquire transport
interface token...\n", ManageabilityProtocolName));
+
+ Status = AcquireTransportSession (ManageabilityProtocolSpec, TransportToken);
+ if (Status == EFI_UNSUPPORTED) {
+ DEBUG ((DEBUG_ERROR, "%a: No supported transport interface for %s
packet.\n", __FUNCTION__, ManageabilityProtocolName));
+ return Status;
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Fail to acquire Manageability transport token for %s (%r).\n",
+ __FUNCTION__,
+ ManageabilityProtocolName,
+ Status
+ ));
+ return Status;
+ }
+
+ ManageabilityTransportName = HelperManageabilitySpecName
((*TransportToken)->Transport->ManageabilityTransportSpecification);
+ if (ManageabilityTransportName == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Unsupported Manageability Transport Interface
Specification\n", __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: This is the transfer session for %s over %s\n",
__FUNCTION__, ManageabilityProtocolName, ManageabilityTransportName));
+ return Status;
+}
+
+/**
+ Helper function to initial the transport interface.
+
+ @param[in] TransportToken Transport token.
+ @param[in] HardwareInfo Optional hardware information of
transport interface.
+ @param[out] TransportAdditionalStatus Transport additional status.
+
+ @retval EFI_SUCCESS Transport interface is initiated
successfully.
+ @retval EFI_DEVICE_ERROR The transport interface has problems
+ @retval EFI_INVALID_PARAMETER INput parameter is not valid.
+ Otherwise Other errors.
+**/
+EFI_STATUS
+HelperInitManageabilityTransport (
+ IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken,
+ IN MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION HardwareInfo OPTIONAL,
+ OUT MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS *TransportAdditionalStatus
OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ if (TransportToken == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: TransportToken is invalid.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Initial transport interface.
+ Status = TransportToken->Transport->Function.Version1_0->TransportInit
(TransportToken, HardwareInfo);
+ if ((Status != EFI_SUCCESS) && (Status != EFI_ALREADY_STARTED)) {
+ if (Status == EFI_DEVICE_ERROR) {
+ // Try to reset the transport and initialize it again.
+ Status = TransportToken->Transport->Function.Version1_0->TransportReset (
+
TransportToken,
+
TransportAdditionalStatus
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_UNSUPPORTED) {
+ DEBUG ((DEBUG_ERROR, "%a: Transport interface doesn't have reset
capability.\n", __FUNCTION__));
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a: Fail to reset transport interface
(%r).\n", __FUNCTION__, Status));
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ } else {
+ Status = TransportToken->Transport->Function.Version1_0->TransportInit
(TransportToken, HardwareInfo);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Transport interface is not able to use after
the reset (%r).\n", __FUNCTION__, Status));
+ }
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a: Transport interface is not able to use
(%r).\n", __FUNCTION__, Status));
+ }
+ }
+
+ return Status;
+}
diff --git
a/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.uni
b/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.uni
new file mode 100644
index 0000000000..dfb6051aeb
--- /dev/null
+++
b/Features/ManageabilityPkg/Library/BaseManageabilityTransportHelperLib/BaseManageabilityTransportHelper.uni
@@ -0,0 +1,13 @@
+// /** @file
+// Null instance of Manageability Transport Helper Library
+//
+// Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Manageability Transport
Helper Library"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Manageability Transport
Helper Functions."
+
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#101706): https://edk2.groups.io/g/devel/message/101706
Mute This Topic: https://groups.io/mt/97770712/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-