[edk2-devel] [edk2-platforms] [PATCH v1 4/9] IpmiFeaturePkg: Add GenericIpmi driver common code

Nate DeSimone nathaniel.l.desimone at intel.com
Tue Mar 2 02:27:59 UTC 2021


From: Isaac Oram <isaac.w.oram at intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3242

Adds phase independent code for the generic IPMI
transport driver.

Cc: Sai Chaganty <rangasai.v.chaganty at intel.com>
Cc: Liming Gao <gaoliming at byosoft.com.cn>
Cc: Michael Kubacki <michael.kubacki at microsoft.com>
Signed-off-by: Isaac Oram <isaac.w.oram at intel.com>
Co-authored-by: Nate DeSimone <nathaniel.l.desimone at intel.com>
---
 .../GenericIpmi/Common/IpmiBmc.c              | 297 +++++++++++
 .../GenericIpmi/Common/IpmiBmc.h              |  44 ++
 .../GenericIpmi/Common/IpmiBmcCommon.h        | 179 +++++++
 .../GenericIpmi/Common/IpmiHooks.c            |  96 ++++
 .../GenericIpmi/Common/IpmiHooks.h            |  81 +++
 .../GenericIpmi/Common/IpmiPhysicalLayer.h    |  29 ++
 .../GenericIpmi/Common/KcsBmc.c               | 483 ++++++++++++++++++
 .../GenericIpmi/Common/KcsBmc.h               | 236 +++++++++
 8 files changed, 1445 insertions(+)
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmc.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmc.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmcCommon.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiHooks.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiHooks.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiPhysicalLayer.h
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/KcsBmc.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/KcsBmc.h

diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmc.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmc.c
new file mode 100644
index 0000000000..03b8174e37
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmc.c
@@ -0,0 +1,297 @@
+/** @file
+  IPMI Transport common layer driver
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "IpmiBmc.h"
+
+EFI_STATUS
+UpdateErrorStatus (
+  IN UINT8                      BmcError,
+  IPMI_BMC_INSTANCE_DATA    *IpmiInstance
+  )
+/*++
+
+Routine Description:
+
+  Check if the completion code is a Soft Error and increment the count.  The count
+  is not updated if the BMC is in Force Update Mode.
+
+Arguments:
+
+  BmcError      - Completion code to check
+  IpmiInstance  - BMC instance data
+
+Returns:
+
+  EFI_SUCCESS   - Status
+
+--*/
+{
+  UINT8   Errors[] = COMPLETION_CODES;
+  UINT16  CodeCount;
+  UINT8   i;
+
+  CodeCount = sizeof (Errors) / sizeof (Errors[0]);
+  for (i = 0; i < CodeCount; i++) {
+    if (BmcError == Errors[i]) {
+      //
+      // Don't change Bmc Status flag if the BMC is in Force Update Mode.
+      //
+      if (IpmiInstance->BmcStatus != BMC_UPDATE_IN_PROGRESS) {
+        IpmiInstance->BmcStatus = BMC_SOFTFAIL;
+      }
+
+      IpmiInstance->SoftErrorCount++;
+      break;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiSendCommandToBmc (
+  IN      IPMI_TRANSPORT            *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:
+
+  Send IPMI command to BMC
+
+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           - Context
+
+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
+
+--*/
+{
+  IPMI_BMC_INSTANCE_DATA  *IpmiInstance;
+  UINT8                   DataSize;
+  EFI_STATUS              Status;
+  IPMI_COMMAND            *IpmiCommand;
+  IPMI_RESPONSE           *IpmiResponse;
+  UINT8                   RetryCnt = IPMI_SEND_COMMAND_MAX_RETRY;
+  UINT8                   Index;
+
+  IpmiInstance = INSTANCE_FROM_SM_IPMI_BMC_THIS (This);
+
+  while (RetryCnt--) {
+    //
+    // The TempData buffer is used for both sending command data and receiving
+    // response data.  Since the command format is different from the response
+    // format, the buffer is cast to both structure definitions.
+    //
+    IpmiCommand  = (IPMI_COMMAND*)  IpmiInstance->TempData;
+    IpmiResponse = (IPMI_RESPONSE*) IpmiInstance->TempData;
+
+    //
+    // Send IPMI command to BMC
+    //
+    IpmiCommand->Lun = Lun;
+    IpmiCommand->NetFunction = NetFunction;
+    IpmiCommand->Command = Command;
+
+    //
+    // Ensure that the buffer is valid before attempting to copy the command data
+    // buffer into the IpmiCommand structure.
+    //
+    if (CommandDataSize > 0) {
+      if (CommandData == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      CopyMem (
+        IpmiCommand->CommandData,
+        CommandData,
+        CommandDataSize
+        );
+    }
+
+    Status = SendDataToBmcPort (
+               IpmiInstance->KcsTimeoutPeriod,
+               IpmiInstance->IpmiIoBase,
+               Context,
+               (UINT8 *) IpmiCommand,
+               (CommandDataSize + IPMI_COMMAND_HEADER_SIZE)
+               );
+
+    if (Status != EFI_SUCCESS) {
+      IpmiInstance->BmcStatus = BMC_SOFTFAIL;
+      IpmiInstance->SoftErrorCount++;
+      return Status;
+    }
+
+    //
+    // Get Response to IPMI Command from BMC.
+    // Subtract 1 from DataSize so memory past the end of the buffer can't be written
+    //
+    DataSize = MAX_TEMP_DATA - 1;
+    Status = ReceiveBmcDataFromPort (
+               IpmiInstance->KcsTimeoutPeriod,
+               IpmiInstance->IpmiIoBase,
+               Context,
+               (UINT8 *) IpmiResponse,
+               &DataSize
+               );
+
+    if (Status != EFI_SUCCESS) {
+      IpmiInstance->BmcStatus = BMC_SOFTFAIL;
+      IpmiInstance->SoftErrorCount++;
+      return Status;
+    }
+
+    //
+    // If we got this far without any error codes, but the DataSize less than IPMI_RESPONSE_HEADER_SIZE, then the
+    // command response failed, so do not continue.
+    //
+    if (DataSize < IPMI_RESPONSE_HEADER_SIZE) {
+      return EFI_DEVICE_ERROR;
+    }
+
+    if ((IpmiResponse->CompletionCode != COMP_CODE_NORMAL) &&
+        (IpmiInstance->BmcStatus == BMC_UPDATE_IN_PROGRESS)) {
+      //
+      // If the completion code is not normal and the BMC is in Force Update
+      // mode, then update the error status and return EFI_UNSUPPORTED.
+      //
+      UpdateErrorStatus (
+        IpmiResponse->CompletionCode,
+        IpmiInstance
+        );
+      return EFI_UNSUPPORTED;
+    } else if (IpmiResponse->CompletionCode != COMP_CODE_NORMAL) {
+      //
+      // Otherwise if the BMC is in normal mode, but the completion code
+      // is not normal, then update the error status and return device error.
+      //
+      UpdateErrorStatus (
+        IpmiResponse->CompletionCode,
+        IpmiInstance
+        );
+      //
+      // Intel Server System Integrated Baseboard Management Controller (BMC) Firmware v0.62
+      // D4h C Insufficient privilege, in KCS channel this indicates KCS Policy Control Mode is Deny All.
+      // In authenticated channels this indicates invalid authentication/privilege.
+      //
+      if (IpmiResponse->CompletionCode == COMP_INSUFFICIENT_PRIVILEGE) {
+        return EFI_SECURITY_VIOLATION;
+      } else {
+        return EFI_DEVICE_ERROR;
+      }
+    }
+
+    //
+    // Verify the response data buffer passed in is big enough.
+    //
+    if ((DataSize - IPMI_RESPONSE_HEADER_SIZE) > *ResponseDataSize) {
+      //
+      //Verify the response data matched with the cmd sent.
+      //
+      if ((IpmiResponse->NetFunction != (NetFunction | 0x1)) || (IpmiResponse->Command != Command)) {
+        if (0 == RetryCnt) {
+          return EFI_DEVICE_ERROR;
+        } else {
+          continue;
+        }
+      }
+      return EFI_BUFFER_TOO_SMALL;
+    }
+
+    break;
+  }
+  //
+  // Copy data over to the response data buffer.
+  //
+  *ResponseDataSize = DataSize - IPMI_RESPONSE_HEADER_SIZE;
+  CopyMem (
+    ResponseData,
+    IpmiResponse->ResponseData,
+    *ResponseDataSize
+    );
+
+  //
+  // Add completion code in response data to meet the requirement of IPMI spec 2.0
+  //
+  *ResponseDataSize += 1; // Add one byte for Completion Code
+  for (Index = 1; Index < *ResponseDataSize; Index++) {
+    ResponseData [*ResponseDataSize - Index] = ResponseData [*ResponseDataSize - (Index + 1)];
+  }
+  ResponseData [0] = IpmiResponse->CompletionCode;
+
+  IpmiInstance->BmcStatus = BMC_OK;
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+IpmiBmcStatus (
+  IN  IPMI_TRANSPORT              *This,
+  OUT BMC_STATUS                  *BmcStatus,
+  OUT SM_COM_ADDRESS              *ComAddress,
+  IN  VOID                            *Context
+  )
+/*++
+
+Routine Description:
+
+  Updates the BMC status and returns the Com Address
+
+Arguments:
+
+  This        - Pointer to IPMI protocol instance
+  BmcStatus   - BMC status
+  ComAddress  - Com Address
+  Context     - Context
+
+Returns:
+
+  EFI_SUCCESS - Success
+
+--*/
+{
+  IPMI_BMC_INSTANCE_DATA  *IpmiInstance;
+
+  IpmiInstance = INSTANCE_FROM_SM_IPMI_BMC_THIS (This);
+
+  if ((IpmiInstance->BmcStatus == BMC_SOFTFAIL) && (IpmiInstance->SoftErrorCount >= MAX_SOFT_COUNT)) {
+    IpmiInstance->BmcStatus = BMC_HARDFAIL;
+  }
+
+  *BmcStatus = IpmiInstance->BmcStatus;
+  ComAddress->ChannelType = SmBmc;
+  ComAddress->Address.BmcAddress.LunAddress = 0x0;
+  ComAddress->Address.BmcAddress.SlaveAddress = IpmiInstance->SlaveAddress;
+  ComAddress->Address.BmcAddress.ChannelAddress = 0x0;
+
+  return EFI_SUCCESS;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmc.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmc.h
new file mode 100644
index 0000000000..d306a085e5
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmc.h
@@ -0,0 +1,44 @@
+/** @file
+  IPMI Transport common layer driver head file
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMI_BMC_H_
+#define _IPMI_BMC_H_
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/IpmiBaseLib.h>
+#include <Protocol/IpmiTransportProtocol.h>
+
+#include "IpmiBmcCommon.h"
+#include "KcsBmc.h"
+
+
+#define BMC_KCS_TIMEOUT  5   // [s] Single KSC request timeout
+
+//
+// IPMI Instance signature
+//
+#define SM_IPMI_BMC_SIGNATURE SIGNATURE_32 ('i', 'p', 'm', 'i')
+#define IPMI_SEND_COMMAND_MAX_RETRY  3   // Number of retries
+#define INSTANCE_FROM_SM_IPMI_BMC_THIS(a) \
+  CR ( \
+  a, \
+  IPMI_BMC_INSTANCE_DATA, \
+  IpmiTransport, \
+  SM_IPMI_BMC_SIGNATURE \
+  )
+
+#endif // _IPMI_BMC_H_
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmcCommon.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmcCommon.h
new file mode 100644
index 0000000000..1e5dfd81f1
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiBmcCommon.h
@@ -0,0 +1,179 @@
+/** @file
+  IPMI Transport common layer driver common head file
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMI_COMMON_BMC_H_
+#define _IPMI_COMMON_BMC_H_
+
+#define MAX_TEMP_DATA     255 // 160 Modified to increase number of bytes transfered per command
+#define BMC_SLAVE_ADDRESS 0x20
+#define MAX_SOFT_COUNT    10
+#define COMP_CODE_NORMAL  0x00
+
+//
+// IPMI command completion codes to check for in the UpdateErrorStatus routine.
+// These completion codes indicate a soft error and a running total of the occurrences
+// of these errors is maintained.
+//
+#define COMP_CODE_NODE_BUSY               0xC0
+#define COMP_CODE_TIMEOUT                 0xC3
+#define COMP_CODE_OUT_OF_SPACE            0xC4
+#define COMP_CODE_OUT_OF_RANGE            0xC9
+#define COMP_CODE_CMD_RESP_NOT_PROVIDED   0xCE
+#define COMP_CODE_FAIL_DUP_REQUEST        0xCF
+#define COMP_CODE_SDR_REP_IN_UPDATE_MODE  0xD0
+#define COMP_CODE_DEV_IN_FW_UPDATE_MODE   0xD1
+#define COMP_CODE_BMC_INIT_IN_PROGRESS    0xD2
+//
+// Intel Server System Integrated Baseboard Management Controller (BMC) Firmware v0.62
+// D4h C Insufficient privilege, in KCS channel this indicates KCS Policy Control Mode is Deny All.
+// In authenticated channels this indicates invalid authentication/privilege.
+//
+#define COMP_INSUFFICIENT_PRIVILEGE       0xD4
+#define COMP_CODE_UNSPECIFIED             0xFF
+
+#define COMPLETION_CODES \
+  { \
+    COMP_CODE_NODE_BUSY, COMP_CODE_TIMEOUT, COMP_CODE_OUT_OF_SPACE, COMP_CODE_OUT_OF_RANGE, \
+    COMP_CODE_CMD_RESP_NOT_PROVIDED, COMP_CODE_FAIL_DUP_REQUEST, COMP_CODE_SDR_REP_IN_UPDATE_MODE, \
+    COMP_CODE_DEV_IN_FW_UPDATE_MODE, COMP_CODE_BMC_INIT_IN_PROGRESS, COMP_INSUFFICIENT_PRIVILEGE, COMP_CODE_UNSPECIFIED \
+  }
+
+//
+// Dxe Ipmi instance data
+//
+typedef struct {
+  UINTN               Signature;
+  UINT64              KcsTimeoutPeriod;
+  UINT8               SlaveAddress;
+  UINT8               TempData[MAX_TEMP_DATA];
+  BMC_STATUS          BmcStatus;
+  UINT64              ErrorStatus;
+  UINT8               SoftErrorCount;
+  UINT16              IpmiIoBase;
+  IPMI_TRANSPORT      IpmiTransport;
+  EFI_HANDLE          IpmiSmmHandle;
+} IPMI_BMC_INSTANCE_DATA;
+
+//
+// Structure of IPMI Command buffer
+//
+#define IPMI_COMMAND_HEADER_SIZE  2
+
+typedef struct {
+  UINT8 Lun : 2;
+  UINT8 NetFunction : 6;
+  UINT8 Command;
+  UINT8 CommandData[MAX_TEMP_DATA - IPMI_COMMAND_HEADER_SIZE];
+} IPMI_COMMAND;
+
+//
+// Structure of IPMI Command response buffer
+//
+#define IPMI_RESPONSE_HEADER_SIZE 3
+
+typedef struct {
+  UINT8 Lun : 2;
+  UINT8 NetFunction : 6;
+  UINT8 Command;
+  UINT8 CompletionCode;
+  UINT8 ResponseData[MAX_TEMP_DATA - IPMI_RESPONSE_HEADER_SIZE];
+} IPMI_RESPONSE;
+
+EFI_STATUS
+EFIAPI
+IpmiSendCommandToBmc (
+  IN      IPMI_TRANSPORT                *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:
+
+  Send IPMI command to BMC
+
+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           - Context
+
+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_SUCCESS           - Command completed successfully
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+IpmiBmcStatus (
+  IN  IPMI_TRANSPORT              *This,
+  OUT BMC_STATUS                  *BmcStatus,
+  OUT SM_COM_ADDRESS              *ComAddress,
+  IN  VOID                        *Context
+  )
+/*++
+
+Routine Description:
+
+  Updates the BMC status and returns the Com Address
+
+Arguments:
+
+  This        - Pointer to IPMI protocol instance
+  BmcStatus   - BMC status
+  ComAddress  - Com Address
+  Context     - Context
+
+Returns:
+
+  EFI_SUCCESS - Success
+
+--*/
+;
+
+VOID
+GetDeviceSpecificTestResults (
+  IN      IPMI_BMC_INSTANCE_DATA  *IpmiInstance
+  )
+/*++
+
+Routine Description:
+
+  This is a BMC specific routine to check the device specific self test results as defined
+  in the Bensley BMC core specification.
+
+Arguments:
+
+  IpmiInstance  - Data structure describing BMC variables and used for sending commands
+
+Returns:
+
+  VOID
+
+--*/
+;
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiHooks.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiHooks.c
new file mode 100644
index 0000000000..86ff7c0fdf
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiHooks.c
@@ -0,0 +1,96 @@
+/** @file
+  IPMI common hook functions
+
+  @copyright
+  Copyright 2014 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "IpmiHooks.h"
+
+EFI_STATUS
+IpmiSendCommand (
+  IN      IPMI_TRANSPORT               *This,
+  IN      UINT8                        NetFunction,
+  IN      UINT8                        Lun,
+  IN      UINT8                        Command,
+  IN      UINT8                        *CommandData,
+  IN      UINT32                       CommandDataSize,
+  IN OUT  UINT8                        *ResponseData,
+  IN OUT  UINT32                       *ResponseDataSize
+  )
+/*++
+
+Routine Description:
+
+  Send Ipmi Command in the right mode: HECI or KCS,  to the
+  appropiate device, ME or BMC.
+
+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
+
+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
+
+--*/
+{
+  //
+  // This Will be unchanged ( BMC/KCS style )
+  //
+  return IpmiSendCommandToBmc (
+           This,
+           NetFunction,
+           Lun,
+           Command,
+           CommandData,
+           (UINT8) CommandDataSize,
+           ResponseData,
+           (UINT8*) ResponseDataSize,
+           NULL
+           );
+} // IpmiSendCommand()
+
+EFI_STATUS
+IpmiGetBmcStatus (
+  IN IPMI_TRANSPORT                *This,
+  OUT BMC_STATUS                   *BmcStatus,
+  OUT SM_COM_ADDRESS               *ComAddress
+  )
+/*++
+
+Routine Description:
+
+  Updates the BMC status and returns the Com Address
+
+Arguments:
+
+  This        - Pointer to IPMI protocol instance
+  BmcStatus   - BMC status
+  ComAddress  - Com Address
+
+Returns:
+
+  EFI_SUCCESS - Success
+
+--*/
+{
+  return IpmiBmcStatus (
+           This,
+           BmcStatus,
+           ComAddress,
+           NULL
+           );
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiHooks.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiHooks.h
new file mode 100644
index 0000000000..083c9e70b0
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiHooks.h
@@ -0,0 +1,81 @@
+/** @file
+  IPMI common hook functions head file
+
+  @copyright
+  Copyright 2014 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMI_HOOKS_H
+#define _IPMI_HOOKS_H
+
+#include "IpmiBmc.h"
+
+//
+// Internal(hook) function list
+//
+EFI_STATUS
+IpmiSendCommand (
+  IN      IPMI_TRANSPORT               *This,
+  IN      UINT8                        NetFunction,
+  IN      UINT8                        Lun,
+  IN      UINT8                        Command,
+  IN      UINT8                        *CommandData,
+  IN      UINT32                       CommandDataSize,
+  IN OUT  UINT8                        *ResponseData,
+  IN OUT  UINT32                       *ResponseDataSize
+  )
+/*++
+
+Routine Description:
+
+  Send IPMI command to BMC
+
+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
+
+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
+IpmiGetBmcStatus (
+  IN IPMI_TRANSPORT                                    *This,
+  OUT BMC_STATUS                                       *BmcStatus,
+  OUT SM_COM_ADDRESS                                   *ComAddress
+  )
+/*++
+
+Routine Description:
+
+  Updates the BMC status and returns the Com Address
+
+Arguments:
+
+  This        - Pointer to IPMI protocol instance
+  BmcStatus   - BMC status
+  ComAddress  - Com Address
+
+Returns:
+
+  EFI_SUCCESS - Success
+
+--*/
+;
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiPhysicalLayer.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiPhysicalLayer.h
new file mode 100644
index 0000000000..0215bd0e5a
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/IpmiPhysicalLayer.h
@@ -0,0 +1,29 @@
+/** @file
+  IPMI Common physical layer functions.
+
+  @copyright
+  Copyright 2014 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPMI_PHYSICAL_LAYER_H
+#define _IPMI_PHYSICAL_LAYER_H
+
+//
+// KCS physical interface layer
+//
+EFI_STATUS
+InitializeIpmiKcsPhysicalLayer (
+  IN EFI_HANDLE ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  );
+
+
+EFI_STATUS
+SmmInitializeIpmiKcsPhysicalLayer (
+  IN EFI_HANDLE ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  );
+
+#endif
+
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/KcsBmc.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/KcsBmc.c
new file mode 100644
index 0000000000..7243d37cc5
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/KcsBmc.c
@@ -0,0 +1,483 @@
+/** @file
+  KCS Transport Hook.
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "KcsBmc.h"
+
+EFI_STATUS
+KcsErrorExit (
+  UINT64                            KcsTimeoutPeriod,
+  UINT16                            KcsPort,
+  VOID                              *Context
+  )
+/*++
+
+Routine Description:
+
+  Check the KCS error status
+
+Arguments:
+
+  IpmiInstance     - The pointer of IPMI_BMC_INSTANCE_DATA
+  KcsPort          - The base port of KCS
+  Context          - The Context for this operation
+
+Returns:
+
+  EFI_DEVICE_ERROR - The device error happened
+  EFI_SUCCESS      - Successfully check the KCS error status
+
+--*/
+{
+  EFI_STATUS      Status;
+  UINT8           KcsData;
+  KCS_STATUS      KcsStatus;
+  UINT8           BmcStatus;
+  UINT8           RetryCount;
+  UINT64          TimeOut;
+
+  TimeOut     = 0;
+  RetryCount  = 0;
+  while (RetryCount < KCS_ABORT_RETRY_COUNT) {
+
+    TimeOut = 0;
+    do {
+      MicroSecondDelay (KCS_DELAY_UNIT);
+      KcsStatus.RawData = IoRead8 (KcsPort + 1);
+      if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+        RetryCount = KCS_ABORT_RETRY_COUNT;
+        break;
+      }
+      TimeOut++;
+    } while (KcsStatus.Status.Ibf);
+
+    if (RetryCount >= KCS_ABORT_RETRY_COUNT) {
+      break;
+    }
+
+    KcsData = KCS_ABORT;
+    IoWrite8 ((KcsPort + 1), KcsData);
+
+    TimeOut = 0;
+    do {
+      MicroSecondDelay (KCS_DELAY_UNIT);
+      KcsStatus.RawData = IoRead8 (KcsPort + 1);
+      if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+        Status = EFI_DEVICE_ERROR;
+        goto LabelError;
+      }
+      TimeOut++;
+    } while (KcsStatus.Status.Ibf);
+
+    KcsData = IoRead8 (KcsPort);
+
+    KcsData = 0x0;
+    IoWrite8 (KcsPort, KcsData);
+
+    TimeOut = 0;
+    do {
+      MicroSecondDelay (KCS_DELAY_UNIT);
+      KcsStatus.RawData = IoRead8 (KcsPort + 1);
+      if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+        Status = EFI_DEVICE_ERROR;
+        goto LabelError;
+      }
+      TimeOut++;
+    } while (KcsStatus.Status.Ibf);
+
+    if (KcsStatus.Status.State == KcsReadState) {
+      TimeOut = 0;
+      do {
+        MicroSecondDelay (KCS_DELAY_UNIT);
+        KcsStatus.RawData = IoRead8 (KcsPort + 1);
+        if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+          Status = EFI_DEVICE_ERROR;
+          goto LabelError;
+        }
+        TimeOut++;
+      } while (!KcsStatus.Status.Obf);
+
+      BmcStatus = IoRead8 (KcsPort);
+
+      KcsData = KCS_READ;
+      IoWrite8 (KcsPort, KcsData);
+
+      TimeOut = 0;
+      do {
+        MicroSecondDelay (KCS_DELAY_UNIT);
+        KcsStatus.RawData = IoRead8 (KcsPort + 1);
+        if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+          Status = EFI_DEVICE_ERROR;
+          goto LabelError;
+        }
+        TimeOut++;
+      } while (KcsStatus.Status.Ibf);
+
+      if (KcsStatus.Status.State == KcsIdleState) {
+        TimeOut = 0;
+        do {
+          MicroSecondDelay (KCS_DELAY_UNIT);
+          KcsStatus.RawData = IoRead8 (KcsPort + 1);
+          if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+            Status = EFI_DEVICE_ERROR;
+            goto LabelError;
+          }
+          TimeOut++;
+        } while (!KcsStatus.Status.Obf);
+
+        KcsData = IoRead8 (KcsPort);
+        break;
+
+      } else {
+        RetryCount++;
+        continue;
+      }
+
+    } else {
+      RetryCount++;
+      continue;
+    }
+  }
+
+  if (RetryCount >= KCS_ABORT_RETRY_COUNT) {
+    Status = EFI_DEVICE_ERROR;
+    goto LabelError;
+  }
+
+  return EFI_SUCCESS;
+
+LabelError:
+  return Status;
+}
+
+EFI_STATUS
+KcsCheckStatus (
+  UINT64                            KcsTimeoutPeriod,
+  UINT16                            KcsPort,
+  KCS_STATE                         KcsState,
+  BOOLEAN                           *Idle,
+  VOID                              *Context
+  )
+/*++
+
+Routine Description:
+
+  Ckeck KCS status
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  KcsPort       - The base port of KCS
+  KcsState      - The state of KCS to be checked
+  Idle          - If the KCS is idle
+  Context       - The context for this operation
+
+Returns:
+
+  EFI_SUCCESS   - Checked the KCS status successfully
+
+--*/
+{
+  EFI_STATUS      Status;
+  KCS_STATUS      KcsStatus;
+  UINT8           KcsData;
+  UINT64          TimeOut;
+
+  if (Idle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Idle = FALSE;
+
+  TimeOut = 0;
+  do {
+    MicroSecondDelay (KCS_DELAY_UNIT);
+    KcsStatus.RawData = IoRead8 (KcsPort + 1);
+    if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+      Status = EFI_DEVICE_ERROR;
+      goto LabelError;
+    }
+    TimeOut++;
+  } while (KcsStatus.Status.Ibf);
+
+  if (KcsState == KcsWriteState) {
+    KcsData = IoRead8 (KcsPort);
+  }
+
+  if (KcsStatus.Status.State != KcsState) {
+    if ((KcsStatus.Status.State == KcsIdleState) && (KcsState == KcsReadState)) {
+      *Idle = TRUE;
+    } else {
+      Status = KcsErrorExit (KcsTimeoutPeriod, KcsPort, Context);
+      goto LabelError;
+    }
+  }
+
+  if (KcsState == KcsReadState) {
+    TimeOut = 0;
+    do {
+      MicroSecondDelay (KCS_DELAY_UNIT);
+      KcsStatus.RawData = IoRead8 (KcsPort + 1);
+      if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+        Status = EFI_DEVICE_ERROR;
+        goto LabelError;
+      }
+      TimeOut++;
+    } while (!KcsStatus.Status.Obf);
+  }
+
+  if (KcsState == KcsWriteState || (*Idle == TRUE)) {
+    KcsData = IoRead8 (KcsPort);
+  }
+
+  return EFI_SUCCESS;
+
+LabelError:
+  return Status;
+}
+
+EFI_STATUS
+SendDataToBmc (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  VOID                            *Context,
+  UINT8                           *Data,
+  UINT8                           DataSize
+  )
+/*++
+
+Routine Description:
+
+  Send data to BMC
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  Context       - The context of this operation
+  Data          - The data pointer to be sent
+  DataSize      - The data size
+
+Returns:
+
+  EFI_SUCCESS   - Send out the data successfully
+
+--*/
+{
+  KCS_STATUS      KcsStatus;
+  UINT8           KcsData;
+  UINT16          KcsIoBase;
+  EFI_STATUS      Status;
+  UINT8           i;
+  BOOLEAN         Idle;
+  UINT64          TimeOut;
+
+  KcsIoBase = KcsPort;
+
+  TimeOut = 0;
+
+  do {
+    MicroSecondDelay (KCS_DELAY_UNIT);
+    KcsStatus.RawData = IoRead8 (KcsIoBase + 1);
+    if ((KcsStatus.RawData == 0xFF) || (TimeOut >= KcsTimeoutPeriod)) {
+      if ((Status = KcsErrorExit (KcsTimeoutPeriod, KcsIoBase, Context)) != EFI_SUCCESS) {
+        return Status;
+      }
+    }
+    TimeOut++;
+  } while (KcsStatus.Status.Ibf);
+
+  KcsData = KCS_WRITE_START;
+  IoWrite8 ((KcsIoBase + 1), KcsData);
+  if ((Status = KcsCheckStatus (KcsTimeoutPeriod, KcsIoBase, KcsWriteState, &Idle, Context)) != EFI_SUCCESS) {
+    return Status;
+  }
+
+  for (i = 0; i < DataSize; i++) {
+    if (i == (DataSize - 1)) {
+      if ((Status = KcsCheckStatus (KcsTimeoutPeriod, KcsIoBase, KcsWriteState, &Idle, Context)) != EFI_SUCCESS) {
+        return Status;
+      }
+
+      KcsData = KCS_WRITE_END;
+      IoWrite8 ((KcsIoBase + 1), KcsData);
+    }
+
+    Status = KcsCheckStatus (KcsTimeoutPeriod, KcsIoBase, KcsWriteState, &Idle, Context);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    IoWrite8 (KcsIoBase, Data[i]);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ReceiveBmcData (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  VOID                            *Context,
+  UINT8                           *Data,
+  UINT8                           *DataSize
+  )
+/*++
+
+Routine Description:
+
+  Routine Description:
+
+  Receive data from BMC
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  Context       - The context of this operation
+  Data          - The buffer pointer
+  DataSize      - The buffer size
+
+Returns:
+
+  EFI_SUCCESS   - Received data successfully
+
+--*/
+{
+  UINT8       KcsData;
+  UINT16      KcsIoBase;
+  EFI_STATUS  Status;
+  BOOLEAN     Idle;
+  UINT8       Count;
+
+  Count     = 0;
+  KcsIoBase = KcsPort;
+
+  while (TRUE) {
+
+    if ((Status = KcsCheckStatus (KcsTimeoutPeriod, KcsIoBase, KcsReadState, &Idle, Context)) != EFI_SUCCESS) {
+      return Status;
+    }
+
+    if (Idle) {
+      *DataSize = Count;
+      break;
+    }
+
+    //
+    //Need to check Data Size -1 to account for array access
+    //
+    if (Count >= *DataSize) {
+      return EFI_DEVICE_ERROR;
+    }
+
+    Data[Count] = IoRead8 (KcsIoBase);
+
+    Count++;
+
+    KcsData = KCS_READ;
+    IoWrite8 (KcsIoBase, KcsData);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ReceiveBmcDataFromPort (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  VOID                            *Context,
+  UINT8                           *Data,
+  UINT8                           *DataSize
+  )
+/*++
+
+Routine Description:
+
+  Receive data from BMC
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  Context       - The context of this operation
+  Data          - The buffer pointer to receive data
+  DataSize      - The buffer size
+
+Returns:
+
+  EFI_SUCCESS   - Received the data successfully
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT16      KcsIoBase;
+  UINT8       i;
+  UINT8       MyDataSize;
+
+  MyDataSize  = *DataSize;
+  KcsIoBase   = KcsPort;
+
+  for (i = 0; i < KCS_ABORT_RETRY_COUNT; i++) {
+    Status = ReceiveBmcData (KcsTimeoutPeriod, KcsIoBase, Context, Data, DataSize);
+    if (EFI_ERROR (Status)) {
+      if ((Status = KcsErrorExit (KcsTimeoutPeriod, KcsIoBase, Context)) != EFI_SUCCESS) {
+        return Status;
+      }
+
+      *DataSize = MyDataSize;
+    } else {
+      return Status;
+    }
+  }
+
+  return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+SendDataToBmcPort (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  VOID                            *Context,
+  UINT8                           *Data,
+  UINT8                           DataSize
+  )
+/*++
+
+Routine Description:
+
+  Send data to BMC
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  Context       - The context of this operation
+  Data          - The data pointer to be sent
+  DataSize      - The data size
+
+Returns:
+
+  EFI_SUCCESS   - Send out the data successfully
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT16      KcsIoBase;
+  UINT8       i;
+
+  KcsIoBase = KcsPort;
+
+  for (i = 0; i < KCS_ABORT_RETRY_COUNT; i++) {
+    Status = SendDataToBmc (KcsTimeoutPeriod, KcsIoBase, Context, Data, DataSize);
+    if (EFI_ERROR (Status)) {
+      if ((Status = KcsErrorExit (KcsTimeoutPeriod, KcsIoBase, Context)) != EFI_SUCCESS) {
+        return Status;
+      }
+    } else {
+      return Status;
+    }
+  }
+
+  return EFI_DEVICE_ERROR;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/KcsBmc.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/KcsBmc.h
new file mode 100644
index 0000000000..a8684cc4f6
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/KcsBmc.h
@@ -0,0 +1,236 @@
+/** @file
+  KCS Transport Hook head file.
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _KCS_BMC_H
+#define _KCS_BMC_H
+
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+
+#define KCS_WRITE_START       0x61
+#define KCS_WRITE_END         0x62
+#define KCS_READ              0x68
+#define KCS_GET_STATUS        0x60
+#define KCS_ABORT             0x60
+#define KCS_DELAY_UNIT        50  // [s] Each KSC IO delay
+
+//
+// In OpenBMC, UpdateMode: the bit 7 of byte 4 in get device id command is used for the BMC status:
+// 0 means BMC is ready, 1 means BMC is not ready.
+// At the very beginning of BMC power on, the status is 1 means BMC is in booting process and not ready. It is not the flag for force update mode.
+//
+#define BMC_READY             0
+
+
+#define KCS_ABORT_RETRY_COUNT 1
+
+//#define TIMEOUT64(a,b)  ((INT64)((b) - (a)) < 0)
+
+typedef enum {
+  KcsIdleState,
+  KcsReadState,
+  KcsWriteState,
+  KcsErrorState
+} KCS_STATE;
+
+typedef union {
+  UINT8     RawData;
+  struct {
+    UINT8 Obf   : 1;
+    UINT8 Ibf   : 1;
+    UINT8 SmAtn : 1;
+    UINT8 CD    : 1;
+    UINT8 Oem1  : 1;
+    UINT8 Oem2  : 1;
+    UINT8 State : 2;
+  } Status;
+} KCS_STATUS;
+
+
+//
+//External Fucntion List
+//
+EFI_STATUS
+SendDataToBmcPort (
+  UINT64                                    KcsTimeoutPeriod,
+  UINT16                                    KcsPort,
+  VOID                                      *Context,
+  UINT8                                     *Data,
+  UINT8                                     DataSize
+  )
+/*++
+
+Routine Description:
+
+  Send data to BMC
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  Context       - The context of this operation
+  Data          - The data pointer to be sent
+  DataSize      - The data size
+
+Returns:
+
+  EFI_SUCCESS   - Send out the data successfully
+
+--*/
+;
+
+EFI_STATUS
+ReceiveBmcDataFromPort (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  VOID                            *Context,
+  UINT8                           *Data,
+  UINT8                           *DataSize
+  )
+/*++
+
+Routine Description:
+
+  Routine Description:
+
+  Receive data from BMC
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  Context       - The context of this operation
+  Data          - The buffer pointer
+  DataSize      - The buffer size
+
+Returns:
+
+  EFI_SUCCESS   - Received data successfully
+
+--*/
+;
+
+//
+//Internal Fucntion List
+//
+EFI_STATUS
+KcsErrorExit (
+  UINT64                            KcsTimeoutPeriod,
+  UINT16                            KcsPort,
+  VOID                              *Context
+  )
+/*++
+
+Routine Description:
+
+  Check the KCS error status
+
+Arguments:
+
+  IpmiInstance     - The pointer of IPMI_BMC_INSTANCE_DATA
+  KcsPort          - The base port of KCS
+  Context          - The Context for this operation
+
+Returns:
+
+  EFI_DEVICE_ERROR - The device error happened
+  EFI_SUCCESS      - Successfully check the KCS error status
+
+--*/
+;
+
+EFI_STATUS
+KcsCheckStatus (
+  UINT64                            KcsTimeoutPeriod,
+  UINT16                            KcsPort,
+  KCS_STATE                         KcsState,
+  BOOLEAN                           *Idle,
+  VOID                              *Context
+  )
+/*++
+
+Routine Description:
+
+  Ckeck KCS status
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  KcsPort       - The base port of KCS
+  KcsState      - The state of KCS to be checked
+  Idle          - If the KCS is idle
+  Context       - The context for this operation
+
+Returns:
+
+  EFI_SUCCESS   - Checked the KCS status successfully
+
+--*/
+;
+
+
+EFI_STATUS
+SendDataToBmc (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  VOID                            *Context,
+  UINT8                           *Data,
+  UINT8                           DataSize
+  )
+/*++
+
+Routine Description:
+
+  Send data to BMC
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  Context       - The context of this operation
+  Data          - The data pointer to be sent
+  DataSize      - The data size
+
+Returns:
+
+  EFI_SUCCESS   - Send out the data successfully
+
+--*/
+;
+
+
+EFI_STATUS
+ReceiveBmcData (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  VOID                            *Context,
+  UINT8                           *Data,
+  UINT8                           *DataSize
+  )
+/*++
+
+Routine Description:
+
+  Routine Description:
+
+  Receive data from BMC
+
+Arguments:
+
+  IpmiInstance  - The pointer of IPMI_BMC_INSTANCE_DATA
+  Context       - The context of this operation
+  Data          - The buffer pointer
+  DataSize      - The buffer size
+
+Returns:
+
+  EFI_SUCCESS   - Received data successfully
+
+--*/
+;
+
+#endif
-- 
2.27.0.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#72314): https://edk2.groups.io/g/devel/message/72314
Mute This Topic: https://groups.io/mt/81016656/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list