232 lines
6.8 KiB
C
232 lines
6.8 KiB
C
/** @file
|
|
This driver provides IHISI interface in SMM mode
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2016 - 2020, Insyde Software Corporation. 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 "MeCapsuleSmm.h"
|
|
#include <Library/BaseMemoryLib.h>
|
|
|
|
#include <Register/HeciRegs.h>
|
|
#include <Library/SmmHeciLib.h>
|
|
#include <Library/PciSegmentLib.h>
|
|
#include <Guid/MeUpdVariable.h>
|
|
|
|
#define MAX_RECOVERY_RETRY 3
|
|
|
|
H2O_IHISI_PROTOCOL *mH2OIhisi = NULL;
|
|
EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *mSmmFwBlockService = NULL;
|
|
STATIC CONST BOOLEAN mPcdIhisiRegisterTableValid = (BOOLEAN)(FixedPcdGetPtrSize (PcdIhisiRegisterTable) % sizeof (PCD_IHISI_REGISTER_TABLE) == 0);
|
|
|
|
/**
|
|
Ihisi driver entry point to initialize all of IHISI relative services
|
|
|
|
@param[in] ImageHandle The firmware allocated handle for the UEFI image.
|
|
@param[in] SystemTable A pointer to the EFI System Table.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
*/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
IfwuSmmEntryPoint (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
Status = gSmst->SmmLocateProtocol (
|
|
&gH2OIhisiProtocolGuid,
|
|
NULL,
|
|
(VOID **) &mH2OIhisi
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
if (mSmmFwBlockService == NULL) {
|
|
Status = gSmst->SmmLocateProtocol (
|
|
&gEfiSmmFwBlockServiceProtocolGuid,
|
|
NULL,
|
|
(VOID **) &mSmmFwBlockService
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
Status = FmtsUseIntelLibInit ();
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Register IHISI sub function if SubFuncTable CmdNumber/AsciiFuncGuid define in PcdIhisiRegisterTable list.
|
|
|
|
@param[out] SubFuncTable Pointer to ihisi register table.
|
|
@param[out] TableCount SubFuncTable count
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
@return Other Error occurred in this function.
|
|
**/
|
|
EFI_STATUS
|
|
RegisterIhisiSubFunction (
|
|
IHISI_REGISTER_TABLE *SubFuncTable,
|
|
UINT16 TableCount
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *PcdTable;
|
|
UINT8 PcdPriority;
|
|
UINT8 EndChar;
|
|
UINTN Index;
|
|
UINTN PcdCount;
|
|
UINTN PcdMaxCount;
|
|
UINTN SignatureSize;
|
|
BOOLEAN PcdFoundRegistered;
|
|
|
|
Status = EFI_SUCCESS;
|
|
EndChar = 0;
|
|
PcdFoundRegistered = FALSE;
|
|
|
|
PcdTable = (UINT8 *)PcdGetPtr (PcdIhisiRegisterTable);
|
|
PcdMaxCount = FixedPcdGetPtrSize (PcdIhisiRegisterTable) / sizeof (UINT8);
|
|
if (!mPcdIhisiRegisterTableValid) {
|
|
DEBUG ((DEBUG_ERROR, "PcdIhisiRegisterTable of description not follow PCD_IHISI_REGISTER_TABLE definition, \
|
|
it may cause some of IHISI function register fail \n"));
|
|
}
|
|
|
|
for (Index = 0; Index < TableCount; Index ++) {
|
|
PcdCount = 0;
|
|
PcdPriority = 0x80;
|
|
PcdFoundRegistered = FALSE;
|
|
SignatureSize = AsciiStrLen (SubFuncTable[Index].FuncSignature);
|
|
|
|
//
|
|
// Caculate PCD of address to find 1. CmdNumber 2. FuncSignature 3. Priority
|
|
//
|
|
do {
|
|
if (SubFuncTable[Index].CmdNumber == *(PcdTable + PcdCount)) {
|
|
PcdCount++;
|
|
if (AsciiStrnCmp (SubFuncTable[Index].FuncSignature, (CHAR8 *) (PcdTable + PcdCount), SignatureSize) == 0) {
|
|
if (EndChar == *(PcdTable + PcdCount + SignatureSize)) {
|
|
PcdPriority = *(PcdTable + PcdCount + SignatureSize + 1);
|
|
PcdFoundRegistered = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
PcdCount++;
|
|
} while (PcdCount < PcdMaxCount);
|
|
|
|
if (PcdFoundRegistered) {
|
|
Status = mH2OIhisi->RegisterCommand (SubFuncTable[Index].CmdNumber, SubFuncTable[Index].IhisiFunction, PcdPriority);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((DEBUG_ERROR, "IHISI command :0x%X, priority : 0x%X, that already has a registered function\n", SubFuncTable[Index].CmdNumber, PcdPriority));
|
|
ASSERT (FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
#if 1
|
|
UINTN
|
|
CheckAndFixHeciForAccess (
|
|
IN HECI_DEVICE HeciDev
|
|
);
|
|
|
|
/**
|
|
Determine whether ME state is in recovery mode.
|
|
|
|
@retval TRUE Is in Recovery mode.
|
|
@retval FALSE Not in Recovery mode.
|
|
|
|
**/
|
|
BOOLEAN
|
|
EFIAPI
|
|
IsMeStateRecovery (
|
|
VOID
|
|
)
|
|
{
|
|
HECI_FWS_REGISTER MeFirmwareStatus;
|
|
|
|
MeFirmwareStatus.ul = 0;
|
|
|
|
if (CheckAndFixHeciForAccess (HECI1_DEVICE) != 0) {
|
|
MeFirmwareStatus.ul = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (ME_SEGMENT, ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, R_ME_HFS));
|
|
if (MeFirmwareStatus.r.CurrentState == ME_STATE_RECOVERY) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Determine whether is up to maximum try of ME recovery.
|
|
|
|
@param[in] Recorder If TRUE, set the variable to record the times of recovery try.
|
|
|
|
@retval TRUE Is up to maximum try.
|
|
@retval FALSE Not up to maximum try.
|
|
|
|
**/
|
|
BOOLEAN
|
|
EFIAPI
|
|
IsMaxRecoveryTry (
|
|
IN BOOLEAN Recorder
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Size;
|
|
UINT8 MaxRecoveryRetryCounter;
|
|
|
|
Size = sizeof (MaxRecoveryRetryCounter);
|
|
Status = CommonGetVariable (
|
|
L"MeRecoveryRetry",
|
|
&gMeUpdCountGuid,
|
|
&Size,
|
|
&MaxRecoveryRetryCounter
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
MaxRecoveryRetryCounter = 1;
|
|
}
|
|
|
|
MaxRecoveryRetryCounter++;
|
|
if (MaxRecoveryRetryCounter > MAX_RECOVERY_RETRY) {
|
|
return TRUE;
|
|
}
|
|
|
|
if (Recorder) {
|
|
//
|
|
// Set recovery retry counter
|
|
//
|
|
Size = sizeof (MaxRecoveryRetryCounter);
|
|
Status = CommonSetVariable (
|
|
L"MeRecoveryRetry",
|
|
&gMeUpdCountGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
Size,
|
|
&MaxRecoveryRetryCounter
|
|
);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
#endif
|