/** @file IPMI stack initialization. Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #define BMC_TIMEOUT 30 // [s] How long shall BIOS wait for BMC #define BMC_KCS_TIMEOUT 5 // [s] Single KSC request timeout EFI_STATUS GetSelfTest ( VOID ) /*++ Routine Description: Execute the Get Self Test results command to determine whether or not the BMC self tests have passed Arguments: mIpmiInstance - 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; IPMI_SELF_TEST_RESULT_RESPONSE TestResult; // // Get the SELF TEST Results. // Status = IpmiGetSelfTestResult (&TestResult); if (EFI_ERROR(Status)) { DEBUG((DEBUG_ERROR, "\n[IPMI] BMC does not respond (status: %r)!\n\n", Status)); return Status; } DEBUG((DEBUG_INFO, "[IPMI] BMC self-test result: %02X-%02X\n", TestResult.Result, TestResult.Param)); return EFI_SUCCESS; } EFI_STATUS GetDeviceId ( OUT BOOLEAN *UpdateMode ) /*++ 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: Returns: Status --*/ { EFI_STATUS Status; IPMI_GET_DEVICE_ID_RESPONSE BmcInfo; UINT32 Retries; // // Set up a loop to retry for up to 30 seconds. Calculate retries not timeout // so that in case KCS is not enabled and IpmiSendCommand() returns // immediately we will not wait all the 30 seconds. // Retries = BMC_TIMEOUT / BMC_KCS_TIMEOUT + 1; // // Get the device ID information for the BMC. // do { Status = IpmiGetDeviceId (&BmcInfo); if (!EFI_ERROR(Status)) { break; } DEBUG ((DEBUG_ERROR, "[IPMI] BMC does not respond (status: %r), %d retries left\n", Status, Retries)); MicroSecondDelay(50 * 1000); if (Retries-- == 0) { return Status; } } while (TRUE); DEBUG(( DEBUG_INFO, "[IPMI] BMC Device ID: 0x%02X, firmware version: %d.%02X\n", BmcInfo.DeviceId, BmcInfo.FirmwareRev1.Bits.MajorFirmwareRev, BmcInfo.MinorFirmwareRev )); *UpdateMode = (BOOLEAN)BmcInfo.FirmwareRev1.Bits.UpdateMode; return Status; } /** The entry point of the Ipmi DXE. @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 EFIAPI IpmiInterfaceInit ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { BOOLEAN UpdateMode; EFI_STATUS Status; DEBUG((DEBUG_ERROR,"IPMI Dxe:Get BMC Device Id\n")); // // Get the Device ID and check if the system is in Force Update mode. // Status = GetDeviceId (&UpdateMode); // // Do not continue initialization if the BMC is in Force Update Mode. // if (!EFI_ERROR(Status) && !UpdateMode) { // // Get the SELF TEST Results. // GetSelfTest (); } return EFI_SUCCESS; }