3215 lines
102 KiB
C
3215 lines
102 KiB
C
/** @file
|
|
FbtsLib Library Instance implementation
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2014 - 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 "IhisiFbts.h"
|
|
#include <EfiFlashMap.h>
|
|
#include <Protocol/Pcd.h>
|
|
#include <Protocol/SmmSwapAddressRange.h>
|
|
#include <Library/HobLib.h>
|
|
#include <Library/BvdtLib.h>
|
|
#include <Library/FdSupportLib.h>
|
|
#include <Library/SmmOemSvcKernelLib.h>
|
|
#include <Library/FlashRegionLib.h>
|
|
#include <Library/CacheMaintenanceLib.h>
|
|
#include <Library/VariableSupportLib.h>
|
|
#include <Library/VariableLib.h>
|
|
#include <Library/LockBoxLib.h>
|
|
#include <Library/SeamlessRecoveryLib.h>
|
|
#include <Guid/FlashMapHob.h>
|
|
#include <Guid/AuthenticatedVariableFormat.h>
|
|
|
|
#define UPDATE_EXT_ITEM_FUN_TABLE_MAX 8
|
|
#define DEFAULT_VARIABLE_NAME_SIZE 0x50
|
|
STATIC EFI_GUID mDefaultPreservedVendorGuid = { 0x77fa9abd, 0x0359, 0x4d32, 0xbd, 0x60, 0x28, 0xf4, 0xe7, 0x8f, 0x78, 0x4b };
|
|
STATIC EFI_GUID mPreservedVariableTable2OtherAllGuid = {0xffffffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
|
|
|
STATIC FBTS_PLATFORM_ROM_MAP_BUFFER mRomMapBuffer;
|
|
STATIC FBTS_PLATFORM_PRIVATE_ROM_BUFFER mPrivateRomMapBuffer;
|
|
|
|
STATIC BOOLEAN mUpdateSequenceEnabled = FALSE;
|
|
STATIC EFI_SWAP_ADDRESS_RANGE_PROTOCOL *mSwapAddressRange = NULL;
|
|
|
|
extern BOOLEAN mInPOST;
|
|
extern EFI_GUID gInsydeTokenSpaceGuid;
|
|
//
|
|
// FBTS Support Functions
|
|
//
|
|
STATIC
|
|
IHISI_REGISTER_TABLE
|
|
FBTS_REGISTER_TABLE[] = {
|
|
//
|
|
// AH=10h
|
|
//
|
|
{ FBTSGetSupportVersion, "S10Cs_GetPermission", ChipsetFbtsGetPermission }, \
|
|
{ FBTSGetSupportVersion, "S10OemGetPermission", OemFbtsGetPermission }, \
|
|
{ FBTSGetSupportVersion, "S10OemGetAcStatus00", OemFbtsGetAcStatus }, \
|
|
{ FBTSGetSupportVersion, "S10OemBatterylife00", OemFbtsGetBatteryLife }, \
|
|
{ FBTSGetSupportVersion, "S10Kn_GetVersion000", KernelFbtsGetVersion }, \
|
|
{ FBTSGetSupportVersion, "S10Kn_InitOemHelp00", KernelFbtsInitOemHelp }, \
|
|
{ FBTSGetSupportVersion, "S10Kn_GetVendorID00", KernelFbtsGetVendorId }, \
|
|
{ FBTSGetSupportVersion, "S10Kn_GetBatteryLow", KernelFbtsGetBatteryLowBound }, \
|
|
|
|
//
|
|
// AH=11h
|
|
//
|
|
{ FBTSGetPlatformInfo, "S11Kn_GetModelName0", KernelFbtsGetModelName }, \
|
|
{ FBTSGetPlatformInfo, "S11Kn_GModelVersion", KernelFbtsGetModelVersion }, \
|
|
{ FBTSGetPlatformInfo, "S11OemFbtsApCheck00", OemFbtsApCheck }, \
|
|
{ FBTSGetPlatformInfo, "S11Kn_UpExtPlatform", KernelFbtsUpdateExtendPlatform}, \
|
|
|
|
//
|
|
// AH=12h
|
|
//
|
|
{ FBTSGetPlatformRomMap, "S12Kn_ProtectRomMap", KernelFbtsUpdateProtectRomMap }, \
|
|
{ FBTSGetPlatformRomMap, "S12Kn_PrivateRomMap", KernelFbtsUpdatePrivateRomMap }, \
|
|
{ FBTSGetPlatformRomMap, "S12Cs_PlatformRomMp", ChipsetFbtsGetPlatformRomMap }, \
|
|
{ FBTSGetPlatformRomMap, "S12OemPlatformRomMp", OemGetPlatformRomMap }, \
|
|
|
|
//
|
|
// AH=13h
|
|
//
|
|
{ FBTSGetFlashPartInfo, "S13Kn_FlashPartInfo", KernelFbtsGetFlashPartInfo }, \
|
|
|
|
//
|
|
// AH=14h
|
|
//
|
|
{ FBTSRead, "S14Cs_DoBeforeRead0", ChipsetFbtsDoBeforeReadProcess }, \
|
|
{ FBTSRead, "S14Kn_FbtsReadProce", KernelFbtsRead }, \
|
|
{ FBTSRead, "S14Cs_DoAfterRead00", ChipsetFbtsDoAfterReadProcess }, \
|
|
|
|
//
|
|
// AH=15h
|
|
//
|
|
{ FBTSWrite, "S15Cs_DoBeforeWrite", ChipsetFbtsDoBeforeWriteProcess }, \
|
|
{ FBTSWrite, "S15Kn_FbtsWriteProc", KernelFbtsWrite }, \
|
|
{ FBTSWrite, "S15Cs_DoAfterWrite0", ChipsetFbtsDoAfterWriteProcess }, \
|
|
|
|
//
|
|
// AH=16h
|
|
//
|
|
{ FBTSComplete, "S16Cs_CApTerminalte", ChipsetFbtsCompleteApTerminated}, \
|
|
{ FBTSComplete, "S16Cs_CNormalFlash0", ChipsetFbtsCompleteNormalFlash }, \
|
|
{ FBTSComplete, "S16Cs_CPartialFlash", ChipsetFbtsCompletePartialFlash}, \
|
|
{ FBTSComplete, "S16Kn_PurifyVariabl", KernelFbtsPurifyVariable }, \
|
|
{ FBTSComplete, "S16Cs_FbtsComplete0", ChipsetFbtsComplete }, \
|
|
{ FBTSComplete, "S16Cs_FbtsReboot000", ChipsetFbtsReboot }, \
|
|
{ FBTSComplete, "S16Cs_FbtsShutDown0", ChipsetFbtsShutDown }, \
|
|
{ FBTSComplete, "S16Cs_FbtsDoNothing", ChipsetFbtsDoNothing }, \
|
|
|
|
//
|
|
// AH=1Bh
|
|
//
|
|
{ FBTSSkipMcCheckAndBinaryTrans, "S1BKn_SkipMcCheck00", KernelSkipMcCheckAndBinaryTrans }, \
|
|
|
|
//
|
|
// AH=1Eh
|
|
//
|
|
{ FBTSGetWholeBiosRomMap, "S1EKn_WholeBiosRomp", KernelFbtsGetWholeBiosRomMap }, \
|
|
{ FBTSGetWholeBiosRomMap, "S1EOemWholeBiosRomp", OemFbtsGetWholeBiosRomMap }, \
|
|
|
|
//
|
|
// AH=1Fh
|
|
//
|
|
{ FBTSApHookPoint, "S1FKn_ApHookforBios", OemFbtsApHookForBios}
|
|
};
|
|
|
|
STATIC
|
|
FLASH_MAP_MAPPING_TABLE mFlashMapTypeMappingTable[] = {
|
|
{FbtsRomMapPei, EFI_FLASH_AREA_RECOVERY_BIOS},
|
|
{FbtsRomMapCpuMicrocode, EFI_FLASH_AREA_CPU_MICROCODE},
|
|
{FbtsRomMapNVRam, EFI_FLASH_AREA_EFI_VARIABLES},
|
|
{FbtsRomMapDxe, EFI_FLASH_AREA_MAIN_BIOS},
|
|
{FbtsRomMapEc, EFI_FLASH_AREA_FV_EC},
|
|
{FbtsRomMapNvStorage, EFI_FLASH_AREA_GUID_DEFINED},
|
|
{FbtsRomMapFtwBackup, EFI_FLASH_AREA_FTW_BACKUP},
|
|
{FbtsRomMapFtwState, EFI_FLASH_AREA_FTW_STATE},
|
|
{FbtsRomMapSmbiosLog, EFI_FLASH_AREA_SMBIOS_LOG},
|
|
{FbtsRomMapOemData, EFI_FLASH_AREA_OEM_BINARY},
|
|
{FbtsRomMapGpnv, EFI_FLASH_AREA_GPNV},
|
|
{FbtsRomMapDmiFru, EFI_FLASH_AREA_DMI_FRU},
|
|
{FbtsRomMapPalB, EFI_FLASH_AREA_PAL_B},
|
|
{FbtsRomMapMcaLog, EFI_FLASH_AREA_MCA_LOG},
|
|
{FbtsRomMapPassword, EFI_FLASH_AREA_RESERVED_03},
|
|
{FbtsRomMapOemNvs, EFI_FLASH_AREA_RESERVED_04},
|
|
{FbtsRomMapReserved07, EFI_FLASH_AREA_RESERVED_07},
|
|
{FbtsRomMapReserved08, EFI_FLASH_AREA_RESERVED_08},
|
|
{FbtsRomMapReserved0A, EFI_FLASH_AREA_RESERVED_0A},
|
|
{FbtsRomMapUnused, EFI_FLASH_AREA_UNUSED},
|
|
{FbtsRomMapUndefined, EFI_FLASH_AREA_GUID_DEFINED},
|
|
{FbtsRomMapFactoryCopy, EFI_FLASH_AREA_RESERVED_09}, // factory default
|
|
{FbtsRomMapEos, FbtsRomMapEos} //End of table
|
|
};
|
|
EFI_STATUS
|
|
UpdateOemFlashMap (
|
|
VOID
|
|
);
|
|
/**
|
|
Fill platform protect ROM map information to module ROM map buffer.
|
|
|
|
@retval EFI_SUCCESS Set platform protect ROM map information to module ROM map buffer successful.
|
|
@retval EFI_UNSUPPORTED Module ROM map buffer is full.
|
|
*/
|
|
EFI_STATUS
|
|
FillPlatformRomMapBuffer (
|
|
IN UINT8 Type,
|
|
IN UINT32 Address,
|
|
IN UINT32 Length,
|
|
IN UINT8 Entry
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ConvertedAddress;
|
|
|
|
if (Entry >= (sizeof (FBTS_PLATFORM_ROM_MAP_BUFFER) / sizeof (FBTS_PLATFORM_ROM_MAP))) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (Type != FbtsRomMapEos) {
|
|
Status = mSmmFwBlockService->ConvertToSpiAddress(
|
|
mSmmFwBlockService,
|
|
(UINTN) Address,
|
|
&ConvertedAddress
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Address = (UINT32) ConvertedAddress;
|
|
}
|
|
}
|
|
|
|
mRomMapBuffer.PlatFormRomMap[Entry].Type = Type;
|
|
mRomMapBuffer.PlatFormRomMap[Entry].Address = Address;
|
|
mRomMapBuffer.PlatFormRomMap[Entry].Length = Length;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Fill platform private ROM map information to module ROM map buffer.
|
|
|
|
@retval EFI_SUCCESS Set platform ROM map information to module ROM map buffer successful.
|
|
@retval EFI_UNSUPPORTED Module ROM map buffer is full.
|
|
*/
|
|
EFI_STATUS
|
|
FillPlatformPrivateRomMapBuffer (
|
|
IN UINT32 Address,
|
|
IN UINT32 Length,
|
|
IN UINT8 Entry
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ConvertedAddress;
|
|
|
|
if (Entry >= (sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER) / sizeof (FBTS_PLATFORM_PRIVATE_ROM))) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (Address != FbtsRomMapEos) {
|
|
Status = mSmmFwBlockService->ConvertToSpiAddress(
|
|
mSmmFwBlockService,
|
|
(UINTN) Address,
|
|
&ConvertedAddress
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Address = (UINT32) ConvertedAddress;
|
|
}
|
|
}
|
|
mPrivateRomMapBuffer.PlatFormRomMap[Entry].LinearAddress = Address;
|
|
mPrivateRomMapBuffer.PlatFormRomMap[Entry].Size = Length;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get IHISI status.translated from EFI status
|
|
|
|
@param[in] Status EFI_STATUS
|
|
|
|
@return UINT32 IHISI status
|
|
**/
|
|
UINT32
|
|
GetFbtsIhisiStatus (
|
|
EFI_STATUS Status
|
|
)
|
|
{
|
|
switch (Status) {
|
|
case EFI_SUCCESS:
|
|
return (UINT32) IHISI_SUCCESS;
|
|
break;
|
|
|
|
case EFI_BUFFER_TOO_SMALL:
|
|
return (UINT32) IHISI_OB_LEN_TOO_SMALL;
|
|
break;
|
|
|
|
case EFI_UNSUPPORTED:
|
|
return (UINT32) IHISI_UNSUPPORTED_FUNCTION;
|
|
break;
|
|
|
|
default:
|
|
return (UINT32) IHISI_FBTS_PERMISSION_DENIED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Check if this variable should be deleted. Search from the preserved list.
|
|
|
|
@param[in] VariableName The variable name.
|
|
@param[in] VendorGuid The variable GUID.
|
|
@param[in] VariablePreservedTablePtr The preserved table.
|
|
@param[in] IsKeepVariableInList This flag determines the property of the preserved table.
|
|
|
|
@retval TRUE This variable should be deleteted
|
|
@retval FALSE Keep this variable
|
|
**/
|
|
BOOLEAN
|
|
CheckVariableDelete (
|
|
IN CHAR16 *VariableName,
|
|
IN EFI_GUID *VendorGuid,
|
|
IN PRESERVED_VARIABLE_TABLE *VariablePreservedTablePtr,
|
|
IN BOOLEAN IsKeepVariableInList
|
|
)
|
|
{
|
|
UINTN Index;
|
|
BOOLEAN IsVariableFound;
|
|
|
|
//
|
|
// According to logo requirement, should preserve all UEFI variables with VendorGuid
|
|
// {77fa9abd-0359-4d32-bd60-28f4e78f784b}
|
|
//
|
|
if (CompareGuid (VendorGuid, &mDefaultPreservedVendorGuid)) {
|
|
return FALSE;
|
|
}
|
|
//
|
|
// Check if the variable is in the preserved list or not.
|
|
//
|
|
Index = 0;
|
|
IsVariableFound = FALSE;
|
|
while (VariablePreservedTablePtr[Index].VariableName != NULL) {
|
|
if ((CompareGuid (VendorGuid, &VariablePreservedTablePtr[Index].VendorGuid)) &&
|
|
(StrCmp (VariableName, VariablePreservedTablePtr[Index].VariableName) == 0)) {
|
|
IsVariableFound = TRUE;
|
|
break;
|
|
}
|
|
if ((CompareGuid (&VariablePreservedTablePtr[Index].VendorGuid, &mPreservedVariableTable2OtherAllGuid)) &&
|
|
(StrCmp (VariablePreservedTablePtr[Index].VariableName, L"PreservedTable2OtherAllName") != 0)) {
|
|
//
|
|
// Only check VariableName
|
|
//
|
|
if ((StrCmp (VariableName, VariablePreservedTablePtr[Index].VariableName) == 0)) {
|
|
IsVariableFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((!CompareGuid (&VariablePreservedTablePtr[Index].VendorGuid, &mPreservedVariableTable2OtherAllGuid)) &&
|
|
(StrCmp (VariablePreservedTablePtr[Index].VariableName, L"PreservedTable2OtherAllName") == 0)) {
|
|
//
|
|
// Only check VendorGUID
|
|
//
|
|
if(CompareGuid (VendorGuid, &VariablePreservedTablePtr[Index].VendorGuid)) {
|
|
IsVariableFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
Index++;
|
|
}
|
|
|
|
//
|
|
// IsKeepVariableInList | IsVariableFound | result
|
|
// ------------------------------------------------
|
|
// TRUE | TRUE | Keep
|
|
// TRUE | FALSE | Delete
|
|
// FALSE | TRUE | Delete
|
|
// FALSE | FALSE | Keep
|
|
//
|
|
if (IsKeepVariableInList != IsVariableFound) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Use variable service to get the next variable. If the variable name size is not enough, re-allocate memory for it.
|
|
return the memory buffer size to "MaxVariableNameSize".
|
|
|
|
@param[in, out] VariableSize The variable size.
|
|
@param[in, out] VariableName The variable name.
|
|
@param[in, out] VendorGuid The variable GUID.
|
|
@param[in, out] MaxVariableNameSize The max variable name size. Will allocate memory according to this size.
|
|
|
|
@retval EFI_INVALID_PARAMETER Invalid parameters
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory
|
|
@retval EFI_SUCCESS Successfully
|
|
**/
|
|
EFI_STATUS
|
|
RelocateNextVariableName (
|
|
IN OUT UINTN *VariableSize,
|
|
IN OUT CHAR16 **VariableName,
|
|
IN OUT EFI_GUID *VendorGuid,
|
|
IN OUT UINTN *MaxVariableNameSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_GUID NextVendorGuid;
|
|
UINTN NextVariableSize;
|
|
CHAR16 *NextVariableName;
|
|
|
|
if (VariableSize == NULL || VariableName == NULL || VendorGuid == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
NextVariableName = *VariableName;
|
|
CopyGuid (&NextVendorGuid, VendorGuid);
|
|
if (*VariableName == NULL) {
|
|
NextVariableName = AllocateZeroPool (*MaxVariableNameSize);
|
|
if (NextVariableName == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
}
|
|
|
|
NextVariableSize = *MaxVariableNameSize;
|
|
Status = CommonGetNextVariableName (&NextVariableSize, NextVariableName, &NextVendorGuid);
|
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
|
NextVariableName = ReallocatePool (*MaxVariableNameSize, NextVariableSize, NextVariableName);
|
|
if (NextVariableName == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
*MaxVariableNameSize = NextVariableSize;
|
|
Status = CommonGetNextVariableName (&NextVariableSize, NextVariableName, &NextVendorGuid);
|
|
}
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
*VariableSize = NextVariableSize;
|
|
*VariableName = NextVariableName;
|
|
CopyGuid (VendorGuid, &NextVendorGuid);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
UINTN
|
|
GetNumberOfVariable (
|
|
IN UINT8 *TablePtr,
|
|
IN BOOLEAN NewTableFlag
|
|
)
|
|
{
|
|
UINTN NumberOfVariable;
|
|
|
|
NumberOfVariable = 0;
|
|
while (!IsZeroGuid ((EFI_GUID *) TablePtr)) {
|
|
TablePtr += sizeof (EFI_GUID);
|
|
if (NewTableFlag) {
|
|
TablePtr += sizeof (BOOLEAN);
|
|
}
|
|
NumberOfVariable++;
|
|
TablePtr += StrSize ((CHAR16 *) TablePtr);
|
|
}
|
|
|
|
//
|
|
// Add one for the end of data
|
|
//
|
|
NumberOfVariable++;
|
|
|
|
return NumberOfVariable;
|
|
}
|
|
/**
|
|
Get corresponding IHISI area type by flash area type accordingly.
|
|
|
|
@param[in] FlashAreaType Flash area type.
|
|
|
|
@return UINT8 Corresponding IHISI area type.
|
|
**/
|
|
STATIC
|
|
UINT8
|
|
GetMappingType (
|
|
UINT8 FlashAreaType
|
|
)
|
|
{
|
|
UINTN Index = 0;
|
|
|
|
while (mFlashMapTypeMappingTable[Index].FlashAreaType != FbtsRomMapEos) {
|
|
if (FlashAreaType == mFlashMapTypeMappingTable[Index].FlashAreaType) {
|
|
return mFlashMapTypeMappingTable[Index].IhisiAreaType;
|
|
} else {
|
|
Index++;
|
|
}
|
|
}
|
|
|
|
return FbtsRomMapUndefined;
|
|
}
|
|
|
|
|
|
/**
|
|
Get flash map from HOB.
|
|
|
|
@retval EFI_SUCCESS Get flash map from HOB successful.
|
|
@return Others Any error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
GetFlashMapByHob (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Index;
|
|
VOID *HobList;
|
|
EFI_FLASH_MAP_ENTRY_DATA *FlashMapEntryData;
|
|
|
|
HobList = GetHobList ();
|
|
ASSERT (HobList != NULL);
|
|
|
|
Index = 0;
|
|
do {
|
|
HobList = GetNextGuidHob (&gEfiFlashMapHobGuid, HobList);
|
|
if (HobList == NULL) {
|
|
//
|
|
// Fill end of structure ROM map if all of flash map HOBs have been filled to ROM map buffer.
|
|
//
|
|
Status = FillPlatformRomMapBuffer ((UINT8)FbtsRomMapEos, 0, 0, Index);
|
|
break;
|
|
}
|
|
|
|
FlashMapEntryData = (EFI_FLASH_MAP_ENTRY_DATA *) HobList;
|
|
Status = FillPlatformRomMapBuffer (GetMappingType (
|
|
FlashMapEntryData->AreaType),
|
|
(UINT32) (FlashMapEntryData->Entries[0].Base),
|
|
(UINT32) (FlashMapEntryData->Entries[0].Length),
|
|
Index
|
|
);
|
|
Index++;
|
|
} while (!EFI_ERROR (Status));
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Get the default preserved variable table from PCD.
|
|
|
|
@param[out] TablePtr The pointer to the default table.
|
|
@param[out] TableNewType The flag is new or old structure of PCD preserved table.
|
|
|
|
@return IHISI_SUCCESS Get default table successfully.
|
|
@return IHISI_INVALID_PARAMETER TablePtr or TableNewType is NULL.
|
|
@return IHISI_OUT_OF_RESOURCES Allocate memory failed.
|
|
**/
|
|
STATIC
|
|
UINT32
|
|
GetDefaultTable (
|
|
OUT VOID **TablePtr,
|
|
OUT BOOLEAN *TableNewType
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINTN NumberOfVariable;
|
|
UINT8 TempValue;
|
|
UINT8 *StringPtr;
|
|
PRESERVED_VARIABLE_TABLE *TempTablePtr;
|
|
PRESERVED_VARIABLE_TABLE_2 *TempTablePtr2;
|
|
|
|
if (TablePtr == NULL || TableNewType == NULL) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
StringPtr = NULL;
|
|
TempTablePtr = NULL;
|
|
TempTablePtr2 = NULL;
|
|
//
|
|
// Check the table is new or old structure
|
|
//
|
|
*TablePtr = (VOID *) PcdGetPtr (PcdDefaultPreservedVariableList);
|
|
StringPtr = (UINT8 *) *TablePtr;
|
|
StringPtr += sizeof (EFI_GUID);
|
|
//
|
|
// Assume the table is new, check the DeleteVariable value
|
|
//
|
|
TempValue = (UINT8) (*StringPtr);
|
|
|
|
if ((TempValue == 0x00) || (TempValue == 0x01)) {
|
|
//
|
|
// Process new structure
|
|
//
|
|
if (!IsZeroGuid ((EFI_GUID *) *TablePtr)) {
|
|
*TableNewType = TRUE;
|
|
NumberOfVariable = GetNumberOfVariable ((UINT8 *) *TablePtr, TRUE);
|
|
TempTablePtr2 = AllocatePool (NumberOfVariable * sizeof (PRESERVED_VARIABLE_TABLE_2));
|
|
if (TempTablePtr2 == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
StringPtr = (UINT8 *) *TablePtr;
|
|
for (Index = 0; (!IsZeroGuid ((EFI_GUID *) StringPtr)); Index++) {
|
|
CopyMem (&TempTablePtr2[Index].VendorGuid, StringPtr, sizeof (EFI_GUID));
|
|
|
|
StringPtr += sizeof (EFI_GUID);
|
|
TempTablePtr2[Index].DeleteVariable = (UINT8) (*StringPtr);
|
|
|
|
StringPtr += sizeof (BOOLEAN);
|
|
TempTablePtr2[Index].VariableName = (CHAR16 *) StringPtr;
|
|
//
|
|
// Go to the next variable.
|
|
//
|
|
StringPtr += StrSize (TempTablePtr2[Index].VariableName);
|
|
}
|
|
//
|
|
// Fill end of the table
|
|
//
|
|
CopyMem (&TempTablePtr2[Index].VendorGuid, StringPtr, sizeof (EFI_GUID));
|
|
TempTablePtr2[Index].DeleteVariable = FALSE;
|
|
TempTablePtr2[Index].VariableName = NULL;
|
|
}
|
|
*TablePtr = TempTablePtr2;
|
|
} else {
|
|
//
|
|
// Process old structure
|
|
//
|
|
if (!IsZeroGuid ((EFI_GUID *) *TablePtr)) {
|
|
*TableNewType = FALSE;
|
|
NumberOfVariable = GetNumberOfVariable ((UINT8 *) *TablePtr, FALSE);
|
|
TempTablePtr = AllocatePool (NumberOfVariable * sizeof (PRESERVED_VARIABLE_TABLE));
|
|
if (TempTablePtr == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
StringPtr = (UINT8 *) *TablePtr;
|
|
for (Index = 0; (!IsZeroGuid ( (EFI_GUID *) StringPtr)); Index++) {
|
|
CopyMem (&TempTablePtr[Index].VendorGuid, StringPtr, sizeof (EFI_GUID));
|
|
|
|
StringPtr += sizeof (EFI_GUID);
|
|
TempTablePtr[Index].VariableName = (CHAR16 *) StringPtr;
|
|
//
|
|
// Go to the next variable.
|
|
//
|
|
StringPtr += StrSize (TempTablePtr[Index].VariableName);
|
|
}
|
|
//
|
|
// Fill end of the table
|
|
//
|
|
CopyMem (&TempTablePtr[Index].VendorGuid, StringPtr, sizeof (EFI_GUID));
|
|
TempTablePtr[Index].VariableName = NULL;
|
|
}
|
|
*TablePtr = TempTablePtr;
|
|
}
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Check target variable repeated of the VariablePreservedTable2, the range is from Index 0 to specific target index.
|
|
|
|
@param[in] VariablePreservedTable2 The pointer to the new structure table
|
|
@param[in] TargetIndex The specific index of target variable in VariablePreservedTable2
|
|
@param[out] IsRepeated This flag determines the target variable is repeated or not from Index 0 to targetIndex
|
|
|
|
**/
|
|
VOID
|
|
IsVariableRepeatedOfPreservedTable2(
|
|
IN PRESERVED_VARIABLE_TABLE_2 *VariablePreservedTable2,
|
|
IN UINTN TargetIndex,
|
|
OUT BOOLEAN *IsRepeated
|
|
)
|
|
{
|
|
UINTN TempIndex;
|
|
//
|
|
// Compare from index 0 to specific target index
|
|
//
|
|
*IsRepeated = FALSE;
|
|
for (TempIndex=0; TempIndex < TargetIndex; TempIndex++) {
|
|
if (CompareGuid(&VariablePreservedTable2[TargetIndex].VendorGuid, &VariablePreservedTable2[TempIndex].VendorGuid)) {
|
|
if ((StrCmp(VariablePreservedTable2[TargetIndex].VariableName, VariablePreservedTable2[TempIndex].VariableName) == 0) ||
|
|
(StrCmp(VariablePreservedTable2[TempIndex].VariableName, L"PreservedTable2OtherAllName") == 0)) {
|
|
*IsRepeated = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (StrCmp(VariablePreservedTable2[TargetIndex].VariableName, VariablePreservedTable2[TempIndex].VariableName) == 0) {
|
|
if (CompareGuid(&VariablePreservedTable2[TempIndex].VendorGuid, &mPreservedVariableTable2OtherAllGuid)) {
|
|
*IsRepeated = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((StrCmp(VariablePreservedTable2[TempIndex].VariableName, L"PreservedTable2OtherAllName") == 0) &&
|
|
(CompareGuid(&VariablePreservedTable2[TempIndex].VendorGuid, &mPreservedVariableTable2OtherAllGuid))) {
|
|
*IsRepeated = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Parse the new preserved variable table to old structure.
|
|
|
|
@param[in] VariablePreservedTable2 The pointer to the new structure table
|
|
@param[out] VariablePreservedTable The pointer to the old structure table
|
|
@param[out] IsKeepVariableInList This flag determines the property of the old structure preserved table
|
|
|
|
**/
|
|
VOID
|
|
ParsePreservedTable(
|
|
IN PRESERVED_VARIABLE_TABLE_2 *VariablePreservedTable2,
|
|
OUT PRESERVED_VARIABLE_TABLE **VariablePreservedTable,
|
|
OUT BOOLEAN *IsKeepVariableInList
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINTN Index1;
|
|
UINTN NumberOfVariable;
|
|
BOOLEAN DeleteVariable;
|
|
BOOLEAN IsRepeated;
|
|
PRESERVED_VARIABLE_TABLE *TempBuffer;
|
|
|
|
//
|
|
// Get the DeleteVariable when below two conditions are both true,
|
|
// GUID = {0xffffffff, 0xffff, 0xffff, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff}
|
|
// Name = PreservedTable2OtherAllName
|
|
//
|
|
DeleteVariable = FALSE;
|
|
for (Index=0; VariablePreservedTable2[Index].VariableName != NULL; Index++) {
|
|
if (CompareGuid (&VariablePreservedTable2[Index].VendorGuid, &mPreservedVariableTable2OtherAllGuid) &&
|
|
(StrCmp (VariablePreservedTable2[Index].VariableName, L"PreservedTable2OtherAllName") == 0)) {
|
|
DeleteVariable = VariablePreservedTable2[Index].DeleteVariable;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Index = 0;
|
|
while(VariablePreservedTable2[Index].VariableName != NULL) {
|
|
Index++;
|
|
}
|
|
NumberOfVariable = (Index + 1);
|
|
TempBuffer = AllocateZeroPool (sizeof (PRESERVED_VARIABLE_TABLE) * NumberOfVariable);
|
|
if (TempBuffer == NULL) {
|
|
*VariablePreservedTable = NULL;
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Collect declarations if there DeleteVariable are different and also skip repeated of declarations
|
|
//
|
|
Index1 = 0;
|
|
for (Index=0; VariablePreservedTable2[Index].VariableName != NULL; Index++) {
|
|
if ((!CompareGuid (&VariablePreservedTable2[Index].VendorGuid, &mPreservedVariableTable2OtherAllGuid)) ||
|
|
(StrCmp (VariablePreservedTable2[Index].VariableName, L"PreservedTable2OtherAllName") != 0)) {
|
|
//
|
|
// Check target variable repeated of the VariablePreservedTable2, the range is from index 0 to specific target index.
|
|
//
|
|
IsVariableRepeatedOfPreservedTable2(VariablePreservedTable2, Index, &IsRepeated);
|
|
if ((IsRepeated != TRUE) && (VariablePreservedTable2[Index].DeleteVariable != DeleteVariable)) {
|
|
TempBuffer[Index1].VariableName = AllocateCopyPool ( StrSize ( (CHAR16 *) VariablePreservedTable2[Index].VariableName), VariablePreservedTable2[Index].VariableName);
|
|
CopyMem (&TempBuffer[Index1].VendorGuid, &VariablePreservedTable2[Index].VendorGuid, sizeof (EFI_GUID));
|
|
Index1++;
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// Fill the end of table
|
|
//
|
|
TempBuffer[Index1].VariableName = NULL;
|
|
CopyMem (&TempBuffer[Index1].VendorGuid, &VariablePreservedTable2[Index].VendorGuid, sizeof (EFI_GUID));
|
|
|
|
*IsKeepVariableInList = DeleteVariable;
|
|
*VariablePreservedTable = TempBuffer;
|
|
}
|
|
|
|
/**
|
|
Purify the variables if needed. If there is NO OemService "OemSvcVariablePreservedTable",
|
|
do nothing in this function.
|
|
|
|
@retval IHISI_SUCCESS Success
|
|
@retval IHISI_UNSUPPORTED_FUNCTION there is no SmmVariable service
|
|
@retval IHISI_OUT_OF_RESOURCES not enough memory
|
|
|
|
**/
|
|
UINT32
|
|
PurifyVariable (
|
|
VOID
|
|
)
|
|
{
|
|
UINT32 Status;
|
|
EFI_STATUS EfiStatus;
|
|
EFI_STATUS OemSVc2Status;
|
|
EFI_STATUS OemSVcStatus;
|
|
EFI_GUID VendorGuid;
|
|
EFI_GUID NextVendorGuid;
|
|
UINTN VariableNameSize;
|
|
UINTN MaxVariableNameSize;
|
|
BOOLEAN IsKeepVariableInList;
|
|
BOOLEAN TableNewType;
|
|
UINTN NextVariableNameSize;
|
|
CHAR16 *VariableName;
|
|
CHAR16 *NextVariableName;
|
|
PRESERVED_VARIABLE_TABLE *VariablePreservedTablePtr;
|
|
PRESERVED_VARIABLE_TABLE_2 *VariablePreservedTablePtr2;
|
|
VOID *VoidTempPtr;
|
|
|
|
//
|
|
// Get default preserved variable table from PCD, and check the table is new or old structure
|
|
//
|
|
IsKeepVariableInList = PcdGetBool (PcdKeepVariableInList);
|
|
TableNewType = FALSE;
|
|
VariablePreservedTablePtr = NULL;
|
|
VariablePreservedTablePtr2 = NULL;
|
|
Status = GetDefaultTable (&VoidTempPtr, &TableNewType);
|
|
if (Status != IHISI_SUCCESS) {
|
|
return Status;
|
|
}
|
|
|
|
if (TableNewType == TRUE) {
|
|
//
|
|
// The data is new structure from PCD
|
|
//
|
|
VariablePreservedTablePtr2 = (PRESERVED_VARIABLE_TABLE_2 *) VoidTempPtr;
|
|
} else {
|
|
//
|
|
// The data is old structure from PCD
|
|
//
|
|
VariablePreservedTablePtr = (PRESERVED_VARIABLE_TABLE *) VoidTempPtr;
|
|
}
|
|
|
|
//
|
|
// Get variable preserved table from OemServices, the oemServices only support new structure
|
|
//
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcVariablePreservedTable2 \n"));
|
|
OemSVc2Status = OemSvcVariablePreservedTable2 (
|
|
&VariablePreservedTablePtr2
|
|
);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcVariablePreservedTable2 Status: %r\n", OemSVc2Status));
|
|
if (!EFI_ERROR (OemSVc2Status)) {
|
|
return IHISI_SUCCESS;
|
|
}
|
|
//
|
|
// Check old table OemSVCVariablePreserved If OemSvcVariablePreservedTable2 return EFI_UNSUPPORTED
|
|
//
|
|
OemSVcStatus = EFI_SUCCESS;
|
|
if (OemSVc2Status == EFI_UNSUPPORTED) {
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcVariablePreservedTable \n"));
|
|
OemSVcStatus = OemSvcVariablePreservedTable (
|
|
&VariablePreservedTablePtr,
|
|
&IsKeepVariableInList
|
|
);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcVariablePreservedTable Status: %r\n", OemSVcStatus));
|
|
if (!EFI_ERROR (OemSVcStatus)) {
|
|
return IHISI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if ((OemSVc2Status == RETURN_MEDIA_CHANGED) ||
|
|
((OemSVc2Status == RETURN_UNSUPPORTED) && (OemSVcStatus == RETURN_UNSUPPORTED) && (TableNewType == TRUE))) {
|
|
if (VariablePreservedTablePtr2 == NULL) {
|
|
//
|
|
// This OemService does not exist, so do nothing.
|
|
//
|
|
return IHISI_SUCCESS;
|
|
}
|
|
//
|
|
// Parse data from new to old structure
|
|
//
|
|
ParsePreservedTable (VariablePreservedTablePtr2, &VariablePreservedTablePtr, &IsKeepVariableInList);
|
|
}
|
|
|
|
if (VariablePreservedTablePtr == NULL) {
|
|
//
|
|
// This OemService does not exist, so do nothing.
|
|
//
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
if ( (!IsKeepVariableInList) && (VariablePreservedTablePtr->VariableName == NULL)) {
|
|
//
|
|
// Clear an empty table, so do nothing.
|
|
//
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
NextVariableName = NULL;
|
|
VariableNameSize = sizeof (UINT8);
|
|
VariableName = AllocatePool (VariableNameSize);
|
|
if (VariableName == NULL) {
|
|
Status = IHISI_OUT_OF_RESOURCES;
|
|
goto Done;
|
|
}
|
|
|
|
MaxVariableNameSize = DEFAULT_VARIABLE_NAME_SIZE;
|
|
EfiStatus = RelocateNextVariableName (&NextVariableNameSize, &NextVariableName, &NextVendorGuid, &MaxVariableNameSize);
|
|
|
|
while (!EFI_ERROR (EfiStatus)) {
|
|
if (VariableNameSize < MaxVariableNameSize) {
|
|
VariableName = ReallocatePool (VariableNameSize, MaxVariableNameSize, VariableName);
|
|
VariableNameSize = MaxVariableNameSize;
|
|
if (VariableName == NULL) {
|
|
Status = IHISI_OUT_OF_RESOURCES;
|
|
goto Done;
|
|
}
|
|
}
|
|
CopyMem (VariableName, NextVariableName, NextVariableNameSize);
|
|
CopyGuid (&VendorGuid, &NextVendorGuid);
|
|
EfiStatus = RelocateNextVariableName (&NextVariableNameSize, &NextVariableName, &NextVendorGuid, &MaxVariableNameSize);
|
|
if (EfiStatus == EFI_OUT_OF_RESOURCES) {
|
|
Status = IHISI_OUT_OF_RESOURCES;
|
|
goto Done;
|
|
}
|
|
|
|
if (CheckVariableDelete (VariableName, &VendorGuid, VariablePreservedTablePtr, IsKeepVariableInList)) {
|
|
CommonSetVariable (VariableName, &VendorGuid, 0, 0, NULL);
|
|
}
|
|
}
|
|
Status = IHISI_SUCCESS;
|
|
|
|
Done:
|
|
|
|
if (VariableName != NULL) {
|
|
FreePool (VariableName);
|
|
}
|
|
|
|
if (NextVariableName != NULL) {
|
|
FreePool (NextVariableName);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Swaps the boot block and backup block, or swaps them back.
|
|
|
|
@param[in] NewSwapState True to swap real boot block and backup block, False to swap them back.
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval Others Operation was unsuccessful.
|
|
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
InternalSetSwapState (
|
|
IN BOOLEAN NewSwapState
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS LockCapStatus;
|
|
EFI_SWAP_LOCK_CAPABILITY LockCapability;
|
|
|
|
if (mSwapAddressRange == NULL) {
|
|
Status = gSmst->SmmLocateProtocol (
|
|
&gEfiSmmSwapAddressRangeProtocolGuid,
|
|
NULL,
|
|
(VOID **)&mSwapAddressRange
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
LockCapStatus = mSwapAddressRange->GetSwapLockCapability (mSwapAddressRange, &LockCapability);
|
|
if (!EFI_ERROR (LockCapStatus)) {
|
|
mSwapAddressRange->SetSwapLock (mSwapAddressRange, LockCapability, FALSE);
|
|
}
|
|
Status = mSwapAddressRange->SetSwapState (mSwapAddressRange, NewSwapState);
|
|
if (!EFI_ERROR (LockCapStatus)) {
|
|
mSwapAddressRange->SetSwapLock (mSwapAddressRange, LockCapability, TRUE);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Checks if the boot block and backup block has been swapped.
|
|
|
|
@param[out] SwapState True if the boot block and backup block has been swapped.
|
|
False if the boot block and backup block has not been swapped.
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval Others Operation was unsuccessful.
|
|
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
InternalGetSwapState (
|
|
OUT BOOLEAN *SwapState
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (mSwapAddressRange == NULL) {
|
|
Status = gSmst->SmmLocateProtocol (
|
|
&gEfiSmmSwapAddressRangeProtocolGuid,
|
|
NULL,
|
|
(VOID **)&mSwapAddressRange
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
return mSwapAddressRange->GetSwapState (mSwapAddressRange, SwapState);
|
|
}
|
|
|
|
/**
|
|
AH=1Fh, AP Hook Point for bios update sequence.
|
|
|
|
@param[in] ApState The current AP state.
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval Others Operation was unsuccessful.
|
|
|
|
**/
|
|
STATIC
|
|
VOID
|
|
FbtsApHookForUpdateSequence (
|
|
IN UINT8 ApState
|
|
)
|
|
{
|
|
if (!mUpdateSequenceEnabled) {
|
|
return;
|
|
}
|
|
|
|
if (IsFirmwareUpdateResiliencySupported ()) {
|
|
//
|
|
// PBB->SBB
|
|
//
|
|
switch (ApState) {
|
|
|
|
case 0x10:
|
|
InternalSetSwapState (TRUE); // Enable TopSwap before flashing PBB
|
|
SetFirmwareUpdateProgress (FlashPbb);
|
|
break;
|
|
|
|
case 0x11:
|
|
InternalSetSwapState (FALSE); // Disable TopSwap after PBB flashed
|
|
break;
|
|
|
|
case 0x12:
|
|
SetFirmwareUpdateProgress (FlashSbb);
|
|
break;
|
|
|
|
case 0x13:
|
|
SetFirmwareUpdateProgress (FlashResiliency);
|
|
break;
|
|
|
|
case 0x00:
|
|
if (!IsFirmwareUpdateResiliencyEnabled ()) {
|
|
InternalSetSwapState (FALSE);
|
|
ClearFirmwareUpdateProgress ();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
//
|
|
// PBBR->PBB->SBB
|
|
//
|
|
switch (ApState) {
|
|
|
|
case 0x10:
|
|
SetFirmwareUpdateProgress (FlashPbbR);
|
|
break;
|
|
|
|
case 0x12:
|
|
InternalSetSwapState (TRUE); // Enable TopSwap before flashing PBB
|
|
SetFirmwareUpdateProgress (FlashPbb);
|
|
break;
|
|
|
|
case 0x13:
|
|
InternalSetSwapState (FALSE); // Disable TopSwap after PBB flashed
|
|
break;
|
|
|
|
case 0x14:
|
|
SetFirmwareUpdateProgress (FlashSbb);
|
|
break;
|
|
|
|
case 0x15:
|
|
// Update complete. Clear progress.
|
|
ClearFirmwareUpdateProgress ();
|
|
break;
|
|
|
|
case 0x00:
|
|
InternalSetSwapState (FALSE);
|
|
ClearFirmwareUpdateProgress ();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Get rom size from block map.
|
|
|
|
@param[out] RomSize ROM size.
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval Others Operation was unsuccessful.
|
|
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
GetRomSizeFromBlockMap (
|
|
OUT UINT32 *RomSize
|
|
)
|
|
{
|
|
FLASH_DEVICE *Buffer;
|
|
EFI_STATUS Status;
|
|
UINT16 BlockMap[3];
|
|
UINT8 SpiFlashNumber;
|
|
|
|
Buffer = AllocatePool (sizeof (FLASH_DEVICE));
|
|
if (Buffer == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = mSmmFwBlockService->DetectDevice (
|
|
mSmmFwBlockService,
|
|
(UINT8 *)Buffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (Buffer);
|
|
return Status;
|
|
}
|
|
|
|
CopyMem ((VOID *) BlockMap, &(Buffer->DeviceInfo.BlockMap), sizeof (FD_BLOCK_MAP));
|
|
if (Buffer->DeviceInfo.Size != 0xFF) {
|
|
Status = mSmmFwBlockService->GetSpiFlashNumber (
|
|
mSmmFwBlockService,
|
|
&SpiFlashNumber
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
BlockMap[1] *= 1 << (SpiFlashNumber - 1);
|
|
}
|
|
}
|
|
|
|
FreePool (Buffer);
|
|
|
|
*RomSize = (UINT32)(BlockMap[0] * BlockMap[1] * 0x100);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Report the bios Update sequence for AH=11h.
|
|
|
|
@param[in,out] ExtInfoDataItemPtr Pointer to ExtInfoData.
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval Others Operation was unsuccessful.
|
|
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
UpdateExtendPlatformBiosUpdateSequence (
|
|
IN OUT EXTEND_PLATFORM_DATA_ITEM *ExtInfoDataItemPtr
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 BufferSize;
|
|
UINT32 DataSize;
|
|
BIOS_UPDATE_SEQUENCE *BiosUpdateSequence;
|
|
BIOS_UPDATE_AREA *BiosUpdateArea;
|
|
BOOLEAN SwapState;
|
|
UINT32 BiosRegionOffset;
|
|
UINT32 RomSize;
|
|
|
|
if (!mInPOST) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if ((PcdGet32 (PcdFlashPbbSize) == 0) ||
|
|
(PcdGet32 (PcdFlashSbbSize) == 0)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = InternalGetSwapState (&SwapState);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
RomSize = 0;
|
|
Status = GetRomSizeFromBlockMap (&RomSize);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (RomSize < PcdGet32 (PcdFlashAreaSize)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
BiosRegionOffset = RomSize - PcdGet32 (PcdFlashAreaSize);
|
|
|
|
if (IsFirmwareUpdateResiliencySupported ()) {
|
|
DataSize = sizeof (BIOS_UPDATE_SEQUENCE) + sizeof (BIOS_UPDATE_AREA) * 0x02;
|
|
BiosUpdateSequence = AllocatePool (DataSize);
|
|
if (BiosUpdateSequence == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
// Number of Areas
|
|
BiosUpdateSequence->AreaCount = 0x02;
|
|
BiosUpdateArea = (BIOS_UPDATE_AREA *)(BiosUpdateSequence + 1);
|
|
// Area 1: Flash PBB content into PBBR
|
|
BiosUpdateArea[0].Type = FbtsRomMapPrimaryBootBlock;
|
|
BiosUpdateArea[0].Address = PcdGet32 (PcdFlashPbbBase);
|
|
BiosUpdateArea[0].DataSize = PcdGet32 (PcdFlashPbbSize);
|
|
BiosUpdateArea[0].DataOffset = PcdGet32 (PcdFlashPbbBase) - PcdGet32 (PcdFlashAreaBaseAddress) + BiosRegionOffset;
|
|
// Area 2: Flash SBB content into SBB
|
|
BiosUpdateArea[1].Type = FbtsRomMapSecondaryBootBlock;
|
|
BiosUpdateArea[1].Address = PcdGet32 (PcdFlashSbbBase);
|
|
BiosUpdateArea[1].DataSize = PcdGet32 (PcdFlashSbbSize);
|
|
BiosUpdateArea[1].DataOffset = PcdGet32 (PcdFlashSbbBase) - PcdGet32 (PcdFlashAreaBaseAddress) + BiosRegionOffset;
|
|
} else {
|
|
DataSize = sizeof (BIOS_UPDATE_SEQUENCE) + sizeof (BIOS_UPDATE_AREA) * 0x03;
|
|
BiosUpdateSequence = AllocatePool (DataSize);
|
|
if (BiosUpdateSequence == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
// Number of Areas
|
|
BiosUpdateSequence->AreaCount = 0x03;
|
|
BiosUpdateArea = (BIOS_UPDATE_AREA *)(BiosUpdateSequence + 1);
|
|
// Area 1: Flash PBB content into PBBR
|
|
BiosUpdateArea[0].Type = FbtsRomMapPrimaryBootBlockReserved;
|
|
BiosUpdateArea[0].Address = PcdGet32 (PcdFlashPbbRBase);
|
|
BiosUpdateArea[0].DataSize = PcdGet32 (PcdFlashPbbSize);
|
|
BiosUpdateArea[0].DataOffset = PcdGet32 (PcdFlashPbbBase) - PcdGet32 (PcdFlashAreaBaseAddress) + BiosRegionOffset;
|
|
// Area 2: Flash PBB content into PBB
|
|
BiosUpdateArea[1].Type = FbtsRomMapPrimaryBootBlock;
|
|
BiosUpdateArea[1].Address = PcdGet32 (PcdFlashPbbBase);
|
|
BiosUpdateArea[1].DataSize = PcdGet32 (PcdFlashPbbSize);
|
|
BiosUpdateArea[1].DataOffset = PcdGet32 (PcdFlashPbbBase) - PcdGet32 (PcdFlashAreaBaseAddress) + BiosRegionOffset;
|
|
// Area 3: Flash SBB content into SBB
|
|
BiosUpdateArea[2].Type = FbtsRomMapSecondaryBootBlock;
|
|
BiosUpdateArea[2].Address = PcdGet32 (PcdFlashSbbBase);
|
|
BiosUpdateArea[2].DataSize = PcdGet32 (PcdFlashSbbSize);
|
|
BiosUpdateArea[2].DataOffset = PcdGet32 (PcdFlashSbbBase) - PcdGet32 (PcdFlashAreaBaseAddress) + BiosRegionOffset;
|
|
}
|
|
BufferSize = ExtInfoDataItemPtr->DataSize;
|
|
|
|
ExtInfoDataItemPtr->DataSize = DataSize;
|
|
if (ExtInfoDataItemPtr->DataSize > BufferSize) {
|
|
FreePool (BiosUpdateSequence);
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
CopyMem (ExtInfoDataItemPtr->Data, BiosUpdateSequence, DataSize);
|
|
|
|
//
|
|
// Clear update flag if using sequence update.
|
|
//
|
|
SetFirmwareUpdatingFlag (FALSE);
|
|
mUpdateSequenceEnabled = TRUE;
|
|
|
|
FreePool (BiosUpdateSequence);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
UpdateExtendPlatformBuildDateTimeInfo (
|
|
IN OUT EXTEND_PLATFORM_DATA_ITEM *ExtInfoDataItemPtr
|
|
)
|
|
{
|
|
UINTN StringSize;
|
|
EFI_STATUS Status;
|
|
CHAR16 StringDate[MODEL_DATE_SIZE];
|
|
CHAR16 StringTime[MODEL_TIME_SIZE];
|
|
UINT32 BufferSize;
|
|
|
|
BufferSize = ExtInfoDataItemPtr->DataSize;
|
|
ExtInfoDataItemPtr->DataSize = 0;
|
|
|
|
//
|
|
// Get build date string
|
|
//
|
|
StringSize = MODEL_DATE_SIZE;
|
|
Status = GetBvdtInfo ((BVDT_TYPE) BvdtBuildDate, &StringSize, StringDate);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Get build time string
|
|
//
|
|
Status = GetBvdtInfo ((BVDT_TYPE) BvdtBuildTime, &StringSize, StringTime);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
ExtInfoDataItemPtr->DataSize = (UINT32)(StrSize (StringDate) + StrSize (StringTime));
|
|
if (ExtInfoDataItemPtr->DataSize > BufferSize) {
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
//Merge Build date String . Build time string
|
|
StringSize = StrSize (StringDate);
|
|
StringDate[(StrSize (StringDate)/sizeof (StringDate[0])) - 1] = L' ';
|
|
CopyMem ( ExtInfoDataItemPtr->Data, StringDate, StringSize);
|
|
//
|
|
// Update build time string
|
|
//
|
|
ExtInfoDataItemPtr = (EXTEND_PLATFORM_DATA_ITEM *)(ExtInfoDataItemPtr->Data + StringSize);
|
|
StringSize = StrSize (StringTime);
|
|
CopyMem ( ExtInfoDataItemPtr, StringTime, StringSize);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=10h, Get permission,hook OemSvcIhisiS10HookGetPermission.
|
|
|
|
@retval EFI_SUCCESS Command successful returned.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemFbtsGetPermission (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Eax;
|
|
UINT16 Permission;
|
|
FBTS_TOOLS_VERSION_BUFFER *VersionPtr;
|
|
|
|
VersionPtr = (FBTS_TOOLS_VERSION_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) VersionPtr, sizeof (FBTS_TOOLS_VERSION_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (VersionPtr->Signature != FBTS_VERSION_SIGNATURE) {
|
|
return IHISI_UNSUPPORTED_FUNCTION;
|
|
}
|
|
//
|
|
//Get Permission
|
|
//
|
|
Permission = (UINT16)IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS10HookGetPermission \n"));
|
|
Status = OemSvcIhisiS10HookGetPermission (&Permission);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS10HookGetPermission Status: %r\n", Status));
|
|
|
|
Eax = IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX);
|
|
Eax = (UINT32)((Eax & 0xffff0000) | Permission);
|
|
IhisiProtWriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX, Eax);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=10h, Get Ac status,hook OemSvcIhisiS10HookGetAcStatus
|
|
|
|
|
|
@retval EFI_SUCCESS Command successful returned.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemFbtsGetAcStatus (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 AcStatus;
|
|
FBTS_PLATFORM_STATUS_BUFFER *PlatformInfoPtr;
|
|
//
|
|
//Get AC Status.
|
|
//
|
|
PlatformInfoPtr = (FBTS_PLATFORM_STATUS_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) PlatformInfoPtr, sizeof (FBTS_PLATFORM_STATUS_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
AcStatus = AC_PlugIn;
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS10HookGetAcStatus \n"));
|
|
Status = OemSvcIhisiS10HookGetAcStatus (&AcStatus);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS10HookGetAcStatus Status: %r\n", Status));
|
|
|
|
PlatformInfoPtr->AcStatus = AcStatus;
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
AH=10h, Get battery life,hook OemSvcIhisiS10HookGetBatterylife.
|
|
|
|
@retval EFI_SUCCESS Command successful returned.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemFbtsGetBatteryLife (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 BattLife;
|
|
FBTS_PLATFORM_STATUS_BUFFER *PlatformInfoPtr;
|
|
|
|
//
|
|
//Get AC Status and BattLife.
|
|
//
|
|
PlatformInfoPtr = (FBTS_PLATFORM_STATUS_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) PlatformInfoPtr, sizeof (FBTS_PLATFORM_STATUS_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
BattLife = 100;
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS10HookGetBatterylife \n"));
|
|
Status = OemSvcIhisiS10HookGetBatterylife (&BattLife);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS10HookGetBatterylife Status: %r\n", Status));
|
|
|
|
PlatformInfoPtr->Battery = BattLife;
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=11h, AP check ,hook OemSvcIhisiS11HookFbtsApCheck.
|
|
|
|
@retval
|
|
BIT 0: Model name check
|
|
BIT 1: Model version check
|
|
BIT 2: Allow same version file.
|
|
BIT 3: Verify file checksum
|
|
BIT 4: Disable display model name
|
|
BIT 5: Disable display model version
|
|
BIT 6: Disable read comparison while flash process
|
|
BIT 7: Enable ECX to return extended flag.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemFbtsApCheck (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Eax;
|
|
UINT8 ApCheck;
|
|
|
|
//
|
|
//Udpate AP check capability
|
|
//
|
|
ApCheck = AP_DO_NOTHING;
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS11HookFbtsApCheck \n"));
|
|
Status = OemSvcIhisiS11HookFbtsApCheck (&ApCheck);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS11HookFbtsApCheck Status: %r\n", Status));
|
|
|
|
Eax = IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX);
|
|
Eax = (UINT32) ((Eax & 0xffff00ff) | (ApCheck<<8));
|
|
IhisiProtWriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX, Eax);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=12h(FbtsGetPlatformRomMap), Get Oem define flash map.
|
|
|
|
@retval EFI_SUCCESS Get OEM flash map successful.
|
|
@retval EFI_UNSUPPORTED FBTS_OEM_ROM_MAP_COUNT is 0 or module rom map buffer is full.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemGetPlatformRomMap (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
FBTS_PLATFORM_ROM_MAP *OemRomMap;
|
|
UINTN OemRomMapSize;
|
|
FBTS_PLATFORM_ROM_MAP_BUFFER *InputRomMapBuffer;
|
|
FBTS_PLATFORM_PRIVATE_ROM *OemPrivateRomMap;
|
|
UINTN OemPrivateRomMapSize;
|
|
FBTS_PLATFORM_PRIVATE_ROM_BUFFER *InputPrivateRomMapBuffer;
|
|
FBTS_PLATFORM_ROM_MAP *OemRomMapBuffer;
|
|
FBTS_PLATFORM_PRIVATE_ROM *OemPrivateRomMapBuffer;
|
|
UINTN Index;
|
|
|
|
InputRomMapBuffer = (FBTS_PLATFORM_ROM_MAP_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
InputPrivateRomMapBuffer = (FBTS_PLATFORM_PRIVATE_ROM_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
|
|
//
|
|
// Check input address and whole input buffer isn't located in SM RAM.
|
|
//
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) InputRomMapBuffer, sizeof (FBTS_PLATFORM_ROM_MAP_BUFFER)) ||
|
|
!IhisiProtBufferInCmdBuffer ((VOID *) InputPrivateRomMapBuffer, sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
OemRomMap = AllocatePool (sizeof(FBTS_PLATFORM_ROM_MAP_BUFFER));
|
|
if (OemRomMap == NULL) {
|
|
return IHISI_OB_LEN_TOO_SMALL;
|
|
}
|
|
|
|
CopyMem (OemRomMap, InputRomMapBuffer, sizeof (FBTS_PLATFORM_ROM_MAP_BUFFER));
|
|
for (Index = 0, OemRomMapSize = 0; Index < sizeof(FBTS_PLATFORM_ROM_MAP_BUFFER)/sizeof(FBTS_PLATFORM_ROM_MAP); Index++) {
|
|
if(OemRomMap[Index].Type == FbtsRomMapEos) {
|
|
OemRomMapSize = Index++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
OemPrivateRomMap = AllocatePool (sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER));
|
|
if (OemPrivateRomMap == NULL) {
|
|
return IHISI_OB_LEN_TOO_SMALL;
|
|
}
|
|
|
|
CopyMem (OemPrivateRomMap, InputPrivateRomMapBuffer, sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER));
|
|
for (Index = 0, OemPrivateRomMapSize = 0; Index < sizeof(FBTS_PLATFORM_PRIVATE_ROM_BUFFER)/sizeof(FBTS_PLATFORM_PRIVATE_ROM); Index++) {
|
|
if(OemPrivateRomMap[Index].LinearAddress == FbtsRomMapEos) {
|
|
OemPrivateRomMapSize = Index++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Record currently allocate buffer
|
|
//
|
|
OemRomMapBuffer = OemRomMap;
|
|
OemPrivateRomMapBuffer = OemPrivateRomMap;
|
|
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS12HookGetOemFlashMap \n"));
|
|
Status = OemSvcIhisiS12HookGetOemFlashMap (
|
|
&OemRomMapSize,
|
|
&OemRomMap,
|
|
&OemPrivateRomMapSize,
|
|
&OemPrivateRomMap
|
|
);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS12HookGetOemFlashMap Status: %r\n", Status));
|
|
|
|
if (OemRomMapSize == 0 || OemPrivateRomMapSize == 0) {
|
|
// Error , not overwrite default data;
|
|
FreePool (OemRomMap);
|
|
FreePool (OemPrivateRomMap);
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
if ((Status == EFI_SUCCESS) || (Status == EFI_MEDIA_CHANGED)) {
|
|
if (OemPrivateRomMap != NULL) {
|
|
for (Index = 0; Index < sizeof(FBTS_PLATFORM_PRIVATE_ROM_BUFFER)/sizeof(FBTS_PLATFORM_PRIVATE_ROM); Index++ ) {
|
|
Status = FillPlatformPrivateRomMapBuffer (
|
|
OemPrivateRomMap[Index].LinearAddress,
|
|
OemPrivateRomMap[Index].Size,
|
|
(UINT8) Index
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
FillPlatformPrivateRomMapBuffer ((UINT8) FbtsRomMapEos, 0, 0);
|
|
break;
|
|
}
|
|
if (OemPrivateRomMap[Index].LinearAddress == (UINT32)FbtsRomMapEos) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (OemRomMap != NULL) {
|
|
for (Index = 0 ; Index < sizeof(FBTS_PLATFORM_ROM_MAP_BUFFER)/sizeof(FBTS_PLATFORM_ROM_MAP); Index++) {
|
|
Status = FillPlatformRomMapBuffer (
|
|
OemRomMap[Index].Type,
|
|
OemRomMap[Index].Address,
|
|
OemRomMap[Index].Length,
|
|
(UINT8) Index
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
FillPlatformRomMapBuffer ((UINT8) FbtsRomMapEos, 0, 0, 0);
|
|
break;
|
|
}
|
|
if (OemRomMap[Index].Type == FbtsRomMapEos) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update protect ROM map
|
|
//
|
|
CopyMem (InputRomMapBuffer, &mRomMapBuffer, sizeof (FBTS_PLATFORM_ROM_MAP_BUFFER));
|
|
|
|
//
|
|
// Update private ROM map
|
|
//
|
|
CopyMem (InputPrivateRomMapBuffer, &mPrivateRomMapBuffer, sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER));
|
|
}
|
|
|
|
//
|
|
// Compare the buffer address same with allocate address
|
|
//
|
|
if (OemRomMapBuffer == OemRomMap) {
|
|
FreePool (OemRomMap);
|
|
}
|
|
|
|
if (OemPrivateRomMapBuffer == OemPrivateRomMap) {
|
|
FreePool (OemPrivateRomMap);
|
|
}
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=1Eh,Get whole BIOS ROM map, hook OemSvcIhisiGetWholeBiosRomMap;
|
|
|
|
@retval EFI_SUCCESS FBTS get BIOS ROM map success.
|
|
@return Others FBTS get BIOS ROM map failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemFbtsGetWholeBiosRomMap (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN RomMapSize;
|
|
UINTN NumberOfRegions;
|
|
UINT8 *RomMapPtr;
|
|
FBTS_INTERNAL_BIOS_ROM_MAP *BiosRomMap;
|
|
|
|
NumberOfRegions = 0;
|
|
BiosRomMap = (FBTS_INTERNAL_BIOS_ROM_MAP *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
if (BiosRomMap == NULL) {
|
|
return IHISI_ACCESS_PROHIBITED;
|
|
}
|
|
|
|
//
|
|
// checck buffer in cmd buffer before accessing the data
|
|
//
|
|
for (NumberOfRegions = 0; ;NumberOfRegions++) {
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) BiosRomMap, (NumberOfRegions + 1) * sizeof (FBTS_INTERNAL_BIOS_ROM_MAP))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (BiosRomMap[NumberOfRegions].Type == FbtsRomMapEos) {
|
|
NumberOfRegions++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save default Rommap to RomMapPtr
|
|
//
|
|
RomMapSize = NumberOfRegions * sizeof (FBTS_INTERNAL_BIOS_ROM_MAP);
|
|
RomMapPtr = NULL;
|
|
RomMapPtr = AllocatePool (RomMapSize);
|
|
if (RomMapPtr == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
CopyMem ((VOID *)RomMapPtr, (VOID *)BiosRomMap, RomMapSize);
|
|
|
|
//
|
|
// OemSvcIhisiGetWholeBiosRomMap update default Rommap
|
|
//
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiGetWholeBiosRomMap \n"));
|
|
Status = OemSvcIhisiGetWholeBiosRomMap ((VOID **)&BiosRomMap, &NumberOfRegions);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiGetWholeBiosRomMap Status: %r\n", Status));
|
|
if (Status == EFI_SUCCESS) {
|
|
FreePool (RomMapPtr);
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
if (BiosRomMap[NumberOfRegions - 1].Type != FbtsRomMapEos) {
|
|
//Error, restore default rommap
|
|
BiosRomMap = (FBTS_INTERNAL_BIOS_ROM_MAP *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
CopyMem ((VOID *)BiosRomMap, (VOID *)RomMapPtr, RomMapSize);
|
|
FreePool (RomMapPtr);
|
|
return IHISI_FBTS_UNKNOWN_PLATFORM_ROM_MAP;
|
|
}
|
|
|
|
RomMapSize = NumberOfRegions * sizeof (FBTS_INTERNAL_BIOS_ROM_MAP);
|
|
CopyMem ((VOID *)(UINTN)IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI), (VOID *)BiosRomMap, RomMapSize);
|
|
FreePool (RomMapPtr);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=1Fh, AP Hook Point for BIOS
|
|
|
|
@retval EFI_SUCCESS FBTS get BIOS ROM map success.
|
|
@return Others FBTS get BIOS ROM map failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OemFbtsApHookForBios (
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
AH=1Fh, This call back function will be invoked several times during flash process.
|
|
BIOS can know which step is running now.
|
|
BIOS can base on it to do specific hook such as EC idle and weak up.
|
|
|
|
Arguments:
|
|
|
|
CL - denote the start of AP process.
|
|
CL = 0x00, AP terminate. (Before IHISI 0x16)
|
|
CL = 0x01, AP start. (After IHISI 0x10)
|
|
CL = 0x02, Start to read ROM. (Before IHISI 0x14)
|
|
CL = 0x03, Start to write ROM. (Before IHISI 0x15)
|
|
CL = 0x04, Start to write EC. (Before IHISI 0x20)
|
|
CL = 0x05, Before dialog popup.
|
|
CL = 0x06, After dialog close and continue running.
|
|
CL = 0x07, Before read EC.
|
|
CL = 0x08, After read EC.
|
|
CL = 0x09, After read ROM.
|
|
CL = 0x0A, After write ROM.
|
|
CL = 0x0B, After write EC.
|
|
CL = 0x0C - 0x0F, Reserved.
|
|
CL = 0x10 - 0x1F, Before/after write BIOS area. Even value for before action;
|
|
odd value for after action. Total 8 sets.
|
|
Ex:
|
|
0x10: Before write BIOS area 1
|
|
0x11: After write BIOS area 1
|
|
0x12: Before write BIOS area 2
|
|
0x13: After write BIOS area 2
|
|
0x14: Before write BIOS area 3
|
|
0x15: After write BIOS area 3
|
|
--*/
|
|
{
|
|
UINT8 ApState;
|
|
EFI_STATUS Status;
|
|
|
|
ApState = (UINT8) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX); // CL
|
|
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIhisiS1FHookFbtsApHookForBios \n"));
|
|
Status = OemSvcIhisiS1FHookFbtsApHookForBios (ApState);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIhisiS1FHookFbtsApHookForBios Status: %r\n", Status));
|
|
|
|
if (FeaturePcdGet (PcdH2OBiosUpdateFaultToleranceEnabled)) {
|
|
FbtsApHookForUpdateSequence (ApState);
|
|
}
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=10h,Get Permission, hook SmmCsSvcIhisiFbtsGetPermission.
|
|
|
|
@retval EFI_SUCCESS Command successful returned.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsGetPermission (
|
|
VOID
|
|
)
|
|
{
|
|
UINT32 Eax;
|
|
UINT16 Permission;
|
|
FBTS_TOOLS_VERSION_BUFFER *VersionPtr;
|
|
|
|
VersionPtr = (FBTS_TOOLS_VERSION_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) VersionPtr, sizeof (FBTS_TOOLS_VERSION_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
if (VersionPtr->Signature != FBTS_VERSION_SIGNATURE) {
|
|
return IHISI_UNSUPPORTED_FUNCTION;
|
|
}
|
|
//
|
|
//Get Permission
|
|
//
|
|
Permission = FBTS_PERMISSION_ALLOWED;
|
|
SmmCsSvcIhisiFbtsGetPermission (VersionPtr, &Permission);
|
|
Eax = IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX);
|
|
Eax = (UINT32)((Eax & 0xffff0000) | Permission);
|
|
IhisiProtWriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX, Eax);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
AH=14h ,FbtsRead before process , hook SmmCsSvcIhisiFbtsDoBeforeReadProcess
|
|
|
|
@retval EFI_SUCCESS Chipset FBTS read success.
|
|
@return Others FBTS read failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsDoBeforeReadProcess (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Size;
|
|
UINTN Offset;
|
|
UINTN Address;
|
|
UINT8 *DataBuffer;
|
|
|
|
//
|
|
// ECX - Size to read.
|
|
// DS:ESI - Pointer to returned data buffer. Size in ECX.
|
|
// EDI - Target linear address to read.
|
|
//
|
|
DataBuffer = (UINT8 *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
Size = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
Address = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
Offset = 0;
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) DataBuffer, Size) || IhisiProtBufferOverlapSmram ((VOID *) Address, Size)) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
Status = SmmCsSvcIhisiFbtsDoBeforeReadProcess(&Address, &Size, DataBuffer);
|
|
if (Status != EFI_SUCCESS) {
|
|
return Status;
|
|
}
|
|
|
|
IhisiProtWriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX, (UINT32)Size );
|
|
IhisiProtWriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI, (UINT32)Address );
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=14h ,FbtsRead after process , hook SmmCsSvcIhisiFbtsDoAfterReadProcess
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsDoAfterReadProcess (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = (EFI_STATUS) (IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX) & 0xff);
|
|
|
|
if (Status != EFI_SUCCESS) {
|
|
Status = ENCODE_ERROR (Status);
|
|
}
|
|
|
|
Status = SmmCsSvcIhisiFbtsDoAfterReadProcess(Status);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=15h ,FbtsWrite before process , hook SmmCsSvcIhisiFbtsDoBeforeWriteProcess
|
|
|
|
@retval EFI_SUCCESS Chipset FBTS read success.
|
|
@return Others FBTS read failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsDoBeforeWriteProcess (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN WriteSize;
|
|
UINTN RomBaseAddress;
|
|
UINT8 *WriteDataBuffer;
|
|
|
|
//
|
|
// ECX - Size to write.
|
|
// DS:ESI - Pointer to returned data buffer. Size in ECX.
|
|
// EDI - Target linear address to write.
|
|
//
|
|
WriteDataBuffer = (UINT8 *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
WriteSize = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
RomBaseAddress = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) WriteDataBuffer, WriteSize) || IhisiProtBufferOverlapSmram ((VOID *) RomBaseAddress, WriteSize)) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
Status = SmmCsSvcIhisiFbtsDoBeforeWriteProcess(WriteDataBuffer, &WriteSize, &RomBaseAddress);
|
|
if (Status != EFI_SUCCESS) {
|
|
return Status;
|
|
}
|
|
|
|
IhisiProtWriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX, (UINT32)WriteSize );
|
|
IhisiProtWriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI, (UINT32)RomBaseAddress );
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=15h ,FbtsWrite after process , hook SmmCsSvcIhisiFbtsDoAfterWriteProcess
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsDoAfterWriteProcess (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = (EFI_STATUS) (IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX) & 0xff);
|
|
|
|
if (Status != EFI_SUCCESS) {
|
|
Status = ENCODE_ERROR (Status);
|
|
}
|
|
|
|
Status = SmmCsSvcIhisiFbtsDoAfterWriteProcess(Status);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
AH=16h, FbtsComplete, hook SmmCsSvcIhisiFbtsApTerminated.
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsCompleteApTerminated (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
FBTS_FLASH_COMPLETE_STATUS *FlashCompleteStatus;
|
|
|
|
|
|
*(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE;
|
|
|
|
FlashCompleteStatus = (FBTS_FLASH_COMPLETE_STATUS *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) FlashCompleteStatus, sizeof (FBTS_FLASH_COMPLETE_STATUS))) {
|
|
IhisiErrorCodeHandler(IHISI_BUFFER_RANGE_ERROR);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
if ((FlashCompleteStatus->Signature != FLASH_COMPLETE_STATUS_SIGNATURE) ||
|
|
(FlashCompleteStatus->StructureSize != sizeof (FBTS_FLASH_COMPLETE_STATUS))) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (FlashCompleteStatus->CompleteStatus == ApTerminated) {
|
|
Status = SmmCsSvcIhisiFbtsApTerminated ();
|
|
IhisiErrorCodeHandler((UINT32)Status);
|
|
}
|
|
|
|
IhisiErrorCodeHandler((UINT32)Status);
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=16h, FbtsComplete, hook SmmCsSvcIhisiFbtsNormalFlash.
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsCompleteNormalFlash (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
FBTS_FLASH_COMPLETE_STATUS *FlashCompleteStatus;
|
|
|
|
|
|
*(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE;
|
|
FlashCompleteStatus = (FBTS_FLASH_COMPLETE_STATUS *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) FlashCompleteStatus, sizeof (FBTS_FLASH_COMPLETE_STATUS))) {
|
|
IhisiErrorCodeHandler(IHISI_BUFFER_RANGE_ERROR);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
if ((FlashCompleteStatus->Signature != FLASH_COMPLETE_STATUS_SIGNATURE) ||
|
|
(FlashCompleteStatus->StructureSize != sizeof (FBTS_FLASH_COMPLETE_STATUS))) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (FlashCompleteStatus->CompleteStatus == NormalFlash) {
|
|
Status = SmmCsSvcIhisiFbtsNormalFlash ();
|
|
IhisiErrorCodeHandler((UINT32)Status);
|
|
}
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=16h, FbtsComplete, hook SmmCsSvcIhisiFbtsPartialFlash.
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsCompletePartialFlash (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
FBTS_FLASH_COMPLETE_STATUS *FlashCompleteStatus;
|
|
|
|
|
|
*(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE;
|
|
|
|
FlashCompleteStatus = (FBTS_FLASH_COMPLETE_STATUS *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) FlashCompleteStatus, sizeof (FBTS_FLASH_COMPLETE_STATUS))) {
|
|
IhisiErrorCodeHandler(IHISI_BUFFER_RANGE_ERROR);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
if ((FlashCompleteStatus->Signature != FLASH_COMPLETE_STATUS_SIGNATURE) ||
|
|
(FlashCompleteStatus->StructureSize != sizeof (FBTS_FLASH_COMPLETE_STATUS))) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (FlashCompleteStatus->CompleteStatus == PartialFlash) {
|
|
Status = SmmCsSvcIhisiFbtsPartialFlash ();
|
|
IhisiErrorCodeHandler((UINT32)Status);
|
|
}
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=16h, FbtsComplete, hook SmmCsSvcIhisiFbtsOemComplete.
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsComplete (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 ApRequest;
|
|
|
|
ApRequest = (UINT8) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
|
|
if (ApRequest > (UINT8) FlashCompleteS3) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = SmmCsSvcIhisiFbtsOemComplete(ApRequest);
|
|
if (Status == EFI_SUCCESS) {
|
|
return IHISI_END_FUNCTION_CHAIN;
|
|
}
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=16h, FbtsComplete, hook SmmCsSvcIhisiFbtsShutDown/SmmCsSvcIhisiFbtsReboot/SmmCsSvcIhisiFbtsApRequestDoNothing.
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsReboot (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 ApRequest;
|
|
|
|
ApRequest = (UINT8) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
|
|
if (ApRequest > (UINT8) FlashCompleteS3) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
Status = EFI_SUCCESS;
|
|
if (ApRequest == FlashCompleteReboot) {
|
|
Status = SmmCsSvcIhisiFbtsReboot();
|
|
}
|
|
return Status;
|
|
}
|
|
/**
|
|
AH=16h, FbtsComplete, hook SmmCsSvcIhisiFbtsShutDown.
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsShutDown (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 ApRequest;
|
|
|
|
ApRequest = (UINT8) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (ApRequest > (UINT8) FlashCompleteS3) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (ApRequest == FlashCompleteShutdown) {
|
|
Status = SmmCsSvcIhisiFbtsShutDown();
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
/**
|
|
AH=16h, FbtsComplete, hook SmmCsSvcIhisiFbtsApRequestDoNothing.
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsDoNothing (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 ApRequest;
|
|
|
|
ApRequest = (UINT8) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
if (ApRequest > (UINT8) FlashCompleteS3) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (ApRequest == FlashCompleteDoNothing) {
|
|
Status = SmmCsSvcIhisiFbtsApRequestDoNothing();
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=12h, Get Platform ROM map protection, hook SmmCsSvcIhisiFbtsGetOemFlashMap
|
|
|
|
@retval EFI_SUCCESS Get Platform ROM map protection successful.
|
|
**/
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChipsetFbtsGetPlatformRomMap (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Index;
|
|
FBTS_PLATFORM_ROM_MAP *OemRomMapBuffer;
|
|
FBTS_PLATFORM_PRIVATE_ROM *OemPrivateRomMap;
|
|
FBTS_PLATFORM_ROM_MAP *OemRomMapTempBuffer;
|
|
FBTS_PLATFORM_PRIVATE_ROM *OemPrivateRomMapTempBuffer;
|
|
FBTS_PLATFORM_ROM_MAP_BUFFER *InputRomMapBuffer;
|
|
FBTS_PLATFORM_PRIVATE_ROM_BUFFER *InputPrivateRomMapBuffer;
|
|
|
|
InputRomMapBuffer = (FBTS_PLATFORM_ROM_MAP_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
InputPrivateRomMapBuffer = (FBTS_PLATFORM_PRIVATE_ROM_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
//
|
|
// Check input address and whole input buffer isn't located in SM RAM.
|
|
//
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) InputRomMapBuffer, sizeof (FBTS_PLATFORM_ROM_MAP_BUFFER)) ||
|
|
!IhisiProtBufferInCmdBuffer ((VOID *) InputPrivateRomMapBuffer, sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
//
|
|
// Update Chipset Flash Map
|
|
//
|
|
OemRomMapBuffer = AllocatePool (sizeof(FBTS_PLATFORM_ROM_MAP_BUFFER));
|
|
if (OemRomMapBuffer == NULL) {
|
|
return IHISI_OB_LEN_TOO_SMALL;
|
|
}
|
|
|
|
OemPrivateRomMap = AllocatePool (sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER));
|
|
if (OemPrivateRomMap == NULL) {
|
|
return IHISI_OB_LEN_TOO_SMALL;
|
|
}
|
|
|
|
//
|
|
// Record currently allocate buffer
|
|
//
|
|
OemRomMapTempBuffer = OemRomMapBuffer;
|
|
OemPrivateRomMapTempBuffer = OemPrivateRomMap;
|
|
|
|
Status = SmmCsSvcIhisiFbtsGetOemFlashMap (&OemRomMapBuffer, &OemPrivateRomMap);
|
|
if (Status == EFI_SUCCESS) {
|
|
if (OemPrivateRomMap != NULL) {
|
|
for (Index = 0; Index < sizeof(FBTS_PLATFORM_PRIVATE_ROM_BUFFER)/sizeof(FBTS_PLATFORM_PRIVATE_ROM); Index++ ) {
|
|
Status = FillPlatformPrivateRomMapBuffer (
|
|
OemPrivateRomMap[Index].LinearAddress,
|
|
OemPrivateRomMap[Index].Size,
|
|
(UINT8) Index
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
FillPlatformPrivateRomMapBuffer ((UINT8) FbtsRomMapEos, 0, 0);
|
|
break;
|
|
}
|
|
if (OemPrivateRomMap[Index].LinearAddress == (UINT32)FbtsRomMapEos) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (OemRomMapBuffer != NULL) {
|
|
for (Index = 0 ; Index < sizeof(FBTS_PLATFORM_ROM_MAP_BUFFER)/sizeof(FBTS_PLATFORM_ROM_MAP); Index++) {
|
|
Status = FillPlatformRomMapBuffer (
|
|
OemRomMapBuffer[Index].Type,
|
|
OemRomMapBuffer[Index].Address,
|
|
OemRomMapBuffer[Index].Length,
|
|
(UINT8) Index
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
FillPlatformRomMapBuffer ((UINT8) FbtsRomMapEos, 0, 0, 0);
|
|
break;
|
|
}
|
|
if (OemRomMapBuffer[Index].Type == FbtsRomMapEos) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update protect ROM map
|
|
//
|
|
CopyMem (InputRomMapBuffer, &mRomMapBuffer, sizeof (FBTS_PLATFORM_ROM_MAP_BUFFER));
|
|
|
|
//
|
|
// Update private ROM map
|
|
//
|
|
CopyMem (InputPrivateRomMapBuffer, &mPrivateRomMapBuffer, sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER));
|
|
}
|
|
|
|
//
|
|
// Compare the buffer address same with allocate address
|
|
//
|
|
if (OemRomMapTempBuffer == OemRomMapBuffer) {
|
|
FreePool (OemRomMapBuffer);
|
|
}
|
|
|
|
if (OemPrivateRomMapTempBuffer == OemPrivateRomMap) {
|
|
FreePool (OemPrivateRomMap);
|
|
}
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=10h, Get IHISI version/Battery low bound/VendorId.
|
|
|
|
@retval EFI_SUCCESS Command successful returned.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsGetVersion (
|
|
VOID
|
|
)
|
|
{
|
|
UINT32 Ecx;
|
|
|
|
//
|
|
//Get IHISI version
|
|
//
|
|
Ecx = IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
Ecx = (UINT32)((Ecx & 0xffff0000) | PcdGet16 (PcdIhisiFbtsVersion));
|
|
IhisiProtWriteCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX, Ecx);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=10h, Init OemHelp1/2.
|
|
|
|
@retval EFI_SUCCESS Command successful returned.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsInitOemHelp (
|
|
VOID
|
|
)
|
|
{
|
|
FBTS_PLATFORM_STATUS_BUFFER *PlatformInfoPtr;
|
|
UINTN PlatformInfoSize;
|
|
//
|
|
//Init OemHelp1/OemHelp2
|
|
//
|
|
PlatformInfoPtr = (FBTS_PLATFORM_STATUS_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
PlatformInfoSize = EXTEND_OFFSET (FBTS_PLATFORM_STATUS_BUFFER, Signature);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) PlatformInfoPtr, PlatformInfoSize)) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
PlatformInfoPtr->OemHelp1.Data = 0;
|
|
PlatformInfoPtr->OemHelp2.Data = 0;
|
|
return IHISI_SUCCESS;
|
|
|
|
}
|
|
|
|
/**
|
|
AH=10h, Get IHISI VendorId.
|
|
|
|
@retval EFI_SUCCESS Command successful returned.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsGetVendorId (
|
|
VOID
|
|
)
|
|
{
|
|
FBTS_PLATFORM_STATUS_BUFFER *PlatformInfoPtr;
|
|
UINTN PlatformInfoSize;
|
|
|
|
PlatformInfoPtr = (FBTS_PLATFORM_STATUS_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
PlatformInfoSize = EXTEND_OFFSET (FBTS_PLATFORM_STATUS_BUFFER, Signature);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) PlatformInfoPtr, PlatformInfoSize)) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
|
|
}
|
|
|
|
PlatformInfoPtr->Customer = PcdGet16 (PcdIhisiFbtsVendorId);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=10h, Get Battery low bound.
|
|
|
|
@retval EFI_SUCCESS Command successful returned.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsGetBatteryLowBound (
|
|
VOID
|
|
)
|
|
{
|
|
FBTS_PLATFORM_STATUS_BUFFER *PlatformInfoPtr;
|
|
UINTN PlatformInfoSize;
|
|
|
|
PlatformInfoPtr = (FBTS_PLATFORM_STATUS_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
PlatformInfoSize = EXTEND_OFFSET (FBTS_PLATFORM_STATUS_BUFFER, Signature);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) PlatformInfoPtr, PlatformInfoSize)) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
PlatformInfoPtr->Bound = PcdGet8 (PcdIhisiFbtsBatteryLowBound);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=11h, Get platform information. Get Model Name.
|
|
|
|
@retval EFI_SUCCESS Get platform information successful.
|
|
@return Other Get platform information failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsGetModelName (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN StrLen;
|
|
FBTS_PLATFORM_INFO_BUFFER *PlatformInfoPtr;
|
|
|
|
//
|
|
// DS:EDI - Pointer to platform information structure as below.
|
|
//
|
|
// Offset | Size | Item | Description
|
|
// --------|------|---------------|--------------
|
|
// 00h | 40h | Model Name | Unicode string, end with '00h'.
|
|
// 40h | FFh | Model Version | Unicode string, end with '00h'.
|
|
//
|
|
PlatformInfoPtr = (FBTS_PLATFORM_INFO_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
//
|
|
// Check input address and whole input buffer isn't located in SM RAM.
|
|
//
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) PlatformInfoPtr, sizeof (FBTS_PLATFORM_INFO_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
StrLen = MODEL_NAME_SIZE;
|
|
ZeroMem (PlatformInfoPtr->ModelName, StrLen * sizeof (CHAR16));
|
|
|
|
//
|
|
//Update Model name
|
|
//
|
|
Status = GetBvdtInfo ((BVDT_TYPE) BvdtProductName, &StrLen, PlatformInfoPtr->ModelName);
|
|
if (EFI_ERROR (Status)) {
|
|
return IHISI_FBTS_UNKNOWN_PLATFORM_INFO;
|
|
}
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=11h, Get platform information. Get Model Version
|
|
|
|
@retval EFI_SUCCESS Get platform information successful.
|
|
@return Other Get platform information failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsGetModelVersion (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN StrLen;
|
|
FBTS_PLATFORM_INFO_BUFFER *PlatformInfoPtr;
|
|
|
|
//
|
|
// DS:EDI - Pointer to platform information structure as below.
|
|
//
|
|
// Offset | Size | Item | Description
|
|
// --------|------|---------------|--------------
|
|
// 00h | 40h | Model Name | Unicode string, end with '00h'.
|
|
// 40h | FFh | Model Version | Unicode string, end with '00h'.
|
|
//
|
|
PlatformInfoPtr = (FBTS_PLATFORM_INFO_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
//
|
|
// Check input address and whole input buffer isn't located in SM RAM.
|
|
//
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) PlatformInfoPtr, sizeof (FBTS_PLATFORM_INFO_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
StrLen = MODEL_VERSION_SIZE;
|
|
ZeroMem (PlatformInfoPtr->ModelVersion, StrLen * sizeof (CHAR16));
|
|
|
|
//
|
|
//Update Model version
|
|
//
|
|
Status = GetBvdtInfo ((BVDT_TYPE) BvdtBiosVer, &StrLen, PlatformInfoPtr->ModelVersion);
|
|
if (EFI_ERROR (Status)) {
|
|
return IHISI_FBTS_UNKNOWN_PLATFORM_INFO;
|
|
}
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=11h, Get platform information.Update Extend Platform
|
|
|
|
@retval EFI_SUCCESS Get platform information successful.
|
|
@return Other Get platform information failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsUpdateExtendPlatform (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Index;
|
|
UINT32 BufferSize;
|
|
UINT32 DataItemUseSize;
|
|
UINT32 DataItemTotalSize;
|
|
EXTEND_PLATFORM_DATA_ITEM *DataItemPtr;
|
|
EXTEND_PLATFORM_DATA_ITEM *TempDataItemPtr;
|
|
FBTS_EXTEND_PLATFORM_INFO_TABLE_OUTPUT *ExtendPlatformInfoOutput;
|
|
FBTS_EXTEND_PLATFORM_INFO_TABLE_INPUT *ExternPlatformInfoInput;
|
|
UPDATE_EXT_ITEM_FUN_TABLE UpdateFunTable[UPDATE_EXT_ITEM_FUN_TABLE_MAX];
|
|
UINTN UpdateFunCount;
|
|
|
|
ExternPlatformInfoInput = (FBTS_EXTEND_PLATFORM_INFO_TABLE_INPUT *)(UINTN)IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ExternPlatformInfoInput, sizeof (FBTS_EXTEND_PLATFORM_INFO_TABLE_INPUT))){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
if (ExternPlatformInfoInput->Signature != EXTEND_PLATFORM_INPUT_BUFFER_SIGNATURE) {
|
|
//
|
|
// Tool do not support Extend Platform Info, no change , return success.
|
|
//
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
if (ExternPlatformInfoInput->StructureSize < sizeof (FBTS_EXTEND_PLATFORM_INFO_TABLE_INPUT)) {
|
|
//
|
|
// The structure size should bigger than Signature size
|
|
//
|
|
return IHISI_UNSUPPORTED_FUNCTION;
|
|
}
|
|
|
|
BufferSize = ExternPlatformInfoInput->StructureSize;
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ExternPlatformInfoInput, BufferSize)){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
ExtendPlatformInfoOutput = (FBTS_EXTEND_PLATFORM_INFO_TABLE_OUTPUT *)(UINTN)IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) ExtendPlatformInfoOutput, sizeof (FBTS_EXTEND_PLATFORM_INFO_TABLE_OUTPUT))){
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
DataItemPtr = ExtendPlatformInfoOutput->DataItem;
|
|
DataItemTotalSize = BufferSize - EXTEND_OFFSET(FBTS_EXTEND_PLATFORM_INFO_TABLE_OUTPUT, DataItem);
|
|
TempDataItemPtr = AllocatePool (DataItemTotalSize);
|
|
if (TempDataItemPtr == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
ExtendPlatformInfoOutput->DataItemCount = 0;
|
|
|
|
UpdateFunCount = 0;
|
|
|
|
//
|
|
// BuildDateTimeID
|
|
//
|
|
ASSERT (UpdateFunCount < UPDATE_EXT_ITEM_FUN_TABLE_MAX);
|
|
if (UpdateFunCount >= UPDATE_EXT_ITEM_FUN_TABLE_MAX) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
UpdateFunTable[UpdateFunCount].DataID = BuildDateTimeID;
|
|
UpdateFunTable[UpdateFunCount].UpdateExtItemFun = UpdateExtendPlatformBuildDateTimeInfo;
|
|
UpdateFunCount++;
|
|
|
|
//
|
|
// BiosUpdateSequence
|
|
//
|
|
if (FeaturePcdGet (PcdH2OBiosUpdateFaultToleranceEnabled)) {
|
|
ASSERT (UpdateFunCount < UPDATE_EXT_ITEM_FUN_TABLE_MAX);
|
|
if (UpdateFunCount >= UPDATE_EXT_ITEM_FUN_TABLE_MAX) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
UpdateFunTable[UpdateFunCount].DataID = BiosUpdateSequence;
|
|
UpdateFunTable[UpdateFunCount].UpdateExtItemFun = UpdateExtendPlatformBiosUpdateSequence;
|
|
UpdateFunCount++;
|
|
}
|
|
|
|
for (Index = 0, DataItemUseSize = 0; Index < UpdateFunCount; Index++) {
|
|
ZeroMem (TempDataItemPtr, DataItemTotalSize);
|
|
TempDataItemPtr->DataID = UpdateFunTable[Index].DataID;
|
|
//
|
|
//DataSize :Indicates how many available data size in Data field (offset 05h). Not include Data_ID (offset 00h) and Data_Size (offset 01h) fields.
|
|
//
|
|
TempDataItemPtr->DataSize = DataItemTotalSize - EXTEND_OFFSET(EXTEND_PLATFORM_DATA_ITEM, Data);
|
|
Status = UpdateFunTable[Index].UpdateExtItemFun(TempDataItemPtr);
|
|
if (Status == EFI_OUT_OF_RESOURCES) {
|
|
FreePool (TempDataItemPtr);
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
if (Status == EFI_SUCCESS || Status == EFI_BUFFER_TOO_SMALL) {
|
|
//
|
|
//Add each function dataitem use size to DataItemUseSize
|
|
//
|
|
ExtendPlatformInfoOutput->Signature = EXTEND_PLATFORM_OUTPUT_BUFFER_SIGNATURE;
|
|
DataItemUseSize += TempDataItemPtr->DataSize + EXTEND_OFFSET(EXTEND_PLATFORM_DATA_ITEM, Data);
|
|
if (DataItemUseSize < DataItemTotalSize) {
|
|
//
|
|
//Copy and point to next DataItem start address.
|
|
//
|
|
ExtendPlatformInfoOutput->DataItemCount ++;
|
|
CopyMem (DataItemPtr, TempDataItemPtr, TempDataItemPtr->DataSize + EXTEND_OFFSET(EXTEND_PLATFORM_DATA_ITEM, Data));
|
|
DataItemPtr = (EXTEND_PLATFORM_DATA_ITEM *)((UINT8 *)DataItemPtr + TempDataItemPtr->DataSize + EXTEND_OFFSET(EXTEND_PLATFORM_DATA_ITEM, Data));
|
|
}
|
|
}
|
|
}
|
|
FreePool (TempDataItemPtr);
|
|
//
|
|
//if DataItemUseSize over AP provide buffer size(DataItemTotalSize),restore signature and return buffer to small.
|
|
//
|
|
if (DataItemUseSize > DataItemTotalSize) {
|
|
ExtendPlatformInfoOutput->DataItemCount = DataItemUseSize;
|
|
return IHISI_OB_LEN_TOO_SMALL;
|
|
}
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=12h, Get Platform ROM map protection.
|
|
|
|
@retval EFI_SUCCESS Get Platform ROM map protection successful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsUpdateProtectRomMap (
|
|
VOID
|
|
)
|
|
{
|
|
FBTS_PLATFORM_ROM_MAP_BUFFER *InputRomMapBuffer;
|
|
|
|
//
|
|
// Get ROM map protection structure.
|
|
//
|
|
InputRomMapBuffer = (FBTS_PLATFORM_ROM_MAP_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
//
|
|
// Check input address and whole input buffer isn't located in SM RAM.
|
|
//
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) InputRomMapBuffer, sizeof (FBTS_PLATFORM_ROM_MAP_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
//
|
|
// Update protect ROM map
|
|
//
|
|
CopyMem (InputRomMapBuffer, &mRomMapBuffer, sizeof (FBTS_PLATFORM_ROM_MAP_BUFFER));
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=12h, Get Platform ROM map protection.
|
|
|
|
@retval EFI_SUCCESS Get Platform ROM map protection successful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsUpdatePrivateRomMap (
|
|
VOID
|
|
)
|
|
{
|
|
FBTS_PLATFORM_PRIVATE_ROM_BUFFER *InputPrivateRomMapBuffer;
|
|
|
|
//
|
|
// Get ROM map protection structure.
|
|
//
|
|
InputPrivateRomMapBuffer = (FBTS_PLATFORM_PRIVATE_ROM_BUFFER *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
//
|
|
// Check input address and whole input buffer isn't located in SM RAM.
|
|
//
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) InputPrivateRomMapBuffer, sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
//
|
|
// Update private ROM map
|
|
//
|
|
CopyMem (InputPrivateRomMapBuffer, &mPrivateRomMapBuffer, sizeof (FBTS_PLATFORM_PRIVATE_ROM_BUFFER));
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=13h, Get Flash part information.
|
|
|
|
@retval EFI_SUCCESS Get Flash part information successful.
|
|
@return Other Get Flash part information failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsGetFlashPartInfo (
|
|
VOID
|
|
)
|
|
{
|
|
FLASH_DEVICE *Buffer;
|
|
EFI_STATUS Status;
|
|
FBTS_FLASH_DEVICE FlashDevice;
|
|
UINT16 BlockMap[3];
|
|
UINT8 SpiFlashNumber;
|
|
UINT8 *FlashInfo;
|
|
UINTN FlashInfoSize;
|
|
UINT8 *FlashBlockMap;
|
|
|
|
//
|
|
// DS:EDI - Pointer to flash part information structure.
|
|
//
|
|
FlashInfo = (UINT8 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
FlashInfoSize = sizeof(FBTS_FLASH_DEVICE);
|
|
//
|
|
// Check output address and whole output bufferis located in command buffer.
|
|
//
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) FlashInfo , FlashInfoSize)) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
//
|
|
// DS:ESI - Pointer to flash part block map structure.
|
|
//
|
|
FlashBlockMap = (UINT8 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
//
|
|
// Check output address and whole output buffer is located in command buffer.
|
|
//
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) FlashBlockMap, sizeof (FD_BLOCK_MAP))) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
//
|
|
// CL = 00h => default, no choice from AP.
|
|
// 01h => AP need flash SPI flash part.
|
|
// 02h => AP need flash non-SPI flash part (LPC, FWH).
|
|
//
|
|
Buffer = AllocatePool (sizeof (FLASH_DEVICE));
|
|
if (Buffer == NULL) {
|
|
return IHISI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = mSmmFwBlockService->DetectDevice (
|
|
mSmmFwBlockService,
|
|
(UINT8*)Buffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (Buffer);
|
|
return Status;
|
|
}
|
|
|
|
ZeroMem (&FlashDevice, sizeof (FBTS_FLASH_DEVICE));
|
|
FlashDevice.Id = (UINT32)Buffer->DeviceInfo.Id;
|
|
FlashDevice.Size = Buffer->DeviceInfo.Size;
|
|
FlashDevice.SpecifiedSize = 0;
|
|
AsciiStrnCpyS (FlashDevice.VendorName, 31, Buffer->DeviceInfo.VendorName, 31);
|
|
AsciiStrnCpyS (FlashDevice.DeviceName, 32, Buffer->DeviceInfo.DeviceName, 32);
|
|
CopyMem ((VOID *) BlockMap, &(Buffer->DeviceInfo.BlockMap), sizeof (FD_BLOCK_MAP));
|
|
if (FlashDevice.Size == 0xFF) {
|
|
//
|
|
// The BlockSize unit is 256(0x100) byte.
|
|
//
|
|
FlashDevice.SpecifiedSize = (Buffer->DeviceInfo.BlockMap.Multiple * Buffer->DeviceInfo.BlockMap.BlockSize) * 0x100;
|
|
} else {
|
|
Status = mSmmFwBlockService->GetSpiFlashNumber (
|
|
mSmmFwBlockService,
|
|
&SpiFlashNumber
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
FlashDevice.Size += SpiFlashNumber - 1;
|
|
BlockMap[1] *= 1 << (SpiFlashNumber - 1);
|
|
}
|
|
}
|
|
|
|
CopyMem (
|
|
(VOID *) FlashInfo,
|
|
&FlashDevice,
|
|
FlashInfoSize
|
|
);
|
|
|
|
CopyMem ((VOID *) FlashBlockMap, BlockMap, sizeof (FD_BLOCK_MAP));
|
|
|
|
FreePool (Buffer);
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=1Bh,Skip module check allows and binary file transmissions.
|
|
|
|
@retval EFI_SUCCESS Success returns.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelSkipMcCheckAndBinaryTrans (
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// return IHISI_SUCCESS to allow skip module check. If doesn't allow
|
|
// skip module check, please return IHISI_FBTS_CANNOT_SKIP_MODULE_CHECK (0x27)
|
|
//
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get default BIOS ROM map
|
|
|
|
@param[out] BiosRomMap Pointer to the returned (FBTS_INTERNAL_BIOS_ROM_MAP *) data
|
|
@param[out] NumberOfRegions The total number of regions in BiosRomMap
|
|
|
|
@retval EFI_SUCCESS FBTS get BIOS ROM map success.
|
|
@return Others FBTS get BIOS ROM map failed.
|
|
**/
|
|
EFI_STATUS
|
|
GetDefaultBiosRomMap (
|
|
OUT FBTS_INTERNAL_BIOS_ROM_MAP **BiosRomMap,
|
|
OUT UINTN *NumberOfRegions
|
|
)
|
|
{
|
|
UINTN Index;
|
|
extern FBTS_INTERNAL_BIOS_ROM_MAP mDefaultBiosRomMap[];
|
|
UINT32 NvStorageRegionSize;
|
|
UINTN Conuter;
|
|
|
|
if ((BiosRomMap == NULL) || (NumberOfRegions == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
#define ADD_ROM_MAP_ENTRY(RegionType, RegionAddress, RegionSize, RegionAttr) \
|
|
mDefaultBiosRomMap[Index].Type = (UINT8)RegionType; \
|
|
mDefaultBiosRomMap[Index].Address = RegionAddress; \
|
|
mDefaultBiosRomMap[Index].Size = RegionSize; \
|
|
mDefaultBiosRomMap[Index].Attribute = RegionAttr; \
|
|
Index++; \
|
|
Conuter = __COUNTER__;
|
|
|
|
#define ADD_ROM_MAP_ENTRY_FROM_PCD(RegionType, AddressPcd, SizePcd, RegionAttr) \
|
|
if (PcdGet32(SizePcd) > 0) { \
|
|
ADD_ROM_MAP_ENTRY(RegionType, PcdGet32(AddressPcd), PcdGet32(SizePcd), RegionAttr); \
|
|
}
|
|
|
|
|
|
#define ADD_ROM_MAP_ENTRY_FROM_FDM(RegionType, FdmRegionType, Instance, RegionAttr) \
|
|
{ \
|
|
UINT64 Size; \
|
|
if ((Size = FdmGetNAtSize(&FdmRegionType, Instance)) > 0) { \
|
|
ADD_ROM_MAP_ENTRY(RegionType, (UINT32) FdmGetNAtAddr(&FdmRegionType, Instance), (UINT32) Size, RegionAttr); \
|
|
} \
|
|
}
|
|
|
|
#define ADD_DXE_FV_ROM_ENTRY_FROM_FDM(RegionAttr) \
|
|
{ \
|
|
UINT64 Size; \
|
|
if ((Size = FdmGetSizeById (&gH2OFlashMapRegionFvGuid, &gH2OFlashMapRegionDxeFvGuid, 1)) > 0) { \
|
|
ADD_ROM_MAP_ENTRY(FbtsRomMapDxe, (UINT32) FdmGetAddressById(&gH2OFlashMapRegionFvGuid, &gH2OFlashMapRegionDxeFvGuid, 1), (UINT32) Size, RegionAttr); \
|
|
} \
|
|
}
|
|
|
|
#define ADD_PEI_FV_ROM_ENTRY_FROM_FDM(RegionAttr) \
|
|
{ \
|
|
UINT64 Size; \
|
|
if ((Size = FdmGetNAtSize (&gH2OFlashMapRegionBootFvGuid, 1)) > 0) { \
|
|
ADD_ROM_MAP_ENTRY(FbtsRomMapPei, (UINT32) FdmGetNAtAddr(&gH2OFlashMapRegionBootFvGuid, 1), (UINT32) Size, RegionAttr); \
|
|
} \
|
|
}
|
|
|
|
Index = 0;
|
|
ADD_DXE_FV_ROM_ENTRY_FROM_FDM (0);
|
|
ADD_ROM_MAP_ENTRY_FROM_FDM (FbtsRomMapCpuMicrocode, gH2OFlashMapRegionMicrocodeGuid, 1, 0);
|
|
ADD_ROM_MAP_ENTRY_FROM_FDM (FbtsRomMapOemData, gH2OFlashMapRegionBvdtGuid, 1, 0);
|
|
ADD_ROM_MAP_ENTRY_FROM_FDM (FbtsRomMapDmiFru, gH2OFlashMapRegionSmbiosUpdateGuid, 1, 0);
|
|
ADD_ROM_MAP_ENTRY_FROM_FDM (FbtsRomMapOemData, gH2OFlashMapRegionMsdmGuid, 1, 0);
|
|
ADD_ROM_MAP_ENTRY_FROM_FDM (FbtsRomMapOemData, gH2OFlashMapRegionBvdtGuid, 1, 0);
|
|
ADD_PEI_FV_ROM_ENTRY_FROM_FDM (0);
|
|
|
|
NvStorageRegionSize = (UINT32) FdmGetNAtSize (&gH2OFlashMapRegionVarGuid, 1) +
|
|
(UINT32) FdmGetNAtSize (&gH2OFlashMapRegionFtwStateGuid,1) +
|
|
(UINT32) FdmGetNAtSize (&gH2OFlashMapRegionFtwBackupGuid, 1) +
|
|
(UINT32) FdmGetSizeById (&gH2OFlashMapRegionVarDefaultGuid, &gH2OFlashMapRegionFactoryCopyGuid, 1);
|
|
if (NvStorageRegionSize > 0) {
|
|
ADD_ROM_MAP_ENTRY (FbtsRomMapNvStorage, (UINT32) FdmGetNAtAddr (&gH2OFlashMapRegionVarGuid, 1), NvStorageRegionSize, 0);
|
|
}
|
|
|
|
if (FdmGetSizeById (&gH2OFlashMapRegionVarDefaultGuid, &gH2OFlashMapRegionFactoryCopyGuid, 1) > 0){
|
|
ADD_ROM_MAP_ENTRY (FbtsRomMapFactoryCopy, (UINT32) FdmGetAddressById (&gH2OFlashMapRegionVarDefaultGuid, &gH2OFlashMapRegionFactoryCopyGuid, 1), (UINT32) FdmGetSizeById (&gH2OFlashMapRegionVarDefaultGuid, &gH2OFlashMapRegionFactoryCopyGuid, 1), 0);
|
|
}
|
|
|
|
|
|
//
|
|
// End of ROM map
|
|
//
|
|
ADD_ROM_MAP_ENTRY (FbtsRomMapEos, 0, 0, 0);
|
|
|
|
*BiosRomMap = (FBTS_INTERNAL_BIOS_ROM_MAP *)mDefaultBiosRomMap;
|
|
*NumberOfRegions = Index;
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
//
|
|
// the mDefaultBiosRomMap is declared after GetDefaultRomMap() on purpose to
|
|
// ensure the array size of mDefaultBiosRomMap is enough, DO NOT move it to the top
|
|
//
|
|
FBTS_INTERNAL_BIOS_ROM_MAP mDefaultBiosRomMap[__COUNTER__];
|
|
|
|
/**
|
|
AH=1Eh, Get whole BIOS ROM map.
|
|
|
|
@retval EFI_SUCCESS FBTS get BIOS ROM map success.
|
|
@return Others FBTS get BIOS ROM map failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsGetWholeBiosRomMap (
|
|
VOID
|
|
)
|
|
{
|
|
UINTN RomMapSize;
|
|
UINTN NumberOfRegions;
|
|
UINT8 *RomMapPtr;
|
|
FBTS_INTERNAL_BIOS_ROM_MAP *BiosRomMap;
|
|
|
|
GetDefaultBiosRomMap ((FBTS_INTERNAL_BIOS_ROM_MAP **)&BiosRomMap, &NumberOfRegions);
|
|
|
|
if (BiosRomMap[NumberOfRegions - 1].Type != FbtsRomMapEos) {
|
|
return IHISI_FBTS_UNKNOWN_PLATFORM_ROM_MAP;
|
|
}
|
|
|
|
//
|
|
// Check input address and whole input buffer isn't located in SM RAM.
|
|
//
|
|
RomMapPtr = (UINT8 *) (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
RomMapSize = NumberOfRegions * sizeof (FBTS_INTERNAL_BIOS_ROM_MAP);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) RomMapPtr, RomMapSize)) {
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
//
|
|
// Get ROM map protection structure.
|
|
//
|
|
CopyMem ((VOID *)RomMapPtr, (VOID *)BiosRomMap, RomMapSize);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=14h, FBTS Read.
|
|
|
|
@retval EFI_SUCCESS FBTS read success.
|
|
@return Others FBTS read failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsRead (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Size;
|
|
UINTN Offset;
|
|
UINTN Address;
|
|
UINT8 *DataBuffer;
|
|
|
|
//
|
|
// ECX - Size to read.
|
|
// DS:ESI - Pointer to returned data buffer. Size in ECX.
|
|
// EDI - Target linear address to read.
|
|
//
|
|
DataBuffer = (UINT8 *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
Size = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
Address = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
Offset = 0;
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) DataBuffer, Size) || IhisiProtBufferOverlapSmram ((VOID *) Address, Size)) {
|
|
Status = IHISI_BUFFER_RANGE_ERROR;
|
|
goto ReadDone;
|
|
}
|
|
|
|
Status = mSmmFwBlockService->Read (
|
|
mSmmFwBlockService,
|
|
Address,
|
|
Offset,
|
|
&Size,
|
|
DataBuffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
Status = IHISI_FBTS_READ_FAILED;
|
|
}
|
|
ReadDone:
|
|
|
|
IhisiErrorCodeHandler((UINT32)Status);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
AH=15h,FBTS write.
|
|
|
|
@retval EFI_SUCCESS FBTS write success.
|
|
@return Others FBTS write failed.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsWrite (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN WriteSize;
|
|
UINT8 EraseCount;
|
|
UINT8 WriteCount;
|
|
UINTN RomBaseAddress;
|
|
BOOLEAN InUnsignedRegion;
|
|
UINTN UnsignedRegionBase;
|
|
UINT8 *WriteDataBuffer;
|
|
|
|
//
|
|
// ECX - Size to write.
|
|
// DS:ESI - Pointer to returned data buffer. Size in ECX.
|
|
// EDI - Target linear address to write.
|
|
//
|
|
WriteDataBuffer = (UINT8 *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
WriteSize = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX);
|
|
RomBaseAddress = (UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI);
|
|
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) WriteDataBuffer, WriteSize) || IhisiProtBufferOverlapSmram ((VOID *) RomBaseAddress, WriteSize)) {
|
|
Status = IHISI_BUFFER_RANGE_ERROR;
|
|
goto WriteDone;
|
|
}
|
|
|
|
InUnsignedRegion = FALSE;
|
|
if (PcdGetBool (PcdSecureFlashSupported)) {
|
|
Status = mSmmFwBlockService->ConvertToSpiAddress(
|
|
mSmmFwBlockService,
|
|
(UINTN) FdmGetAddressById(&gH2OFlashMapRegionFvGuid, &gH2OFlashMapRegionUnsignedFvGuid, 1),
|
|
&UnsignedRegionBase
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// Check Write address is in the Unsigned Region or not
|
|
//
|
|
if ((RomBaseAddress >= UnsignedRegionBase) && \
|
|
((RomBaseAddress + WriteSize) <= (UnsignedRegionBase + PcdGet32 (PcdEndOfFlashUnsignedFvRegionTotalSize)))) {
|
|
InUnsignedRegion = TRUE;
|
|
}
|
|
}
|
|
|
|
if (!mInPOST && !InUnsignedRegion) {
|
|
Status = IHISI_FBTS_WRITE_FAILED;
|
|
goto WriteDone;
|
|
}
|
|
}
|
|
|
|
EraseCount = 0;
|
|
WriteCount = 0;
|
|
do {
|
|
Status = mSmmFwBlockService->EraseBlocks (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
(UINTN *) &WriteSize
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
EraseCount = 0;
|
|
Status = mSmmFwBlockService->Write (
|
|
mSmmFwBlockService,
|
|
RomBaseAddress,
|
|
(UINTN *) &WriteSize,
|
|
WriteDataBuffer
|
|
);
|
|
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:
|
|
IhisiErrorCodeHandler((UINT32)Status);
|
|
|
|
return IHISI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function will delete the variable if the variable size is different between variable region and variable default
|
|
region.
|
|
|
|
Some variable size may be changed in different BIOS version. Using the mismatched variable after updating BIOS
|
|
may cause unpredictable behaviors. To prevent from tis situation so delete this type variables.
|
|
|
|
@retval EFI_SUCCESS Delete all of variable which variable is different between variable region and variable default region.
|
|
@retval EFI_OUT_OF_RESOURCES There are not enough resource to store variable region data.
|
|
@retval Other The request could not be completed by other reason.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
CheckVariableConsistency (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN VariableStoreHeaderSize;
|
|
UINTN VariableRegionSize;
|
|
UINT8 *VarRegionBuffer;
|
|
VARIABLE_HEADER *VariableHeader;
|
|
VARIABLE_HEADER *DefaultVariableHeader;
|
|
VARIABLE_HEADER *DefaultVariableHeaderbySkuId0;
|
|
UINTN DefaultVariableSize;
|
|
BOOLEAN FoundMismatchedVariable;
|
|
|
|
//
|
|
// Write back invalid related MMIO address to prevent from reading out-of-date data
|
|
//
|
|
WriteBackInvalidateDataCacheRange (
|
|
(VOID *)(UINTN)FdmGetNAtAddr (&gH2OFlashMapRegionVarGuid, 1),
|
|
(UINTN)FdmGetNAtSize (&gH2OFlashMapRegionVarGuid, 1)
|
|
);
|
|
WriteBackInvalidateDataCacheRange (
|
|
(VOID *)(UINTN) FdmGetNAtAddr (&gH2OFlashMapRegionVarDefaultGuid, 1),
|
|
(UINTN)FdmGetNAtSize (&gH2OFlashMapRegionVarDefaultGuid, 1)
|
|
);
|
|
//
|
|
// Get whole variable region and put in memory buffer.
|
|
//
|
|
VariableRegionSize = (UINTN)FdmGetNAtSize (&gH2OFlashMapRegionVarGuid, 1);
|
|
VarRegionBuffer = AllocatePool (VariableRegionSize);
|
|
if (VarRegionBuffer == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = mSmmFwBlockService->Read (
|
|
mSmmFwBlockService,
|
|
(UINTN)FdmGetNAtAddr (&gH2OFlashMapRegionVarGuid, 1),
|
|
0,
|
|
&VariableRegionSize,
|
|
VarRegionBuffer
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (VarRegionBuffer);
|
|
return Status;
|
|
}
|
|
//
|
|
// Get each variable in default variable region. If default variable isn't in current SKU, use it in SKU 0.
|
|
//
|
|
VariableStoreHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY) + GetVariableStoreHeaderSize ();
|
|
DefaultVariableHeaderbySkuId0 = (VARIABLE_HEADER *)(UINTN)FdmGetNAtAddr (&gH2OFlashMapRegionVarDefaultGuid, 1);
|
|
if (DefaultVariableHeaderbySkuId0 == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
FoundMismatchedVariable = FALSE;
|
|
for (DefaultVariableHeader = (VARIABLE_HEADER *)((UINT8 *)DefaultVariableHeaderbySkuId0 + GetVariableStoreHeaderSize ());
|
|
IsValidVariableHeader (DefaultVariableHeader);
|
|
DefaultVariableHeader = GetNextVariablePtr (DefaultVariableHeader)) {
|
|
if (DefaultVariableHeader->State != VAR_ADDED) {
|
|
continue;
|
|
}
|
|
DefaultVariableSize = 0;
|
|
Status = CommonGetDefaultVariable (
|
|
GET_VARIABLE_NAME_PTR (DefaultVariableHeader),
|
|
&DefaultVariableHeader->VendorGuid,
|
|
(H2O_BOARD_ID)(LibPcdGetSku()),
|
|
NULL,
|
|
(UINTN *)&DefaultVariableSize,
|
|
NULL
|
|
);
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
DefaultVariableSize = DefaultVariableHeader->DataSize;
|
|
}
|
|
//
|
|
// Delete variable if the variable size is different between variable region and variable default region.
|
|
//
|
|
for (VariableHeader = (VARIABLE_HEADER *)(VarRegionBuffer + VariableStoreHeaderSize);
|
|
IsValidVariableHeader (VariableHeader);
|
|
VariableHeader = GetNextVariablePtr (VariableHeader)) {
|
|
if (VariableHeader->State != VAR_ADDED && VariableHeader->State != (VAR_ADDED & VAR_IN_DELETED_TRANSITION)) {
|
|
continue;
|
|
}
|
|
if (StrCmp (GET_VARIABLE_NAME_PTR (VariableHeader), GET_VARIABLE_NAME_PTR (DefaultVariableHeader)) != 0 ||
|
|
!CompareGuid(&VariableHeader->VendorGuid, &DefaultVariableHeader->VendorGuid)) {
|
|
continue;
|
|
}
|
|
if (DefaultVariableSize != DataSizeOfVariable (VariableHeader)) {
|
|
VariableHeader->State &= VAR_DELETED;
|
|
FoundMismatchedVariable = TRUE;
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// Write updated variable region data to variable region if finding any mismatched variable.
|
|
//
|
|
Status = EFI_SUCCESS;
|
|
if (FoundMismatchedVariable) {
|
|
Status = mSmmFwBlockService->Write (
|
|
mSmmFwBlockService,
|
|
(UINTN)FdmGetNAtAddr (&gH2OFlashMapRegionVarGuid, 1),
|
|
&VariableRegionSize,
|
|
VarRegionBuffer
|
|
);
|
|
}
|
|
FreePool (VarRegionBuffer);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
AH=16h, This function uses to execute some specific action after the flash process is completed.
|
|
|
|
@retval EFI_SUCCESS Function succeeded.
|
|
@return Other Error occurred in this function.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
KernelFbtsPurifyVariable (
|
|
VOID
|
|
)
|
|
{
|
|
UINT32 Status;
|
|
FBTS_FLASH_COMPLETE_STATUS *FlashCompleteStatus;
|
|
|
|
*(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE;
|
|
|
|
// Only execute kernel purify variable in NormalFlash and chipset SmmCsSvcIhisiFbtsNormalFlash not Succes.
|
|
FlashCompleteStatus = (FBTS_FLASH_COMPLETE_STATUS *)(UINTN) IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI);
|
|
if (!IhisiProtBufferInCmdBuffer ((VOID *) FlashCompleteStatus, sizeof (FBTS_FLASH_COMPLETE_STATUS))) {
|
|
IhisiErrorCodeHandler(IHISI_BUFFER_RANGE_ERROR);
|
|
return IHISI_BUFFER_RANGE_ERROR;
|
|
}
|
|
|
|
if ((FlashCompleteStatus->Signature != FLASH_COMPLETE_STATUS_SIGNATURE) ||
|
|
(FlashCompleteStatus->StructureSize != sizeof (FBTS_FLASH_COMPLETE_STATUS))) {
|
|
return IHISI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!mPurifyVariable) {
|
|
return IHISI_SUCCESS;
|
|
}
|
|
Status = IHISI_SUCCESS;
|
|
if (FlashCompleteStatus->CompleteStatus == NormalFlash) {
|
|
Status = IhisiProtReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RAX) & 0xff;
|
|
if (Status != IHISI_SUCCESS) { // Execute PurifyVariable when SmmCsSvcIhisiFbtsNormalFlash not success;
|
|
Status = PurifyVariable();
|
|
CheckVariableConsistency ();
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SmmFwBlockNotification (
|
|
IN CONST EFI_GUID *Protocol,
|
|
IN VOID *Interface,
|
|
IN EFI_HANDLE Handle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = gSmst->SmmLocateProtocol (
|
|
&gEfiSmmFwBlockServiceProtocolGuid,
|
|
NULL,
|
|
(VOID **) &mSmmFwBlockService
|
|
);
|
|
|
|
if (EFI_ERROR(Status)) {
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
UpdateOemFlashMap();
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
UpdateOemFlashMap (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VOID *Registration;
|
|
|
|
if (mSmmFwBlockService == NULL) {
|
|
//
|
|
// If FwBlockService is not installed, register Protocol notification to update Oem Flash map
|
|
//
|
|
Status = gSmst->SmmLocateProtocol (
|
|
&gEfiSmmFwBlockServiceProtocolGuid,
|
|
NULL,
|
|
(VOID **) &mSmmFwBlockService
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
Status = gSmst->SmmRegisterProtocolNotify (
|
|
&gEfiSmmFwBlockServiceProtocolGuid,
|
|
SmmFwBlockNotification,
|
|
&Registration
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
//Update Oem Flash Map
|
|
//
|
|
ZeroMem ((VOID *)&mRomMapBuffer, sizeof (mRomMapBuffer));
|
|
FillPlatformRomMapBuffer ((UINT8) FbtsRomMapEos, 0, 0, 0);
|
|
ZeroMem ((VOID *)&mPrivateRomMapBuffer, sizeof (mPrivateRomMapBuffer));
|
|
FillPlatformPrivateRomMapBuffer ((UINT8) FbtsRomMapEos, 0, 0);
|
|
|
|
//Default mRomMapBuffer from GetFlashMapByHob
|
|
Status = GetFlashMapByHob ();
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
InstallFbtsServices (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
IHISI_REGISTER_TABLE *SubFuncTable;
|
|
UINT16 TableCount;
|
|
|
|
//
|
|
//Update Oem Flash Map
|
|
//
|
|
Status = UpdateOemFlashMap ();
|
|
if (EFI_ERROR(Status)) {
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
SubFuncTable = FBTS_REGISTER_TABLE;
|
|
TableCount = sizeof(FBTS_REGISTER_TABLE)/sizeof(FBTS_REGISTER_TABLE[0]);
|
|
Status = RegisterIhisiSubFunction (SubFuncTable, TableCount);
|
|
if (EFI_ERROR(Status)) {
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|