mirror of https://github.com/acidanthera/audk.git
Enable UEFI firmware to support FMP capsule format.
signed-off-by : Chao Zhang <chao.b.zhang@intel.com> reviewed-by : Gao Liming <liming.gao@intel.com> reviewed-by : Yao Jiewen <Jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14773 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
0127372430
commit
566771b0a7
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Capsule Library instance to update capsule image to flash.
|
||||
Capsule Library instance to process capsule images.
|
||||
|
||||
Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -13,12 +13,368 @@
|
|||
|
||||
**/
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Guid/Capsule.h>
|
||||
#include <Guid/FmpCapsule.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/CapsuleLib.h>
|
||||
#include <Library/GenericBdsLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
|
||||
#include <Protocol/FirmwareManagement.h>
|
||||
#include <Protocol/DevicePath.h>
|
||||
|
||||
|
||||
/**
|
||||
Function indicate the current completion progress of the firmware
|
||||
update. Platform may override with own specific progress function.
|
||||
|
||||
@param Completion A value between 1 and 100 indicating the current completion progress of the firmware update
|
||||
|
||||
@retval EFI_SUCESS Input capsule is a correct FMP capsule.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Update_Image_Progress (
|
||||
IN UINTN Completion
|
||||
)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Validate Fmp capsules layout.
|
||||
|
||||
@param CapsuleHeader Points to a capsule header.
|
||||
|
||||
@retval EFI_SUCESS Input capsule is a correct FMP capsule.
|
||||
@retval EFI_INVALID_PARAMETER Input capsule is not a correct FMP capsule.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ValidateFmpCapsule (
|
||||
IN EFI_CAPSULE_HEADER *CapsuleHeader
|
||||
)
|
||||
{
|
||||
EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;
|
||||
UINT8 *EndOfCapsule;
|
||||
EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader;
|
||||
UINT8 *EndOfPayload;
|
||||
UINT64 *ItemOffsetList;
|
||||
UINT32 ItemNum;
|
||||
UINTN Index;
|
||||
|
||||
FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);
|
||||
EndOfCapsule = (UINT8 *) CapsuleHeader + CapsuleHeader->CapsuleImageSize;
|
||||
|
||||
if (FmpCapsuleHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
|
||||
|
||||
ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
|
||||
|
||||
if (ItemNum == FmpCapsuleHeader->EmbeddedDriverCount) {
|
||||
//
|
||||
// No payload element
|
||||
//
|
||||
if (((UINT8 *)FmpCapsuleHeader + ItemOffsetList[ItemNum - 1]) < EndOfCapsule) {
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
if (FmpCapsuleHeader->PayloadItemCount != 0) {
|
||||
//
|
||||
// Check if the last payload is within capsule image range
|
||||
//
|
||||
ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[ItemNum - 1]);
|
||||
EndOfPayload = (UINT8 *)(ImageHeader + 1) + ImageHeader->UpdateImageSize + ImageHeader->UpdateVendorCodeSize;
|
||||
} else {
|
||||
//
|
||||
// No driver & payload element in FMP
|
||||
//
|
||||
EndOfPayload = (UINT8 *)(FmpCapsuleHeader + 1);
|
||||
}
|
||||
|
||||
if (EndOfPayload != EndOfCapsule) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// All the address in ItemOffsetList must be stored in ascending order
|
||||
//
|
||||
if (ItemNum >= 2) {
|
||||
for (Index = 0; Index < ItemNum - 1; Index++) {
|
||||
if (ItemOffsetList[Index] >= ItemOffsetList[Index + 1]) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Process Firmware management protocol data capsule.
|
||||
|
||||
@param CapsuleHeader Points to a capsule header.
|
||||
|
||||
@retval EFI_SUCESS Process Capsule Image successfully.
|
||||
@retval EFI_UNSUPPORTED Capsule image is not supported by the firmware.
|
||||
@retval EFI_VOLUME_CORRUPTED FV volume in the capsule is corrupted.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough memory.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ProcessFmpCapsuleImage (
|
||||
IN EFI_CAPSULE_HEADER *CapsuleHeader
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;
|
||||
UINT8 *EndOfCapsule;
|
||||
EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader;
|
||||
EFI_HANDLE ImageHandle;
|
||||
UINT64 *ItemOffsetList;
|
||||
UINT32 ItemNum;
|
||||
UINTN Index;
|
||||
UINTN ExitDataSize;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
|
||||
UINTN NumberOfHandles;
|
||||
UINTN DescriptorSize;
|
||||
UINT8 FmpImageInfoCount;
|
||||
UINT32 FmpImageInfoDescriptorVer;
|
||||
UINTN ImageInfoSize;
|
||||
UINT32 PackageVersion;
|
||||
CHAR16 *PackageVersionName;
|
||||
CHAR16 *AbortReason;
|
||||
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
|
||||
EFI_FIRMWARE_IMAGE_DESCRIPTOR *TempFmpImageInfo;
|
||||
UINTN DriverLen;
|
||||
UINTN Index1;
|
||||
UINTN Index2;
|
||||
MEMMAP_DEVICE_PATH MemMapNode;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DriverDevicePath;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
HandleBuffer = NULL;
|
||||
ExitDataSize = 0;
|
||||
DriverDevicePath = NULL;
|
||||
|
||||
FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);
|
||||
EndOfCapsule = (UINT8 *) CapsuleHeader + CapsuleHeader->CapsuleImageSize;
|
||||
|
||||
if (FmpCapsuleHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
|
||||
|
||||
ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
|
||||
|
||||
//
|
||||
// capsule in which driver count and payload count are both zero is not processed.
|
||||
//
|
||||
if (ItemNum == 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// 1. ConnectAll to ensure
|
||||
// All the communication protocol required by driver in capsule installed
|
||||
// All FMP protocols are installed
|
||||
//
|
||||
BdsLibConnectAll();
|
||||
|
||||
|
||||
//
|
||||
// 2. Try to load & start all the drivers within capsule
|
||||
//
|
||||
SetDevicePathNodeLength (&MemMapNode.Header, sizeof (MemMapNode));
|
||||
MemMapNode.Header.Type = HARDWARE_DEVICE_PATH;
|
||||
MemMapNode.Header.SubType = HW_MEMMAP_DP;
|
||||
MemMapNode.MemoryType = EfiBootServicesCode;
|
||||
MemMapNode.StartingAddress = (EFI_PHYSICAL_ADDRESS)CapsuleHeader;
|
||||
MemMapNode.EndingAddress = (EFI_PHYSICAL_ADDRESS)((UINT8 *)CapsuleHeader + CapsuleHeader->CapsuleImageSize - 1);
|
||||
|
||||
DriverDevicePath = AppendDevicePathNode (NULL, &MemMapNode.Header);
|
||||
if (DriverDevicePath == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < FmpCapsuleHeader->EmbeddedDriverCount; Index++) {
|
||||
if (FmpCapsuleHeader->PayloadItemCount == 0 && Index == FmpCapsuleHeader->EmbeddedDriverCount - 1) {
|
||||
//
|
||||
// When driver is last element in the ItemOffsetList array, the driver size is calculated by reference CapsuleImageSize in EFI_CAPSULE_HEADER
|
||||
//
|
||||
DriverLen = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize - ItemOffsetList[Index];
|
||||
} else {
|
||||
DriverLen = ItemOffsetList[Index + 1] - ItemOffsetList[Index];
|
||||
}
|
||||
|
||||
Status = gBS->LoadImage(
|
||||
FALSE,
|
||||
gImageHandle,
|
||||
DriverDevicePath,
|
||||
(UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index],
|
||||
DriverLen,
|
||||
&ImageHandle
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
Status = gBS->StartImage(
|
||||
ImageHandle,
|
||||
&ExitDataSize,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Driver Return Status = %r\n", Status));
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Connnect all again to connect drivers within capsule
|
||||
//
|
||||
if (FmpCapsuleHeader->EmbeddedDriverCount > 0) {
|
||||
BdsLibConnectAll();
|
||||
}
|
||||
|
||||
//
|
||||
// 3. Route payload to right FMP instance
|
||||
//
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiFirmwareManagementProtocolGuid,
|
||||
NULL,
|
||||
&NumberOfHandles,
|
||||
&HandleBuffer
|
||||
);
|
||||
|
||||
if (!EFI_ERROR(Status)) {
|
||||
for(Index1 = 0; Index1 < NumberOfHandles; Index1++) {
|
||||
Status = gBS->HandleProtocol(
|
||||
HandleBuffer[Index1],
|
||||
&gEfiFirmwareManagementProtocolGuid,
|
||||
&Fmp
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ImageInfoSize = 0;
|
||||
Status = Fmp->GetImageInfo (
|
||||
Fmp,
|
||||
&ImageInfoSize,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FmpImageInfoBuf = NULL;
|
||||
FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
|
||||
if (FmpImageInfoBuf == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
PackageVersionName = NULL;
|
||||
Status = Fmp->GetImageInfo (
|
||||
Fmp,
|
||||
&ImageInfoSize, // ImageInfoSize
|
||||
FmpImageInfoBuf, // ImageInfo
|
||||
&FmpImageInfoDescriptorVer, // DescriptorVersion
|
||||
&FmpImageInfoCount, // DescriptorCount
|
||||
&DescriptorSize, // DescriptorSize
|
||||
&PackageVersion, // PackageVersion
|
||||
&PackageVersionName // PackageVersionName
|
||||
);
|
||||
|
||||
//
|
||||
// If FMP GetInformation interface failed, skip this resource
|
||||
//
|
||||
if (EFI_ERROR(Status)) {
|
||||
FreePool(FmpImageInfoBuf);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PackageVersionName != NULL) {
|
||||
FreePool(PackageVersionName);
|
||||
}
|
||||
|
||||
TempFmpImageInfo = FmpImageInfoBuf;
|
||||
for (Index2 = 0; Index2 < FmpImageInfoCount; Index2++) {
|
||||
//
|
||||
// Check all the payload entry in capsule payload list
|
||||
//
|
||||
for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {
|
||||
ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
|
||||
if (CompareGuid(&ImageHeader->UpdateImageTypeId, &TempFmpImageInfo->ImageTypeId) &&
|
||||
ImageHeader->UpdateImageIndex == TempFmpImageInfo->ImageIndex) {
|
||||
AbortReason = NULL;
|
||||
if (ImageHeader->UpdateVendorCodeSize == 0) {
|
||||
Status = Fmp->SetImage(
|
||||
Fmp,
|
||||
TempFmpImageInfo->ImageIndex, // ImageIndex
|
||||
(UINT8 *)(ImageHeader + 1), // Image
|
||||
ImageHeader->UpdateImageSize, // ImageSize
|
||||
NULL, // VendorCode
|
||||
Update_Image_Progress, // Progress
|
||||
&AbortReason // AbortReason
|
||||
);
|
||||
} else {
|
||||
Status = Fmp->SetImage(
|
||||
Fmp,
|
||||
TempFmpImageInfo->ImageIndex, // ImageIndex
|
||||
(UINT8 *)(ImageHeader + 1), // Image
|
||||
ImageHeader->UpdateImageSize, // ImageSize
|
||||
(UINT8 *)((UINT8 *) (ImageHeader + 1) + ImageHeader->UpdateImageSize), // VendorCode
|
||||
Update_Image_Progress, // Progress
|
||||
&AbortReason // AbortReason
|
||||
);
|
||||
}
|
||||
if (AbortReason != NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "%s\n", AbortReason));
|
||||
FreePool(AbortReason);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
|
||||
//
|
||||
TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSize);
|
||||
}
|
||||
FreePool(FmpImageInfoBuf);
|
||||
}
|
||||
}
|
||||
|
||||
EXIT:
|
||||
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool(HandleBuffer);
|
||||
}
|
||||
|
||||
if (DriverDevicePath != NULL) {
|
||||
FreePool(DriverDevicePath);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Those capsules supported by the firmwares.
|
||||
|
@ -27,6 +383,7 @@
|
|||
|
||||
@retval EFI_SUCESS Input capsule is supported by firmware.
|
||||
@retval EFI_UNSUPPORTED Input capsule is not supported by the firmware.
|
||||
@retval EFI_INVALID_PARAMETER Input capsule layout is not correct
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
|
@ -38,6 +395,13 @@ SupportCapsuleImage (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (CompareGuid (&gEfiFmpCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {
|
||||
//
|
||||
// Check layout of FMP capsule
|
||||
//
|
||||
return ValidateFmpCapsule(CapsuleHeader);
|
||||
}
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -72,6 +436,21 @@ ProcessCapsuleImage (
|
|||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Check FMP capsule layout
|
||||
//
|
||||
if (CompareGuid (&gEfiFmpCapsuleGuid, &CapsuleHeader->CapsuleGuid)){
|
||||
Status = ValidateFmpCapsule(CapsuleHeader);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Press EFI FMP Capsule
|
||||
//
|
||||
return ProcessFmpCapsuleImage(CapsuleHeader);
|
||||
}
|
||||
|
||||
//
|
||||
// Skip the capsule header, move to the Firware Volume
|
||||
//
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Capsule library instance for DXE_DRIVER, DXE_RUNTIME_DRIVER
|
||||
#
|
||||
# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -33,15 +33,22 @@
|
|||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
MemoryAllocationLib
|
||||
DxeServicesTableLib
|
||||
GenericBdsLib
|
||||
UefiBootServicesTableLib
|
||||
DevicePathLib
|
||||
|
||||
[Protocols]
|
||||
gEfiFirmwareManagementProtocolGuid # CONSUMES
|
||||
|
||||
[Guids]
|
||||
gEfiCapsuleGuid # SOMETIMES_CONSUMED
|
||||
|
||||
gEfiFmpCapsuleGuid # SOMETIMES_CONSUMED
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
FILE_GUID = e405ec31-ccaa-4dd4-83e8-0aec01703f7e
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = GenericBdsLib|DXE_DRIVER UEFI_APPLICATION
|
||||
LIBRARY_CLASS = GenericBdsLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION
|
||||
CONSTRUCTOR = GenericBdsLibConstructor
|
||||
|
||||
#
|
||||
|
@ -78,6 +78,7 @@
|
|||
gLastEnumLangGuid ## SOMETIMES_PRODUCES ## Variable:L"LastEnumLang" (Platform language at last time enumeration.)
|
||||
gHdBootDevicePathVariablGuid ## SOMETIMES_PRODUCES ## Variable:L"HDDP" (The device path of Boot file on Hard device.)
|
||||
gBdsLibStringPackageGuid ## PRODUCES ## GUID (HII String PackageList Guid)
|
||||
gEfiLegacyDevOrderVariableGuid ## CONSUMES ## GUID
|
||||
|
||||
[Protocols]
|
||||
gEfiSimpleFileSystemProtocolGuid # PROTOCOL CONSUMES
|
||||
|
|
|
@ -36,6 +36,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#include <Guid/BdsHii.h>
|
||||
#include <Guid/ConnectConInEvent.h>
|
||||
#include <Guid/Performance.h>
|
||||
#include <Guid/FmpCapsule.h>
|
||||
#include <Protocol/GenericMemoryTest.h>
|
||||
#include <Protocol/FormBrowser2.h>
|
||||
#include <Protocol/HiiConfigAccess.h>
|
||||
|
|
|
@ -141,6 +141,7 @@
|
|||
gDeviceManagerFormSetGuid ## SOMETIMES_PRODUCES ## DeviceManager HII Package
|
||||
gDriverHealthFormSetGuid ## SOMETIMES_PRODUCES ## DriverHealth HII Package
|
||||
gConnectConInEventGuid ## CONSUMES ## GUID (Connect ConIn Event)
|
||||
gEfiFmpCapsuleGuid ## CONSUMES ## GUID (FMP Capsule)
|
||||
|
||||
[Protocols]
|
||||
gEfiSimpleFileSystemProtocolGuid ## PROTOCOL CONSUMES
|
||||
|
|
|
@ -403,7 +403,9 @@ BdsFormalizeEfiGlobalVariable (
|
|||
//
|
||||
// OS indicater support variable
|
||||
//
|
||||
OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
|
||||
OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI \
|
||||
| EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED;
|
||||
|
||||
Status = gRT->SetVariable (
|
||||
L"OsIndicationsSupported",
|
||||
&gEfiGlobalVariableGuid,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
BDS routines to handle capsules.
|
||||
|
||||
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -52,14 +52,16 @@ BdsProcessCapsules (
|
|||
VOID **CapsulePtr;
|
||||
VOID **CapsulePtrCache;
|
||||
EFI_GUID *CapsuleGuidCache;
|
||||
BOOLEAN NeedReset;
|
||||
|
||||
CapsuleNumber = 0;
|
||||
CapsuleNumber = 0;
|
||||
CapsuleTotalNumber = 0;
|
||||
CacheIndex = 0;
|
||||
CacheNumber = 0;
|
||||
CapsulePtr = NULL;
|
||||
CapsulePtrCache = NULL;
|
||||
CapsuleGuidCache = NULL;
|
||||
CacheIndex = 0;
|
||||
CacheNumber = 0;
|
||||
CapsulePtr = NULL;
|
||||
CapsulePtrCache = NULL;
|
||||
CapsuleGuidCache = NULL;
|
||||
NeedReset = FALSE;
|
||||
|
||||
//
|
||||
// We don't do anything else if the boot mode is not flash-update
|
||||
|
@ -190,6 +192,13 @@ BdsProcessCapsules (
|
|||
for (Index = 0; Index < CapsuleTotalNumber; Index++) {
|
||||
CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];
|
||||
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
|
||||
//
|
||||
// Always reset system after all capsule processed if FMP capsule exist
|
||||
//
|
||||
if (CompareGuid (&gEfiFmpCapsuleGuid, &CapsuleHeader->CapsuleGuid)){
|
||||
NeedReset = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Call capsule library to process capsule image.
|
||||
//
|
||||
|
@ -197,6 +206,19 @@ BdsProcessCapsules (
|
|||
}
|
||||
}
|
||||
|
||||
if (NeedReset) {
|
||||
Print(L"Capsule Request Cold Reboot.\n");
|
||||
|
||||
for (Index = 5; Index > 0; Index--) {
|
||||
Print(L"\rResetting system in %d seconds ...", Index);
|
||||
gBS->Stall (1000000);
|
||||
}
|
||||
|
||||
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||||
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
PlatformBdsLockNonUpdatableFlash ();
|
||||
|
||||
//
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# It installs the Capsule Architectural Protocol defined in PI1.0a to signify
|
||||
# the capsule runtime services are ready.
|
||||
#
|
||||
# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -53,7 +53,8 @@
|
|||
UefiRuntimeLib
|
||||
BaseLib
|
||||
PrintLib
|
||||
|
||||
BaseMemoryLib
|
||||
|
||||
[LibraryClasses.X64]
|
||||
LockBoxLib
|
||||
UefiLib
|
||||
|
@ -62,6 +63,7 @@
|
|||
|
||||
[Guids]
|
||||
gEfiCapsuleVendorGuid ## SOMETIMES_PRODUCED (Process across reset capsule image) ## Variable:L"CapsuleUpdateData" for capsule updated data
|
||||
gEfiFmpCapsuleGuid ## FMP capsule GUID
|
||||
|
||||
[Guids.X64]
|
||||
gEfiAcpiVariableGuid # ALWAYS_CONSUMED
|
||||
|
|
|
@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
|
||||
#include <Protocol/Capsule.h>
|
||||
#include <Guid/CapsuleVendor.h>
|
||||
#include <Guid/FmpCapsule.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
@ -29,7 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#include <Library/UefiRuntimeLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
//
|
||||
// Handle for the installation of Capsule Architecture Protocol.
|
||||
//
|
||||
|
@ -124,12 +125,23 @@ UpdateCapsule (
|
|||
if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check FMP capsule flag
|
||||
//
|
||||
if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)
|
||||
&& (CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Capsule image without populate flag by firmware support capsule function
|
||||
//
|
||||
if (((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) &&
|
||||
(SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
|
||||
Status = SupportCapsuleImage (CapsuleHeader);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,6 +262,7 @@ QueryCapsuleCapabilities (
|
|||
OUT EFI_RESET_TYPE *ResetType
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN ArrayNumber;
|
||||
EFI_CAPSULE_HEADER *CapsuleHeader;
|
||||
BOOLEAN NeedReset;
|
||||
|
@ -287,12 +300,23 @@ QueryCapsuleCapabilities (
|
|||
if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check FMP capsule flag
|
||||
//
|
||||
if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)
|
||||
&& (CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Capsule image without populate flag is supported by firmware
|
||||
//
|
||||
if (((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) &&
|
||||
(SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
|
||||
Status = SupportCapsuleImage (CapsuleHeader);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,7 +330,7 @@ QueryCapsuleCapabilities (
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (NeedReset) {
|
||||
//
|
||||
//Check if the platform supports update capsule across a system reset
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/** @file
|
||||
Guid & data structure used for Delivering Capsules Containing Updates to Firmware
|
||||
Managment Protocol
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
@par Revision Reference:
|
||||
GUIDs defined in UEFI 2.4 spec.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#ifndef _FMP_CAPSULE_GUID_H__
|
||||
#define _FMP_CAPSULE_GUID_H__
|
||||
|
||||
//
|
||||
// This is the GUID of the capsule for Firmware Management Protocol.
|
||||
//
|
||||
#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \
|
||||
{ \
|
||||
0x6dcbd5ed, 0xe82d, 0x4c44, {0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a } \
|
||||
}
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
UINT32 Version;
|
||||
|
||||
///
|
||||
/// The number of drivers included in the capsule and the number of corresponding
|
||||
/// offsets stored in ItemOffsetList array.
|
||||
///
|
||||
UINT16 EmbeddedDriverCount;
|
||||
|
||||
///
|
||||
/// The number of payload items included in the capsule and the number of
|
||||
/// corresponding offsets stored in the ItemOffsetList array.
|
||||
///
|
||||
UINT16 PayloadItemCount;
|
||||
|
||||
///
|
||||
/// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount]
|
||||
/// containing offsets of each of the drivers and payload items contained within the capsule
|
||||
///
|
||||
// UINT64 ItemOffsetList[];
|
||||
} EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT32 Version;
|
||||
|
||||
///
|
||||
/// Used to identifiy device firmware targeted by this update. This guid is matched by
|
||||
/// system firmware against ImageTypeId field within a EFI_FIRMWARE_IMAGE_DESCRIPTOR
|
||||
///
|
||||
EFI_GUID UpdateImageTypeId;
|
||||
|
||||
///
|
||||
/// Passed as ImageIndex in call to EFI_FIRMWARE_MANAGEMENT_PROTOCOL.SetImage()
|
||||
///
|
||||
UINT8 UpdateImageIndex;
|
||||
UINT8 reserved_bytes[3];
|
||||
|
||||
///
|
||||
/// Size of the binary update image which immediately follows this structure
|
||||
///
|
||||
UINT32 UpdateImageSize;
|
||||
|
||||
///
|
||||
///Size of the VendorCode bytes which optionally immediately follow binary update image in the capsule
|
||||
///
|
||||
UINT32 UpdateVendorCodeSize;
|
||||
} EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION 0x00000001
|
||||
#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000001
|
||||
|
||||
extern EFI_GUID gEfiFmpCapsuleGuid;
|
||||
|
||||
#endif
|
|
@ -1752,7 +1752,11 @@ EFI_STATUS
|
|||
//
|
||||
// Firmware should stop at a firmware user interface on next boot
|
||||
//
|
||||
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
|
||||
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
|
||||
#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION 0x0000000000000002
|
||||
#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED 0x0000000000000004
|
||||
#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED 0x0000000000000008
|
||||
#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED 0x0000000000000010
|
||||
|
||||
//
|
||||
// EFI Runtime Services Table
|
||||
|
|
|
@ -514,6 +514,12 @@
|
|||
gEfiHashAlgorithmSha1NoPadGuid = { 0x24c5dc2f, 0x53e2, 0x40ca, { 0x9e, 0xd6, 0xa5, 0xd9, 0xa4, 0x9f, 0x46, 0x3b }}
|
||||
gEfiHashAlgorithmSha256NoPadGuid = { 0x8628752a, 0x6cb7, 0x4814, { 0x96, 0xfc, 0x24, 0xa8, 0x15, 0xac, 0x22, 0x26 }}
|
||||
|
||||
#
|
||||
# GUIDs defined in UEFI2.4
|
||||
#
|
||||
## Include/Guid/FmpCapsule.h
|
||||
gEfiFmpCapsuleGuid = { 0x6dcbd5ed, 0xe82d, 0x4c44, {0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a }}
|
||||
|
||||
#
|
||||
# GUID defined in PI1.0
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue