From: "Nate DeSimone" <nathaniel.l.desimone@intel.com>
To: devel@edk2.groups.io
Cc: Isaac Oram <isaac.w.oram@intel.com>,
Sai Chaganty <rangasai.v.chaganty@intel.com>,
Liming Gao <gaoliming@byosoft.com.cn>,
Michael Kubacki <michael.kubacki@microsoft.com>
Subject: [edk2-platforms] [PATCH v1 4/9] IpmiFeaturePkg: Add GenericIpmi driver common code
Date: Mon, 1 Mar 2021 18:27:59 -0800 [thread overview]
Message-ID: <20210302022804.8641-5-nathaniel.l.desimone@intel.com> (raw)
In-Reply-To: <20210302022804.8641-1-nathaniel.l.desimone@intel.com>
From: Isaac Oram <isaac.w.oram@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@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Michael Kubacki <michael.kubacki@microsoft.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
Co-authored-by: Nate DeSimone <nathaniel.l.desimone@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
next prev parent reply other threads:[~2021-03-02 2:29 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-02 2:27 [edk2-platforms] [PATCH v1 0/9] IpmiFeaturePkg: Add IPMI transport drivers Nate DeSimone
2021-03-02 2:27 ` [edk2-platforms] [PATCH v1 1/9] IpmiFeaturePkg: Add IPMI driver Include headers Nate DeSimone
2021-03-02 2:27 ` [edk2-platforms] [PATCH v1 2/9] IpmiFeaturePkg: Add IpmiBaseLib and IpmiCommandLib Nate DeSimone
2021-03-02 2:27 ` [edk2-platforms] [PATCH v1 3/9] IpmiFeaturePkg: Add IpmiInit driver DEPEXs Nate DeSimone
2021-03-02 2:27 ` Nate DeSimone [this message]
2021-03-02 2:28 ` [edk2-platforms] [PATCH v1 5/9] IpmiFeaturePkg: Add GenericIpmi PEIM Nate DeSimone
2021-03-02 2:28 ` [edk2-platforms] [PATCH v1 6/9] IpmiFeaturePkg: Add GenericIpmi DXE Driver Nate DeSimone
2021-03-02 2:28 ` [edk2-platforms] [PATCH v1 7/9] IpmiFeaturePkg: Add GenericIpmi SMM Driver Nate DeSimone
2021-03-02 2:28 ` [edk2-platforms] [PATCH v1 8/9] IpmiFeaturePkg: Add IPMI driver build files Nate DeSimone
2021-03-02 2:28 ` [edk2-platforms] [PATCH v1 9/9] Maintainers.txt: Add IpmiFeaturePkg maintainers Nate DeSimone
2021-03-03 19:22 ` [edk2-devel] [edk2-platforms] [PATCH v1 0/9] IpmiFeaturePkg: Add IPMI transport drivers Michael Kubacki
2021-03-04 23:33 ` Oram, Isaac W
2021-03-05 11:06 ` Nhi Pham
2021-03-11 19:29 ` Chaganty, Rangasai V
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210302022804.8641-5-nathaniel.l.desimone@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox