/** @file IPMI Command - NetFnApp. Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.
Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include /** This function is used to retrieve device ID. @param [out] DeviceId The pointer to receive IPMI_GET_DEVICE_ID_RESPONSE. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiGetDeviceId ( OUT IPMI_GET_DEVICE_ID_RESPONSE *DeviceId ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*DeviceId); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_DEVICE_ID, NULL, 0, (VOID *)DeviceId, &DataSize ); return Status; } /** This function returns device self test results @param [out] SelfTestResult The pointer to receive IPMI_SELF_TEST_RESULT_RESPONSE. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiGetSelfTestResult ( OUT IPMI_SELF_TEST_RESULT_RESPONSE *SelfTestResult ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*SelfTestResult); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_SELFTEST_RESULTS, NULL, 0, (VOID *)SelfTestResult, &DataSize ); return Status; } /** This function is used for starting and restarting the Watchdog Timer from the initial countdown value that was specified in the Set Watchdog Timer command the watchdog timer @param [out] CompletionCode IPMI completetion code, refer to Ipmi.h. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiResetWatchdogTimer ( OUT UINT8 *CompletionCode ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*CompletionCode); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_RESET_WATCHDOG_TIMER, NULL, 0, (VOID *)CompletionCode, &DataSize ); return Status; } /** This function is used for initializing and configuring the watchdog timer. @param [in] SetWatchdogTimer Pointer to receive IPMI_SET_WATCHDOG_TIMER_REQUEST. @param [out] CompletionCode IPMI completetion code, refer to Ipmi.h. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiSetWatchdogTimer ( IN IPMI_SET_WATCHDOG_TIMER_REQUEST *SetWatchdogTimer, OUT UINT8 *CompletionCode ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*CompletionCode); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_SET_WATCHDOG_TIMER, (VOID *)SetWatchdogTimer, sizeof (*SetWatchdogTimer), (VOID *)CompletionCode, &DataSize ); return Status; } /** This function retrieves the current settings and present countdown of the watchdog timer. @param [out] GetWatchdogTimer Pointer to receive IPMI_GET_WATCHDOG_TIMER_RESPONSE. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiGetWatchdogTimer ( OUT IPMI_GET_WATCHDOG_TIMER_RESPONSE *GetWatchdogTimer ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*GetWatchdogTimer); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_WATCHDOG_TIMER, NULL, 0, (VOID *)GetWatchdogTimer, &DataSize ); return Status; } /** This function enables message reception into Message Buffers, and any interrupt associated with that buffer getting full. @param [in] SetBmcGlobalEnables Pointer receive to IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST. @param [out] CompletionCode IPMI completetion code refer to Ipmi.h. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiSetBmcGlobalEnables ( IN IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST *SetBmcGlobalEnables, OUT UINT8 *CompletionCode ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*CompletionCode); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_SET_BMC_GLOBAL_ENABLES, (VOID *)SetBmcGlobalEnables, sizeof (*SetBmcGlobalEnables), (VOID *)CompletionCode, &DataSize ); return Status; } /** This function retrieves the present setting of the Global Enables @param [out] GetBmcGlobalEnables Pointer to receive IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiGetBmcGlobalEnables ( OUT IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE *GetBmcGlobalEnables ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*GetBmcGlobalEnables); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_BMC_GLOBAL_ENABLES, NULL, 0, (VOID *)GetBmcGlobalEnables, &DataSize ); return Status; } /** This function is used to flush unread data from the Receive Message Queue or Event Message Buffer @param [in] ClearMessageFlagsRequest IPMI_CLEAR_MESSAGE_FLAGS_REQUEST @param [out] CompletionCode IPMI completetion code, refer to Ipmi.h. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiClearMessageFlags ( IN IPMI_CLEAR_MESSAGE_FLAGS_REQUEST *ClearMessageFlagsRequest, OUT UINT8 *CompletionCode ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*CompletionCode); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_CLEAR_MESSAGE_FLAGS, (VOID *)ClearMessageFlagsRequest, sizeof (*ClearMessageFlagsRequest), (VOID *)CompletionCode, &DataSize ); return Status; } /** This function is used to retrieve the present message available states. @param [out] GetMessageFlagsResponse Pointer to receive IPMI_GET_MESSAGE_FLAGS_RESPONSE @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiGetMessageFlags ( OUT IPMI_GET_MESSAGE_FLAGS_RESPONSE *GetMessageFlagsResponse ) { EFI_STATUS Status; UINT32 DataSize; DataSize = sizeof (*GetMessageFlagsResponse); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_MESSAGE_FLAGS, NULL, 0, (VOID *)GetMessageFlagsResponse, &DataSize ); return Status; } /** This function is used to get data from the Receive Message Queue. @param [out] GetMessageResponse Pointer to receive IPMI_GET_MESSAGE_RESPONSE. @param [in, out] GetMessageResponseSize When in, which is the expected size of response. When out, which is the actual size returned. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiGetMessage ( OUT IPMI_GET_MESSAGE_RESPONSE *GetMessageResponse, IN OUT UINT32 *GetMessageResponseSize ) { EFI_STATUS Status; Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_MESSAGE, NULL, 0, (VOID *)GetMessageResponse, GetMessageResponseSize ); return Status; } /** This function is used for bridging IPMI messages between channels, and between the system management software (SMS) and a given channel @param [in] SendMessageRequest Pointer to IPMI_SEND_MESSAGE_REQUEST. @param [in] SendMessageRequestSize Size of entire SendMessageRequestSize. @param [out] SendMessageResponse Pointer to receive IPMI_SEND_MESSAGE_RESPONSE. @param [in, out] SendMessageResponseSize When in, which is the expected size of response. When out, which is the actual size returned. @retval EFI_STATUS See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiSendMessage ( IN IPMI_SEND_MESSAGE_REQUEST *SendMessageRequest, IN UINT32 SendMessageRequestSize, OUT IPMI_SEND_MESSAGE_RESPONSE *SendMessageResponse, IN OUT UINT32 *SendMessageResponseSize ) { EFI_STATUS Status; Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_SEND_MESSAGE, (VOID *)SendMessageRequest, SendMessageRequestSize, (VOID *)SendMessageResponse, SendMessageResponseSize ); return Status; } /** This function gets the system UUID. @param[out] SystemGuid The pointer to retrieve system UUID. @retval EFI_SUCCESS UUID is returned. @retval EFI_INVALID_PARAMETER SystemGuid is a NULL pointer. @retval Others See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiGetSystemUuid ( OUT EFI_GUID *SystemGuid ) { EFI_STATUS Status; UINT32 RequestSize; UINT32 ResponseSize; IPMI_GET_SYSTEM_UUID_RESPONSE GetSystemUuidResponse; if (SystemGuid == NULL) { return EFI_INVALID_PARAMETER; } RequestSize = 0; ResponseSize = sizeof (IPMI_GET_SYSTEM_UUID_RESPONSE); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_SYSTEM_GUID, (VOID *)NULL, RequestSize, (VOID *)&GetSystemUuidResponse, &ResponseSize ); if (!EFI_ERROR (Status) && (GetSystemUuidResponse.CompletionCode == IPMI_COMP_CODE_NORMAL)) { CopyMem ( (VOID *)SystemGuid, (VOID *)&GetSystemUuidResponse.SystemUuid, sizeof (EFI_GUID) ); } else { return EFI_DEVICE_ERROR; } return Status; } /** This function gets the channel information. @param[in] GetChannelInfoRequest The get channel information request. @param[out] GetChannelInfoResponse The get channel information response. @param[out] GetChannelInfoResponseSize When input, the expected size of response. When output, the exact size of the returned response. @retval EFI_SUCCESS Get channel information successfully. @retval EFI_INVALID_PARAMETER One of the given input parameters is invalid. @retval Others See the return values of IpmiSubmitCommand () function. **/ EFI_STATUS EFIAPI IpmiGetChannelInfo ( IN IPMI_GET_CHANNEL_INFO_REQUEST *GetChannelInfoRequest, OUT IPMI_GET_CHANNEL_INFO_RESPONSE *GetChannelInfoResponse, OUT UINT32 *GetChannelInfoResponseSize ) { EFI_STATUS Status; if ((GetChannelInfoRequest == NULL) || (GetChannelInfoResponse == NULL) || (GetChannelInfoResponseSize == NULL)) { return EFI_INVALID_PARAMETER; } *GetChannelInfoResponseSize = sizeof (IPMI_GET_CHANNEL_INFO_RESPONSE); Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_CHANNEL_INFO, (UINT8 *)GetChannelInfoRequest, sizeof (IPMI_GET_CHANNEL_INFO_REQUEST), (UINT8 *)GetChannelInfoResponse, GetChannelInfoResponseSize ); return Status; } /** This function gets system interface capability @param[in] InterfaceCapabilityRequest Get system interface capability request. @param[out] InterfaceCapabilityResponse The response of system interface capability. That is caller's responsibility to allocate memory for the response data. @retval EFI_SUCCESS Command is sent successfully. @retval Other Failure. **/ EFI_STATUS EFIAPI IpmiGetSystemInterfaceCapability ( IN IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_REQUEST *InterfaceCapabilityRequest, OUT IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_RESPONSE *InterfaceCapabilityResponse ) { UINT8 InterfaceType; UINT32 ResponseSize; UINT32 ActualResponseSize; UINT8 *ResponsePtr; EFI_STATUS Status; if (InterfaceCapabilityRequest == NULL) { return EFI_INVALID_PARAMETER; } InterfaceType = InterfaceCapabilityRequest->Bits.InterfaceType; if ((InterfaceType != IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_INTERFACE_TYPE_SSIF) && (InterfaceType != IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_INTERFACE_TYPE_KCS) && (InterfaceType != IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_INTERFACE_TYPE_SMIC)) { DEBUG ((DEBUG_ERROR, "%a: Unsupported given system interface type = 0x%x.\n", __func__, InterfaceType)); return EFI_INVALID_PARAMETER; } if (InterfaceType == IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_INTERFACE_TYPE_SSIF) { ResponseSize = sizeof (IPMI_GET_SYSTEM_INTERFACE_SSIF_CAPABILITIES_RESPONSE); ResponsePtr = (UINT8 *)InterfaceCapabilityResponse->InterfaceSsifCapability; } else { ResponseSize = sizeof (IPMI_GET_SYSTEM_INTERFACE_KCS_SMIC_CAPABILITIES_RESPONSE); ResponsePtr = (UINT8 *)InterfaceCapabilityResponse->InterfaceKcsSmicCapability; } ActualResponseSize = ResponseSize; Status = IpmiSubmitCommand ( IPMI_NETFN_APP, IPMI_APP_GET_SYSTEM_INTERFACE_CAPABILITIES, (UINT8 *)InterfaceCapabilityRequest, sizeof (IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_REQUEST), ResponsePtr, &ActualResponseSize ); if (ActualResponseSize != ResponseSize) { DEBUG (( DEBUG_ERROR, "%a: The expected response size 0x%x is not equal to the returned size 0x%x.\n", __func__, ResponseSize, ActualResponseSize )); } return Status; }