alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/IhisiSmm/BiosGCI.c

650 lines
20 KiB
C

/** @file
This driver provides some functions for Smart Tool
;******************************************************************************
;* Copyright (c) 2014, 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 "BiosGCI.h"
//
// The following codes are the sample. Please customize here.
// The default codes are some dummy functions.
//
#if 0
EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *mBiosSmmFwBlockService;
EFI_SMM_VARIABLE_PROTOCOL *mBiosSmmVariable;
UINT32 mCommandNumber;
STATIC
EFI_STATUS
SmmVariableCallback (
IN CONST EFI_GUID *Protocol,
IN VOID *Interface,
IN EFI_HANDLE Handle
)
{
return gSmst->SmmLocateProtocol (
&gEfiSmmVariableProtocolGuid,
NULL,
(VOID **)&mBiosSmmVariable
);
}
EFI_STATUS
BiosGCIInit (
VOID
)
{
EFI_STATUS Status;
EFI_EVENT SmmVariableEvent;
Status = gSmst->SmmLocateProtocol (
&gEfiSmmFwBlockServiceProtocolGuid,
NULL,
(VOID **)&mBiosSmmFwBlockService
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gSmst->SmmLocateProtocol (
&gEfiSmmVariableProtocolGuid,
NULL,
(VOID **)&mBiosSmmVariable
);
//
// If not find gEfiSmmVariableProtocolGuid, Create a callback function to locate
// gEfiSmmVariableProtocolGuid when gEfiSmmVariableProtocolGuid is installed
//
if (EFI_ERROR (Status)) {
Status = gSmst->SmmRegisterProtocolNotify (
&gEfiSmmVariableProtocolGuid,
SmmVariableCallback,
&SmmVariableEvent
);
}
return Status;
}
/**
Implement IHISI SPEC. AH=60h, Data Access Communication.
@param None
**/
EFI_STATUS
DataAccessCommunication (
VOID
)
{
EFI_STATUS Status;
UINT32 IhisiStatus;
DATA_ACCESS_COMMUNICATION_INPUT *APCommunicationDataBuffer;
DATA_ACCESS_COMMUNICATION_OUTPUT *BIOSCommunicationDataBuffer;
EFI_GUID IdentificationGuid = DATA_ACCESS_COMM_GUID_FOR_IDENTIFICATION;
UINT32 ApSize;
UINT32 ApDataSize;
UINT8 *StartType;
Status = EFI_SUCCESS;
IhisiStatus = IhisiSuccess;
APCommunicationDataBuffer = NULL;
BIOSCommunicationDataBuffer = NULL;
//
// Pointer to ECX AP communication data buffer (Input buffer).
//
//APCommunicationDataBuffer = (DATA_ACCESS_COMMUNICATION_INPUT *)(UINTN) SmmCpuSaveLocalState->ECX;
APCommunicationDataBuffer = (DATA_ACCESS_COMMUNICATION_INPUT *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RCX);
//StartType = (UINT8 *)(UINTN) SmmCpuSaveLocalState->EDI;
StartType = (UINT8 *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RDI);
//
// Get and keep input parameters from input buffer.
//
ApSize = APCommunicationDataBuffer->Size;
mCommandNumber = APCommunicationDataBuffer->CommandNumber;
ApDataSize = APCommunicationDataBuffer->DataSize;
//
// Pointer to ECX BIOS communication data buffer (Output buffer).
//
//BIOSCommunicationDataBuffer = (DATA_ACCESS_COMMUNICATION_OUTPUT *)(UINTN) SmmCpuSaveLocalState->ECX;
BIOSCommunicationDataBuffer = (DATA_ACCESS_COMMUNICATION_OUTPUT *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RCX);
//
// Set output structure size.
//
BIOSCommunicationDataBuffer->Size = sizeof (DATA_ACCESS_COMMUNICATION_OUTPUT);
//
// Set data size default = 0 for event command.
//
BIOSCommunicationDataBuffer->DataSize = 0;
//
// Check platform GUID
//
if (!CompareGuid (&APCommunicationDataBuffer->GuidForIdentification, &IdentificationGuid)) {
BIOSCommunicationDataBuffer->StatusReturn.ErrorStatus = 0;
BIOSCommunicationDataBuffer->StatusReturn.General.GuidNotMatch = 1;
CopyMem (&BIOSCommunicationDataBuffer->GuidForIdentification, &IdentificationGuid, sizeof (EFI_GUID));
IhisiLibErrorCodeHandler (IhisiSuccess);
return EFI_NOT_FOUND;
}
//
// Note: The followings are the sample codes. You can customize your functions here.
// Ihisi60hForCreateUefiVariable(), Ihisi60hForEraseUefiVariable(), Ihisi60hForQueryUefiVariableStatus(),
// Ihisi60hForStartEvent() and Ihisi60hForFinishEvent() are the sample functions.
//
//
// Execute according to mUserDefCommandNum.
//
switch (mCommandNumber) {
case DATA_ACCSEE_COMM_NUM_CREATE_UEFI_VARIABLE:
BIOSCommunicationDataBuffer->StatusReturn.ErrorStatus = 0;
Status = Ihisi60hForCreateUefiVariable (&IhisiStatus);
if (EFI_ERROR (Status)) {
//
// Inform AP that create action fails.
//
BIOSCommunicationDataBuffer->StatusReturn.CreateUefiVariable.CreateVariableResult = DATA_ACCSEE_COMM_NUM_ERROR_RETURN_STATUS_FAIL;
BIOSCommunicationDataBuffer->StatusReturn.CreateUefiVariable.Reserved = 0;
}
break;
case DATA_ACCSEE_COMM_NUM_ERASE_UEFI_VARIABLE:
BIOSCommunicationDataBuffer->StatusReturn.ErrorStatus = 0;
Status = Ihisi60hForEraseUefiVariable (&IhisiStatus);
if (EFI_ERROR (Status)) {
//
// Inform AP that create action fails.
//
BIOSCommunicationDataBuffer->StatusReturn.EraseUefiVariable.EraseVariableResult = DATA_ACCSEE_COMM_NUM_ERROR_RETURN_STATUS_FAIL;
BIOSCommunicationDataBuffer->StatusReturn.EraseUefiVariable.Reserved = 0;
}
break;
case DATA_ACCSEE_COMM_NUM_QUERY_DATA_FROM_UEFI_VARIABLE:
BIOSCommunicationDataBuffer->StatusReturn.ErrorStatus = 0;
Status = Ihisi60hForQueryUefiVariableStatus (&IhisiStatus);
if (EFI_ERROR (Status)) {
//
// Inform AP that create action fails.
//
BIOSCommunicationDataBuffer->StatusReturn.QueryUefiVariableStatus.QueryVariableResult = DATA_ACCSEE_COMM_NUM_ERROR_RETURN_STATUS_FAIL;
BIOSCommunicationDataBuffer->StatusReturn.QueryUefiVariableStatus.Reserved = 0;
}
break;
case DATA_ACCSEE_COMM_NUM_READ_UEFI_VARIABLE_DATA:
BIOSCommunicationDataBuffer->StatusReturn.ErrorStatus = 0;
BIOSCommunicationDataBuffer->DataSize = UEFI_VARIABLE_SIZE;
break;
case DATA_ACCSEE_COMM_NUM_WRITE_UEFI_VARIABLE_DATA:
BIOSCommunicationDataBuffer->StatusReturn.ErrorStatus = 0;
//
// Check data size
//
if (ApDataSize != UEFI_VARIABLE_SIZE) {
BIOSCommunicationDataBuffer->StatusReturn.General.DataSizeNotAccept = 1;
BIOSCommunicationDataBuffer->DataSize = UEFI_VARIABLE_SIZE;
} else {
BIOSCommunicationDataBuffer->DataSize = ApDataSize;
}
break;
case DATA_ACCSEE_COMM_NUM_START_EVENT:
BIOSCommunicationDataBuffer->StatusReturn.ErrorStatus = 0;
Status = Ihisi60hForStartEvent (&IhisiStatus, *StartType);
if (EFI_ERROR (Status)) {
//
// Inform AP that create action fails.
//
}
break;
case DATA_ACCSEE_COMM_NUM_FINISH_EVENT:
BIOSCommunicationDataBuffer->StatusReturn.ErrorStatus = 0;
Status = Ihisi60hForFinishEvent (&IhisiStatus);
if (EFI_ERROR (Status)) {
//
// Inform AP that create action fails.
//
}
break;
default:
//
// Set ErrorReturn default to NotSupportDataType.
//
BIOSCommunicationDataBuffer->StatusReturn.General.CommandNotSupport = 1; // Not support this type.
break;
}
IhisiLibErrorCodeHandler (IhisiStatus);
return Status;
}
/**
Implement IHISI SPEC. AH=61h, Data Read.
@param None
**/
EFI_STATUS
DataRead (
VOID
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 IhisiStatus = IhisiSuccess;
UINT32 *BufferAddress = NULL;
DATA_INPUT *InDataBuffer = NULL;
DATA_OUTPUT *OutDataBuffer = NULL;
EFI_GUID UefiVariableGuid = UEFI_VARIABLE_GUID;
UINTN VariableSize = UEFI_VARIABLE_SIZE;
UINT8 VariableData[UEFI_VARIABLE_SIZE - 1] = {0};
UINT32 VariableOffset;
UINT32 Attribute;
//BufferAddress = (UINT32 *)(UINTN) SmmCpuSaveLocalState->ESI;
//InDataBuffer = (DATA_INPUT *)(UINTN) SmmCpuSaveLocalState->EDI;
BufferAddress = (UINT32 *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RSI);
InDataBuffer = (DATA_INPUT *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RDI);
VariableOffset = InDataBuffer->DataOffset;
//OutDataBuffer = (DATA_OUTPUT *)(UINTN) SmmCpuSaveLocalState->EDI;
OutDataBuffer = (DATA_OUTPUT *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RDI);
//
// Note: The followings are the sample codes. You can customize your codes here.
//
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
//
// Execute by mDataTypeOfOemExtraData got from 60h.
//
switch (mCommandNumber) {
case DATA_ACCSEE_COMM_NUM_CREATE_UEFI_VARIABLE:
case DATA_ACCSEE_COMM_NUM_ERASE_UEFI_VARIABLE:
case DATA_ACCSEE_COMM_NUM_QUERY_DATA_FROM_UEFI_VARIABLE:
break;
//
// Command number = 0x00000003 or 0x00000004
//
case DATA_ACCSEE_COMM_NUM_READ_UEFI_VARIABLE_DATA:
case DATA_ACCSEE_COMM_NUM_WRITE_UEFI_VARIABLE_DATA:
//Status = mSmst->SmmAllocatePool (
// EfiRuntimeServicesData,
// VariableSize,
// &InDataBuffer
// );
Status = gSmst->SmmAllocatePool (
EfiRuntimeServicesData,
VariableSize,
(VOID **)&InDataBuffer
);
if (Status != EFI_SUCCESS) {
IhisiLibErrorCodeHandler (IhisiObLenTooSmall);
return EFI_BUFFER_TOO_SMALL;
}
Status = mBiosSmmVariable->SmmGetVariable (
L"XFILE",
&UefiVariableGuid,
&Attribute,
&VariableSize,
&VariableData
);
if (!EFI_ERROR (Status)) {
if (VariableOffset < UEFI_VARIABLE_SIZE) {
CopyMem (
//(VOID *)(UINTN) SmmCpuSaveLocalState->ESI,
(VOID *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RSI),
&VariableData,
VariableSize
);
VariableOffset += UEFI_VARIABLE_OFFSET;
}
OutDataBuffer->Size = sizeof (DATA_OUTPUT);
OutDataBuffer->DataSize = (UINT32) VariableSize;
OutDataBuffer->DataOffset = VariableOffset;
} else {
return Status;
}
break;
default:
break;
}
IhisiLibErrorCodeHandler (IhisiStatus);
return EFI_SUCCESS;
}
/**
Implement IHISI SPEC. AH=62h, Data Write.
@param None
**/
EFI_STATUS
DataWrite (
VOID
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 IhisiStatus = IhisiSuccess;
UINT32 *BufferAddress = NULL;
DATA_INPUT *InDataBuffer = NULL;
DATA_OUTPUT *OutDataBuffer = NULL;
EFI_GUID UefiVariableGuid = UEFI_VARIABLE_GUID;
UINTN VariableSize = UEFI_VARIABLE_SIZE;
UINT32 VariableOffset;
UINT32 Attribute;
//BufferAddress = (UINT32 *)(UINTN) SmmCpuSaveLocalState->ESI;
//InDataBuffer = (DATA_INPUT *)(UINTN) SmmCpuSaveLocalState->EDI;
BufferAddress = (UINT32 *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RSI);
InDataBuffer = (DATA_INPUT *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RDI);
VariableOffset = InDataBuffer->DataOffset;
//
// Note: The followings are the sample codes. You can customize your codes here.
//
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
//
// Execute by mUserDefCommandNum got from 60h.
//
switch (mCommandNumber) {
case DATA_ACCSEE_COMM_NUM_CREATE_UEFI_VARIABLE:
case DATA_ACCSEE_COMM_NUM_ERASE_UEFI_VARIABLE:
case DATA_ACCSEE_COMM_NUM_QUERY_DATA_FROM_UEFI_VARIABLE:
break;
//
// Command number = 0x00000003 or 0x00000004
//
case DATA_ACCSEE_COMM_NUM_READ_UEFI_VARIABLE_DATA:
case DATA_ACCSEE_COMM_NUM_WRITE_UEFI_VARIABLE_DATA:
//Status = mSmst->SmmAllocatePool (
Status = gSmst->SmmAllocatePool (
EfiRuntimeServicesData,
VariableSize,
(VOID **)&InDataBuffer
);
Status = mBiosSmmVariable->SmmSetVariable (
L"XFILE",
&UefiVariableGuid,
Attribute,
VariableSize,
BufferAddress
);
if (!EFI_ERROR (Status)) {
if (VariableOffset < UEFI_VARIABLE_SIZE) {
CopyMem (
BufferAddress,
//(VOID *)(UINTN) SmmCpuSaveLocalState->ESI,
(VOID *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RSI),
VariableSize
);
VariableOffset += UEFI_VARIABLE_OFFSET;
}
//OutDataBuffer = (DATA_OUTPUT *)(UINTN) SmmCpuSaveLocalState->EDI;
OutDataBuffer = (DATA_OUTPUT *)(UINTN) IhisiLibGetDwordRegister (EFI_SMM_SAVE_STATE_REGISTER_RDI);
OutDataBuffer->DataSize = (UINT32) VariableSize;
OutDataBuffer->DataOffset = VariableOffset;
} else {
return Status;
}
break;
default:
break;
}
IhisiLibErrorCodeHandler (IhisiStatus);
return EFI_SUCCESS;
}
EFI_STATUS
Ihisi60hForCreateUefiVariable (
IN OUT UINT32 *IhisiStatus
)
{
EFI_STATUS Status;
EFI_GUID UefiVariableGuid = UEFI_VARIABLE_GUID;
UINTN VariableSize = UEFI_VARIABLE_SIZE;
UINT8 VariableData[UEFI_VARIABLE_SIZE - 1] = {0};
UINT32 Attribute;
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
Status = mBiosSmmVariable->SmmGetVariable (
L"XFILE",
&UefiVariableGuid,
&Attribute,
&VariableSize,
&VariableData
);
if (EFI_ERROR (Status)) {
Status = mBiosSmmVariable->SmmSetVariable (
L"XFILE",
&UefiVariableGuid,
Attribute,
VariableSize,
&VariableData
);
} else {
Status = EFI_ABORTED;
}
return Status;
}
EFI_STATUS
Ihisi60hForEraseUefiVariable (
IN OUT UINT32 *IhisiStatus
)
{
EFI_STATUS Status;
EFI_GUID UefiVariableGuid = UEFI_VARIABLE_GUID;
UINT32 VariableData[UEFI_VARIABLE_SIZE - 1] = {0};
UINT32 Attribute;
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
Status = mBiosSmmVariable->SmmSetVariable (
L"XFILE",
&UefiVariableGuid,
Attribute,
0,
&VariableData
);
return Status;
}
EFI_STATUS
Ihisi60hForQueryUefiVariableStatus (
IN OUT UINT32 *IhisiStatus
)
{
EFI_STATUS Status;
EFI_GUID UefiVariableGuid = UEFI_VARIABLE_GUID;
UINTN VariableSize = UEFI_VARIABLE_SIZE;
UINT8 VariableData[UEFI_VARIABLE_SIZE - 1] = {0};
UINT32 Attribute;
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
Status = mBiosSmmVariable->SmmGetVariable (
L"XFILE",
&UefiVariableGuid,
&Attribute,
&VariableSize,
&VariableData
);
return Status;
}
EFI_STATUS
Ihisi60hForStartEvent (
IN OUT UINT32 *IhisiStatus,
IN UINT8 StartType
)
{
EFI_STATUS Status;
EFI_GUID TestGuid1 = TEST_GUID1;
EFI_GUID TestGuid2 = TEST_GUID2;
EFI_GUID TestGuid3 = TEST_GUID3;
UINTN VariableSize = UEFI_VARIABLE_SIZE;
UINT8 VariableData[UEFI_VARIABLE_SIZE - 1] = {0};
UINT32 Attribute;
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
switch (StartType) {
case DATA_ACCSEE_COMM_NUM_START_EVENT_WINDOWS:
Status = mBiosSmmVariable->SmmSetVariable (
L"WINDOWS",
&TestGuid1,
Attribute,
VariableSize,
&VariableData
);
break;
case DATA_ACCSEE_COMM_NUM_START_EVENT_DOS:
Status = mBiosSmmVariable->SmmSetVariable (
L"DOS",
&TestGuid2,
Attribute,
VariableSize,
&VariableData
);
break;
case DATA_ACCSEE_COMM_NUM_START_EVENT_EFI:
Status = mBiosSmmVariable->SmmSetVariable (
L"EFI",
&TestGuid3,
Attribute,
VariableSize,
&VariableData
);
break;
default:
Status = EFI_ABORTED;
break;
}
return Status;
}
EFI_STATUS
Ihisi60hForFinishEvent (
IN OUT UINT32 *IhisiStatus
)
{
EFI_STATUS Status;
EFI_GUID TestGuid4 = TEST_GUID4;
UINTN VariableSize = UEFI_VARIABLE_SIZE;
UINT8 VariableData[UEFI_VARIABLE_SIZE - 1] = {0};
UINT32 Attribute;
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
Status = mBiosSmmVariable->SmmGetVariable (
L"FINISH",
&TestGuid4,
&Attribute,
&VariableSize,
&VariableData
);
if (EFI_ERROR (Status)) {
Status = mBiosSmmVariable->SmmSetVariable (
L"FINISH",
&TestGuid4,
Attribute,
VariableSize,
&VariableData
);
} else {
Status = EFI_ABORTED;
}
return Status;
}
#else
EFI_STATUS
BiosGCIInit (
VOID
)
{
return EFI_SUCCESS;
}
EFI_STATUS
DataAccessCommunication (
VOID
)
{
return EFI_SUCCESS;
}
EFI_STATUS
DataRead (
VOID
)
{
return EFI_SUCCESS;
}
EFI_STATUS
DataWrite (
VOID
)
{
return EFI_SUCCESS;
}
#endif