781 lines
26 KiB
C
781 lines
26 KiB
C
/** @file
|
|
Implement the Chipset Servcie IHISI OemExtra Data subfunction for this driver.
|
|
|
|
;***************************************************************************
|
|
;* Copyright (c) 2017 - 2021, 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 <Uefi.h>
|
|
#include <H2OIhisi.h>
|
|
#include "BiosGuard.h"
|
|
#include <CpuRegs.h>
|
|
#include "IndustryStandard/Oa3_0.h"
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/SmmChipsetSvcLib.h>
|
|
#include <Library/SmmOemSvcChipsetLib.h>
|
|
#include <Library/SmmServicesTableLib.h>
|
|
#include <Library/BaseOemSvcKernelLib.h>
|
|
#include <Protocol/BiosGuard.h>
|
|
#include <Protocol/H2OIhisi.h>
|
|
#include <Protocol/SmmFwBlockService.h>
|
|
#include <Protocol/SmmVariable.h>
|
|
#include <CsSvcIhisiOemExtraDataCommunication.h>
|
|
#include <CsSvcIhisiFbts.h>
|
|
#include <Register/CommonMsr.h>
|
|
#include <Library/MsrFruLib.h>
|
|
#include <IndustryStandard/Oa3_0.h>
|
|
#include <Library/SmmHeciLib.h>
|
|
|
|
extern BOOLEAN mFlashME;
|
|
extern UINTN mWriteSize;
|
|
extern H2O_IHISI_PROTOCOL *mH2OIhisi;
|
|
extern EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *mSmmFwBlockService;
|
|
extern BIOSGUARD_PROTOCOL *mBiosGuardProtocol;
|
|
extern EFI_PHYSICAL_ADDRESS mBiosGuardMemAddress;
|
|
extern UINTN mBiosGuardMemSize;
|
|
extern EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;
|
|
static EFI_GUID gMsdmAddressGuid = MEMORY_ADDRESS_FOR_MSDM_GUID;
|
|
|
|
// These Offset should check BiosGuard Script, which described the Destination Flash Address and DataSize, Please reference GenBiosGuardHdr.h
|
|
#define BGSL_DST_TYPE_OFFSET 0x03
|
|
#define BGSL_SIZE_OFFSET 0x05
|
|
#define BGSL_SPI_DST_ADDR_OFFSET 0x07
|
|
|
|
|
|
/**
|
|
TURE -- Platform Pfat/BiosGuard feature enabling
|
|
FALSE -- Platform Pfat/BiosGuard feature disabling
|
|
**/
|
|
BOOLEAN
|
|
IsBiosGuardSupport (
|
|
VOID
|
|
)
|
|
{
|
|
MSR_PLAT_FRMW_PROT_CTRL_REGISTER PlatFrmwProtCtrl;
|
|
|
|
if (!MsrIsPfatEnabled()) {
|
|
//
|
|
// Cpu does not support Pfat/BiosGuard Feature.
|
|
//
|
|
return FALSE;
|
|
}
|
|
|
|
PlatFrmwProtCtrl.Uint64 = AsmReadMsr64 (MSR_PLAT_FRMW_PROT_CTRL);
|
|
if (PlatFrmwProtCtrl.Bits.PfatEnable == 1) {
|
|
//
|
|
// Pfat/BiosGuard feature enabled.
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
TURE -- Platform FlashWearOut Set
|
|
FALSE -- Platform FlashWearOut Un-set
|
|
**/
|
|
BOOLEAN
|
|
IsFlashWearOutSet (
|
|
VOID
|
|
)
|
|
{
|
|
UINT64 PlatformBiosInfo;
|
|
UINTN DataSize;
|
|
EFI_STATUS Status;
|
|
|
|
DataSize = sizeof (UINT64);
|
|
Status = mSmmVariable->SmmGetVariable (
|
|
L"BiosInfoFlagData",
|
|
&gBiosInfoFlagGuid,
|
|
NULL,
|
|
&DataSize,
|
|
&PlatformBiosInfo
|
|
);
|
|
if (!EFI_ERROR(Status) && PlatformBiosInfo & BIT0) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
STATIC
|
|
BOOLEAN
|
|
MsdmExist (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN DataSize;
|
|
BOOLEAN MsdmExist;
|
|
UINTN RomBaseAddress;
|
|
EFI_ACPI_MSDM_DATA_STRUCTURE *MsdmData;
|
|
UINT8 *VarDataBuffer;
|
|
|
|
MsdmData = NULL;
|
|
MsdmExist = FALSE;
|
|
VarDataBuffer = NULL;
|
|
|
|
if (IsBiosGuardSupport () && IsFlashWearOutSet()) {
|
|
DataSize = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataSize);
|
|
Status = gSmst->SmmAllocatePool (
|
|
EfiRuntimeServicesData,
|
|
DataSize,
|
|
(VOID **)&VarDataBuffer
|
|
);
|
|
Status = mSmmVariable->SmmGetVariable (
|
|
L"MsdmUpdate",
|
|
&gMsdmAddressGuid,
|
|
NULL,
|
|
&DataSize,
|
|
VarDataBuffer
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)){
|
|
Status = mSmmVariable->SmmSetVariable (
|
|
L"MsdmUpdate",
|
|
&gMsdmAddressGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
|
|
DataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE);
|
|
RomBaseAddress = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataBase);
|
|
|
|
Status = gSmst->SmmAllocatePool (
|
|
EfiRuntimeServicesData,
|
|
DataSize,
|
|
(VOID **)&MsdmData
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
goto Done;
|
|
}
|
|
*(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE;
|
|
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) {
|
|
gSmst->SmmFreePool (MsdmData);
|
|
}
|
|
return MsdmExist;
|
|
}
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type 50h to read/write OA3.0.
|
|
|
|
@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
|
|
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 to erase OA3.0 (reset to default).
|
|
|
|
@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
|
|
Oa30EraseFunction (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS OemSvcStatus;
|
|
UINT8 LoopCount;
|
|
UINTN RomBaseAddress;
|
|
UINTN EraseSize;
|
|
UINT8 Erase;
|
|
|
|
RomBaseAddress = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataBase);
|
|
LoopCount = 0;
|
|
EraseSize = 0x1000;
|
|
Status = EFI_SUCCESS;
|
|
|
|
if (!MsdmExist ()) {
|
|
BiosCommDataBuffer->ErrorReturn = (BiosCommDataBuffer->ErrorReturn | ERROR_RETURE_OA30_NOT_EXIST);
|
|
goto Done;
|
|
}
|
|
|
|
if (PcdGetBool (PcdEcSharedFlashSupported)) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n"));
|
|
OemSvcStatus = OemSvcEcIdle (TRUE);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus));
|
|
}
|
|
|
|
Status = EFI_UNSUPPORTED;
|
|
if (IsBiosGuardSupport () && IsFlashWearOutSet()) {
|
|
Erase = 1;
|
|
Status = mSmmVariable->SmmSetVariable (
|
|
L"MsdmErase",
|
|
&gMsdmAddressGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
sizeof(UINT8),
|
|
&Erase
|
|
);
|
|
} else {
|
|
*(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE;
|
|
while ((EFI_ERROR (Status)) && (LoopCount < 100)) {
|
|
Status = mSmmFwBlockService->EraseBlocks (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
&EraseSize
|
|
);
|
|
LoopCount++;
|
|
}
|
|
}
|
|
|
|
if (PcdGetBool (PcdEcSharedFlashSupported)) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n"));
|
|
OemSvcStatus = OemSvcEcIdle (FALSE);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus));
|
|
}
|
|
|
|
Done:
|
|
BiosCommDataBuffer->DataSize = ApCommDataBuffer->DataSize;
|
|
BiosCommDataBuffer->PhysicalDataSize = ApCommDataBuffer->PhysicalDataSize;
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=41h, OEM Extra Data Communication type 52h to populate header.
|
|
|
|
@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
|
|
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.
|
|
|
|
@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
|
|
Oa30DePopulateHeaderFunction (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
BiosGuardUpdateHandleFunction (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
if (IsBiosGuardSupport () == FALSE) {
|
|
BiosCommDataBuffer->ErrorReturn = ERROR_RETURE_NOT_SUPPORT;
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
BiosCommDataBuffer->BlockSize = OemExtraMaximunBlockSize;
|
|
BiosCommDataBuffer->DataSize = OemExtraReportWriteSize;
|
|
BiosCommDataBuffer->PhysicalDataSize = ApCommDataBuffer->PhysicalDataSize;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
BiosGuardReturnHandleFunction (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (IsBiosGuardSupport () == FALSE) {
|
|
BiosCommDataBuffer->ErrorReturn = ERROR_RETURE_NOT_SUPPORT;
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
BiosCommDataBuffer->BlockSize = OemExtraMaximunBlockSize;
|
|
BiosCommDataBuffer->DataSize = OemExtraReportWriteSize;
|
|
BiosCommDataBuffer->PhysicalDataSize = ApCommDataBuffer->PhysicalDataSize;
|
|
BiosCommDataBuffer->ErrorReturn = ERROR_RETURE_RETURN_CODE_VALID;
|
|
|
|
BiosCommDataBuffer->ReturnCode = AsmReadMsr64 (MSR_PLAT_FRMW_PROT_TRIG_PARAM) &
|
|
(LShiftU64 (V_MSR_PLAT_FRMW_PROT_TRIG_PARAM_STATUS_MASK,
|
|
N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_STATUS_OFFSET) |
|
|
LShiftU64 (V_MSR_PLAT_FRMW_PROT_TRIG_PARAM_DATA_MASK,
|
|
N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_DATA_OFFSET));
|
|
if (mFlashME) {
|
|
if (BiosCommDataBuffer->ReturnCode == 0x0) {
|
|
Status = IhisiSuccess;
|
|
} else {
|
|
Status = FbtsWriteFail;
|
|
}
|
|
FlashMEAfterProcess(Status);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
BiosGuardUpdateWrite (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 BgupcSize;
|
|
UINT32 BgupcOffset;
|
|
UINT32 BufferSize;
|
|
EFI_PHYSICAL_ADDRESS BgupCertificate;
|
|
UINT8 *InputDataBuffer;
|
|
UINT32 DataSize;
|
|
UINT32 *BGSL;
|
|
UINT32 ROMOffset;
|
|
Status = EFI_SUCCESS;
|
|
InputDataBuffer = NULL;
|
|
BgupcOffset = 0x00;
|
|
BgupcSize = 0x00;
|
|
BufferSize = 0x00;
|
|
BgupCertificate = 0x00;
|
|
DataSize = 0x00;
|
|
BGSL = NULL;
|
|
ROMOffset = 0x00;
|
|
|
|
if (IsBiosGuardSupport () == FALSE){
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
InputDataBuffer = (UINT8*) (UINTN) mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
BgupcOffset = sizeof (BGUP_HEADER) + ((BGUP *) InputDataBuffer)->BgupHeader.ScriptSectionSize + ((BGUP *) InputDataBuffer)->BgupHeader.DataSectionSize;
|
|
BufferSize = mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
BgupCertificate = (EFI_PHYSICAL_ADDRESS) (mBiosGuardMemAddress + mBiosGuardMemSize - BGUPC_MEMORY_OFFSET);
|
|
|
|
if (!mH2OIhisi->BufferInCmdBuffer ((VOID *) InputDataBuffer, BufferSize)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
switch (((BGUPC_HEADER *)(InputDataBuffer + BgupcOffset))->Algorithm) {
|
|
case 1:
|
|
BgupcSize = sizeof (BGUPC_ALGORITHM_1);
|
|
break;
|
|
default:
|
|
BgupcSize = sizeof (BGUPC_ALGORITHM_1);
|
|
break;
|
|
}
|
|
|
|
if ((BgupcOffset + BgupcSize) != BufferSize) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem ((VOID *)(UINT64) mBiosGuardMemAddress, mBiosGuardMemSize);
|
|
CopyMem ((VOID *)(UINT64) mBiosGuardMemAddress, InputDataBuffer, BgupcOffset);
|
|
CopyMem ((VOID *) BgupCertificate, InputDataBuffer + BgupcOffset, BgupcSize);
|
|
|
|
if (!mFlashME){
|
|
DataSize = ((BGUP_HEADER*)mBiosGuardMemAddress)->ScriptSectionSize;
|
|
|
|
Status = gSmst->SmmAllocatePool (
|
|
EfiRuntimeServicesData,
|
|
DataSize,
|
|
(VOID **)&BGSL
|
|
);
|
|
if (!EFI_ERROR (Status )) {
|
|
CopyMem (BGSL, (VOID *)(mBiosGuardMemAddress + sizeof(BGUP_HEADER)), DataSize);
|
|
//
|
|
// 0x00000000 means Full image
|
|
// 0xFFFFFFFF means only BIOS
|
|
//
|
|
if ((BGSL[BGSL_DST_TYPE_OFFSET]) == 0x00000000) {
|
|
mWriteSize = BGSL[BGSL_SIZE_OFFSET];
|
|
ROMOffset = BGSL[BGSL_SPI_DST_ADDR_OFFSET];
|
|
CheckInMERange (ROMOffset);
|
|
}
|
|
gSmst->SmmFreePool (BGSL);
|
|
}
|
|
}
|
|
if (mFlashME){
|
|
SetMeHalt ();
|
|
}
|
|
|
|
//
|
|
// Use Intel BIOS Guard protocol to trigger BIOS Guard ACM
|
|
//
|
|
// Status = gSmst->SmmIo.Io.Write (&gSmst->SmmIo, SMM_IO_UINT8, mGlobalNvsArea->BiosGuardIoTrapAddress, 1, &Trigger);
|
|
mBiosGuardProtocol->Execute (mBiosGuardProtocol, TRUE);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Function to write OA3.0 data and do action which request from IHISI function 42h.
|
|
|
|
@retval EFI_SUCCESS Successfully returns.
|
|
**/
|
|
EFI_STATUS
|
|
Oa30DataWrite (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS OemSvcStatus;
|
|
UINT32 WriteSize;
|
|
UINT8 EraseCount;
|
|
UINT8 WriteCount;
|
|
UINT8 ShutdownMode;
|
|
UINT32 MsdmDataSize;
|
|
UINTN RomBaseAddress;
|
|
UINT8 *WriteDataBuffer;
|
|
UINT8 *ReturnDataBuffer;
|
|
UINTN Index2;
|
|
UINTN EraseSize;
|
|
UINT8 *TEMP;
|
|
|
|
WriteDataBuffer = (UINT8 *) (UINTN) mH2OIhisi->ReadCpuReg32(EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
WriteSize = (UINT32) mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
RomBaseAddress = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataBase);
|
|
MsdmDataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE);
|
|
|
|
if (WriteSize == MsdmDataSize) {
|
|
EraseSize = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataSize);
|
|
ReturnDataBuffer = NULL;
|
|
|
|
Status = gSmst->SmmAllocatePool (
|
|
EfiRuntimeServicesData,
|
|
EraseSize,
|
|
(VOID **)&ReturnDataBuffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
*(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE;
|
|
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];
|
|
}
|
|
|
|
Status = EFI_UNSUPPORTED;
|
|
if (PcdGetBool (PcdEcSharedFlashSupported)) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n"));
|
|
OemSvcStatus = OemSvcEcIdle (TRUE);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus));
|
|
}
|
|
|
|
if (IsBiosGuardSupport () && IsFlashWearOutSet()) {
|
|
Status = mSmmVariable->SmmSetVariable (
|
|
L"MsdmUpdate",
|
|
&gMsdmAddressGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
MsdmDataSize,
|
|
ReturnDataBuffer
|
|
);
|
|
} else {
|
|
EraseCount = 0;
|
|
WriteCount = 0;
|
|
do {
|
|
Status = mSmmFwBlockService->EraseBlocks (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
&EraseSize
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
EraseCount = 0;
|
|
Status = mSmmFwBlockService->Write (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
&EraseSize,
|
|
ReturnDataBuffer
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
goto WriteDone;
|
|
} else {
|
|
Status = IHISI_FBTS_WRITE_FAILED;
|
|
WriteCount++;
|
|
}
|
|
} else {
|
|
Status = IHISI_FBTS_ERASE_FAILED;
|
|
EraseCount++;
|
|
}
|
|
} while ((EraseCount < 100) && (WriteCount < 100));
|
|
}
|
|
|
|
WriteDone:
|
|
gSmst->SmmFreePool (ReturnDataBuffer);
|
|
if (PcdGetBool (PcdEcSharedFlashSupported)) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n"));
|
|
OemSvcStatus = OemSvcEcIdle (FALSE);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus));
|
|
}
|
|
|
|
if (EFI_ERROR(Status)){
|
|
return EFI_ACCESS_DENIED;
|
|
}
|
|
} else {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ShutdownMode = (UINT8) mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
switch (ShutdownMode) {
|
|
|
|
case DoNothing:
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
|
|
case WindowsReboot:
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
|
|
case WindowsShutdown:
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
|
|
case DosReboot:
|
|
//
|
|
// Note: Reboot by Oem hook
|
|
//
|
|
Status = IhisiFbtsReboot ();
|
|
break;
|
|
|
|
case DosShutdown:
|
|
Status = IhisiFbtsShutDown ();
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_UNSUPPORTED;
|
|
break;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=41h(OemExtraDataCommunication),
|
|
This function offers an interface to do IHISI Sub function AH=41h.
|
|
|
|
@param[in] ApCommDataBuffer Pointer to AP communication data buffer.
|
|
@param[in, out] BiosCommDataBuffer On entry, pointer to BIOS communication data buffer.
|
|
On exit, points to updated BIOS communication data buffer.
|
|
|
|
@retval EFI_UNSUPPORTED Returns unsupported by default.
|
|
@retval EFI_MEDIA_CHANGED Alter the Configuration Parameter or hook code.
|
|
@retval EFI_SUCCESS The function performs the same operation as caller.
|
|
The caller will skip the specified behavior and assuming
|
|
that it has been handled completely by this function.
|
|
*/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
IhisiOemExtCommunication (
|
|
IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer,
|
|
IN OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer
|
|
)
|
|
{
|
|
EFI_STATUS 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;
|
|
|
|
case PfatUpdate:
|
|
Status = BiosGuardUpdateHandleFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
break;
|
|
|
|
case PfatReturn:
|
|
Status = BiosGuardReturnHandleFunction (ApCommDataBuffer, BiosCommDataBuffer);
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_UNSUPPORTED; //Return unsupported to indicate this is reserved function
|
|
break;
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
} else {
|
|
CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
AH=42h(OemExtraDataWrite)
|
|
This function offers an interface to do IHISI Sub function AH=42h,
|
|
|
|
@param[in] FunctionType Function type.
|
|
@param[in, out] WriteDataBuffer Pointer to input file data buffer.
|
|
@param[in, out] WriteSize Write size.
|
|
@param[in, out] RomBaseAddress Target offset to write.
|
|
@param[in] ShutdownMode Shutdown mode.
|
|
|
|
@retval EFI_UNSUPPORTED Returns unsupported by default.
|
|
@retval EFI_MEDIA_CHANGED Alter the Configuration Parameter or hook code.
|
|
@retval EFI_SUCCESS The function performs the same operation as caller.
|
|
The caller will skip the specified behavior and assuming
|
|
that it has been handled completely by this function.
|
|
*/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
IhisiOemExtDataWrite (
|
|
IN UINT8 FunctionType,
|
|
IN OUT UINT8 *WriteDataBuffer,
|
|
IN OUT UINTN *WriteSize,
|
|
IN OUT UINTN *RomBaseAddress,
|
|
IN UINT8 ShutdownMode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = EFI_UNSUPPORTED;
|
|
|
|
switch (FunctionType) {
|
|
case Oa30ReadWrite:
|
|
Status = Oa30DataWrite ();
|
|
break;
|
|
|
|
case PfatUpdate:
|
|
FunctionType = 0x00;
|
|
Status = BiosGuardUpdateWrite ();
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_UNSUPPORTED;
|
|
break;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=47h(OemExtraDataRead),
|
|
This function offers an interface to do IHISI Sub function AH=47h,
|
|
|
|
@param[in] FunctionType Function type
|
|
@param[in, out] DataBuffer Pointer to return data buffer.
|
|
@param[in, out] Size Read size.
|
|
@param[in, out] RomBaseAddress Read address.
|
|
|
|
@retval EFI_UNSUPPORTED Returns unsupported by default.
|
|
@retval EFI_MEDIA_CHANGED Alter the Configuration Parameter or hook code.
|
|
@retval EFI_SUCCESS The function performs the same operation as caller.
|
|
The caller will skip the specified behavior and assuming
|
|
that it has been handled completely by this function.
|
|
*/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
IhisiOemExtDataRead (
|
|
IN UINT8 FunctionType,
|
|
IN OUT UINT8 *DataBuffer,
|
|
IN OUT UINTN *Size,
|
|
IN OUT UINTN *RomBaseAddress
|
|
)
|
|
{
|
|
return EFI_UNSUPPORTED;
|
|
}
|