1295 lines
39 KiB
C
1295 lines
39 KiB
C
/** @file
|
|
This driver provides IHISI interface in SMM mode
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2014 - 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 "IhisiOemExtraDataCommunication.h"
|
|
#include <IndustryStandard/Oa3_0.h>
|
|
#include <Library/SmmChipsetSvcLib.h>
|
|
#include <Library/BaseOemSvcKernelLib.h>
|
|
#include <Library/SmmOemSvcKernelLib.h>
|
|
#include <Library/FlashRegionLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
|
|
STATIC UINT8 mOemExtraDataType;
|
|
STATIC UINTN mRomBaseAddress;
|
|
STATIC UINTN mRomSize;
|
|
STATIC BOOLEAN mEcIdle = FALSE;
|
|
AP_COMMUNICATION_DATA_TABLE mApCommDataBuffer;
|
|
|
|
STATIC
|
|
IHISI_REGISTER_TABLE
|
|
OEM_EXT_COMMON_REGISTER_TABLE[] = {
|
|
//
|
|
// AH=41h
|
|
//
|
|
{ OEMSFOEMExCommunication, "S41Kn_CommuSaveRegs", KernelCommunicationSaveRegs }, \
|
|
{ OEMSFOEMExCommunication, "S41Cs_ExtDataCommun", ChipsetOemExtraDataCommunication }, \
|
|
{ OEMSFOEMExCommunication, "S41OemT01Vbios00000", OemIhisiS41T1Vbios }, \
|
|
{ OEMSFOEMExCommunication, "S41OemT54LogoUpdate", OemIhisiS41T54LogoUpdate }, \
|
|
{ OEMSFOEMExCommunication, "S41OemT55CheckSignB", OemIhisiS41T55CheckBiosSignBySystemBios }, \
|
|
{ OEMSFOEMExCommunication, "S41OemReservedFun00", OemIhisiS41ReservedFunction }, \
|
|
{ OEMSFOEMExCommunication, "S41Kn_T51EcIdelTrue", KernelT51EcIdelTrue }, \
|
|
{ OEMSFOEMExCommunication, "S41Kn_ExtDataCommun", KernelOemExtraDataCommunication }, \
|
|
{ OEMSFOEMExCommunication, "S41Kn_T51EcIdelFals", KernelT51EcIdelFalse }, \
|
|
{ OEMSFOEMExCommunication, "S41OemT50Oa30RWFun0", OemIhisiS41T50a30ReadWrite }, \
|
|
|
|
//
|
|
// AH=42h
|
|
//
|
|
{ OEMSFOEMExDataWrite, "S42Cs_ExtDataWrite0", ChipsetOemExtraDataWrite, }, \
|
|
{ OEMSFOEMExDataWrite, "S42Kn_T50EcIdelTrue", KernelT50EcIdelTrue, }, \
|
|
{ OEMSFOEMExDataWrite, "S42Kn_ExtDataWrite0", KernelOemExtraDataWrite, }, \
|
|
{ OEMSFOEMExDataWrite, "S42Kn_T50EcIdelFals", KernelT50EcIdelFalse, }, \
|
|
{ OEMSFOEMExDataWrite, "S42Cs_DShutdownMode", ChipsetOemExtraDataDosShutdownMode}, \
|
|
|
|
//
|
|
// AH=47h
|
|
//
|
|
{ OEMSFOEMExDataRead, "S47Cs_ExtDataRead00", ChipsetOemExtraDataRead}, \
|
|
{ OEMSFOEMExDataRead, "S47Kn_ExtDataRead00", KernelOemExtraDataRead }
|
|
};
|
|
|
|
/**
|
|
Inernal function to check if the application data type is valid
|
|
|
|
@param[in] Datatype Application data type
|
|
|
|
@retval TRUE Application data type is valid.
|
|
@retval FALSE Application data type is invalid.
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
IsValidApDataType (
|
|
IN UINT8 Datatype
|
|
)
|
|
{
|
|
if (Datatype == Vbios || Datatype == Oa30ReadWrite ||
|
|
Datatype == Oa30Erase || Datatype == Oa30PopulateHeader ||
|
|
Datatype == Oa30DePopulateHeader || Datatype == LogoUpdate ||
|
|
Datatype == CheckBiosSignBySystemBios || Datatype == ClaenSecureKey ||
|
|
Datatype == FactoryKeyRestore || Datatype == PfatUpdate ||
|
|
Datatype == BiosPasswordErase || Datatype == PfatReturn ||
|
|
Datatype == StartTimeMeasure || Datatype == QueryTimeInterval ||
|
|
Datatype == GetSpiLockTable || Datatype == AccessViaSpi ||
|
|
Datatype == PassErrorLog || Datatype == RefereExtendDataType) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
STATIC
|
|
BOOLEAN
|
|
MsdmExist (
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN DataSize;
|
|
BOOLEAN MsdmExist;
|
|
UINTN RomBaseAddress;
|
|
EFI_ACPI_MSDM_DATA_STRUCTURE *MsdmData;
|
|
|
|
MsdmData = NULL;
|
|
MsdmExist = FALSE;
|
|
|
|
DataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE);
|
|
RomBaseAddress = (UINTN) FdmGetNAtAddr (&gH2OFlashMapRegionMsdmGuid, 1);
|
|
if (RomBaseAddress == 0) {
|
|
goto Done;
|
|
}
|
|
|
|
MsdmData = AllocatePool (DataSize);
|
|
if (MsdmData == NULL) {
|
|
goto Done;
|
|
}
|
|
Status = mSmmFwBlockService->Read (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
0,
|
|
&DataSize,
|
|
(UINT8*) MsdmData
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
goto Done;
|
|
}
|
|
|
|
if ((MsdmData->MsdmVersion == 0xFFFFFFFF) &&
|
|
(MsdmData->MdsmDataType == 0xFFFFFFFF) &&
|
|
(MsdmData->MsdmDataLength == 0xFFFFFFFF)) {
|
|
goto Done;
|
|
}
|
|
|
|
MsdmExist = TRUE;
|
|
|
|
Done:
|
|
if (MsdmData != NULL) {
|
|
FreePool (MsdmData);
|
|
}
|
|
return MsdmExist;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SetApandBiosCommDataBuffer (
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
|
|
if ((ApCommDataBuffer->Signature != AP_COMMUNICATION_SIGNATURE) && (ApCommDataBuffer->Signature != BIOS_COMMUNICATION_SIGNATURE)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (!IhisiProtBufferInCmdBuffer (ApCommDataBuffer, ApCommDataBuffer->StructureSize)){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
if (ApCommDataBuffer->Signature == BIOS_COMMUNICATION_SIGNATURE) {
|
|
CopyMem(BiosCommDataBuffer, (VOID *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX), sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
CopyMem(ApCommDataBuffer, &mApCommDataBuffer, sizeof (AP_COMMUNICATION_DATA_TABLE));
|
|
} else {
|
|
ZeroMem (BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
BiosCommDataBuffer->Signature = BIOS_COMMUNICATION_SIGNATURE;
|
|
BiosCommDataBuffer->StructureSize = sizeof (BIOS_COMMUNICATION_DATA_TABLE);
|
|
BiosCommDataBuffer->BlockSize = OemExtraBlockSize4k;
|
|
BiosCommDataBuffer->DataSize = OemExtraDataSize64k;
|
|
BiosCommDataBuffer->PhysicalDataSize = 0;
|
|
BiosCommDataBuffer->ErrorReturn = 0;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type.
|
|
|
|
50h = Oa30ReadWrite
|
|
|
|
@param[in] ApCommDataBuffer Pointer to AP communication data buffer.
|
|
@param[out] BiosCommDataBuffer Pointer to BIOS communication data buffer.
|
|
|
|
@retval EFI_SUCCESS Read or write OA3.0 successful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Oa30ReadWriteFunction (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
UINT32 MsdmDataSize;
|
|
|
|
MsdmDataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE);
|
|
switch (ApCommDataBuffer->DataSize) {
|
|
|
|
case OemExtraReportReadSize:
|
|
BiosCommDataBuffer->Signature = BIOS_COMMUNICATION_SIGNATURE;
|
|
BiosCommDataBuffer->StructureSize = sizeof (BIOS_COMMUNICATION_DATA_TABLE);
|
|
BiosCommDataBuffer->BlockSize = OemExtraBlockSize4k;
|
|
BiosCommDataBuffer->DataSize = OemExtraReportReadSize;
|
|
BiosCommDataBuffer->PhysicalDataSize = MsdmDataSize;
|
|
break;
|
|
|
|
case OemExtraSkipSizeCheck:
|
|
BiosCommDataBuffer->Signature = BIOS_COMMUNICATION_SIGNATURE;
|
|
BiosCommDataBuffer->StructureSize = sizeof (BIOS_COMMUNICATION_DATA_TABLE);
|
|
BiosCommDataBuffer->BlockSize = OemExtraBlockSize4k;
|
|
BiosCommDataBuffer->DataSize = OemExtraSkipSizeCheck; //Don't care
|
|
BiosCommDataBuffer->PhysicalDataSize = 0x00; //Don't care
|
|
break;
|
|
|
|
case OemExtraReportWriteSize:
|
|
BiosCommDataBuffer->Signature = BIOS_COMMUNICATION_SIGNATURE;
|
|
BiosCommDataBuffer->StructureSize = sizeof (BIOS_COMMUNICATION_DATA_TABLE);
|
|
BiosCommDataBuffer->BlockSize = OemExtraBlockSize4k;
|
|
BiosCommDataBuffer->DataSize = OemExtraReportWriteSize;
|
|
BiosCommDataBuffer->PhysicalDataSize = MsdmDataSize; //bin size
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!MsdmExist ()) {
|
|
BiosCommDataBuffer->ErrorReturn = (BiosCommDataBuffer->ErrorReturn | ERROR_RETURE_OA30_NOT_EXIST);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type.
|
|
51h = Oa30Erase Ec Idle true
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelT51EcIdelTrue (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS OemSvcStatus;
|
|
|
|
if (!IsValidApDataType (mOemExtraDataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
mEcIdle = FALSE;
|
|
if (MsdmExist () && mOemExtraDataType == Oa30Erase) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n"));
|
|
OemSvcStatus = OemSvcEcIdle (TRUE);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus));
|
|
mEcIdle = TRUE;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type.
|
|
51h = Oa30Erase Ec Idle False
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelT51EcIdelFalse (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS OemSvcStatus;
|
|
|
|
if (mEcIdle) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n"));
|
|
OemSvcStatus = OemSvcEcIdle (FALSE);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus));
|
|
mEcIdle = FALSE;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type.
|
|
|
|
51h = Oa30Erase
|
|
|
|
@param[in] ApCommDataBuffer Pointer to AP communication data buffer.
|
|
@param[out] BiosCommDataBuffer Pointer to BIOS communication data buffer.
|
|
|
|
@retval EFI_SUCCESS Erase OA3.0 successful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Oa30EraseFunction (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 LoopCount;
|
|
UINTN RomBaseAddress;
|
|
UINTN RomSize;
|
|
|
|
LoopCount = 0;
|
|
Status = EFI_SUCCESS;
|
|
|
|
RomBaseAddress = (UINTN) FdmGetNAtAddr (&gH2OFlashMapRegionMsdmGuid, 1);
|
|
if (RomBaseAddress == 0) {
|
|
BiosCommDataBuffer->ErrorReturn = (BiosCommDataBuffer->ErrorReturn | ERROR_RETURE_OA30_NOT_EXIST);
|
|
goto Done;
|
|
}
|
|
RomSize = (UINTN) FdmGetNAtSize (&gH2OFlashMapRegionMsdmGuid, 1);
|
|
|
|
|
|
if (!MsdmExist ()) {
|
|
BiosCommDataBuffer->ErrorReturn = (BiosCommDataBuffer->ErrorReturn | ERROR_RETURE_OA30_NOT_EXIST);
|
|
goto Done;
|
|
}
|
|
Status = EFI_UNSUPPORTED;
|
|
while ((EFI_ERROR (Status)) && (LoopCount < 100)) {
|
|
Status = mSmmFwBlockService->EraseBlocks (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
&RomSize
|
|
);
|
|
LoopCount++;
|
|
}
|
|
|
|
Done:
|
|
BiosCommDataBuffer->DataSize = ApCommDataBuffer->DataSize;
|
|
BiosCommDataBuffer->PhysicalDataSize = ApCommDataBuffer->PhysicalDataSize;
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type.
|
|
|
|
52h = Oa30PopulateHeader
|
|
|
|
@param[in] ApCommDataBuffer Pointer to AP communication data buffer.
|
|
@param[out] BiosCommDataBuffer Pointer to BIOS communication data buffer.
|
|
|
|
@retval EFI_SUCCESS populate header successful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Oa30PopulateHeaderFunction (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type 53h to de-populate header.
|
|
|
|
53h = Oa30DePopulateHeader
|
|
|
|
@param[in] ApCommDataBuffer Pointer to AP communication data buffer.
|
|
@param[out] BiosCommDataBuffer Pointer to BIOS communication data buffer.
|
|
|
|
@retval EFI_SUCCESS populate header successful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Oa30DePopulateHeaderFunction (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=42h, OEM Extra Data Write.
|
|
50h = Oa30ReadWrite Ec Idle true
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelT50EcIdelTrue (
|
|
VOID
|
|
)
|
|
{
|
|
UINTN WriteSize;
|
|
UINT32 MsdmDataSize;
|
|
EFI_STATUS OemSvcStatus;
|
|
|
|
WriteSize = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
MsdmDataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE);
|
|
mEcIdle = FALSE;
|
|
|
|
if ((WriteSize == MsdmDataSize) && (mOemExtraDataType == Oa30ReadWrite)) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n"));
|
|
OemSvcStatus = OemSvcEcIdle (TRUE);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus));
|
|
mEcIdle = TRUE;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=42h, OEM Extra Data Write.
|
|
50h = Oa30ReadWrite Ec Idle false
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelT50EcIdelFalse (
|
|
VOID
|
|
)
|
|
{
|
|
UINTN WriteSize;
|
|
UINT32 MsdmDataSize;
|
|
EFI_STATUS OemSvcStatus;
|
|
|
|
WriteSize = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
MsdmDataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE);
|
|
|
|
if (mEcIdle) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n"));
|
|
OemSvcStatus = OemSvcEcIdle (FALSE);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus));
|
|
mEcIdle = FALSE;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=42h, OEM Extra Data Write.
|
|
50h = Oa30ReadWrite
|
|
|
|
@retval EFI_SUCCESS Successfully returns.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Oa30DataWrite (
|
|
UINT8 *WriteDataBuffer,
|
|
UINTN WriteSize,
|
|
UINTN RomBaseAddress
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 LoopCount;
|
|
UINT32 MsdmDataSize;
|
|
|
|
MsdmDataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE);
|
|
|
|
if (WriteSize == MsdmDataSize) {
|
|
UINT8 *ReturnDataBuffer = NULL;
|
|
UINTN Index2 = 0;
|
|
UINTN EraseSize = 0x1000;
|
|
UINT8 *TEMP;
|
|
|
|
ReturnDataBuffer = AllocatePool (0x1000);
|
|
if (ReturnDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = mSmmFwBlockService->Read (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
0,
|
|
&EraseSize,
|
|
ReturnDataBuffer
|
|
);
|
|
//
|
|
// Only modify the first 0x31 bytes
|
|
//
|
|
TEMP = ReturnDataBuffer;
|
|
for (Index2 = 0; Index2 < MsdmDataSize; Index2++) {
|
|
TEMP[Index2] = WriteDataBuffer[Index2];
|
|
}
|
|
|
|
LoopCount = 0;
|
|
Status = EFI_UNSUPPORTED;
|
|
*(mSmmFwBlockService->FlashMode) = SMM_FW_FLASH_MODE;
|
|
|
|
while ((EFI_ERROR (Status)) && (LoopCount < 100)) {
|
|
Status = mSmmFwBlockService->EraseBlocks (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
&EraseSize
|
|
);
|
|
Status = mSmmFwBlockService->Write (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
&EraseSize,
|
|
ReturnDataBuffer
|
|
);
|
|
LoopCount++;
|
|
}
|
|
FreePool (ReturnDataBuffer);
|
|
} else {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=47h, OEM Extra Data Read.
|
|
|
|
50h = Oa30ReadWrite
|
|
|
|
@retval EFI_SUCCESS Successfully returns.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
Oa30DataRead (
|
|
UINT8 *ReadDataBuffer,
|
|
UINTN *ReadSize,
|
|
UINTN RomBaseAddress
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *ReturnDataBuffer = NULL;
|
|
UINTN DataSize = 0x1000;
|
|
|
|
ReturnDataBuffer = AllocatePool (DataSize);
|
|
if (ReturnDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = mSmmFwBlockService->Read (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
0,
|
|
&DataSize,
|
|
ReturnDataBuffer
|
|
);
|
|
|
|
*ReadSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE);
|
|
CopyMem (ReadDataBuffer, ReturnDataBuffer, *ReadSize);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type.
|
|
|
|
Hook chipset service SmmCsSvcIhisiOemExtCommunication.
|
|
|
|
@retval EFI_SUCCESS OEM Extra Data Write successful.
|
|
@return Other OEM Extra Data Write failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetOemExtraDataCommunication (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS OemSvcStatus;
|
|
BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer;
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer;
|
|
UINTN BufferSize;
|
|
|
|
ApCommDataBuffer = (AP_COMMUNICATION_DATA_TABLE*) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, sizeof(BIOS_COMMUNICATION_DATA_TABLE))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
BiosCommDataBuffer = AllocatePool (sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
if (BiosCommDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
BufferSize = ApCommDataBuffer->StructureSize;
|
|
if (BufferSize < sizeof(BIOS_COMMUNICATION_DATA_TABLE)) {
|
|
BufferSize = sizeof(BIOS_COMMUNICATION_DATA_TABLE);
|
|
}
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, BufferSize)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (!IsValidApDataType (ApCommDataBuffer->DataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = SetApandBiosCommDataBuffer(ApCommDataBuffer, BiosCommDataBuffer);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return Status;
|
|
}
|
|
|
|
OemSvcStatus = SmmCsSvcIhisiOemExtCommunication(ApCommDataBuffer, BiosCommDataBuffer);
|
|
Status = OemSvcStatus;
|
|
switch (OemSvcStatus) {
|
|
case EFI_SUCCESS:
|
|
Status = IHISI_END_FUNCTION_CHAIN;
|
|
break;
|
|
|
|
case EFI_UNSUPPORTED:
|
|
case EFI_MEDIA_CHANGED:
|
|
if ((ApCommDataBuffer->DataType == Oa30ReadWrite) ||
|
|
(ApCommDataBuffer->DataType == Oa30Erase) ||
|
|
(ApCommDataBuffer->DataType == Oa30PopulateHeader) ||
|
|
(ApCommDataBuffer->DataType == Oa30DePopulateHeader)) {
|
|
Status = IHISI_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
if (OemSvcStatus == EFI_MEDIA_CHANGED) {
|
|
CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
}
|
|
|
|
FreePool (BiosCommDataBuffer);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
/**
|
|
AH=42h, OEM Extra Data Write.
|
|
|
|
Hook chipset service SmmCsSvcIhisiOemExtDataWrite.
|
|
|
|
@retval EFI_SUCCESS OEM Extra Data Write successful.
|
|
@return Other OEM Extra Data Write failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetOemExtraDataWrite (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN WriteSize;
|
|
UINT8 ShutdownMode;
|
|
UINTN RomBaseAddress;
|
|
UINT8 *WriteDataBuffer;
|
|
UINT32 Ecx;
|
|
|
|
WriteDataBuffer = (UINT8 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
WriteSize = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
RomBaseAddress = (UINTN) (IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX) >> 8);
|
|
ShutdownMode = (UINT8) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) WriteDataBuffer, WriteSize)){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
Status = SmmCsSvcIhisiOemExtDataWrite(mOemExtraDataType, WriteDataBuffer, &WriteSize, &RomBaseAddress, ShutdownMode);
|
|
switch (Status) {
|
|
case EFI_SUCCESS:
|
|
Status = IHISI_END_FUNCTION_CHAIN;
|
|
break;
|
|
|
|
case EFI_UNSUPPORTED:
|
|
if (mOemExtraDataType == Oa30ReadWrite) {
|
|
mRomBaseAddress = (UINTN) FdmGetNAtAddr (&gH2OFlashMapRegionMsdmGuid, 1);
|
|
mRomSize = (UINTN) FdmGetNAtSize (&gH2OFlashMapRegionMsdmGuid, 1);
|
|
}
|
|
case EFI_MEDIA_CHANGED:
|
|
IhisiProtWriteCpuReg32(EFI_SMM_SAVE_STATE_REGISTER_RDI, (UINT32)WriteSize);
|
|
Ecx = IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
Ecx &=0xFFFF00FF;
|
|
Ecx |= (RomBaseAddress << 8);
|
|
IhisiProtWriteCpuReg32(EFI_SMM_SAVE_STATE_REGISTER_RCX, Ecx);
|
|
Status = IHISI_SUCCESS;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=47h, OEM Extra Data Read.
|
|
|
|
Hook chipset service SmmCsSvcIhisiOemExtDataRead.
|
|
|
|
@retval EFI_SUCCESS OEM Extra Data Read successful.
|
|
@return Other OEM Extra Data Read failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetOemExtraDataRead (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ReadSize;
|
|
UINTN RomBaseAddress;
|
|
UINT8 *ReadDataBuffer;
|
|
|
|
ReadSize = 0;
|
|
RomBaseAddress = 0;
|
|
ReadDataBuffer = (UINT8 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *)(UINTN)IhisiProtReadCpuReg32(EFI_SMM_SAVE_STATE_REGISTER_RDI), sizeof (UINT32))){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
ReadSize = *(UINT32 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ReadDataBuffer, ReadSize)){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
Status = SmmCsSvcIhisiOemExtDataRead(mOemExtraDataType, ReadDataBuffer, &ReadSize, &RomBaseAddress);
|
|
|
|
//
|
|
// Pass Chipset update parameter to kernel
|
|
//
|
|
switch (Status) {
|
|
case EFI_SUCCESS:
|
|
Status = IHISI_END_FUNCTION_CHAIN;
|
|
break;
|
|
|
|
case EFI_MEDIA_CHANGED:
|
|
mRomBaseAddress = RomBaseAddress;
|
|
mRomSize = ReadSize;
|
|
CopyMem ((VOID *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI), &ReadSize, sizeof(UINT32));
|
|
Status = IHISI_SUCCESS;
|
|
break;
|
|
|
|
case EFI_UNSUPPORTED:
|
|
if (mOemExtraDataType == Oa30ReadWrite) {
|
|
mRomBaseAddress = (UINTN) FdmGetNAtAddr (&gH2OFlashMapRegionMsdmGuid, 1);
|
|
mRomSize = (UINTN) FdmGetNAtSize (&gH2OFlashMapRegionMsdmGuid, 1);
|
|
}
|
|
Status = IHISI_SUCCESS;
|
|
break;
|
|
|
|
default:
|
|
Status = IHISI_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
/**
|
|
AH=42h, OEM Extra Data Write.
|
|
|
|
Hook chipset service.SmmCsSvcIhisiFbtsShutDown
|
|
|
|
@retval EFI_SUCCESS OEM Extra Data Write successful.
|
|
@return Other OEM Extra Data Write failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetOemExtraDataDosShutdownMode (
|
|
VOID
|
|
)
|
|
{
|
|
UINT8 ShutdownMode;
|
|
EFI_STATUS Status;
|
|
|
|
Status = EFI_SUCCESS;
|
|
ShutdownMode = (UINT8) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
|
|
switch (ShutdownMode) {
|
|
case DosReboot:
|
|
Status = SmmCsSvcIhisiFbtsReboot ();
|
|
break;
|
|
|
|
case DosShutdown:
|
|
Status = SmmCsSvcIhisiFbtsShutDown ();
|
|
break;
|
|
|
|
case DoNothing:
|
|
case WindowsReboot:
|
|
case WindowsShutdown:
|
|
case ContinueToFlash:
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
default:
|
|
Status = EFI_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=41h, Hook OemService OEM Extra Data Communication
|
|
|
|
01h = VBIOS
|
|
@retval EFI_SUCCESS Process OEM extra data communication successful.
|
|
@return Other Process OEM extra data communication failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemIhisiS41T1Vbios (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer;
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer;
|
|
UINTN BufferSize;
|
|
|
|
ApCommDataBuffer = (AP_COMMUNICATION_DATA_TABLE*) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, sizeof(AP_COMMUNICATION_DATA_TABLE))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
if (!IsValidApDataType (ApCommDataBuffer->DataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
BiosCommDataBuffer = AllocatePool (sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
if (BiosCommDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = SetApandBiosCommDataBuffer(ApCommDataBuffer, BiosCommDataBuffer);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return Status;
|
|
}
|
|
|
|
Status = IHISI_SUCCESS;
|
|
if (ApCommDataBuffer->DataType == Vbios) {
|
|
BufferSize = ApCommDataBuffer->StructureSize;
|
|
if (BufferSize < sizeof(BIOS_COMMUNICATION_DATA_TABLE)) {
|
|
BufferSize = sizeof(BIOS_COMMUNICATION_DATA_TABLE);
|
|
}
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, BufferSize)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS41T1VbiosFunction \n"));
|
|
Status = OemSvcIhisiS41T1VbiosFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS41T1VbiosFunction Status: %r\n", Status));
|
|
if (Status == EFI_MEDIA_CHANGED) {
|
|
CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
}
|
|
Status = IHISI_END_FUNCTION_CHAIN;
|
|
}
|
|
|
|
FreePool (BiosCommDataBuffer);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=41h, Oem OEM Extra Data Communication
|
|
|
|
54h = LogoUpdate
|
|
@retval EFI_SUCCESS Process OEM extra data communication successful.
|
|
@return Other Process OEM extra data communication failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemIhisiS41T54LogoUpdate (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer;
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer;
|
|
UINTN BufferSize;
|
|
|
|
ApCommDataBuffer = (AP_COMMUNICATION_DATA_TABLE*) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, sizeof(BIOS_COMMUNICATION_DATA_TABLE))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (!IsValidApDataType (ApCommDataBuffer->DataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
BiosCommDataBuffer = AllocatePool (sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
if (BiosCommDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = SetApandBiosCommDataBuffer(ApCommDataBuffer, BiosCommDataBuffer);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return Status;
|
|
}
|
|
|
|
Status = IHISI_SUCCESS;
|
|
if (ApCommDataBuffer->DataType == LogoUpdate) {
|
|
BufferSize = ApCommDataBuffer->StructureSize;
|
|
if (BufferSize < sizeof(BIOS_COMMUNICATION_DATA_TABLE)) {
|
|
BufferSize = sizeof(BIOS_COMMUNICATION_DATA_TABLE);
|
|
}
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, BufferSize)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS41T54LogoUpdateFunction \n"));
|
|
Status = OemSvcIhisiS41T54LogoUpdateFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS41T54LogoUpdateFunction Status: %r\n", Status));
|
|
if (Status == EFI_MEDIA_CHANGED) {
|
|
CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
}
|
|
Status = IHISI_END_FUNCTION_CHAIN;
|
|
}
|
|
|
|
FreePool (BiosCommDataBuffer);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=41h, Oem OEM Extra Data Communication
|
|
|
|
55h = CheckBiosSignBySystemBios
|
|
@retval EFI_SUCCESS Process OEM extra data communication successful.
|
|
@return Other Process OEM extra data communication failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemIhisiS41T55CheckBiosSignBySystemBios (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer;
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer;
|
|
UINTN BufferSize;
|
|
|
|
ApCommDataBuffer = (AP_COMMUNICATION_DATA_TABLE*) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, sizeof(BIOS_COMMUNICATION_DATA_TABLE))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (!IsValidApDataType (ApCommDataBuffer->DataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
BiosCommDataBuffer = AllocatePool (sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
if (BiosCommDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = SetApandBiosCommDataBuffer(ApCommDataBuffer, BiosCommDataBuffer);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return Status;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (ApCommDataBuffer->DataType == CheckBiosSignBySystemBios) {
|
|
BufferSize = ApCommDataBuffer->StructureSize;
|
|
if (BufferSize < sizeof(BIOS_COMMUNICATION_DATA_TABLE)) {
|
|
BufferSize = sizeof(BIOS_COMMUNICATION_DATA_TABLE);
|
|
}
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, BufferSize)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS41T55CheckBiosSignBySystemBiosFunction \n"));
|
|
Status = OemSvcIhisiS41T55CheckBiosSignBySystemBiosFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS41T55CheckBiosSignBySystemBiosFunction Status: %r\n", Status));
|
|
if (Status == EFI_MEDIA_CHANGED) {
|
|
CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
}
|
|
Status = IHISI_END_FUNCTION_CHAIN;
|
|
}
|
|
|
|
FreePool (BiosCommDataBuffer);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=41h, Oem OEM Extra Data Communication
|
|
|
|
50h = Oa30ReadWrite
|
|
@retval EFI_SUCCESS Process OEM extra data communication successful.
|
|
@return Other Process OEM extra data communication failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemIhisiS41T50a30ReadWrite (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer;
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer;
|
|
UINTN BufferSize;
|
|
|
|
ApCommDataBuffer = (AP_COMMUNICATION_DATA_TABLE*) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (!IsValidApDataType (ApCommDataBuffer->DataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
BiosCommDataBuffer = AllocatePool (sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
if (BiosCommDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
BufferSize = ApCommDataBuffer->StructureSize;
|
|
if (BufferSize < sizeof(BIOS_COMMUNICATION_DATA_TABLE)) {
|
|
BufferSize = sizeof(BIOS_COMMUNICATION_DATA_TABLE);
|
|
}
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, BufferSize)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
Status = SetApandBiosCommDataBuffer(ApCommDataBuffer, BiosCommDataBuffer);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return Status;
|
|
}
|
|
|
|
Status = IHISI_SUCCESS;
|
|
if (ApCommDataBuffer->DataType == Oa30ReadWrite) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS41T50HookOa30ReadWriteFunction \n"));
|
|
Status = OemSvcIhisiS41T50HookOa30ReadWriteFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS41T50HookOa30ReadWriteFunction Status: %r\n", Status));
|
|
if (Status == EFI_MEDIA_CHANGED) {
|
|
CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
}
|
|
Status = IHISI_END_FUNCTION_CHAIN;
|
|
}
|
|
FreePool (BiosCommDataBuffer);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=41h, Oem OEM Extra Data Communication
|
|
|
|
Resserved
|
|
@retval EFI_SUCCESS Process OEM extra data communication successful.
|
|
@return Other Process OEM extra data communication failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemIhisiS41ReservedFunction (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer;
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer;
|
|
UINTN BufferSize;
|
|
|
|
ApCommDataBuffer = (AP_COMMUNICATION_DATA_TABLE*) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, sizeof(BIOS_COMMUNICATION_DATA_TABLE))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (!IsValidApDataType (ApCommDataBuffer->DataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
BiosCommDataBuffer = AllocatePool (sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
if (BiosCommDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
BufferSize = ApCommDataBuffer->StructureSize;
|
|
if (BufferSize < sizeof(BIOS_COMMUNICATION_DATA_TABLE)) {
|
|
BufferSize = sizeof(BIOS_COMMUNICATION_DATA_TABLE);
|
|
}
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, BufferSize)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
Status = SetApandBiosCommDataBuffer(ApCommDataBuffer, BiosCommDataBuffer);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return Status;
|
|
}
|
|
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS41ReservedFunction \n"));
|
|
Status = OemSvcIhisiS41ReservedFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS41ReservedFunction Status: %r\n", Status));
|
|
|
|
if (Status == EFI_MEDIA_CHANGED) {
|
|
CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
}
|
|
FreePool (BiosCommDataBuffer);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=41h,OEM Extra Data Communication
|
|
|
|
Save input registers;
|
|
|
|
@retval EFI_SUCCESS Process OEM extra data communication successful.
|
|
@return Other Process OEM extra data communication failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelCommunicationSaveRegs (
|
|
VOID
|
|
)
|
|
{
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer;
|
|
UINTN BufferSize;
|
|
|
|
mRomBaseAddress = 0;
|
|
mRomSize = 0;
|
|
ApCommDataBuffer = (AP_COMMUNICATION_DATA_TABLE*) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, sizeof(AP_COMMUNICATION_DATA_TABLE))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
if (ApCommDataBuffer->Signature != AP_COMMUNICATION_SIGNATURE) {
|
|
return IHISI_UNSUPPORTED_FUNCTION;
|
|
}
|
|
|
|
BufferSize = ApCommDataBuffer->StructureSize;
|
|
if (BufferSize < sizeof(AP_COMMUNICATION_DATA_TABLE)) {
|
|
BufferSize = sizeof(AP_COMMUNICATION_DATA_TABLE);
|
|
}
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, BufferSize)) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (!IsValidApDataType (ApCommDataBuffer->DataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
mOemExtraDataType = ApCommDataBuffer->DataType;
|
|
|
|
CopyMem(&mApCommDataBuffer, ApCommDataBuffer, sizeof(AP_COMMUNICATION_DATA_TABLE));
|
|
|
|
IhisiErrorCodeHandler((UINT32)IHISI_SUCCESS);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication
|
|
|
|
@retval EFI_SUCCESS Process OEM extra data communication successful.
|
|
@return Other Process OEM extra data communication failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelOemExtraDataCommunication (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer;
|
|
AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer;
|
|
UINTN BufferSize;
|
|
|
|
ApCommDataBuffer = (AP_COMMUNICATION_DATA_TABLE*) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, sizeof(BIOS_COMMUNICATION_DATA_TABLE))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (!IsValidApDataType (ApCommDataBuffer->DataType)) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
BiosCommDataBuffer = AllocatePool (sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
if (BiosCommDataBuffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
BufferSize = ApCommDataBuffer->StructureSize;
|
|
if (BufferSize < sizeof(BIOS_COMMUNICATION_DATA_TABLE)) {
|
|
BufferSize = sizeof(BIOS_COMMUNICATION_DATA_TABLE);
|
|
}
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ApCommDataBuffer, BufferSize)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
Status = SetApandBiosCommDataBuffer(ApCommDataBuffer, BiosCommDataBuffer);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (BiosCommDataBuffer);
|
|
return Status;
|
|
}
|
|
|
|
switch (ApCommDataBuffer->DataType) {
|
|
case Oa30ReadWrite:
|
|
Status = Oa30ReadWriteFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
break;
|
|
|
|
case Oa30Erase:
|
|
Status = Oa30EraseFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
break;
|
|
|
|
case Oa30PopulateHeader:
|
|
Status = Oa30PopulateHeaderFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
break;
|
|
|
|
case Oa30DePopulateHeader:
|
|
Status = Oa30DePopulateHeaderFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
mOemExtraDataType = 0;
|
|
FreePool (BiosCommDataBuffer);
|
|
return Status;
|
|
}
|
|
|
|
CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
|
|
FreePool (BiosCommDataBuffer);
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=42h, OEM Extra Data Write.
|
|
|
|
@retval EFI_SUCCESS OEM Extra Data Write successful.
|
|
@return Other OEM Extra Data Write failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelOemExtraDataWrite (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN WriteSize;
|
|
UINTN RomBaseAddress;
|
|
UINT8 *WriteDataBuffer;
|
|
|
|
WriteDataBuffer = (UINT8 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
WriteSize = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
RomBaseAddress = (UINTN) (IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX) >> 8);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) WriteDataBuffer, WriteSize)){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
switch (mOemExtraDataType) {
|
|
case Oa30ReadWrite:
|
|
if (WriteSize > mRomSize) {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
} else {
|
|
RomBaseAddress = mRomBaseAddress;
|
|
Status = Oa30DataWrite(WriteDataBuffer, WriteSize, RomBaseAddress);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=47h, OEM Extra Data Read.
|
|
|
|
@retval EFI_SUCCESS OEM Extra Data Read successful.
|
|
@return Other OEM Extra Data Read failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelOemExtraDataRead (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ReadSize;
|
|
UINTN RomBaseAddress;
|
|
UINT8 *ReadDataBuffer;
|
|
|
|
ReadSize = 0;
|
|
RomBaseAddress = mRomBaseAddress;
|
|
ReadDataBuffer = (UINT8 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *)(UINTN)IhisiProtReadCpuReg32(EFI_SMM_SAVE_STATE_REGISTER_RDI), sizeof (UINT32))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
ReadSize = *(UINT32 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ReadDataBuffer, ReadSize)){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
switch (mOemExtraDataType) {
|
|
case Oa30ReadWrite:
|
|
Status = Oa30DataRead(ReadDataBuffer, &ReadSize, RomBaseAddress);
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
CopyMem ((VOID *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI), &ReadSize, sizeof(UINT32));
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
InstallOemExtraDataCommunicationServices (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
IHISI_REGISTER_TABLE *SubFuncTable;
|
|
UINT16 TableCount;
|
|
|
|
SubFuncTable = OEM_EXT_COMMON_REGISTER_TABLE;
|
|
TableCount = sizeof(OEM_EXT_COMMON_REGISTER_TABLE)/sizeof(OEM_EXT_COMMON_REGISTER_TABLE[0]);
|
|
Status = RegisterIhisiSubFunction (SubFuncTable, TableCount);
|
|
if (EFI_ERROR(Status)) {
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|