diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/Recovery/ReFlash | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/EM/Recovery/ReFlash')
-rw-r--r-- | Core/EM/Recovery/ReFlash/Esrt.c | 415 | ||||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlash.c | 601 | ||||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlash.cif | 16 | ||||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlash.dxs | 72 | ||||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlash.h | 268 | ||||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlash.mak | 135 | ||||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlash.sdl | 135 | ||||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlash.uni | bin | 0 -> 13216 bytes | |||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlash.vfr | 240 | ||||
-rw-r--r-- | Core/EM/Recovery/ReFlash/ReFlashWorker.c | 720 |
10 files changed, 2602 insertions, 0 deletions
diff --git a/Core/EM/Recovery/ReFlash/Esrt.c b/Core/EM/Recovery/ReFlash/Esrt.c new file mode 100644 index 0000000..1823328 --- /dev/null +++ b/Core/EM/Recovery/ReFlash/Esrt.c @@ -0,0 +1,415 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/Esrt.c 1 3/21/13 7:25a Thomaschen $ +// +// $Revision: 1 $ +// +// $Date: 3/21/13 7:25a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/Esrt.c $ +// +// 1 3/21/13 7:25a Thomaschen +// +// 6 2/27/13 3:54p Artems +// [TAG] EIP106722 +// [Category] Improvement +// [Description] Used different GUID to differentiate between AMI and +// Win8 firmware update +// [Files] Esrt.c +// +// 5 2/07/13 5:26p Artems +// [TAG] EIP106722 +// [Category] Improvement +// [Description] Add creation of firmware update version from FID table +// [Files] Esrt.c +// +// 4 2/05/13 1:41p Artems +// [TAG] EIP111562 +// [Category] Improvement +// [Description] Add Enable/Disable support for Windows8-style firmware +// update +// [Files] Esrt.c Reflash.c Reflash.sdl +// +// 3 1/02/13 12:18p Artems +// [TAG] EIP N/A +// [Category] Improvement +// [Description] Flash update progress report changes: +// - report progress in non-interactive flash update +// - do not report progress in Win8-style flash update +// [Files] ReflashWorker.c Reflash.h Esrt.c +// +// 2 8/02/12 11:59a Artems +// [TAG] EIP93520 +// [Category] New Feature +// [Description] Support of Microsoft ESRT spec +// [Files] Recovery.h Recovery.sdl Recovery.c Reflash.c ReflashWorker.c +// Esrt.c +// +// 1 7/20/12 10:20a Artems +// [TAG] EIP93520 +// [Category] New Feature +// [Description] Support for Microsoft ESRT spec +// [Files] Reflash.c Esrt.c Reflash.h Capsule.h ReflashWorker.c +// Protocol.cif AmiReflashProtocol.h Setup.h +// +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: Esrt.c +// +// Description: +// +//<AMI_FHDR_END> +//********************************************************************** + +#include <Token.h> + +#if SUPPORT_WIN8_STYLE_FW_UPDATE + +#include <AmiHobs.h> +#include <AmiDxeLib.h> +#include <Capsule.h> +#include <Setup.h> +#include <PPI/FwVersion.h> +#include <Protocol/AmiReflashProtocol.h> +#include <Protocol/FirmwareVolume2.h> +#include "Reflash.h" + +#define MAX_ESRT_ENTRIES 1 + +#define FW_TYPE_UNKNOWN 0 +#define FW_TYPE_SYSTEM_FIRMWARE 1 +#define FW_TYPE_DEVICE_FIRMWARE 2 +#define FW_TYPE_FIRMWARE_DRIVER 3 + +#define FW_UPDATE_STATUS_SUCCESS 0 +#define FW_UPDATE_STATUS_UNKNOWN_ERROR 1 +#define FW_UPDATE_STATUS_OUT_OF_RESOURCES 2 +#define FW_UPDATE_STATUS_INCORRECT_VERSION 3 +#define FW_UPDATE_STATUS_INVALID_FORMAT 4 +#define FW_UPDATE_STATUS_AUTHENTICATION_ERROR 5 + +#define EFI_SYSTEM_RESOURCE_TABLE_GUID \ + { 0xb122a263, 0x3661, 0x4f68, 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 } + +#define FID_FFS_FILE_NAME_GUID \ + { 0x3fd1d3a2, 0x99f7, 0x420b, 0xbc, 0x69, 0x8b, 0xb1, 0xd4, 0x92, 0xa3, 0x32 } + +#define FID_FFS_FILE_SECTION_GUID \ + { 0x2EBE0275, 0x6458, 0x4AF9, 0x91, 0xED, 0xD3, 0xF4, 0xED, 0xB1, 0x00, 0xAA } + +#pragma pack(push, 1) +typedef struct _FIRMWARE_RESOURCE_ENTRY { + EFI_GUID FwClass; + UINT32 FwType; + UINT32 FwVersion; + UINT32 LowestSupportedFwVersion; + UINT32 CapsuleFlags; + UINT32 LastAttemptVersion; + UINT32 LastAttemptStatus; +} FIRMWARE_RESOURCE_ENTRY; + +typedef struct _EFI_ESRT_TABLE { + UINT32 FwResourceCount; + UINT32 FwMaxResources; + UINT64 FwResourceVersion; + FIRMWARE_RESOURCE_ENTRY Entries[MAX_ESRT_ENTRIES]; +} EFI_ESRT_TABLE; + +#pragma pack(pop) + +static EFI_GUID SystemFirmwareUpdateClass = W8_FW_UPDATE_IMAGE_CAPSULE_GUID; +static EFI_GUID SystemResourceTableGuid = EFI_SYSTEM_RESOURCE_TABLE_GUID; +static EFI_GUID guidHob = HOB_LIST_GUID; +static W8_IMAGE_CAPSULE *Image; + +static const UINT32 FidSignature = 0x44494624; //$FID + +EFI_STATUS GetDisplayImage( + IN EFI_REFLASH_PROTOCOL *This, + OUT UINTN *CoordinateX, + OUT UINTN *CoordinateY, + OUT VOID **ImageAddress +); + +EFI_STATUS FwUpdate( + IN EFI_REFLASH_PROTOCOL *This +); + +EFI_REFLASH_PROTOCOL AmiReflashProtocol = { + FwUpdate, + GetDisplayImage +}; + +EFI_STATUS GetFidFromFv( + OUT VOID *Fid +) +{ + static EFI_GUID FidFileName = FID_FFS_FILE_NAME_GUID; + EFI_STATUS Status; + EFI_HANDLE *FvHandle; + UINTN FvCount; + UINTN i; + UINTN BufferSize; + VOID *Buffer; + + Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &FvCount, &FvHandle); + if (EFI_ERROR(Status)) + return Status; + + for(i = 0; i < FvCount; i++) + { + EFI_FIRMWARE_VOLUME_PROTOCOL *Fv; + UINT32 AuthStatus; + Status = pBS->HandleProtocol(FvHandle[i], &gEfiFirmwareVolume2ProtocolGuid, &Fv); + if (EFI_ERROR(Status)) + continue; + Buffer = 0; + BufferSize = 0; + Status = Fv->ReadSection(Fv, &FidFileName, EFI_SECTION_FREEFORM_SUBTYPE_GUID, 0, &Buffer, &BufferSize, &AuthStatus); + TRACE((-1, "extracted section with guid %g\n", (EFI_GUID *)Buffer)); + if (!EFI_ERROR(Status)) { + (UINT8 *)Buffer += sizeof(EFI_GUID); + MemCpy(Fid, Buffer, sizeof(FW_VERSION)); + (UINT8 *)Buffer -= sizeof(EFI_GUID); + pBS->FreePool(Buffer); + return EFI_SUCCESS; + } + } + pBS->FreePool(FvHandle); + return EFI_NOT_FOUND; +} + +EFI_STATUS GetFidFromBuffer( + IN VOID *Buffer, + OUT VOID *Fid +) +{ + static EFI_GUID FidSectionGuid = FID_FFS_FILE_SECTION_GUID; + UINT32 Signature; + UINT32 *SearchPointer; + UINT32 *FidPointer; + + SearchPointer = (UINT32 *)((UINT8 *)Buffer - sizeof(EFI_GUID) + FLASH_SIZE); + Signature = FidSectionGuid.Data1; + + do { + if(*SearchPointer == Signature) { + if(!guidcmp(&FidSectionGuid, (EFI_GUID *)SearchPointer)) { + FidPointer = (UINT32 *)((EFI_GUID *)SearchPointer + 1); + if(*FidPointer == FidSignature) { + MemCpy(Fid, FidPointer, sizeof(FW_VERSION)); + return EFI_SUCCESS; + } + } + } + } while(SearchPointer-- >= (UINT32 *)Buffer); + + return EFI_NOT_FOUND; +} + +UINT32 GetVersionFromFid( + VOID *Image OPTIONAL +) +{ + FW_VERSION Fid; + UINT32 Version; + EFI_STATUS Status; + + if(Image == NULL) + Status = GetFidFromFv(&Fid); + else + Status = GetFidFromBuffer(Image, &Fid); + + if(EFI_ERROR(Status)) + return 0; + + Version = Atoi(Fid.ProjectMajorVersion); + Version <<= 16; + Version += Atoi(Fid.ProjectMinorVersion); + return Version; +} + +EFI_STATUS InstallEsrtTable( + VOID +) +{ + static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID; + EFI_HOB_HANDOFF_INFO_TABLE *pHit; + EFI_STATUS Status; + UINTN Size = sizeof(UINT32); + UINT32 Version; + EFI_ESRT_TABLE *EsrtTable; + + Status = pBS->AllocatePool(EfiRuntimeServicesData, sizeof(EFI_ESRT_TABLE), &EsrtTable); + if(EFI_ERROR(Status)) + return Status; + + EsrtTable->FwResourceCount = 1; + EsrtTable->FwMaxResources = MAX_ESRT_ENTRIES; + EsrtTable->FwResourceVersion = 1; + + EsrtTable->Entries[0].FwClass = SystemFirmwareUpdateClass; + EsrtTable->Entries[0].FwType = FW_TYPE_SYSTEM_FIRMWARE; + EsrtTable->Entries[0].FwVersion = GetVersionFromFid(NULL); + EsrtTable->Entries[0].LowestSupportedFwVersion = EsrtTable->Entries[0].FwVersion; //no rollback allowed + EsrtTable->Entries[0].CapsuleFlags = 0; + + Status = pRS->GetVariable(FW_VERSION_VARIABLE, &gAmiGlobalVariableGuid, NULL, &Size, &Version); + if(!EFI_ERROR(Status)) { + EsrtTable->Entries[0].LastAttemptVersion = Version; + EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_UNKNOWN_ERROR; + } else { + pHit = GetEfiConfigurationTable(pST, &guidHob); + if(pHit != NULL && !EFI_ERROR(FindNextHobByGuid(&RecoveryHobGuid, &pHit))) { + EsrtTable->Entries[0].LastAttemptVersion = GetVersionFromFid((VOID *)(UINTN)((RECOVERY_IMAGE_HOB*)pHit)->Address); + switch(((RECOVERY_IMAGE_HOB*)pHit)->FailedStage) { + case 0: //no authentication/verification error + EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_UNKNOWN_ERROR; + break; + case 1: + EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_INVALID_FORMAT; + break; + case 2: + EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_AUTHENTICATION_ERROR; + break; + case 3: + EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_AUTHENTICATION_ERROR; + break; + case 4: + EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_INCORRECT_VERSION; + break; + default: + EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_UNKNOWN_ERROR; + break; + } + } else { //recovery hob not found - regular boot + EsrtTable->Entries[0].LastAttemptVersion = EsrtTable->Entries[0].FwVersion; + EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_SUCCESS; + } + } + + Status = pBS->InstallConfigurationTable(&SystemResourceTableGuid, EsrtTable); + return Status; +} + +EFI_STATUS IsWin8Update( + BOOLEAN RecoveryFailed +) +{ + AMI_CAPSULE_HOB *Hob; + static EFI_GUID AmiCapsuleHobGuid = AMI_CAPSULE_HOB_GUID; + static EFI_GUID ImageCapsuleGuid = W8_SCREEN_IMAGE_CAPSULE_GUID; + static EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID; + EFI_HANDLE Handle = NULL; + EFI_STATUS Status; + UINT32 BootFlow = BOOT_FLOW_CONDITION_OS_UPD_CAP; + + Hob = GetEfiConfigurationTable(pST, &guidHob); + if(Hob == NULL) + return EFI_NOT_FOUND; + + do { + Status = FindNextHobByGuid(&AmiCapsuleHobGuid, &Hob); + if(!EFI_ERROR(Status) && !guidcmp(&(Hob->CapsuleGuid), &ImageCapsuleGuid)) + break; + } while(!EFI_ERROR(Status)); + + if(EFI_ERROR(Status)) //no image hob - we're not on OS FW update path + return Status; + + if(RecoveryFailed) { //we're on OS FW update path, but recovery can't be performed + InstallEsrtTable(); + return EFI_UNLOAD_IMAGE; + } + +//save image capsule pointer + Image = (W8_IMAGE_CAPSULE *)(VOID *)(UINTN)(Hob->CapsuleData); +//install reflash protocol + Status = pBS->InstallMultipleProtocolInterfaces( + &Handle, + &gAmiReflashProtocolGuid, + &AmiReflashProtocol, + NULL); + if(EFI_ERROR(Status)) + return Status; + +//set boot flow + pRS->SetVariable(L"BootFlow", &guidBootFlow, EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof(BootFlow), &BootFlow); + return Status; +} + +EFI_STATUS GetDisplayImage( + IN EFI_REFLASH_PROTOCOL *This, + OUT UINTN *CoordinateX, + OUT UINTN *CoordinateY, + OUT VOID **ImageAddress +) +{ + if(CoordinateX == NULL || + CoordinateY == NULL || + ImageAddress == NULL) + return EFI_INVALID_PARAMETER; + + *CoordinateX = Image->ImageOffsetX; + *CoordinateY = Image->ImageOffsetY; + *ImageAddress = Image->Image; + return EFI_SUCCESS; +} + +EFI_STATUS FwUpdate( + IN EFI_REFLASH_PROTOCOL *This +) +{ + EFI_STATUS Status; + UINT32 Version; + +/* set version we're upgrading to */ + Version = GetVersionFromFid(RecoveryBuffer); + Status = pRS->SetVariable(FW_VERSION_VARIABLE, &gAmiGlobalVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(UINT32), &Version); + + Status = Prologue(FALSE, TRUE); + if(EFI_ERROR(Status)) + pRS->ResetSystem(EfiResetCold, Status, 0, NULL); + + Status = FlashWalker(FALSE); + if(EFI_ERROR(Status)) + pRS->ResetSystem(EfiResetCold, Status, 0, NULL); + + Status = Epilogue(); + return Status; +} + +#endif // #if SUPPORT_WIN8_STYLE_FW_UPDATE + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/Recovery/ReFlash/ReFlash.c b/Core/EM/Recovery/ReFlash/ReFlash.c new file mode 100644 index 0000000..773d7f9 --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlash.c @@ -0,0 +1,601 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlash.c 3 10/01/13 2:03a Thomaschen $ +// +// $Revision: 3 $ +// +// $Date: 10/01/13 2:03a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlash.c $ +// +// 3 10/01/13 2:03a Thomaschen +// Update for EIP137328. +// +// 2 4/16/13 5:48a Thomaschen +// Fixed for EIP106722. +// +// +// 40 2/11/13 3:41p Artems +// [TAG] EIP112180 +// [Category] Bug Fix +// [Severity] Critical +// [Symptom] In non-interactive mode system updated flash even when +// there is no valid image +// [RootCause] In non-interactive mode system didn't check flash image +// validity +// [Solution] Added check of flash image validity. Inform user if image +// is invalid or not found +// [Files] Reflash.c ReflashWorker.c Reflash.uni Reflash.vfr +// +// 39 2/05/13 1:41p Artems +// [TAG] EIP111562 +// [Category] Improvement +// [Description] Add Enable/Disable support for Windows8-style firmware +// update +// [Files] Esrt.c Reflash.c Reflash.sdl +// +// 38 7/20/12 10:17a Artems +// [TAG] EIP93520 +// [Category] New Feature +// [Description] Support of Microsoft ESRT spec +// [Files] Reflash.c Esrt.c Reflash.h Capsule.h ReflashWorker.c +// Protocol.cif AmiReflashProtocol.h Setup.h +// +// 37 5/22/12 4:54p Artems +// [TAG] EIP88314 +// [Category] Improvement +// [Description] Recovery takes a long time for large flash size +// Rewrite reflash code to not give control back to TSE until finished +// reporting progress via DisplayProgress API of AMI Post manager +// [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr +// Reflash.uni +// +// 36 4/09/12 6:03p Artems +// Undo previous change +// +// 35 2/08/12 4:27a Nerofan +// Update it for capsule function if memory size is over 2G. +// +// 34 12/05/11 1:49p Artems +// EIP 74623: Add capabilities similar to ones in SMIFlash module +// +// 33 11/14/11 4:07p Artems +// Fixed bug with hob size comparison +// Set default attributes for Reflash Setup variable +// +// 32 11/14/11 3:18p Artems +// Defined Extended errors for security recovery capsule check +// +// 31 11/12/11 6:48p Artems +// Added fault tolerant recovery support +// +// 30 11/02/11 4:54p Artems +// EIP 74446: Fixed bug - reflash is enabled when recovery image is not +// found +// +// 29 5/13/11 4:51p Artems +// Added secure flash recovery/update support. Extended error reporting +// Added handling of unsupported FormBrowser actions +// +// 28 5/05/11 2:00p Artems +// Bugfix: callback supports only "CHANGING" browser action +// +// 27 5/04/11 5:54p Artems +// Bugfix: function FlashProgress output parameter ActionRequest was +// undefined +// +// 26 11/17/10 2:52p Felixp +// Enhencement (EIP 36355): +// The Reflash component is updated to be extensible with external +// eModules. +// The eModules can contribute content for the Recovery setup page, +// and provide callback function that will be periodically called +// once BIOS update is completed.The external eModules can be used +// to implement update of non-standard firmware components. +// For example, update of the non-shared EC firmware. +// +// 25 10/07/10 11:02a Felixp +// FlashDeviceWriteEnable/FlashDeviceWriteDisable calls added. +// +// 24 10/01/10 2:14p Felixp +// Previous changes related to descrete EC firmware update are rolled back +// for the Core labeling. +// +// 22 12/24/09 12:42p Oleksiyy +// EIP 30173: Support for the EC Firmware Area Update control added. Main +// token to enable this support is EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT +// should be located in specific EC-related .sdl file. +// +// 21 11/25/09 11:38a Felixp +// +// 20 11/25/09 11:27a Felixp +// Action parameter of the Callback function is updated based on UEFI +// errata +// +// 19 10/09/09 6:30p Felixp +// ReFlash component is updated to support Framework and UEFI 2.1 HII +// +// 18 8/25/09 5:29p Felixp +// Recovery module is updated to pass recovery image location via special +// GUIDed HOB. +// Old implementation that was relying on Firmware Volume (FV) handle, +// required porting for a projects with non standard FV management policy. +// +// 17 7/09/09 5:59p Oleksiyy +// Files clean-up, some headers added +// +// 16 5/21/09 4:44p Felixp +// ReFlash driver is updated to use FlashProtocol instead of Flash library +// functions. +// +// 15 1/02/09 1:14p Felixp +// Bug fix: initialize size before call to GetVariable +// +// 14 10/10/08 5:30p Felixp +// +// 13 3/12/08 2:55p Felixp +// Error code reporting when flash update failed added +// +// 12 10/19/07 6:23p Felixp +// Recovery Flash Update module extended to support Boot Block update. +// Boot block update can be enabled or disabled using SDL token. +// In addition to that there is an SDL token that enables/disables +// checkbox on the +// recovery setup page that user can use to enable or disable boot block +// update. +// +// 11 4/13/07 6:07p Ambikas +// Coding standard changes: updated the year in the AMI copyright +// header/footer. +// +// 10 1/26/07 10:31a Anandakrishnanl +// Added Flash Device Write Enabling and Disabling code to make the device +// Write wnable before Flash Block writes. +// +// 9 12/29/06 2:58p Felixp +// Updated to use new Flash Interface +// +// 8 12/22/06 9:38a Felixp +// Support for optional NVRAM reset based on user input added +// +// 7 12/20/06 1:36p Felixp +// +// 6 10/30/06 5:44p Felixp +// Updated to be complient with HII Spec. 0.92 (used to be 0.91) +// +// 5 10/27/06 11:48a Felixp +// Flash related external variables from Tokens.c are used (instead of +// global variables declared in Reflash.c) +// +// 4 8/24/06 9:19a Felixp +// x64 Support +// +// 3 4/12/06 5:49p Felixp +// +// 2 3/13/06 1:47a Felixp +// +// 1 12/01/05 9:35a Felixp +// +// 1 11/08/05 4:04a Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: ReFlash.c +// +// Description: +// +//<AMI_FHDR_END> +//********************************************************************** +#include <HOB.h> +#include <Flash.h> +#include <AmiCspLib.h> +#include <AmiHobs.h> +#include "ReFlash.h" + + +static EFI_GUID guidRecovery = RECOVERY_FORM_SET_GUID; +EFI_HANDLE ThisImageHandle; +FLASH_PROTOCOL *Flash; +EFI_HII_HANDLE ReflashHiiHandle = NULL; +UINT8 *RecoveryBuffer = NULL; +EFI_STATUS RecoveryStatus = EFI_SUCCESS; + + +EFI_HII_CONFIG_ACCESS_PROTOCOL CallBack = { NULL,NULL,FlashProgressEx }; + +CALLBACK_INFO SetupCallBack[] = +{ + // Last field in every structure will be filled by the Setup + { &guidRecovery, &CallBack, RECOVERY_FORM_SET_CLASS, 0, 0}, +}; + + +//------------------------------- +//Before flash and After flash eLinks + +typedef VOID (OEM_FLASH_UPDATE_CALLBACK) (VOID); +extern OEM_FLASH_UPDATE_CALLBACK OEM_BEFORE_FLASH_UPDATE_CALLBACK_LIST EndOfList; +extern OEM_FLASH_UPDATE_CALLBACK OEM_AFTER_FLASH_UPDATE_CALLBACK_LIST EndOfList; +OEM_FLASH_UPDATE_CALLBACK* OemBeforeFlashCallbackList[] = { OEM_BEFORE_FLASH_UPDATE_CALLBACK_LIST NULL }; +OEM_FLASH_UPDATE_CALLBACK* OemAfterFlashCallbackList[] = { OEM_AFTER_FLASH_UPDATE_CALLBACK_LIST NULL }; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: OemBeforeFlashCallback +// +// Description: This function executes OEM porting hooks before starting flash update +// +// Input: +// None +// +// Output: +// None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID OemBeforeFlashCallback( + VOID +) +{ + UINT32 i; + for(i = 0; OemBeforeFlashCallbackList[i] != NULL; i++) + OemBeforeFlashCallbackList[i](); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: OemAfterFlashCallback +// +// Description: This function executes OEM porting hooks after finishing flash update +// +// Input: +// None +// +// Output: +// None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID OemAfterFlashCallback( + VOID +) +{ + UINT32 i; + for(i = 0; OemAfterFlashCallbackList[i] != NULL; i++) + OemAfterFlashCallbackList[i](); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetHiiString +// +// Description: This function reads a string from HII +// +// Input: IN EFI_HII_HANDLE HiiHandle - Efi Hii Handle +// IN STRING_REF Token - String Token +// IN OUT UINTN *pDataSize - Length of the StringBuffer +// OUT EFI_STRING *ppData - The buffer to receive the characters in the string. +// +// Output: EFI_STATUS - Depending on result +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS GetHiiString( + IN EFI_HII_HANDLE HiiHandle, + IN STRING_REF Token, + IN OUT UINTN *pDataSize, + OUT EFI_STRING *ppData +) +{ + EFI_STATUS Status; + + if (!*ppData) *pDataSize=0; + + Status = HiiLibGetString(HiiHandle, Token, pDataSize, *ppData); + if (!EFI_ERROR(Status)) return Status; + //--- If size was too small free pool and try with right size, which was passed + if (Status==EFI_BUFFER_TOO_SMALL) + { + if (*ppData) pBS->FreePool(*ppData); + + if (!(*ppData=Malloc(*pDataSize))) return EFI_OUT_OF_RESOURCES; + + Status = HiiLibGetString(HiiHandle, Token, pDataSize, *ppData); + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ApplyUserSelection +// +// Description: This function updates flash parameteres based on user selection +// or Setup values +// +// Input: +// IN BOOLEAN Interactive - if TRUE get selection from user input, otherwise +// use Setup values +// +// Output: +// None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ApplyUserSelection( + IN BOOLEAN Interactive +) +{ + EFI_STATUS Status; + AUTOFLASH FlashUpdateControl; + UINTN Size = sizeof(FlashUpdateControl); + UINT32 i; + + if(Interactive) { + /* get values from Setup Browser */ + Status = HiiLibGetBrowserData(&Size, &FlashUpdateControl, &guidRecovery, L"Setup"); + } else { + /* get values from NVRAM */ + Status = pRS->GetVariable(L"Setup", &guidRecovery, NULL, &Size, &FlashUpdateControl); + } + if(EFI_ERROR(Status)) { + /* no user selection, use defaults */ + FlashUpdateControl.UpdateMain = REFLASH_UPDATE_MAIN_BLOCK; + FlashUpdateControl.UpdateBb = REFLASH_UPDATE_BOOT_BLOCK; + FlashUpdateControl.UpdateNv = REFLASH_UPDATE_NVRAM; +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT + FlashUpdateControl.UpdateEC = REFLASH_UPDATE_EC_FIRMWARE; +#endif + } + + for(i = 0; BlocksToUpdate[i].Type != FvTypeMax; i++) { + switch(BlocksToUpdate[i].Type) { + case FvTypeMain: + BlocksToUpdate[i].Update = FlashUpdateControl.UpdateMain; +#if FtRecovery_SUPPORT + if(FlashUpdateControl.UpdateBb == 1) + BlocksToUpdate[i].Update = TRUE; //with fault tolerant recovery FV_MAIN is used for backup - force update +#endif + break; + case FvTypeBootBlock: + BlocksToUpdate[i].Update = FlashUpdateControl.UpdateBb; +#if FtRecovery_SUPPORT + if(IsTopSwapOn()) //if we're here BB update failed we use backup copy - force BB update again + BlocksToUpdate[i].Update = TRUE; +#endif + break; + case FvTypeNvRam: + BlocksToUpdate[i].Update = FlashUpdateControl.UpdateNv; + break; +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT + case FvTypeCustom: + BlocksToUpdate[i].Update = FlashUpdateControl.UpdateEC; + break; +#endif + default: + break; + } + } +} + +//---------------------------------------------------------------------------- +// IsRecovery prototypes +//---------------------------------------------------------------------------- +// Bit Mask of checks to perform on Aptio FW Image +// 1- Capsule integrity +// 2- Verify Signature +// 3- Verify FW Key +// 4- Verify FW Version compatibility. +// To prevent possible re-play attack: +// update current FW with older version with lower security. +// 5- Compare MonotonicCounters/date. Replay attack +//---------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: UpdateSetupStrings +// +// Description: This function updates status strings in setup window, based +// on execution results +// +// Input: +// IN EFI_HII_HANDLE Handle - handle of Reflash setup formset (page) +// IN EFI_STATUS Error - execution error if any +// IN UINT32 FailedStage - in case of authentication error failed stage description +// +// Output: +// None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID UpdateSetupStrings( + IN EFI_HII_HANDLE Handle, + IN EFI_STATUS Error, + IN UINT32 FailedStage +) +{ + UINTN Size; + EFI_STRING Template = NULL; + EFI_STRING Template2 = NULL; + CHAR16 ReportString[100]; + + if(!EFI_ERROR(Error)) { + GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE1_SUCCESS), &Size, &Template); + if(FailedStage == 0) + GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE2_SUCCESS), &Size, &Template2); + else //if we're here we're on manual BIOS rollback to older version + GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE2_ROLLBACK_WARNING), &Size, &Template2); + + if(Template != NULL) { + HiiLibSetString(Handle, STRING_TOKEN(STR_SUBTITLE1), Template); + pBS->FreePool(Template); + } + + if(Template2 != NULL) { + HiiLibSetString(Handle, STRING_TOKEN(STR_SUBTITLE2), Template2); + pBS->FreePool(Template2); + } + + return; + } + +//Get Error string template + GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE1_ERROR), &Size, &Template); + if(Template != NULL) { + HiiLibSetString(Handle, STRING_TOKEN(STR_SUBTITLE1), Template); + pBS->FreePool(Template); + Template = NULL; + } + + GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE2_ERROR_TEMPLATE), &Size, &Template); + switch(FailedStage) { + case InvalidHeader: + GetHiiString(Handle, STRING_TOKEN(STR_ERR), &Size, &Template2); + break; + case InvalidSignature: + GetHiiString(Handle, STRING_TOKEN(STR_ERR1), &Size, &Template2); + break; + case IvalidPlatformKey: + GetHiiString(Handle, STRING_TOKEN(STR_ERR2), &Size, &Template2); + break; + case InvalidFwVersion: + GetHiiString(Handle, STRING_TOKEN(STR_ERR3), &Size, &Template2); + break; + default: + GetHiiString(Handle, STRING_TOKEN(STR_ERR4), &Size, &Template2); + break; + } + + if((Template != NULL) && (Template2 != NULL)) { + Swprintf(ReportString, Template, Error, Template2); + HiiLibSetString(Handle, STRING_TOKEN(STR_SUBTITLE2), ReportString); + pBS->FreePool(Template); + pBS->FreePool(Template2); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReFlashEntry +// +// Description: This is the standard EFI driver entry point called for +// Recovery flash module initlaization +// Input: IN EFI_HANDLE ImageHandle - ImageHandle of the loaded driver +// IN EFI_SYSTEM_TABLE SystemTable - Pointer to the System Table +// +// Output: EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS EFIAPI ReFlashEntry (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) +{ + static EFI_GUID guidHob = HOB_LIST_GUID; + static EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID; + static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID; + UINT32 BootFlow = BOOT_FLOW_CONDITION_RECOVERY; + EFI_HOB_HANDOFF_INFO_TABLE *pHit; + UINTN Size; + UINT32 Attributes; + UINT32 FailedStage; + EFI_STATUS Status = EFI_SUCCESS; + + AUTOFLASH AutoFlash = { + (UINT8)(EFI_SUCCESS), + REFLASH_UPDATE_NVRAM, + REFLASH_UPDATE_BOOT_BLOCK, + REFLASH_UPDATE_MAIN_BLOCK +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT + ,REFLASH_UPDATE_EC_FIRMWARE +#endif + }; + + ThisImageHandle = ImageHandle; + InitAmiLib(ImageHandle,SystemTable); + + //Get Boot Mode + pHit = GetEfiConfigurationTable(pST, &guidHob); + + //unload the module if we are not in recovery mode + // TODO:need to distinguish between recovery and Flash Update + if (!pHit || (pHit->BootMode != BOOT_IN_RECOVERY_MODE && pHit->BootMode != BOOT_ON_FLASH_UPDATE)) { +#if SUPPORT_WIN8_STYLE_FW_UPDATE + InstallEsrtTable(); +#endif + return EFI_UNLOAD_IMAGE; + } + + VERIFY_EFI_ERROR(pBS->LocateProtocol(&gFlashProtocolGuid, NULL, &Flash)); +//Get Recovery Image verification status + if(!EFI_ERROR(FindNextHobByGuid(&RecoveryHobGuid, &pHit))) { + if(((EFI_HOB_GENERIC_HEADER *)pHit)->HobLength < sizeof(RECOVERY_IMAGE_HOB)) { + //we got update from older Core here + FailedStage = 0; + RecoveryStatus = EFI_SUCCESS; + } else { + FailedStage = ((RECOVERY_IMAGE_HOB*)pHit)->FailedStage; + RecoveryStatus = ((RECOVERY_IMAGE_HOB*)pHit)->Status; + + //Since RECOVERY_IMAGE_HOB Status field is byte long, we should set error bit by ourselves + if(RecoveryStatus != NULL) + RecoveryStatus |= EFI_ERROR_BIT; + } + RecoveryBuffer = (UINT8 *)(UINTN)((RECOVERY_IMAGE_HOB*)pHit)->Address; + } else { //Recovery Hob not found - should not happen, we always create this hob to report errors + FailedStage = 0; + RecoveryStatus = EFI_ABORTED; + } + + AutoFlash.FailedRecovery = (UINT8)RecoveryStatus; + +//Update Reflash parameters + Size = sizeof(AUTOFLASH); + Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; + pRS->SetVariable(L"Setup", &guidRecovery, Attributes, Size, &AutoFlash); + +#if SUPPORT_WIN8_STYLE_FW_UPDATE +//Verify if we're on OS firmware update path + Status = IsWin8Update((EFI_ERROR(RecoveryStatus)) ? TRUE : FALSE); + if(Status == EFI_SUCCESS || Status == EFI_UNLOAD_IMAGE) + return Status; +#endif + +//Load setup page and create error message if necessary + LoadResources(ImageHandle, sizeof(SetupCallBack) / sizeof(CALLBACK_INFO), SetupCallBack, NULL); + ReflashHiiHandle = SetupCallBack[0].HiiHandle; + pRS->SetVariable(L"BootFlow", &guidBootFlow, EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof(BootFlow), &BootFlow); + + UpdateSetupStrings(ReflashHiiHandle, RecoveryStatus, FailedStage); + + return EFI_SUCCESS; +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, 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/Recovery/ReFlash/ReFlash.cif b/Core/EM/Recovery/ReFlash/ReFlash.cif new file mode 100644 index 0000000..8d76667 --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlash.cif @@ -0,0 +1,16 @@ +<component> + name = "ReFlash" + category = ModulePart + LocalRoot = "Core\EM\Recovery\ReFlash\" + RefName = "ReFlash" +[files] +"ReFlash.sdl" +"ReFlash.mak" +"ReFlash.vfr" +"ReFlash.c" +"ReFlashWorker.c" +"ReFlash.dxs" +"ReFlash.uni" +"ReFlash.h" +"Esrt.c" +<endComponent> diff --git a/Core/EM/Recovery/ReFlash/ReFlash.dxs b/Core/EM/Recovery/ReFlash/ReFlash.dxs new file mode 100644 index 0000000..11e6c8d --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlash.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/BIN/Core/Modules/Recovery/ReFlash.dxs 3 10/09/09 6:30p Felixp $ +// +// $Revision: 3 $ +// +// $Date: 10/09/09 6:30p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Core/Modules/Recovery/ReFlash.dxs $ +// +// 3 10/09/09 6:30p Felixp +// ReFlash component is updated to support Framework and UEFI 2.1 HII +// +// 2 5/21/09 4:44p Felixp +// ReFlash driver is updated to use FlashProtocol instead of Flash library +// functions. +// +// 1 12/01/05 9:35a Felixp +// +// 1 11/08/05 4:04a Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: ReFlash.dxs +// +// Description: Dependancy expression for the component +// +//<AMI_FHDR_END> +//********************************************************************** +#if EFI_SPECIFICATION_VERSION>0x20000 +#include <Protocol/HiiDatabase.h> +#else +#include <Protocol/HII.h> +#endif +#include <Protocol/FlashProtocol.h> +DEPENDENCY_START +#if EFI_SPECIFICATION_VERSION>0x20000 + EFI_HII_DATABASE_PROTOCOL_GUID +#else + EFI_HII_PROTOCOL_GUID +#endif + AND 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/Recovery/ReFlash/ReFlash.h b/Core/EM/Recovery/ReFlash/ReFlash.h new file mode 100644 index 0000000..26ad479 --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlash.h @@ -0,0 +1,268 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlash.h 2 4/16/13 5:50a Thomaschen $ +// +// $Revision: 2 $ +// +// $Date: 4/16/13 5:50a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlash.h $ +// +// 2 4/16/13 5:50a Thomaschen +// Fixed for EIP106722. +// +// 13 1/02/13 12:18p Artems +// [TAG] EIP N/A +// [Category] Improvement +// [Description] Flash update progress report changes: +// - report progress in non-interactive flash update +// - do not report progress in Win8-style flash update +// [Files] ReflashWorker.c Reflash.h Esrt.c +// +// 12 7/20/12 10:20a Artems +// [TAG] EIP93520 +// [Category] New Feature +// [Description] Support of Microsoft ESRT spec +// [Files] Reflash.c Esrt.c Reflash.h Capsule.h ReflashWorker.c +// Protocol.cif AmiReflashProtocol.h Setup.h +// +// 11 5/22/12 4:44p Artems +// [TAG] EIP88314 +// [Description] Recovery takes a long time for large flash size +// Rewrite reflash code to not give control back to TSE until finished +// reporting progress via DisplayProgress API of AMI Post manager +// [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr +// Reflash.uni +// +// 10 11/12/11 6:49p Artems +// Added fault tolerant recovery support +// +// 9 5/13/11 4:52p Artems +// Added extended error reporting for secure flash update/recovery +// +// 8 11/17/10 2:52p Felixp +// Enhencement (EIP 36355): +// The Reflash component is updated to be extensible with external +// eModules. +// The eModules can contribute content for the Recovery setup page, +// and provide callback function that will be periodically called +// once BIOS update is completed.The external eModules can be used +// to implement update of non-standard firmware components. +// For example, update of the non-shared EC firmware. +// +// 7 12/24/09 12:42p Oleksiyy +// EIP 30173: Support for the EC Firmware Area Update control added. Main +// token to enable this support is EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT +// should be located in specific EC-related .sdl file. +// +// 6 10/09/09 6:30p Felixp +// ReFlash component is updated to support Framework and UEFI 2.1 HII +// +// 5 7/09/09 5:59p Oleksiyy +// Files clean-up, some headers added +// +// 4 10/19/07 6:23p Felixp +// Recovery Flash Update module extended to support Boot Block update. +// Boot block update can be enabled or disabled using SDL token. +// In addition to that there is an SDL token that enables/disables +// checkbox on the +// recovery setup page that user can use to enable or disable boot block +// update. +// +// 3 4/13/07 6:08p Ambikas +// Coding standard changes: updated the year in the AMI copyright +// header/footer. +// +// 2 12/22/06 9:38a Felixp +// Support for optional NVRAM reset based on user input added +// +// 1 12/01/05 9:35a Felixp +// +// 1 11/08/05 4:04a Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: ReFlash.h +// +// Description: Header file for component +// +//<AMI_FHDR_END> +//********************************************************************** +#ifndef __REFLASH__H__ +#define __REFLASH__H__ +#ifdef __cplusplus +extern "C" +{ +#endif +#include <ReFlashStrTokens.h> +#include <Token.h> +#ifndef VFRCOMPILE +#include <AmiDxeLib.h> +#include <Protocol/FlashProtocol.h> +#endif + +#define RECOVERY_FORM_SET_CLASS 0x40 +// {80E1202E-2697-4264-9CC9-80762C3E5863} +#define RECOVERY_FORM_SET_GUID { 0x80e1202e, 0x2697, 0x4264, 0x9c, 0xc9, 0x80, 0x76, 0x2c, 0x3e, 0x58, 0x63 } + +#if REFLASH_INTERACTIVE +#define RECOVERY_MAIN 1 +#define RECOVERY_FLASH 2 +#else +#define RECOVERY_FLASH 1 +#endif + +#define FLASH_PROGRESS_KEY 100 +#define FLASH_START_KEY 101 + +#pragma pack(push, 1) +typedef struct { + UINT8 FailedRecovery; // EFI_STATUS error code + UINT8 UpdateNv; + UINT8 UpdateBb; + UINT8 UpdateMain; +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT + UINT8 UpdateEC; +#endif + +#define REFLASH_DATA_DEFINITION +#include <ReflashDefinitions.h> +#undef REFLASH_DATA_DEFINITION + +} AUTOFLASH; +#pragma pack(pop) + +#include <Setup.h> + +#ifndef VFRCOMPILE + +#define FW_VERSION_VARIABLE L"AmiFwVersion" + +typedef enum { + FvTypeMain, + FvTypeBootBlock, + FvTypeNvRam, + FvTypeCustom, + FvTypeMax +} FLASH_FV_TYPE; + +typedef struct _FLASH_AREA_EX FLASH_AREA_EX; + +typedef EFI_STATUS (REFLASH_FUNCTION_EX)( + IN FLASH_AREA_EX *Block, + IN UINTN BlockNumber +); + +struct _FLASH_AREA_EX +{ + UINT8 *BlockAddress; + UINT8 *BackUpAddress; + UINTN Size; + UINT32 BlockSize; + FLASH_FV_TYPE Type; + BOOLEAN Update; + BOOLEAN TopSwapTrigger; + REFLASH_FUNCTION_EX *BackUp; + REFLASH_FUNCTION_EX *Program; + EFI_STRING_ID BackUpString; + EFI_STRING_ID ProgramString; +}; + +extern FLASH_AREA_EX BlocksToUpdate[]; +extern FLASH_PROTOCOL *Flash; +extern EFI_HII_HANDLE ReflashHiiHandle; +extern UINT8 *RecoveryBuffer; + +EFI_STATUS GetHiiString( + IN EFI_HII_HANDLE HiiHandle, + IN STRING_REF Token, + IN OUT UINTN *pDataSize, + OUT EFI_STRING *ppData +); + +EFI_STATUS AmiFlashBackUp( + IN FLASH_AREA_EX *Block, + IN UINTN BlockNumber +); +EFI_STATUS AmiFlashProgram( + IN FLASH_AREA_EX *Block, + IN UINTN BlockNumber +); + +VOID ApplyUserSelection( + IN BOOLEAN Interactive +); + +VOID OemBeforeFlashCallback( + VOID +); + +VOID OemAfterFlashCallback( + VOID +); + +EFI_STATUS FlashProgressEx( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID KeyValue, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest +); + +EFI_STATUS IsWin8Update( + BOOLEAN RecoveryFailed +); + +EFI_STATUS FlashWalker( + IN BOOLEAN BackUp +); + +EFI_STATUS Epilogue( + VOID +); + +EFI_STATUS Prologue( + IN BOOLEAN Interactive, + IN BOOLEAN Win8StyleUpdate +); + +EFI_STATUS InstallEsrtTable( + VOID +); + +#endif + /****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif +//********************************************************************** +//********************************************************************** +//** ** +//** (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/Recovery/ReFlash/ReFlash.mak b/Core/EM/Recovery/ReFlash/ReFlash.mak new file mode 100644 index 0000000..6edcd3e --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlash.mak @@ -0,0 +1,135 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/BIN/Core/Modules/Recovery/ReFlash.mak 15 5/22/12 5:10p Artems $ +# +# $Revision: 15 $ +# +# $Date: 5/22/12 5:10p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Core/Modules/Recovery/ReFlash.mak $ +# +# 15 5/22/12 5:10p Artems +# [TAG] EIP88314 +# [Category] Improvement +# [Description] Recovery takes a long time for large flash size +# Rewrite reflash code to not give control back to TSE until finished +# reporting progress via DisplayProgress API of AMI Post manager +# [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr +# Reflash.uni +# +# 14 12/05/11 1:48p Artems +# EIP 74623: Add capabilities similar to ones in SMIFlash module +# +# 13 11/29/11 3:33p Artems +# Fixed build error when FtRecovery module is present but disabled +# +# 12 11/12/11 6:47p Artems +# Added fault tolerant recovery support +# +# 11 11/30/10 5:04p Felixp +# Bug fix: VfrCompile build error when ReflashFunctions eLink list +# contains more than one function. +# +# 10 11/17/10 5:27p Felixp +# $(BUILD_DIR)\ReFlash.mak dependency is updated. +# +# 9 11/17/10 2:52p Felixp +# Enhencement (EIP 36355): +# The Reflash component is updated to be extensible with external +# eModules. +# The eModules can contribute content for the Recovery setup page, +# and provide callback function that will be periodically called +# once BIOS update is completed.The external eModules can be used +# to implement update of non-standard firmware components. +# For example, update of the non-shared EC firmware. +# +# 8 10/01/10 2:14p Felixp +# Previous changes related to descrete EC firmware update are rolled back +# for the Core labeling. +# +# 6 2/23/10 9:20p Felixp +# Support of the ReFlash String Override via REFLASH_SDBS eLink (EIP +# 32696). +# +# 5 7/09/09 5:59p Oleksiyy +# Files clean-up, some headers added +# +# 4 12/29/06 2:58p Felixp +# RecoveryDxeLib removed. Functionality moved to Flash.lib +# +# 3 8/24/06 9:19a Felixp +# x64 Support +# +# 1 11/08/05 4:04a Felixp +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: ReFlash.mak +# +# Description: +# +#<AMI_FHDR_END> +#********************************************************************** +all : ReFlash + +SetupData : ReFlash + +ReFlash : $(BUILD_DIR)\ReFlash.mak ReFlashBin + +$(BUILD_DIR)\ReFlash.mak : $(ReFlash_DIR)\$(@B).cif $(ReFlash_DIR)\$(@B).mak $(BUILD_RULES) $(REFLASH_CIFS) $(BUILD_DIR)\token.h + $(CIF2MAK) $(ReFlash_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) $(REFLASH_CIFS) + +REFLASH_LISTS = \ +/D\"REFLASH_FUNCTION_LIST=$(ReflashFunctions)\"\ +/D\"OEM_BEFORE_FLASH_UPDATE_CALLBACK_LIST=$(OemBeforeFlashUpdateList)\"\ +/D\"OEM_AFTER_FLASH_UPDATE_CALLBACK_LIST=$(OemAfterFlashUpdateList)\" + +ReFlashBin : $(AMIDXELIB) $(FLASHLIB) + type << >$(BUILD_DIR)\ReflashDefinitions.h +!IF "$(REFLASH_DEFINITIONS)"!="" +#include<$(REFLASH_DEFINITIONS: =>^ +#include<)> +!ENDIF +<< + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\ReFlash.mak all\ + GUID=70e1a818-0be1-4449-bfd4-9ef68c7f02a8\ + ENTRY_POINT=ReFlashEntry\ + "EXT_HEADERS=$(BUILD_DIR)\token.h"\ + TYPE=BS_DRIVER \ + MY_INCLUDES=/I$(ReFlash_DIR)\ + "CFLAGS=$(CFLAGS) $(REFLASH_LISTS)"\ + COMPRESS=1 HAS_RESOURCES=1\ +!IF "$(REFLASH_SDBS: =)"!="" + "MY_SDBS=-db $(REFLASH_SDBS: = -db )"\ +!ENDIF + +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, 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/Recovery/ReFlash/ReFlash.sdl b/Core/EM/Recovery/ReFlash/ReFlash.sdl new file mode 100644 index 0000000..db29792 --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlash.sdl @@ -0,0 +1,135 @@ +TOKEN + Name = "ReFlash_SUPPORT" + Value = "1" + Help = "Main switch to enable ReFlash support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "REFLASH_INTERACTIVE" + Value = "1" + Help = "When this switch is enabled, flash update process is interactive.\User can adjust update parameters before the update.\User can also choose not to update the flash.\Once update is completed user has to press a key to reset the system\When this switch is disabled, flash update process is started automatically.\User can only monitor progress of the operation.\Once update is completed system resets." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "REFLASH_UPDATE_NVRAM_CONTROL" + Value = "1" + Help = "Eanbles/Disables Setup option that that controls NVRAM update" + TokenType = Boolean + TargetH = Yes + Token = "REFLASH_INTERACTIVE" "=" "1" +End + +TOKEN + Name = "REFLASH_UPDATE_NVRAM" + Value = "1" + Help = "Enables/Disables update of the NVRAM flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_NVRAM_CONTROL is on\this value can be overriden by the user using setup option." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "REFLASH_UPDATE_BOOT_BLOCK_CONTROL" + Value = "0" + Help = "Enables/Disables Setup option that controls boot block update" + TokenType = Boolean + TargetH = Yes + Token = "REFLASH_INTERACTIVE" "=" "1" +End + +TOKEN + Name = "REFLASH_UPDATE_BOOT_BLOCK" + Value = "0" + Help = "Enables/Disables update of the boot block flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_BOOT_BLOCK_CONTROL is on\this value can be overriden by the user using setup option." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "REFLASH_UPDATE_MAIN_BLOCK" + Value = "1" + Help = "Enables/Disables update of the Main block flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_BOOT_BLOCK_CONTROL is on\this value can be overriden by the user using setup option." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "REFLASH_UPDATE_EC_FIRMWARE_CONTROL" + Value = "0" + Help = "Eanbles/Disables Setup option that controls EC FIRMWARE update" + TokenType = Boolean + TargetH = Yes + Token = "REFLASH_INTERACTIVE" "=" "1" + Token = "EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT" "=" "1" +End + +TOKEN + Name = "REFLASH_UPDATE_EC_FIRMWARE" + Value = "0" + Help = "Enables/Disables update of the EC FIRMWARE flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_EC_FIRMWARE_CONTROL is on\this value can be overriden by the user using setup option." + TokenType = Boolean + TargetH = Yes + Token = "EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT" "=" "1" +End + +PATH + Name = "ReFlash_DIR" +End + +MODULE + Help = "Includes ReFlash.mak to Project" + File = "ReFlash.mak" +End + +ELINK + Name = "$(BUILD_DIR)\ReFlash.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(BUILD_DIR)\$(ReFlash_DIR)" + Parent = "IFR_DIR_LIST" + InvokeOrder = BeforeParent +End + +ELINK + Name = "REFLASH_SDBS" + Help = "List of SDB files with the string overrides for the ReFlash component" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "REFLASH_CIFS" + Help = "List of CIF files of the ReFlash plug-ins" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "REFLASH_DEFINITIONS" + Help = "List of SD files of the ReFlash plug-ins" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "ReflashFunctions" + Help = "List of callback functions of the ReFlash plug-ins" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "OemBeforeFlashUpdateList" + Help = "List of callback functions to be called before flash update" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "OemAfterFlashUpdateList" + Help = "List of callback functions to be called after flash update" + InvokeOrder = ReplaceParent +End diff --git a/Core/EM/Recovery/ReFlash/ReFlash.uni b/Core/EM/Recovery/ReFlash/ReFlash.uni Binary files differnew file mode 100644 index 0000000..13e42f7 --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlash.uni diff --git a/Core/EM/Recovery/ReFlash/ReFlash.vfr b/Core/EM/Recovery/ReFlash/ReFlash.vfr new file mode 100644 index 0000000..5884ea2 --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlash.vfr @@ -0,0 +1,240 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Core/Modules/Recovery/ReFlash.vfr 17 5/22/12 5:12p Artems $ +// +// $Revision: 17 $ +// +// $Date: 5/22/12 5:12p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Core/Modules/Recovery/ReFlash.vfr $ +// +// 17 5/22/12 5:12p Artems +// [TAG] EIP88314 +// [Category] Improvement +// [Description] Recovery takes a long time for large flash size +// Rewrite reflash code to not give control back to TSE until finished +// reporting progress via DisplayProgress API of AMI Post manager +// +// [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr +// Reflash.uni +// +// 16 11/12/11 6:48p Artems +// Added fault tolerant recovery support +// +// 15 11/02/11 4:53p Artems +// EIP 74446: Fixed bug - reflash is enabled when recovery image is not +// found +// +// 14 5/13/11 4:49p Artems +// Added REFLASH_UPDATE_MAIN_BLOCK setup control +// +// 13 11/17/10 2:52p Felixp +// Enhencement (EIP 36355): +// The Reflash component is updated to be extensible with external +// eModules. +// The eModules can contribute content for the Recovery setup page, +// and provide callback function that will be periodically called +// once BIOS update is completed.The external eModules can be used +// to implement update of non-standard firmware components. +// For example, update of the non-shared EC firmware. +// +// 12 10/01/10 2:14p Felixp +// Previous changes related to descrete EC firmware update are rolled back +// for the Core labeling. +// +// 10 12/24/09 12:41p Oleksiyy +// EIP 30173: Support for the EC Firmware Area Update control added. Main +// token to enable this support is EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT +// should be located in specific EC-related .sdl file. +// +// 9 12/14/09 3:11p Aaronp +// Updated to support UEFI2.1 interactive text +// +// 8 10/09/09 6:30p Felixp +// ReFlash component is updated to support Framework and UEFI 2.1 HII +// +// 7 7/09/09 5:59p Oleksiyy +// Files clean-up, some headers added +// +// 6 10/22/08 9:36a Felixp +// Bug fix (EIP 15931): NVRAM was never reset during BIOS Recovery. Even +// when 'Reset NVRAM' setup option was enabled. +// The bug was caused by the wrong varstore passed into the callback +// routine. +// Form layout has been changed to make sure default varstore is active +// when goto statement is reached. +// +// 5 10/09/08 5:30p Felixp +// Bug fix (EIP 13077): During BIOS Recovery the warning about flash +// update being disabled due to the user access level was truncated +// +// 4 1/17/08 5:30p Felixp +// Updated to disable flash update option during boot with the USER access +// level +// +// 3 10/19/07 6:23p Felixp +// Recovery Flash Update module extended to support Boot Block update. +// Boot block update can be enabled or disabled using SDL token. +// In addition to that there is an SDL token that enables/disables +// checkbox on the +// recovery setup page that user can use to enable or disable boot block +// update. +// +// 2 12/22/06 9:38a Felixp +// Support for optional NVRAM reset based on user input added +// +// 1 12/01/05 9:35a Felixp +// +// 1 11/08/05 4:04a Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: ReFlash.vfr +// +// Description: Reflash formset +// +//<AMI_FHDR_END> +//********************************************************************** +#include "ReFlash.h" + +formset guid = RECOVERY_FORM_SET_GUID, + title = STRING_TOKEN(STR_RECOVERY), + help = STRING_TOKEN(STR_EMPTY), + class = RECOVERY_FORM_SET_CLASS, subclass = 0, + + varstore AUTOFLASH, + name = Setup, + guid = RECOVERY_FORM_SET_GUID; + + AMI_CALLBACK_VARSTORE + SYSTEM_ACCESS_VARSTORE + + +#if REFLASH_INTERACTIVE + + form formid = RECOVERY_MAIN, + title = STRING_TOKEN(STR_RECOVERY); + + SUBTITLE(STRING_TOKEN(STR_SUBTITLE1)) + SUBTITLE(STRING_TOKEN(STR_SUBTITLE2)) + + suppressif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_ADMIN; + text + help = STRING_TOKEN(STR_EMPTY), + text = STRING_TOKEN(STR_ACCESS_DENIED), + text = STRING_TOKEN(STR_ACCESS_DENIED2), + flags = 0, key = 0; + text + help = STRING_TOKEN(STR_EMPTY), + text = STRING_TOKEN(STR_ACCESS_DENIED3), + text = STRING_TOKEN(STR_ACCESS_DENIED4), + flags = 0, key = 0; + endif; + + SEPARATOR + + SUBTITLE(STRING_TOKEN(STR_OPTIONS)) + + grayoutif NOT ideqval AUTOFLASH.FailedRecovery == 0 OR ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER; + +#if REFLASH_UPDATE_NVRAM_CONTROL + checkbox varid = AUTOFLASH.UpdateNv, + prompt = STRING_TOKEN(STR_UPDATE_NVRAM), + help = STRING_TOKEN(STR_UPDATE_NVRAM_HELP), + flags = REFLASH_UPDATE_NVRAM, // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value. 1 = ON, 0 = off + endcheckbox; +#endif +#if REFLASH_UPDATE_BOOT_BLOCK_CONTROL + checkbox varid = AUTOFLASH.UpdateBb, + prompt = STRING_TOKEN(STR_UPDATE_BB), + help = STRING_TOKEN(STR_UPDATE_BB_HELP), + flags = REFLASH_UPDATE_BOOT_BLOCK, // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value. 1 = ON, 0 = off + endcheckbox; +#endif + + checkbox varid = AUTOFLASH.UpdateMain, + prompt = STRING_TOKEN(STR_UPDATE_MAIN), + help = STRING_TOKEN(STR_UPDATE_MAIN_HELP), + flags = REFLASH_UPDATE_MAIN_BLOCK, // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value. 1 = ON, 0 = off +#if FtRecovery_SUPPORT + inconsistentif prompt = STRING_TOKEN(STR_FLASH_SELECTION_ERROR_POPUP), + ideqval AUTOFLASH.UpdateBb == 1 + AND + ideqval AUTOFLASH.UpdateMain == 0 + endif +#endif + endcheckbox; +#if REFLASH_UPDATE_EC_FIRMWARE_CONTROL + checkbox varid = AUTOFLASH.UpdateEC, + prompt = STRING_TOKEN(STR_UPDATE_EC), + help = STRING_TOKEN(STR_UPDATE_EC_HELP), + flags = REFLASH_UPDATE_EC_FIRMWARE, // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value. 1 = ON, 0 = off + endcheckbox; +#endif + +#define REFLASH_CONTROL +#include <ReflashDefinitions.h> +#undef REFLASH_CONTROL + + //Can't use 'SEPARATOR' because it's not allowed in the grayoutif scope + INVENTORY(STRING_TOKEN(STR_EMPTY),STRING_TOKEN(STR_EMPTY)) + + endif;//grayoutif + + suppressif NOT ideqval AUTOFLASH.FailedRecovery == 0 OR ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER; + goto RECOVERY_FLASH, + prompt = STRING_TOKEN(STR_FLASH), + help = STRING_TOKEN(STR_FLASH_HELP), + flags = INTERACTIVE, key = FLASH_START_KEY; + endif; + endform; +#endif //#if REFLASH_INTERACTIVE + + form formid = RECOVERY_FLASH, + title = STRING_TOKEN(STR_RECOVERY_FLASH); + SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING1)) + SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING2)) + SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING3)) + SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING_RESET)) +#if REFLASH_INTERACTIVE + SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING_RESET_USER)) +#else + SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING_RESET_AUTO)) +#endif + SEPARATOR + + INTERACTIVE_TEXT(STRING_TOKEN(STR_FLASH_PROGRESS_HELP), STRING_TOKEN(STR_EMPTY), STRING_TOKEN(STR_EMPTY), FLASH_PROGRESS_KEY) +#define REFLASH_PROGRESS +#include <ReflashDefinitions.h> +#undef REFLASH_PROGRESS + endform; +endformset; +//********************************************************************** +//********************************************************************** +//** ** +//** (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/Recovery/ReFlash/ReFlashWorker.c b/Core/EM/Recovery/ReFlash/ReFlashWorker.c new file mode 100644 index 0000000..6ab6fa7 --- /dev/null +++ b/Core/EM/Recovery/ReFlash/ReFlashWorker.c @@ -0,0 +1,720 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlashWorker.c 3 5/13/13 6:26a Thomaschen $ +// +// $Revision: 3 $ +// +// $Date: 5/13/13 6:26a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlashWorker.c $ +// +// 3 5/13/13 6:26a Thomaschen +// Update for EIP122037. +// +// 2 4/16/13 5:47a Thomaschen +// Fixed for EIP106722. +// +// +// 7 2/11/13 3:42p Artems +// [TAG] EIP112180 +// [Category] Bug Fix +// [Severity] Critical +// [Symptom] In non-interactive mode system updated flash even when +// there is no valid image +// [RootCause] In non-interactive mode system didn't check flash image +// validity +// [Solution] Added check of flash image validity. Inform user if image +// is invalid or not found +// [Files] Reflash.c ReflashWorker.c Reflash.uni Reflash.vfr +// +// 6 1/02/13 12:20p Artems +// [TAG] EIP N/A +// [Category] Improvement +// [Description] Flash update progress report changes: +// - report progress in non-interactive flash update +// - do not report progress in Win8-style flash update +// [Files] ReflashWorker.c Reflash.h Esrt.c +// +// 5 8/02/12 12:00p Artems +// [TAG] EIP93520 +// [Category] New Feature +// [Description] Support of Microsoft ESRT spec +// [Files] Recovery.h Recovery.sdl Recovery.c Reflash.c ReflashWorker.c +// Esrt.c +// +// 4 7/24/12 11:56a Artems +// [TAG] EIP N/A +// [Category] Improvement +// [Description] Added dependency on fault-tolerant support module in +// top-swap triggering code +// [Files] ReflashWorker.c +// +// 3 7/20/12 10:19a Artems +// [TAG] EIP93520 +// [Category] New Feature +// [Description] Support of Microsoft ESRT spec +// [Files] Reflash.c Esrt.c Reflash.h Capsule.h ReflashWorker.c +// Protocol.cif AmiReflashProtocol.h Setup.h +// +// 2 6/08/12 12:35p Artems +// [TAG] EIP88314 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Incorrect strings in progress message +// [RootCause] String tokens were twisted up +// [Solution] Put string tokens in a correct order +// [Files] ReflashWorker.c +// +// 1 5/23/12 1:19p Artems +// [TAG] EIP 88314 +// [Category] Improvement +// [Description] Recovery takes a long time for large flash size +// Rewrite reflash code to not give control back to TSE until finished +// reporting progress via DisplayProgress API of AMI Post manager +// +// [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr +// Reflash.uni +// +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: ReFlashWorker.c +// +// Description: Implementation of Reflash driver +// +//<AMI_FHDR_END> +//********************************************************************** + +#include <Token.h> +#include <FFS.h> +#include <AmiCspLib.h> +#include <Protocol/AmiPostMgr.h> +#include <Protocol/ConsoleControl.h> +#include "Reflash.h" + +#define FLASH_PART_START_ADDRESS (0xFFFFFFFF - FLASH_SIZE + 1) +static UINT32 FlashEraser = (FLASH_ERASE_POLARITY) ? 0 : 0xffffffff; +static UINT8 *FlashPartStart = (UINT8 *)(UINTN)FLASH_PART_START_ADDRESS; +extern EFI_STATUS RecoveryStatus; + +FLASH_AREA_EX BlocksToUpdate[] = { +#if FtRecovery_SUPPORT + { + (UINT8 *)FV_RECOVERY_BASE, + (UINT8 *)FV_RECOVERY_BACKUP_ADDRESS, + FV_RECOVERY_BLOCKS * FLASH_BLOCK_SIZE, + FLASH_BLOCK_SIZE, + FvTypeBootBlock, + REFLASH_UPDATE_BOOT_BLOCK, + FALSE, + AmiFlashBackUp, + AmiFlashProgram, + STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_BACKUP_RECOVERY), + STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_RECOVERY) + }, + { + (UINT8 *)FV_BB_BASE, + (UINT8 *)FV_BB_BACKUP_ADDRESS, + (FV_BB_BLOCKS - FV_RECOVERY_BLOCKS) * FLASH_BLOCK_SIZE, + FLASH_BLOCK_SIZE, + FvTypeBootBlock, + REFLASH_UPDATE_BOOT_BLOCK, + TRUE, + AmiFlashBackUp, + AmiFlashProgram, + STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_BACKUP_BB), + STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_BB) + }, +#else + { + (UINT8 *)FV_BB_BASE, + NULL, + FV_BB_BLOCKS * FLASH_BLOCK_SIZE, + FLASH_BLOCK_SIZE, + FvTypeBootBlock, + REFLASH_UPDATE_BOOT_BLOCK, + FALSE, + NULL, + AmiFlashProgram, + 0, + STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_BB) + }, +#endif + +// EIP122037>> +#if INTEL_FIT_SUPPORT + { + (UINT8 *)FV_DATA_BASE, + NULL, + FV_DATA_SIZE, + FLASH_BLOCK_SIZE, + FvTypeBootBlock, + REFLASH_UPDATE_BOOT_BLOCK, + FALSE, + NULL, + AmiFlashProgram, + 0, + STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_DATA) + }, +#endif +// EIP122037<< + { + (UINT8 *)FV_MAIN_BASE, + NULL, + FV_MAIN_BLOCKS * FLASH_BLOCK_SIZE, + FLASH_BLOCK_SIZE, + FvTypeMain, + REFLASH_UPDATE_MAIN_BLOCK, + FALSE, + NULL, + AmiFlashProgram, + 0, + STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_MAIN) + }, + { + (UINT8 *)NVRAM_ADDRESS, + NULL, + NVRAM_BLOCKS * FLASH_BLOCK_SIZE, + FLASH_BLOCK_SIZE, + FvTypeNvRam, + REFLASH_UPDATE_NVRAM, + FALSE, + NULL, + AmiFlashProgram, + 0, + STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_NVRAM) + }, +#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT + { + (UINT8 *)EC_BASE, + NULL, + EC_BLOCKS * FLASH_BLOCK_SIZE, + FLASH_BLOCK_SIZE, + FvTypeCustom, + REFLASH_UPDATE_EC_FIRMWARE, + FALSE, + NULL, + AmiFlashProgram, + 0, + STRING_TOKEN(STR_FLASH_PROGRESS_CAPTION_FLASH) + }, +#endif + + { + NULL, + NULL, + 0, + 0, + FvTypeMax, + FALSE, + FALSE, + NULL, + NULL, + 0, + 0 + } //terminator +}; + + + +static EFI_GUID AmiPostManagerProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID; +static AMI_POST_MANAGER_PROTOCOL *AmiPostMgr = NULL; +static EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; +static BOOLEAN UserConfirmation = TRUE; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DrawMessageBox +// +// Description: This function draws message box on screen and waits till user presses Enter +// +// Input: +// IN CHAR16 *Caption - message box caption +// IN CHAR16 *Message - message box message +// +// Output: +// None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID DrawMessageBox( + IN CHAR16 *Caption, + IN CHAR16 *Message +) +{ + EFI_STATUS Status; + UINT8 MsgKey; + + if(!UserConfirmation) + return; + + if(AmiPostMgr != NULL) { + if(ConsoleControl != NULL) + ConsoleControl->LockStdIn(ConsoleControl, L""); + + pST->ConIn->Reset(pST->ConIn, FALSE); //discard all keystrokes happend during flash update + + Status = AmiPostMgr->DisplayMsgBox(Caption, Message, MSGBOX_TYPE_OK, &MsgKey); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: CountDown +// +// Description: This function draws ResetSystem waiting bar +// +// Input: +// None +// +// Output: +// None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +//TODO +VOID CountDown( + VOID +) +{ + pBS->Stall(5000000); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: Prologue +// +// Description: This function is called before actual flashing takes place +// +// Input: +// IN BOOLEAN Interactive - if TRUE reflash is interactive +// IN BOOLEAN Win8StyleUpdate - if TRUE reflash is Win8Style +// +// Output: +// EFI_SUCCESS - system prepared for flashing +// EFI_NOT_STARTED - recovery image not found +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS Prologue( + IN BOOLEAN Interactive, + IN BOOLEAN Win8StyleUpdate +) +{ + static BOOLEAN Executed = FALSE; + static EFI_STATUS Status = EFI_SUCCESS; + + if(Executed) + return Status; + + Executed = TRUE; + ApplyUserSelection(Interactive); + + if(!Win8StyleUpdate) //we do not report progress during Win8-style flash update + Status = pBS->LocateProtocol(&AmiPostManagerProtocolGuid, NULL, &AmiPostMgr); + + if(Interactive) { + Status = pBS->LocateProtocol(&gEfiConsoleControlProtocolGuid, NULL, &ConsoleControl); + if(!EFI_ERROR(Status)) + ConsoleControl->LockStdIn(ConsoleControl, L""); + } else { + if(EFI_ERROR(RecoveryStatus)) { //we can't perform flash update, inform user and return error for resetting system + CountDown(); + return EFI_ABORTED; + } + UserConfirmation = FALSE; + } + + OemBeforeFlashCallback(); + Flash->DeviceWriteEnable(); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: Epilogue +// +// Description: This function is called after actual flashing takes place +// +// Input: +// None +// +// Output: (this function is not supposed to return control to caller +// EFI_SUCCESS - flash updated successfully +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS Epilogue(VOID) +{ + Flash->DeviceWriteDisable(); + OemAfterFlashCallback(); + + DrawMessageBox(L"Flash update", L"Flash update completed. Press Enter key to reset the system"); + pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: FlashWalker +// +// Description: This function walks through flash regions and calls respective +// backup and flash functions +// +// Input: +// IN BOOLEAN BackUp - if TRUE, backup functions should be called on this pass +// flash programm functions should be called otherwise +// +// Output: +// EFI_SUCCESS - flash updated successfully +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS FlashWalker( + IN BOOLEAN BackUp +) +{ + EFI_STATUS Status; + UINTN i; + UINTN k; + EFI_STRING Title; + EFI_STRING Message; + UINTN Size; + UINTN Step; + UINTN Threshold; + UINTN Blocks; + + VOID *DisplayHandle; + AMI_POST_MGR_KEY OutKey; + + if(AmiPostMgr != NULL) { + Title = NULL; + if(BackUp) + GetHiiString(ReflashHiiHandle, STRING_TOKEN(STR_FLASH_PROGRESS_TITLE_BACKUP), &Size, &Title); + else + GetHiiString(ReflashHiiHandle, STRING_TOKEN(STR_FLASH_PROGRESS_TITLE_FLASH), &Size, &Title); + + AmiPostMgr->DisplayProgress(AMI_PROGRESS_BOX_INIT, + (Title == NULL) ? L"Flash Update Progress" : Title, + NULL, + NULL, + 0, + &DisplayHandle, + &OutKey); + } + + for(i = 0; BlocksToUpdate[i].Type != FvTypeMax; i++) { + if(!BlocksToUpdate[i].Update) + continue; //block is not updated + + if(BackUp && BlocksToUpdate[i].BackUp == NULL) + continue; //no backup function + + if(AmiPostMgr != NULL) { + /* prepare display progress window */ + Message = NULL; + if(BackUp) + GetHiiString(ReflashHiiHandle, BlocksToUpdate[i].BackUpString, &Size, &Message); + else + GetHiiString(ReflashHiiHandle, BlocksToUpdate[i].ProgramString, &Size, &Message); + } + + /* calculate number of blocks to flash */ + Blocks = BlocksToUpdate[i].Size / BlocksToUpdate[i].BlockSize; + + /* calculate progress steps */ + Step = 0; + if(Blocks > 100) { + Threshold = (Blocks / 100) + 1; + } else { + Threshold = 1; + } + + /* now we're ready to do actual job */ + for(k = 0; k < Blocks; k++) { + if(BackUp) + Status = BlocksToUpdate[i].BackUp(&BlocksToUpdate[i], k); + else + Status = BlocksToUpdate[i].Program(&BlocksToUpdate[i], k); + + if(EFI_ERROR(Status)) + return Status; + + Step++; + if(Step == Threshold && AmiPostMgr != NULL) { + /* report progress to user */ + AmiPostMgr->DisplayProgress(AMI_PROGRESS_BOX_UPDATE, + (Title == NULL) ? L"Flash Update Progress" : Title, + (Message == NULL) ? L"Flash new data" : Message, + NULL, + (k * 100) / Blocks, + &DisplayHandle, + &OutKey); + Step = 0; + } + } + +#if FtRecovery_SUPPORT + /* check if TopSwap should be triggered */ + if(BlocksToUpdate[i].TopSwapTrigger) { + if(BackUp) + SetTopSwap(TRUE); + else + SetTopSwap(FALSE); + } +#endif + } + + if(AmiPostMgr != NULL) { + /* close progress window */ + AmiPostMgr->DisplayProgress(AMI_PROGRESS_BOX_CLOSE, + (Title == NULL) ? L"Flash Update Progress" : Title, + NULL, + NULL, + 0, + &DisplayHandle, + &OutKey); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: FlashProgressEx +// +// Description: This function is called by Setup browser to perform flash update +// +// Input: +// IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This - pointer to the instance of +// ConfigAccess protocol +// IN EFI_BROWSER_ACTION Action - action, that setup browser is performing +// IN EFI_QUESTION_ID KeyValue - value of currently processed setup control +// IN UINT8 Type - value type of setup control data +// IN EFI_IFR_TYPE_VALUE *Value - pointer to setup control data +// OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest - pointer where to store requested action +// +// Output: +// EFI_SUCCESS - flash updated successfully +// EFI_UNSUPPORTED - browser action is not supported +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS FlashProgressEx( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID KeyValue, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest +) +{ + EFI_STATUS Status; + + if (ActionRequest) + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; + + if(Action != EFI_BROWSER_ACTION_CHANGING) + return EFI_UNSUPPORTED; + + +#if REFLASH_INTERACTIVE + if(KeyValue == FLASH_START_KEY) { + Status = Prologue(TRUE, FALSE); + if(EFI_ERROR(Status)) { + /* inform user, that flashing can't be performed */ + DrawMessageBox(L"ERROR!!!!", L"Flash update failed to initialize. Press Enter key to reset system"); + pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + } + /* we have to give control back to setup browser to refresh the screen */ + return EFI_SUCCESS; + } +/* nothing to do here, wait for user response */ + if (KeyValue != FLASH_PROGRESS_KEY) { + return EFI_SUCCESS; + } +#else + Status = Prologue(FALSE, FALSE); + if(EFI_ERROR(Status)) { + pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + } +#endif + + Status = EFI_SUCCESS; + +#if FtRecovery_SUPPORT + if(!IsTopSwapOn()) { + Status = FlashWalker(TRUE); + } +#endif + + if(!EFI_ERROR(Status)) { + Status = FlashWalker(FALSE); + } + + if(EFI_ERROR(Status)) { + /* something was wrong - inform user */ + DrawMessageBox(L"ERROR!!!!", L"Flash update failed. Press Enter key to reset system"); + pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); + } + + Status = Epilogue(); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SetBackUpArea +// +// Description: This function prepares FV_MAIN region to be backup region +// +// Input: +// None +// +// Output: +// None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SetBackUpArea(VOID) +{ + static BOOLEAN FirstRun = TRUE; + static UINT32 FlashEraser = (FLASH_ERASE_POLARITY) ? 0 : 0xffffffff; + EFI_FIRMWARE_VOLUME_HEADER *Fv; + + if(!FirstRun) + return; + + FirstRun = FALSE; + Fv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FV_MAIN_BASE; + Flash->Write(&(Fv->Signature), sizeof(UINT32), &FlashEraser); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: AmiFlashBackUp +// +// Description: This function backs up given block from given region +// +// Input: +// IN FLASH_AREA_EX *Block - flash region to work with +// IN UINTN BlockNumber - block number within flash region +// +// Output: +// EFI_SUCCESS - block saved successfully +// EFI_ERROR - there was an error during operation +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS AmiFlashBackUp( + IN FLASH_AREA_EX *Block, + IN UINTN BlockNumber +) +{ + UINT8 *Source; + UINT8 *Destination; + VOID *Tmp; + EFI_STATUS Status; + EFI_TPL OldTpl; + + Status = pBS->AllocatePool(EfiBootServicesData, Block->BlockSize, &Tmp); + if(EFI_ERROR(Status)) + return Status; + + Source = Block->BlockAddress + BlockNumber * Block->BlockSize; + Destination = Block->BackUpAddress + BlockNumber * Block->BlockSize; + + if(Block->Type == FvTypeBootBlock) + SetBackUpArea(); + + Status = Flash->Read(Source, Block->BlockSize, Tmp); + if(EFI_ERROR(Status)) { + pBS->FreePool(Tmp); + return Status; + } + +//save to backup address + OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL); + Status = Flash->Update(Destination, Block->BlockSize, Tmp); + pBS->RestoreTPL(OldTpl); + + pBS->FreePool(Tmp); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: AmiFlashProgram +// +// Description: This function programs given block from given region +// +// Input: +// IN FLASH_AREA_EX *Block - flash region to work with +// IN UINTN BlockNumber - block number within flash region +// +// Output: +// EFI_SUCCESS - block updated successfully +// EFI_ERROR - there was an error during operation +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS AmiFlashProgram( + IN FLASH_AREA_EX *Block, + IN UINTN BlockNumber +) +{ + UINT8 *ImageStart; + UINT8 *Source; + UINT8 *Destination; + EFI_STATUS Status; + EFI_TPL OldTpl; + + ImageStart = Block->BlockAddress - FlashPartStart + RecoveryBuffer; + Source = ImageStart + BlockNumber * Block->BlockSize; + Destination = Block->BlockAddress + BlockNumber * Block->BlockSize; + + OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL); + Status = Flash->Update(Destination, Block->BlockSize, Source); + pBS->RestoreTPL(OldTpl); + + return Status; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** |