blob: e3b080c6b80403e8359a76c7341aed86afe07033 [file]
/** @file
IPMI Command - NetFnApp.
Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/IpmiLib.h>
#include <IndustryStandard/Ipmi.h>
/**
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;
}