BayTrail/AmiModulePkg/Recovery/UpdateCapsule.c
2018-06-21 15:06:56 +08:00

211 lines
7.9 KiB
C

//**********************************************************************
//**********************************************************************
//** **
//** (C)Copyright 1985-2013 American Megatrends, Inc. **
//** **
//** All Rights Reserved. **
//** **
//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
//** **
//** Phone: (770)-246-8600 **
//** **
//**********************************************************************
//**********************************************************************
//**********************************************************************
// $Header: Alexp $
//
// $Revision: $
//
// $Date: $
//**********************************************************************
//
//<AMI_FHDR_START>
//----------------------------------------------------------------------
//
// Name: EfiCapsuleRecoveryPPI.c - Recovery PPI
//
// Description: Implements EFI_PEI_RECOVERY_BLOCK_IO_PPI forAmi Capsule HOB.
// Capsule Recovery to be invoked separately from generic Recovery PPI
//----------------------------------------------------------------------
//<AMI_FHDR_END>
#include <Token.h>
#include <AmiPeiLib.h>
#include <AmiHobs.h>
#include <Hob.h>
#include <FlashUpd.h>
#include <Capsule.h>
// Definitions
#ifndef EFI_HOB_TYPE_CV
#define EFI_HOB_TYPE_CV EFI_HOB_TYPE_UEFI_CAPSULE
typedef EFI_HOB_UEFI_CAPSULE EFI_HOB_CAPSULE_VOLUME;
#endif // PI BACKWARD_COMPATIBLE_MODE
// Debug
#define W8_FW_UPDATE_IMAGE_CAPSULE_GUID \
{ 0x7039436b, 0x6acf, 0x433b, 0x86, 0xa1, 0x36, 0x8e, 0xc2, 0xef, 0x7e, 0x1f }
static EFI_GUID W8FwUpdateImageCapsuleGuid = W8_FW_UPDATE_IMAGE_CAPSULE_GUID;
// end debug
static EFI_PHYSICAL_ADDRESS gCapsuleAddress = 0;
static UINT64 gCapsuleLength = 0;
//----------------------------------------------------------------------------
// Function Prototypes
//----------------------------------------------------------------------------
EFI_STATUS VerifyFwImage(
IN CONST EFI_PEI_SERVICES **PeiServices, //EIP155099
IN OUT VOID **pCapsule,
IN OUT UINT32 *pCapsuleSize,
IN OUT UINT32 *FailedVTask
);
//----------------------------------------------------------------------------
// Function Definitions
//----------------------------------------------------------------------------
//<AMI_PHDR_START>
//----------------------------------------------------------------------
//
// Procedure: FindFWCapsuleHOB
//
// Description: Locates Aptio FW Capsule in Capsule Hob
//
// Input: EFI_PEI_SERVICES **PeiServices
// Output: EFI_PHYSICAL_ADDRESS pointer to FW CApsule
//----------------------------------------------------------------------
//<AMI_PHDR_END>
EFI_STATUS
FindFWCapsuleHOB
(
IN EFI_PEI_SERVICES **PeiServices
){
EFI_HOB_CAPSULE_VOLUME *pHob;
EFI_PHYSICAL_ADDRESS CapsuleAddress;
UINT64 CapsuleLength;
EFI_CAPSULE_HEADER *FWCapsuleVolume;
EFI_GUID gFWCapsuleGuid = APTIO_FW_CAPSULE_GUID;
BOOLEAN CapsuleFlag = FALSE; //EIP155099
(*PeiServices)->GetHobList(PeiServices, &pHob);
// attempt to locate capsule volume hob
while (!EFI_ERROR(FindNextHobByType(EFI_HOB_TYPE_CV, &pHob)))
{
// if capsule volume hob is found, determine the capsule's location
CapsuleAddress = pHob->BaseAddress;
CapsuleLength = pHob->Length;
FWCapsuleVolume = (EFI_CAPSULE_HEADER*) CapsuleAddress;
//EIP155099 >>
if (!guidcmp( &FWCapsuleVolume->CapsuleGuid, &W8FwUpdateImageCapsuleGuid)) {
CapsuleLength = pHob->Length - FWCapsuleVolume->HeaderSize;
CapsuleAddress = CapsuleAddress + FWCapsuleVolume->HeaderSize;
CapsuleFlag = TRUE;
}
if(CapsuleLength != 0 && FWCapsuleVolume->CapsuleImageSize <= CapsuleLength &&
!(guidcmp(&(FWCapsuleVolume->CapsuleGuid), &gFWCapsuleGuid))) {
CapsuleFlag = TRUE;
}
if (CapsuleFlag) {
PEI_TRACE((-1, PeiServices, "FW Capsule found in Capsule Volume Hob %x\n",CapsuleAddress));
gCapsuleLength = CapsuleLength;
gCapsuleAddress = CapsuleAddress;
return EFI_SUCCESS;
}
//EIP155099 <<
}
PEI_TRACE((-1,PeiServices, "FW capsule HOB not found\n"));
return EFI_NOT_FOUND;
}
//<AMI_PHDR_START>
//----------------------------------------------------------------------
//
// Procedure: LoadUpdateCapsule
//
// Description: LoadRecoveryCapsule function of EFI_PEI_RECOVERY_MODULE_PPI
// ppi. RecoveryDeviceOrder is a list of guids; each guid
// represents a type of recovery device. We go through
// this list and call FindRecoveryDevice for each type of
// device.
// -This function should not be confused with LoadRecoveryCapsule
// function of the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI ppi.
// -Called by DxeIpl.
//
//----------------------------------------------------------------------
//<AMI_PHDR_END>
EFI_STATUS LoadUpdateCapsule(
IN EFI_PEI_SERVICES **PeiServices,
RECOVERY_IMAGE_HOB *RecoveryHob
)
{
EFI_STATUS Status;
UINTN Size;
EFI_PHYSICAL_ADDRESS CapsuleAddress;
PEI_TRACE((TRACE_DXEIPL, PeiServices, "Loading Recovery Image..."));
// Locate Capsule Hob
if(!gCapsuleAddress || !gCapsuleLength) return EFI_NOT_FOUND;
Size = (UINTN)gCapsuleLength;
CapsuleAddress = (EFI_PHYSICAL_ADDRESS)gCapsuleAddress;
Status = VerifyFwImage(PeiServices, (VOID**)&CapsuleAddress, (UINT32*)&Size,(UINT32*)&RecoveryHob->FailedStage );
RecoveryHob->Status = (UINT8)Status;
RecoveryHob->Address = CapsuleAddress;
if (EFI_ERROR(Status)) {
PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_INVALID_CAPSULE, EFI_ERROR_MAJOR);
}else{
PEI_PROGRESS_CODE(PeiServices,PEI_RECOVERY_CAPSULE_LOADED);
}
return Status;
}
//<AMI_PHDR_START>
//----------------------------------------------------------------------
//
// Procedure: ProcessUpdateCapsule
//
// Description: Entry point. Installs EFI_PEI_RECOVERY_MODULE_PPI ppi
// (which has function LoadRecoveryCapsule).
//
//----------------------------------------------------------------------
//<AMI_PHDR_END>
EFI_STATUS ProcessUpdateCapsule(
IN EFI_PEI_SERVICES **PeiServices,
IN RECOVERY_IMAGE_HOB *RecoveryHob
)
{
EFI_STATUS Status;
Status = FindFWCapsuleHOB(PeiServices);
if (!EFI_ERROR(Status)) {
Status = LoadUpdateCapsule(PeiServices,RecoveryHob);
}
if (EFI_ERROR(Status)) {
PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_NO_CAPSULE, EFI_ERROR_MAJOR);
}
return Status;
}
//**********************************************************************
//**********************************************************************
//** **
//** (C)Copyright 1985-2013 American Megatrends, Inc. **
//** **
//** All Rights Reserved. **
//** **
//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
//** **
//** Phone: (770)-246-8600 **
//** **
//**********************************************************************
//**********************************************************************