public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel][edk2-platforms][PATCH V4-3] IpmiFeaturePkg:Provided multiple IPMI interface support in Library
@ 2023-07-03 14:48 Arun K
  0 siblings, 0 replies; only message in thread
From: Arun K @ 2023-07-03 14:48 UTC (permalink / raw)
  To: devel@edk2.groups.io, Arun K
  Cc: isaac.w.oram@intel.com, nathaniel.l.desimone@intel.com,
	Ramkumar Krishnamoorthi, Liming Gao

Created IpmiTransport2 PPI/Protocol to support multiple
IPMI BMC Interface support such as KCS/BT/SSIF/IPMB with 2 API's
IpmiSubmitCommand2 & IpmiSubmitCommand2Ex.
IpmiSubmitCommand2 - This API use the default interface
(PcdDefaultSystemInterface) to send IPMI command.
IpmiSubmitCommand2Ex - This API use the specific interface type
to send IPMI command which is passed as an argument.

Cc: Isaac Oram <isaac.w.oram@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>

Signed-off-by: Arun K <arunk@ami.com>
---
 .../IpmiFeaturePkg/Include/IpmiFeature.dsc    |  15 +
 .../Include/IpmiNetFnAppDefinitions.h         | 239 +++++++
 .../Include/IpmiTransport2Definitions.h       | 152 +++++
 .../Include/Library/BmcCommonInterfaceLib.h   | 227 +++++++
 .../Include/Library/BtInterfaceLib.h          |  78 +++
 .../Include/Library/IpmbInterfaceLib.h        |  94 +++
 .../Include/Library/SsifInterfaceLib.h        | 169 +++++
 .../Include/Ppi/IpmiTransport2Ppi.h           |  23 +
 .../Include/Protocol/IpmiTransport2Protocol.h |  29 +
 .../BmcCommonInterfaceLib.c                   | 256 ++++++++
 .../BmcCommonInterfaceLib.inf                 |  26 +
 .../BtInterfaceLib/BtInterfaceLib.c           | 605 ++++++++++++++++++
 .../BtInterfaceLib/BtInterfaceLib.inf         |  39 ++
 .../IpmbInterfaceLib/DxeIpmbInterfaceLib.c    | 103 +++
 .../IpmbInterfaceLib/DxeIpmbInterfaceLib.inf  |  38 ++
 .../IpmbInterfaceLib/IpmbInterfaceLibCommon.c | 378 +++++++++++
 .../IpmbInterfaceLib/PeiIpmbInterfaceLib.c    | 108 ++++
 .../IpmbInterfaceLib/PeiIpmbInterfaceLib.inf  |  38 ++
 .../IpmbInterfaceLib/SmmIpmbInterfaceLib.c    | 104 +++
 .../IpmbInterfaceLib/SmmIpmbInterfaceLib.inf  |  37 ++
 .../SsifInterfaceLib/DxeSsifInterfaceLib.c    | 137 ++++
 .../SsifInterfaceLib/DxeSsifInterfaceLib.inf  |  40 ++
 .../SsifInterfaceLib/PeiSsifInterfaceLib.c    | 128 ++++
 .../SsifInterfaceLib/PeiSsifInterfaceLib.inf  |  41 ++
 .../SsifInterfaceLib/SmmSsifInterfaceLib.c    | 156 +++++
 .../SsifInterfaceLib/SmmSsifInterfaceLib.inf  |  40 ++
 .../SsifInterfaceLib/SsifInterfaceLibCommon.c | 577 +++++++++++++++++
 27 files changed, 3877 insertions(+)
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiNetFnAppDefinitions.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiTransport2Definitions.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BmcCommonInterfaceLib.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BtInterfaceLib.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/IpmbInterfaceLib.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/SsifInterfaceLib.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/IpmiTransport2Ppi.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/IpmiTransport2Protocol.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c

diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc
index 237a4fc006..0401974b82 100644
--- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc
@@ -7,6 +7,7 @@
 # for the build infrastructure.

 #

 # Copyright (c) 2019 - 2021, Intel Corporation. All rights reserved.<BR>

+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>

 #

 # SPDX-License-Identifier: BSD-2-Clause-Patent

 #

@@ -41,10 +42,24 @@


 [LibraryClasses.common.PEI_CORE,LibraryClasses.common.PEIM]

   IpmiBaseLib|IpmiFeaturePkg/Library/PeiIpmiBaseLib/PeiIpmiBaseLib.inf

+  SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf

+  IpmbInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf



 [LibraryClasses.common.DXE_DRIVER,LibraryClasses.common.UEFI_DRIVER]

   IpmiBaseLib|IpmiFeaturePkg/Library/IpmiBaseLib/IpmiBaseLib.inf



+[LibraryClasses.common]

+  BmcCommonInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.inf

+  BtInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf

+

+[LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]

+  SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf

+  IpmbInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf

+

+[LibraryClasses.common.DXE_SMM_DRIVER]

+  SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf

+  IpmbInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf

+

 ################################################################################

 #

 # Component section - list of all components that need built for this feature.

diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiNetFnAppDefinitions.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiNetFnAppDefinitions.h
new file mode 100644
index 0000000000..7ee6fb1ff3
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiNetFnAppDefinitions.h
@@ -0,0 +1,239 @@
+/** @file IpmiNetFnAppDefinitions.h
+  Ipmi NetFn Application additional commands and its structures.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMI_NETFN_APP_DEFINITIONS_H_
+#define _IPMI_NETFN_APP_DEFINITIONS_H_
+
+#include <IndustryStandard/IpmiNetFnApp.h>
+
+#define IPMI_SPEC_VERSION_1_5       0x51
+#define IPMI_SPEC_VERSION_2_0       0x02
+#define IPMI_APP_SELFTEST_RESERVED  0xFF
+
+#pragma pack(1)
+
+/**
+  Get Bmc global enables command response.
+*/
+typedef struct {
+  /// Completion code.
+  UINT8    CompletionCode;
+  UINT8    ReceiveMsgQueueInterrupt    : 1; ///< Receive Message Queue Interrupt.
+  UINT8    EventMsgBufferFullInterrupt : 1; ///< Event Message Buffer Full Interrupt.
+  UINT8    EventMsgBuffer              : 1; ///< Event Message Buffer.
+  UINT8    SystemEventLogging          : 1; ///< System Event Logging.
+  UINT8    Reserved                    : 1; ///< Reserved.
+  UINT8    OEM0                        : 1; ///< OEM0 interrupt.
+  UINT8    OEM1                        : 1; ///< OEM1 interrupt.
+  UINT8    OEM2                        : 1; ///< OEM2 interrupt.
+} GET_BMC_GLOBAL_ENABLES_RESPONSE;
+
+/**
+  Channel access type.
+ */
+typedef enum {
+  ChannelAccessTypeReserved0,              ///< Reserved0
+  ChannelAccessTypeNonVolatile,            ///< NonVolatile
+  ChannelAccessTypePresentVolatileSetting, ///< PresentVolatileSetting
+  ChannelAccessTypeReserved1               ///< Reserved1
+} CHANNEL_ACCESS_TYPE;
+
+/**
+  Channel access modes.
+*/
+typedef enum {
+  ChannelAccessModeDisabled,          ///< Disabled Channel Access Mode.
+  ChannelAccessModePreBootOnly,       ///< Pre-Boot Only Channel Access Mode.
+  ChannelAccessModeAlwaysAvailable,   ///< Always Available Channel Access Mode.
+  ChannelAccessModeShared             ///< Shared Channel Access Mode.
+} CHANNEL_ACCESS_MODES;
+
+/**
+  SSIF read/write support.
+*/
+typedef enum {
+  SsifSinglePartRw,           ///< Single Part read-write.
+  SsifMultiPartRw,            ///< Multi Part read-write.
+  SsifMultiPartRwWithMiddle,  ///< Multi Part read-write With Middle.
+  SsifReserved                ///< Reserved.
+} SSIF_READ_WRITE_SUPPORT;
+
+/**
+  Channnel states.
+*/
+typedef enum {
+  DisbleChannel = 0,   ///< Disble Channel.
+  EnableChannel,       ///< Enable Channel.
+  GetChannelState,     ///< Get Channel State.
+  ChannelStateReserved ///< Channel State Reserved.
+} CHANNEL_STATE;
+
+/**
+  Enable message channel command request structure.
+*/
+typedef struct {
+  UINT8    ChannelNumber : 4;         /// Channel Number.
+  UINT8    Reserved1     : 4;         ///< Reserved.
+  UINT8    ChannelState  : 2;         ///< Channel State.
+  UINT8    Reserved2     : 6;         ///< Reserved.
+} IPMI_ENABLE_MESSAGE_CHANNEL_REQUEST;
+
+/**
+  Enable message channel command response structure.
+*/
+typedef struct {
+  UINT8    CompletionCode;            /// Completion code.
+  UINT8    ChannelNumber : 4;         ///< Channel Number.
+  UINT8    Reserved1     : 4;         ///< Reserved.
+  UINT8    ChannelState  : 1;         ///< Channel State.
+  UINT8    Reserved2     : 7;         ///< Reserved.
+} IPMI_ENABLE_MESSAGE_CHANNEL_RESPONSE;
+
+/**
+  Set System Info Parameters Command.
+*/
+#define IPMI_APP_SET_SYSTEM_INFO  0x58
+
+/**
+  System Info String Encoding.
+*/
+typedef enum {
+  SysInfoAscii,    ///< Ascii
+  SysInfoUtf8,     ///< Utf8
+  SysInfoUnicode   ///< Unicode
+} SYSTEM_INFO_STRING_ENCODING;
+
+/**
+  System parameter selector.
+*/
+typedef enum {
+  SysInfoSetInProgress,    ///< SetInProgress.
+  SysInfoFirmwareVersion,  ///< FirmwareVersion.
+  SysInfoSystemName,       ///< SystemName.
+  SysInfoPrimaryOsName,    ///< PrimaryOsName.
+  SysInfoPresentOsName,    ///< PresentOsName.
+  SysInfoPresentOsVersion, ///< PresentOsVersion.
+  SysInfoBmcUrl,           ///< BmcUrl.
+  SysInfoHyperviserUrl,    ///< HyperviserUrl.
+} SYSTEM_INFO_PARAMETER_SELECTOR;
+
+/**
+  System info set state.
+*/
+typedef enum {
+  SysInfoStateSetComplete,     ///< SetComplete.
+  SysInfoStateSetInProgress,   ///< SetInProgress.
+  SysInfoStateCommitWrite,     ///< StateCommitWrite.
+  SysInfoStateReserved,        ///< StateReserved.
+} SYSTEM_INFO_SET_STATE;
+
+/**
+  Set system info parameter command request Structure.
+*/
+typedef struct {
+  UINT8    ParamSelector;               /// Parameter selector.
+  UINT8    SetSelector;                 ///< Data 1
+  UINT8    Data[16];                    ///< Data 2:17
+} SET_SYSTEM_INFO_REQUEST;
+
+/**
+  Get System Info Parameters Command.
+*/
+#define IPMI_APP_GET_SYSTEM_INFO  0x59
+
+/**
+  Get system info Command request Structure.
+*/
+typedef struct {
+  UINT8    Reserved : 7;          /// Reserved.
+  UINT8    GetParam : 1;          ///< Get Parameter.
+  UINT8    ParamSelector;         ///< Parameter Selector.
+  UINT8    SetSelector;           ///< Set selector.
+  UINT8    BlockSelector;         ///< Block selector.
+} GET_SYSTEM_INFO_REQUEST;
+
+/**
+  Get system info command response Structure.
+*/
+typedef struct {
+  UINT8    CompletionCode;            /// Completion code.
+  UINT8    ParamRevision;             /// Parameter Revision
+  union {
+    struct {
+      UINT8    State    : 2;          ///< State.
+      UINT8    Reserved : 6;          ///< Reserved.
+    } Progress;
+    UINT8    SetSelector;             ///< Set Selector.
+  } Data1;
+  UINT8    Data[16];                  ///< Data 2:17.
+} GET_SYSTEM_INFO_RESPONSE;
+
+/**
+  Get system Guid Command response Structure.
+*/
+typedef struct {
+  UINT8     CompletionCode;      /// Completion code.
+  UINT8     Node[6];             ///< Node.
+  UINT8     Clock[2];            ///< Clock.
+  UINT16    Time_High;           ///< Time High.
+  UINT16    Time_Mid;            ///< Time Middle.
+  UINT32    Time_Low;            ///< Time Low.
+} GET_SYSTEM_GUID_RESPONSE;
+
+/**
+  Get Bt interface Capability Command response Structure.
+*/
+typedef struct {
+  UINT8    CompletionCode;        /// Completion code.
+  UINT8    OutstaningReq;         ///< Number of outstanding requests supported.
+  UINT8    InputBuffSize;         ///< Input (request) buffer message size in bytes.
+  UINT8    OutputBuffSize;        ///< Output (response) buffer message size in bytes.
+  UINT8    BmcReqToResTime;       ///< BMC Request-to-Response time, in seconds.
+  UINT8    RecommandedRetires;    ///< Recommended retries (1 based
+} IPMI_BT_INTERFACE_CAPABILITY_RES;
+
+/**
+  Get System interface Capability Command request Structure.
+*/
+typedef struct {
+  UINT8    SystemInterfaceType : 4;     /// System Interface Type 0h = SSIF,1h = KCS ,2h = SMIC.
+  UINT8    Reserved            : 4;     ///< Reserved.
+} IPMI_GET_SYSTEM_INTERFACE_CAPABILITY_REQ;
+
+/**
+  Get System interface Capability Command response Structure.
+*/
+typedef struct {
+  UINT8    CompletionCode;            /// Completion code.
+  UINT8    Reserved;                  ///< Reserved.
+  UINT8    SsifVersion        : 3;    ///< Ssif Version.
+  UINT8    PecSupport         : 1;    ///< Pec Support.
+  UINT8    Reserved1          : 2;    ///< Reserved.
+  UINT8    TransactionSupport : 2;    ///< Transaction Support.
+  UINT8    InputMessageSize;          ///< Input Message Size.
+  UINT8    OutputMessageSize;         ///< Output Message Size.
+} IPMI_GET_SYSTEM_INTERFACE_CAPABILITY_RES;
+
+/**
+  Get BMC global Enable Command response Structure.
+*/
+typedef struct {
+  UINT8    CompletionCode;                      /// Completion code.
+  UINT8    ReceiveMsgQueueInterrupt    : 1;     ///< Receive Message Queue Interrupt Enable bit.
+  UINT8    EventMsgBufferFullInterrupt : 1;     ///< Event Message Buffer Full Interrupt Enable bit.
+  UINT8    EventMsgBuffer              : 1;     ///< Event Message Buffer Enable bit.
+  UINT8    SystemEventLogging          : 1;     ///< System Event Logging Enable bit.
+  UINT8    Reserved                    : 1;     ///< Reserved.
+  UINT8    OEM0                        : 1;     ///< oem0 Enable bit.
+  UINT8    OEM1                        : 1;     ///< oem1 Enable bit.
+  UINT8    OEM2                        : 1;     ///< Oem2 Enable bit.
+} IPMI_BMC_GLOBAL_ENABLES_RES;
+#pragma pack()
+
+#endif // #ifndef _IPMI_NETFN_APP_DEFINITIONS_H_
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiTransport2Definitions.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiTransport2Definitions.h
new file mode 100644
index 0000000000..74b4d8743e
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiTransport2Definitions.h
@@ -0,0 +1,152 @@
+/** @file IpmiTransport2Definitions.h
+  Bmc Common interface library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMI_TRANSPORT2_DEFINITIONS_H_
+#define _IPMI_TRANSPORT2_DEFINITIONS_H_
+
+typedef struct _IPMI_TRANSPORT2 IPMI_TRANSPORT2;
+
+/** @internal
+  BT Interface.
+*/
+typedef struct {
+  UINT8      InterfaceState;       /// Interface state.
+  UINT16     CtrlPort;             ///< Control port.
+  UINT16     ComBuffer;            ///< Communication buffer port.
+  UINT16     IntMaskPort;          ///< Interrupt mask port.
+  UINTN      MmioBaseAddress;      ///< Mmio base address.
+  UINTN      BaseAddressRange;     ///< Mmio base address range to
+                                   ///< differentiate port address.
+  UINT8      AccessType;           ///< Access type - IO or MMIO.
+  UINT32     BtRetryCount;         ///< Delay counter for retry.
+  UINT8      BtSoftErrorCount;     ///< Soft error count.
+  BOOLEAN    BtTransportLocked;    ///< Interface lock.
+  UINT8      HosttoBmcBufferSize;  ///< Host to Bmc Buffer Size.
+  UINT8      BmctoHostBufferSize;  ///< Bmc to Host Buffer Size.
+} BT_SYSTEM_INTERFACE;
+
+/** @internal
+  SSIF Interface.
+*/
+typedef struct {
+  UINT8       InterfaceState;       /// Interface state.
+  EFI_GUID    SsifInterfaceApiGuid; ///< Smbus instance guid.
+  UINTN       SsifInterfaceApiPtr;  ///< Smbus instance pointer.
+  UINT8       RwSupport;            ///< Read-write support.
+  UINT16      SsifRetryCounter;     ///< Retry counter.
+  BOOLEAN     PecSupport;           ///< Packet Error Check support.
+  BOOLEAN     SmbAlertSupport;      ///< Smbus alert support.
+  UINT8       SsifSoftErrorCount;   ///< Soft error count.
+  BOOLEAN     SsifTransportLocked;  ///< Interface lock.
+} SSIF_SYSTEM_INTERFACE;
+
+/** @internal
+  IPMB Interface.
+*/
+typedef struct {
+  /// Interface state.
+  UINT8       InterfaceState;
+  EFI_GUID    IpmbInterfaceApiGuid; ///< Ipmb instance guid.
+  UINTN       IpmbInterfaceApiPtr;  ///< Ipmb instance pointer.
+  UINT8       IpmbSoftErrorCount;   ///< Soft error count.
+  BOOLEAN     IpmbTransportLocked;  ///< Interface lock.
+} IPMB_SYSTEM_INTERFACE;
+
+/** @internal
+  System Interface.
+*/
+typedef struct {
+  UINT8                    KcsInterfaceState;
+  BT_SYSTEM_INTERFACE      Bt;       ///< Bt interface.
+  SSIF_SYSTEM_INTERFACE    Ssif;     ///< Ssif interface.
+  IPMB_SYSTEM_INTERFACE    Ipmb;
+} IPMI_SYSTEM_INTERFACE;
+
+/** @inrernal
+  Ipmi Interface Access Type.
+*/
+typedef enum {
+  IpmiMmioAccess,  ///< Mmio Access.
+  IpmiIoAccess     ///< Io Access.
+} IPMI_ACCESS_TYPE;
+
+/** @internal
+  Host to BMC Interface Type.
+*/
+typedef enum {
+  SysInterfaceUnknown,    ///< Unknown interface type.
+  SysInterfaceKcs,        ///< Kcs interface.
+  SysInterfaceSmic,       ///< Smic interface.
+  SysInterfaceBt,         ///< Bt interface.
+  SysInterfaceSsif,       ///< Ssif interface.
+  SysInterfaceIpmb,       ///< Ipmb interface.
+  SysInterfaceMax         ///< Maximum interface type.
+} SYSTEM_INTERFACE_TYPE;
+
+/** @internal
+  BMC Interface status.
+*/
+typedef enum {
+  BmcStatusOk,                 ///< Bmc status Ok.
+  BmcStatusSoftFail,           ///< Bmc status Soft fail.
+  BmcStatusHardFail,           ///< Bmc status Hard fail.
+  BmcStatusUpdateInProgress    ///< Bmc status Update in progress.
+} BMC_INTERFACE_STATUS;
+
+/** @internal
+  Ipmi Interface state.
+*/
+typedef enum {
+  IpmiInterfaceNotReady,       ///< Interface Not Ready.
+  IpmiInterfaceInitialized,    ///< Interface Initialized.
+  IpmiInterfaceInitError,      ///< Interface Initialization Error.
+} IPMI_INTERFACE_STATE;
+
+//
+//  IPMI Function Prototypes
+//
+typedef
+  EFI_STATUS
+(EFIAPI *IPMI_SEND_COMMAND2)(
+                             IN IPMI_TRANSPORT2                   *This,
+                             IN UINT8                             NetFunction,
+                             IN UINT8                             Lun,
+                             IN UINT8                             Command,
+                             IN UINT8                             *CommandData,
+                             IN UINT32                            CommandDataSize,
+                             OUT UINT8                            *ResponseData,
+                             OUT UINT32                           *ResponseDataSize
+                             );
+
+typedef
+  EFI_STATUS
+(EFIAPI *IPMI_SEND_COMMAND2Ex)(
+                               IN IPMI_TRANSPORT2                   *This,
+                               IN UINT8                             NetFunction,
+                               IN UINT8                             Lun,
+                               IN UINT8                             Command,
+                               IN UINT8                             *CommandData,
+                               IN UINT32                            CommandDataSize,
+                               OUT UINT8                            *ResponseData,
+                               OUT UINT32                           *ResponseDataSize,
+                               IN SYSTEM_INTERFACE_TYPE             InterfaceType
+                               );
+
+struct _IPMI_TRANSPORT2 {
+  UINT64                   Revision;
+  IPMI_SEND_COMMAND2       IpmiSubmitCommand2;
+  IPMI_SEND_COMMAND2Ex     IpmiSubmitCommand2Ex;
+  IPMI_SYSTEM_INTERFACE    Interface;                ///< System interface.
+  SYSTEM_INTERFACE_TYPE    InterfaceType;            ///< Bmc Interface Type.
+  BMC_INTERFACE_STATUS     IpmiTransport2BmcStatus;
+  EFI_HANDLE               IpmiHandle;
+  UINT8                    CompletionCode;
+};
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BmcCommonInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BmcCommonInterfaceLib.h
new file mode 100644
index 0000000000..54f7b3c1c3
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BmcCommonInterfaceLib.h
@@ -0,0 +1,227 @@
+/** @file BmcCommonInterfaceLib.h
+  Bmc Common interface library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BMC_COMMON_INTERFACE_LIB_H_
+#define _BMC_COMMON_INTERFACE_LIB_H_
+
+#include <IndustryStandard/IpmiNetFnApp.h>
+#include <IpmiTransport2Definitions.h>
+#include <ServerManagement.h>
+
+#define IPMI_APP_SELFTEST_RESERVED  0xFF
+
+#define IPMI_GET_SET_IN_PROGRESS_RETRY_COUNT  10
+#define IPMI_BIT_CLEAR                        0
+#define IPMI_SELECTOR_NONE                    0
+#define IPMI_CLEAR_FLAG                       0
+#define IPMI_SET_FLAG                         1
+#define IPMI_STALL                            1000
+#define MIN_TO_100MS                          60 * 10
+#define MAX_BMC_CMD_FAIL_COUNT                10
+
+// Completion code macros.
+#define IPMI_COMPLETION_CODE_SUCCESS                 0x00
+#define IPMI_COMPLETION_CODE_DEVICE_SPECIFIC_START   0x01
+#define IPMI_COMPLETION_CODE_DEVICE_SPECIFIC_END     0x7E
+#define IPMI_COMPLETION_CODE_COMMAND_SPECIFIC_START  0x80
+#define IPMI_COMPLETION_CODE_COMMAND_SPECIFIC_END    0xBE
+#define IPMI_MAX_SOFT_COUNT                          10
+
+#define IPMI_MAX_BT_CMD_DATA_SIZE  0xFF
+
+#define IPMI_ERROR_COMPLETION_CODE(a)  !((a == IPMI_COMPLETION_CODE_SUCCESS) ||   \
+                                             ((a >= IPMI_COMPLETION_CODE_DEVICE_SPECIFIC_START) && \
+                                              (a <= IPMI_COMPLETION_CODE_DEVICE_SPECIFIC_END)) || \
+                                             ((a >= IPMI_COMPLETION_CODE_COMMAND_SPECIFIC_START) && \
+                                              (a <= IPMI_COMPLETION_CODE_COMMAND_SPECIFIC_END)) \
+                                             )
+
+/*++
+
+Routine Description:
+  Read 8 bit data from BMC port based on access type.
+
+Arguments:
+  AccessType - Specifies MMIO or IO access.
+  Address    - Specifies Address to read.
+
+Returns:
+  UINT8 - Data read.
+
+--*/
+UINT8
+IpmiBmcRead8 (
+  IN UINT8  AccessType,
+  IN UINTN  Address
+  );
+
+/*++
+
+Routine Description:
+  Write 8 bit data to BMC port based on access type.
+
+Arguments:
+  AccessType - Specifies MMIO or IO access.
+  Address    - Specifies Address to write.
+  Data       - Specifies data to be written.
+
+Returns:
+  UINT8 - Data written.
+
+--*/
+UINT8
+IpmiBmcWrite8 (
+  IN UINT8  AccessType,
+  IN UINTN  Address,
+  IN UINT8  Data
+  );
+
+/*++
+
+Routine Description:
+  Acquire the lock to use the IPMI transport.
+
+Arguments:
+  Lock - Pointer to Lock.
+
+Returns:
+  VOID - Returns nothing.
+
+--*/
+VOID
+IpmiTransportAcquireLock (
+  OUT BOOLEAN  *Lock
+  );
+
+/*++
+
+Routine Description:
+  Release the lock of IPMI transport.
+
+Arguments:
+  Lock - Pointer to Lock.
+
+Returns:
+  VOID - Returns nothing.
+
+--*/
+VOID
+IpmiTransportReleaseLock (
+  OUT BOOLEAN  *Lock
+  );
+
+/*++
+
+Routine Description:
+  Returns the Lock state of IPMI transport.
+
+Arguments:
+  Lock - Pointer to Lock.
+
+Returns:
+  TRUE  - IPMI transport is in lock state.
+  FALSE - IPMI transport is in release state.
+--*/
+BOOLEAN
+IpmiIsIpmiTransportlocked (
+  IN BOOLEAN  *Lock
+  );
+
+/*++
+
+Routine Description:
+  Updates the SoftErrorCount of specific interface based on the BMC Error input.
+
+Arguments:
+  BmcError - BMC Error.
+  Interface - Interface pointer to update soft error count.
+  InterfaceType - Interface type to communicate.
+
+Returns:
+  EFI_SUCCESS           - Updated SoftErrorCount of specific interface.
+  EFI_INVALID_PARAMETER - Invalid Interface pointer or Interface type.
+--*/
+EFI_STATUS
+IpmiUpdateSoftErrorCount (
+  IN     UINT8                  BmcError,
+  IN OUT IPMI_SYSTEM_INTERFACE  *Interface,
+  IN     SYSTEM_INTERFACE_TYPE  InterfaceType
+  );
+
+/*++
+
+Routine Description:
+  Check the BMC Interface self test for the specified Interface.
+
+Arguments:
+  IpmiTransport2 - IPMI Interface pointer.
+  BmcStatus      - BMC Interface status.
+  InterfaceType  - Interface type to communicate.
+
+Returns:
+  EFI_SUCCESS           - BMC self test command success.
+  EFI_INVALID_PARAMETER - Invalid Interface pointer or Interface type.
+--*/
+EFI_STATUS
+CheckSelfTestByInterfaceType (
+  IN OUT  IPMI_TRANSPORT2        *IpmiTransport2,
+  IN OUT  BMC_INTERFACE_STATUS   *BmcStatus,
+  IN      SYSTEM_INTERFACE_TYPE  InterfaceType
+  );
+
+/*++
+
+Routine Description:
+  Initialize BT interface specific data.
+
+Arguments:
+  IpmiTransport2 - IPMI transport2 protocol pointer.
+
+Returns:
+  Status.
+--*/
+EFI_STATUS
+InitBtInterfaceData (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  );
+
+/*++
+
+Routine Description:
+  Initialize SSIF interface specific data.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Return status while initializing interface.
+--*/
+EFI_STATUS
+InitSsifInterfaceData (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  );
+
+/*++
+
+Routine Description:
+  Initialize IPMB interface specific data.
+
+Arguments:
+  IpmiTransport2    - Pointer to IPMI Transport2 instance.
+
+Returns:
+  EFI_SUCCESS - Interface is successfully initialized.
+  Others      - Error status while initializing interface.
+--*/
+EFI_STATUS
+InitIpmbInterfaceData (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  );
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BtInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BtInterfaceLib.h
new file mode 100644
index 0000000000..e9697e7b49
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BtInterfaceLib.h
@@ -0,0 +1,78 @@
+/** @file BtInterfaceLib.h
+  BT interface common macros and declarations.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BT_INTERFACE_LIB_H_
+#define _BT_INTERFACE_LIB_H_
+
+#include <Protocol/IpmiTransport2Protocol.h>
+#include <Include/IpmiNetFnAppDefinitions.h>
+
+#define IPMI_MAX_BT_CMD_DATA_SIZE  0xFF
+#define IPMI_CLR_WR_PTR_BIT        0x01
+#define IPMI_CLR_RD_PTR_BIT        0x02
+#define IPMI_H2B_ATN_BIT           0x04
+#define IPMI_B2H_ATN_BIT           0x08
+#define IPMI_H_BUSY                0x40
+#define IPMI_B_BUSY_BIT            0x80
+
+/*++
+
+Routine Description:
+  BT interface send command implementation.
+
+Arguments:
+  This              - Pointer to IPMI protocol instance.
+  NetFunction       - Net Function of command to send.
+  Lun               - LUN of command to send.
+  Command           - IPMI command to send.
+  CommandData       - Pointer to command data buffer, if needed.
+  CommandDataSize   - Size of command data buffer.
+  ResponseData      - Pointer to response data buffer.
+  ResponseDataSize  - Pointer to response data buffer size.
+  Context           - NULL here.
+
+Returns:
+  EFI_INVALID_PARAMETER - One of the input values is bad.
+  EFI_DEVICE_ERROR      - IPMI command failed.
+  EFI_BUFFER_TOO_SMALL  - Response buffer is too small.
+  EFI_UNSUPPORTED       - Command is not supported by BMC.
+  EFI_SUCCESS           - Command completed successfully.
+--*/
+EFI_STATUS
+EFIAPI
+IpmiBtSendCommandToBmc (
+  IN      IPMI_TRANSPORT2  *This,
+  IN      UINT8            NetFunction,
+  IN      UINT8            Lun,
+  IN      UINT8            Command,
+  IN      UINT8            *CommandData,
+  IN      UINT8            CommandDataSize,
+  IN OUT  UINT8            *ResponseData,
+  IN OUT  UINT8            *ResponseDataSize,
+  IN      VOID             *Context
+  );
+
+/*++
+
+Routine Description:
+  Execute the Get BT Interface Capability command and update the input
+  and output buffer value of IPMI transport2.
+
+Arguments:
+  IpmiTransport2 - IPMI transport2 protocol Instance.
+
+Returns:
+  VOID - Nothing.
+--*/
+VOID
+GetBtInterfaceCapability (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  );
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/IpmbInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/IpmbInterfaceLib.h
new file mode 100644
index 0000000000..6d6af297c0
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/IpmbInterfaceLib.h
@@ -0,0 +1,94 @@
+/** @file IpmbInterfaceLib.h
+  IPMB interface common function declarations and macros.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMB_INTERFACE_LIB_H_
+#define _IPMB_INTERFACE_LIB_H_
+
+#include <Pi/PiI2c.h>
+#include <Protocol/IpmiTransport2Protocol.h>
+#include <Include/IpmiNetFnAppDefinitions.h>
+
+#define IPMI_MAX_IPMB_CMD_DATA_SIZE  0xFF
+#define IPMI_READ_FLAG               1
+#define IPMI_WRITE_FLAG              0
+#define IPMI_SEQ_NO                  0    // IPMB Message Sequence Number.
+
+/*++
+
+Routine Description:
+  Locate I2c Ppi/Protocol instance and initialize interface pointer.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Status returned from functions used.
+--*/
+EFI_STATUS
+IpmiGetI2cApiPtr (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  );
+
+/*++
+
+Routine Description:
+  Send IPMI command through IPMB interface.
+
+Arguments:
+  Interface     - Pointer to System interface.
+  SlaveAddress  - I2C device slave address.
+  RequestPacket - Pointer to an EFI_I2C_REQUEST_PACKET structure describing the I2C transaction.
+
+Returns:
+  Status - Status of the Send I2c command.
+--*/
+EFI_STATUS
+IpmiI2cSendCommand (
+  IN IPMI_SYSTEM_INTERFACE   *Interface,
+  IN UINTN                   SlaveAddress,
+  IN EFI_I2C_REQUEST_PACKET  *RequestPacket
+  );
+
+/*++
+
+Routine Description:
+  IPMB interface send command implementation.
+
+Arguments:
+  This              - Pointer to IPMI protocol instance.
+  NetFunction       - Net Function of command to send.
+  Lun               - LUN of command to send.
+  Command           - IPMI command to send.
+  CommandData       - Pointer to command data buffer, if needed.
+  CommandDataSize   - Size of command data buffer.
+  ResponseData      - Pointer to response data buffer.
+  ResponseDataSize  - Pointer to response data buffer size.
+  Context           - NULL here.
+
+Returns:
+    EFI_INVALID_PARAMETER - One of the input values is bad.
+  EFI_DEVICE_ERROR      - IPMI command failed.
+  EFI_BUFFER_TOO_SMALL  - Response buffer is too small.
+  EFI_UNSUPPORTED       - Command is not supported by BMC.
+  EFI_SUCCESS           - Command completed successfully.
+--*/
+EFI_STATUS
+IpmiIpmbSendCommandToBmc (
+  IN     IPMI_TRANSPORT2  *This,
+  IN     UINT8            NetFunction,
+  IN     UINT8            Lun,
+  IN     UINT8            Command,
+  IN     UINT8            *CommandData,
+  IN     UINT8            CommandDataSize,
+  OUT    UINT8            *ResponseData,
+  IN OUT UINT8            *ResponseDataSize,
+  IN     VOID             *Context
+  );
+
+#endif // #ifndef _IPMB_INTERFACE_LIB_H
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/SsifInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/SsifInterfaceLib.h
new file mode 100644
index 0000000000..c7682436c3
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/SsifInterfaceLib.h
@@ -0,0 +1,169 @@
+/** @file SsifInterfaceLib.h
+  SSIF interface common function declarations and macros.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SSIF_INTERFACE_LIB_H
+#define _SSIF_INTERFACE_LIB_H
+
+#include <Protocol/SmbusHc.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Protocol/IpmiTransport2Protocol.h>
+#include <Include/IpmiNetFnAppDefinitions.h>
+
+#define IPMI_MAX_SSIF_CMD_DATA_SIZE  0xFF
+#define IPMI_SMBUS_BLOCK_LENGTH      0x20
+
+// Smbus Write Commands.
+#define IPMI_SMBUS_SINGLE_WRITE_CMD        0x2
+#define IPMI_SMBUS_MULTI_WRITE_START_CMD   0x6
+#define IPMI_SMBUS_MULTI_WRITE_MIDDLE_CMD  0x7
+#define IPMI_SMBUS_MULTI_WRITE_END_CMD     0x8
+
+// Smbus Read Commands.
+#define IPMI_SMBUS_SINGLE_READ_CMD        0x3
+#define IPMI_SMBUS_MULTI_READ_START_CMD   SMBUS_SINGLE_READ_CMD
+#define IPMI_SMBUS_MULTI_READ_MIDDLE_CMD  0x9
+#define IPMI_SMBUS_MULTI_READ_END_CMD     0x9
+#define IPMI_SMBUS_MULTI_READ_RETRY_CMD   0xA
+
+#define IPMI_MULTI_READ_ZEROTH_STRT_BIT  0x0
+#define IPMI_MULTI_READ_FIRST_STRT_BIT   0x1
+
+/*++
+
+Routine Description:
+  Check the SMBUS alert pin status function.
+
+Arguments:
+  VOID  - Nothing.
+
+Returns:
+  TRUE  - Alert pin status is set.
+  FALSE - Alert pin status is not set.
+--*/
+typedef BOOLEAN (SSIF_ALERT_PIN_CHECK) (
+  VOID
+  );
+
+/*++
+
+Routine Description:
+  Execute the Get System Interface Capability command and update the RwSupport
+  and PecSupport of Ipmi Instance.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  VOID - Nothing.
+--*/
+VOID
+GetSystemInterfaceCapability (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  );
+
+/*++
+
+Routine Description:
+  Execute the Get Global Enable command to get receive message queue interrupt.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  VOID - Nothing.
+--*/
+VOID
+GetGlobalEnables (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  );
+
+/*++
+
+Routine Description:
+  Locate Smbus instance and initialize interface pointer.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Status returned while locating SMBUS instance.
+--*/
+EFI_STATUS
+IpmiGetSmbusApiPtr (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  );
+
+/*++
+
+Routine Description:
+  Send IPMI command through SMBUS instance.
+
+Arguments:
+  Interface     - Pointer to System interface.
+  SlaveAddress  - The SMBUS hardware address.
+  Command       - This command is transmitted by the SMBus host controller to the SMBus slave device..
+  Operation     - Operation to be performed.
+  PecCheck      - Defines if Packet Error Code (PEC) checking is required for this operation.
+  Length        - Signifies the number of bytes that this operation will do.
+  Buffer        - Contains the value of data to execute to
+                  the SMBus slave device. The length of this buffer is identified by Length.
+
+Returns:
+  EFI_NOT_FOUND - SMBUS instance is not found.
+  Others        - Return status of the SMBUS Execute operation.
+--*/
+EFI_STATUS
+IpmiSmbusSendCommand (
+  IN     IPMI_SYSTEM_INTERFACE     *Interface,
+  IN     EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN     EFI_SMBUS_DEVICE_COMMAND  Command,
+  IN     EFI_SMBUS_OPERATION       Operation,
+  IN     BOOLEAN                   PecCheck,
+  IN OUT UINTN                     *Length,
+  IN OUT VOID                      *Buffer
+  );
+
+/*++
+
+Routine Description:
+  SSIF interface Ipmi send command Implementation
+
+Arguments:
+  This              - Pointer to IPMI protocol instance.
+  NetFunction       - Net Function of command to send.
+  Lun               - LUN of command to send.
+  Command           - IPMI command to send.
+  CommandData       - Pointer to command data buffer, if needed.
+  CommandDataSize   - Size of command data buffer.
+  ResponseData      - Pointer to response data buffer.
+  ResponseDataSize  - Pointer to response data buffer size.
+  Context           - NULL here.
+
+Returns:
+  EFI_INVALID_PARAMETER - One of the input values is bad.
+  EFI_DEVICE_ERROR      - IPMI command failed.
+  EFI_BUFFER_TOO_SMALL  - Response buffer is too small.
+  EFI_UNSUPPORTED       - Command is not supported by BMC.
+  EFI_SUCCESS           - Command completed successfully.
+--*/
+EFI_STATUS
+EFIAPI
+IpmiSsifSendCommandToBmc (
+  IN      IPMI_TRANSPORT2  *This,
+  IN      UINT8            NetFunction,
+  IN      UINT8            Lun,
+  IN      UINT8            Command,
+  IN      UINT8            *CommandData,
+  IN      UINT8            CommandDataSize,
+  IN OUT  UINT8            *ResponseData,
+  IN OUT  UINT8            *ResponseDataSize,
+  IN      VOID             *Context
+  );
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/IpmiTransport2Ppi.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/IpmiTransport2Ppi.h
new file mode 100644
index 0000000000..a408474e90
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/IpmiTransport2Ppi.h
@@ -0,0 +1,23 @@
+/** @file
+  IPMI Ttransport2 PPI Header File.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMI_TRANSPORT2_PPI_H_
+#define _IPMI_TRANSPORT2_PPI_H_
+
+#include <IpmiTransport2Definitions.h>
+#include <Library/BmcCommonInterfaceLib.h>
+
+#define PEI_IPMI_TRANSPORT2_PPI_GUID \
+  { \
+    0x8122CEBD, 0xF4FD, 0x4EA8, 0x97, 0x6C, 0xF0, 0x30, 0xAD, 0xDC, 0x4C, 0xB4 \
+  }
+
+extern EFI_GUID  gPeiIpmiTransport2PpiGuid;
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/IpmiTransport2Protocol.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/IpmiTransport2Protocol.h
new file mode 100644
index 0000000000..c8db92b49a
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/IpmiTransport2Protocol.h
@@ -0,0 +1,29 @@
+/** @file IpmiTransport2Protocol.h
+  IpmiTransport2 Protocol Header File.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMI2_TRANSPORT2_PROTO_H_
+#define _IPMI2_TRANSPORT2_PROTO_H_
+
+#include <IpmiTransport2Definitions.h>
+#include <Library/BmcCommonInterfaceLib.h>
+
+#define IPMI_TRANSPORT2_PROTOCOL_GUID \
+  { \
+    0x4a1d0e66, 0x5271, 0x4e22, { 0x83, 0xfe, 0x90, 0x92, 0x1b, 0x74, 0x82, 0x13 } \
+  }
+
+#define SMM_IPMI_TRANSPORT2_PROTOCOL_GUID \
+  { \
+    0x1dbd1503, 0xa60, 0x4230, { 0xaa, 0xa3, 0x80, 0x16, 0xd8, 0xc3, 0xde, 0x2f } \
+  }
+
+extern EFI_GUID  gIpmiTransport2ProtocolGuid;
+extern EFI_GUID  gSmmIpmiTransport2ProtocolGuid;
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.c
new file mode 100644
index 0000000000..6ef5efdac9
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.c
@@ -0,0 +1,256 @@
+/** @file BmcCommonInterfaceLib.c
+  BmcCommonInterfaceLib generic functions for all interfaces.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+
+/*++
+
+Routine Description:
+  Read 8 bit data from BMC port based on access type.
+
+Arguments:
+  AccessType - Specifies MMIO or IO access.
+  Address    - Specifies Address to read.
+
+Returns:
+  UINT8 - Data read.
+
+--*/
+UINT8
+IpmiBmcRead8 (
+  IN UINT8  AccessType,
+  IN UINTN  Address
+  )
+{
+  if (AccessType == IpmiIoAccess) {
+    return IoRead8 (Address);
+  } else {
+    return MmioRead8 (Address);
+  }
+}
+
+/*++
+
+Routine Description:
+  Write 8 bit data to BMC port based on access type.
+
+Arguments:
+  AccessType - Specifies MMIO or IO access.
+  Address    - Specifies Address to write.
+  Data       - Specifies data to be written.
+
+Returns:
+  UINT8 - Data written.
+
+--*/
+UINT8
+IpmiBmcWrite8 (
+  IN UINT8  AccessType,
+  IN UINTN  Address,
+  IN UINT8  Data
+  )
+{
+  if (AccessType == IpmiIoAccess) {
+    return IoWrite8 (
+                     Address,
+                     Data
+                     );
+  } else {
+    return MmioWrite8 (
+                       Address,
+                       Data
+                       );
+  }
+}
+
+/*++
+
+Routine Description:
+  Acquire the lock to use the IPMI transport.
+
+Arguments:
+  Lock - Pointer to Lock.
+
+Returns:
+  VOID - Returns nothing.
+
+--*/
+VOID
+IpmiTransportAcquireLock (
+  OUT BOOLEAN  *Lock
+  )
+{
+  *Lock = TRUE;
+}
+
+/*++
+
+Routine Description:
+  Release the lock of IPMI transport.
+
+Arguments:
+  Lock - Pointer to Lock.
+
+Returns:
+  VOID - Returns nothing.
+
+--*/
+VOID
+IpmiTransportReleaseLock (
+  OUT BOOLEAN  *Lock
+  )
+{
+  *Lock = FALSE;
+}
+
+/*++
+
+Routine Description:
+  Returns the Lock state of IPMI transport.
+
+Arguments:
+  Lock - Pointer to Lock.
+
+Returns:
+  TRUE  - IPMI transport is in lock state.
+  FALSE - IPMI transport is in release state.
+--*/
+BOOLEAN
+IpmiIsIpmiTransportlocked (
+  IN BOOLEAN  *Lock
+  )
+{
+  return *Lock;
+}
+
+/*++
+
+Routine Description:
+  Updates the SoftErrorCount of specific interface based on the BMC Error input.
+
+Arguments:
+  BmcError - BMC Error.
+  Interface - Interface pointer to update soft error count.
+  InterfaceType - Interface type to communicate.
+
+Returns:
+  EFI_SUCCESS           - Updated SoftErrorCount of specific interface.
+  EFI_INVALID_PARAMETER - Invalid Interface pointer or Interface type.
+--*/
+EFI_STATUS
+IpmiUpdateSoftErrorCount (
+  IN     UINT8                  BmcError,
+  IN OUT IPMI_SYSTEM_INTERFACE  *Interface,
+  IN     SYSTEM_INTERFACE_TYPE  InterfaceType
+  )
+{
+  UINT8  Errors[] = { 0xC0, 0xC3, 0xC4, 0xC9, 0xCE, 0xCF, 0xFF, 0x00 };
+  UINT8  Index    = 0;
+
+  if ((Interface == NULL) || (InterfaceType <= SysInterfaceUnknown) ||
+      (InterfaceType >= SysInterfaceMax))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  while (Errors[Index] != 0) {
+    if (Errors[Index] == BmcError) {
+      switch (InterfaceType) {
+        case SysInterfaceBt:
+          Interface->Bt.BtSoftErrorCount++;
+          break;
+
+        case SysInterfaceSsif:
+          Interface->Ssif.SsifSoftErrorCount++;
+          break;
+
+        default:
+          break;
+      }
+    }
+
+    Index++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/*++
+
+Routine Description:
+  Check the BMC Interface self test for the specified Interface.
+
+Arguments:
+  IpmiTransport2 - IPMI Interface pointer.
+  BmcStatus      - BMC Interface status.
+  InterfaceType  - Interface type to communicate.
+
+Returns:
+  EFI_SUCCESS           - BMC self test command success.
+  EFI_INVALID_PARAMETER - Invalid Interface pointer or Interface type.
+--*/
+EFI_STATUS
+CheckSelfTestByInterfaceType (
+  IN OUT  IPMI_TRANSPORT2        *IpmiTransport2,
+  IN OUT  BMC_INTERFACE_STATUS   *BmcStatus,
+  IN      SYSTEM_INTERFACE_TYPE  InterfaceType
+  )
+{
+  EFI_STATUS                      Status;
+  IPMI_SELF_TEST_RESULT_RESPONSE  BstStatus;
+  UINT32                          ResponseDataSize;
+
+  if ((IpmiTransport2 == NULL) || (BmcStatus == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ResponseDataSize = sizeof (IPMI_SELF_TEST_RESULT_RESPONSE);
+
+  Status = IpmiTransport2->IpmiSubmitCommand2Ex (
+                                                 IpmiTransport2,
+                                                 IPMI_NETFN_APP,
+                                                 BMC_LUN,
+                                                 IPMI_APP_GET_SELFTEST_RESULTS,
+                                                 NULL,
+                                                 0,
+                                                 (UINT8 *)&BstStatus,
+                                                 &ResponseDataSize,
+                                                 InterfaceType
+                                                 );
+  if (EFI_ERROR (Status)) {
+    *BmcStatus = BmcStatusHardFail;
+    return Status;
+  }
+
+  if (BstStatus.CompletionCode == IPMI_COMPLETION_CODE_SUCCESS) {
+    /* Check the self test results.  Cases 55h - 58h are Ipmi defined
+       test results. Additional Cases are device specific test results.*/
+    switch (BstStatus.Result) {
+      case IPMI_APP_SELFTEST_NO_ERROR:            // 0x55
+      case IPMI_APP_SELFTEST_NOT_IMPLEMENTED:     // 0x56
+      case IPMI_APP_SELFTEST_RESERVED:            // 0xFF
+        *BmcStatus = BmcStatusOk;
+        break;
+
+      case IPMI_APP_SELFTEST_ERROR:     // 0x57
+        *BmcStatus = BmcStatusSoftFail;
+        break;
+
+      default:     // 0x58 and Other Device Specific Hardware Error.
+        *BmcStatus = BmcStatusHardFail;
+        break;
+    }
+  }
+
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.inf
new file mode 100644
index 0000000000..33bb360c41
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.inf
@@ -0,0 +1,26 @@
+## @file BmcCommonInterfaceLib.inf
+#
+#  INF description file for BmcCommonInterfaceLib Library.
+#
+# @copyright
+# Copyright 2016 - 2021 Intel Corporation. <BR>
+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = BmcCommonInterfaceLib
+  FILE_GUID         = D86308F8-5246-4B2F-AC25-E3D17170D6EF
+  MODULE_TYPE       = BASE
+  VERSION_STRING    = 1.1
+  LIBRARY_CLASS     = BmcCommonInterfaceLib
+
+[Sources]
+  BmcCommonInterfaceLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.c
new file mode 100644
index 0000000000..37501758ad
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.c
@@ -0,0 +1,605 @@
+/** @file BtInterfaceLib.c
+  BT Transport implementation library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/BtInterfaceLib.h>
+
+#define IPMI_BT_DELAY_PER_RETRY  FixedPcdGet32 (PcdBtDelayPerRetry)
+
+/*++
+
+Routine Description:
+  Get the BT interface port addresses based on access type.
+
+Arguments:
+  Interface       - Pointer to System interface.
+  BtCtrlPort      - Pointer to BT control port.
+  BtComBufferPort - Pointer to BT communication buffer port.
+
+Returns:
+  VOID - Nothing.
+
+--*/
+VOID
+GetBtPortAddresses (
+  IN  IPMI_SYSTEM_INTERFACE  *Interface,
+  OUT UINTN                  *BtCtrlPort,
+  OUT UINTN                  *BtComBufferPort
+  )
+{
+  // Update Bt Ports based on Interface AccessType.
+  if (Interface->Bt.AccessType == IpmiIoAccess) {
+    *BtCtrlPort      = (UINTN)Interface->Bt.CtrlPort;
+    *BtComBufferPort = (UINTN)Interface->Bt.ComBuffer;
+  } else {
+    *BtCtrlPort      = Interface->Bt.MmioBaseAddress;
+    *BtComBufferPort = *BtCtrlPort + Interface->Bt.BaseAddressRange;
+  }
+}
+
+/*++
+
+Routine Description:
+  Sends the command to BT interface BMC port.
+
+Arguments:
+  Interface - Pointer to System interface.
+  Context   - NULL here.
+  Data      - Pointer to command data that will be sent to BMC along with Command.
+  DataSize  - Size of the command data.
+
+Returns:
+  EFI_NOT_READY - Interface is not ready to send data.
+  EFI_SUCCESS   - Command sent to BMC successfully.
+--*/
+EFI_STATUS
+SendDataToBtBmcPort (
+  IN IPMI_SYSTEM_INTERFACE  *Interface,
+  IN VOID                   *Context,
+  IN UINT8                  *Data,
+  IN UINT8                  DataSize
+  )
+{
+  UINT8             BtCntlData;
+  UINT8             Index;
+  UINT32            Retry;
+  UINTN             BtCtrlPort;
+  UINTN             BtComBufferPort;
+  IPMI_ACCESS_TYPE  AccessType;
+  UINT8             TempDataSize;
+  BOOLEAN           MultipleDataSend;
+  UINT32            BtRetryCount;
+
+  MultipleDataSend = FALSE;
+  BtRetryCount     = Interface->Bt.BtRetryCount;
+  AccessType       = Interface->Bt.AccessType;
+
+  // Get Bt Ports addresses.
+  GetBtPortAddresses (
+                      Interface,
+                      &BtCtrlPort,
+                      &BtComBufferPort
+                      );
+
+  do {
+    /* Wait for B_BUSY bit to clear (BMC ready to accept a request).
+       Default delay for each retry is 15 micro seconds.*/
+    for (Retry = 0; Retry < BtRetryCount; Retry++) {
+      BtCntlData = IpmiBmcRead8 (
+                                 AccessType,
+                                 BtCtrlPort
+                                 );
+      if (!(BtCntlData & IPMI_B_BUSY_BIT)) {
+        break;
+      }
+
+      MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY);
+    }
+
+    if (Retry == BtRetryCount) {
+      return EFI_TIMEOUT;
+    }
+
+    // Wait for H2B_ATN bit to clear (Acknowledgment of previous commands).
+    for (Retry = 0; Retry < BtRetryCount; Retry++) {
+      BtCntlData = IpmiBmcRead8 (
+                                 AccessType,
+                                 BtCtrlPort
+                                 );
+      if (!(BtCntlData & IPMI_H2B_ATN_BIT)) {
+        break;
+      }
+
+      MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY);
+    }
+
+    if (Retry == BtRetryCount) {
+      return EFI_TIMEOUT;
+    }
+
+    // Set CLR_WR_PTR.
+    BtCntlData = IPMI_CLR_WR_PTR_BIT;
+    IpmiBmcWrite8 (
+                   AccessType,
+                   BtCtrlPort,
+                   BtCntlData
+                   );
+
+    if (DataSize > Interface->Bt.HosttoBmcBufferSize ) {
+      TempDataSize     = Interface->Bt.HosttoBmcBufferSize;
+      MultipleDataSend = TRUE;
+    } else {
+      TempDataSize     = DataSize;
+      MultipleDataSend = FALSE;
+    }
+
+    // Send each message byte out (write data to HOST2BMC buffer).
+    for (Index = 0; Index < TempDataSize; Index++) {
+      IpmiBmcWrite8 (
+                     AccessType,
+                     BtComBufferPort,
+                     *(Data + Index)
+                     );
+    }
+
+    // Set H2B_ATN bit to inform BMC that data is available.
+    BtCntlData = IPMI_H2B_ATN_BIT;
+    IpmiBmcWrite8 (
+                   AccessType,
+                   BtCtrlPort,
+                   BtCntlData
+                   );
+
+    // Command data size greater than available Input buffer size.
+    if (MultipleDataSend) {
+      Data      = Data + TempDataSize;
+      DataSize -= TempDataSize;
+
+      for (Retry = 0; Retry < BtRetryCount; Retry++) {
+        BtCntlData = IpmiBmcRead8 (
+                                   AccessType,
+                                   BtCtrlPort
+                                   );
+        if ((BtCntlData & IPMI_B_BUSY_BIT)) {
+          break;
+        }
+
+        MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY);
+      }
+
+      if (Retry == BtRetryCount) {
+        return EFI_TIMEOUT;
+      }
+    }
+  } while (MultipleDataSend);
+
+  return EFI_SUCCESS;
+}
+
+/*++
+
+Routine Description:
+  Receives the Data from BT interface BMC port.
+
+Arguments:
+  Interface - Pointer to System interface.
+  Context   - NULL here.
+  Data      - Pointer to response data that is received from BMC.
+  DataSize  - Size of the response data.
+
+Returns:
+  EFI_NOT_READY         - Interface is not ready to receive data.
+  EFI_SUCCESS           - Data received from BMC successfully.
+  EFI_INVALID_PARAMETER - Invalid parameter.
+--*/
+EFI_STATUS
+ReceiveBmcDataFromBtPort (
+  IN  IPMI_SYSTEM_INTERFACE  *Interface,
+  IN  VOID                   *Context,
+  OUT UINT8                  *Data,
+  OUT UINT8                  *DataSize
+  )
+{
+  UINT8             BtCntlData;
+  UINT8             Length;
+  UINT8             TempDataSize;
+  UINT8             Index;
+  UINT32            Retry;
+  UINTN             BtCtrlPort;
+  UINTN             BtComBufferPort;
+  IPMI_ACCESS_TYPE  AccessType;
+  BOOLEAN           MultipleDataReceive;
+  UINT32            BtRetryCount;
+
+  Length              = 0;
+  MultipleDataReceive = FALSE;
+  BtRetryCount        = Interface->Bt.BtRetryCount;
+  AccessType          = Interface->Bt.AccessType;
+
+  // Get Bt Ports addresses.
+  GetBtPortAddresses (
+                      Interface,
+                      &BtCtrlPort,
+                      &BtComBufferPort
+                      );
+  do {
+    /* Wait for B2H_ATN bit to be set,signaling data is available for host.
+    Default delay for each retry is 15 micro seconds.*/
+    for (Retry = 0; Retry < BtRetryCount; Retry++) {
+      BtCntlData = IpmiBmcRead8 (
+                                 AccessType,
+                                 BtCtrlPort
+                                 );
+      if (BtCntlData & IPMI_B2H_ATN_BIT) {
+        break;
+      }
+
+      MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY);
+    }
+
+    if (Retry == BtRetryCount) {
+      return EFI_TIMEOUT;
+    }
+
+    // Set H_BUSY bit, indicating host is in process of reading data from interface.
+    BtCntlData = IpmiBmcRead8 (
+                               AccessType,
+                               BtCtrlPort
+                               );
+    if (!(BtCntlData & IPMI_H_BUSY)) {
+      BtCntlData = IPMI_H_BUSY;            // most bits are rw1c, so clear them.
+      IpmiBmcWrite8 (
+                     AccessType,
+                     BtCtrlPort,
+                     BtCntlData
+                     );
+    }
+
+    // Clear B2H_ATN bit,to acknowledge receipt of message response.
+    BtCntlData = IPMI_B2H_ATN_BIT;       // Most bits are rw1c, so clear them.
+    IpmiBmcWrite8 (
+                   AccessType,
+                   BtCtrlPort,
+                   BtCntlData
+                   );
+
+    // Set CLR_RD_PTR bit.
+    BtCntlData = IPMI_CLR_RD_PTR_BIT;    // Most bits are rw1c, so clear them.
+    IpmiBmcWrite8 (
+                   AccessType,
+                   BtCtrlPort,
+                   BtCntlData
+                   );
+
+    if (!Length) {
+      // Read the data bytes from BMC.
+      Length = IpmiBmcRead8 (
+                             AccessType,
+                             BtComBufferPort
+                             );
+      if (Length == 0x00) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      IpmiBmcWrite8 (
+                     AccessType,
+                     BtCtrlPort,
+                     BtCntlData
+                     );
+
+      *DataSize = Length;
+      // Increment Length to include length field
+      Length++;
+    }
+
+    if (Length > Interface->Bt.BmctoHostBufferSize) {
+      TempDataSize        = Interface->Bt.BmctoHostBufferSize;
+      MultipleDataReceive = TRUE;
+    } else {
+      TempDataSize        = Length;
+      MultipleDataReceive = FALSE;
+    }
+
+    for (Index = 0; Index < TempDataSize; Index++) {
+      *(Data + Index) = IpmiBmcRead8 (
+                                      AccessType,
+                                      BtComBufferPort
+                                      );
+    }
+
+    // Clear H_BUSY bit indicating host is done reading data from BMC.
+    BtCntlData = IpmiBmcRead8 (
+                               AccessType,
+                               BtCtrlPort
+                               );
+    if (BtCntlData & IPMI_H_BUSY) {
+      BtCntlData = IPMI_H_BUSY;            // Most bits are rw1c, so clear them.
+      IpmiBmcWrite8 (
+                     AccessType,
+                     BtCtrlPort,
+                     BtCntlData
+                     );
+    }
+
+    if (MultipleDataReceive) {
+      Data    = Data + TempDataSize;
+      Length -= TempDataSize;
+    }
+  } while (MultipleDataReceive);
+
+  return EFI_SUCCESS;
+}
+
+/*++
+
+Routine Description:
+  BT interface send command implementation.
+
+Arguments:
+  This              - Pointer to IPMI protocol instance.
+  NetFunction       - Net Function of command to send.
+  Lun               - LUN of command to send.
+  Command           - IPMI command to send.
+  CommandData       - Pointer to command data buffer, if needed.
+  CommandDataSize   - Size of command data buffer.
+  ResponseData      - Pointer to response data buffer.
+  ResponseDataSize  - Pointer to response data buffer size.
+  Context           - NULL here.
+
+Returns:
+  EFI_INVALID_PARAMETER - One of the input values is bad.
+  EFI_DEVICE_ERROR      - IPMI command failed.
+  EFI_BUFFER_TOO_SMALL  - Response buffer is too small.
+  EFI_UNSUPPORTED       - Command is not supported by BMC.
+  EFI_SUCCESS           - Command completed successfully.
+--*/
+EFI_STATUS
+EFIAPI
+IpmiBtSendCommandToBmc (
+  IN      IPMI_TRANSPORT2  *This,
+  IN      UINT8            NetFunction,
+  IN      UINT8            Lun,
+  IN      UINT8            Command,
+  IN      UINT8            *CommandData,
+  IN      UINT8            CommandDataSize,
+  IN OUT  UINT8            *ResponseData,
+  IN OUT  UINT8            *ResponseDataSize,
+  IN      VOID             *Context
+  )
+{
+  UINT8                  DataSize;
+  EFI_STATUS             Status;
+  UINT8                  Seq;
+  UINT8                  CmdDataBuffer[IPMI_MAX_BT_CMD_DATA_SIZE];
+  IPMI_SYSTEM_INTERFACE  Interface;
+
+  Seq       = 0;
+  Interface = This->Interface;
+
+  if (Interface.Bt.InterfaceState != IpmiInterfaceInitialized) {
+    return EFI_NOT_READY;
+  }
+
+  if (((CommandData == NULL) && (CommandDataSize != 0)) || (This == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((ResponseDataSize == NULL) || ((ResponseData == NULL) && *ResponseDataSize)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (IpmiIsIpmiTransportlocked (&Interface.Bt.BtTransportLocked)) {
+    return EFI_ACCESS_DENIED;
+  } else {
+    IpmiTransportAcquireLock (&Interface.Bt.BtTransportLocked);
+  }
+
+  CmdDataBuffer[0] = (UINT8)CommandDataSize + 0x03;
+  CmdDataBuffer[1] = (UINT8)((NetFunction << 2) | (Lun & 0xfc));
+  CmdDataBuffer[2] = Seq;
+  CmdDataBuffer[3] = Command;
+
+  if (CommandDataSize > 0) {
+    if (CommandData == NULL) {
+      IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (CommandDataSize <= (IPMI_MAX_BT_CMD_DATA_SIZE - 4)) {
+      CopyMem (
+               &CmdDataBuffer[4],
+               CommandData,
+               CommandDataSize
+               );
+    } else {
+      IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked);
+      return EFI_BAD_BUFFER_SIZE;
+    }
+  }
+
+  Status = SendDataToBtBmcPort (
+                                &Interface,
+                                Context,
+                                CmdDataBuffer,
+                                (UINT8)(CommandDataSize + 4)
+                                );
+
+  if (Status != EFI_SUCCESS) {
+    Interface.Bt.BtSoftErrorCount++;
+    IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked);
+    return Status;
+  }
+
+  DataSize = IPMI_MAX_BT_CMD_DATA_SIZE;
+
+  Status = ReceiveBmcDataFromBtPort (
+                                     &Interface,
+                                     Context,
+                                     CmdDataBuffer,
+                                     &DataSize
+                                     );
+
+  if (Status != EFI_SUCCESS) {
+    Interface.Bt.BtSoftErrorCount++;
+    IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked);
+    return Status;
+  }
+
+  if (IPMI_ERROR_COMPLETION_CODE (CmdDataBuffer[4])) {
+    IpmiUpdateSoftErrorCount (
+                              CmdDataBuffer[4],
+                              &Interface,
+                              This->InterfaceType
+                              );
+
+    // Write completion code into return buffer if ipmi command returns an error.
+    if (*ResponseDataSize) {
+      if (ResponseData) {
+        *ResponseData = CmdDataBuffer[4];
+      }
+
+      *ResponseDataSize = 1;
+    }
+
+    IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked);
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (DataSize < 4) {
+    IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked);
+    return EFI_DEVICE_ERROR;
+  }
+
+  if ((DataSize - 3) > *((UINT8 *)ResponseDataSize)) {
+    *ResponseDataSize = (UINT8)(DataSize - 3);
+    IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked);
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  // Copying the response data into ResponseData buffer.
+  CopyMem (
+           ResponseData,
+           &CmdDataBuffer[4],
+           (DataSize - 3)
+           );
+  *ResponseDataSize = (UINT8)(DataSize - 3);
+
+  IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked);
+
+  return EFI_SUCCESS;
+}
+
+/*++
+
+Routine Description:
+  Execute the Get BT Interface Capability command and update the input
+  and output buffer value of IPMI transport2.
+
+Arguments:
+  IpmiTransport2 - IPMI transport2 protocol Instance.
+
+Returns:
+  VOID - Nothing.
+--*/
+VOID
+GetBtInterfaceCapability (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS                        Status;
+  IPMI_BT_INTERFACE_CAPABILITY_RES  Responsedata;
+  UINT32                            ResponseSize;
+
+  ResponseSize = sizeof (IPMI_BT_INTERFACE_CAPABILITY_RES);
+
+  Status = IpmiTransport2->IpmiSubmitCommand2 (
+                                               IpmiTransport2,
+                                               IPMI_NETFN_APP,
+                                               BMC_LUN,
+                                               IPMI_APP_GET_BT_INTERFACE_CAPABILITY,
+                                               NULL,
+                                               0,
+                                               (UINT8 *)&Responsedata,
+                                               &ResponseSize
+                                               );
+
+  if (EFI_ERROR (Status) || Responsedata.CompletionCode) {
+    DEBUG ((DEBUG_ERROR, " IPMI_APP_GET_BT_INTERFACE_CAPABILITY Status: %r Completion code: %x\n", Status, Responsedata.CompletionCode));
+    return;
+  }
+
+  IpmiTransport2->Interface.Bt.HosttoBmcBufferSize = Responsedata.InputBuffSize;
+  IpmiTransport2->Interface.Bt.BmctoHostBufferSize = Responsedata.OutputBuffSize;
+
+  DEBUG ((DEBUG_ERROR, " InputBuffSize:%x OutBuffSize%x  BtRetry %x Status %r \n", IpmiTransport2->Interface.Bt.HosttoBmcBufferSize, IpmiTransport2->Interface.Bt.BmctoHostBufferSize, Responsedata.RecommandedRetires, Status));
+
+  return;
+}
+
+/*++
+
+Routine Description:
+  Initialize BT interface specific data.
+
+Arguments:
+  IpmiTransport2 - IPMI transport2 protocol pointer.
+
+Returns:
+  Status.
+--*/
+EFI_STATUS
+InitBtInterfaceData (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  BMC_INTERFACE_STATUS  BmcStatus;
+  EFI_STATUS            Status;
+
+  if (IpmiTransport2->Interface.Bt.InterfaceState == IpmiInterfaceInitialized) {
+    return EFI_SUCCESS;
+  }
+
+  IpmiTransport2->Interface.Bt.CtrlPort            = FixedPcdGet16 (PcdBtControlPort);           // BT Control Port
+  IpmiTransport2->Interface.Bt.ComBuffer           = FixedPcdGet16 (PcdBtBufferPort);            // BT Buffer Port
+  IpmiTransport2->Interface.Bt.IntMaskPort         = FixedPcdGet16 (PcdBtInterruptMaskPort);     // BT IntMask Port
+  IpmiTransport2->Interface.Bt.BtRetryCount        = FixedPcdGet32 (PcdBtCommandRetryCounter);   // BT retry count
+  IpmiTransport2->Interface.Bt.HosttoBmcBufferSize = FixedPcdGet8 (PcdBtBufferSize);             // Host to Bmc Buffer Size.
+  IpmiTransport2->Interface.Bt.BmctoHostBufferSize = FixedPcdGet8 (PcdBtBufferSize);             // Bmc to Host Buffer Size.
+
+  if (FixedPcdGet8 (PcdIpmiDefaultAccessType)) {
+    IpmiTransport2->Interface.Bt.AccessType       = IpmiIoAccess;
+    IpmiTransport2->Interface.Bt.MmioBaseAddress  = 0;
+    IpmiTransport2->Interface.Bt.BaseAddressRange = 0;
+  } else {
+    IpmiTransport2->Interface.Bt.AccessType       = IpmiMmioAccess;
+    IpmiTransport2->Interface.Bt.MmioBaseAddress  = FixedPcdGet64 (PcdMmioBaseAddress);
+    IpmiTransport2->Interface.Bt.BaseAddressRange = FixedPcdGet64 (PcdBaseAddressRange);
+  }
+
+  IpmiTransportReleaseLock (&IpmiTransport2->Interface.Bt.BtTransportLocked);
+  IpmiTransport2->Interface.Bt.InterfaceState = IpmiInterfaceInitialized;
+
+  Status = CheckSelfTestByInterfaceType (
+                                         IpmiTransport2,
+                                         &BmcStatus,
+                                         SysInterfaceBt
+                                         );
+  if (EFI_ERROR (Status) || (BmcStatus == BmcStatusHardFail)) {
+    IpmiTransport2->Interface.Bt.InterfaceState = IpmiInterfaceInitError;
+    return Status;
+  }
+
+  GetBtInterfaceCapability (IpmiTransport2);
+
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf
new file mode 100644
index 0000000000..1dd4386204
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf
@@ -0,0 +1,39 @@
+## @file BtInterfaceLib.inf
+#
+#  INF description file for BtInterfaceLib common library.
+#
+# @copyright
+# Copyright 2016 - 2021 Intel Corporation. <BR>
+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = BtInterfaceLib
+  FILE_GUID         = DAFB6AEE-0275-45E4-A33C-E3348149C5BF
+  MODULE_TYPE       = BASE
+  VERSION_STRING    = 1.1
+  LIBRARY_CLASS     = BtInterfaceLib
+
+[Sources]
+  BtInterfaceLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+  TimerLib
+  BmcCommonInterfaceLib
+
+[Pcd]
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBtCommandRetryCounter
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBtControlPort
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBtBufferPort
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBtDelayPerRetry
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBtInterruptMaskPort
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBtBufferSize
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBaseAddressRange
+  gIpmiFeaturePkgTokenSpaceGuid.PcdMmioBaseAddress
+  gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiDefaultAccessType
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c
new file mode 100644
index 0000000000..80a3a1afe9
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c
@@ -0,0 +1,103 @@
+/** @file DxeIpmbInterfaceLib.c
+  IPMB Transport Dxe phase Implementation library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/IpmbInterfaceLib.h>
+#include <Protocol/IpmiTransport2Protocol.h>
+#include <Protocol/I2cMaster.h>
+
+/*++
+
+Routine Description:
+  Send IPMI command through IPMB interface.
+
+Arguments:
+  Interface     - Pointer to System interface.
+  SlaveAddress  - I2C device slave address.
+  RequestPacket - Pointer to an EFI_I2C_REQUEST_PACKET structure describing the I2C transaction.
+
+Returns:
+  Status - Status of the Send I2c command.
+--*/
+EFI_STATUS
+IpmiI2cSendCommand (
+  IN IPMI_SYSTEM_INTERFACE   *Interface,
+  IN UINTN                   SlaveAddress,
+  IN EFI_I2C_REQUEST_PACKET  *RequestPacket
+  )
+{
+  EFI_STATUS               Status             = EFI_NOT_FOUND;
+  EFI_I2C_MASTER_PROTOCOL  *I2cMasterTransmit = NULL;
+
+  I2cMasterTransmit = (EFI_I2C_MASTER_PROTOCOL *)Interface->Ipmb.IpmbInterfaceApiPtr;
+
+  if (I2cMasterTransmit != NULL) {
+    Status = I2cMasterTransmit->StartRequest (
+                                              I2cMasterTransmit,
+                                              SlaveAddress,
+                                              RequestPacket,
+                                              NULL,
+                                              NULL
+                                              );
+  }
+
+  DEBUG ((DEBUG_INFO, "I2cMasterTransmit->StartRequest Status = %r\n", Status));
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  Locate I2c Ppi/Protocol instance and initialize interface pointer.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Status returned from functions used.
+--*/
+EFI_STATUS
+IpmiGetI2cApiPtr (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS               Status;
+  EFI_I2C_MASTER_PROTOCOL  *I2cMasterTransmit = NULL;
+  BMC_INTERFACE_STATUS     BmcStatus;
+
+  IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid = gEfiI2cMasterProtocolGuid;
+
+  // Locate the I2C DXE Protocol for Communication.
+  Status = gBS->LocateProtocol (
+                                &gEfiI2cMasterProtocolGuid,
+                                NULL,
+                                (VOID **)&I2cMasterTransmit
+                                );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  IpmiTransport2->Interface.Ipmb.InterfaceState      = IpmiInterfaceInitialized;
+  IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr = (UINTN)I2cMasterTransmit;
+
+  Status = CheckSelfTestByInterfaceType (
+                                         IpmiTransport2,
+                                         &BmcStatus,
+                                         SysInterfaceIpmb
+                                         );
+  if (EFI_ERROR (Status) || (BmcStatus == BmcStatusHardFail)) {
+    IpmiTransport2->Interface.Ipmb.InterfaceState = IpmiInterfaceInitError;
+  }
+
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf
new file mode 100644
index 0000000000..641d7213d4
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf
@@ -0,0 +1,38 @@
+## @file DxeIpmbInterfaceLib.inf
+#
+#  INF description file for IpmbInterfaceLib Library for DXE and UEFI drivers.
+#
+# @copyright
+# Copyright 2016 - 2021 Intel Corporation. <BR>
+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = DxeIpmbInterfaceLib
+  FILE_GUID         = 9068B213-4E53-427E-863C-8C7423509035
+  MODULE_TYPE       = DXE_DRIVER
+  VERSION_STRING    = 1.1
+  LIBRARY_CLASS     = IpmbInterfaceLib | DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+[Sources]
+  DxeIpmbInterfaceLib.c
+  IpmbInterfaceLibCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BmcCommonInterfaceLib
+
+[Protocols]
+  gEfiI2cMasterProtocolGuid
+
+[Pcd]
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c
new file mode 100644
index 0000000000..3837bf8ceb
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c
@@ -0,0 +1,378 @@
+/** @file IpmbInterfaceLibCommon.c
+  IPMB Transport implementation common library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/IpmbInterfaceLib.h>
+
+#define  IPMI_BMC_SLAVE_ADDRESS  FixedPcdGet32 (PcdBmcSlaveAddress)
+
+/*++
+
+Routine Description:
+  Verify the data integrity using checksum of BMC response data.
+
+Arguments:
+  ResponseData  - Response data from BMC.
+  ResponseSize  - Data size of response data.
+
+Returns:
+  EFI_SUCCESS           - Data integrity is valid.
+  EFI_INVALID_PARAMETER - Invalid parameter.
+--*/
+EFI_STATUS
+CheckDataValidity (
+  IN UINT8  *ResponseData,
+  IN UINT8  ResponseSize
+  )
+{
+  UINT8  Index;
+  UINT8  CheckSum = 0;
+  UINT8  DataSum  = 0;
+
+  // Calculate header checksum.
+  for (Index = 0; Index < 2; Index++) {
+    DataSum += ResponseData[Index];
+  }
+
+  // Verify header checksum.
+  CheckSum = (UINT8)(0x100 - DataSum);
+  if (CheckSum != ResponseData[2]) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DataSum = 0;
+
+  // Calculate information checksum.
+  for (Index = 3; Index < (ResponseSize - 1); Index++) {
+    DataSum += ResponseData[Index];
+  }
+
+  // Verify information checksum.
+  CheckSum = (UINT8)(0x100 - DataSum);
+  if (CheckSum != ResponseData[ResponseSize - 1]) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/*++
+
+Routine Description:
+  Sends the command/data to IPMB interface.
+
+Arguments:
+  Interface  - Pointer to System interface.
+  Context    - NULL here.
+  Data       - Pointer to command data that will be sent to BMC along with Command.
+  DataSize   - Size of the command data.
+
+Returns:
+  EFI_STATUS           - Status returned from I2C send command.
+--*/
+EFI_STATUS
+SendDataToIpmbBmcPort (
+  IN IPMI_SYSTEM_INTERFACE  *Interface,
+  IN VOID                   *Context,
+  IN UINT8                  *Data,
+  IN UINT8                  DataSize
+  )
+{
+  EFI_STATUS              Status;
+  EFI_I2C_REQUEST_PACKET  Packet;
+
+  // Pack command data.
+  Packet.Operation[0].Buffer        = Data;
+  Packet.Operation[0].LengthInBytes = DataSize;
+  Packet.Operation[0].Flags         = IPMI_WRITE_FLAG;
+
+  // Call the StartRequest function.
+  Status = IpmiI2cSendCommand (
+                               Interface,
+                               IPMI_BMC_SLAVE_ADDRESS,
+                               &Packet
+                               );
+
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  Receives the data from IPMB interface.
+
+Arguments:
+  Interface  - Pointer to System interface.
+  Context    - NULL here.
+  Data       - Pointer to response data that is received from BMC.
+  DataSize   - Size of the response data.
+
+Returns:
+  EFI_STATUS           - Status returned from I2C send command.
+--*/
+EFI_STATUS
+ReceiveBmcDataFromIpmbPort (
+  IN  IPMI_SYSTEM_INTERFACE  *Interface,
+  IN  VOID                   *Context,
+  OUT UINT8                  *Data,
+  OUT UINT8                  *DataSize
+  )
+{
+  EFI_STATUS              Status;
+  EFI_I2C_REQUEST_PACKET  Packet;
+
+  // Pack command data.
+  Packet.Operation[0].Buffer = Data;
+  Packet.Operation[0].Flags  = IPMI_READ_FLAG;
+
+  // Call the StartRequest function.
+  Status = IpmiI2cSendCommand (
+                               Interface,
+                               IPMI_BMC_SLAVE_ADDRESS,
+                               &Packet
+                               );
+
+  if (!EFI_ERROR (Status)) {
+    *DataSize = (UINT8)Packet.Operation[0].LengthInBytes;
+  }
+
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  IPMB interface send command implementation.
+
+Arguments:
+  This              - Pointer to IPMI protocol instance.
+  NetFunction       - Net Function of command to send.
+  Lun               - LUN of command to send.
+  Command           - IPMI command to send.
+  CommandData       - Pointer to command data buffer, if needed.
+  CommandDataSize   - Size of command data buffer.
+  ResponseData      - Pointer to response data buffer.
+  ResponseDataSize  - Pointer to response data buffer size.
+  Context           - NULL here.
+
+Returns:
+    EFI_INVALID_PARAMETER - One of the input values is bad.
+  EFI_DEVICE_ERROR      - IPMI command failed.
+  EFI_BUFFER_TOO_SMALL  - Response buffer is too small.
+  EFI_UNSUPPORTED       - Command is not supported by BMC.
+  EFI_SUCCESS           - Command completed successfully.
+--*/
+EFI_STATUS
+IpmiIpmbSendCommandToBmc (
+  IN     IPMI_TRANSPORT2  *This,
+  IN     UINT8            NetFunction,
+  IN     UINT8            Lun,
+  IN     UINT8            Command,
+  IN     UINT8            *CommandData,
+  IN     UINT8            CommandDataSize,
+  OUT    UINT8            *ResponseData,
+  IN OUT UINT8            *ResponseDataSize,
+  IN     VOID             *Context
+  )
+{
+  EFI_STATUS             Status;
+  UINT8                  DataSize;
+  UINT8                  DataSum  = 0;
+  UINT8                  CheckSum = 0;
+  UINT8                  Index;
+  UINT8                  CmdDataBuffer[IPMI_MAX_IPMB_CMD_DATA_SIZE];
+  IPMI_SYSTEM_INTERFACE  Interface;
+
+  Interface = This->Interface;
+
+  if (Interface.Ipmb.InterfaceState != IpmiInterfaceInitialized) {
+    return EFI_NOT_READY;
+  }
+
+  if (!ResponseDataSize || (!ResponseData && *ResponseDataSize)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (IpmiIsIpmiTransportlocked (&Interface.Ipmb.IpmbTransportLocked)) {
+    return EFI_ACCESS_DENIED;
+  } else {
+    IpmiTransportAcquireLock (&Interface.Ipmb.IpmbTransportLocked);
+  }
+
+  if (Interface.Ipmb.IpmbSoftErrorCount >= MAX_BMC_CMD_FAIL_COUNT) {
+    IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+    return EFI_NOT_READY;
+  }
+
+  /* Request Packet format.
+      | Slave Address | Netfun/Lun | CheckSum (Check Sum of previous data)
+      | Slave Address | Seq No | Command | Data 1..N
+      | CheckSum (Check Sum of previous data).*/
+  CmdDataBuffer[0] = IPMI_BMC_SLAVE_ADDRESS;
+  CmdDataBuffer[1] = (UINT8)((NetFunction << 2) | (Lun & 0x03));
+
+  DataSum += CmdDataBuffer[1] + IPMI_BMC_SLAVE_ADDRESS;
+  CheckSum = (UINT8)(0x100 - DataSum);
+  DataSum  = 0;
+
+  CmdDataBuffer[2] = CheckSum;
+
+  CmdDataBuffer[3] = IPMI_BMC_SLAVE_ADDRESS;
+  DataSum         += IPMI_BMC_SLAVE_ADDRESS;
+
+  CmdDataBuffer[4] = IPMI_SEQ_NO;
+  DataSum         += IPMI_SEQ_NO;
+
+  CmdDataBuffer[5] = Command;
+  DataSum         += Command;
+
+  if (CommandDataSize > 0) {
+    if (CommandData == NULL) {
+      IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    // Last data will be Checksum so limiting the Max command data to < IPMI_MAX_IPMB_CMD_DATA_SIZE - 6
+    if (CommandDataSize < (IPMI_MAX_IPMB_CMD_DATA_SIZE - 6)) {
+      CopyMem (
+               &CmdDataBuffer[6],
+               CommandData,
+               CommandDataSize
+               );
+    } else {
+      IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+      return EFI_BAD_BUFFER_SIZE;
+    }
+
+    for (Index = 0; Index < CommandDataSize; Index++) {
+      DataSum += CmdDataBuffer[6 + Index];
+    }
+  }
+
+  CheckSum         = (UINT8)(0x100 - DataSum); // Find the checksum for the packing data.
+  CmdDataBuffer[6] = CheckSum;                 // Update the checksum.
+
+  if ((Status = SendDataToIpmbBmcPort (
+                                       &Interface,
+                                       Context,
+                                       CmdDataBuffer,
+                                       (UINT8)(CommandDataSize + 7)
+                                       )) != EFI_SUCCESS)
+  {
+    Interface.Ipmb.IpmbSoftErrorCount++;
+    IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+    return Status;
+  }
+
+  DataSize = IPMI_MAX_IPMB_CMD_DATA_SIZE;
+  if ((Status = ReceiveBmcDataFromIpmbPort (
+                                            &Interface,
+                                            Context,
+                                            CmdDataBuffer,
+                                            &DataSize
+                                            )) != EFI_SUCCESS)
+  {
+    Interface.Ipmb.IpmbSoftErrorCount++;
+    IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+    return Status;
+  }
+
+  /* Response Packet format.
+     | Slave Address | Netfun/Lun | CheckSum (Check Sum of previous data)
+     | Slave Address | Seq No | Command | Completion code| Data 1..N
+     | CheckSum (Check Sum of previous data).*/
+
+  // Calculate and verify checksum.
+  Status = CheckDataValidity (
+                              CmdDataBuffer,
+                              DataSize
+                              );
+  if (EFI_ERROR (Status)) {
+    IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+    return Status;
+  }
+
+  if (IPMI_ERROR_COMPLETION_CODE (CmdDataBuffer[6])) {
+    IpmiUpdateSoftErrorCount (
+                              CmdDataBuffer[6],
+                              &Interface,
+                              This->InterfaceType
+                              );
+    // Write completion code into return buffer if an IPMI command returns an error
+    if (*ResponseDataSize) {
+      if (ResponseData) {
+        *ResponseData = CmdDataBuffer[6];
+      }
+
+      *ResponseDataSize = 1;
+    }
+
+    IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (DataSize < 8) {
+    IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+    return EFI_DEVICE_ERROR;
+  }
+
+  if ((DataSize - 7) > *((UINT8 *)ResponseDataSize)) {
+    *ResponseDataSize = (UINT8)(DataSize - 7);
+    IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  // Copying the response data into ResponseData buffer.
+  CopyMem (
+           ResponseData,
+           &CmdDataBuffer[6],
+           (DataSize - 7)
+           );
+  *ResponseDataSize = (UINT8)(DataSize - 7);
+
+  IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked);
+  return EFI_SUCCESS;
+}
+
+/*++
+
+Routine Description:
+  Initialize IPMB interface specific data.
+
+Arguments:
+  IpmiTransport2    - Pointer to IPMI Transport2 instance.
+
+Returns:
+  EFI_SUCCESS - Interface is successfully initialized.
+  Others      - Error status while initializing interface.
+--*/
+EFI_STATUS
+InitIpmbInterfaceData (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+
+  if (IpmiTransport2->Interface.Ipmb.InterfaceState == IpmiInterfaceInitialized) {
+    return Status;
+  }
+
+  Status = IpmiGetI2cApiPtr (IpmiTransport2);
+
+  if (EFI_ERROR (Status)) {
+    IpmiTransport2->Interface.Ipmb.InterfaceState = IpmiInterfaceInitError;
+    return Status;
+  }
+
+  IpmiTransportReleaseLock (&IpmiTransport2->Interface.Ipmb.IpmbTransportLocked);
+  IpmiTransport2->Interface.Ipmb.InterfaceState = IpmiInterfaceInitialized;
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c
new file mode 100644
index 0000000000..ff57c2c688
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c
@@ -0,0 +1,108 @@
+/** @file PeiIpmbInterfaceLib.c
+  IPMB Transport Pei phase implementation library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/IpmbInterfaceLib.h>
+#include <Ppi/I2cMaster.h>
+
+/*++
+
+Routine Description:
+  Send IPMI command through IPMB interface.
+
+Arguments:
+  Interface    - Pointer to System interface.
+  SlaveAddress - I2C device slave address.
+  RequestPacket - Pointer to an EFI_I2C_REQUEST_PACKET structure describing the I2C transaction.
+Returns:
+  EFI_STATUS - Status of the Send I2c command.
+--*/
+EFI_STATUS
+IpmiI2cSendCommand (
+  IN IPMI_SYSTEM_INTERFACE   *Interface,
+  IN UINTN                   SlaveAddress,
+  IN EFI_I2C_REQUEST_PACKET  *RequestPacket
+  )
+{
+  EFI_STATUS              Status             = EFI_NOT_FOUND;
+  EFI_PEI_I2C_MASTER_PPI  *I2cMasterTransmit = NULL;
+
+  I2cMasterTransmit = (EFI_PEI_I2C_MASTER_PPI *)Interface->Ipmb.IpmbInterfaceApiPtr;
+
+  if (I2cMasterTransmit != NULL) {
+    Status = I2cMasterTransmit->StartRequest (
+                                              I2cMasterTransmit,
+                                              SlaveAddress,
+                                              RequestPacket
+                                              );
+  }
+
+  DEBUG ((DEBUG_INFO, "%a I2cMasterTransmit->StartRequest Status = %r\n", __FUNCTION__, Status));
+
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  Locate I2c Ppi/Protocol instance and initialize interface pointer.
+
+Arguments:
+  IpmiTransport2    - Pointer to IPMI transport2 Instance.
+
+Returns:
+  EFI_STATUS - Status returned from functions used.
+--*/
+EFI_STATUS
+IpmiGetI2cApiPtr (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS              Status;
+  CONST EFI_PEI_SERVICES  **PeiServices;
+  EFI_PEI_I2C_MASTER_PPI  *I2cMasterTransmit = NULL;
+  BMC_INTERFACE_STATUS    BmcStatus;
+
+  PeiServices = GetPeiServicesTablePointer ();
+
+  IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid = gEfiPeiI2cMasterPpiGuid;
+
+  // Locate the I2C PPI for Communication.
+  Status = (*PeiServices)->LocatePpi (
+                                      PeiServices,
+                                      &gEfiPeiI2cMasterPpiGuid,
+                                      0,
+                                      NULL,
+                                      (VOID **)&I2cMasterTransmit
+                                      );
+
+  DEBUG ((DEBUG_INFO, "%a (*PeiServices)->LocatePpi gEfiPeiI2cMasterPpiGuid Status = %r\n", __FUNCTION__, Status));
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  IpmiTransport2->Interface.Ipmb.InterfaceState      = IpmiInterfaceInitialized;
+  IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr = (UINTN)I2cMasterTransmit;
+
+  Status = CheckSelfTestByInterfaceType (
+                                         IpmiTransport2,
+                                         &BmcStatus,
+                                         SysInterfaceIpmb
+                                         );
+
+  if (EFI_ERROR (Status) || (BmcStatus == BmcStatusHardFail)) {
+    IpmiTransport2->Interface.Ipmb.InterfaceState = IpmiInterfaceInitError;
+  }
+
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf
new file mode 100644
index 0000000000..85b19d74c8
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf
@@ -0,0 +1,38 @@
+## @file PeiIpmbInterfaceLib.inf
+#
+#  INF description file for IpmbInterfacePeiLib Library for PEIMs.
+#
+# @copyright
+# Copyright 2016 - 2021 Intel Corporation. <BR>
+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = PeiIpmbInterfaceLib
+  FILE_GUID         = 843DBE4E-4750-4335-9094-58645D897D62
+  MODULE_TYPE       = PEIM
+  VERSION_STRING    = 1.1
+  LIBRARY_CLASS     = IpmbInterfaceLib | PEIM
+
+[Sources]
+  PeiIpmbInterfaceLib.c
+  IpmbInterfaceLibCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+  HobLib
+  DebugLib
+  BaseMemoryLib
+  PeiServicesTablePointerLib
+  BmcCommonInterfaceLib
+
+[Ppis]
+  gEfiPeiI2cMasterPpiGuid
+
+[Pcd]
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c
new file mode 100644
index 0000000000..222b161d3a
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c
@@ -0,0 +1,104 @@
+/** @file SmmIpmbInterfaceLib.c
+  IPMB Transport Smm phase implementation library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/IpmbInterfaceLib.h>
+#include <Protocol/I2cMaster.h>
+
+/*++
+
+Routine Description:
+  Send IPMI command through IPMB interface.
+
+Arguments:
+  Interface     - Pointer to System interface.
+  SlaveAddress  - I2C device slave address.
+  RequestPacket - Pointer to an EFI_I2C_REQUEST_PACKET structure describing the I2C transaction.
+
+Returns:
+  Status - Status of the Send I2c command.
+--*/
+EFI_STATUS
+IpmiI2cSendCommand (
+  IN IPMI_SYSTEM_INTERFACE   *Interface,
+  IN UINTN                   SlaveAddress,
+  IN EFI_I2C_REQUEST_PACKET  *RequestPacket
+  )
+{
+  EFI_STATUS               Status             = EFI_NOT_FOUND;
+  EFI_I2C_MASTER_PROTOCOL  *I2cMasterTransmit = NULL;
+
+  I2cMasterTransmit = (EFI_I2C_MASTER_PROTOCOL *)Interface->Ipmb.IpmbInterfaceApiPtr;
+
+  if (I2cMasterTransmit != NULL) {
+    Status = I2cMasterTransmit->StartRequest (
+                                              I2cMasterTransmit,
+                                              SlaveAddress,
+                                              RequestPacket,
+                                              NULL,
+                                              NULL
+                                              );
+  }
+
+  DEBUG ((DEBUG_INFO, "%a I2cMasterTransmit->StartRequest Status = %r\n", __FUNCTION__, Status));
+
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  Locate I2c Ppi/Protocol instance and initialize interface pointer.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Status returned from functions used.
+--*/
+EFI_STATUS
+IpmiGetI2cApiPtr (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS               Status;
+  EFI_I2C_MASTER_PROTOCOL  *I2cMasterTransmit = NULL;
+  BMC_INTERFACE_STATUS     BmcStatus;
+
+  IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid = gEfiI2cMasterProtocolGuid;
+
+  // Locate the I2C SMM Protocol for Communication.
+  Status = gSmst->SmmLocateProtocol (
+                                     &gEfiI2cMasterProtocolGuid,
+                                     NULL,
+                                     (VOID **)&I2cMasterTransmit
+                                     );
+
+  DEBUG ((DEBUG_INFO, "%a SmmLocateProtocol gEfiI2cMasterProtocolGuid Status = %r\n", __FUNCTION__, Status));
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  IpmiTransport2->Interface.Ipmb.InterfaceState      = IpmiInterfaceInitialized;
+  IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr = (UINTN)I2cMasterTransmit;
+
+  Status = CheckSelfTestByInterfaceType (
+                                         IpmiTransport2,
+                                         &BmcStatus,
+                                         SysInterfaceIpmb
+                                         );
+  if (EFI_ERROR (Status) || (BmcStatus == BmcStatusHardFail)) {
+    IpmiTransport2->Interface.Ipmb.InterfaceState = IpmiInterfaceInitError;
+  }
+
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf
new file mode 100644
index 0000000000..2d3c089ef2
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf
@@ -0,0 +1,37 @@
+## @file SmmAmiIpmbInterfaceLib.inf
+#
+#  INF description file for SmmAmiIpmbInterfaceLib Library for DXE SMM drivers.
+#
+# @copyright
+# Copyright 2016 - 2021 Intel Corporation. <BR>
+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = SmmIpmbInterfaceLib
+  FILE_GUID         = C39F9DC3-37C7-41C1-BE05-8C1524493947
+  MODULE_TYPE       = DXE_SMM_DRIVER
+  VERSION_STRING    = 1.1
+  LIBRARY_CLASS     = IpmbInterfaceLib | DXE_SMM_DRIVER
+
+[Sources]
+  SmmIpmbInterfaceLib.c
+  IpmbInterfaceLibCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  SmmServicesTableLib
+  BmcCommonInterfaceLib
+
+[Protocols]
+  gEfiI2cMasterProtocolGuid
+
+[Pcd]
+  gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c
new file mode 100644
index 0000000000..9867672a41
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c
@@ -0,0 +1,137 @@
+/** @file DxeSsifInterfaceLib.c
+  SSIF Transport Dxe phase Implementation library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/SsifInterfaceLib.h>
+#include <Protocol/IpmiTransport2Protocol.h>
+#include <Protocol/SmbusHc.h>
+
+/*++
+
+Routine Description:
+  Send IPMI command through SMBUS instance.
+
+Arguments:
+  Interface     - Pointer to System interface.
+  SlaveAddress  - The SMBUS hardware address.
+  Command       - This command is transmitted by the SMBus host controller to the SMBus slave device..
+  Operation     - Operation to be performed.
+  PecCheck      - Defines if Packet Error Code (PEC) checking is required for this operation.
+  Length        - Signifies the number of bytes that this operation will do.
+  Buffer        - Contains the value of data to execute to
+                  the SMBus slave device. The length of this buffer is identified by Length.
+
+Returns:
+  EFI_NOT_FOUND - SMBUS instance is not found.
+  Others        - Return status of the SMBUS Execute operation.
+--*/
+EFI_STATUS
+IpmiSmbusSendCommand (
+  IN      IPMI_SYSTEM_INTERFACE     *Interface,
+  IN      EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN      EFI_SMBUS_DEVICE_COMMAND  Command,
+  IN      EFI_SMBUS_OPERATION       Operation,
+  IN      BOOLEAN                   PecCheck,
+  IN OUT  UINTN                     *Length,
+  IN OUT  VOID                      *Buffer
+  )
+{
+  EFI_STATUS             Status;
+  EFI_SMBUS_HC_PROTOCOL  *EfiSmbusHcProtocol;
+
+  Status             = EFI_NOT_FOUND;
+  EfiSmbusHcProtocol = (EFI_SMBUS_HC_PROTOCOL *)Interface->Ssif.SsifInterfaceApiPtr;
+
+  if (EfiSmbusHcProtocol != NULL) {
+    Status = EfiSmbusHcProtocol->Execute (
+                                          EfiSmbusHcProtocol,
+                                          SlaveAddress,
+                                          Command,
+                                          Operation,
+                                          PecCheck,
+                                          Length,
+                                          Buffer
+                                          );
+  }
+
+  DEBUG ((DEBUG_INFO, "EfiSmbusHcProtocol->Execute Status = %r\n", Status));
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  Locate Smbus instance and initialize interface pointer.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Status returned while locating SMBUS instance.
+--*/
+EFI_STATUS
+IpmiGetSmbusApiPtr (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS             Status;
+  EFI_SMBUS_HC_PROTOCOL  *EfiSmbusHcProtocol;
+  UINTN                  HandleCount;
+  EFI_HANDLE             *HandleBuffer;
+  UINTN                  Index;
+  BMC_INTERFACE_STATUS   BmcStatus;
+
+  IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid = gEfiSmbusHcProtocolGuid;
+
+  Status = gBS->LocateHandleBuffer (
+                                    ByProtocol,
+                                    &gEfiSmbusHcProtocolGuid,
+                                    NULL,
+                                    &HandleCount,
+                                    &HandleBuffer
+                                    );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                                  HandleBuffer[Index],
+                                  &gEfiSmbusHcProtocolGuid,
+                                  (VOID **)&EfiSmbusHcProtocol
+                                  );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    IpmiTransport2->Interface.Ssif.InterfaceState      = IpmiInterfaceInitialized;
+    IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr = (UINTN)EfiSmbusHcProtocol;
+
+    Status = CheckSelfTestByInterfaceType (
+                                           IpmiTransport2,
+                                           &BmcStatus,
+                                           SysInterfaceSsif
+                                           );
+    if (EFI_ERROR (Status) || (BmcStatus == BmcStatusHardFail)) {
+      IpmiTransport2->Interface.Ssif.InterfaceState = IpmiInterfaceInitError;
+      continue;
+    }
+
+    GetSystemInterfaceCapability (IpmiTransport2);
+    GetGlobalEnables (IpmiTransport2);
+    break;
+  }
+
+  FreePool (HandleBuffer);
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf
new file mode 100644
index 0000000000..d9120b220c
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf
@@ -0,0 +1,40 @@
+## @file DxeSsifInterfaceLib.inf
+#
+#  INF description file for SsifInterfaceLib Library for DXE and UEFI drivers.
+#
+# @copyright
+# Copyright 2016 - 2021 Intel Corporation. <BR>
+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = DxeSsifInterfaceLib
+  FILE_GUID         = AD66E7C3-FE13-4849-970E-118347FFE857
+  MODULE_TYPE       = DXE_DRIVER
+  VERSION_STRING    = 1.1
+  LIBRARY_CLASS     = SsifInterfaceLib | DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+[Sources]
+  DxeSsifInterfaceLib.c
+  SsifInterfaceLibCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+  UefiLib
+  MemoryAllocationLib
+  BmcCommonInterfaceLib
+
+[Protocols]
+  gEfiSmbusHcProtocolGuid
+
+[Pcd]
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c
new file mode 100644
index 0000000000..e522add31e
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c
@@ -0,0 +1,128 @@
+/** @file PeiSsifInterfaceLib.c
+  SSIF Transport Pei phase Implementation library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/SsifInterfaceLib.h>
+#include <Ppi/Smbus2.h>
+
+/*++
+
+Routine Description:
+  Send IPMI command through SMBUS instance.
+
+Arguments:
+  Interface     - Pointer to System interface.
+  SlaveAddress  - The SMBUS hardware address.
+  Command       - This command is transmitted by the SMBus host controller to the SMBus slave device..
+  Operation     - Operation to be performed.
+  PecCheck      - Defines if Packet Error Code (PEC) checking is required for this operation.
+  Length        - Signifies the number of bytes that this operation will do.
+  Buffer        - Contains the value of data to execute to
+                  the SMBus slave device. The length of this buffer is identified by Length.
+
+Returns:
+  EFI_NOT_FOUND - SMBUS instance is not found.
+  Others        - Return status of the SMBUS Execute operation.
+--*/
+EFI_STATUS
+IpmiSmbusSendCommand (
+  IN     IPMI_SYSTEM_INTERFACE     *Interface,
+  IN     EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN     EFI_SMBUS_DEVICE_COMMAND  Command,
+  IN     EFI_SMBUS_OPERATION       Operation,
+  IN     BOOLEAN                   PecCheck,
+  IN OUT UINTN                     *Length,
+  IN OUT VOID                      *Buffer
+  )
+{
+  EFI_STATUS          Status;
+  EFI_PEI_SMBUS2_PPI  *EfiPeiSmbus2Ppi;
+
+  Status          = EFI_NOT_FOUND;
+  EfiPeiSmbus2Ppi = (EFI_PEI_SMBUS2_PPI *)Interface->Ssif.SsifInterfaceApiPtr;
+
+  if (EfiPeiSmbus2Ppi != NULL) {
+    Status = EfiPeiSmbus2Ppi->Execute (
+                                       EfiPeiSmbus2Ppi,
+                                       SlaveAddress,
+                                       Command,
+                                       Operation,
+                                       PecCheck,
+                                       Length,
+                                       Buffer
+                                       );
+  }
+
+  DEBUG ((DEBUG_INFO, "%a EfiPeiSmbus2Ppi->Execute Status = %r\n", __FUNCTION__, Status));
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  Locate Smbus instance and initialize interface pointer.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Status returned while locating SMBUS instance.
+--*/
+EFI_STATUS
+IpmiGetSmbusApiPtr (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   Instance;
+  CONST EFI_PEI_SERVICES  **PeiServices;
+  EFI_PEI_SMBUS2_PPI      *EfiPeiSmbus2Ppi;
+  BMC_INTERFACE_STATUS    BmcStatus;
+
+  PeiServices = GetPeiServicesTablePointer ();
+
+  IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid = gEfiPeiSmbus2PpiGuid;
+
+  // Traverse all Smbus2 PPI instances and find the right instance for SSIF.
+  for (Instance = 0; ; Instance++) {
+    // Locate the Smbus Ppi.
+    Status = (*PeiServices)->LocatePpi (
+                                        PeiServices,
+                                        &gEfiPeiSmbus2PpiGuid,
+                                        Instance,
+                                        NULL,
+                                        (VOID **)&EfiPeiSmbus2Ppi
+                                        );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    IpmiTransport2->Interface.Ssif.InterfaceState      = IpmiInterfaceInitialized;
+    IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr = (UINTN)EfiPeiSmbus2Ppi;
+
+    Status = CheckSelfTestByInterfaceType (
+                                           IpmiTransport2,
+                                           &BmcStatus,
+                                           SysInterfaceSsif
+                                           );
+    if (EFI_ERROR (Status) || (BmcStatus == BmcStatusHardFail)) {
+      IpmiTransport2->Interface.Ssif.InterfaceState = IpmiInterfaceInitError;
+      continue;
+    }
+
+    GetSystemInterfaceCapability (IpmiTransport2);
+    GetGlobalEnables (IpmiTransport2);
+    break;
+  }
+
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf
new file mode 100644
index 0000000000..b3aad43671
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf
@@ -0,0 +1,41 @@
+## @file PeiSsifInterfaceLib.inf
+#
+#  INF description file for SsifInterfaceLib Library for PEIMs.
+#
+# @copyright
+# Copyright 2016 - 2021 Intel Corporation. <BR>
+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = PeiSsifInterfaceLib
+  FILE_GUID         = EDA631E3-DC66-4120-BADF-B6BA73B6ABD4
+  MODULE_TYPE       = PEIM
+  VERSION_STRING    = 1.1
+  LIBRARY_CLASS     = SsifInterfaceLib | PEIM
+
+[Sources]
+  PeiSsifInterfaceLib.c
+  SsifInterfaceLibCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+  DebugLib
+  TimerLib
+  BaseMemoryLib
+  PeiServicesTablePointerLib
+  BmcCommonInterfaceLib
+
+[Ppis]
+  gEfiPeiSmbus2PpiGuid
+
+[Pcd]
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c
new file mode 100644
index 0000000000..8ca07658e9
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c
@@ -0,0 +1,156 @@
+/** @file SmmSsifInterfaceLib.c
+  SSIF Transport SMM phase Implementation library functions.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SsifInterfaceLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/IpmiTransport2Protocol.h>
+#include <Protocol/SmbusHc.h>
+
+/*++
+
+Routine Description:
+  Send IPMI command through SMBUS instance.
+
+Arguments:
+  Interface     - Pointer to System interface.
+  SlaveAddress  - The SMBUS hardware address.
+  Command       - This command is transmitted by the SMBus host controller to the SMBus slave device..
+  Operation     - Operation to be performed.
+  PecCheck      - Defines if Packet Error Code (PEC) checking is required for this operation.
+  Length        - Signifies the number of bytes that this operation will do.
+  Buffer        - Contains the value of data to execute to
+                  the SMBus slave device. The length of this buffer is identified by Length.
+
+Returns:
+  EFI_NOT_FOUND - SMBUS instance is not found.
+  Others        - Return status of the SMBUS Execute operation.
+--*/
+EFI_STATUS
+IpmiSmbusSendCommand (
+  IN     IPMI_SYSTEM_INTERFACE     *Interface,
+  IN     EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN     EFI_SMBUS_DEVICE_COMMAND  Command,
+  IN     EFI_SMBUS_OPERATION       Operation,
+  IN     BOOLEAN                   PecCheck,
+  IN OUT UINTN                     *Length,
+  IN OUT VOID                      *Buffer
+  )
+{
+  EFI_STATUS             Status;
+  EFI_SMBUS_HC_PROTOCOL  *EfiSmbusHcProtocol;
+
+  Status             = EFI_NOT_FOUND;
+  EfiSmbusHcProtocol = (EFI_SMBUS_HC_PROTOCOL *)Interface->Ssif.SsifInterfaceApiPtr;
+
+  if (EfiSmbusHcProtocol != NULL) {
+    Status = EfiSmbusHcProtocol->Execute (
+                                          EfiSmbusHcProtocol,
+                                          SlaveAddress,
+                                          Command,
+                                          Operation,
+                                          PecCheck,
+                                          Length,
+                                          Buffer
+                                          );
+  }
+
+  DEBUG ((DEBUG_INFO, "%a EfiSmbusHcProtocol->Execute Status = %r\n", __FUNCTION__, Status));
+
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  Locate Smbus instance and initialize interface pointer.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Status returned while locating SMBUS instance.
+--*/
+EFI_STATUS
+IpmiGetSmbusApiPtr (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS             Status;
+  EFI_SMBUS_HC_PROTOCOL  *EfiSmbusHcProtocol;
+  UINTN                  HandleCount;
+  EFI_HANDLE             *HandleBuffer = NULL;
+  UINTN                  Index;
+  BMC_INTERFACE_STATUS   BmcStatus;
+
+  IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid = gEfiSmbusHcProtocolGuid;
+  HandleCount                                         = 0;
+
+  Status = gSmst->SmmLocateHandle (
+                                   ByProtocol,
+                                   &gEfiSmbusHcProtocolGuid,
+                                   NULL,
+                                   &HandleCount,
+                                   HandleBuffer
+                                   );
+  if (EFI_ERROR (Status) && (Status == EFI_BUFFER_TOO_SMALL)) {
+    // Allocate memory for Handle buffer
+    HandleBuffer = AllocateZeroPool (HandleCount);
+    if (HandleBuffer == NULL) {
+      return EFI_NOT_FOUND;
+    }
+
+    Status = gSmst->SmmLocateHandle (
+                                     ByProtocol,
+                                     &gEfiSmbusHcProtocolGuid,
+                                     NULL,
+                                     &HandleCount,
+                                     HandleBuffer
+                                     );
+    if (EFI_ERROR (Status)) {
+      // Free HandleBuffer memory
+      FreePool (HandleBuffer);
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gSmst->SmmHandleProtocol (
+                                       HandleBuffer[Index],
+                                       &gEfiSmbusHcProtocolGuid,
+                                       (VOID **)&EfiSmbusHcProtocol
+                                       );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    IpmiTransport2->Interface.Ssif.InterfaceState      = IpmiInterfaceInitialized;
+    IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr = (UINTN)EfiSmbusHcProtocol;
+
+    Status = CheckSelfTestByInterfaceType (
+                                           IpmiTransport2,
+                                           &BmcStatus,
+                                           SysInterfaceSsif
+                                           );
+    if (EFI_ERROR (Status) || (BmcStatus == BmcStatusHardFail)) {
+      IpmiTransport2->Interface.Ssif.InterfaceState = IpmiInterfaceInitError;
+      continue;
+    }
+
+    GetSystemInterfaceCapability (IpmiTransport2);
+    GetGlobalEnables (IpmiTransport2);
+    break;
+  }
+
+  FreePool (HandleBuffer);
+  return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf
new file mode 100644
index 0000000000..a7e25647e2
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf
@@ -0,0 +1,40 @@
+## @file SmmSsifInterfaceLib.inf
+#
+#  INF description file for SsifInterfaceLib Library for DXE SMM drivers.
+#
+# @copyright
+# Copyright 2016 - 2021 Intel Corporation. <BR>
+# Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = SmmSsifInterfaceLib
+  FILE_GUID         = DB817B63-FA26-44FA-BF84-8D48596F982B
+  MODULE_TYPE       = DXE_SMM_DRIVER
+  VERSION_STRING    = 1.1
+  LIBRARY_CLASS     = SsifInterfaceLib | DXE_SMM_DRIVER
+
+[Sources]
+  SmmSsifInterfaceLib.c
+  SsifInterfaceLibCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+  SmmServicesTableLib
+  MemoryAllocationLib
+  BmcCommonInterfaceLib
+
+[Protocols]
+  gEfiSmbusHcProtocolGuid
+
+[Pcd]
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter
+  gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c
new file mode 100644
index 0000000000..c4ea35f570
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c
@@ -0,0 +1,577 @@
+/** @file SsifInterfaceLibCommon.c
+  SSIF Transport Implementation common functions and variables.
+
+  @copyright
+  Copyright 2016 - 2021 Intel Corporation. <BR>
+  Copyright (c) 1985 - 2023, American Megatrends International LLC. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BmcCommonInterfaceLib.h>
+#include <Library/SsifInterfaceLib.h>
+
+SSIF_ALERT_PIN_CHECK  *gSsifAlertPinCheckHookList[] =
+{
+  NULL
+};
+
+/*++
+
+Routine Description:
+  Check the SMBUS alert pin status function.
+
+Arguments:
+  VOID  - Nothing.
+
+Returns:
+  TRUE  - Alert pin status is set.
+  FALSE - Alert pin status is not set.
+--*/
+BOOLEAN
+CheckAlertPinHook (
+  VOID
+  )
+{
+  BOOLEAN  CheckAlertSignal = FALSE;
+  UINTN    Index;
+
+  for (Index = 0; gSsifAlertPinCheckHookList[Index]; Index++) {
+    CheckAlertSignal = gSsifAlertPinCheckHookList[Index]();
+  }
+
+  return CheckAlertSignal;
+}
+
+/*++
+
+Routine Description:
+  Sends the command/data to SSIF interface.
+
+Arguments:
+  Interface  - Pointer to System interface..
+  Context    - NULL here.
+  Data       - Pointer to command data that will be sent to BMC along with Command.
+  DataSize   - Size of the command data.
+
+Returns:
+  EFI_STATUS  - Status returned from Smbus send command.
+--*/
+EFI_STATUS
+SendDataToSsifBmcPort (
+  IN IPMI_SYSTEM_INTERFACE  *Interface,
+  IN VOID                   *Context,
+  IN UINT8                  *Data,
+  IN UINT8                  DataSize
+  )
+{
+  EFI_STATUS                Status;
+  EFI_SMBUS_DEVICE_ADDRESS  BmcAddress;
+  UINTN                     IpmiWriteCommand;
+  UINT8                     IpmiData[IPMI_SMBUS_BLOCK_LENGTH];
+  UINTN                     DataLength;
+  UINT8                     DataIndex;
+  BOOLEAN                   PECSupport;
+  UINT8                     RetryCount;
+  UINT8                     OriginalDataSize;
+
+  DataLength                    = DataSize;
+  DataIndex                     = 0;
+  RetryCount                    = 0;
+  OriginalDataSize              = DataSize;
+  PECSupport                    = Interface->Ssif.PecSupport;
+  BmcAddress.SmbusDeviceAddress = FixedPcdGet16 (PcdSsifSlaveAddress);
+  ZeroMem (IpmiData, sizeof (IpmiData));
+
+  do {
+    if (OriginalDataSize == DataSize) {
+      if (DataSize <= IPMI_SMBUS_BLOCK_LENGTH) {
+        // Working single writes start.
+        DataLength       = DataSize;
+        IpmiWriteCommand = IPMI_SMBUS_SINGLE_WRITE_CMD;
+        CopyMem (
+                 IpmiData,
+                 &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH],
+                 DataLength
+                 );
+      } else {
+        // Working multi-part writes start.
+        IpmiWriteCommand = IPMI_SMBUS_MULTI_WRITE_START_CMD;
+        DataLength       = IPMI_SMBUS_BLOCK_LENGTH;
+        CopyMem (
+                 IpmiData,
+                 &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH],
+                 DataLength
+                 );
+      }
+    } else {
+      if (DataSize > IPMI_SMBUS_BLOCK_LENGTH) {
+        // Working multi-part writes middle.
+        IpmiWriteCommand = IPMI_SMBUS_MULTI_WRITE_MIDDLE_CMD;
+        DataLength       = IPMI_SMBUS_BLOCK_LENGTH;
+        CopyMem (
+                 IpmiData,
+                 &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH],
+                 DataLength
+                 );
+      } else {
+        // Working multi-part writes end.
+        IpmiWriteCommand = IPMI_SMBUS_MULTI_WRITE_END_CMD;
+        DataLength       = DataSize;
+        CopyMem (
+                 IpmiData,
+                 &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH],
+                 DataLength
+                 );
+      }
+    }
+
+    Status = IpmiSmbusSendCommand (
+                                   Interface,
+                                   BmcAddress,
+                                   IpmiWriteCommand,
+                                   EfiSmbusWriteBlock,
+                                   PECSupport,
+                                   &DataLength,
+                                   IpmiData
+                                   );
+    if (!EFI_ERROR (Status)) {
+      if (DataSize >=  IPMI_SMBUS_BLOCK_LENGTH) {
+        RetryCount = 0;
+        DataSize  -= IPMI_SMBUS_BLOCK_LENGTH;
+        DataIndex++;
+      } else {
+        DataSize = 0;
+      }
+    } else {
+      if (RetryCount == Interface->Ssif.SsifRetryCounter) {
+        break;
+      } else {
+        RetryCount++;
+        // Failed retries delay about 60ms to 250ms.
+        MicroSecondDelay (FixedPcdGet32 (PcdSsifRequestRetriesDelay));
+
+        /* If the Multi-part write fails, then try to write the
+           data from the beginning.*/
+        if (IpmiWriteCommand != IPMI_SMBUS_SINGLE_WRITE_CMD) {
+          DataSize  = OriginalDataSize;
+          DataIndex = 0;
+        }
+      }
+    }
+  } while (DataSize);
+
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  Receives the Data from BMC port.
+
+Arguments:
+  Interface  - Pointer to System interface..
+  Context    - NULL here.
+  Data       - Pointer to response data that is received from BMC.
+  DataSize   - Size of the response data.
+
+Returns:
+  EFI_STATUS  - Status returned from Smbus send command.
+--*/
+EFI_STATUS
+ReceiveBmcDataFromSsifPort (
+  IN  IPMI_SYSTEM_INTERFACE  *Interface,
+  IN  VOID                   *Context,
+  OUT UINT8                  *Data,
+  OUT UINT8                  *DataSize
+  )
+{
+  EFI_STATUS                Status;
+  EFI_SMBUS_DEVICE_ADDRESS  BmcAddress;
+  UINTN                     IpmiReadCommand;
+  UINT8                     IpmiData[IPMI_SMBUS_BLOCK_LENGTH];
+  UINTN                     DataLength;
+  BOOLEAN                   PECSupport;
+  UINT8                     RetryCount;
+  UINT8                     OriginalDataSize;
+
+  DataLength                    = *DataSize;
+  RetryCount                    = 0;
+  OriginalDataSize              = *DataSize;
+  PECSupport                    = Interface->Ssif.PecSupport;
+  BmcAddress.SmbusDeviceAddress = FixedPcdGet16 (PcdSsifSlaveAddress);
+  IpmiReadCommand               = IPMI_SMBUS_SINGLE_READ_CMD;
+
+  while (RetryCount <= Interface->Ssif.SsifRetryCounter) {
+    Status = IpmiSmbusSendCommand (
+                                   Interface,
+                                   BmcAddress,
+                                   IpmiReadCommand,
+                                   EfiSmbusReadBlock,
+                                   PECSupport,
+                                   &DataLength,
+                                   (VOID *)IpmiData
+                                   );
+    if (EFI_ERROR (Status)) {
+      RetryCount++;
+      // Failed retries delay about 60ms to 250ms.
+      MicroSecondDelay (FixedPcdGet32 (PcdSsifRequestRetriesDelay));
+
+      /* If the Multi-part Read command fails, then try to read the
+         data from the beginning.*/
+      if (IpmiReadCommand != IPMI_SMBUS_SINGLE_READ_CMD) {
+        IpmiReadCommand = IPMI_SMBUS_SINGLE_READ_CMD;
+      }
+
+      DataLength = OriginalDataSize;
+      continue;
+    }
+
+    if (IpmiReadCommand == IPMI_SMBUS_SINGLE_READ_CMD) {
+      if ((IpmiData[0] == IPMI_MULTI_READ_ZEROTH_STRT_BIT) &&
+          (IpmiData[1] == IPMI_MULTI_READ_FIRST_STRT_BIT))
+      {
+        // Working multi-part reads start.
+        CopyMem (
+                 Data,
+                 &IpmiData[2],
+                 DataLength-2
+                 );
+        *DataSize       = (UINT8)DataLength-2;
+        IpmiReadCommand = IPMI_SMBUS_MULTI_READ_MIDDLE_CMD;
+      } else {
+        // Working single reads start.
+        CopyMem (
+                 Data,
+                 IpmiData,
+                 DataLength
+                 );
+        *DataSize = (UINT8)DataLength;
+        break;
+      }
+    } else {
+      if (IpmiData[0] == 0xFF) {
+        // Working multi-part reads end.
+        CopyMem (
+                 &Data[*DataSize],
+                 &IpmiData[1],
+                 DataLength-1
+                 );
+        *DataSize += (UINT8)DataLength-1;
+        break;
+      } else {
+        // Working multi-part reads middle.
+        CopyMem (
+                 &Data[*DataSize],
+                 &IpmiData[1],
+                 DataLength-1
+                 );
+        *DataSize      += (UINT8)DataLength-1;
+        IpmiReadCommand = IPMI_SMBUS_MULTI_READ_MIDDLE_CMD;
+      }
+    }
+  }
+
+  return Status;
+}
+
+/*++
+
+Routine Description:
+  SSIF interface Ipmi send command Implementation
+
+Arguments:
+  This              - Pointer to IPMI protocol instance.
+  NetFunction       - Net Function of command to send.
+  Lun               - LUN of command to send.
+  Command           - IPMI command to send.
+  CommandData       - Pointer to command data buffer, if needed.
+  CommandDataSize   - Size of command data buffer.
+  ResponseData      - Pointer to response data buffer.
+  ResponseDataSize  - Pointer to response data buffer size.
+  Context           - NULL here.
+
+Returns:
+  EFI_INVALID_PARAMETER - One of the input values is bad.
+  EFI_DEVICE_ERROR      - IPMI command failed.
+  EFI_BUFFER_TOO_SMALL  - Response buffer is too small.
+  EFI_UNSUPPORTED       - Command is not supported by BMC.
+  EFI_SUCCESS           - Command completed successfully.
+--*/
+EFI_STATUS
+EFIAPI
+IpmiSsifSendCommandToBmc (
+  IN      IPMI_TRANSPORT2  *This,
+  IN      UINT8            NetFunction,
+  IN      UINT8            Lun,
+  IN      UINT8            Command,
+  IN      UINT8            *CommandData,
+  IN      UINT8            CommandDataSize,
+  IN OUT  UINT8            *ResponseData,
+  IN OUT  UINT8            *ResponseDataSize,
+  IN      VOID             *Context
+  )
+{
+  EFI_STATUS             Status;
+  UINT8                  DataSize;
+  UINT8                  CmdDataBuffer[IPMI_MAX_SSIF_CMD_DATA_SIZE];
+  IPMI_SYSTEM_INTERFACE  Interface;
+
+  Interface = This->Interface;
+
+  if (Interface.Ssif.InterfaceState != IpmiInterfaceInitialized) {
+    return EFI_NOT_READY;
+  }
+
+  if (((CommandData == NULL) && (CommandDataSize != 0)) || (This == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((ResponseDataSize == NULL) || ((ResponseData == NULL) && *ResponseDataSize)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (IpmiIsIpmiTransportlocked (&Interface.Ssif.SsifTransportLocked)) {
+    return EFI_ACCESS_DENIED;
+  } else {
+    IpmiTransportAcquireLock (&Interface.Ssif.SsifTransportLocked);
+  }
+
+  // Check the SSIF interface multi-part reads/writes supported.
+  //   Block length include Command data, NetFn, and Command parameter.
+  if (((Interface.Ssif.RwSupport == SsifSinglePartRw) &&
+       ((CommandDataSize + 2) > IPMI_SMBUS_BLOCK_LENGTH)) ||
+      ((Interface.Ssif.RwSupport == SsifMultiPartRw) &&
+       ((CommandDataSize + 2) > (2*IPMI_SMBUS_BLOCK_LENGTH))) ||
+      ((Interface.Ssif.RwSupport == SsifMultiPartRwWithMiddle) &&
+       ((CommandDataSize + 2) > IPMI_MAX_SSIF_CMD_DATA_SIZE)))
+  {
+    IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Interface.Ssif.SsifSoftErrorCount >= MAX_BMC_CMD_FAIL_COUNT) {
+    IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+    return EFI_NOT_READY;
+  }
+
+  CmdDataBuffer[0] = (UINT8)((NetFunction << 2) | (Lun & 0x03));
+  CmdDataBuffer[1] = Command;
+
+  if (CommandDataSize > 0) {
+    if (CommandData == NULL) {
+      IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (CommandDataSize <= (IPMI_MAX_SSIF_CMD_DATA_SIZE - 2)) {
+      CopyMem (
+               &CmdDataBuffer[2],
+               CommandData,
+               CommandDataSize
+               );
+    } else {
+      IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+      return EFI_BAD_BUFFER_SIZE;
+    }
+  }
+
+  Status = SendDataToSsifBmcPort (
+                                  &Interface,
+                                  Context,
+                                  CmdDataBuffer,
+                                  (UINT8)(CommandDataSize + 2)
+                                  );
+
+  if (Status != EFI_SUCCESS) {
+    Interface.Ssif.SsifSoftErrorCount++;
+    IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+    return Status;
+  }
+
+  // Hook to check smbus alert pin.
+  if (Interface.Ssif.SmbAlertSupport) {
+    if (!CheckAlertPinHook ()) {
+      IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+      return EFI_DEVICE_ERROR;
+    }
+  } else {
+    MicroSecondDelay (FixedPcdGet32 (PcdSsifRequestRetriesDelay));
+  }
+
+  DataSize = IPMI_SMBUS_BLOCK_LENGTH;
+
+  Status = ReceiveBmcDataFromSsifPort (
+                                       &Interface,
+                                       Context,
+                                       CmdDataBuffer,
+                                       &DataSize
+                                       );
+  if (Status != EFI_SUCCESS) {
+    Interface.Ssif.SsifSoftErrorCount++;
+    IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+    return Status;
+  }
+
+  if (IPMI_ERROR_COMPLETION_CODE (CmdDataBuffer[2])) {
+    IpmiUpdateSoftErrorCount (
+                              CmdDataBuffer[2],
+                              &Interface,
+                              This->InterfaceType
+                              );
+    // Write completion code into return buffer if ipmi command returns an error.
+    if (*ResponseDataSize) {
+      if (ResponseData) {
+        *ResponseData = CmdDataBuffer[2];
+      }
+
+      *ResponseDataSize = 1;
+    }
+
+    IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (DataSize < 3) {
+    IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+    return EFI_DEVICE_ERROR;
+  }
+
+  if ((DataSize - 2) > *((UINT8 *)ResponseDataSize)) {
+    *ResponseDataSize = (UINT8)(DataSize - 3);
+    IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  // Copying the response data into ResponseData buffer.
+  CopyMem (
+           ResponseData,
+           &CmdDataBuffer[2],
+           (DataSize - 2)
+           );
+  *ResponseDataSize = (UINT8)(DataSize - 2);
+
+  IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked);
+  return EFI_SUCCESS;
+}
+
+/*++
+
+Routine Description:
+  Execute the Get System Interface Capability command and update the RwSupport
+  and PecSupport of Ipmi Instance.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  VOID - Nothing.
+--*/
+VOID
+GetSystemInterfaceCapability (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS                                Status;
+  IPMI_GET_SYSTEM_INTERFACE_CAPABILITY_REQ  GetSystemInterfaceCapabilityCmd;
+  IPMI_GET_SYSTEM_INTERFACE_CAPABILITY_RES  GetSsifInterfaceCapability;
+  UINT32                                    DataSize = sizeof (GetSsifInterfaceCapability);
+
+  GetSystemInterfaceCapabilityCmd.SystemInterfaceType = 0x0; // SSIF
+  GetSystemInterfaceCapabilityCmd.Reserved            = 0x0;
+
+  Status = IpmiTransport2->IpmiSubmitCommand2 (
+                                               IpmiTransport2,
+                                               IPMI_NETFN_APP,
+                                               BMC_LUN,
+                                               IPMI_APP_GET_SYSTEM_INTERFACE_CAPABILITIES,
+                                               (UINT8 *)&GetSystemInterfaceCapabilityCmd,
+                                               sizeof (GetSystemInterfaceCapabilityCmd),
+                                               (UINT8 *)&GetSsifInterfaceCapability,
+                                               &DataSize
+                                               );
+  if (!EFI_ERROR (Status)) {
+    IpmiTransport2->Interface.Ssif.RwSupport  = GetSsifInterfaceCapability.TransactionSupport;
+    IpmiTransport2->Interface.Ssif.PecSupport = GetSsifInterfaceCapability.PecSupport;
+  }
+}
+
+/*++
+
+Routine Description:
+  Execute the Get Global Enable command to get receive message queue interrupt.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  VOID - Nothing.
+--*/
+VOID
+GetGlobalEnables (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS                   Status;
+  IPMI_BMC_GLOBAL_ENABLES_RES  BmcGlobalEnables;
+  UINT32                       ResponseDataSize = sizeof (BmcGlobalEnables);
+
+  //
+  // Get Global Enable Information.
+  //
+  Status = IpmiTransport2->IpmiSubmitCommand2 (
+                                               IpmiTransport2,
+                                               IPMI_NETFN_APP,
+                                               BMC_LUN,
+                                               IPMI_APP_GET_BMC_GLOBAL_ENABLES,
+                                               NULL,
+                                               0,
+                                               (UINT8 *)(&BmcGlobalEnables),
+                                               &ResponseDataSize
+                                               );
+  if (!EFI_ERROR (Status)) {
+    //
+    // Set Smb alert pin based on ReceiveMsgQueueInterrupt bit
+    //
+    IpmiTransport2->Interface.Ssif.SmbAlertSupport = BmcGlobalEnables.ReceiveMsgQueueInterrupt;
+  }
+}
+
+/*++
+
+Routine Description:
+  Initialize SSIF interface specific data.
+
+Arguments:
+  IpmiTransport2     - Pointer to IPMI transport2 instance.
+
+Returns:
+  Status - Return status while initializing interface.
+--*/
+EFI_STATUS
+InitSsifInterfaceData (
+  IN OUT IPMI_TRANSPORT2  *IpmiTransport2
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+
+  if (IpmiTransport2->Interface.Ssif.InterfaceState == IpmiInterfaceInitialized) {
+    return Status;
+  }
+
+  IpmiTransport2->Interface.Ssif.SsifRetryCounter = FixedPcdGet16 (PcdSsifCommandtRetryCounter);
+  IpmiTransport2->Interface.Ssif.PecSupport       = FALSE;
+  IpmiTransport2->Interface.Ssif.RwSupport        = 0x0;      // SSIF multi-part reads/writes support.
+  IpmiTransport2->Interface.Ssif.SmbAlertSupport  = FALSE;    // SMB alert pin support.
+
+  Status = IpmiGetSmbusApiPtr (IpmiTransport2);
+  if (EFI_ERROR (Status)) {
+    IpmiTransport2->Interface.Ssif.InterfaceState = IpmiInterfaceInitError;
+    return Status;
+  }
+
+  IpmiTransportReleaseLock (&IpmiTransport2->Interface.Ssif.SsifTransportLocked);
+  return Status;
+}
--
2.38.1.windows.1
-The information contained in this message may be confidential and proprietary to American Megatrends (AMI). This communication is intended to be read only by the individual or entity to whom it is addressed or by their designee. If the reader of this message is not the intended recipient, you are on notice that any distribution of this message, in any form, is strictly prohibited. Please promptly notify the sender by reply e-mail or by telephone at 770-246-8600, and then delete or destroy all copies of the transmission.

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2023-07-03 14:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-03 14:48 [edk2-devel][edk2-platforms][PATCH V4-3] IpmiFeaturePkg:Provided multiple IPMI interface support in Library Arun K

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox