[edk2-devel] [edk2-platforms] [PATCH v1 6/9] IpmiFeaturePkg: Add GenericIpmi DXE Driver

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


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

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

Adds the DXE version of 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/Dxe/GenericIpmi.c             |  46 ++
 .../GenericIpmi/Dxe/GenericIpmi.inf           |  66 +++
 .../IpmiFeaturePkg/GenericIpmi/Dxe/IpmiInit.c | 452 ++++++++++++++++++
 3 files changed, 564 insertions(+)
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.c
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.inf
 create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/IpmiInit.c

diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.c
new file mode 100644
index 0000000000..957a9c8e6e
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.c
@@ -0,0 +1,46 @@
+/** @file
+  Generic IPMI Transport functions..
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/Ipmi.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 "IpmiPhysicalLayer.h"
+
+/*****************************************************************************
+ @brief
+  This is entry point for IPMI service for BIOS POST.
+
+ @param[in] ImageHandle  a handle to driver image
+ @param[in] SystemTable  a pointer to system table
+
+ @retval EFI_SUCCESS      The function completed successfully.
+ @retval EFI_UNSUPPORTED  IPMI is not available.
+**/
+EFI_STATUS
+LocateIpmiInterface (
+  IN EFI_HANDLE             ImageHandle,
+  IN EFI_SYSTEM_TABLE       *SystemTable
+  )
+{
+  EFI_STATUS          Status;
+
+  Status = InitializeIpmiKcsPhysicalLayer (ImageHandle, SystemTable);
+
+  //
+  // keep this interface for other Physical Layer as new interface.
+  //
+
+  return Status;
+} // LocateIpmiInterface()
+
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.inf
new file mode 100644
index 0000000000..9881f9e3d0
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.inf
@@ -0,0 +1,66 @@
+## @file
+# Generic IPMI DXE Driver.
+#
+# @copyright
+# Copyright 2010 - 2021 Intel Corporation. <BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = GenericIpmi
+  FILE_GUID                      = 07A01ACF-46D5-48de-A63D-74FA92AA8450
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = LocateIpmiInterface
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+#  VIRTUAL_ADDRESS_MAP_CALLBACK  = VariableAddressChangeEvent
+#
+
+[Sources]
+  ../Common/IpmiHooks.h
+  ../Common/IpmiHooks.c
+  ../Common/IpmiBmcCommon.h
+  ../Common/KcsBmc.c
+  ../Common/KcsBmc.h
+  ../Common/IpmiBmc.h
+  ../Common/IpmiBmc.c
+  GenericIpmi.c
+  IpmiInit.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  BaseLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  DebugLib
+  DxeServicesTableLib
+  UefiDriverEntryPoint
+  IoLib
+  ReportStatusCodeLib
+  TimerLib
+
+[Protocols]
+  gIpmiTransportProtocolGuid               # PROTOCOL ALWAYS_PRODUCED
+  gEfiVideoPrintProtocolGuid
+
+[Guids]
+
+[Pcd]
+  gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress
+  gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiBmcReadyDelayTimer
+
+[Depex]
+  gEfiRuntimeArchProtocolGuid AND
+  gEfiVariableArchProtocolGuid
+
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/IpmiInit.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/IpmiInit.c
new file mode 100644
index 0000000000..1e0c132508
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/IpmiInit.c
@@ -0,0 +1,452 @@
+/** @file
+  Generic IPMI stack driver
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/Ipmi.h>
+#include <SmStatusCodes.h>
+#include "IpmiHooks.h"
+#include "IpmiBmcCommon.h"
+#include "IpmiBmc.h"
+#include "IpmiPhysicalLayer.h"
+#include <Library/TimerLib.h>
+#ifdef FAST_VIDEO_SUPPORT
+  #include <Protocol/VideoPrint.h>
+#endif
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+
+/******************************************************************************
+ * Local variables
+ */
+IPMI_BMC_INSTANCE_DATA       *mIpmiInstance = NULL;
+EFI_HANDLE                    mImageHandle;
+
+//
+// Specific test interface
+//
+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
+
+--*/
+{
+  return;
+}
+
+EFI_STATUS
+GetSelfTest (
+  IN      IPMI_BMC_INSTANCE_DATA     *IpmiInstance,
+  IN      EFI_STATUS_CODE_VALUE       StatusCodeValue[],
+  IN OUT  UINT8                       *ErrorCount
+  )
+/*++
+
+Routine Description:
+
+  Execute the Get Self Test results command to determine whether or not the BMC self tests
+  have passed
+
+Arguments:
+
+  IpmiInstance    - Data structure describing BMC variables and used for sending commands
+  StatusCodeValue - An array used to accumulate error codes for later reporting.
+  ErrorCount      - Counter used to keep track of error codes in StatusCodeValue
+
+Returns:
+
+  EFI_SUCCESS       - BMC Self test results are retrieved and saved into BmcStatus
+  EFI_DEVICE_ERROR  - BMC failed to return self test results.
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT32      DataSize;
+  UINT8       Index;
+  UINT8       *TempPtr;
+  UINT32      Retries;
+  BOOLEAN     bResultFlag = FALSE;
+
+  //
+  // Get the SELF TEST Results.
+  //
+  //
+  //Note: If BMC PcdIpmiBmcReadyDelayTimer < BMC_KCS_TIMEOUT, it need set Retries as 1. Otherwise it will make SELT failure, caused by below condition (EFI_ERROR(Status) || Retries == 0)
+  //
+  if (PcdGet8 (PcdIpmiBmcReadyDelayTimer) < BMC_KCS_TIMEOUT) {
+    Retries = 1;
+  } else {
+    Retries = PcdGet8 (PcdIpmiBmcReadyDelayTimer);
+  }
+
+  DataSize = sizeof (IpmiInstance->TempData);
+
+  IpmiInstance->TempData[1] = 0;
+
+  do {
+    Status = IpmiSendCommand (
+               &IpmiInstance->IpmiTransport,
+               IPMI_NETFN_APP,
+               0,
+               IPMI_APP_GET_SELFTEST_RESULTS,
+               NULL,
+               0,
+               IpmiInstance->TempData,
+               &DataSize
+               );
+    if (Status == EFI_SUCCESS) {
+      switch (IpmiInstance->TempData[1]) {
+        case IPMI_APP_SELFTEST_NO_ERROR:
+        case IPMI_APP_SELFTEST_NOT_IMPLEMENTED:
+        case IPMI_APP_SELFTEST_ERROR:
+        case IPMI_APP_SELFTEST_FATAL_HW_ERROR:
+          bResultFlag = TRUE;
+          break;
+
+        default:
+          break;
+      } //switch
+
+      if (bResultFlag) {
+        break;
+      }
+    }
+
+    MicroSecondDelay (500 * 1000);
+  } while (--Retries > 0);
+
+  //
+  // If Status indicates a Device error, then the BMC is not responding, so send an error.
+  //
+  if (EFI_ERROR (Status) || Retries == 0) {
+    DEBUG ((EFI_D_ERROR, "\n[IPMI]  BMC self-test does not respond (status: %r)!\n\n", Status));
+    if (*ErrorCount < MAX_SOFT_COUNT) {
+      StatusCodeValue[*ErrorCount] = EFI_COMPUTING_UNIT_FIRMWARE_PROCESSOR | EFI_CU_FP_EC_COMM_ERROR;
+      (*ErrorCount)++;
+    }
+
+    IpmiInstance->BmcStatus = BMC_HARDFAIL;
+    return Status;
+  } else {
+    DEBUG ((EFI_D_INFO, "[IPMI] BMC self-test result: %02X-%02X\n", IpmiInstance->TempData[1], IpmiInstance->TempData[2]));
+    //
+    // Copy the Self test results to Error Status.  Data will be copied as long as it
+    // does not exceed the size of the ErrorStatus variable.
+    //
+    for (Index = 0, TempPtr = (UINT8 *) &IpmiInstance->ErrorStatus;
+         (Index < DataSize) && (Index < sizeof (IpmiInstance->ErrorStatus));
+         Index++, TempPtr++
+         ) {
+      *TempPtr = IpmiInstance->TempData[Index];
+    }
+    //
+    // Check the IPMI defined self test results.
+    // Additional Cases are device specific test results.
+    //
+    switch (IpmiInstance->TempData[0]) {
+      case IPMI_APP_SELFTEST_NO_ERROR:
+      case IPMI_APP_SELFTEST_NOT_IMPLEMENTED:
+        IpmiInstance->BmcStatus = BMC_OK;
+        break;
+
+      case IPMI_APP_SELFTEST_ERROR:
+        //
+        // Three of the possible errors result in BMC hard failure; FRU Corruption,
+        // BootBlock Firmware corruption, and Operational Firmware Corruption.  All
+        // other errors are BMC soft failures.
+        //
+        if ((IpmiInstance->TempData[1] & (IPMI_APP_SELFTEST_FRU_CORRUPT | IPMI_APP_SELFTEST_FW_BOOTBLOCK_CORRUPT | IPMI_APP_SELFTEST_FW_CORRUPT)) != 0) {
+          IpmiInstance->BmcStatus = BMC_HARDFAIL;
+        } else {
+          IpmiInstance->BmcStatus = BMC_SOFTFAIL;
+        }
+        //
+        // Check if SDR repository is empty and report it if it is.
+        //
+        if ((IpmiInstance->TempData[1] & IPMI_APP_SELFTEST_SDR_REPOSITORY_EMPTY) != 0) {
+          if (*ErrorCount < MAX_SOFT_COUNT) {
+            StatusCodeValue[*ErrorCount] = EFI_COMPUTING_UNIT_FIRMWARE_PROCESSOR | CU_FP_EC_SDR_EMPTY;
+            (*ErrorCount)++;
+          }
+        }
+        break;
+
+      case IPMI_APP_SELFTEST_FATAL_HW_ERROR:
+        IpmiInstance->BmcStatus = BMC_HARDFAIL;
+        break;
+
+      default:
+        //
+        // Call routine to check device specific failures.
+        //
+        GetDeviceSpecificTestResults (IpmiInstance);
+    }
+
+    if (IpmiInstance->BmcStatus == BMC_HARDFAIL) {
+      if (*ErrorCount < MAX_SOFT_COUNT) {
+        StatusCodeValue[*ErrorCount] = EFI_COMPUTING_UNIT_FIRMWARE_PROCESSOR | EFI_CU_FP_EC_HARD_FAIL;
+        (*ErrorCount)++;
+      }
+    } else if (IpmiInstance->BmcStatus == BMC_SOFTFAIL) {
+      if (*ErrorCount < MAX_SOFT_COUNT) {
+        StatusCodeValue[*ErrorCount] = EFI_COMPUTING_UNIT_FIRMWARE_PROCESSOR | EFI_CU_FP_EC_SOFT_FAIL;
+        (*ErrorCount)++;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+} // GetSelfTest()
+
+
+EFI_STATUS
+GetDeviceId (
+  IN      IPMI_BMC_INSTANCE_DATA       *IpmiInstance,
+  IN      EFI_STATUS_CODE_VALUE        StatusCodeValue[ ],
+  IN OUT  UINT8                        *ErrorCount
+  )
+/*++
+
+Routine Description:
+  Execute the Get Device ID command to determine whether or not the BMC is in Force Update
+  Mode.  If it is, then report it to the error manager.
+
+Arguments:
+  IpmiInstance    - Data structure describing BMC variables and used for sending commands
+  StatusCodeValue - An array used to accumulate error codes for later reporting.
+  ErrorCount      - Counter used to keep track of error codes in StatusCodeValue
+
+Returns:
+  Status
+
+--*/
+{
+  EFI_STATUS                      Status;
+  UINT32                          DataSize;
+  SM_CTRL_INFO                    *pBmcInfo;
+  EFI_IPMI_MSG_GET_BMC_EXEC_RSP   *pBmcExecContext;
+  UINT32                          Retries;
+#ifdef FAST_VIDEO_SUPPORT
+  EFI_VIDEOPRINT_PROTOCOL         *VideoPrintProtocol;
+  EFI_STATUS                      VideoPrintStatus;
+#endif
+
+#ifdef FAST_VIDEO_SUPPORT
+  VideoPrintStatus = gBS->LocateProtocol (
+                            &gEfiVideoPrintProtocolGuid,
+                            NULL,
+                            &VideoPrintProtocol
+                            );
+#endif
+
+  //
+  // Set up a loop to retry for up to PcdIpmiBmcReadyDelayTimer seconds. Calculate retries not timeout
+  // so that in case KCS is not enabled and IpmiSendCommand() returns
+  // immediately we will not wait all the PcdIpmiBmcReadyDelayTimer seconds.
+  //
+  Retries = PcdGet8 (PcdIpmiBmcReadyDelayTimer);
+  //
+  // Get the device ID information for the BMC.
+  //
+  DataSize = sizeof (IpmiInstance->TempData);
+  while (EFI_ERROR (Status = IpmiSendCommand (
+                               &IpmiInstance->IpmiTransport,
+                               IPMI_NETFN_APP, 0,
+                               IPMI_APP_GET_DEVICE_ID,
+                               NULL, 0,
+                               IpmiInstance->TempData, &DataSize))
+         ) {
+    DEBUG ((DEBUG_ERROR, "[IPMI] BMC does not respond by Get BMC DID (status: %r), %d retries left, ResponseData: 0x%lx\n",
+            Status, Retries, IpmiInstance->TempData));
+
+    if (Retries-- == 0) {
+      IpmiInstance->BmcStatus = BMC_HARDFAIL;
+      return Status;
+    }
+    //
+    //Handle the case that BMC FW still not enable KCS channel after AC cycle. just stall 1 second
+    //
+    MicroSecondDelay (1*1000*1000);
+  }
+
+  pBmcInfo = (SM_CTRL_INFO*)&IpmiInstance->TempData[0];
+  DEBUG ((EFI_D_ERROR, "[IPMI] BMC Device ID: 0x%02X, firmware version: %d.%02X UpdateMode:%x\n", pBmcInfo->DeviceId, pBmcInfo->MajorFirmwareRev, pBmcInfo->MinorFirmwareRev,pBmcInfo->UpdateMode));
+  //
+  // 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.
+  //
+  if (pBmcInfo->UpdateMode == BMC_READY) {
+    mIpmiInstance->BmcStatus = BMC_OK;
+    return EFI_SUCCESS;
+  } else {
+    Status = IpmiSendCommand (
+               &IpmiInstance->IpmiTransport,
+               IPMI_NETFN_FIRMWARE, 0,
+               EFI_FIRMWARE_GET_BMC_EXECUTION_CONTEXT,
+               NULL, 0,
+               IpmiInstance->TempData, &DataSize
+               );
+
+    pBmcExecContext = (EFI_IPMI_MSG_GET_BMC_EXEC_RSP*)&IpmiInstance->TempData[0];
+    DEBUG ((DEBUG_INFO, "[IPMI] Operational status of BMC: 0x%x\n", pBmcExecContext->CurrentExecutionContext));
+    if ((pBmcExecContext->CurrentExecutionContext == EFI_FIRMWARE_BMC_IN_FORCED_UPDATE_MODE) &&
+        !EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "[IPMI] BMC in Forced Update mode, skip waiting for BMC_READY.\n"));
+      IpmiInstance->BmcStatus = BMC_UPDATE_IN_PROGRESS;
+    } else {
+      //
+      // Updatemode = 1 mean BMC is not ready, continue waiting.
+      //
+      while (Retries-- != 0) {
+        MicroSecondDelay(1*1000*1000); //delay 1 seconds
+        DEBUG ((EFI_D_ERROR, "[IPMI] UpdateMode Retries: %d \n",Retries));
+        Status = IpmiSendCommand (
+                   &IpmiInstance->IpmiTransport,
+                   IPMI_NETFN_APP, 0,
+                   IPMI_APP_GET_DEVICE_ID,
+                   NULL, 0,
+                   IpmiInstance->TempData, &DataSize
+                   );
+
+        if (!EFI_ERROR (Status)) {
+          pBmcInfo = (SM_CTRL_INFO*)&IpmiInstance->TempData[0];
+          DEBUG ((EFI_D_ERROR, "[IPMI] UpdateMode Retries: %d   pBmcInfo->UpdateMode:%x, Status: %r, Response Data: 0x%lx\n",Retries, pBmcInfo->UpdateMode, Status, IpmiInstance->TempData));
+          if (pBmcInfo->UpdateMode == BMC_READY) {
+            mIpmiInstance->BmcStatus = BMC_OK;
+            return EFI_SUCCESS;
+          }
+        }
+      }
+      mIpmiInstance->BmcStatus = BMC_HARDFAIL;
+    }
+  }
+  return Status;
+} // GetDeviceId()
+
+
+/**
+  This function initializes KCS interface to BMC.
+
+  Setup and initialize the BMC for the DXE phase.  In order to verify the BMC is functioning
+  as expected, the BMC Selftest is performed.  The results are then checked and any errors are
+  reported to the error manager.  Errors are collected throughout this routine and reported
+  just prior to installing the driver.  If there are more errors than MAX_SOFT_COUNT, then they
+  will be ignored.
+
+  @param[in] ImageHandle - Handle of this driver image
+  @param[in] SystemTable - Table containing standard EFI services
+
+  @retval EFI_SUCCESS - Always success is returned even if KCS does not function
+ **/
+EFI_STATUS
+InitializeIpmiKcsPhysicalLayer (
+  IN EFI_HANDLE             ImageHandle,
+  IN EFI_SYSTEM_TABLE       *SystemTable
+  )
+{
+  EFI_STATUS             Status;
+  UINT8                  ErrorCount;
+  EFI_HANDLE             Handle;
+  UINT8                  Index;
+  EFI_STATUS_CODE_VALUE  StatusCodeValue[MAX_SOFT_COUNT];
+
+  ErrorCount = 0;
+  mImageHandle = ImageHandle;
+
+  mIpmiInstance = AllocateZeroPool (sizeof (*mIpmiInstance));
+  if (mIpmiInstance == NULL) {
+    DEBUG ((EFI_D_ERROR, "ERROR!! Null Pointer returned by AllocateZeroPool ()\n"));
+    ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+    return EFI_OUT_OF_RESOURCES;
+  } else {
+    //
+    // Calibrate TSC Counter.  Stall for 10ms, then multiply the resulting number of
+    // ticks in that period by 100 to get the number of ticks in a 1 second timeout
+    //
+
+    //
+    // Initialize the KCS transaction timeout.
+    //
+    mIpmiInstance->KcsTimeoutPeriod = (BMC_KCS_TIMEOUT * 1000*1000) / KCS_DELAY_UNIT;
+    DEBUG ((EFI_D_ERROR, "[IPMI] mIpmiInstance->KcsTimeoutPeriod: 0x%lx\n",mIpmiInstance->KcsTimeoutPeriod));
+
+    //
+    // Initialize IPMI IO Base.
+    //
+    mIpmiInstance->IpmiIoBase                       = PcdGet16 (PcdIpmiIoBaseAddress);
+    mIpmiInstance->Signature                        = SM_IPMI_BMC_SIGNATURE;
+    mIpmiInstance->SlaveAddress                     = BMC_SLAVE_ADDRESS;
+    mIpmiInstance->BmcStatus                        = BMC_NOTREADY;
+    mIpmiInstance->IpmiTransport.IpmiSubmitCommand  = IpmiSendCommand;
+    mIpmiInstance->IpmiTransport.GetBmcStatus       = IpmiGetBmcStatus;
+
+    //
+    // Get the Device ID and check if the system is in Force Update mode.
+    //
+    Status = GetDeviceId (
+               mIpmiInstance,
+               StatusCodeValue,
+               &ErrorCount
+               );
+    //
+    // Do not continue initialization if the BMC is in Force Update Mode.
+    //
+    if ((mIpmiInstance->BmcStatus != BMC_UPDATE_IN_PROGRESS) &&
+        (mIpmiInstance->BmcStatus != BMC_HARDFAIL)) {
+      //
+      // Get the SELF TEST Results.
+      //
+      Status = GetSelfTest (
+                 mIpmiInstance,
+                 StatusCodeValue,
+                 &ErrorCount
+                 );
+    }
+
+    //
+    // iterate through the errors reporting them to the error manager.
+    //
+    for (Index = 0; Index < ErrorCount; Index++) {
+      ReportStatusCode (
+        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+        StatusCodeValue[Index]
+        );
+    }
+
+    //
+    // Now install the Protocol if the BMC is not in a HardFail State and not in Force Update mode
+    //
+    if ((mIpmiInstance->BmcStatus != BMC_HARDFAIL) && (mIpmiInstance->BmcStatus != BMC_UPDATE_IN_PROGRESS)) {
+      Handle = NULL;
+      Status = gBS->InstallProtocolInterface (
+                      &Handle,
+                      &gIpmiTransportProtocolGuid,
+                      EFI_NATIVE_INTERFACE,
+                      &mIpmiInstance->IpmiTransport
+                      );
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    return EFI_SUCCESS;
+  }
+} // InitializeIpmiKcsPhysicalLayer()
+
-- 
2.27.0.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#72309): https://edk2.groups.io/g/devel/message/72309
Mute This Topic: https://groups.io/mt/81016651/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