777 lines
23 KiB
C
777 lines
23 KiB
C
/** @file
|
|
Platform Level Data Model implementation
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2020, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "Pldm.h"
|
|
#include <Library/BdsCpLib.h>
|
|
#include <Guid/H2OBdsCheckPoint.h>
|
|
|
|
PLDM_CONTEXT mPldmContext;
|
|
|
|
VOID
|
|
EFIAPI
|
|
PushManagementDataToMC(
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
);
|
|
|
|
VOID
|
|
EFIAPI
|
|
SyncBootOrderDataWhenBootOrderHookEnable (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
);
|
|
|
|
VOID
|
|
EFIAPI
|
|
SetPldmResponseMode(
|
|
EFI_PLDM_PROTOCOL *This
|
|
)
|
|
{
|
|
PLDM_CONTEXT *Context;
|
|
|
|
Context = PLDM_CONTEXT_FROM_THIS(This);
|
|
Context->Mctp->SetResponseMode(Context->Mctp);
|
|
Context->ResponseMode = TRUE;
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
SetPldmRequestMode(
|
|
EFI_PLDM_PROTOCOL *This
|
|
)
|
|
{
|
|
PLDM_CONTEXT *Context;
|
|
|
|
Context = PLDM_CONTEXT_FROM_THIS(This);
|
|
Context->Mctp->SetRequestMode(Context->Mctp);
|
|
Context->ResponseMode = FALSE;
|
|
}
|
|
|
|
|
|
/**
|
|
Set binding MCTP protcol
|
|
|
|
@param [in] This Point to EFI_PLDM_PROTOCOL
|
|
@param [in] Mctp Binding MCTP protocol
|
|
|
|
@retval EFI_SUCCESS Successful
|
|
@retval EFI_INVALID_PARAMETER Invalid parameter error
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PldmSetMctpBinding (
|
|
IN EFI_PLDM_PROTOCOL *This,
|
|
IN EFI_MCTP_PROTOCOL *Mctp
|
|
)
|
|
{
|
|
PLDM_CONTEXT *PldmContext;
|
|
|
|
if (Mctp == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PldmContext = PLDM_CONTEXT_FROM_THIS (This);
|
|
PldmContext->Mctp = Mctp;
|
|
|
|
return EFI_SUCCESS;
|
|
/**
|
|
Set Data Transfer Handle and Data Transfer Flag for the transfer header of a PLDM request message
|
|
|
|
@param [out] RequestMessage The PLDM request message
|
|
@param [in] TransferHandle The Transfer Handle
|
|
@param [in] Flag The Transfer Flag
|
|
|
|
@retval none
|
|
|
|
**/
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
PldmSetDataTransferHandle (
|
|
OUT VOID *RequestMessage,
|
|
IN UINT32 TransferHandle,
|
|
IN UINT8 Flag
|
|
)
|
|
{
|
|
((UINT32 *)RequestMessage)[0] = TransferHandle;
|
|
((UINT8 *)RequestMessage)[4] = Flag;
|
|
}
|
|
|
|
/**
|
|
Retrieve Data Transfer Handle and Data Transfer Flag from PLDM response data
|
|
|
|
@param [in] ResponseMessage The PLDM response message
|
|
@param [out] TransferHandle The Transfer Handle
|
|
@param [out] Flag The Transfer Flag
|
|
|
|
@retval none
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
PldmGetNextDataTransferHandle (
|
|
IN VOID *ResponseMessage,
|
|
OUT UINT32 *TransferHandle,
|
|
OUT UINT8 *Flag
|
|
)
|
|
{
|
|
*TransferHandle = ((UINT32 *)(UINT8 *)ResponseMessage)[0];
|
|
if (Flag != NULL) {
|
|
*Flag = ((UINT8 *)ResponseMessage)[4];
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
Process a complete PLDM request and response transaction with single request and single response
|
|
|
|
@param [in] This
|
|
@param [in] PldmType 00: PLDM Base, 01: SMBIOS, 02: Monitoring & Control, 03: BIOS Control & Configuration
|
|
@param [in] Command The PLDM command according to the PLDM Type
|
|
@param [in] RequestMessage PLDM Request Message with PLDM header excluded
|
|
@param [in] RequestMessageSize Number of bytes for RequestMessage
|
|
@param [in] ResponseMessage PLDM Response Message with PLDM header excluded
|
|
@param [in, out] ResponseMessageSize Number of bytes for ResponseMessage
|
|
|
|
@retval EFI_SUCCESS Successful
|
|
@return Other values Unsuccessful
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ProcessSimplePldmMessage (
|
|
IN EFI_PLDM_PROTOCOL *This,
|
|
IN UINT8 PldmType,
|
|
IN UINT8 Command,
|
|
IN VOID *RequestMessage,
|
|
IN UINTN RequestMessageSize,
|
|
IN VOID *ResponseMessage,
|
|
IN OUT UINTN *ResponseMessageSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PLDM_HEADER Header = PLDM_HEADER_COMMON;
|
|
PLDM_CONTEXT *PldmContext;
|
|
|
|
PldmContext = PLDM_CONTEXT_FROM_THIS (This);
|
|
|
|
This->SetRequestMode(This);
|
|
PldmContext->TransactionInProgress = TRUE;
|
|
|
|
Header.PldmType = PldmType;
|
|
Header.PldmCmdCode = Command;
|
|
|
|
PldmContext->InstanceId = (PldmContext->InstanceId + 1) % 32;
|
|
Header.InstanceId = PldmContext->InstanceId;
|
|
|
|
Status = This->SendMessage(This, Header, RequestMessage,RequestMessageSize);
|
|
|
|
if (Status == EFI_SUCCESS) {
|
|
Status = This->ReceiveMessage (This, &Header, ResponseMessage, ResponseMessageSize);
|
|
}
|
|
PldmContext->TransactionInProgress = FALSE;;
|
|
|
|
|
|
return Status;
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
Process a complete PLDM request and response transaction with multiple requests for large request data transfer
|
|
|
|
@param [in] This
|
|
@param [in] PldmType 00: PLDM Base, 01: SMBIOS, 02: Monitoring & Control, 03: BIOS Control & Configuration
|
|
@param [in] Command The PLDM command according to the PLDM Type
|
|
@param [in] TransferHeader The Request Transfer Header according to the PLDM command
|
|
@param [in] TransferHeaderSize Number of bytes for TransferHeader
|
|
@param [in] RequestMessage PLDM Request Message with PLDM header and Transfer Header excluded
|
|
@param [in] RequestMessageSize Number of bytes for RequestMessage
|
|
|
|
@retval EFI_SUCCESS Successful
|
|
@return Other values Unsuccessful
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ProcessPldmMessageWithSplitRequests (
|
|
IN EFI_PLDM_PROTOCOL *This,
|
|
IN UINT8 PldmType,
|
|
IN UINT8 Command,
|
|
IN VOID *TransferHeader,
|
|
IN UINTN TransferHeaderSize,
|
|
IN VOID *RequestMessage,
|
|
IN UINTN RequestMessageSize
|
|
)
|
|
{
|
|
|
|
UINT8 Payload[MAX_PLDM_PAYLOAD_SIZE];
|
|
UINT8 TransferFlag;
|
|
UINT32 TransferHandle;
|
|
UINTN TransferIndex;
|
|
UINTN PayloadSize;
|
|
UINTN MsgSize;
|
|
UINTN RemainingBytes;
|
|
PLDM_HEADER RequestHeader = PLDM_HEADER_COMMON;
|
|
PLDM_HEADER ResponseHeader;
|
|
PLDM_CONTEXT *PldmContext;
|
|
EFI_STATUS Status;
|
|
UINT32 Crc32;
|
|
|
|
PldmContext = PLDM_CONTEXT_FROM_THIS(This);
|
|
This->SetRequestMode(This);
|
|
PldmContext->TransactionInProgress = TRUE;
|
|
|
|
RequestHeader.PldmType = PldmType;
|
|
RequestHeader.PldmCmdCode = Command;
|
|
|
|
Status = EFI_SUCCESS;
|
|
TransferHandle = 0x10;
|
|
TransferIndex = 0;
|
|
Crc32 = 0;
|
|
gBS->CalculateCrc32(RequestMessage, RequestMessageSize, &Crc32);
|
|
|
|
do {
|
|
|
|
PldmContext->InstanceId = (PldmContext->InstanceId + 1) % 32;
|
|
RequestHeader.InstanceId = PldmContext->InstanceId;
|
|
|
|
//
|
|
// Add additinal 4 CRC32 bytes
|
|
//
|
|
RemainingBytes = RequestMessageSize - TransferIndex + 4;
|
|
|
|
if (RemainingBytes + TransferHeaderSize > PldmContext->MaxPayloadSize) {
|
|
if (RemainingBytes + TransferHeaderSize - 4 >= PldmContext->MaxPayloadSize) {
|
|
PayloadSize = PldmContext->MaxPayloadSize;
|
|
} else {
|
|
//
|
|
// CRC bytes will be sent in the next transfer loop
|
|
//
|
|
PayloadSize = RemainingBytes + TransferHeaderSize - 4;
|
|
}
|
|
MsgSize = PayloadSize - TransferHeaderSize;
|
|
if (TransferIndex == 0) {
|
|
TransferFlag = PldmTransferStart;
|
|
} else {
|
|
TransferFlag = PldmTransferMiddle;
|
|
}
|
|
} else {
|
|
PayloadSize = RemainingBytes + TransferHeaderSize;
|
|
MsgSize = RemainingBytes - 4;
|
|
if (TransferIndex == 0) {
|
|
TransferFlag = PldmTransferStartAndEnd;
|
|
} else {
|
|
TransferFlag = PldmTransferEnd;
|
|
}
|
|
}
|
|
|
|
PldmSetDataTransferHandle (TransferHeader, TransferHandle, TransferFlag);
|
|
gBS->CopyMem (Payload, TransferHeader, TransferHeaderSize);
|
|
gBS->CopyMem (Payload + TransferHeaderSize, (UINT8 *)RequestMessage + TransferIndex, MsgSize);
|
|
if ((TransferFlag & PldmTransferEnd) == PldmTransferEnd) {
|
|
gBS->CopyMem (Payload + PayloadSize - 4, &Crc32, 4);
|
|
}
|
|
|
|
|
|
Status = This->SendMessage (This, RequestHeader, Payload, PayloadSize );
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
TransferIndex += PayloadSize - TransferHeaderSize;
|
|
|
|
|
|
|
|
PayloadSize = PldmContext->MaxPayloadSize;
|
|
Status = This->ReceiveMessage (This, &ResponseHeader, Payload, &PayloadSize);
|
|
if (EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
|
|
PldmGetNextDataTransferHandle(Payload, &TransferHandle, NULL);
|
|
|
|
}while ((TransferFlag & PldmTransferEnd)!= PldmTransferEnd);
|
|
PldmContext->TransactionInProgress = FALSE;;
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Process a complete PLDM request and response transaction with multiple responses for large response data transfer
|
|
|
|
@param [in] This
|
|
@param [in] PldmType 00: PLDM Base, 01: SMBIOS, 02: Monitoring & Control, 03: BIOS Control & Configuration
|
|
@param [in] Command The PLDM command according to the PLDM Type
|
|
@param [in] TransferHeader The Request Transfer Header according to the PLDM command
|
|
@param [in] TransferHeaderSize Number of bytes for TransferHeader
|
|
@param [out] ResponseMessage PLDM Response Message with PLDM header and Transfer Header excluded
|
|
@param [in, out] ResponseMessageSize Number of bytes for ResponseMessage
|
|
|
|
@retval EFI_SUCCESS Successful
|
|
@return Other values Unsuccessful
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ProcessPldmMessageWithSplitResponses (
|
|
IN EFI_PLDM_PROTOCOL *This,
|
|
IN UINT8 PldmType,
|
|
IN UINT8 Command,
|
|
IN VOID *TransferHeader,
|
|
IN UINTN TransferHeaderSize,
|
|
OUT VOID *ResponseMessage,
|
|
IN OUT UINTN *ResponseMessageSize
|
|
)
|
|
{
|
|
|
|
UINT8 Payload[MAX_PLDM_PAYLOAD_SIZE];
|
|
UINT8 TransferOperationFlag;
|
|
UINT8 TransferFlag;
|
|
UINT32 TransferHandle;
|
|
UINTN TransferIndex;
|
|
UINTN PayloadSize;
|
|
UINTN MsgSize;
|
|
PLDM_HEADER RequestHeader = PLDM_HEADER_COMMON;
|
|
PLDM_HEADER ResponseHeader;
|
|
PLDM_CONTEXT *PldmContext;
|
|
EFI_STATUS Status;
|
|
UINT32 Crc32;
|
|
|
|
|
|
PldmContext = PLDM_CONTEXT_FROM_THIS(This);
|
|
This->SetRequestMode(This);
|
|
PldmContext->TransactionInProgress = TRUE;
|
|
|
|
RequestHeader.PldmType = PldmType;
|
|
RequestHeader.PldmCmdCode = Command;
|
|
|
|
TransferHandle = 0x10;
|
|
TransferOperationFlag = PldmGetFirstPart;
|
|
TransferIndex = 0;
|
|
Status = EFI_SUCCESS;
|
|
do {
|
|
|
|
PldmContext->InstanceId = (PldmContext->InstanceId + 1) % 32;
|
|
RequestHeader.InstanceId = PldmContext->InstanceId;
|
|
|
|
PldmSetDataTransferHandle (TransferHeader, TransferHandle, TransferOperationFlag);
|
|
gBS->CopyMem (Payload , TransferHeader, TransferHeaderSize);
|
|
PayloadSize = TransferHeaderSize;
|
|
Status = This->SendMessage (This, RequestHeader, Payload, PayloadSize);
|
|
if (EFI_ERROR(Status)) {
|
|
break;
|
|
}
|
|
|
|
|
|
PayloadSize = PldmContext->MaxPayloadSize;
|
|
Status = This->ReceiveMessage (This, &ResponseHeader, Payload, &PayloadSize);
|
|
if (EFI_ERROR(Status)) {
|
|
break;
|
|
}
|
|
|
|
PldmGetNextDataTransferHandle(Payload, &TransferHandle, &TransferFlag);
|
|
if ((TransferFlag & 0xF8) !=0x00) {
|
|
Status = EFI_PROTOCOL_ERROR;
|
|
break;
|
|
}
|
|
|
|
if ((TransferFlag & PldmTransferEnd) == PldmTransferEnd) {
|
|
MsgSize = PayloadSize - (RESPONSE_TRANSFER_HEADER_SIZE + 4);
|
|
} else {
|
|
MsgSize = PayloadSize - RESPONSE_TRANSFER_HEADER_SIZE;
|
|
}
|
|
|
|
gBS->CopyMem ((UINT8 *)ResponseMessage + TransferIndex, Payload + RESPONSE_TRANSFER_HEADER_SIZE, MsgSize);
|
|
|
|
TransferIndex += MsgSize;
|
|
TransferOperationFlag = PldmGetNextPart;
|
|
|
|
}while ((TransferFlag & PldmTransferEnd) != PldmTransferEnd);
|
|
|
|
if (Status == EFI_SUCCESS) {
|
|
|
|
*ResponseMessageSize = TransferIndex;
|
|
|
|
Crc32 = 0;
|
|
gBS->CalculateCrc32 (ResponseMessage, *ResponseMessageSize, &Crc32);
|
|
|
|
if ( *(UINT32 *)(Payload + PayloadSize - 4) != Crc32) {
|
|
Status = EFI_CRC_ERROR;
|
|
}
|
|
}
|
|
PldmContext->TransactionInProgress = FALSE;
|
|
|
|
return Status;
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
Send a single request message to the management controller
|
|
|
|
@param [in] This Pointer to EFI_PLDM_PROTOCOL
|
|
@param [in] Header The PLDM header
|
|
@param [in] Message The Request Message without PLDM header
|
|
@param [in] MessageSize
|
|
|
|
@retval EFI_SUCCESS Successful
|
|
@return Other values Unsuccessful
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PldmSendMessage (
|
|
IN EFI_PLDM_PROTOCOL *This,
|
|
IN PLDM_HEADER Header,
|
|
IN VOID *Message,
|
|
IN UINTN MessageSize
|
|
)
|
|
{
|
|
PLDM_CONTEXT *PldmContext;
|
|
EFI_STATUS Status;
|
|
UINT8 *MctpMsg;
|
|
|
|
|
|
PldmContext = PLDM_CONTEXT_FROM_THIS (This);
|
|
MctpMsg = PldmContext->Buffer;
|
|
|
|
if (PldmContext->ResponseMode) {
|
|
Header.RequestBit = 0;
|
|
}
|
|
gBS->CopyMem (MctpMsg, &Header, sizeof (PLDM_HEADER));
|
|
if ((MessageSize != 0) && (Message != NULL)) {
|
|
gBS->CopyMem (MctpMsg + sizeof (PLDM_HEADER), Message, MessageSize);
|
|
}
|
|
|
|
Status = PldmContext->Mctp->SendMessage (PldmContext->Mctp,
|
|
MctpMsg,
|
|
MessageSize + sizeof (PLDM_HEADER)
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Receive a single response message from the management controller
|
|
|
|
@param [in] This Pointer to EFI_PLDM_PROTOCOL
|
|
@param [out] Header The PLDM header
|
|
@param [out] Message The Response Message without PLDM header
|
|
@param [in, out] MessageSize
|
|
|
|
@retval EFI_SUCCESS Successful
|
|
@return Other values Unsuccessful
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PldmReceiveMessage (
|
|
IN EFI_PLDM_PROTOCOL *This,
|
|
OUT PLDM_HEADER *Header,
|
|
OUT VOID *Message,
|
|
IN OUT UINTN *MessageSize
|
|
)
|
|
{
|
|
PLDM_CONTEXT *PldmContext;
|
|
EFI_STATUS Status;
|
|
UINT8 *MctpMsg;
|
|
UINTN MctpMsgSize;
|
|
UINTN MsgOffset;
|
|
|
|
PldmContext = PLDM_CONTEXT_FROM_THIS (This);
|
|
MctpMsg = PldmContext->Buffer;
|
|
MctpMsgSize = *MessageSize + sizeof (PLDM_HEADER) + 1;
|
|
Status = PldmContext->Mctp->ReceiveMessage (PldmContext->Mctp,
|
|
MctpMsg,
|
|
&MctpMsgSize
|
|
);
|
|
|
|
if (Status == EFI_SUCCESS) {
|
|
if ((!PldmContext->ResponseMode) && (MctpMsg[sizeof(PLDM_HEADER)] != PLDM_SUCCESS)) {
|
|
return EFI_PLDM_COMPLETION_ERROR;
|
|
}
|
|
if (PldmContext->ResponseMode) {
|
|
MsgOffset = sizeof (PLDM_HEADER);
|
|
} else {
|
|
MsgOffset = sizeof (PLDM_HEADER) + 1;
|
|
}
|
|
|
|
gBS->CopyMem (Header, MctpMsg, sizeof (PLDM_HEADER));
|
|
*MessageSize = MctpMsgSize - MsgOffset;
|
|
gBS->CopyMem (Message, MctpMsg + MsgOffset, *MessageSize);
|
|
}
|
|
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
Get PLDM Target ID
|
|
|
|
@param [in] This Pointer to EFI_PLDM_PROTOCOL
|
|
@param [out] Tid The Target ID
|
|
|
|
@retval EFI_SUCCESS Command completed successfully
|
|
@return Other value Unknown error
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PldmGetTid (
|
|
IN EFI_PLDM_PROTOCOL *This,
|
|
OUT UINT8 *Tid
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Size;
|
|
|
|
Size = 1;
|
|
Status = ProcessSimplePldmMessage(This,
|
|
PLDM_TYPE_MESSAGE_CONTROL_AND_DISCOVERY,
|
|
PLDM_BASE_GET_TID,
|
|
NULL,
|
|
0,
|
|
Tid,
|
|
&Size
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Get PLDM supported versions
|
|
|
|
@param [in] This Pointer to EFI_PLDM_PROTOCOL
|
|
@param [in] PldmType
|
|
@param [out] VersionInfo The supported version information
|
|
@param [out] VersionInfoSize Number of bytes for VersionInfo
|
|
|
|
@retval EFI_SUCCESS Command completed successfully
|
|
@return Other value Unknown error
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetPldmVersion (
|
|
IN EFI_PLDM_PROTOCOL *This,
|
|
IN UINT8 PldmType,
|
|
OUT UINT32 *VersionInfo,
|
|
OUT UINTN *VersionInfoSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PLDM_GET_VERSION_REQUEST_DATA PldmRequest;
|
|
|
|
PldmRequest.DataTransferHandle = 0;
|
|
PldmRequest.TransferOperationFlag = PldmGetFirstPart;
|
|
PldmRequest.PldmType = PldmType;
|
|
Status = ProcessPldmMessageWithSplitResponses(This,
|
|
PLDM_TYPE_MESSAGE_CONTROL_AND_DISCOVERY,
|
|
PLDM_BASE_GET_PLDM_VERSION,
|
|
&PldmRequest,
|
|
sizeof (PldmRequest),
|
|
VersionInfo,
|
|
VersionInfoSize
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Get supported PLDM Types
|
|
|
|
@param This Pointer to EFI_PLDM_PROTOCOL
|
|
@param SupportedTypes Bit mask for the supported types,
|
|
if Bit No. N of the Mth Byte is set, then command M*8+N is supported
|
|
|
|
@retval EFI_SUCCESS Command completed successfully
|
|
@return Other value Unknown error
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetPldmSupportedTypes (
|
|
EFI_PLDM_PROTOCOL *This,
|
|
UINT8 *SupportedTypes
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ResponseSize;
|
|
|
|
ResponseSize = 8; //sizeof (PLDM_SUPPORTED_TYPES);
|
|
Status = ProcessSimplePldmMessage(This,
|
|
PLDM_TYPE_MESSAGE_CONTROL_AND_DISCOVERY,
|
|
PLDM_BASE_GET_PLDM_TYPES,
|
|
NULL,
|
|
0,
|
|
SupportedTypes,
|
|
&ResponseSize
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Get supported PLDM commands for a specified PLDM type
|
|
|
|
@param This Pointer to EFI_PLDM_PROTOCOL
|
|
@param PldmType 00: PLDM Base, 01: SMBIOS, 02: Monitoring & Control, 03: BIOS Control & Configuration
|
|
@param PldmTypeVersion Version for the PLDM type, it should be 0xF1F0F000
|
|
@param SupportedCommands
|
|
|
|
@retval EFI_SUCCESS Command completed successfully
|
|
@return Other value Unknown error
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetPldmSupportedCommands (
|
|
EFI_PLDM_PROTOCOL *This,
|
|
UINT8 PldmType,
|
|
UINT32 PldmTypeVersion,
|
|
UINT8 *SupportedCommands
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ResponseSize;
|
|
PLDM_GET_COMMANDS_REQUEST_DATA PldmRequest;
|
|
|
|
|
|
|
|
PldmRequest.PldmType = PldmType;
|
|
PldmRequest.Version = PldmTypeVersion;
|
|
ResponseSize = 32; //sizeof (PLDM_SUPPORTED_COMMANDS);
|
|
Status = ProcessSimplePldmMessage(This,
|
|
PLDM_TYPE_MESSAGE_CONTROL_AND_DISCOVERY,
|
|
PLDM_BASE_GET_PLDM_COMMANDS,
|
|
&PldmRequest,
|
|
sizeof (PLDM_GET_COMMANDS_REQUEST_DATA),
|
|
SupportedCommands,
|
|
&ResponseSize
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
EFI_PLDM_PROTOCOL initialization
|
|
|
|
@param PldmContext pointer to PLDM_CONTEXT structure
|
|
@param Mctp pointer to EFI_MCTP_PROTOCOL structure
|
|
|
|
@retval SUCCESS command complete successfully
|
|
@return other values command failed
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
EFIAPI
|
|
SetupPldmProtocol (
|
|
PLDM_CONTEXT *PldmContext,
|
|
EFI_MCTP_PROTOCOL *Mctp
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
H2O_CP_HANDLE CpHandle;
|
|
|
|
PldmContext->Signature = PLDM_SIGNATURE;
|
|
PldmContext->Mctp = Mctp;
|
|
PldmContext->InstanceId = 0;
|
|
PldmContext->MaxPayloadSize = MAX_PLDM_PAYLOAD_SIZE;
|
|
PldmContext->Pldm.SetRequestMode = SetPldmRequestMode;
|
|
PldmContext->Pldm.SetResponseMode = SetPldmResponseMode;
|
|
PldmContext->Pldm.SendMessage = PldmSendMessage;
|
|
PldmContext->Pldm.ReceiveMessage = PldmReceiveMessage;
|
|
PldmContext->Pldm.GetTid = PldmGetTid;
|
|
PldmContext->Pldm.GetVersion = GetPldmVersion;
|
|
PldmContext->Pldm.GetSupportedTypes = GetPldmSupportedTypes;
|
|
PldmContext->Pldm.GetSupportedCommands = GetPldmSupportedCommands;
|
|
PldmContext->Pldm.GetSmbiosStructureTableMetaData = PldmGetSmbiosStructureTableMetaData;
|
|
PldmContext->Pldm.SetSmbiosStructureTableMetaData = PldmSetSmbiosStructureTableMetaData;
|
|
PldmContext->Pldm.GetSmbiosStructureTable = PldmGetSmbiosStructureTable;
|
|
PldmContext->Pldm.SetSmbiosStructureTable = PldmSetSmbiosStructureTable;
|
|
PldmContext->Pldm.SetDateTime = PldmBiosSetDateTime;
|
|
PldmContext->Pldm.GetBiosTable = PldmGetBiosTable;
|
|
PldmContext->Pldm.SetBiosTable = PldmSetBiosTable;
|
|
PldmContext->Pldm.GetBiosTableTags = PldmGetBiosTableTags;
|
|
PldmContext->Pldm.SetBiosTableTags = PldmSetBiosTableTags;
|
|
PldmContext->Pldm.GetBiosAttrCurrentValueByHandle = PldmGetBiosAttrCurrentValueByHandle;
|
|
PldmContext->Pldm.GetBiosAttrCurrentValueByType = PldmGetBiosAttrCurrentValueByType;
|
|
PldmContext->Pldm.SetBiosAttrCurrentValue = PldmSetBiosAttrCurrentValue;
|
|
PldmContext->Pldm.GetBiosAttrPendingValueByHandle = PldmGetBiosAttrPendingValueByHandle;
|
|
PldmContext->Pldm.GetBiosAttrPendingValueByType = PldmGetBiosAttrPendingValueByType;
|
|
PldmContext->Pldm.AcceptBiosAttrPendingValues = PldmAcceptBiosAttrPendingValues;
|
|
PldmContext->Pldm.PlatformEventMessage = PldmPlatformEventMessage;
|
|
PldmContext->Pldm.AppendBiosString = AppendBiosString;
|
|
PldmContext->Pldm.AppendBiosAttr = AppendBiosAttr;
|
|
PldmContext->Pldm.AppendBiosAttrValue = AppendBiosAttrValue;
|
|
PldmContext->Pldm.ResetBiosTables = ResetBiosTables;
|
|
PldmContext->Pldm.PushBiosTables = PushBiosTables;
|
|
PldmContext->Pldm.RegisterSensorReadingFunction = RegisterSensorReadingFunction;
|
|
PldmContext->SensorReadingEvent = NULL;
|
|
PldmContext->SensorReadingCheckEvent = NULL;
|
|
|
|
PldmContext->Pldm.SetRequestMode(&PldmContext->Pldm);
|
|
|
|
PldmContext->Buffer = AllocatePool (PLDM_BUFFER_SIZE);
|
|
if (PldmContext->Buffer == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = InitBiosTables (PldmContext);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (PldmContext->Buffer);
|
|
return Status;
|
|
}
|
|
|
|
if (FeaturePcdGet (PcdH2OBdsCpBootDeviceEnumAfterSupported)) {
|
|
Status = H2OCpRegisterHandler (
|
|
&gH2OBdsCpBootDeviceEnumAfterGuid,
|
|
SyncBootOrderDataFromMC,
|
|
H2O_CP_MEDIUM,
|
|
&CpHandle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OBdsCpBootDeviceEnumAfterGuid, Status));
|
|
return Status;
|
|
}
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OBdsCpBootDeviceEnumAfterGuid, Status));
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, "PcdH2OBdsCpBootDeviceEnumAfterSupported is not set to true for boot order sync with MC!\n"));
|
|
ASSERT (FALSE);
|
|
}
|
|
|
|
if (FeaturePcdGet (PcdH2OBdsCpReadyToBootAfterSupported)) {
|
|
Status = H2OCpRegisterHandler (
|
|
&gH2OBdsCpReadyToBootAfterGuid,
|
|
PushManagementDataToMC,
|
|
H2O_CP_MEDIUM,
|
|
&CpHandle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OBdsCpReadyToBootAfterGuid, Status));
|
|
return Status;
|
|
}
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OBdsCpReadyToBootAfterGuid, Status));
|
|
}
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|