From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- Core/EM/SMIFlash/SMIFlash.c | 990 +++++++++++++++++ Core/EM/SMIFlash/SMIFlash.chm | Bin 0 -> 35457 bytes Core/EM/SMIFlash/SMIFlash.cif | 16 + Core/EM/SMIFlash/SMIFlash.dxs | 103 ++ Core/EM/SMIFlash/SMIFlash.mak | 183 ++++ Core/EM/SMIFlash/SMIFlash.sdl | 349 ++++++ Core/EM/SMIFlash/SMIFlashDxe.dxs | 72 ++ Core/EM/SMIFlash/SMIFlashLinks.c | 2227 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 3940 insertions(+) create mode 100644 Core/EM/SMIFlash/SMIFlash.c create mode 100644 Core/EM/SMIFlash/SMIFlash.chm create mode 100644 Core/EM/SMIFlash/SMIFlash.cif create mode 100644 Core/EM/SMIFlash/SMIFlash.dxs create mode 100644 Core/EM/SMIFlash/SMIFlash.mak create mode 100644 Core/EM/SMIFlash/SMIFlash.sdl create mode 100644 Core/EM/SMIFlash/SMIFlashDxe.dxs create mode 100644 Core/EM/SMIFlash/SMIFlashLinks.c (limited to 'Core/EM/SMIFlash') diff --git a/Core/EM/SMIFlash/SMIFlash.c b/Core/EM/SMIFlash/SMIFlash.c new file mode 100644 index 0000000..6566102 --- /dev/null +++ b/Core/EM/SMIFlash/SMIFlash.c @@ -0,0 +1,990 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.c 52 3/23/16 3:58a Calvinchen $ +// +// $Revision: 52 $ +// +// $Date: 3/23/16 3:58a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.c $ +// +// 52 3/23/16 3:58a Calvinchen +// [TAG] EIP262060 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Buffer Overflow Vulnerability +// [RootCause] SmiFlash interface security vulnerability if the buffer +// address is starting before/less SMM Base and the buffer length is +// larger than SMM size. +// [Solution] Adapted the CheckAddressRange function as the +// "AmiValidateMemoryBuffer" function of the AptioV. +// [Files] SMIFlash.c +// +// 51 1/08/16 3:59a Calvinchen +// [TAG] EIP249791 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] SMM Buffer Validation - additional vulnerability +// [RootCause] BufAddr is an embedded input pointer which has not been +// validated to be outside of SMRAM and is being used as a destination +// buffer for read/write operation from flash. +// +// [Solution] Validate BufAddr to must be outside of SMRAM. +// [Files] SMIFlash.c +// SMIFlash.chm +// SMIFlash.cif +// +// 50 6/21/13 4:32a Tristinchou +// [TAG] EIP125801 +// [Category] Improvement +// [Description] SMI Flash handler could be used to set value in SMRAM. +// Check the adrress before use the function. +// [Files] SMIFlash.c +// +// 49 11/02/12 7:13a Calvinchen +// [TAG] EIP64328 +// [Category] Improvement +// [Description] Improvement: +// 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI +// 2.3.1 specifications. +// BugFix: +// 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed +// after restored. +// 2. (EIP98199) The #### in Boot#### should be upper case. +// [Files] SMIFlash.mak +// SMIFlash.dxs +// SMIFlash.c +// SMIFlash.chm +// SMIFlashLinks.c +// SMIFlashDxe.dxs +// SMIFlash.cif +// +// 48 3/06/12 2:40a Klzhan +// NVRAM backup address will not updated. +// +// 47 1/16/12 2:29a Calvinchen +// [TAG] EIPNone +// [Category] Improvement +// [Description] Updated for Secure Update. +// +// 46 5/17/11 3:16a Klzhan +// Report BIOS project tag length to AFU. +// +// 45 3/23/11 4:44a Calvinchen +// [TAG] EIP53067 +// [Category] Improvement +// [Description] Modified for OEM Secure BIOS Update Requirements. +// [Files] SMIFlash.sdl +// SMIFlash.mak +// SMIFlash.dxs +// SMIFlash.c +// SMIFlash.chm +// SMIFlashLinks.c +// SMIFlash.cif +// +// 44 1/21/11 4:48a Klzhan +// Improvement : Check CPU number in SMIHandler +// +// 43 12/14/10 4:16a Klzhan +// Move Locate USB Protocol to SMIFlashLinks.c. +// +// 42 12/14/10 1:13a Klzhan +// Improvement : Move ELinks to SMIFlashLinks.c. +// +// 41 10/20/10 2:21a Klzhan +// Remove ASFU related codes, ASFU will implement with OFBD module. +// +// 40 10/19/10 6:58a Klzhan +// Improvement : Support Secure Flash Update. +// EIP : 46069 +// +// 39 8/10/10 2:40a Klzhan +// Improvement : Replace Memory Read by SPIRead when checking flash data. +// +// 38 6/15/10 3:12a Klzhan +// Improvement: Add Elink to modify GetFlashInfo. +// +// 37 4/14/10 5:43a Klzhan +// BugFix : Fix compile error when FAULT_TOLERANT_NVRAM_UPDATE is off. +// +// 36 4/13/10 4:26a Klzhan +// Improvement : Report NVRam backup as NVRam block. +// +// 35 4/12/10 7:45a Klzhan +// Improvement : When FAULT_TOLERANT_NVRAM_UPDATE is on and System working +// at NVRam backup address, system works fine on next boot. +// +// 34 4/12/10 3:37a Klzhan +// Improvement : Add E-Link to Enable/Disable USB KBD. +// BugFix : Correct USB driver verion control. +// +// 33 4/08/10 2:22a Rameshr +// Usb changes added based on AMIUSB release version. +// +// 32 4/07/10 1:53a Rameshr +// USB K/B and USB M/S should be stopped during flashing BIOS. +// EIP 37130 +// +// 31 3/26/10 5:25a Rameshr +// After flashupdate, Silent boot setup option is not restored to default +// value +// EIP 36617 +// +// 30 3/02/10 2:59a Klzhan +// Improvement : If Setup PassWord Length is changed, Password will not be +// restore when update NVRam region. +// +// 29 3/02/10 12:43a Klzhan +// Improvement : Disable Power Button when flash ROM image.(EIP35662) +// +// 28 2/26/10 2:31a Klzhan +// 1. Improvement : Restore "Windows Boot Manager" for EFI OS(EIP 32339) +// +// 27 12/21/09 4:39a Klzhan +// Improvement : Updated for Aptio Source Enhancement. +// +// 26 11/26/09 6:03a Klzhan +// Improvement : Add Flash Chip info.EIP 30081 +// +// 25 8/25/09 8:22a Klzhan +// Improvement: Support Flash ME FW. +// +// 24 5/22/09 8:19p Felixp +// SmiFlash module is updated to replace Flash library calls with the +// calls to new Core 4.6.3.6 Flash Protocol . +// +// 23 4/03/09 11:28a Fredericko +// Reverting changes for EIP 18818. causing Afu flash error. +// +// 22 3/05/09 1:17p Felixp +// - Bug fix. EIP 17632. +// Flash Blocks that do not belong to FV_BB, FV_MAIN, and FV_NVRAM +// have been reported as boot block. +// The SmiFlash.c is updated to report these blocks as non critical +// blocks. +// The SmiFlash.h header is updated to define non critical block type +// (NC_BLOCK ). +// - Headers updated. +// +// 21 2/02/09 6:46p Fredericko +// Changes for EIP 18819: Using FlashRead to read from flash part. Changed +// SMIFLASH_RRE_UPDATE_LIST to SMIFLASH_PRE_UPDATE_LIST +// +// 19 1/29/09 7:33p Fredericko +// Added code to account for functions (ELinked) that need to run before +// we program flash and after we program flash. EIP 18819 +// +// 18 1/13/09 4:36p Fredericko +// EIP18723: Increase the size of Index (to UINT16) variable for case +// where number of blocks is more than 255. +// +// 17 3/07/08 11:41a Rameshraju +// Readflash failed for 1.5Mb flash size +// +// 16 8/21/07 3:39p Pats +// Removed calculations for sizeof(AMITSESETUP) +// +// 15 8/17/07 4:37p Pats +// Fixed sizeof problem. +// +// 14 8/16/07 6:12p Pats +// Sizeof was returning wrong size for AMITSESETUP. +// +// 13 8/16/07 10:54a Pats +// Fixed problem with setvariable call in password preservation path. +// +// 12 8/15/07 7:06p Pats +// Modified to support preservation of passwords through flashing. +// +// 11 1/24/07 1:42p Felixp +// Erase/Programming code changed to use low level flash routines because +// AFU sends write requests, for a chunks of data smaller then the flash +// block. +// +// 10 12/29/06 3:04p Felixp +// 1. Updated to use new Flash Interface. +// 2. Embedded Controller support added. +// +// 9 3/24/06 7:57p Felixp +// +// 7 11/11/05 11:46a Markw +// Renamed IntallSmmHandler to InitSmmHandler because of build errors +// because another driver used InstallSmmHandler. +// +// 6 11/09/05 3:09p Yakovlevs +// InSmmFunction() "not all controls return a value" compiler warning +// fixed +// +// 5 11/08/05 6:05p Markw +// Using libary function InstallSmiHandler. +// +// 4 7/12/05 11:19a Markw +// Add code to detect which CPU is executing. +// +// 3 5/02/05 6:42p Markw +// Added Eswar's updates. +// +// 2 5/02/05 6:25p Markw +// +// 1 4/05/05 3:47p Sivagarn +// Initial Checkin +// +//********************************************************************** +// +// +// Name: SMIFlash.c +// +// Description: SMIFlash Driver. +// +// +//********************************************************************** +#include +#include +#include +#if PI_SPECIFICATION_VERSION >= 0x1000A +#include +#include +#include +#define RETURN(status) {return status;} +#else +#include +#include +#define RETURN(status) {return ;} +#endif +#include +#include +#include +#include +#include +#include +#include +#if AMIUSB_SUPPORT == 1 +#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) +#include +#endif +#endif + +//---------------------------------------------------------------------- +// component MACROs +#define FLASH_EMPTY_BYTE (UINT8)(-FLASH_ERASE_POLARITY) +#define STR(a) CONVERT_TO_STRING(a) +//---------------------------------------------------------------------- +// Module defined global variables + +//---------------------------------------------------------------------- +// Module specific global variable +EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID; +#if PI_SPECIFICATION_VERSION >= 0x1000A +EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID; +EFI_GUID gEfiSmmBase2ProtocolGuid = EFI_SMM_BASE2_PROTOCOL_GUID; +EFI_GUID gEfiSmmCpuProtocolGuid = EFI_SMM_CPU_PROTOCOL_GUID; +EFI_SMM_BASE2_PROTOCOL *gSmmBase2; +EFI_SMM_CPU_PROTOCOL *gSmmCpu; +#else +EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID; +#endif +EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID; + + +// oem flash write enable/disable list creation code must be in this order +typedef VOID (SMIFLASH_UPDATE) (VOID); +extern SMIFLASH_UPDATE SMIFLASH_PRE_UPDATE_LIST EndOfSMIFlashList; +extern SMIFLASH_UPDATE SMIFLASH_END_UPDATE_LIST EndOfSMIFlashList; +SMIFLASH_UPDATE* SMIFlashPreUpdate[] = {SMIFLASH_PRE_UPDATE_LIST NULL}; +SMIFLASH_UPDATE* SMIFlashEndUpdate[] = {SMIFLASH_END_UPDATE_LIST NULL}; +typedef VOID (SMIFLASH_PRE_HANDLER) (UINT8 Date, UINT64 pInfoBlock); +typedef VOID (SMIFLASH_END_HANDLER) (UINT8 Date, UINT64 pInfoBlock); +extern SMIFLASH_PRE_HANDLER SMIFLASH_PRE_HANDLER_LIST EndOfPreHandlerList; +extern SMIFLASH_END_HANDLER SMIFLASH_END_HANDLER_LIST EndOfEndHandlerList; +SMIFLASH_PRE_HANDLER* SMIFlashPreHandler[] = {SMIFLASH_PRE_HANDLER_LIST NULL}; +SMIFLASH_END_HANDLER* SMIFlashEndHandler[] = {SMIFLASH_END_HANDLER_LIST NULL}; + +typedef VOID (SMIFLASH_FUNCTION) (VOID); +extern SMIFLASH_FUNCTION SMIFLASH_IN_SMM_LIST EndOfInSmmList; +SMIFLASH_FUNCTION* SMIFlashInSmm[] = {SMIFLASH_IN_SMM_LIST NULL}; +extern SMIFLASH_FUNCTION SMIFLASH_NOT_IN_SMM_LIST EndOfNotInSmmList; +SMIFLASH_FUNCTION* SMIFlashNotInSmm[] = {SMIFLASH_NOT_IN_SMM_LIST NULL}; + +FLASH_PROTOCOL *Flash = NULL; +SMM_HOB gSmmHob; +#ifdef FLASH_PART_STRING_LENGTH +VOID GetFlashPartInfomation(UINT8 *pBlockAddress, UINT8 *Buffer); +#endif +//---------------------------------------------------------------------- +// externally defined variables + +//---------------------------------------------------------------------- +// Function definitions +EFI_STATUS +GetFlashInfo( + IN OUT INFO_BLOCK *pInfoBlock +); +EFI_STATUS EnableFlashWrite( + IN OUT FUNC_BLOCK *pFuncBlock +); +EFI_STATUS DisableFlashWrite( + IN OUT FUNC_BLOCK *pFuncBlock +); +EFI_STATUS ReadFlash( + IN OUT FUNC_BLOCK *pFuncBlock +); +EFI_STATUS WriteFlash( + IN OUT FUNC_BLOCK *pFuncBlock +); +EFI_STATUS EraseFlash( + IN OUT FUNC_BLOCK *pFuncBlock +); +EFI_SMI_FLASH_PROTOCOL SmiFlash = { + GetFlashInfo, + EnableFlashWrite, + DisableFlashWrite, + ReadFlash, + WriteFlash, + EraseFlash, + FLASH_SIZE +}; +// +//--------------------------------------------------------------------------- +// +// Procedure: CheckAddressRange +// +// Description: Check address range to avoid TSEG area. +// +// Input: +// Address - starting address +// Range - length of the area +// +// Output: +// EFI_SUCCESS - Access granted +// EFI_ACCESS_DENIED - Access denied! +// +//--------------------------------------------------------------------------- +// + +EFI_STATUS CheckAddressRange( IN UINT8 *Address, IN UINTN Range ) +{ + // Check the size and range + if (((EFI_PHYSICAL_ADDRESS)Address + Range) < (EFI_PHYSICAL_ADDRESS)Address) + return EFI_INVALID_PARAMETER; // overflow + + if (((EFI_PHYSICAL_ADDRESS)Address >= gSmmHob.Tseg) && \ + ((EFI_PHYSICAL_ADDRESS)Address < (gSmmHob.Tseg + gSmmHob.TsegLength))) + return EFI_ACCESS_DENIED; // Buffer starts in SMRAM + + if (((EFI_PHYSICAL_ADDRESS)Address < gSmmHob.Tseg) && \ + (((EFI_PHYSICAL_ADDRESS)Address + Range) > gSmmHob.Tseg)) + return EFI_ACCESS_DENIED; // Buffer overlaps with SMRAM + + return EFI_SUCCESS; +} +// +//---------------------------------------------------------------------- +// Procedure: GetFlashInfo +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS +GetFlashInfo( + IN OUT INFO_BLOCK *pInfoBlock +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 BuffLen = 0; + UINT64 BlkOff; + BLOCK_DESC *pBlock; + UINT16 Index; + UINT32 Add; + UINT32 Flash4GBMapStart; + UINT16 NumBlocks, MainStart, MainEnd, + NVStart, NVEnd, BBStart, BBEnd; + UINT16 LastNcb = 0xFFFF; + UINT8 NcbType = NC_BLOCK; +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT && SMI_FLASH_INTERFACE_VERSION > 10 + UINT16 ECStart, ECEnd; +#endif +#ifdef FAULT_TOLERANT_NVRAM_UPDATE +#if FAULT_TOLERANT_NVRAM_UPDATE + UINT16 NVBackupStart, NVBackupEnd; +#endif +#endif + + BuffLen = pInfoBlock->Length; // Total buffer length + pInfoBlock->Version = SMI_FLASH_INTERFACE_VERSION; + pInfoBlock->Implemented = 0; +#if SMI_FLASH_INTERFACE_VERSION > 10 +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT + pInfoBlock->ECVersionOffset = EC_VERSION_OFFSET; + pInfoBlock->ECVersionMask = EC_VERSION_MASK; +#else + pInfoBlock->ECVersionOffset = 0; + pInfoBlock->ECVersionMask = 0; +#endif +#endif + + // Reduce number of bytes used for header information + BuffLen -= EFI_FIELD_OFFSET( INFO_BLOCK, Blocks); + + // Get the total block count + pInfoBlock->TotalBlocks = NumBlocks = NUMBER_OF_BLOCKS; + + // Calculate the flash mapping start address. This is calculated + // as follows: + // 1. Find the total size of the flash (FLASH_BLOCK_SIZE * + // pInfoBlock->TotalBlocks) + // 2. Subtract the total flash size from 4GB + Flash4GBMapStart = 0xFFFFFFFF - (FLASH_BLOCK_SIZE * NumBlocks); + Flash4GBMapStart ++; + + // Fill the flash region start & end values + BBStart = (FV_BB_BASE - Flash4GBMapStart) / FLASH_BLOCK_SIZE; + BBEnd = BBStart + FV_BB_BLOCKS - 1; + + MainStart = (FV_MAIN_BASE - Flash4GBMapStart) / FLASH_BLOCK_SIZE; + MainEnd = MainStart + FV_MAIN_BLOCKS - 1; + + NVStart = (NVRAM_ADDRESS - Flash4GBMapStart) / FLASH_BLOCK_SIZE; + NVEnd = NVStart + NVRAM_BLOCKS - 1; + +#ifdef FAULT_TOLERANT_NVRAM_UPDATE +#if FAULT_TOLERANT_NVRAM_UPDATE + NVBackupStart = (NVRAM_BACKUP_ADDRESS - Flash4GBMapStart) / FLASH_BLOCK_SIZE; + NVBackupEnd = NVBackupStart + NVRAM_BLOCKS - 1; +#endif +#endif + +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT && SMI_FLASH_INTERFACE_VERSION > 10 + ECStart = (EC_BASE - Flash4GBMapStart) / FLASH_BLOCK_SIZE; + ECEnd = ECStart + EC_BLOCKS - 1; +#endif + + BlkOff = (UINT64)&pInfoBlock->Blocks; + + // Chek whether we have enough buffer space + if (BuffLen < (sizeof (BLOCK_DESC) * NumBlocks)) { + pInfoBlock->Implemented = 1; + return Status; + } + + for (Index = 0; Index < NumBlocks; Index++) { + + pBlock = (BLOCK_DESC *)BlkOff; + Add = Index * FLASH_BLOCK_SIZE; + + pBlock->StartAddress = Add; + Add |= Flash4GBMapStart; + pBlock->BlockSize = FLASH_BLOCK_SIZE; + + if ((Index >= MainStart) && (Index <= MainEnd)) + pBlock->Type = MAIN_BLOCK; + else if ((Index >= NVStart) && (Index <= NVEnd)) + pBlock->Type = NV_BLOCK; + else if ((Index >= BBStart) && (Index <= BBEnd)) + pBlock->Type = BOOT_BLOCK; +#ifdef FAULT_TOLERANT_NVRAM_UPDATE +#if FAULT_TOLERANT_NVRAM_UPDATE + else if ((Index >= NVBackupStart) && (Index <= NVBackupEnd)) + { + pBlock->Type = NVB_BLOCK; + } +#endif +#endif +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT && SMI_FLASH_INTERFACE_VERSION > 10 + else if ((Index >= ECStart) && (Index <= ECEnd)) + pBlock->Type = EC_BLOCK; +#endif + else { + if (LastNcb+1 != Index) NcbType++; + + pBlock->Type = NcbType; + LastNcb=Index; + } + BlkOff += sizeof (BLOCK_DESC); + } + + // Info AFU Project Tag length. + if (((UINT64)pInfoBlock + pInfoBlock->Length) > (BlkOff + 5)) + { + CHAR8* ProjectTag = STR(PROJECT_TAG); + UINTN TagLength; + UINT8 ProjectTagSign[4] = {'$','B','P','T'}; + + TagLength = Strlen(ProjectTag); + + MemCpy ( (UINT8*)BlkOff, ProjectTagSign, 4 ); + BlkOff += sizeof (UINT32); + *(UINT8*)BlkOff = (UINT8)TagLength; + BlkOff += 1; + } + +#ifdef FLASH_PART_STRING_LENGTH + if (((UINT64)pInfoBlock + pInfoBlock->Length) > \ + (BlkOff + FLASH_PART_STRING_LENGTH + 8)) + GetFlashPartInfomation ( (UINT8*)Flash4GBMapStart, (UINT8*)BlkOff ); +#endif + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------- +// Procedure: EnableFlashWrite +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS EnableFlashWrite( + IN OUT FUNC_BLOCK *pFuncBlock +) +{ + return Flash->DeviceWriteEnable(); +} + + +// +//---------------------------------------------------------------------- +// Procedure: DisableFlashWrite +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS DisableFlashWrite( + IN OUT FUNC_BLOCK *pFuncBlock +) +{ + return Flash->DeviceWriteDisable(); +} + +// +//---------------------------------------------------------------------- +// Procedure: EraseFlash +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS EraseFlash( + IN OUT FUNC_BLOCK *pFuncBlock +) +{ + EFI_STATUS Status; + UINT8 *BlockAddress; + BlockAddress = (UINT8*)(UINTN)(pFuncBlock->BlockAddr + \ + (0xFFFFFFFF - SmiFlash.FlashCapacity + 1)); + (UINT32)BlockAddress &= (0xFFFFFFFF - FLASH_BLOCK_SIZE + 1); + if (EFI_ERROR(CheckAddressRange (BlockAddress, \ + FlashBlockSize))) return EFI_ACCESS_DENIED; + Status = Flash->Erase(BlockAddress, FlashBlockSize); + pFuncBlock->ErrorCode = EFI_ERROR(Status) != 0; + return Status; +} + +// +//---------------------------------------------------------------------- +// Procedure: ReadFlash +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS ReadFlash( + IN OUT FUNC_BLOCK *pFuncBlock +) +{ + UINT32 Flash4GBMapStart; + EFI_STATUS Status; + + Flash4GBMapStart = 0xFFFFFFFF - (FLASH_BLOCK_SIZE * NUMBER_OF_BLOCKS); + Flash4GBMapStart += (pFuncBlock->BlockAddr + 1); + if (EFI_ERROR(CheckAddressRange ((UINT8*)Flash4GBMapStart, \ + pFuncBlock->BlockSize))) return EFI_ACCESS_DENIED; + if (EFI_ERROR(CheckAddressRange ((UINT8*)pFuncBlock->BufAddr, \ + pFuncBlock->BlockSize))) return EFI_ACCESS_DENIED; + Status = Flash->Read((UINT8*)Flash4GBMapStart, \ + pFuncBlock->BlockSize, (UINT8*)pFuncBlock->BufAddr); + pFuncBlock->ErrorCode = EFI_ERROR(Status) != 0; + return Status; +} + +// +//---------------------------------------------------------------------- +// Procedure: WriteFlash +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS WriteFlash( + IN OUT FUNC_BLOCK *pFuncBlock +) +{ + EFI_STATUS Status; + UINT8 *FlashAddress; + + FlashAddress = (UINT8*)(UINTN)(pFuncBlock->BlockAddr + \ + (0xFFFFFFFF - SmiFlash.FlashCapacity + 1)); + if (EFI_ERROR(CheckAddressRange (FlashAddress, \ + pFuncBlock->BlockSize))) return EFI_ACCESS_DENIED; + if (EFI_ERROR(CheckAddressRange ((UINT8*)pFuncBlock->BufAddr, \ + pFuncBlock->BlockSize))) return EFI_ACCESS_DENIED; + Status = Flash->Write(FlashAddress, \ + pFuncBlock->BlockSize, (UINT8*)pFuncBlock->BufAddr); + pFuncBlock->ErrorCode = EFI_ERROR(Status) != 0; + return Status; +} + +// +//---------------------------------------------------------------------- +// Procedure: SMIFlashSMIHandler +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +#if PI_SPECIFICATION_VERSION >= 0x1000A +EFI_STATUS +SMIFlashSMIHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL +) +#else +VOID SMIFlashSMIHandler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext +) +#endif +{ + EFI_SMM_CPU_SAVE_STATE *pCpuSaveState = NULL; + EFI_STATUS Status = EFI_SUCCESS; + UINT8 Data; + UINT64 pCommBuff; + UINT32 HighBufferAddress = 0; + UINT32 LowBufferAddress = 0; + UINTN Cpu = (UINTN)-1, i = 0; + +#if PI_SPECIFICATION_VERSION >= 0x1000A + if (CommBuffer != NULL && CommBufferSize != NULL) { + Cpu = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->SwSmiCpuIndex; + Data = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->CommandPort; + } + + // + // Found Invalid CPU number, return + // + if(Cpu == (UINTN)-1) RETURN(Status); + + Status = gSmmCpu->ReadSaveState ( gSmmCpu, \ + 4, \ + EFI_SMM_SAVE_STATE_REGISTER_RBX, \ + Cpu, \ + &LowBufferAddress ); + Status = gSmmCpu->ReadSaveState ( gSmmCpu, \ + 4, \ + EFI_SMM_SAVE_STATE_REGISTER_RCX, \ + Cpu, \ + &HighBufferAddress ); +#else // PI_SPECIFICATION_VERSION < 0x1000A + SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger; + + for (i = 0; i < pSmst->NumberOfTableEntries; ++i) { + if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid, + &gSwSmiCpuTriggerGuid) == 0) { + break; + } + } + + //If found table, check for the CPU that caused the software Smi. + if (i != pSmst->NumberOfTableEntries) { + SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable; + Cpu = SwSmiCpuTrigger->Cpu; + } + + // + // Found Invalid CPU number, return + // + if(Cpu == (UINTN) -1) RETURN(Status); + + Data = (UINT8)DispatchContext->SwSmiInputValue; + + pCpuSaveState = pSmst->CpuSaveState; + HighBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.ECX; + LowBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.EBX; + +#endif + + pCommBuff = HighBufferAddress; + pCommBuff = Shl64(pCommBuff, 32); + pCommBuff += LowBufferAddress; + + if(Data == SMIFLASH_GET_FLASH_INFO) + Status = CheckAddressRange( (UINT8*)pCommBuff, sizeof(INFO_BLOCK) ); + else + Status = CheckAddressRange( (UINT8*)pCommBuff, sizeof(FUNC_BLOCK) ); + if(EFI_ERROR(Status)) RETURN(Status); + + if (Data != SMIFLASH_GET_FLASH_INFO) + ((FUNC_BLOCK*)pCommBuff)->ErrorCode = 0; + for (i = 0; SMIFlashPreHandler[i] != NULL; i++) + SMIFlashPreHandler[i](Data, pCommBuff); + if ((Data == SMIFLASH_GET_FLASH_INFO) || \ + (((FUNC_BLOCK*)pCommBuff)->ErrorCode == 0)) { + switch (Data) { + case 0x20: // Enable Flash + for (i = 0; SMIFlashPreUpdate[i] != NULL; i++) + SMIFlashPreUpdate[i](); + EnableFlashWrite((FUNC_BLOCK *)pCommBuff); + break; + + case 0x24: // Disable Flash + for (i = 0; SMIFlashEndUpdate[i] != NULL; i++) + SMIFlashEndUpdate[i](); + + DisableFlashWrite((FUNC_BLOCK *)pCommBuff); + break; + + case 0x22: // Erase Flash + + EraseFlash((FUNC_BLOCK *)pCommBuff); + + break; + + case 0x21: // Read Flash + ReadFlash((FUNC_BLOCK *)pCommBuff); + break; + + case 0x23: // Write Flash + + WriteFlash((FUNC_BLOCK *)pCommBuff); + break; + + case 0x25: // Get Flash Info + GetFlashInfo((INFO_BLOCK *)pCommBuff); + } + + } + for (i = 0; SMIFlashEndHandler[i] != NULL; i++) + SMIFlashEndHandler[i](Data, pCommBuff); + RETURN(Status); +} + +// +//---------------------------------------------------------------------- +// Procedure: InSmmFunction +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS InSmmFunction( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_HANDLE Handle; + UINTN Index; + EFI_HANDLE DummyHandle = NULL; + EFI_STATUS Status; + SMM_HOB *SmmHob; + EFI_GUID SmmHobGuid = SMM_HOB_GUID; + EFI_GUID HobListGuid = HOB_LIST_GUID; +#if PI_SPECIFICATION_VERSION >= 0x1000A + EFI_SMM_SW_DISPATCH2_PROTOCOL *pSwDispatch; + EFI_SMM_SW_REGISTER_CONTEXT SwContext; +#else + EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch; + EFI_SMM_SW_DISPATCH_CONTEXT SwContext; +#endif + +#if PI_SPECIFICATION_VERSION >= 0x1000A + Status = InitAmiSmmLib( ImageHandle, SystemTable ); + Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2); + if (EFI_ERROR(Status)) return EFI_SUCCESS; + + Status = pSmmBase->GetSmstLocation (gSmmBase2, &pSmst); + if (EFI_ERROR(Status)) return EFI_SUCCESS; + + Status = pSmst->SmmLocateProtocol( \ + &gEfiSmmSwDispatch2ProtocolGuid, NULL, &pSwDispatch); + if (EFI_ERROR(Status)) return EFI_SUCCESS; + + Status = pSmst->SmmLocateProtocol(&gEfiSmmCpuProtocolGuid, NULL, &gSmmCpu); + if (EFI_ERROR(Status)) return EFI_SUCCESS; +#else + VERIFY_EFI_ERROR(pBS->LocateProtocol( + &gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch)); +#endif + VERIFY_EFI_ERROR(pBS->LocateProtocol(&gFlashSmmProtocolGuid, + NULL, &Flash)); + TRACE((TRACE_ALWAYS,"SmiFlash: Flash Protocol %X\n",Flash)); + + SmmHob = (SMM_HOB*)GetEfiConfigurationTable(pST, &HobListGuid); + if (SmmHob == NULL) return EFI_NOT_FOUND; + Status = FindNextHobByGuid(&SmmHobGuid,(VOID**)&SmmHob); + if (EFI_ERROR(Status)) return Status; + gSmmHob = *SmmHob; + + for (Index = 0x20; Index < 0x26; Index++) { + SwContext.SwSmiInputValue = Index; + Status = pSwDispatch->Register(pSwDispatch, SMIFlashSMIHandler, + &SwContext, &Handle); + ASSERT_EFI_ERROR(Status); + + if (EFI_ERROR(Status)) return EFI_SUCCESS; + + //TODO: If any errors, unregister any registered SwSMI by this driver. + //If error, and driver is unloaded, then a serious problem would exist. + } + +#if PI_SPECIFICATION_VERSION >= 0x1000A + Status = pSmst->SmmInstallProtocolInterface( + &DummyHandle, + &gEfiSmiFlashProtocolGuid, + EFI_NATIVE_INTERFACE, + &SmiFlash + ); +#endif + // If PI 1.2, install this protocol for backward compatible. + DummyHandle = NULL; + Status = pBS->InstallMultipleProtocolInterfaces( + &DummyHandle, + &gEfiSmiFlashProtocolGuid,&SmiFlash, + NULL + ); + ASSERT_EFI_ERROR(Status); + + for (Index = 0; SMIFlashInSmm[Index] != NULL; Index++) { + SMIFlashInSmm[Index](); + } + return EFI_SUCCESS; +} +// +//---------------------------------------------------------------------- +// Procedure: NonSmmElinkFunctions +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS +NonSmmElinkFunctions( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + UINT8 i; + + for (i = 0; SMIFlashNotInSmm[i] != NULL; i++) + SMIFlashNotInSmm[i](); + + return EFI_SUCCESS; +} +// +//---------------------------------------------------------------------- +// Procedure: SMIFlashDriverEntryPoint +// +// Description: +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS SMIFlashDriverEntryPoint( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + InitAmiLib(ImageHandle, SystemTable); + return InitSmmHandler (ImageHandle, \ + SystemTable, InSmmFunction, NonSmmElinkFunctions); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/SMIFlash/SMIFlash.chm b/Core/EM/SMIFlash/SMIFlash.chm new file mode 100644 index 0000000..7235dae Binary files /dev/null and b/Core/EM/SMIFlash/SMIFlash.chm differ diff --git a/Core/EM/SMIFlash/SMIFlash.cif b/Core/EM/SMIFlash/SMIFlash.cif new file mode 100644 index 0000000..ebed2dc --- /dev/null +++ b/Core/EM/SMIFlash/SMIFlash.cif @@ -0,0 +1,16 @@ + + name = "SMIFlash" + category = eModule + LocalRoot = "CORE\EM\SMIFlash\" + RefName = "SMIFlash" +[files] +"SMIFlash.sdl" +"SMIFlash.mak" +"SMIFlash.dxs" +"SMIFlash.c" +"SMIFlash.chm" +"SMIFlashLinks.c" +"SMIFlashDxe.dxs" +[parts] +"SMIFlashProtocols" + diff --git a/Core/EM/SMIFlash/SMIFlash.dxs b/Core/EM/SMIFlash/SMIFlash.dxs new file mode 100644 index 0000000..0fbc5ec --- /dev/null +++ b/Core/EM/SMIFlash/SMIFlash.dxs @@ -0,0 +1,103 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.dxs 7 11/02/12 7:13a Calvinchen $ +// +// $Revision: 7 $ +// +// $Date: 11/02/12 7:13a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.dxs $ +// +// 7 11/02/12 7:13a Calvinchen +// [TAG] EIP64328 +// [Category] Improvement +// [Description] Improvement: +// 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI +// 2.3.1 specifications. +// BugFix: +// 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed +// after restored. +// 2. (EIP98199) The #### in Boot#### should be upper case. +// [Files] SMIFlash.mak +// SMIFlash.dxs +// SMIFlash.c +// SMIFlash.chm +// SMIFlashLinks.c +// SMIFlashDxe.dxs +// SMIFlash.cif +// +// 6 12/14/10 3:51a Klzhan +// Remove dependency of USB protocol. +// USB might be remove in some Mobile when FAST_BOOT is on. +// +// 5 4/07/10 1:56a Rameshr +// USB K/B and USB M/S should be stopped during flashing BIOS. +// EIP 37130 +// +// 4 12/21/09 4:41a Klzhan +// +// 3 5/22/09 8:19p Felixp +// SmiFlash module is updated to replace Flash library calls with the +// calls to new Core 4.6.3.6 Flash Protocol . +// +// 2 5/11/07 1:47p Felixp +// +//********************************************************************** +// +// +// Name: SMIFlash_dxs +// +// Description: This file is the dependency file for the SMIFlash driver. +// +// +//********************************************************************** + +#include +#if PI_SPECIFICATION_VERSION >= 0x1000A +#include +#include +#else +#include +#include +#endif +#include + +DEPENDENCY_START +#if PI_SPECIFICATION_VERSION >= 0x1000A + EFI_SMM_BASE2_PROTOCOL_GUID AND + EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID AND +#else + EFI_SMM_BASE_PROTOCOL_GUID AND + EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND +#endif + FLASH_SMM_PROTOCOL_GUID +DEPENDENCY_END + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** \ No newline at end of file diff --git a/Core/EM/SMIFlash/SMIFlash.mak b/Core/EM/SMIFlash/SMIFlash.mak new file mode 100644 index 0000000..cb840d3 --- /dev/null +++ b/Core/EM/SMIFlash/SMIFlash.mak @@ -0,0 +1,183 @@ +#//**********************************************************************// +#//**********************************************************************// +#//** **// +#//** (C)Copyright 1985-2005, American Megatrends, Inc. **// +#//** **// +#//** All Rights Reserved. **// +#//** **// +#//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **// +#//** **// +#//** Phone: (770)-246-8600 **// +#//** **// +#//**********************************************************************// +#//**********************************************************************// + +#************************************************************************// +# $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.mak 13 11/02/12 7:13a Calvinchen $ +# +# $Revision: 13 $ +# +# $Date: 11/02/12 7:13a $ +#************************************************************************// +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.mak $ +# +# 13 11/02/12 7:13a Calvinchen +# [TAG] EIP64328 +# [Category] Improvement +# [Description] Improvement: +# 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI +# 2.3.1 specifications. +# BugFix: +# 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed +# after restored. +# 2. (EIP98199) The #### in Boot#### should be upper case. +# [Files] SMIFlash.mak +# SMIFlash.dxs +# SMIFlash.c +# SMIFlash.chm +# SMIFlashLinks.c +# SMIFlashDxe.dxs +# SMIFlash.cif +# +# 12 5/29/12 5:45a Klzhan +# [TAG] EIP86878 +# [Category] Improvement +# [Description] Restore SMBIOS data when recovery. +# [Files] SMIFlash.sdl +# SMIFlash.mak +# SMIFlash.dxs +# SMIFlash.c +# SMIFlash.chm +# SMIFlashLinks.c +# SMIFlash.cif +# +# 11 5/23/12 3:01a Klzhan +# [TAG] EIP81706 +# [Category] Improvement +# [Description] Restore variables when recovery. +# +# 10 3/06/12 2:41a Klzhan +# Improvement : +# 1. Add non SMM Elinks +# 2. Search Variables on in-active NVRam. +# +# 9 11/23/11 3:39a Calvinchen +# [TAG] EIP54533 +# [Category] Improvement +# [Description] 1. Removed BiosLockEnablePatchHook hook. Moved to +# Chipset file. +# 2. Also enable/disable PS2 keyboard in Enable/DisableUSBKBD hook. +# 3. (EIP54533) Request for afu capable updating OEM firmware volumes +# [Files] SMIFlash.sdl +# SMIFlash.mak +# SMIFlash.chm +# SMIFlashLinks.c +# +# 8 3/23/11 4:44a Calvinchen +# [TAG] EIP53067 +# [Category] Improvement +# [Description] Modified for OEM Secure BIOS Update Requirements. +# [Files] SMIFlash.sdl +# SMIFlash.mak +# SMIFlash.dxs +# SMIFlash.c +# SMIFlash.chm +# SMIFlashLinks.c +# SMIFlash.cif +# +# 7 6/15/10 3:11a Klzhan +# Improvement: Add Elink to modify GetFlashInfo. +# +# 6 2/02/09 6:42p Fredericko +# +# 5 1/29/09 5:36p Fredericko +# modified build for SMIFLASH_PRE_UPDATE_LIST and +# SMIFLASH_END_UPDATE_LIST. See EIP 18819 +# +# 4 8/15/07 7:07p Pats +# Modified to support preservation of passwords through flashing. +# +# 3 12/29/06 3:04p Felixp +# 1. Updated to use new Flash Interface. +# 2. Embedded Controller support added. +# +# 2 12/02/05 11:48a Felixp +# +# 1 4/05/05 3:47p Sivagarn +# Initial Checkin +# +#************************************************************************// + +all : SMIFlash + +SMIFLASH_BUILD_DIR = $(BUILD_DIR)\$(SMI_FLASH_DIR) + +SMIFlash : $(SMIFLASH_BUILD_DIR)\RomLayout.obj $(BUILD_DIR)\SMIFlash.mak SMIFlashBin + +SMIFlashObjects =\ +$(SMIFLASH_BUILD_DIR)\SMIFlash.obj\ +$(SMIFLASH_BUILD_DIR)\SMIFlashLinks.obj\ +$(SMIFLASH_BUILD_DIR)\RomLayout.obj\ +$(BUILD_DIR)\$(NVRAM_DIR)\NVRAMRead.obj\ + +SMIFLASH_LISTS = \ +/D\"PRESERVE_FFS_GUID=$(SMIFlashPreserveRomHoleGuid)\"\ +/D\"SMIFLASH_IN_SMM_LIST=$(SMIFlashInSmmList)\"\ +/D\"SMIFLASH_NOT_IN_SMM_LIST=$(SMIFlashNotSmmList)\"\ +/D\"SMIFLASH_END_UPDATE_LIST=$(SMIFlashEndUpdateList)\"\ +/D\"SMIFLASH_PRE_UPDATE_LIST=$(SMIFlashPreUpdateList)\"\ +/D\"SMIFLASH_PRE_HANDLER_LIST=$(SMIFlashPreHandlerList)\"\ +/D\"SMIFLASH_END_HANDLER_LIST=$(SMIFlashEndHandlerList)\" + +$(BUILD_DIR)\SMIFlash.mak : $(SMI_FLASH_DIR)\SMIFlash.cif $(SMI_FLASH_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SMI_FLASH_DIR)\SMIFlash.cif $(CIF2MAK_DEFAULTS) + +SMIFlashBin : $(AMIDXELIB) $(FLASHLIB) $(PRESERVE_LIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SMIFlash.mak all\ + GUID=BC327DBD-B982-4f55-9F79-056AD7E987C5\ + OBJECTS="$(SMIFlashObjects)" \ + ENTRY_POINT=SMIFlashDriverEntryPoint\ + "EXT_HEADERS=$(BUILD_DIR)\token.h"\ + "CFLAGS=$(CFLAGS) /DVFRCOMPILE $(SMIFLASH_LISTS)"\ +!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A + TYPE=DXESMM_DRIVER\ + DEPEX1=$(SMI_FLASH_DIR)\SMIFlash.dxs \ + DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \ + DEPEX2=$(SMI_FLASH_DIR)\SMIFlashDxe.dxs \ + DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \ +!ELSE + TYPE=BS_DRIVER\ + DEPEX1=$(SMI_FLASH_DIR)\SMIFlash.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ +!ENDIF + COMPRESS=1 + +$(SMIFLASH_BUILD_DIR)\RomLayout.obj : $(BUILD_DIR)\RomLayout.c + $(CC) /Fo$@ $(CFLAGS) $(BUILD_DIR)\RomLayout.c + +#--------------------------------------------------------------------------- +# Reflash link file +#--------------------------------------------------------------------------- +!IF "$(RECOVERY_PRESERVE_VARS_IN_SMM)"=="1" +ReFlashBin : $(BUILD_DIR)\ReflashHooks.obj + +$(BUILD_DIR)\ReflashHooks.obj : $(SMI_FLASH_DIR)\SMIFlashLinks.c + $(CC) /Fo$(BUILD_DIR)\ReflashHooks.obj $(CFLAGS) /D_OUTSIDE_SMM_ $(SMI_FLASH_DIR)\SMIFlashLinks.c +!ENDIF + +#//**********************************************************************// +#//**********************************************************************// +#//** **// +#//** (C)Copyright 1985-2005, American Megatrends, Inc. **// +#//** **// +#//** All Rights Reserved. **// +#//** **// +#//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **// +#//** **// +#//** Phone: (770)-246-8600 **// +#//** **// +#//**********************************************************************// +#//**********************************************************************// diff --git a/Core/EM/SMIFlash/SMIFlash.sdl b/Core/EM/SMIFlash/SMIFlash.sdl new file mode 100644 index 0000000..7cdc8e2 --- /dev/null +++ b/Core/EM/SMIFlash/SMIFlash.sdl @@ -0,0 +1,349 @@ +TOKEN + Name = "SMIFlash_SUPPORT" + Value = "1" + Help = "Main switch to enable SMIFlash support in Project" + TokenType = Boolean + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "SMI_FLASH_INTERFACE_VERSION" + Value = "11" + Help = "Version of the SMI Flash Interface" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "REPORT_NCB_BY_ROM_LAYOUT" + Value = "0" + Help = "Report NCBs by ROM Layout Definitions." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "PRESERVE_PASSWORDS" + Value = "0" + Help = "1 - Preserve passwords through flashing. 0 - Do not preserve passwords." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "PRESERVE_EFIBOOTORDER" + Value = "1" + Help = "1 - Preserve EFI BootOrder through flashing. 0 - Do not preserve EFI BootOrder." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "AFU_BUFFER_IN_SHADOW" + Value = "0" + Help = "1 - AFU will store the buffer pointer in F-segment If Afu support." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "DISABLE_PWR_BUTTON" + Value = "0" + Help = "1 - Disable PWR Button when flashing BIOS in DOS." + TokenType = Boolean + TargetH = Yes +End + +PATH + Name = "SMI_FLASH_DIR" +End + +MODULE + Help = "Includes SMIFlash.mak to Project" + File = "SMIFlash.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SMIFlash.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +ELINK + Name = "PreserveSetupPassword," + Parent = "SMIFlashPreUpdateList" + Token = "PRESERVE_PASSWORDS" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "RestoreSetupPassword," + Parent = "SMIFlashEndUpdateList" + Token = "PRESERVE_PASSWORDS" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "PreserveEfiBootOrders," + Parent = "SMIFlashPreUpdateList" + Token = "PRESERVE_EFIBOOTORDER" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "RestoreEfiBootOrders," + Parent = "SMIFlashEndUpdateList" + Token = "PRESERVE_EFIBOOTORDER" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "DisablePowerButton," + Parent = "SMIFlashPreUpdateList" + Token = "DISABLE_PWR_BUTTON" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "EnablePowerButton," + Parent = "SMIFlashEndUpdateList" + Token = "DISABLE_PWR_BUTTON" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "DisableUSBKBD," + Parent = "SMIFlashPreUpdateList" + InvokeOrder = AfterParent +End + +ELINK + Name = "EnableUSBKBD," + Parent = "SMIFlashEndUpdateList" + InvokeOrder = AfterParent +End + + +ELINK + Name = "UpdateShadowBuffer," + Parent = "SMIFlashPreHandlerList" + Token = "AFU_BUFFER_IN_SHADOW" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "ClearShadowBuffer," + Parent = "SMIFlashEndHandlerList" + Token = "AFU_BUFFER_IN_SHADOW" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(BUILD_DIR)\AMICSPLib.Lib" + Parent = "PRESERVE_LIB" + Token = "AFU_BUFFER_IN_SHADOW" "=" "1" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "ReassignNcbByRomLayout," + Parent = "SMIFlashEndHandlerList" + Token = "REPORT_NCB_BY_ROM_LAYOUT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "PostRestoreVariables," + Parent = "SMIFlashNotSmmList" + Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1" + Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "USBNonSmmFunction," + Parent = "SMIFlashNotSmmList" + InvokeOrder = AfterParent +End + +ELINK + Name = "USBInSmmFunction," + Parent = "SMIFlashInSmmList" + InvokeOrder = AfterParent +End + +ELINK + Name = "SMIFlashInSmmList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "SMIFlashPreserveRomHoleGuid" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "SMIFlashNotSmmList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "SMIFlashPreUpdateList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "SMIFlashEndUpdateList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "SMIFlashPreHandlerList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "SMIFlashEndHandlerList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "PRESERVE_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "RestoreSecureVariablesPreHandler," + Parent = "SMIFlashPreHandlerList" + Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1" + Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "RestoreSecureVariablesEndHandler," + Parent = "SMIFlashEndHandlerList" + Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1" + Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "ClearFFSState," + Parent = "SecureUpdBeforeSmiflashWrite," + InvokeOrder = AfterParent +End + +ELINK + Name = "PreserveWin8Variables," + Parent = "SMIFlashPreUpdateList" + InvokeOrder = AfterParent +End + +ELINK + Name = "RestoreWin8Variables," + Parent = "SMIFlashEndUpdateList" + InvokeOrder = AfterParent +End + +TOKEN + Name = "NON_SECURE_NCB_UPDATE" + Value = "0" + Help = "1 - Allow NCB Update w/o Secure check." + TokenType = Boolean + TargetH = Yes + Token = "SecSMIFlash_SUPPORT" "=" "1" +End + +ELINK + Name = "NCBUpdate," + Parent = "SecureUpdBeforeSmiflashWrite," + Token = "NON_SECURE_NCB_UPDATE" "=" "1" + Token = "SecSMIFlash_SUPPORT" "=" "1" + InvokeOrder = BeforeParent +End + +ELINK + Name = "NCBUpdate," + Parent = "SecureUpdBeforeSmiflashWrite," + Token = "NON_SECURE_NCB_UPDATE" "=" "1" + Token = "SecSMIFlash_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +TOKEN + Name = "RECOVERY_PRESERVE_VARS_IN_SMM" + Value = "1" + Help = "1 - Preserved variables thru SMIFlash Func 0x20/0x24 if Capsule/Recovery mode of Secure Flash." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Token = "SecSMIFlash_SUPPORT" "=" "1" +End + +TOKEN + Name = "RECOVERY_PRESERVE_ROMHOLE" + Value = "1" + Help = "1 - Preserved Romholes if Capsule/Recovery mode of Secure Flash." + TokenType = Boolean + TargetH = Yes + Token = "SecSMIFlash_SUPPORT" "=" "1" +End + +ELINK + Name = "RecoveryPreserveRomHoles," + Parent = "SMIFlashNotSmmList" + Token = "RECOVERY_PRESERVE_ROMHOLE" "=" "1" + Token = "SecSMIFlash_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "RecoveryHookBeforeFlash," + Parent = "OemBeforeFlashUpdateList" + Token = "RECOVERY_PRESERVE_VARS_IN_SMM" "=" "1" + Token = "SecSMIFlash_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "RecoveryHookAfterFlash," + Parent = "OemAfterFlashUpdateList" + Token = "RECOVERY_PRESERVE_VARS_IN_SMM" "=" "1" + Token = "SecSMIFlash_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "{0xFD44820B,0xF1AB,0x41c0,0xAE,0x4E,0x0C,0x55,0x55,0x6E,0xB9,0xBD}," + Parent = "SMIFlashPreserveRomHoleGuid" + InvokeOrder = AfterParent +End + +TOKEN + Name = "BACKUP_NVRAM_WHEN_FLASH" + Value = "0" + Help = "1 - Keep Current NVRAM, update new NVRAM to another NVRAM Region." + TokenType = Boolean + TargetH = Yes + Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1" +End + +ELINK + Name = "CheckNVRAMArea," + Parent = "SMIFlashPreUpdateList" + Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1" + Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "0" + InvokeOrder = BeforeParent +End + +ELINK + Name = "UpdateNVRAMArea," + Parent = "SMIFlashEndUpdateList" + Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1" + Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "0" + InvokeOrder = BeforeParent +End diff --git a/Core/EM/SMIFlash/SMIFlashDxe.dxs b/Core/EM/SMIFlash/SMIFlashDxe.dxs new file mode 100644 index 0000000..09c5a47 --- /dev/null +++ b/Core/EM/SMIFlash/SMIFlashDxe.dxs @@ -0,0 +1,72 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlashDxe.dxs 2 11/02/12 7:14a Calvinchen $ +// +// $Revision: 2 $ +// +// $Date: 11/02/12 7:14a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlashDxe.dxs $ +// +// 2 11/02/12 7:14a Calvinchen +// [TAG] EIP64328 +// [Category] Improvement +// [Description] Improvement: +// 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI +// 2.3.1 specifications. +// BugFix: +// 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed +// after restored. +// 2. (EIP98199) The #### in Boot#### should be upper case. +// [Files] SMIFlash.mak +// SMIFlash.dxs +// SMIFlash.c +// SMIFlash.chm +// SMIFlashLinks.c +// SMIFlashDxe.dxs +// SMIFlash.cif +// +// +//********************************************************************** +// +// +// Name: SMIFlashDxe.dxs +// +// Description: This file is the dependency file for the SMIFlash driver. +// +// +//********************************************************************** +#include + +DEPENDENCY_START + FLASH_PROTOCOL_GUID +DEPENDENCY_END + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** \ No newline at end of file diff --git a/Core/EM/SMIFlash/SMIFlashLinks.c b/Core/EM/SMIFlash/SMIFlashLinks.c new file mode 100644 index 0000000..88e3155 --- /dev/null +++ b/Core/EM/SMIFlash/SMIFlashLinks.c @@ -0,0 +1,2227 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlashLinks.c 52 4/11/16 9:22p Tristinchou $ +// +// $Revision: 52 $ +// +// $Date: 4/11/16 9:22p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlashLinks.c $ +// +// 52 4/11/16 9:22p Tristinchou +// [TAG] EIP261702 +// [Category] Improvement +// [Description] Register event to get UsbRtKbcAccessControl() function +// to disable keyboard +// +// 51 4/07/15 2:52a Tristinchou +// [TAG] EIP211721 +// [Category] Improvement +// [Description] Modify codes to call UsbRtKbcAccessControl() instead of +// using outside smm pointer. +// +// 50 5/06/14 5:01a Calvinchen +// [TAG] EIP166597 +// [Category] New Feature +// [Description] Removing RT from variables could cause problems +// accessing variables if PRESERVE_EFIBOOTORDER=1 +// [Files] SMIFlash.chm +// SMIFlashLinks.c +// SMIFlash.cif +// +// 49 3/10/14 2:44a Calvinchen +// [TAG] EIP156780 +// [Category] Improvement +// [Description] Boot related variables preserving in Aptio 4 SmiFlash +// +// 48 12/06/13 4:20a Calvinchen +// [TAG] EIP145305 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Variable Restored failed after re-flashing when Nvram is in +// Backup Area. +// [RootCause] NVRAM State is not restored after re-flashing. +// [Solution] Restore Nvram State. +// [Files] SMIFlash.sdl +// SMIFlash.chm +// SMIFlashLinks.c +// SMIFlash.cif +// +// 47 12/20/12 8:52a Calvinchen +// [TAG] EIP103562 +// [Category] Improvement +// [Description] Need a way to preserve debug policy NV+BS variable( +// WIN8 Logo requirement) in Nvram driver +// [Files] SMIFlashLinks.c +// +// 46 12/06/12 4:56a Calvinchen +// [TAG] EIP106623 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] SmiFlash breaks build when NVRAM_BACKUP_ADDRESS is not +// defined. +// [RootCause] Smiflash don't remove the related procedures if +// FAULT_TOLERANT_NVRAM_UPDATE is disabled. +// [Solution] Remove the related procedures if +// FAULT_TOLERANT_NVRAM_UPDATE is disabled. +// [Files] SMIFlashLinks.c +// +// 45 11/20/12 5:39a Calvinchen +// [TAG] EIP106623 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] SmiFlash breaks build when FAULT_TOLERANT_NVRAM_UPDATE is +// disabled +// [RootCause] Smiflash don't remove the related procedures if +// FAULT_TOLERANT_NVRAM_UPDATE is disabled. +// [Solution] Remove the related procedures if +// FAULT_TOLERANT_NVRAM_UPDATE is disabled. +// [Files] SMIFlashLinks.c +// +// 44 11/19/12 3:48a Calvinchen +// SmiFlash does not compile when CryptoPkg/Secure Boot Pkg/Secure Flash +// Pkg are not in the project. +// +// 43 11/02/12 7:13a Calvinchen +// [TAG] EIP64328 +// [Category] Improvement +// [Description] Improvement: +// 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI +// 2.3.1 specifications. +// BugFix: +// 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed +// after restored. +// 2. (EIP98199) The #### in Boot#### should be upper case. +// [Files] SMIFlash.mak +// SMIFlash.dxs +// SMIFlash.c +// SMIFlash.chm +// SMIFlashLinks.c +// SMIFlashDxe.dxs +// SMIFlash.cif +// +// 41 7/13/12 2:14a Klzhan +// Fix : Backup Flag not clear property. +// +// 4 7/02/12 3:45a Nerofan +// Update to version 36 +// +// 36 6/13/12 5:17a Klzhan +// [TAG] EIP92023 +// [Category] Improvement +// [Description] Emulation SMI should be disabled before Read/Write +// 60/64 ports in smiflash. +// +// 35 6/01/12 5:13a Klzhan +// Fix sometimes Deadloop when GetNextVariableName +// +// 34 5/31/12 2:22a Klzhan +// Correct pointers. +// +// 33 5/30/12 4:19a Klzhan +// Remove un-used GUID. +// +// 32 5/29/12 5:45a Klzhan +// [TAG] EIP86878 +// [Category] Improvement +// [Description] Restore SMBIOS data when recovery. +// [Files] SMIFlash.sdl +// SMIFlash.mak +// SMIFlash.dxs +// SMIFlash.c +// SMIFlash.chm +// SMIFlashLinks.c +// SMIFlash.cif +// +// 31 5/25/12 6:26a Klzhan +// [TAG] EIP90325 +// [Category] Improvement +// [Description] UEFI Compliant - Global Defined Variables test +// +// 30 5/24/12 11:57p Klzhan +// Fix exception error after flash NVRAM. +// +// 29 5/23/12 2:58a Klzhan +// [TAG] EIP81706 +// [Category] Improvement +// [Description] Restore variables when recovery. +// +// 28 5/22/12 4:43a Klzhan +// [TAG] EIP90325 +// [Category] Improvement +// [Description] Fix : UEFI Compliant - Globally Defined Variables test +// fail +// +// 27 5/22/12 3:09a Klzhan +// [TAG] EIP87892 +// [Category] Improvement +// [Description] As Windows Logo requirment, need support to preserve +// all UEFI variables with VendorGuid {77fa9abd-0359-4d32-bd60- +// 28f4e78f784b} between flash updates +// +// 26 5/22/12 3:00a Klzhan +// Set secure variables with authenticated Attributes. +// +// 25 5/21/12 4:48a Klzhan +// Improvement : POST resetore only been called after AFU update. +// +// 24 4/05/12 4:40a Klzhan +// BugFix : AFU will stop when SecureFlash is enabled. +// +// 23 3/27/12 11:19p Klzhan +// [TAG] EIP86161 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Build Error when X64_BUILD = 0 +// +// 22 3/14/12 6:59a Klzhan +// Remove un-use code +// +// 21 3/09/12 1:02a Klzhan +// Fix variables not been restored property. +// +// 20 3/06/12 3:01a Klzhan +// Improvement : +// Support restore secure variables in POST. +// +// 19 2/10/12 7:14a Klzhan +// Support NCB blocks updated with secure flash updated. +// +// 18 2/07/12 3:05a Klzhan +// BugFIx : Fix erase size not correct. +// +// 17 2/06/12 3:27a Klzhan +// [TAG] EIP80781 +// [Category] Improvement +// [Description] Support OA key in NCB updated when Scure Flash Enabled +// +// 15 11/23/11 3:39a Calvinchen +// [TAG] EIP54533 +// [Category] Improvement +// [Description] 1. Removed BiosLockEnablePatchHook hook. Moved to +// Chipset file. +// 2. Also enable/disable PS2 keyboard in Enable/DisableUSBKBD hook. +// 3. (EIP54533) Request for afu capable updating OEM firmware volumes +// [Files] SMIFlash.sdl +// SMIFlash.mak +// SMIFlash.chm +// SMIFlashLinks.c +// +// 14 11/03/11 7:09a Klzhan +// [TAG] EIP73027 +// [Category] Improvement +// [Description] Avoid un-inital variable used. +// +// 13 10/31/11 11:07p Klzhan +// [TAG] EIP73017 +// [Category] Improvement +// [Description] SavedBootXXX, conditionally not set. +// +// 12 5/18/11 6:03a Klzhan +// BugFix : Memory will be crashed, free memory property. +// +// 11 5/17/11 3:23a Klzhan +// Add Elinks to read buffer form shadow. +// +// 10 5/16/11 4:03a Klzhan +// [TAG] EIP35562 +// [Category] Improvement +// [Description] Boot#### variable,the #### should be upper case of A-F. +// [Files] SMIFlahElinks.c +// +// 9 5/05/11 3:05a Klzhan +// +// 8 4/26/11 6:07a Calvinchen +// [TAG] EIP58402 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] AFUxxx flash utility hangs when Bootxxxx variable size is +// greater than 0x200 +// [RootCause] The size of Boot0003 variable in the customer's project +// is 0x242 bytes, which causes the memory corruption. +// [Solution] Used allocate smm buffer instead of static structure. +// [Files] SMIFlashLinks.c +// +// 6 3/23/11 4:44a Calvinchen +// [TAG] EIP53067 +// [Category] Improvement +// [Description] Modified for OEM Secure BIOS Update Requirements. +// [Files] SMIFlash.sdl +// SMIFlash.mak +// SMIFlash.dxs +// SMIFlash.c +// SMIFlash.chm +// SMIFlashLinks.c +// SMIFlash.cif +// +// 5 12/14/10 4:38a Klzhan +// [TAG] EIP49217 +// [Category] Improvement +// [Description] Preserve BOOTxxxx for all EFI OS. +// [Files] SMIFlashLinks.c +// +// 4 12/14/10 4:18a Klzhan +// Move Locate USB Protocol to SMIFlashLinks.c. +// +// 3 12/14/10 3:49a Klzhan +// Improvement : check is ROM layout changed before update NVRAM. +// +// 2 12/14/10 1:18a Klzhan +// Remove debug codes. +// +// 1 12/14/10 1:15a Klzhan +// Improvement : Move ELinks to SMIFlashLinks.c. +// +//********************************************************************** +// +// +// Name: SMIFlashLinks.c +// +// Description: Elinks to SMIFlash. +// +// +//********************************************************************** +#include +#include +#include +#include +#include +#if AMIUSB_SUPPORT == 1 +#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) +#include +#endif +#endif + +#include +#include +#include +#include +#include +#include +#include "timestamp.h" +//---------------------------------------------------------------------- +// component MACROs +GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCertTypePkcs7Guid = EFI_CERT_TYPE_PKCS7_GUID; + +//---------------------------------------------------------------------- +// Module defined global variables +extern FLASH_PROTOCOL *Flash; +//*********** INSIDE SMM *********************************************** +#if !defined _OUTSIDE_SMM_ + +extern ROM_AREA RomLayout[]; +extern VOID ChipsetFlashDeviceWriteEnable(); + +EFI_GUID RecoveryPreserveGUID[] = +{ + { 0x05ca01fc, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca01fd, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca01fe, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca01ff, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0200, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0201, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0202, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0203, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0204, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0205, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0206, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0207, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0208, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca0209, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca020a, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + { 0x05ca020b, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 }, + PRESERVE_FFS_GUID + {NULL} +}; + +//---------------------------------------------------------------------- +// Module specific global variable +#define ROM_LAYOUT_FFS_GUID \ + { 0x0DCA793A, 0xEA96, 0x42d8, 0xBD, 0x7B, 0xDC, 0x7F, 0x68, 0x4E, 0x38, 0xC1 } +#define AMITSESETUP_GUID \ + { 0xc811fa38, 0x42c8, 0x4579, 0xa9, 0xbb, 0x60, 0xe9, 0x4e, 0xdd, 0xfb, 0x34 } +#define WIN8_GUID \ + { 0x77FA9ABD, 0x0359, 0x4D32, 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B } +EFI_GUID gWin8Guid = WIN8_GUID; +#define DefaultVariableSize 100 + +EFI_GUID gAmiTseSetupGuid = AMITSESETUP_GUID; +AMITSESETUP gAmiTseData; +UINT32 gAmiTseDataAttr = 0; + +#pragma pack(1) +typedef struct { + CHAR16 BootVarName[0x20]; + UINT16 BootOrderNO; + UINTN BootXXXXSize; +//- UINT8 *BootXXXX; +} RESTORE_BOOTORDER; +EFI_PHYSICAL_ADDRESS gSmmBootOrder = NULL; +UINT8 gNumBootDevice = 0; +#define RESTORE_BOOT_ORDER_BUFFER 0x4000 +#define BOOT_ORDER_OFFSET (RESTORE_BOOT_ORDER_BUFFER - 0x100) +#define LEGACY_BOOT_ORDER_OFFSET (RESTORE_BOOT_ORDER_BUFFER - 0x200) + +typedef struct { + CHAR16 *BootVarName; + EFI_GUID *Guid; +} RESTORE_VARIABLES; + +typedef struct { + UINT32 Attrib; + UINTN Size; + UINT8* Data; +} RESTORE_ATTR; + +typedef struct { + RESTORE_VARIABLES rVar; + RESTORE_ATTR rATTR; + UINTN NextData; +} RESTORE_VAR; +#pragma pack() +RESTORE_VAR *RestoreVarList; +#if AMIUSB_SUPPORT == 1 +#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) +EFI_KBC_ACCESS_CONTROL gUsbRtKbcAccessControl = NULL; +#endif +#endif + +#define EFI_IMAGE_SECURITY_DATABASE L"db" +#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx" +#define EFI_PLATFORM_KEY_NAME L"PK" +#define EFI_KEY_EXCHANGE_KEY_NAME L"KEK" + +EFI_GUID PKeyFileGuid = EFI_GLOBAL_VARIABLE; +EFI_GUID KekFileGuid = EFI_GLOBAL_VARIABLE; +EFI_GUID DbFileGuid = EFI_IMAGE_SECURITY_DATABASE_GUID; +EFI_GUID DbxFileGuid = EFI_IMAGE_SECURITY_DATABASE_GUID; + +//-VOID CheckNVRAMArea(VOID); +EFI_FFS_FILE_STATE NvramFFSState; +EFI_FFS_FILE_STATE *NvramFFSStatePtr; + +RESTORE_VARIABLES RestoreVariables[] = { +{EFI_IMAGE_SECURITY_DATABASE1, &DbxFileGuid}, +{EFI_IMAGE_SECURITY_DATABASE, &DbFileGuid}, +{EFI_KEY_EXCHANGE_KEY_NAME, &KekFileGuid}, +{EFI_PLATFORM_KEY_NAME, &PKeyFileGuid}, +{NULL,NULL} +}; + +#define NUM_OF_RESTORE_VARS (sizeof(RestoreVariables)/sizeof(RESTORE_VARIABLES)) + +#ifndef EFI_VARIABLE_AUTHENTICATION_2 +typedef struct { + EFI_TIME TimeStamp; + WIN_CERTIFICATE_UEFI_GUID AuthInfo; +} EFI_VARIABLE_AUTHENTICATION_2; +#endif + +static EFI_TIME EfiTimeStamp = { + FOUR_DIGIT_YEAR_INT, + TWO_DIGIT_MONTH_INT, + TWO_DIGIT_DAY_INT, + TWO_DIGIT_HOUR_INT, + TWO_DIGIT_MINUTE_INT, + TWO_DIGIT_SECOND_INT,0,0,0,0,0}; + +RESTORE_ATTR RestoreAttr[NUM_OF_RESTORE_VARS - 1]; + +// SMM Nvram Control Protocol Definitions +typedef EFI_STATUS (*SHOW_BOOT_TIME_VARIABLES)(BOOLEAN Show); +typedef struct{ + SHOW_BOOT_TIME_VARIABLES ShowBootTimeVariables; +} AMI_NVRAM_CONTROL_PROTOCOL; + +AMI_NVRAM_CONTROL_PROTOCOL *LocateNvramControlSmmProtocol(){ + static EFI_GUID gAmiNvramControlProtocolGuid = { 0xf7ca7568, 0x5a09, 0x4d2c, { 0x8a, 0x9b, 0x75, 0x84, 0x68, 0x59, 0x2a, 0xe2 } }; + return GetSmstConfigurationTable(&gAmiNvramControlProtocolGuid); +} +AMI_NVRAM_CONTROL_PROTOCOL *gNvramControl = NULL; +//---------------------------------------------------------------------- +// externally defined variables +//---------------------------------------------------------------------- +// Function definitions +// BIT00 = 1 --> Update NVRAM +// BIT01 = 1 --> Update NVRAM Backup Address +UINT8 UpdateNVram = 0; +UINT64 BufAddr; +UINT8 FFSState; +#if FAULT_TOLERANT_NVRAM_UPDATE +// +//---------------------------------------------------------------------- +// Procedure: MoveNVRamToAnotherRegion +// +// Description: Copy current NVRAM to another NBRAM region +// +// +// Input: Data - SW SMI value number +// pInfoBlock - AFU Data Buffer +// +// Output: None +// +//---------------------------------------------------------------------- +// +VOID +MoveNVRamToAnotherRegion +( + VOID +) +{ + // Move NVRam to another Region + // We can keep secure variables + EFI_STATUS Status; + UINT32 UpdateAddress, SourceAddress, i, Buffer32; + UINTN NumberOfPages; + EFI_PHYSICAL_ADDRESS Phy_Address; + UINT8* Buffer; + + if(UpdateNVram & BIT00) + { + UpdateAddress = NVRAM_BACKUP_ADDRESS; + SourceAddress = NVRAM_ADDRESS; + } + else + { + UpdateAddress = NVRAM_ADDRESS; + SourceAddress = NVRAM_BACKUP_ADDRESS; + } + NumberOfPages = ((NVRAM_SIZE) >> 12); + Status = pSmst->SmmAllocatePages(AllocateAnyPages, + EfiRuntimeServicesData, NumberOfPages, &Phy_Address); + + Flash->Erase((UINT8*)UpdateAddress, NVRAM_SIZE); + if(!EFI_ERROR(Status)) + { + Buffer = (UINT8*)Phy_Address; + Flash->Read( + (UINT8*)(SourceAddress), NVRAM_SIZE, Buffer); + + Flash->Write( + (UINT8*)(UpdateAddress), NVRAM_SIZE, Buffer); + + pSmst->SmmFreePages(Phy_Address, NumberOfPages); + }else + { + // If no memory , just do it 4 bytes one time. + for(i = 0; i < NVRAM_SIZE ; i += sizeof(UINT32)) + { + Flash->Read( + (UINT8*)(SourceAddress + i), sizeof(UINT32), &Buffer32); + if(Buffer32 == 0xFFFFFFFF) + continue; + Flash->Write( + (UINT8*)(UpdateAddress + i), sizeof(UINT32), &Buffer32); + } + } + +} +#endif // #if FAULT_TOLERANT_NVRAM_UPDATE +// +//---------------------------------------------------------------------- +// Procedure: ClearFFSState +// +// Description: Clear FFS State of Buffer +// +// +// Input: Data - SW SMI value number +// pInfoBlock - AFU Data Buffer +// +// Output: None +// +//---------------------------------------------------------------------- +// +VOID ClearFFSState( + UINT8 Data, + UINT64 pInfoBlock +) +{ + FUNC_BLOCK *pFuncBuff = (FUNC_BLOCK*)pInfoBlock; + UINT32 FlashAddress; + + FlashAddress = (pFuncBuff->BlockAddr + (0xFFFFFFFF - FLASH_SIZE + 1)); + // Runs in Main Address, clear FFSState + // if power-off while update, system runs in Backup address + if((Data == SMIFLASH_WRITE_FLASH) && (FlashAddress == NVRAM_ADDRESS)) + { + BufAddr = pFuncBuff->BufAddr; + FFSState = *(UINT8*)(pFuncBuff->BufAddr + 0x5F); + *(UINT8*)(pFuncBuff->BufAddr + 0x5F) = 0xFF; + } +} +#if FAULT_TOLERANT_NVRAM_UPDATE +// +//---------------------------------------------------------------------- +// Procedure: RestoreSecureVariablesPreHandler +// +// Description: Clear and Set FFS state when NVRAM region updated +// +// +// Input: Data - SW SMI value number +// pInfoBlock - AFU Data Buffer +// +// Output: None +// +//---------------------------------------------------------------------- +// +VOID RestoreSecureVariablesPreHandler( + UINT8 Data, + UINT64 pInfoBlock +) +{ + FUNC_BLOCK *pFuncBuff = (FUNC_BLOCK*)pInfoBlock; + UINT32 FlashAddress; + static BOOLEAN InitDone = FALSE, RunInMain = FALSE; + + if((Data != SMIFLASH_ERASE_FLASH) && + (Data != SMIFLASH_WRITE_FLASH) && + (Data != SMIFLASH_READ_FLASH)) + return; + + FlashAddress = (pFuncBuff->BlockAddr + (0xFFFFFFFF - FLASH_SIZE + 1)); + if((FlashAddress < NVRAM_ADDRESS) || + (FlashAddress >= NVRAM_ADDRESS + NVRAM_SIZE)) + return; + + if(!InitDone) + { + NVRAM_STORE_INFO MainNvram; + BOOLEAN BackupStoreValid; + VOID *BackupNvramAddress = (VOID*)NVRAM_BACKUP_ADDRESS; + + + MainNvram.NvramAddress = (UINT8*)NVRAM_ADDRESS; + MainNvram.NvramSize = NVRAM_SIZE; + if (!IsMainNvramStoreValid(&MainNvram, BackupNvramAddress,&BackupStoreValid)){ + if (BackupStoreValid) + RunInMain = FALSE; + }else + RunInMain = TRUE; + + InitDone = TRUE; + } + + // NVRam runs in NVRAM address + if(RunInMain) + { + UpdateNVram |= BIT00; + }else + { + if(NVRAM_ADDRESS > NVRAM_BACKUP_ADDRESS) + pFuncBuff->BlockAddr -= (NVRAM_ADDRESS - NVRAM_BACKUP_ADDRESS); + else + pFuncBuff->BlockAddr += (NVRAM_BACKUP_ADDRESS - NVRAM_ADDRESS); + + UpdateNVram |= BIT01; + } + + // Frist in, move current NVRam to another + if((Data == SMIFLASH_ERASE_FLASH) && (FlashAddress == NVRAM_ADDRESS)) + MoveNVRamToAnotherRegion(); + + // Runs in Main Address, clear FFSState + // if power-off while update, system runs in Backup address + if((Data == SMIFLASH_WRITE_FLASH) && (FlashAddress == NVRAM_ADDRESS)) + *(UINT8*)(pFuncBuff->BufAddr + 0x5F) = 0xFF; + +} +// +//---------------------------------------------------------------------- +// Procedure: RestoreSecureVariablesEndHandler +// +// Description: Clear and Set FFS state when NVRAM region updated +// +// +// Input: Data - SW SMI value number +// pInfoBlock - AFU Data Buffer +// +// Output: None +// +//---------------------------------------------------------------------- +// +VOID RestoreSecureVariablesEndHandler( + UINT8 Data, + UINT64 pInfoBlock +) +{ + FUNC_BLOCK *pFuncBuff = (FUNC_BLOCK*)pInfoBlock; + UINT32 FlashAddress, EndNVRamAddress, TempNVRamAddress; + UINT8 Buffer8 = 0x08; + + if(Data != SMIFLASH_WRITE_FLASH) + return; + + switch(UpdateNVram) + { + case 1: + EndNVRamAddress = NVRAM_ADDRESS + NVRAM_SIZE; + TempNVRamAddress = NVRAM_BACKUP_ADDRESS; + break; + case 2: + EndNVRamAddress = NVRAM_BACKUP_ADDRESS + NVRAM_SIZE; + TempNVRamAddress = NVRAM_ADDRESS; + break; + default: + return; + } + + FlashAddress = (pFuncBuff->BlockAddr + (0xFFFFFFFF - FLASH_SIZE + 1)); + if(FlashAddress == NVRAM_ADDRESS) + *(UINT8*)(BufAddr + 0x5F) = FFSState; + + if((FlashAddress + pFuncBuff->BlockSize) != EndNVRamAddress) + return; + + // Clear State + Flash->Write((UINT8*)(TempNVRamAddress + 0x5F), + sizeof(UINT8), &Buffer8); + + Buffer8 = 0xF8; + // Set State + Flash->Write((UINT8*)(EndNVRamAddress - NVRAM_SIZE + 0x5F), + sizeof(UINT8), &Buffer8); +} +// +//---------------------------------------------------------------------- +// Procedure: PostRestoreVariables +// +// Description: Find Variables want to restore and restore then +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +VOID +PostRestoreVariables( + VOID +) +{ + NVRAM_STORE_INFO pInfo; + UINTN HeaderSize = 0x60, i; + UINT8 Flags = NVRAM_STORE_FLAG_NON_VALATILE; + EFI_STATUS Status; + NVRAM_STORE_INFO MainNvram; + BOOLEAN BackupStoreValid, RunInMain, ClearFlag = FALSE; + VOID *BackupNvramAddress = (VOID*)NVRAM_BACKUP_ADDRESS; + UINT8 Buffer8 = 0x08; + EFI_VARIABLE_AUTHENTICATION_2 *AuthHdr2; + UINTN VarSize; + + for(i = 0 ; i < (NUM_OF_RESTORE_VARS - 1) ; i ++) + { + RestoreAttr[i].Size = 0; + Status = pRS->GetVariable(RestoreVariables[i].BootVarName, + RestoreVariables[i].Guid, + &RestoreAttr[i].Attrib, + &RestoreAttr[i].Size, + NULL); + // EFI_BUFFER_TOO_SMALL means variable exists + if(Status != EFI_BUFFER_TOO_SMALL) + break; + } + + // All secure variable exist, return + if(i == (NUM_OF_RESTORE_VARS - 1)) + ClearFlag = TRUE; + + + VERIFY_EFI_ERROR(pBS->LocateProtocol(&gFlashProtocolGuid, + NULL, &Flash)); + // Check current running region + MainNvram.NvramAddress = (UINT8*)NVRAM_ADDRESS; + MainNvram.NvramSize = NVRAM_SIZE; + if (!IsMainNvramStoreValid(&MainNvram, BackupNvramAddress,&BackupStoreValid)){ + if (BackupStoreValid) + RunInMain = FALSE; + }else + RunInMain = TRUE; + + if(RunInMain) + { + + pInfo.NvramAddress = (UINT8*)NVRAM_BACKUP_ADDRESS; + // NVRAM update successful, but variables not restored yet. + if(*(pInfo.NvramAddress + 0x5F) == 0xF8) + { + Flash->DeviceWriteEnable(); + Flash->Write((UINT8*)(pInfo.NvramAddress + 0x5F), + sizeof(UINT8), &Buffer8); + Flash->DeviceWriteDisable(); + } + } + else + pInfo.NvramAddress = (UINT8*)NVRAM_ADDRESS; + + // FFS State is 8 mneas AFU update NVRAM but variables not been restored + if(*(pInfo.NvramAddress + 0x5F) != 0x08) + return; + + pInfo.NvramSize = NVRAM_SIZE; + NvInitInfoBuffer(&pInfo, HeaderSize, Flags); + + for( ; i < (NUM_OF_RESTORE_VARS - 1) && !ClearFlag ; i ++) + { + + RestoreAttr[i].Size = 0; + Status = NvGetVariable2(RestoreVariables[i].BootVarName, + RestoreVariables[i].Guid, + &RestoreAttr[i].Attrib, + &RestoreAttr[i].Size, + NULL, + 1, + &pInfo); + + // It should be happened on frist few boots + if(Status == EFI_BUFFER_TOO_SMALL) + { + UINT8* DataBuffer = NULL; + + VarSize = RestoreAttr[i].Size + sizeof(EFI_VARIABLE_AUTHENTICATION_2); + + Status = pBS->AllocatePool (EfiBootServicesData, + VarSize, + (VOID**)&DataBuffer); + + Status = NvGetVariable2(RestoreVariables[i].BootVarName, + RestoreVariables[i].Guid, + &RestoreAttr[i].Attrib, + &RestoreAttr[i].Size, + DataBuffer + sizeof(EFI_VARIABLE_AUTHENTICATION_2), + 1, + &pInfo); + + AuthHdr2 = (EFI_VARIABLE_AUTHENTICATION_2*)DataBuffer; + MemCpy (&AuthHdr2->TimeStamp, &EfiTimeStamp, sizeof (EFI_TIME)); + AuthHdr2->AuthInfo.Hdr.dwLength = sizeof(WIN_CERTIFICATE_UEFI_GUID); + AuthHdr2->AuthInfo.Hdr.wRevision = 0x200; + AuthHdr2->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; + AuthHdr2->AuthInfo.CertType = gEfiCertTypePkcs7Guid; + + if (!EFI_ERROR(Status)) { + Status = pRS->SetVariable ( RestoreVariables[i].BootVarName, + RestoreVariables[i].Guid, + RestoreAttr[i].Attrib | \ + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, + VarSize, + DataBuffer); + pBS->FreePool (DataBuffer); + } + + } + } + Buffer8 = 0; + Flash->DeviceWriteEnable(); + Flash->Write((UINT8*)(pInfo.NvramAddress + 0x5F), + sizeof(UINT8), &Buffer8); + Flash->DeviceWriteDisable(); +} +#endif // #if FAULT_TOLERANT_NVRAM_UPDATE +// +//---------------------------------------------------------------------- +// Procedure: NCBUpdate +// +// Description: Support All NCBs updated when enable secure Flash Support +// +// +// Input: SwSmiNum - SW SMI value number +// Buffer - Flash descriptor address +// +// Output: None +// +//---------------------------------------------------------------------- +// +VOID NCBUpdate( + UINT8 Data, + UINT64 pInfoBlock +) +{ + FUNC_BLOCK *pFuncBuff = (FUNC_BLOCK*)pInfoBlock; + EFI_STATUS Status; + UINT8 *FlashAddress; + static BOOLEAN BeforeSecure = FALSE; + ROM_AREA *Area; + + if(BeforeSecure) + { + BeforeSecure = FALSE; + pFuncBuff->ErrorCode = 0; + return; + } + + if((Data != SMIFLASH_ERASE_FLASH) && (Data != SMIFLASH_WRITE_FLASH)) + return; + + FlashAddress = (UINT8*)(UINTN)(pFuncBuff->BlockAddr + + (0xFFFFFFFF - FLASH_SIZE + 1)); + for (Area = RomLayout; Area->Size != 0; Area++) { + + if(Area->Type != RomAreaTypeRaw) + continue; + + if(((UINT32)FlashAddress >= Area->Address) && + ((UINT32)FlashAddress < (Area->Address + Area->Size))) + { + if(Data == 0x22) + { + Status = Flash->Erase(FlashAddress, FLASH_BLOCK_SIZE); + pFuncBuff->ErrorCode = EFI_ERROR(Status) != 0; + BeforeSecure = TRUE; + } + if(Data == 0x23) + { + Status = Flash->Write(FlashAddress, pFuncBuff->BlockSize, + (UINT8*)pFuncBuff->BufAddr); + pFuncBuff->ErrorCode = EFI_ERROR(Status) != 0; + BeforeSecure = TRUE; + } + } + } +} +#if REPORT_NCB_BY_ROM_LAYOUT +// +//---------------------------------------------------------------------- +// Procedure: ReassignNcbByRomLayout +// +// Description: Re-assign NCBs Type Id by ROM Layout definition for +// separating NCBs. +// +// Input: SwSmiNum - SW SMI value number +// Buffer - Flash descriptor address +// +// Output: None +// +//---------------------------------------------------------------------- +// +VOID +ReassignNcbByRomLayout ( + IN UINT8 SwSmiNum, + IN UINT64 Buffer +) +{ + BLOCK_DESC *BlockDesc; + ROM_AREA *Area; + UINT16 i, j, LastNcb; + UINT8 NCBTypeId = NC_BLOCK; + + // return if SW SMI value is not "Get Flash Info" + if (SwSmiNum != SMIFLASH_GET_FLASH_INFO) return; + + BlockDesc = (BLOCK_DESC*)&((INFO_BLOCK*)Buffer)->Blocks; + for (i = 0, LastNcb = 0xffff; i < ((INFO_BLOCK*)Buffer)->TotalBlocks; i++) { + if (BlockDesc[i].Type < NC_BLOCK) continue; + // check whether NCB is described in RomLayout. + for (Area = RomLayout; Area->Size != 0; Area++) { + if (BlockDesc[i].StartAddress != \ + (UINT32)(Area->Address - FlashDeviceBase)) continue; + for (j = 0, NCBTypeId++; j < (Area->Size / FlashBlockSize); j++) { + BlockDesc[i + j].Type = NCBTypeId; + } + i += ((Area->Size / FLASH_BLOCK_SIZE) - 1); + break; + } + // if this NCB isn't describe in RomLayout + if (Area->Size == 0) { + if (i != (LastNcb + 1)) NCBTypeId++; + BlockDesc[i].Type = NCBTypeId; + } + LastNcb = i; + } +} +#endif // #if REPORT_NCB_BY_ROM_LAYOUT + +#ifdef FAULT_TOLERANT_NVRAM_UPDATE +#if FAULT_TOLERANT_NVRAM_UPDATE == 1 && BACKUP_NVRAM_WHEN_FLASH == 0 +// +//---------------------------------------------------------------------- +// Procedure: GetNvramMainFFSStats +// +// Description: Get NVRAM Main FFS state. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +EFI_FFS_FILE_STATE* +GetNvramMainFFSStats( + VOID +) +{ + EFI_FFS_FILE_HEADER *FfsFileHeader; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)NVRAM_ADDRESS; + + if (FwVolHeader->FvLength == NVRAM_SIZE) + { + FfsFileHeader = (EFI_FFS_FILE_HEADER *)( + NVRAM_ADDRESS + FwVolHeader->HeaderLength + ); + return &FfsFileHeader->State; + }else + return NULL; +} +// +//---------------------------------------------------------------------- +// Procedure: CheckNVRAMArea +// +// Description: Check NVRam FFS state. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID +CheckNVRAMArea( + VOID +) +{ + NvramFFSState = *GetNvramMainFFSStats(); + NvramFFSStatePtr = GetNvramMainFFSStats(); +} +// +//---------------------------------------------------------------------- +// Procedure: NVRAMChanged +// +// Description: Check Location of NVRAM region. +// +// Input: NONE +// +// Output: NONE +// +// Returns: TRUE - Location of NVRAM been changed. +// +//---------------------------------------------------------------------- +// +BOOLEAN +NVRAMChanged( + VOID +) +{ + UINTN FVSignOffset = 0x28, NVRAMRegion = NVRAM_ADDRESS; + UINT32 FVSig; + + // Check NVRAM_ADDRESS still NVRAM region + // Can we find signature ?? + Flash->Read((UINT8*)(NVRAMRegion + FVSignOffset),sizeof(FVSig), &FVSig); + if (FVSig != FV_SIGNATURE) return TRUE; + + // The first Data is NVAR ?? + // Simple verify. + Flash->Read((UINT8*)(NVRAMRegion + NVRAM_HEADER_SIZE),sizeof(FVSig), &FVSig); + if ((FVSig != 'RAVN') && (FVSig != 'NVAR')) return TRUE; + return FALSE; +} +// +//---------------------------------------------------------------------- +// Procedure: UpdateNVRAMArea +// +// Description: If NVRam updated and current NVRam runs at Backup address. +// also update NVRAM Backup address. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID +UpdateNVRAMArea( + VOID +) +{ + UINT32 i = 0, Buffer32 = 0; + UINT8* Buffer; + EFI_FFS_FILE_STATE NewNVRamFFSState; + EFI_STATUS Status; + UINTN NumberOfPages; + EFI_PHYSICAL_ADDRESS Phy_Address; + + // Check NVRAM_ADDRESS FFS State + // If Status changed. + // Then, we got an NVRAM area update + // and current NVRam working at NVRAM_BACKUP_ADDRESS!! + // So move the NVRAM_MAIN to NVRAM_BACKUP and Restore NVRAM_MAIN State. + Flash->Read((UINT8*)NvramFFSStatePtr, + sizeof(EFI_FFS_FILE_STATE), &NewNVRamFFSState); + // Before update FFSState to new NVRAM, check ROMLAYOUT changed or not. + if(NVRAMChanged()) + return; + if((NvramFFSState == NewNVRamFFSState) || (NvramFFSState == 0)) + return; + NumberOfPages = ((NVRAM_SIZE) >> 12); + Status = pSmst->SmmAllocatePages(AllocateAnyPages, EfiRuntimeServicesData, NumberOfPages, &Phy_Address); + + // NVRAM updated !! + // Move NVRAM Main to NVRAM Backup + Flash->Erase((UINT8*)NVRAM_BACKUP_ADDRESS, NVRAM_SIZE); + // For AMD chipset workaround !! + // AMD SPI can't read SPI ROM as buffer. + if(!EFI_ERROR(Status)) + { + Buffer = (UINT8*)Phy_Address; + Flash->Read( + (UINT8*)(NVRAM_ADDRESS), NVRAM_SIZE, Buffer); + + Flash->Write( + (UINT8*)(NVRAM_BACKUP_ADDRESS), NVRAM_SIZE, Buffer); + + pSmst->SmmFreePages(Phy_Address, NumberOfPages); + + }else + { + // If no memory , just do it 4 bytes one time. + for(; i < NVRAM_SIZE ; i += sizeof(UINT32)) + { + Flash->Read( + (UINT8*)(NVRAM_ADDRESS + i), sizeof(UINT32), &Buffer32); + if(Buffer32 == 0xFFFFFFFF) + continue; + Flash->Write( + (UINT8*)(NVRAM_BACKUP_ADDRESS + i), sizeof(UINT32), &Buffer32); + } + } + // Restore NVRAM Main FFS state!! + Flash->Write((UINT8*)NvramFFSStatePtr, + sizeof(EFI_FFS_FILE_STATE),&NvramFFSState); +} +#endif +#endif + +// +//---------------------------------------------------------------------- +// Procedure: PreserveEfiBootOrders +// +// Description: Save the BootXXXX contains "Windows Boot Manager" +// For EFI OS. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID PreserveEfiBootOrders(VOID) +{ + + UINTN BootOrderSize, LegacyOrderSize; + EFI_STATUS Status; + EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE; + EFI_GUID LegacyDevOrderGuid = LEGACY_DEV_ORDER_GUID; + RESTORE_BOOTORDER *SavedBootXXX; + UINT8 i; + UINT16 *BootOrder, *LegacyOrder; + + // Get BootOrder for restore + if (gSmmBootOrder == NULL) { + Status = pSmst->SmmAllocatePages ( AllocateAnyPages, \ + 0, \ + RESTORE_BOOT_ORDER_BUFFER >> 12, \ + &gSmmBootOrder); + if (EFI_ERROR(Status)) return ; + SavedBootXXX = (RESTORE_BOOTORDER*)gSmmBootOrder; + BootOrder = (UINT16*)(gSmmBootOrder + BOOT_ORDER_OFFSET); + } else return; + + // Get BootOrder variable size + BootOrderSize = 0; + Status = pRS->GetVariable(L"BootOrder",&EfiVariableGuid, \ + NULL,&BootOrderSize, NULL); + if(Status != EFI_NOT_FOUND) + { + Status = pRS->GetVariable(L"BootOrder", &EfiVariableGuid, \ + NULL, &BootOrderSize, BootOrder); + if(EFI_ERROR(Status)) return; + + } else return; // If BootOrder is not found, just return + + // Due to the "RT" attribute could be removed from LegacyDevOreder variable, + // here to enable Nvram Full Access control for getting variable if "NV+BS" only. + if (gNvramControl == NULL) gNvramControl = LocateNvramControlSmmProtocol(); + if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE); + // Get LegacyBootOrder variable size + LegacyOrder = (UINT16*)(gSmmBootOrder + LEGACY_BOOT_ORDER_OFFSET); + LegacyOrderSize = 0; + Status = pRS->GetVariable(L"LegacyDevOrder", \ + &LegacyDevOrderGuid, NULL, &LegacyOrderSize, NULL); + if(Status != EFI_NOT_FOUND) { + Status = pRS->GetVariable(L"LegacyDevOrder", + &LegacyDevOrderGuid, \ + (UINT32*)((UINT8*)LegacyOrder + sizeof(UINT32)), \ + &LegacyOrderSize, \ + (UINT8*)LegacyOrder + (sizeof(UINT32) * 2)); + *(UINT32*)LegacyOrder = (UINT32)LegacyOrderSize; + } else *(UINT32*)LegacyOrder = 0; // Clear Buffer to indicate no LegacyDevOrder + // Disable the Nvram Full Access control after processing the "LegacyDevOrder". + if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE); + + // Get BootXXXX for restore + for(i = 0, gNumBootDevice = 0; i < (BootOrderSize / sizeof(UINT16)); i++) + { + Swprintf(SavedBootXXX->BootVarName, L"Boot%04X", *(BootOrder + i)); + // Get Bootxxx variable size + SavedBootXXX->BootXXXXSize = 0; + Status = pRS->GetVariable( SavedBootXXX->BootVarName, \ + &EfiVariableGuid, \ + NULL, \ + &SavedBootXXX->BootXXXXSize, \ + NULL); + // if not found, try upper case. + if(Status == EFI_NOT_FOUND) + { + Swprintf(SavedBootXXX->BootVarName, L"Boot%04X", *(BootOrder + i)); + // Get Variable size. + SavedBootXXX->BootXXXXSize = 0; + Status = pRS->GetVariable( + SavedBootXXX->BootVarName, \ + &EfiVariableGuid, \ + NULL, \ + &SavedBootXXX->BootXXXXSize, \ + NULL); + } + // Get this from BootOrder, there must be a variable + pRS->GetVariable( SavedBootXXX->BootVarName, \ + &EfiVariableGuid, \ + NULL, \ + &SavedBootXXX->BootXXXXSize, \ + (UINT8*)SavedBootXXX + sizeof(RESTORE_BOOTORDER)); + SavedBootXXX->BootOrderNO = *(BootOrder + i); + // Ptr to next "BootXXXX" buffer. + (UINT8*)SavedBootXXX += (SavedBootXXX->BootXXXXSize + \ + sizeof(RESTORE_BOOTORDER)); + gNumBootDevice++; + } +} + + +// +//---------------------------------------------------------------------- +// Procedure: RestoreEfiBootOrders +// +// Description: Restore the BootXXXX contains "Windows Boot Manager" +// For EFI OS. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// + +VOID RestoreEfiBootOrders (VOID) +{ + EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE; + EFI_GUID LegacyDevOrderGuid = LEGACY_DEV_ORDER_GUID; + UINTN BootOrderSize; + UINT16 *BootOrder; + RESTORE_BOOTORDER *SavedBootXXX; + UINT8 i; + EFI_STATUS Status; + + if (gSmmBootOrder == NULL) return; + BootOrder = (UINT16*)(gSmmBootOrder + BOOT_ORDER_OFFSET); + SavedBootXXX = (RESTORE_BOOTORDER*)gSmmBootOrder; + BootOrderSize = 0; + // Get BootOrderSize Variable size if exist. + Status = pRS->GetVariable(L"BootOrder",&EfiVariableGuid,NULL,&BootOrderSize, NULL); + if(Status != EFI_NOT_FOUND) + { + Status = pRS->GetVariable( L"BootOrder", &EfiVariableGuid, \ + NULL, &BootOrderSize, BootOrder); + // if BootOreder found, update nothing. + if(!EFI_ERROR(Status)) + { + // Free BootOrder buffer in SMM. + pSmst->SmmFreePages (gSmmBootOrder, RESTORE_BOOT_ORDER_BUFFER >> 12); + // Re-initial global variable. + gSmmBootOrder = NULL; + gNumBootDevice = 0; + return; + } + } + + for(i = 0 ; i < gNumBootDevice; i++) + { + // Restore BootXXXX + Status = pRS->SetVariable ( \ + SavedBootXXX->BootVarName, \ + &EfiVariableGuid, \ + EFI_VARIABLE_NON_VOLATILE | \ + EFI_VARIABLE_RUNTIME_ACCESS | \ + EFI_VARIABLE_BOOTSERVICE_ACCESS, \ + SavedBootXXX->BootXXXXSize, \ + (UINT8*)SavedBootXXX + sizeof(RESTORE_BOOTORDER)); + BootOrder[i] = SavedBootXXX->BootOrderNO; + // Ptr to next "BootXXXX" buffer. + (UINT8*)SavedBootXXX += (SavedBootXXX->BootXXXXSize + sizeof(RESTORE_BOOTORDER)); + } + // Restore "BootOrder" + pRS->SetVariable ( L"BootOrder", + &EfiVariableGuid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + (sizeof(UINT16) * i), + BootOrder ); + + // Enable the Nvram Full Access control for processing the "LegacyDevOrder". + if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE); + // Restore "LegacyDevOrder" + BootOrder = (UINT16*)(gSmmBootOrder + LEGACY_BOOT_ORDER_OFFSET); + BootOrderSize = *(UINT32*)BootOrder; + if (BootOrderSize != 0) pRS->SetVariable (L"LegacyDevOrder", \ + &LegacyDevOrderGuid, \ + *(UINT32*)((UINT8*)BootOrder + sizeof(UINT32)), \ + BootOrderSize, \ + (UINT8*)BootOrder + (sizeof(UINT32) * 2)); + // Disable the Nvram Full Access control after processing the "LegacyDevOrder". + if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE); + + // Free BootOrder buffer in SMM. + pSmst->SmmFreePages (gSmmBootOrder, RESTORE_BOOT_ORDER_BUFFER >> 12); + // Re-initial global variable. + gSmmBootOrder = NULL; + gNumBootDevice = 0; +} +// +//---------------------------------------------------------------------- +// Procedure: PreserveSetupPassword +// +// Description: Save the Setup Password +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID PreserveSetupPassword(VOID) +{ + UINTN VariableSize; + EFI_STATUS Status; + + // Due to the "RT" attribute could be removed from "AMITSESetup" variable, + // here to enable Nvram Full Access control for getting variable with "NV+BS" only. + if (gNvramControl == NULL) gNvramControl = LocateNvramControlSmmProtocol(); + if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE); + + VariableSize = sizeof(AMITSESETUP); + Status = pRS->GetVariable ( L"AMITSESetup", \ + &gAmiTseSetupGuid, \ + &gAmiTseDataAttr, \ + &VariableSize, \ + &gAmiTseData ); + + if (EFI_ERROR(Status)) gAmiTseDataAttr = 0; + + // Disable the Nvram Full Access control after processing the "AMITSESetup". + if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE); +} + + +// +//---------------------------------------------------------------------- +// Procedure: RestoreSetupPassword +// +// Description: Restore previous Password +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID RestoreSetupPassword (VOID) +{ + UINTN VariableSize = 0; + EFI_STATUS Status; + AMITSESETUP TempAmiTseData; + + pRS->GetVariable ( L"AMITSESetup", \ + &gAmiTseSetupGuid, \ + NULL, \ + &VariableSize, \ + &gAmiTseData ); + + // + // Check the length of new AMITSESETUP stucture and old AMITSESETUP + // + if(VariableSize != sizeof(AMITSESETUP)) { + // + // Sturcture changed, Don't Restore !! + // + return; + } + + if (gAmiTseDataAttr == 0) return; + // + // Check Nvram is updated or not. If updated, restore only the password. + // SilentBoot value will be restored to default value. + // + VariableSize = sizeof(AMITSESETUP); + Status = pRS->GetVariable ( L"AMITSESetup", \ + &gAmiTseSetupGuid, \ + NULL, \ + &VariableSize, \ + &TempAmiTseData ); + + if(Status == EFI_SUCCESS) { + // + // If the nvram is not modified exit without restoring the AMITSESETUP nvram variable. + // + if (!MemCmp(&TempAmiTseData, &gAmiTseData, sizeof(AMITSESETUP))){ + return; + } + } + // Enable the Nvram Full Access control for processing the "AMITSESetup". + if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE); + gAmiTseData.AMISilentBoot= DEFAULT_QUIET_BOOT; + VariableSize = sizeof(AMITSESETUP); + pRS->SetVariable ( L"AMITSESetup", \ + &gAmiTseSetupGuid, \ + gAmiTseDataAttr, \ + VariableSize, \ + &gAmiTseData ); + // Disable the Nvram Full Access control after processing the "AMITSESetup". + if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE); +} +// +//---------------------------------------------------------------------- +// Procedure: DisablePowerButton +// +// Description: Disable Power Button when AFU. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID DisablePowerButton(VOID) +{ + // Disable PWR Button SMI + IoWrite16(PM_BASE_ADDRESS + 0x02, IoRead16(PM_BASE_ADDRESS + 0x02) & 0xFEDF); +} +// +//---------------------------------------------------------------------- +// Procedure: EnablePowerButton +// +// Description: Re-Enable PowerButton after flash BIOS +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID EnablePowerButton (VOID) +{ + //Clear All PM Statuses + IoWrite16(PM_BASE_ADDRESS,IoRead16(PM_BASE_ADDRESS)); + // Re-ensable PWR Button SMI + IoWrite16(PM_BASE_ADDRESS + 0x02, BIT05 + BIT08); +} +// +//---------------------------------------------------------------------- +// Procedure: DisableUSBKBD +// +// Description: Disable USB Keyboard when flashing BIOS. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID DisableUSBKBD(VOID) +{ +#if AMIUSB_SUPPORT == 1 +#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) + EFI_GUID EfiVariableGuid = AMITSESETUP_GUID; + UINTN VariableSize = sizeof(VOID*); + EFI_STATUS Status; + + Status = pRS->GetVariable ( L"USB_POINT", + &EfiVariableGuid, + NULL, + &VariableSize, + &gUsbRtKbcAccessControl); + if(!EFI_ERROR(Status) && (gUsbRtKbcAccessControl != NULL)) + gUsbRtKbcAccessControl(1); +#endif +#endif + + // Disable KBC. + if (0xff != IoRead8(0x60)) { + IoWrite8(0x64, 0xad); + IoWrite8(0x21, IoRead8(0x21) | 0x2); + } +} +// +//---------------------------------------------------------------------- +// Procedure: EnableUSBKBD +// +// Description: Re-Enable USB KeyBoard after flashing BIOS +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID EnableUSBKBD (VOID) +{ + // Enable KBC. + if (0xff != IoRead8(0x60)) { + IoWrite8(0x64, 0xae); + IoWrite8(0x21, IoRead8(0x21) & 0xfd); + } + +#if AMIUSB_SUPPORT == 1 +#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) + if (gUsbRtKbcAccessControl != NULL) + gUsbRtKbcAccessControl(0); +#endif +#endif +} +// +//---------------------------------------------------------------------- +// Procedure: GetUsbProtocol +// +// Description: This hook gets USB Protocol for disabling USB while flashing. +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +VOID +GetUsbProtocolPoint( + IN EFI_EVENT Event, + IN VOID *Context +) +{ +#if AMIUSB_SUPPORT == 1 +#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) + EFI_GUID EfiVariableGuid = AMITSESETUP_GUID; + EFI_USB_PROTOCOL *AmiUsb = NULL; + + pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &AmiUsb); + pRS->SetVariable ( L"USB_POINT", + &EfiVariableGuid, + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(VOID*), + (VOID*)&AmiUsb->UsbRtKbcAccessControl ); +#endif +#endif + return; +} +// +//---------------------------------------------------------------------- +// Procedure: GetUsbControl +// +// Description: This hook gets USB Protocol's function +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +EFI_STATUS +GetUsbControl( + CONST EFI_GUID *Protocol, + VOID *Interface, + EFI_HANDLE Handle +) +{ + GetUsbProtocolPoint( NULL, NULL ); + + return EFI_SUCCESS; +} +// +//---------------------------------------------------------------------- +// Procedure: USBInSmmFunction +// +// Description: Notify for USB smm Protocol +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +VOID +USBInSmmFunction( + VOID +) +{ +#if AMIUSB_SUPPORT == 1 +#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) + EFI_STATUS Status; + EFI_USB_PROTOCOL *AmiUsb = NULL; + EFI_GUID EfiVariableGuid = AMITSESETUP_GUID; + EFI_GUID AmiUsbSmmProtocolGuid = AMI_USB_SMM_PROTOCOL_GUID; + + Status = pSmst->SmmLocateProtocol( + &AmiUsbSmmProtocolGuid, + NULL, + &AmiUsb ); + if( EFI_ERROR(Status) ) + { + VOID *NotifyReg; + + Status = pSmst->SmmRegisterProtocolNotify( + &AmiUsbSmmProtocolGuid, + GetUsbControl, + &NotifyReg ); + } + else + { + GetUsbProtocolPoint( NULL, NULL ); + } + + return; +#else + return; +#endif +#else + return; +#endif +} +// +//---------------------------------------------------------------------- +// Procedure: USBNonSmmFunction +// +// Description: Find USB Protocol pointer +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +VOID +USBNonSmmFunction( + VOID +) +{ +#if AMIUSB_SUPPORT == 1 +#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) + EFI_STATUS Status; + EFI_USB_PROTOCOL *AmiUsb = NULL; + EFI_GUID EfiVariableGuid = AMITSESETUP_GUID; + + Status = pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &AmiUsb); + if(EFI_ERROR(Status)) + { + EFI_EVENT SmiFlashEvt; + VOID *NotifyReg; + + Status = pBS->CreateEvent ( + EFI_EVENT_NOTIFY_SIGNAL, + TPL_CALLBACK, + GetUsbProtocolPoint, + NULL, + &SmiFlashEvt + ); + + if (!EFI_ERROR (Status)) { + Status = pBS->RegisterProtocolNotify ( + &gEfiUsbProtocolGuid, + SmiFlashEvt, + &NotifyReg); + } + }else + pRS->SetVariable ( L"USB_POINT", + &EfiVariableGuid, + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(VOID*), + (VOID*)&AmiUsb->UsbRtKbcAccessControl ); + + return; +#else + return; +#endif //(((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891) +#else + return; +#endif //AMIUSB_SUPPORT +} +#if AFU_BUFFER_IN_SHADOW +#include +// +//---------------------------------------------------------------------- +// Procedure: UpdateShadowBuffer +// +// Description: This hook enables shadow write for updating buffer pointer +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +VOID UpdateShadowBuffer( + IN UINT8 Data, + IN OUT UINT64 pCommBuff +) +{ + UINT8 FixLen; + static UINT8* Buffer = 0; + UINT32 LowBufferAddress, HighBufferAddress; + + if(Data == SMIFLASH_ENABLE_FLASH) + OemRuntimeShadowRamWrite(TRUE); + else + { + if((UINTN)Buffer == 0) + { + Buffer = (UINT8*)0xF0000; + for(;*(UINT32*)Buffer != 0x46534124 && + ((UINTN)Buffer < 0x100000);(UINTN)Buffer++); + } + + if((UINTN)Buffer == 0xFFFFF) + return; + // Skip Sig + FixLen = *(Buffer + 4); + + if(*(UINT32*)(Buffer + FixLen) == 0 || + *(UINT32*)(Buffer + FixLen) == 0xFFFFFFFF) + return; + + LowBufferAddress = *(UINT32*)(Buffer + FixLen); + HighBufferAddress = 0; + pCommBuff = HighBufferAddress; + pCommBuff = Shl64(pCommBuff, 32); + pCommBuff += LowBufferAddress; + } +} +// +//---------------------------------------------------------------------- +// Procedure: ClearShadowBuffer +// +// Description: Elink for Disable shadow and clear buffer pointer +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +VOID ClearShadowBuffer ( + IN UINT8 Data, + IN OUT UINT64 pCommBuff +) +{ + UINT8 FixLen; + static UINT8* Buffer = 0; + + if(Data == SMIFLASH_DISABLE_FLASH) + OemRuntimeShadowRamWrite(FALSE); + else + { + if((UINTN)Buffer == 0) + { + Buffer = (UINT8*)0xF0000; + for(;*(UINT32*)Buffer != 0x46534124 && + ((UINTN)Buffer < 0x100000);(UINTN)Buffer++); + + } + if((UINTN)Buffer == 0xFFFFF) + return; + + // Skip Sig + FixLen = *(Buffer + 4); + // Clear Buffer address + *(UINT32*)(Buffer + FixLen) = 0; + } +} +#endif +// +//---------------------------------------------------------------------- +// Procedure: FindFfsFileByGuid +// +// Description: This hooks finds FFS file by GUID. +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +UINT32 +FindFfsFileByGuid ( + IN UINT8 *pFV, + IN UINT32 FvLength, + IN EFI_GUID *pGuid +) +{ + EFI_FFS_FILE_HEADER *pFfsFile; + UINT32 Length, FileSize; + + if ((((EFI_FIRMWARE_VOLUME_HEADER*)pFV)->Signature != FV_SIGNATURE) || \ + (((EFI_FIRMWARE_VOLUME_HEADER*)pFV)->FvLength != (UINT64)FvLength)) + return FALSE; + Length = ((EFI_FIRMWARE_VOLUME_HEADER*)pFV)->HeaderLength; + pFfsFile = (EFI_FFS_FILE_HEADER*)((UINT32)pFV + Length); + FileSize = *(UINT32 *)pFfsFile->Size & 0x00FFFFFF; + do { + if (!MemCmp ((UINT8*)pFfsFile, pGuid ,sizeof(EFI_GUID))) + return (UINT32)pFfsFile; + FileSize = *(UINT32 *)pFfsFile->Size & 0x00FFFFFF; + pFfsFile = (EFI_FFS_FILE_HEADER*)((UINT32)pFfsFile + FileSize); + pFfsFile = (EFI_FFS_FILE_HEADER*)(((UINT32)pFfsFile + 7) & 0xfffffff8); + if ((UINT32)((UINT8*)pFfsFile - pFV) >= FvLength) break; + } while(((*(UINT32 *)pFfsFile->Size & 0x00FFFFFF) != 0xFFFFFF) && \ + ((*(UINT32 *)pFfsFile->Size & 0x00FFFFFF) != 0)); + return FALSE; +} +#if defined SecSMIFlash_SUPPORT && SecSMIFlash_SUPPORT == 1 +#include +// +//---------------------------------------------------------------------- +// Procedure: PreserveRomHole +// +// Description: This hook preserves ROM Holes while flashing. +// +// Input: +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +// +VOID RecoveryPreserveRomHoles(VOID) { + EFI_GUID RomLayoutGuid = ROM_LAYOUT_FFS_GUID; + ROM_AREA *RomArea; + UINT32 FfsFile = 0, RomHoleFfs1, RomHoleFfs2, RomHoleSize; + EFI_GUID HobListGuid = HOB_LIST_GUID; + EFI_STATUS Status; + RECOVERY_IMAGE_HOB *RecoveryHob; + EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID; + EFI_GUID FlashUpdGuid = FLASH_UPDATE_GUID; + AMI_FLASH_UPDATE_BLOCK FlashUpdDesc; + UINTN Size, Attributes; + UINT8 *Fv; + EFI_GUID *pGuid = NULL; + + RecoveryHob = GetEfiConfigurationTable(pST, &HobListGuid); + if ((RecoveryHob == NULL) || \ + (((EFI_HOB_HANDOFF_INFO_TABLE*)RecoveryHob)->BootMode != \ + BOOT_ON_FLASH_UPDATE)) return; + // Due to AFU 3.03 have support to preserve Romholes if capsule mode, + // SMIFlash only preserve Romholes if Recovery mode of Secure Update. + Status = pRS->GetVariable(FLASH_UPDATE_VAR, \ + &FlashUpdGuid, (UINT32*)&Attributes, &Size, &FlashUpdDesc); + if (EFI_ERROR(Status) || (FlashUpdDesc.FlashOpType != FlRecovery)) return; + + Status = FindNextHobByGuid(&RecoveryHobGuid, &RecoveryHob); + if (EFI_ERROR(Status)) return; + // Search Romlayout in ROM + for(Fv = (UINT8*)(0xffffffff - FLASH_SIZE + 1); + ((Fv < (UINT8*)0xffffffff) && (FfsFile == 0)); + FfsFile = FindFfsFileByGuid (Fv, + (UINT32)(((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->FvLength), &RomLayoutGuid), + Fv = Fv+16 ); + + if(FfsFile == 0) return; + for(pGuid = RecoveryPreserveGUID; pGuid->Data1 != 0; pGuid++) { + // Search in ROM File + RomHoleFfs1 = 0; + for (RomArea = (ROM_AREA*)(FfsFile + 0x2c); RomArea->Size != 0; RomArea++) + { + if (RomArea->Type != RomAreaTypeFv) continue; + RomHoleFfs1 = FindFfsFileByGuid ((UINT8*)RomArea->Address, \ + RomArea->Size, \ + pGuid); + if(RomHoleFfs1 != 0) + break; + } + // if not found, search next. + if (RomHoleFfs1 == 0) continue; + + // Search in Recovery File + RomHoleFfs2 = 0; + for (RomArea = RomLayout; RomArea->Size != 0; RomArea++) + { + + if (RomArea->Type != RomAreaTypeFv) continue; + RomHoleFfs2 = FindFfsFileByGuid ( \ + (UINT8*)(RecoveryHob->Address + RomArea->Offset), \ + RomArea->Size, \ + pGuid); + if(RomHoleFfs2 != 0) + break; + } + // FFS found in ROM and Recovery File + if (RomHoleFfs2 != 0) + { + RomHoleSize = *(UINT32*)(RomHoleFfs1 + 0x14) & 0xFFFFFF; + if ((RomHoleSize == (*(UINT32*)(RomHoleFfs2 + 0x14) & 0xFFFFFF)) && \ + MemCmp((UINT8*)(RomHoleFfs1 + sizeof(EFI_FFS_FILE_HEADER)), \ + (UINT8*)(RomHoleFfs2 + sizeof(EFI_FFS_FILE_HEADER)), \ + RomHoleSize - sizeof(EFI_FFS_FILE_HEADER))) { + pBS->CopyMem((UINT8*)(RomHoleFfs2 + sizeof(EFI_FFS_FILE_HEADER)), \ + (UINT8*)(RomHoleFfs1 + sizeof(EFI_FFS_FILE_HEADER)), \ + RomHoleSize - sizeof(EFI_FFS_FILE_HEADER)); + } + } + } +} +#endif +// +//---------------------------------------------------------------------- +// Procedure: PreserveWin8Variables +// +// Description: Preserve all variables that GUID is {77fa9abd-0359-4d32-bd60-28f4e78f784b}. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID PreserveWin8Variables(VOID) +{ + UINTN VarNameSize = 2; + CHAR16 *VarName = NULL; + CHAR16 *OldVarName = NULL; + EFI_GUID VarGuid; + UINTN VariableSize; + UINT8 *VariableData; + EFI_STATUS Status; + RESTORE_VAR *pRestoreVarList; + UINT8 *pData; + UINT32 VariableAttr; + + Status = pSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + VarNameSize, &VarName + ); + + if(EFI_ERROR(Status)) + return; + + Status = pSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + sizeof(RESTORE_VAR), &RestoreVarList); + + if(EFI_ERROR(Status)) + { + RestoreVarList = NULL; + return; + } + gNvramControl = LocateNvramControlSmmProtocol(); + if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE); + pRestoreVarList = RestoreVarList; + + // Init Variable List + pRestoreVarList->NextData = 0; + + // Get frist variable + VarName[0] = NULL; + do{ + if(VarNameSize != 0) + Status = pRS->GetNextVariableName (&VarNameSize, + VarName, &VarGuid); + else + Status = EFI_BUFFER_TOO_SMALL; + if(Status == EFI_BUFFER_TOO_SMALL) + { + // If VarNameSize is 0, VarName is not existed. + if(VarNameSize != 0) + { + // Keep the old variable name for next search + OldVarName = VarName; + } + + // Avoid dead loop + VarNameSize = DefaultVariableSize; + + Status = pSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + VarNameSize, &VarName); + + if(EFI_ERROR(Status)) + return; + + MemCpy(VarName, OldVarName, VarNameSize); + + continue; + } + + + if(!EFI_ERROR(Status)) + { + if(guidcmp(&VarGuid, &gWin8Guid)) + { + // Make sure every time, it gets a buffer too small, + // don't waste this buffer + VarNameSize = DefaultVariableSize; + continue; + } + + VariableSize = 0; + Status = pRS->GetVariable(VarName, &gWin8Guid, + NULL, &VariableSize, NULL); + + if(Status != EFI_BUFFER_TOO_SMALL) + continue; + + Status = pSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + VariableSize, &VariableData); + + if(EFI_ERROR(Status)) + continue; + + Status = pRS->GetVariable(VarName, &gWin8Guid, + &VariableAttr, &VariableSize, VariableData); + + if(EFI_ERROR(Status)) + { + pSmst->SmmFreePool(VariableData); + continue; + } + // Store variable in Link list + Status = pSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + sizeof(RESTORE_VAR), &pData); + + if(EFI_ERROR(Status)) + continue; + Status = pSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + VarNameSize, &OldVarName); + + if(EFI_ERROR(Status)) + continue; + + MemCpy(OldVarName, VarName, VarNameSize); + // Free the bigger Varname + pSmst->SmmFreePool(VarName); + + + pRestoreVarList->rVar.BootVarName = OldVarName; + pRestoreVarList->rVar.Guid = &gWin8Guid; + pRestoreVarList->rATTR.Attrib = VariableAttr; + pRestoreVarList->rATTR.Size = VariableSize; + pRestoreVarList->rATTR.Data = VariableData; + pRestoreVarList->NextData = (UINTN)pData; + + (UINT8*)pRestoreVarList = pData; + pRestoreVarList->NextData = 0; + // Make sure every time, it gets a buffer too small, + // make it allocate new buffer for name + VarNameSize = 0; + } + + }while(Status != EFI_NOT_FOUND); + if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE); +} +// +//--------------------------------------------------------------------- +// Procedure: RestoreWin8Variables +// +// Description: Restore all variables that GUID is {77fa9abd-0359-4d32-bd60-28f4e78f784b}. +// +// Input: NONE +// +// Output: NONE +// +// Returns: NONE +// +//---------------------------------------------------------------------- +// +VOID RestoreWin8Variables (VOID) +{ + RESTORE_VAR *pRestoreVarList = RestoreVarList, *TempPoint; + EFI_STATUS Status; + + if(RestoreVarList == NULL) + return; + if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE); + for( ; pRestoreVarList->NextData != 0 ; ) + { + Status = pRS->SetVariable ( pRestoreVarList->rVar.BootVarName, + pRestoreVarList->rVar.Guid, + pRestoreVarList->rATTR.Attrib, + pRestoreVarList->rATTR.Size, + pRestoreVarList->rATTR.Data ); + + (UINTN)TempPoint = pRestoreVarList->NextData; + + pSmst->SmmFreePool(pRestoreVarList->rVar.BootVarName); + pSmst->SmmFreePool(pRestoreVarList->rATTR.Data); + pSmst->SmmFreePool(pRestoreVarList); + pRestoreVarList = TempPoint; + } + if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE); + RestoreVarList = NULL; +} +#else // #if defined _OUTSIDE_SMM_ +//*********** OUTSIDE SMM *********************************************** +#if defined RECOVERY_PRESERVE_VARS_IN_SMM && RECOVERY_PRESERVE_VARS_IN_SMM == 1 +// +//---------------------------------------------------------------------------- +// +// Procedure: mSMIFlashSmi +// +// Description: mSMIFlashSmi structure for generating SW SMI call. +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +static UINT8 mSMIFlashSmi[] = { + 0x50, // push eax + 0x53, // push ebx + 0x51, // push ecx + 0x52, // push edx + 0xBA, SW_SMI_IO_ADDRESS, 0, 0, 0, // mov edx, SW_SMI_IO_ADDRESS + 0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, 0 //SW SMI value + 0xBB, 0x00, 0x00, 0x00, 0x00, // mov ebx, 0 //LowBufferAddress + 0xB9, 0x00, 0x00, 0x00, 0x00, // mov ecx, 0 //HighBufferAddress + 0xEE, // out dx, al + 0x5A, // pop edx + 0x59, // pop ecx + 0x5B, // pop ebx + 0x58, // pop eax + 0xC3, // ret +};//mSMIFlashSmi[] + +FUNC_BLOCK FuncBlock = {0,0,0,0}; +// +//---------------------------------------------------------------------------- +// +// Procedure: RecoveryHookBeforeFlash +// +// Description: This hook preserves variables in SMM while reflash update. +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID RecoveryHookBeforeFlash (VOID) +{ + void (*IssueSWSMI)(void); + *(UINT8*)&mSMIFlashSmi[10] = SMIFLASH_ENABLE_FLASH; //EAX + *(UINT32*)&mSMIFlashSmi[15] = (UINT32)&FuncBlock; //EBX + IssueSWSMI = (void*)mSMIFlashSmi; + IssueSWSMI(); +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT + // For following DeviceWriteEnable call of reflash.c. + Flash->DeviceWriteDisable(); +#endif +} +// +//---------------------------------------------------------------------------- +// +// Procedure: RecoveryHookAfterFlash +// +// Description: This hook restores variables from SMM after reflash update. +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID RecoveryHookAfterFlash (VOID) +{ + void (*IssueSWSMI)(void); + +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT + // For following DeviceWriteDisable call of smiflash func#24. + Flash->DeviceWriteEnable(); +#endif + *(UINT8*)&mSMIFlashSmi[10] = SMIFLASH_DISABLE_FLASH;//EAX + *(UINT32*)&mSMIFlashSmi[15] = (UINT32)&FuncBlock; //EBX + IssueSWSMI = (void*)mSMIFlashSmi; + IssueSWSMI(); +} +#endif // if defined RECOVERY_PRESERVE_IN_SMM && RECOVERY_PRESERVE_IN_SMM == 1 +#endif // if defined _OUTSIDE_SMM_ + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** -- cgit v1.2.3