public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Tinh Nguyen" <tinhnguyen@os.amperecomputing.com>
To: devel@edk2.groups.io, abner.chang@amd.com
Cc: Liming Gao <gaoliming@byosoft.com.cn>,
	Isaac Oram <isaac.w.oram@intel.com>,
	Nate DeSimone <nathaniel.l.desimone@intel.com>,
	Abdul Lateef Attar <abdattar@amd.com>,
	Nickle Wang <nicklew@nvidia.com>,
	Igor Kulchytskyy <igork@ami.com>
Subject: Re: [edk2-devel] [PATCH v4 7/9] ManageabilityPkg: Implement Ipmi Protocol/Ppi
Date: Fri, 24 Mar 2023 02:40:39 +0700	[thread overview]
Message-ID: <4064fa08-dec2-91dd-ba42-42200eec7e55@amperemail.onmicrosoft.com> (raw)
In-Reply-To: <20230322024840.1629-7-abner.chang@amd.com>

Hi Abner,


On 3/22/2023 9:48 AM, Chang, Abner via groups.io wrote:
> From: Abner Chang <abner.chang@amd.com>
>
> Add Ipmi Protocol/Ppi/SMM implementations.
> The underlying implementation of transport
> interface depends on the binded
> ManageabilityTransportLib.
>
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Isaac Oram <isaac.w.oram@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Abdul Lateef Attar <abdattar@amd.com>
> Cc: Nickle Wang <nicklew@nvidia.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> ---
>   .../IpmiProtocol/Dxe/IpmiProtocolDxe.inf      |  50 ++++
>   .../Universal/IpmiProtocol/Pei/IpmiPpiPei.inf |  53 ++++
>   .../IpmiProtocol/Smm/IpmiProtocolSmm.inf      |  52 ++++
>   .../IpmiProtocol/Common/IpmiProtocolCommon.h  | 108 ++++++++
>   .../IpmiProtocol/Pei/IpmiPpiInternal.h        |  25 ++
>   .../IpmiProtocol/Common/IpmiProtocolCommon.c  | 252 ++++++++++++++++++
>   .../Universal/IpmiProtocol/Dxe/IpmiProtocol.c | 177 ++++++++++++
>   .../Universal/IpmiProtocol/Pei/IpmiPpi.c      | 159 +++++++++++
>   .../Universal/IpmiProtocol/Smm/IpmiProtocol.c | 147 ++++++++++
>   9 files changed, 1023 insertions(+)
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocolDxe.inf
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpiPei.inf
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocolSmm.inf
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Common/IpmiProtocolCommon.h
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpiInternal.h
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Common/IpmiProtocolCommon.c
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocol.c
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpi.c
>   create mode 100644 Features/ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocol.c
>
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocolDxe.inf b/Features/ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocolDxe.inf
> new file mode 100644
> index 0000000000..ff5ec56c73
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocolDxe.inf
> @@ -0,0 +1,50 @@
> +## @file
> +# IPMI Protocol DXE Driver.
> +#
> +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001d
> +  BASE_NAME                      = IpmiDxe
> +  FILE_GUID                      = BC41B0C2-9D8A-42B5-A28F-02CE0D4A6C28
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = DxeIpmiEntry
> +  UNLOAD_IMAGE                   = IpmiUnloadImage
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
> +#
> +
> +[Sources]
> +  IpmiProtocol.c
> +  ../Common/IpmiProtocolCommon.c
> +  ../Common/IpmiProtocolCommon.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  ManageabilityPkg/ManageabilityPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  ManageabilityTransportHelperLib
> +  ManageabilityTransportLib
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +
> +[Protocols]
> +  gIpmiProtocolGuid               # PROTOCOL ALWAYS_PRODUCED
> +
> +[Guids]
> +  gManageabilityProtocolIpmiGuid
> +  gManageabilityTransportKcsGuid
> +
> +[FixedPcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdIpmiKcsBaseAddress
> +
> +[Depex]
> +  TRUE
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpiPei.inf b/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpiPei.inf
> new file mode 100644
> index 0000000000..4e00693f64
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpiPei.inf
> @@ -0,0 +1,53 @@
> +## @file
> +# IPMI Protocol PEI Driver.
> +#
> +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001d
> +  BASE_NAME                      = IpmiPei
> +  FILE_GUID                      = 7832F989-CB72-4715-ADCA-35C0B031856C
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = PeiIpmiEntry
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
> +#
> +
> +[Sources]
> +  IpmiPpi.c
> +  IpmiPpiInternal.h
> +  ../Common/IpmiProtocolCommon.c
> +  ../Common/IpmiProtocolCommon.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  ManageabilityPkg/ManageabilityPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +  ManageabilityTransportHelperLib
> +  ManageabilityTransportLib
> +  PeimEntryPoint
> +  ManageabilityTransportLib
Duplicate ManageabilityTransportLib
> +
> +[Ppis]
> +  gPeiIpmiPpiGuid       # PPI ALWAYS PRODUCED
> +
> +[Guids]
> +  gManageabilityProtocolIpmiGuid
> +  gManageabilityTransportKcsGuid
> +
> +[FixedPcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdIpmiKcsBaseAddress
> +
> +[Depex]
> +  TRUE
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocolSmm.inf b/Features/ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocolSmm.inf
> new file mode 100644
> index 0000000000..cae1462f4f
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocolSmm.inf
> @@ -0,0 +1,52 @@
> +## @file
> +# IPMI Protocol SMM Driver.
> +#
> +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
> +#
> +[Defines]
> +  INF_VERSION                         = 0x0001001d
> +  BASE_NAME                           = IpmiSmm
> +  FILE_GUID                           = CDD5D1DE-E3D3-4B1F-8689-DCC661561BB4
> +  MODULE_TYPE                         = DXE_SMM_DRIVER
> +  PI_SPECIFICATION_VERSION            = 0x0001000A
> +  VERSION_STRING                      = 1.0
> +  ENTRY_POINT                         = SmmIpmiEntry
> +
> +[Sources]
> +  IpmiProtocol.c
> +  ../Common/IpmiProtocolCommon.c
> +  ../Common/IpmiProtocolCommon.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  ManageabilityPkg/ManageabilityPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  ManageabilityTransportHelperLib
> +  ManageabilityTransportLib
> +  SmmServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +
> +[Protocols]
> +  gSmmIpmiProtocolGuid               # PROTOCOL ALWAYS_PRODUCED
> +
> +[Guids]
> +  gManageabilityProtocolIpmiGuid
> +  gManageabilityTransportKcsGuid
> +
> +[FixedPcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdIpmiKcsBaseAddress
> +
> +[Depex]
> +  TRUE
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Common/IpmiProtocolCommon.h b/Features/ManageabilityPkg/Universal/IpmiProtocol/Common/IpmiProtocolCommon.h
> new file mode 100644
> index 0000000000..57b92cf2be
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Common/IpmiProtocolCommon.h
> @@ -0,0 +1,108 @@
> +/** @file
> +
> +    IPMI Manageability Protocol common header file.
> +
> +  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef MANAGEABILITY_IPMI_COMMON_H_
> +#define MANAGEABILITY_IPMI_COMMON_H_
> +
> +#include <IndustryStandard/IpmiKcs.h>
> +#include <Library/ManageabilityTransportLib.h>
> +
> +///
> +/// IPMI KCS hardware information.
> +///
> +#define IPMI_KCS_BASE_ADDRESS  PcdGet16 (PcdIpmiKcsBaseAddress)
> +#define IPMI_KCS_REG_DATA_IN   IPMI_KCS_BASE_ADDRESS + IPMI_KCS_DATA_IN_REGISTER_OFFSET
> +#define IPMI_KCS_REG_DATA_OUT  IPMI_KCS_BASE_ADDRESS + IPMI_KCS_DATA_OUT_REGISTER_OFFSET
> +#define IPMI_KCS_REG_COMMAND   IPMI_KCS_BASE_ADDRESS + IPMI_KCS_COMMAND_REGISTER_OFFSET
> +#define IPMI_KCS_REG_STATUS    IPMI_KCS_BASE_ADDRESS + IPMI_KCS_STATUS_REGISTER_OFFSET
> +
> +/**
> +  This functions setup the IPMI transport hardware information according
> +  to the specification of transport token acquired from transport library.
> +
> +  @param[in]         TransportToken       The transport interface.
> +  @param[out]        HardwareInformation  Pointer to receive the hardware information.
> +
> +  @retval EFI_SUCCESS            Hardware information is returned in HardwareInformation.
> +                                 Caller must free the memory allocated for HardwareInformation
> +                                 once it doesn't need it.
> +  @retval EFI_UNSUPPORTED        No hardware information for the specification specified
> +                                 in the transport token.
> +**/
> +EFI_STATUS
> +SetupIpmiTransportHardwareInformation (
> +  IN   MANAGEABILITY_TRANSPORT_TOKEN                 *TransportToken,
> +  OUT  MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION  *HardwareInformation
> +  );
> +
> +/**
> +  This functions setup the final header/body/trailer packets for
> +  the acquired transport interface.
> +
> +  @param[in]         TransportToken  The transport interface.
> +  @param[in]         NetFunction     IPMI function.
> +  @param[in]         Command         IPMI command.
> +  @param[out]        PacketHeader    The pointer to receive header of request.
> +  @param[in, out]    PacketBody      The request body.
> +                                     When IN, it is the caller's request body.
> +                                     When OUT and NULL, the request body is not
> +                                     changed.
> +                                     Whee out and non-NULL, the request body is
> +                                     changed to comfort the transport interface.
> +  @param[in, out]    PacketBodySize  The request body size.
> +                                     When IN and non-zero, it is the new data
> +                                     length of request body.
> +                                     When IN and zero, the request body is unchanged.
> +  @param[out]        PacketTrailer   The pointer to receive trailer of request.
> +
> +  @retval EFI_SUCCESS            Request packet is returned.
> +  @retval EFI_UNSUPPORTED        Request packet is not returned because
> +                                 the unsupported transport interface.
> +**/
> +EFI_STATUS
> +SetupIpmiRequestTransportPacket (
> +  IN   MANAGEABILITY_TRANSPORT_TOKEN    *TransportToken,
> +  IN   UINT8                            NetFunction,
> +  IN   UINT8                            Command,
> +  OUT  MANAGEABILITY_TRANSPORT_HEADER   *PacketHeader OPTIONAL,
> +  IN OUT UINT8                          **PacketBody OPTIONAL,
> +  IN OUT UINT32                         *PacketBodySize OPTIONAL,
> +  OUT  MANAGEABILITY_TRANSPORT_TRAILER  *PacketTrailer OPTIONAL
> +  );
> +
> +/**
> +  Common code to submit IPMI commands
> +
> +  @param[in]         TransportToken    TRansport token.
> +  @param[in]         NetFunction       Net function of the command.
> +  @param[in]         Command           IPMI Command.
> +  @param[in]         RequestData       Command Request Data.
> +  @param[in]         RequestDataSize   Size of Command Request Data.
> +  @param[out]        ResponseData      Command Response Data. The completion code is the first byte of response data.
> +  @param[in, out]    ResponseDataSize  Size of Command Response Data.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully submit to the device and a response was successfully received.
> +  @retval EFI_NOT_FOUND          The command was not successfully sent to the device or a response was not successfully received from the device.
> +  @retval EFI_NOT_READY          Ipmi Device is not ready for Ipmi command access.
> +  @retval EFI_DEVICE_ERROR       Ipmi Device hardware error.
> +  @retval EFI_TIMEOUT            The command time out.
> +  @retval EFI_UNSUPPORTED        The command was not successfully sent to the device.
> +  @retval EFI_OUT_OF_RESOURCES   The resource allocation is out of resource or data size error.
> +**/
> +EFI_STATUS
> +CommonIpmiSubmitCommand (
> +  IN     MANAGEABILITY_TRANSPORT_TOKEN  *TransportToken,
> +  IN     UINT8                          NetFunction,
> +  IN     UINT8                          Command,
> +  IN     UINT8                          *RequestData OPTIONAL,
> +  IN     UINT32                         RequestDataSize,
> +  OUT    UINT8                          *ResponseData OPTIONAL,
> +  IN OUT UINT32                         *ResponseDataSize OPTIONAL
> +  );
> +
> +#endif
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpiInternal.h b/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpiInternal.h
> new file mode 100644
> index 0000000000..bbe0c8c5cb
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpiInternal.h
> @@ -0,0 +1,25 @@
> +/** @file
> +
> +    IPMI Manageability PPI internal header file.
> +
> +  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef MANAGEABILITY_IPMI_PPI_INTERNAL_H_
> +#define MANAGEABILITY_IPMI_PPI_INTERNAL_H_
> +
> +#include <Library/ManageabilityTransportLib.h>
> +#include <Ppi/IpmiPpi.h>
> +
> +#define MANAGEABILITY_IPMI_PPI_INTERNAL_SIGNATURE  SIGNATURE_32 ('I', 'P', 'P', 'I')
> +
> +#define MANAGEABILITY_IPMI_PPI_INTERNAL_FROM_LINK(a)  CR (a, PEI_IPMI_PPI_INTERNAL, PeiIpmiPpi, MANAGEABILITY_IPMI_PPI_INTERNAL_SIGNATURE)
> +
> +typedef struct {
> +  UINT32                         Signature;
> +  MANAGEABILITY_TRANSPORT_TOKEN  *TransportToken;
> +  PEI_IPMI_PPI                   PeiIpmiPpi;
> +} PEI_IPMI_PPI_INTERNAL;
> +
> +#endif // MANAGEABILITY_IPMI_PPI_INTERNAL_H_
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Common/IpmiProtocolCommon.c b/Features/ManageabilityPkg/Universal/IpmiProtocol/Common/IpmiProtocolCommon.c
> new file mode 100644
> index 0000000000..d1294d2f7c
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Common/IpmiProtocolCommon.c
> @@ -0,0 +1,252 @@
> +/** @file
> +
> +  IPMI Manageability Protocol common file.
> +
> +  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/MemoryAllocationLib.h>
> +#include <Library/ManageabilityTransportIpmiLib.h>
> +#include <Library/ManageabilityTransportLib.h>
> +
> +#include "IpmiProtocolCommon.h"
> +
> +/**
> +  This functions setup the IPMI transport hardware information according
> +  to the specification of transport token acquired from transport library.
> +
> +  @param[in]         TransportToken       The transport interface.
> +  @param[out]        HardwareInformation  Pointer to receive the hardware information.
> +
> +  @retval EFI_SUCCESS            Hardware information is returned in HardwareInformation.
> +                                 Caller must free the memory allocated for HardwareInformation
> +                                 once it doesn't need it.
> +  @retval EFI_UNSUPPORTED        No hardware information for the specification specified
> +                                 in the transport token.
> +  #retval EFI_OUT_OF_RESOURCES   Not enough memory for MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO.
> +**/
> +EFI_STATUS
> +SetupIpmiTransportHardwareInformation (
> +  IN   MANAGEABILITY_TRANSPORT_TOKEN                 *TransportToken,
> +  OUT  MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION  *HardwareInformation
> +  )
> +{
> +  MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO  *KcsHardwareInfo;
> +
> +  KcsHardwareInfo = AllocatePool (sizeof (MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO));
> +  if (KcsHardwareInfo == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Not enough memory for MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO.\n", __FUNCTION__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  if (CompareGuid (&gManageabilityTransportKcsGuid, TransportToken->Transport->ManageabilityTransportSpecification)) {
> +    // This is KCS transport interface.
> +    KcsHardwareInfo->MemoryMap                    = MANAGEABILITY_TRANSPORT_KCS_IO_MAP_IO;
> +    KcsHardwareInfo->IoBaseAddress.IoAddress16    = IPMI_KCS_BASE_ADDRESS;
> +    KcsHardwareInfo->IoDataInAddress.IoAddress16  = IPMI_KCS_REG_DATA_IN;
> +    KcsHardwareInfo->IoDataOutAddress.IoAddress16 = IPMI_KCS_REG_DATA_OUT;
> +    KcsHardwareInfo->IoCommandAddress.IoAddress16 = IPMI_KCS_REG_COMMAND;
> +    KcsHardwareInfo->IoStatusAddress.IoAddress16  = IPMI_KCS_REG_STATUS;
> +    *HardwareInformation                          =
> +      (MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION)KcsHardwareInfo;
> +    return EFI_SUCCESS;
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "%a: No implementation of setting hardware information.", __FUNCTION__));
> +    ASSERT (FALSE);
> +  }
> +
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  This functions setup the final header/body/trailer packets for
> +  the acquired transport interface.
> +
> +  @param[in]         TransportToken  The transport interface.
> +  @param[in]         NetFunction     IPMI function.
> +  @param[in]         Command         IPMI command.
> +  @param[out]        PacketHeader    The pointer to receive header of request.
> +  @param[in, out]    PacketBody      The request body.
> +                                     When IN, it is the caller's request body.
> +                                     When OUT and NULL, the request body is not
> +                                     changed.
> +                                     When OUT and non-NULL, the request body is
> +                                     changed to conform the transport interface.
> +  @param[in, out]    PacketBodySize  The request body size.
> +                                     When OUT and non-zero, it is the new data
> +                                     length of request body.
> +                                     When OUT and zero, the request body is unchanged.
> +  @param[out]        PacketTrailer   The pointer to receive trailer of request.
> +
> +  @retval EFI_SUCCESS            Request packet is returned.
> +  @retval EFI_UNSUPPORTED        Request packet is not returned because
> +                                 the unsupported transport interface.
> +**/
> +EFI_STATUS
> +SetupIpmiRequestTransportPacket (
> +  IN   MANAGEABILITY_TRANSPORT_TOKEN    *TransportToken,
> +  IN   UINT8                            NetFunction,
> +  IN   UINT8                            Command,
> +  OUT  MANAGEABILITY_TRANSPORT_HEADER   *PacketHeader OPTIONAL,
> +  IN OUT UINT8                          **PacketBody OPTIONAL,
> +  IN OUT UINT32                         *PacketBodySize OPTIONAL,
> +  OUT  MANAGEABILITY_TRANSPORT_TRAILER  *PacketTrailer OPTIONAL
> +  )
> +{
> +  MANAGEABILITY_IPMI_TRANSPORT_HEADER  *IpmiHeader;
> +
> +  if (CompareGuid (&gManageabilityTransportKcsGuid, TransportToken->Transport->ManageabilityTransportSpecification)) {
> +    // This is KCS transport interface.
> +    IpmiHeader = AllocateZeroPool (sizeof (MANAGEABILITY_IPMI_TRANSPORT_HEADER));
> +    if (IpmiHeader == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    IpmiHeader->Command = Command;
> +    IpmiHeader->Lun     = 0;
> +    IpmiHeader->NetFn   = NetFunction;
> +    if (PacketHeader != NULL) {
> +      *PacketHeader = (MANAGEABILITY_TRANSPORT_HEADER *)IpmiHeader;
> +    }
> +    if (PacketTrailer != NULL) {
> +      *PacketTrailer = NULL;
> +    }
> +    if (PacketBody != NULL) {
> +      *PacketBody = NULL;
> +    }
> +    if (PacketBodySize != NULL) {
> +      *PacketBodySize = 0;
> +    }
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "%a: No implementation of building up packet.", __FUNCTION__));
> +    ASSERT (FALSE);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Common code to submit IPMI commands
> +
> +  @param[in]         TransportToken    TRansport token.
> +  @param[in]         NetFunction       Net function of the command.
> +  @param[in]         Command           IPMI Command.
> +  @param[in]         RequestData       Command Request Data.
> +  @param[in]         RequestDataSize   Size of Command Request Data.
> +  @param[out]        ResponseData      Command Response Data. The completion code is the first byte of response data.
> +  @param[in, out]    ResponseDataSize  Size of Command Response Data.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully submit to the device and a response was successfully received.
> +  @retval EFI_NOT_FOUND          The command was not successfully sent to the device or a response was not successfully received from the device.
> +  @retval EFI_NOT_READY          Ipmi Device is not ready for Ipmi command access.
> +  @retval EFI_DEVICE_ERROR       Ipmi Device hardware error.
> +  @retval EFI_TIMEOUT            The command time out.
> +  @retval EFI_UNSUPPORTED        The command was not successfully sent to the device.
> +  @retval EFI_OUT_OF_RESOURCES   The resource allocation is out of resource or data size error.
> +**/
> +EFI_STATUS
> +CommonIpmiSubmitCommand (
> +  IN     MANAGEABILITY_TRANSPORT_TOKEN  *TransportToken,
> +  IN     UINT8                          NetFunction,
> +  IN     UINT8                          Command,
> +  IN     UINT8                          *RequestData OPTIONAL,
> +  IN     UINT32                         RequestDataSize,
> +  OUT    UINT8                          *ResponseData OPTIONAL,
> +  IN OUT UINT32                         *ResponseDataSize OPTIONAL
> +  )
> +{
> +  EFI_STATUS                                 Status;
> +  UINT8                                      *ThisRequestData;
> +  UINT32                                     ThisRequestDataSize;
> +  MANAGEABILITY_TRANSFER_TOKEN               TransferToken;
> +  MANAGEABILITY_TRANSPORT_HEADER             IpmiTransportHeader;
> +  MANAGEABILITY_TRANSPORT_TRAILER            IpmiTransportTrailer;
> +  MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS  TransportAdditionalStatus;
> +
> +  if (TransportToken == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: No transport toke for IPMI\n", __FUNCTION__));
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Status = TransportToken->Transport->Function.Version1_0->TransportStatus (
> +                                                             TransportToken,
> +                                                             &TransportAdditionalStatus
> +                                                             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Transport for IPMI has problem - (%r)\n", __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  ThisRequestData       = RequestData;
> +  ThisRequestDataSize   = RequestDataSize;
> +  IpmiTransportHeader  = NULL;
> +  IpmiTransportTrailer = NULL;
> +  Status               = SetupIpmiRequestTransportPacket (
> +                           TransportToken,
> +                           NetFunction,
> +                           Command,
> +                           &IpmiTransportHeader,
> +                           &ThisRequestData,
> +                           &ThisRequestDataSize,
> +                           &IpmiTransportTrailer
> +                           );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to build packets - (%r)\n", __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  ZeroMem (&TransferToken, sizeof (MANAGEABILITY_TRANSFER_TOKEN));
> +  TransferToken.TransmitHeader  = IpmiTransportHeader;
> +  TransferToken.TransmitTrailer = IpmiTransportTrailer;
> +
> +  // Transmit packet.
> +  if ((ThisRequestData == NULL) || (ThisRequestDataSize == 0)) {
> +
> +    // Transmit parameter were not changed by SetupIpmiRequestTransportPacket().
> +    TransferToken.TransmitPackage.TransmitPayload    = RequestData;
> +    TransferToken.TransmitPackage.TransmitSizeInByte = RequestDataSize;
> +  } else {
> +    TransferToken.TransmitPackage.TransmitPayload    = ThisRequestData;
> +    TransferToken.TransmitPackage.TransmitSizeInByte = ThisRequestDataSize;
> +  }
> +
> +  TransferToken.TransmitPackage.TransmitTimeoutInMillisecond = MANAGEABILITY_TRANSPORT_NO_TIMEOUT;
> +
> +  // Receive packet.
> +  TransferToken.ReceivePackage.ReceiveBuffer                = ResponseData;
> +  TransferToken.ReceivePackage.ReceiveSizeInByte            = *ResponseDataSize;
> +  TransferToken.ReceivePackage.TransmitTimeoutInMillisecond = MANAGEABILITY_TRANSPORT_NO_TIMEOUT;
> +  TransportToken->Transport->Function.Version1_0->TransportTransmitReceive (
> +                                                    TransportToken,
> +                                                    &TransferToken
> +                                                    );
> +
> +  if (IpmiTransportHeader != NULL) {
> +    FreePool ((VOID *)IpmiTransportHeader);
> +  }
> +
> +  if (IpmiTransportTrailer != NULL) {
> +    FreePool ((VOID *)IpmiTransportTrailer);
> +  }
> +
> +  if (ThisRequestData != NULL) {
> +    FreePool ((VOID *)ThisRequestData);
> +  }
> +
> +  // Return transfer status.
> +  //
> +  Status                    = TransferToken.TransferStatus;
> +  TransportAdditionalStatus = TransferToken.TransportAdditionalStatus;
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to send IPMI command.\n", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  if (ResponseDataSize != NULL) {
> +    *ResponseDataSize = TransferToken.ReceivePackage.ReceiveSizeInByte;
> +  }
> +  return Status;
> +}
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocol.c b/Features/ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocol.c
> new file mode 100644
> index 0000000000..05175ee448
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocol.c
> @@ -0,0 +1,177 @@
> +/** @file
> +  This file provides IPMI Protocol implementation.
> +
> +  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiDxe.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/ManageabilityTransportLib.h>
> +#include <Library/ManageabilityTransportIpmiLib.h>
> +#include <Library/ManageabilityTransportHelperLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/IpmiProtocol.h>
> +
> +#include "IpmiProtocolCommon.h"
> +
> +MANAGEABILITY_TRANSPORT_TOKEN  *mTransportToken = NULL;
> +CHAR16                         *mTransportName;
> +
> +MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION  mHardwareInformation;
> +
> +/**
> +  This service enables submitting commands via Ipmi.
> +
> +  @param[in]         This              This point for IPMI_PROTOCOL structure.
> +  @param[in]         NetFunction       Net function of the command.
> +  @param[in]         Command           IPMI Command.
> +  @param[in]         RequestData       Command Request Data.
> +  @param[in]         RequestDataSize   Size of Command Request Data.
> +  @param[out]        ResponseData      Command Response Data. The completion code is the first byte of response data.
> +  @param[in, out]    ResponseDataSize  Size of Command Response Data.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully submit to the device and a response was successfully received.
> +  @retval EFI_NOT_FOUND          The command was not successfully sent to the device or a response was not successfully received from the device.
> +  @retval EFI_NOT_READY          Ipmi Device is not ready for Ipmi command access.
> +  @retval EFI_DEVICE_ERROR       Ipmi Device hardware error.
> +  @retval EFI_TIMEOUT            The command time out.
> +  @retval EFI_UNSUPPORTED        The command was not successfully sent to the device.
> +  @retval EFI_OUT_OF_RESOURCES   The resource allocation is out of resource or data size error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DxeIpmiSubmitCommand (
> +  IN     IPMI_PROTOCOL  *This,
> +  IN     UINT8          NetFunction,
> +  IN     UINT8          Command,
> +  IN     UINT8          *RequestData,
> +  IN     UINT32         RequestDataSize,
> +  OUT    UINT8          *ResponseData,
> +  IN OUT UINT32         *ResponseDataSize
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = CommonIpmiSubmitCommand (
> +             mTransportToken,
> +             NetFunction,
> +             Command,
> +             RequestData,
> +             RequestDataSize,
> +             ResponseData,
> +             ResponseDataSize
> +             );
> +  return Status;
> +}
> +
> +static IPMI_PROTOCOL  mIpmiProtocol = {
> +  DxeIpmiSubmitCommand
> +};
> +
> +/**
> +  The entry point of the Ipmi DXE driver.
> +
> +  @param[in] ImageHandle - Handle of this driver image
> +  @param[in] SystemTable - Table containing standard EFI services
> +
> +  @retval EFI_SUCCESS    - IPMI Protocol is installed successfully.
> +  @retval Otherwise      - Other errors.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DxeIpmiEntry (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                                 Status;
> +  EFI_HANDLE                                 Handle;
> +  MANAGEABILITY_TRANSPORT_CAPABILITY         TransportCapability;
> +  MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS  TransportAdditionalStatus;
> +
> +  GetTransportCapability (&TransportCapability);
> +
> +  Status = HelperAcquireManageabilityTransport (
> +             &gManageabilityProtocolIpmiGuid,
> +             &mTransportToken
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to acquire transport interface for IPMI protocol - %r\n", __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  mTransportName = HelperManageabilitySpecName (mTransportToken->Transport->ManageabilityTransportSpecification);
> +  DEBUG ((DEBUG_INFO, "%a: IPMI protocol over %s.\n", __FUNCTION__, mTransportName));
> +
> +  //
> +  // Setup hardware information according to the transport interface.
> +  Status = SetupIpmiTransportHardwareInformation (
> +             mTransportToken,
> +             &mHardwareInformation
> +             );
> +  if (EFI_ERROR (Status)) {
> +    if (Status == EFI_UNSUPPORTED) {
> +      DEBUG ((DEBUG_ERROR, "%a: No hardware information of %s transport interface.\n", __FUNCTION__, mTransportName));
> +    }
> +
> +    return Status;
> +  }
> +
> +  //
> +  // Initial transport interface with the hardware information assigned.
This, I think is not a comment style defined in the EDK2 coding style.
> +  Status = HelperInitManageabilityTransport (
> +             mTransportToken,
> +             mHardwareInformation,
> +             &TransportAdditionalStatus
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +

At here, everything is ready to go. We will install the protocol and 
done. But what about the "Host's partner"?

IPMI protocol is usually to use to communicate between Host and BMC. In 
some systems,

BMC will provide a mechanism to the host to notify it that everything is 
fine and that it is ready to communicate (the common way is GPIO).

What if we issue a request to BMC, and BMC fails to respond or returns 
dummy data?

On one level, it is an enhancement feature, and it is not supported by 
all platforms.  Why don't we support a library/protocol

that allows platforms to choose whether or not to issue a request?. 
Because the problem could occur at any time, we should check before 
starting a request.

It can be put into CommonIpmiSubmitCommand ().


Why not include it in ManageabilityTransportLib? Because that is the 
IPMI issue,

the KCS controller is fine, the I2C controller is fine, and the BMC is 
ready to communicate via MCTP, but IPMI is stuck

I'm happy when you can assist with this. Personally, I love Protocol more

- Tinh

> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gIpmiProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  (VOID **)&mIpmiProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to install IPMI protocol - %r\n", __FUNCTION__, Status));
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This is the unload handler for IPMI protocol module.
> +
> +  Release the MANAGEABILITY_TRANSPORT_TOKEN acquired at entry point.
> +
> +  @param[in] ImageHandle           The drivers' driver image.
> +
> +  @retval    EFI_SUCCESS           The image is unloaded.
> +  @retval    Others                Failed to unload the image.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IpmiUnloadImage (
> +  IN EFI_HANDLE  ImageHandle
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = EFI_SUCCESS;
> +  if (mTransportToken != NULL) {
> +    Status = ReleaseTransportSession (mTransportToken);
> +  }
> +
> +  if (mHardwareInformation.Pointer != NULL) {
> +    FreePool (mHardwareInformation.Pointer);
> +  }
> +
> +  return Status;
> +}
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpi.c b/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpi.c
> new file mode 100644
> index 0000000000..f839cd7387
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Pei/IpmiPpi.c
> @@ -0,0 +1,159 @@
> +/** @file
> +  This file provides IPMI PPI implementation.
> +
> +  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/ManageabilityTransportLib.h>
> +#include <Library/ManageabilityTransportIpmiLib.h>
> +#include <Library/ManageabilityTransportHelperLib.h>
> +#include <Library/PeiServicesLib.h>
> +
> +#include <Ppi/IpmiPpi.h>
> +
> +#include "IpmiProtocolCommon.h"
> +#include "IpmiPpiInternal.h"
> +
> +/**
> +  This service enables submitting commands via Ipmi.
> +
> +  @param[in]         This              This point for PEI_IPMI_PPI structure.
> +  @param[in]         NetFunction       Net function of the command.
> +  @param[in]         Command           IPMI Command.
> +  @param[in]         RequestData       Command Request Data.
> +  @param[in]         RequestDataSize   Size of Command Request Data.
> +  @param[out]        ResponseData      Command Response Data. The completion code is the first byte of response data.
> +  @param[in, out]    ResponseDataSize  Size of Command Response Data.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully submit to the device and a response was successfully received.
> +  @retval EFI_NOT_FOUND          The command was not successfully sent to the device or a response was not successfully received from the device.
> +  @retval EFI_NOT_READY          Ipmi Device is not ready for Ipmi command access.
> +  @retval EFI_DEVICE_ERROR       Ipmi Device hardware error.
> +  @retval EFI_TIMEOUT            The command time out.
> +  @retval EFI_UNSUPPORTED        The command was not successfully sent to the device.
> +  @retval EFI_OUT_OF_RESOURCES   The resource allocation is out of resource or data size error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiIpmiSubmitCommand (
> +  IN     PEI_IPMI_PPI  *This,
> +  IN     UINT8         NetFunction,
> +  IN     UINT8         Command,
> +  IN     UINT8         *RequestData,
> +  IN     UINT32        RequestDataSize,
> +  OUT    UINT8         *ResponseData,
> +  IN OUT UINT32        *ResponseDataSize
> +  )
> +{
> +  EFI_STATUS            Status;
> +  PEI_IPMI_PPI_INTERNAL *PeiIpmiPpiinternal;
> +
> +  PeiIpmiPpiinternal = MANAGEABILITY_IPMI_PPI_INTERNAL_FROM_LINK(This);
> +  Status = CommonIpmiSubmitCommand (
> +             PeiIpmiPpiinternal->TransportToken,
> +             NetFunction,
> +             Command,
> +             RequestData,
> +             RequestDataSize,
> +             ResponseData,
> +             ResponseDataSize
> +             );
> +  return Status;
> +}
> +
> +/**
> +  The entry point of the Ipmi PPI PEIM.
> +
> +  @param  FileHandle  Handle of the file being invoked.
> +  @param  PeiServices Describes the list of possible PEI Services.
> +
> +  @retval EFI_SUCCESS   Indicates that Ipmi initialization completed successfully.
> +  @retval Others        Indicates that Ipmi initialization could not complete successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiIpmiEntry (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  EFI_STATUS                                    Status;
> +  CHAR16                                        *TransportName;
> +  PEI_IPMI_PPI_INTERNAL                         *PeiIpmiPpiinternal;
> +  EFI_PEI_PPI_DESCRIPTOR                        *PpiDescriptor;
> +  MANAGEABILITY_TRANSPORT_CAPABILITY            TransportCapability;
> +  MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS     TransportAdditionalStatus;
> +  MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION  HardwareInformation;
> +
> +  PeiIpmiPpiinternal = (PEI_IPMI_PPI_INTERNAL *)AllocateZeroPool (sizeof(PEI_IPMI_PPI_INTERNAL));
> +  if (PeiIpmiPpiinternal == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Not enough memory for PEI_IPMI_PPI_INTERNAL.\n", __FUNCTION__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  PpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)AllocateZeroPool (sizeof(EFI_PEI_PPI_DESCRIPTOR));
> +  if (PpiDescriptor == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Not enough memory for EFI_PEI_PPI_DESCRIPTOR.\n", __FUNCTION__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  PeiIpmiPpiinternal->Signature = MANAGEABILITY_IPMI_PPI_INTERNAL_SIGNATURE;
> +  PeiIpmiPpiinternal->PeiIpmiPpi.IpmiSubmitCommand = PeiIpmiSubmitCommand;
> +
> +  PpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  PpiDescriptor->Guid  = &gPeiIpmiPpiGuid;
> +  PpiDescriptor->Ppi   = &PeiIpmiPpiinternal->PeiIpmiPpi;
> +
> +  GetTransportCapability (&TransportCapability);
> +  Status = HelperAcquireManageabilityTransport (
> +             &gManageabilityProtocolIpmiGuid,
> +             &PeiIpmiPpiinternal->TransportToken
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to acquire transport interface for IPMI protocol - %r\n", __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  TransportName = HelperManageabilitySpecName (PeiIpmiPpiinternal->TransportToken->Transport->ManageabilityTransportSpecification);
> +  DEBUG ((DEBUG_INFO, "%a: IPMI protocol over %s.\n", __FUNCTION__, TransportName));
> +
> +  //
> +  // Setup hardware information according to the transport interface.
> +  Status = SetupIpmiTransportHardwareInformation (
> +             PeiIpmiPpiinternal->TransportToken,
> +             &HardwareInformation
> +             );
> +  if (EFI_ERROR (Status)) {
> +    if (Status == EFI_UNSUPPORTED) {
> +      DEBUG ((DEBUG_ERROR, "%a: No hardware information of %s transport interface.\n", __FUNCTION__, TransportName));
> +    }
> +
> +    return Status;
> +  }
> +
> +  //
> +  // Initial transport interface with the hardware information assigned.
> +  Status = HelperInitManageabilityTransport (
> +             PeiIpmiPpiinternal->TransportToken,
> +             HardwareInformation,
> +             &TransportAdditionalStatus
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Install IPMI PPI.
> +  //
> +  Status = PeiServicesInstallPpi (PpiDescriptor);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to install IPMI PPI - %r\n", __FUNCTION__, Status));
> +  }
> +
> +  return Status;
> +}
> diff --git a/Features/ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocol.c b/Features/ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocol.c
> new file mode 100644
> index 0000000000..87a5436bdf
> --- /dev/null
> +++ b/Features/ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocol.c
> @@ -0,0 +1,147 @@
> +/** @file
> +  This file provides IPMI SMM Protocol implementation.
> +
> +  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiDxe.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/ManageabilityTransportLib.h>
> +#include <Library/ManageabilityTransportIpmiLib.h>
> +#include <Library/ManageabilityTransportHelperLib.h>
> +#include <Library/SmmServicesTableLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <Protocol/IpmiProtocol.h>
> +
> +#include "IpmiProtocolCommon.h"
> +
> +MANAGEABILITY_TRANSPORT_TOKEN  *mTransportToken = NULL;
> +CHAR16                         *mTransportName;
> +
> +MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION  mHardwareInformation;
> +
> +/**
> +  This service enables submitting commands via Ipmi.
> +
> +  @param[in]         This              This point for IPMI_PROTOCOL structure.
> +  @param[in]         NetFunction       Net function of the command.
> +  @param[in]         Command           IPMI Command.
> +  @param[in]         RequestData       Command Request Data.
> +  @param[in]         RequestDataSize   Size of Command Request Data.
> +  @param[out]        ResponseData      Command Response Data. The completion code is the first byte of response data.
> +  @param[in, out]    ResponseDataSize  Size of Command Response Data.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully submit to the device and a response was successfully received.
> +  @retval EFI_NOT_FOUND          The command was not successfully sent to the device or a response was not successfully received from the device.
> +  @retval EFI_NOT_READY          Ipmi Device is not ready for Ipmi command access.
> +  @retval EFI_DEVICE_ERROR       Ipmi Device hardware error.
> +  @retval EFI_TIMEOUT            The command time out.
> +  @retval EFI_UNSUPPORTED        The command was not successfully sent to the device.
> +  @retval EFI_OUT_OF_RESOURCES   The resource allocation is out of resource or data size error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmIpmiSubmitCommand (
> +  IN     IPMI_PROTOCOL  *This,
> +  IN     UINT8          NetFunction,
> +  IN     UINT8          Command,
> +  IN     UINT8          *RequestData,
> +  IN     UINT32         RequestDataSize,
> +  OUT    UINT8          *ResponseData,
> +  IN OUT UINT32         *ResponseDataSize
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = CommonIpmiSubmitCommand (
> +             mTransportToken,
> +             NetFunction,
> +             Command,
> +             RequestData,
> +             RequestDataSize,
> +             ResponseData,
> +             ResponseDataSize
> +             );
> +  return Status;
> +}
> +
> +static IPMI_PROTOCOL  mIpmiProtocol = {
> +  SmmIpmiSubmitCommand
> +};
> +
> +/**
> +  The entry point of the Ipmi DXE driver.
> +
> +  @param[in] ImageHandle - Handle of this driver image
> +  @param[in] SystemTable - Table containing standard EFI services
> +
> +  @retval EFI_SUCCESS    - IPMI Protocol is installed successfully.
> +  @retval Otherwise      - Other errors.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmIpmiEntry (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                                 Status;
> +  EFI_HANDLE                                 Handle;
> +  MANAGEABILITY_TRANSPORT_CAPABILITY         TransportCapability;
> +  MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS  TransportAdditionalStatus;
> +
> +  GetTransportCapability (&TransportCapability);
> +
> +  Status = HelperAcquireManageabilityTransport (
> +             &gManageabilityProtocolIpmiGuid,
> +             &mTransportToken
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to acquire transport interface for IPMI protocol - %r\n", __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  mTransportName = HelperManageabilitySpecName (mTransportToken->Transport->ManageabilityTransportSpecification);
> +  DEBUG ((DEBUG_INFO, "%a: IPMI protocol over %s.\n", __FUNCTION__, mTransportName));
> +
> +  //
> +  // Setup hardware information according to the transport interface.
> +  Status = SetupIpmiTransportHardwareInformation (
> +             mTransportToken,
> +             &mHardwareInformation
> +             );
> +  if (EFI_ERROR (Status)) {
> +    if (Status == EFI_UNSUPPORTED) {
> +      DEBUG ((DEBUG_ERROR, "%a: No hardware information of %s transport interface.\n", __FUNCTION__, mTransportName));
> +    }
> +
> +    return Status;
> +  }
> +
> +  //
> +  // Initial transport interface with the hardware information assigned.
> +  Status = HelperInitManageabilityTransport (
> +             mTransportToken,
> +             mHardwareInformation,
> +             &TransportAdditionalStatus
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Handle = NULL;
> +  Status = gSmst->SmmInstallProtocolInterface (
> +                    &Handle,
> +                    &gSmmIpmiProtocolGuid,
> +                    EFI_NATIVE_INTERFACE,
> +                    (VOID **)&mIpmiProtocol
> +                    );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to install IPMI SMM protocol - %r\n", __FUNCTION__, Status));
> +  }
> +
> +  return Status;
> +}

  reply	other threads:[~2023-03-23 19:41 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-22  2:48 [PATCH v4 1/9] ManageabilityPkg: Add Readme file Chang, Abner
2023-03-22  2:48 ` [PATCH v4 2/9] ManageabilityPkg: Initial package Chang, Abner
2023-03-23 18:02   ` [edk2-devel] " Isaac Oram
2023-03-28 12:37   ` Tinh Nguyen
2023-03-29  1:32     ` Chang, Abner
2023-03-30  8:52       ` Tinh Nguyen
2023-03-22  2:48 ` [PATCH v4 3/9] ManageabilityPkg: Add ManageabilityTransportLib header file Chang, Abner
2023-03-24  9:18   ` Nickle Wang
2023-03-24 11:18   ` Attar, AbdulLateef (Abdul Lateef)
2023-03-22  2:48 ` [PATCH v4 4/9] ManageabilityPkg: Add NULL ManageabilityTransportLib Chang, Abner
2023-03-24  9:19   ` Nickle Wang
2023-03-22  2:48 ` [PATCH v4 5/9] ManageabilityPkg: Add ManageabilityTransportHelperLib Chang, Abner
2023-03-23 18:30   ` [edk2-devel] " Tinh Nguyen
2023-04-15  6:12     ` Chang, Abner
2023-03-24  9:20   ` Nickle Wang
2023-03-22  2:48 ` [PATCH v4 6/9] ManageabilityPkg/ManageabilityTransportKcsLib Chang, Abner
2023-03-24  9:23   ` Nickle Wang
2023-03-22  2:48 ` [PATCH v4 7/9] ManageabilityPkg: Implement Ipmi Protocol/Ppi Chang, Abner
2023-03-23 19:40   ` Tinh Nguyen [this message]
2023-04-15  8:38     ` [edk2-devel] " Chang, Abner
2023-04-15 12:07       ` Chang, Abner
2023-03-24  9:25   ` Nickle Wang
2023-03-22  2:48 ` [PATCH v4 8/9] ManageabilityPkg: Add IpmiProtocol to Manageability Package Chang, Abner
2023-03-28 12:22   ` [edk2-devel] " Tinh Nguyen
2023-04-15  3:38     ` Chang, Abner
2023-03-22  2:48 ` [PATCH v4 9/9] edk2-platforms: Maintainers.txt Chang, Abner
2023-03-23 14:45   ` Leif Lindholm
2023-03-23 17:37     ` Isaac Oram
2023-03-24  3:06       ` Attar, AbdulLateef (Abdul Lateef)
2023-03-23 17:55 ` [edk2-devel] [PATCH v4 1/9] ManageabilityPkg: Add Readme file Isaac Oram
2023-03-24  9:17   ` Attar, AbdulLateef (Abdul Lateef)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4064fa08-dec2-91dd-ba42-42200eec7e55@amperemail.onmicrosoft.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox