mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
IntelFrameworkModulePkg: Add UpdateDriverDxe driver
Signed-off-by: jljusten Reviewed-by: rsun3 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12257 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
c2df8e13f6
commit
b2824a8e13
@ -163,6 +163,7 @@
|
||||
IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.inf
|
||||
IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandlerDxe/DatahubStatusCodeHandlerDxe.inf
|
||||
IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDxe.inf
|
||||
IntelFrameworkModulePkg/Universal/FirmwareVolume/UpdateDriverDxe/UpdateDriverDxe.inf
|
||||
|
||||
[Components.IA32,Components.X64]
|
||||
IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,846 @@
|
||||
/** @file
|
||||
Functions in this file will mainly focus on looking through the capsule
|
||||
for the image to be programmed, and the flash area that is going to be
|
||||
programed.
|
||||
|
||||
Copyright (c) 2002 - 2011, 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.
|
||||
|
||||
**/
|
||||
|
||||
#include "UpdateDriver.h"
|
||||
|
||||
EFI_GUID UpdateDataGuid = EFI_UPDATE_DATA_FILE_GUID;
|
||||
EFI_HII_HANDLE gHiiHandle;
|
||||
|
||||
/**
|
||||
Update the whole FV, or certain files in the FV.
|
||||
|
||||
@param ConfigData Pointer to the config data on updating file.
|
||||
@param ImageBuffer Image buffer to be updated.
|
||||
@param ImageSize Image size.
|
||||
@param FileType FFS file type.
|
||||
@param FileAttributes FFS file attribute.
|
||||
|
||||
@retval EFI_NOT_FOUND The matched FVB protocol is not found.
|
||||
@retval EFI_SUCCESS The image buffer is updated into FV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformUpdateOnFirmwareVolume (
|
||||
IN UPDATE_CONFIG_DATA *ConfigData,
|
||||
IN UINT8 *ImageBuffer,
|
||||
IN UINTN ImageSize,
|
||||
IN EFI_FV_FILETYPE FileType,
|
||||
IN EFI_FV_FILE_ATTRIBUTES FileAttributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN Found;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
|
||||
UINTN Index;
|
||||
UINTN NumOfHandles;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||
EFI_FVB_ATTRIBUTES_2 Attributes;
|
||||
|
||||
//
|
||||
// Locate all Fvb protocol
|
||||
//
|
||||
HandleBuffer = NULL;
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
NULL,
|
||||
&NumOfHandles,
|
||||
&HandleBuffer
|
||||
);
|
||||
if ((EFI_ERROR (Status)) || (NumOfHandles == 0) || (HandleBuffer == NULL)) {
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool (HandleBuffer);
|
||||
}
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Check the FVB protocol one by one
|
||||
//
|
||||
Found = FALSE;
|
||||
FvbProtocol = NULL;
|
||||
for (Index = 0; Index < NumOfHandles; Index++) {
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
(VOID **) &FvbProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure this FVB protocol supported Write operation.
|
||||
//
|
||||
Status = FvbProtocol->GetAttributes (FvbProtocol, &Attributes);
|
||||
if (EFI_ERROR (Status) || ((Attributes & EFI_FVB2_WRITE_STATUS) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = FvbProtocol->GetPhysicalAddress (
|
||||
FvbProtocol,
|
||||
&BaseAddress
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
if (BaseAddress == ConfigData->BaseAddress) {
|
||||
Found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Found) {
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool (HandleBuffer);
|
||||
HandleBuffer = NULL;
|
||||
}
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Now we have got the corresponding FVB protocol. Use the FVB protocol
|
||||
// to update the whole FV, or certain files in the FV.
|
||||
//
|
||||
if (ConfigData->UpdateType == UpdateWholeFV) {
|
||||
if (FileType != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
} else {
|
||||
Status = PerformUpdateOnWholeFv (
|
||||
HandleBuffer[Index],
|
||||
FvbProtocol,
|
||||
ConfigData,
|
||||
ImageBuffer,
|
||||
ImageSize
|
||||
);
|
||||
}
|
||||
} else if (ConfigData->UpdateType == UpdateFvFile) {
|
||||
Status = PerformUpdateOnFvFile (
|
||||
HandleBuffer[Index],
|
||||
FvbProtocol,
|
||||
ConfigData,
|
||||
ImageBuffer,
|
||||
ImageSize,
|
||||
FileType,
|
||||
FileAttributes
|
||||
);
|
||||
}
|
||||
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool (HandleBuffer);
|
||||
HandleBuffer = NULL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Update the file directly into flash area.
|
||||
|
||||
@param ConfigData Pointer to the config data on updating file.
|
||||
@param ImageBuffer Image buffer to be updated.
|
||||
@param ImageSize Image size.
|
||||
|
||||
@retval EFI_SUCCESS The file is updated into flash area.
|
||||
@retval EFI_NOT_FOUND The FVB protocol for the updated flash area is not found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformUpdateOnFlashArea (
|
||||
IN UPDATE_CONFIG_DATA *ConfigData,
|
||||
IN UINT8 *ImageBuffer,
|
||||
IN UINTN ImageSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN SizeLeft;
|
||||
EFI_PHYSICAL_ADDRESS FlashAddress;
|
||||
UINT8 *PtrImage;
|
||||
BOOLEAN Found;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
|
||||
UINTN Index;
|
||||
UINTN NumOfHandles;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
EFI_HANDLE FvbHandle;
|
||||
UINTN SizeUpdated;
|
||||
CHAR16 *TmpStr;
|
||||
EFI_FVB_ATTRIBUTES_2 Attributes;
|
||||
|
||||
SizeLeft = ImageSize;
|
||||
PtrImage = ImageBuffer;
|
||||
FlashAddress = ConfigData->BaseAddress;
|
||||
Status = EFI_SUCCESS;
|
||||
HandleBuffer = NULL;
|
||||
|
||||
//
|
||||
// Print on screen
|
||||
//
|
||||
TmpStr = HiiGetString (gHiiHandle, STRING_TOKEN(UPDATE_FLASH_RANGE), NULL);
|
||||
if (TmpStr != NULL) {
|
||||
Print (TmpStr, FlashAddress, ((UINT64)SizeLeft + FlashAddress));
|
||||
FreePool (TmpStr);
|
||||
}
|
||||
|
||||
//
|
||||
// Locate all Fvb protocol
|
||||
//
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
NULL,
|
||||
&NumOfHandles,
|
||||
&HandleBuffer
|
||||
);
|
||||
if ((EFI_ERROR (Status)) || (NumOfHandles == 0) || (HandleBuffer == NULL)) {
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool (HandleBuffer);
|
||||
}
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
while (SizeLeft > 0) {
|
||||
//
|
||||
// First get the FVB protocols. If the flash area is a FV, or sub FV,
|
||||
// we can directly locate all the FVB protocol. Otherwise we should use
|
||||
// implementation specific method to get the alternate FVB protocol
|
||||
//
|
||||
Found = FALSE;
|
||||
FvbProtocol = NULL;
|
||||
|
||||
//
|
||||
// Check the FVB protocol one by one
|
||||
//
|
||||
for (Index = 0; Index < NumOfHandles; Index++) {
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
(VOID **) &FvbProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure this FVB protocol supported Write operation.
|
||||
//
|
||||
Status = FvbProtocol->GetAttributes (FvbProtocol, &Attributes);
|
||||
if (EFI_ERROR (Status) || ((Attributes & EFI_FVB2_WRITE_STATUS) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = FvbProtocol->GetPhysicalAddress (
|
||||
FvbProtocol,
|
||||
&BaseAddress
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress;
|
||||
|
||||
//
|
||||
// This sub area entry falls in the range of the FV
|
||||
//
|
||||
if ((FlashAddress >= BaseAddress) && (FlashAddress < (BaseAddress + FwVolHeader->FvLength))) {
|
||||
Found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Found) {
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool (HandleBuffer);
|
||||
HandleBuffer = NULL;
|
||||
}
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
FvbHandle = HandleBuffer[Index];
|
||||
SizeUpdated = 0;
|
||||
|
||||
//
|
||||
// If the flash area is boot required, the update must be fault tolerant
|
||||
//
|
||||
if (ConfigData->FaultTolerant) {
|
||||
//
|
||||
// Finally we are here. We have got the corresponding FVB protocol. Now
|
||||
// we need to convert the physical address to LBA and offset and call
|
||||
// FTW write. Also check if the flash range is larger than the FV.
|
||||
//
|
||||
Status = FaultTolerantUpdateOnPartFv (
|
||||
PtrImage,
|
||||
SizeLeft,
|
||||
&SizeUpdated,
|
||||
ConfigData,
|
||||
FlashAddress,
|
||||
FvbProtocol,
|
||||
FvbHandle
|
||||
);
|
||||
} else {
|
||||
//
|
||||
// Finally we are here. We have got the corresponding FVB protocol. Now
|
||||
// we need to convert the physical address to LBA and offset and call
|
||||
// FVB write. Also check if the flash range is larger than the FV.
|
||||
//
|
||||
Status = NonFaultTolerantUpdateOnPartFv (
|
||||
PtrImage,
|
||||
SizeLeft,
|
||||
&SizeUpdated,
|
||||
FlashAddress,
|
||||
FvbProtocol,
|
||||
FvbHandle
|
||||
);
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// As part of the FV has been replaced, the FV driver shall re-parse
|
||||
// the firmware volume. So re-install FVB protocol here
|
||||
//
|
||||
Status = gBS->ReinstallProtocolInterface (
|
||||
FvbHandle,
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
FvbProtocol,
|
||||
FvbProtocol
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if we are done with the update
|
||||
//
|
||||
SizeLeft = SizeLeft - SizeUpdated;
|
||||
FlashAddress = FlashAddress + SizeUpdated;
|
||||
PtrImage = PtrImage + SizeUpdated;
|
||||
}
|
||||
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool (HandleBuffer);
|
||||
HandleBuffer = NULL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the updated file, and program it into the flash area based on the config data.
|
||||
|
||||
@param FwVolProtocol Pointer to FV protocol that contains the updated file.
|
||||
@param ConfigData Pointer to the Config Data on updating file.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The update operation is not valid.
|
||||
@retval EFI_NOT_FOUND The updated file is not found.
|
||||
@retval EFI_SUCCESS The file is updated into the flash area.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformUpdate (
|
||||
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVolProtocol,
|
||||
IN UPDATE_CONFIG_DATA *ConfigData
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 *FileBuffer;
|
||||
UINTN FileBufferSize;
|
||||
EFI_FV_FILETYPE FileType;
|
||||
EFI_FV_FILE_ATTRIBUTES Attrib;
|
||||
EFI_SECTION_TYPE SectionType;
|
||||
UINT32 AuthenticationStatus;
|
||||
CHAR16 *TmpStr;
|
||||
BOOLEAN StartToUpdate;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
FileBuffer = NULL;
|
||||
FileBufferSize = 0;
|
||||
Status = FwVolProtocol->ReadFile (
|
||||
FwVolProtocol,
|
||||
&(ConfigData->FileGuid),
|
||||
(VOID **) &FileBuffer,
|
||||
&FileBufferSize,
|
||||
&FileType,
|
||||
&Attrib,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
StartToUpdate = FALSE;
|
||||
|
||||
//
|
||||
// Check if the update image is the one we require
|
||||
// and then perform the update
|
||||
//
|
||||
switch (ConfigData->UpdateType) {
|
||||
|
||||
case UpdateWholeFV:
|
||||
|
||||
//
|
||||
// For UpdateWholeFv, the update file shall be a firmware volume
|
||||
// image file.
|
||||
//
|
||||
if (FileType != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
|
||||
DEBUG ((EFI_D_UPDATE, "UpdateDriver: Data file should be of TYPE EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n"));
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
} else {
|
||||
if (FileBuffer != NULL) {
|
||||
FreePool (FileBuffer);
|
||||
}
|
||||
SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
|
||||
FileBuffer = NULL;
|
||||
FileBufferSize = 0;
|
||||
Status = FwVolProtocol->ReadSection (
|
||||
FwVolProtocol,
|
||||
&(ConfigData->FileGuid),
|
||||
SectionType,
|
||||
0,
|
||||
(VOID **) &FileBuffer,
|
||||
&FileBufferSize,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Execute the update. For UpdateWholeFv, the update
|
||||
// will always execute on a whole FV
|
||||
//
|
||||
StartToUpdate = TRUE;
|
||||
Status = PerformUpdateOnFirmwareVolume (
|
||||
ConfigData,
|
||||
FileBuffer,
|
||||
FileBufferSize,
|
||||
FileType,
|
||||
Attrib
|
||||
);
|
||||
|
||||
} else {
|
||||
DEBUG ((EFI_D_UPDATE, "UpdateDriver: Data file should be sectioned with TYPE EFI_SECTION_FIRMWARE_VOLUME_IMAGE\n"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UpdateFvRange:
|
||||
|
||||
//
|
||||
// For UpdateFvRange, the update file shall be a raw file
|
||||
// which does not contain any sections. The contents of the file
|
||||
// will be directly programmed.
|
||||
//
|
||||
if (FileType != EFI_FV_FILETYPE_RAW) {
|
||||
DEBUG ((EFI_D_UPDATE, "UpdateDriver: Data file should of TYPE EFI_FV_FILETYPE_RAW\n"));
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
} else {
|
||||
//
|
||||
// For UpdateFvRange, the update may be performed on a sub area
|
||||
// of a certain FV, or a flash area that is not FV, or part of FV.
|
||||
// The update may also go across more than one FVs.
|
||||
//
|
||||
StartToUpdate = TRUE;
|
||||
Status = PerformUpdateOnFlashArea (
|
||||
ConfigData,
|
||||
FileBuffer,
|
||||
FileBufferSize
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case UpdateFvFile:
|
||||
|
||||
//
|
||||
// No check will be done the the file got. The contents of the file
|
||||
// will be directly programmed.
|
||||
// Though UpdateFvFile will only update a single file, but the update
|
||||
// will always execute on a FV
|
||||
//
|
||||
StartToUpdate = TRUE;
|
||||
Status = PerformUpdateOnFirmwareVolume (
|
||||
ConfigData,
|
||||
FileBuffer,
|
||||
FileBufferSize,
|
||||
FileType,
|
||||
Attrib
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (StartToUpdate) {
|
||||
if (EFI_ERROR (Status)) {
|
||||
TmpStr = HiiGetString (gHiiHandle, STRING_TOKEN(UPDATE_DRIVER_ABORTED), NULL);
|
||||
} else {
|
||||
TmpStr = HiiGetString (gHiiHandle, STRING_TOKEN(UPDATE_DRIVER_DONE), NULL);
|
||||
}
|
||||
if (TmpStr != NULL) {
|
||||
Print (TmpStr);
|
||||
FreePool (TmpStr);
|
||||
}
|
||||
}
|
||||
|
||||
if (FileBuffer != NULL) {
|
||||
FreePool(FileBuffer);
|
||||
FileBuffer = NULL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Process the input firmware volume by using DXE service ProcessFirmwareVolume.
|
||||
|
||||
@param DataBuffer Point to the FV image to be processed.
|
||||
@param BufferSize Size of the FV image buffer.
|
||||
@param FwVolProtocol Point to the installed FV protocol for the input FV image.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory is allocated.
|
||||
@retval EFI_VOLUME_CORRUPTED FV image is corrupted.
|
||||
@retval EFI_SUCCESS FV image is processed and FV protocol is installed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ProcessUpdateImage (
|
||||
UINT8 *DataBuffer,
|
||||
UINTN BufferSize,
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL **FwVolProtocol
|
||||
)
|
||||
{
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
EFI_HANDLE FwVolHandle;
|
||||
EFI_STATUS Status;
|
||||
UINT8 *ProcessedDataBuffer;
|
||||
UINT32 FvAlignment;
|
||||
|
||||
ProcessedDataBuffer = NULL;
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DataBuffer;
|
||||
if (FwVolHeader->FvLength != BufferSize) {
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
|
||||
//
|
||||
// FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
|
||||
//
|
||||
if (FvAlignment < 8) {
|
||||
FvAlignment = 8;
|
||||
}
|
||||
//
|
||||
// Check FvImage Align is required.
|
||||
//
|
||||
if (((UINTN) FwVolHeader % FvAlignment) == 0) {
|
||||
ProcessedDataBuffer = DataBuffer;
|
||||
} else {
|
||||
//
|
||||
// Allocate new aligned buffer to store DataBuffer.
|
||||
//
|
||||
ProcessedDataBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);
|
||||
if (ProcessedDataBuffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
CopyMem (ProcessedDataBuffer, DataBuffer, BufferSize);
|
||||
}
|
||||
//
|
||||
// Process the firmware volume
|
||||
//
|
||||
gDS->ProcessFirmwareVolume (
|
||||
ProcessedDataBuffer,
|
||||
BufferSize,
|
||||
&FwVolHandle
|
||||
);
|
||||
|
||||
//
|
||||
// Get the FwVol protocol
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
FwVolHandle,
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
(VOID **) FwVolProtocol
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the image in the same FV and program it in a target Firmware Volume device.
|
||||
After update image, it will reset system and no return.
|
||||
|
||||
@param ImageHandle A handle for the image that is initializing this driver
|
||||
@param SystemTable A pointer to the EFI system table
|
||||
|
||||
@retval EFI_ABORTED System reset failed.
|
||||
@retval EFI_NOT_FOUND The updated image is not found in the same FV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeUpdateDriver (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocol;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVolProtocol;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *DataFwVolProtocol;
|
||||
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FwVolFilePathNode;
|
||||
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *AlignedDevPathNode;
|
||||
EFI_DEVICE_PATH_PROTOCOL *FilePathNode;
|
||||
EFI_SECTION_TYPE SectionType;
|
||||
UINT8 *FileBuffer;
|
||||
UINTN FileBufferSize;
|
||||
EFI_FV_FILETYPE FileType;
|
||||
EFI_FV_FILE_ATTRIBUTES Attrib;
|
||||
UINT32 AuthenticationStatus;
|
||||
UPDATE_CONFIG_DATA *ConfigData;
|
||||
UPDATE_CONFIG_DATA *UpdateConfigData;
|
||||
UINTN NumOfUpdates;
|
||||
UINTN Index;
|
||||
CHAR16 *TmpStr;
|
||||
|
||||
//
|
||||
// Clear screen
|
||||
//
|
||||
if (gST->ConOut != NULL) {
|
||||
gST->ConOut->ClearScreen (gST->ConOut);
|
||||
gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);
|
||||
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
|
||||
}
|
||||
|
||||
gHiiHandle = HiiAddPackages (
|
||||
&gEfiCallerIdGuid,
|
||||
NULL,
|
||||
UpdateDriverDxeStrings,
|
||||
NULL
|
||||
);
|
||||
ASSERT (gHiiHandle != NULL);
|
||||
|
||||
//
|
||||
// In order to look for the update data file and programmed image file
|
||||
// from the same volume which this driver is dispatched from, we need
|
||||
// to get the device path of this driver image. It is done by first
|
||||
// locate the LoadedImageProtocol and then get its device path
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ImageHandle,
|
||||
&gEfiLoadedImageProtocolGuid,
|
||||
(VOID **)&LoadedImageProtocol,
|
||||
ImageHandle,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Get the firmware volume protocol where this file resides
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
LoadedImageProtocol->DeviceHandle,
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
(VOID **) &FwVolProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Shall do some extra check to see if it is really contained in the FV?
|
||||
// Should be able to find the section of this driver in the the FV.
|
||||
//
|
||||
FilePathNode = LoadedImageProtocol->FilePath;
|
||||
FwVolFilePathNode = NULL;
|
||||
while (!IsDevicePathEnd (FilePathNode)) {
|
||||
if (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)FilePathNode)!= NULL) {
|
||||
FwVolFilePathNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) FilePathNode;
|
||||
break;
|
||||
}
|
||||
FilePathNode = NextDevicePathNode (FilePathNode);
|
||||
}
|
||||
|
||||
if (FwVolFilePathNode != NULL) {
|
||||
AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength (FwVolFilePathNode), FwVolFilePathNode);
|
||||
|
||||
SectionType = EFI_SECTION_PE32;
|
||||
FileBuffer = NULL;
|
||||
FileBufferSize = 0;
|
||||
Status = FwVolProtocol->ReadSection (
|
||||
FwVolProtocol,
|
||||
&(AlignedDevPathNode->FvFileName),
|
||||
SectionType,
|
||||
0,
|
||||
(VOID **) &FileBuffer,
|
||||
&FileBufferSize,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (AlignedDevPathNode);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (FileBuffer != NULL) {
|
||||
FreePool(FileBuffer);
|
||||
FileBuffer = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Check the NameGuid of the udpate driver so that it can be
|
||||
// used as the CallerId in fault tolerant write protocol
|
||||
//
|
||||
if (!CompareGuid (&gEfiCallerIdGuid, &(AlignedDevPathNode->FvFileName))) {
|
||||
FreePool (AlignedDevPathNode);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
FreePool (AlignedDevPathNode);
|
||||
} else {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Now try to find the script file. The script file is usually
|
||||
// a raw data file which does not contain any sections.
|
||||
//
|
||||
FileBuffer = NULL;
|
||||
FileBufferSize = 0;
|
||||
Status = FwVolProtocol->ReadFile (
|
||||
FwVolProtocol,
|
||||
&gEfiConfigFileNameGuid,
|
||||
(VOID **) &FileBuffer,
|
||||
&FileBufferSize,
|
||||
&FileType,
|
||||
&Attrib,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
if (FileType != EFI_FV_FILETYPE_RAW) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Parse the configuration file.
|
||||
//
|
||||
ConfigData = NULL;
|
||||
NumOfUpdates = 0;
|
||||
Status = ParseUpdateDataFile (
|
||||
FileBuffer,
|
||||
FileBufferSize,
|
||||
&NumOfUpdates,
|
||||
&ConfigData
|
||||
);
|
||||
if (FileBuffer != NULL) {
|
||||
FreePool (FileBuffer);
|
||||
FileBuffer = NULL;
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Now find the update image. The update image should be put in a FV, and then
|
||||
// encapsulated as a raw FFS file. This is to prevent the update image from
|
||||
// being dispatched. So the raw data we get here should be an FV. We need to
|
||||
// process this FV and read the files that is going to be updated.
|
||||
//
|
||||
FileBuffer = NULL;
|
||||
FileBufferSize = 0;
|
||||
Status = FwVolProtocol->ReadFile (
|
||||
FwVolProtocol,
|
||||
&UpdateDataGuid,
|
||||
(VOID **) &FileBuffer,
|
||||
&FileBufferSize,
|
||||
&FileType,
|
||||
&Attrib,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
if (FileType != EFI_FV_FILETYPE_RAW) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// FileBuffer should be an FV. Process the FV
|
||||
//
|
||||
DataFwVolProtocol = NULL;
|
||||
Status = ProcessUpdateImage (
|
||||
FileBuffer,
|
||||
FileBufferSize,
|
||||
&DataFwVolProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (FileBuffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Print on screen
|
||||
//
|
||||
TmpStr = HiiGetString (gHiiHandle, STRING_TOKEN(UPDATE_PROCESS_DATA), NULL);
|
||||
if (TmpStr != NULL) {
|
||||
Print (TmpStr);
|
||||
FreePool(TmpStr);
|
||||
}
|
||||
|
||||
//
|
||||
// Execute the update
|
||||
//
|
||||
Index = 0;
|
||||
UpdateConfigData = ConfigData;
|
||||
while (Index < NumOfUpdates) {
|
||||
Status = PerformUpdate (
|
||||
DataFwVolProtocol,
|
||||
UpdateConfigData
|
||||
);
|
||||
//
|
||||
// Shall updates be serialized so that if an update is not successfully completed,
|
||||
// the remaining updates won't be performed.
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
Index++;
|
||||
UpdateConfigData++;
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (ConfigData != NULL) {
|
||||
FreePool(ConfigData);
|
||||
ConfigData = NULL;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Call system reset
|
||||
//
|
||||
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||||
|
||||
//
|
||||
// Hopefully it won't be reached
|
||||
//
|
||||
return EFI_ABORTED;
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
/** @file
|
||||
Common defines and definitions for a component update driver.
|
||||
|
||||
Copyright (c) 2002 - 2010, 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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _EFI_UPDATE_DRIVER_H_
|
||||
#define _EFI_UPDATE_DRIVER_H_
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Guid/Capsule.h>
|
||||
#include <Protocol/FaultTolerantWrite.h>
|
||||
#include <Protocol/FirmwareVolumeBlock.h>
|
||||
#include <Protocol/FirmwareVolume2.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
|
||||
//
|
||||
// {283FA2EE-532C-484d-9383-9F93B36F0B7E}
|
||||
//
|
||||
#define EFI_UPDATE_DATA_FILE_GUID \
|
||||
{ 0x283fa2ee, 0x532c, 0x484d, { 0x93, 0x83, 0x9f, 0x93, 0xb3, 0x6f, 0xb, 0x7e } }
|
||||
|
||||
extern EFI_HII_HANDLE gHiiHandle;
|
||||
|
||||
typedef enum {
|
||||
UpdateWholeFV = 0, // 0, update whole FV
|
||||
UpdateFvFile, // 1, update a set of FV files asynchronously
|
||||
UpdateFvRange, // 2, update part of FV or flash
|
||||
UpdateOperationMaximum // 3
|
||||
} UPDATE_OPERATION_TYPE;
|
||||
|
||||
typedef struct {
|
||||
UINTN Index;
|
||||
UPDATE_OPERATION_TYPE UpdateType;
|
||||
EFI_DEVICE_PATH_PROTOCOL DevicePath;
|
||||
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||
EFI_GUID FileGuid;
|
||||
UINTN Length;
|
||||
BOOLEAN FaultTolerant;
|
||||
} UPDATE_CONFIG_DATA;
|
||||
|
||||
typedef struct _SECTION_ITEM SECTION_ITEM;
|
||||
struct _SECTION_ITEM {
|
||||
CHAR8 *ptrSection;
|
||||
UINTN SecNameLen;
|
||||
CHAR8 *ptrEntry;
|
||||
CHAR8 *ptrValue;
|
||||
SECTION_ITEM *ptrNext;
|
||||
};
|
||||
|
||||
typedef struct _COMMENT_LINE COMMENT_LINE;
|
||||
struct _COMMENT_LINE {
|
||||
CHAR8 *ptrComment;
|
||||
COMMENT_LINE *ptrNext;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID FileGuid;
|
||||
} UPDATE_PRIVATE_DATA;
|
||||
|
||||
#define MAX_LINE_LENGTH 512
|
||||
#define EFI_D_UPDATE EFI_D_ERROR
|
||||
|
||||
#define MIN_ALIGNMENT_SIZE 4
|
||||
#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
|
||||
|
||||
/**
|
||||
Parse Config data file to get the updated data array.
|
||||
|
||||
@param DataBuffer Config raw file buffer.
|
||||
@param BufferSize Size of raw buffer.
|
||||
@param NumOfUpdates Pointer to the number of update data.
|
||||
@param UpdateArray Pointer to the config of update data.
|
||||
|
||||
@retval EFI_NOT_FOUND No config data is found.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory is allocated.
|
||||
@retval EFI_SUCCESS Parse the config file successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseUpdateDataFile (
|
||||
IN UINT8 *DataBuffer,
|
||||
IN UINTN BufferSize,
|
||||
IN OUT UINTN *NumOfUpdates,
|
||||
IN OUT UPDATE_CONFIG_DATA **UpdateArray
|
||||
);
|
||||
|
||||
/**
|
||||
Update the whole FV image, and reinsall FVB protocol for the updated FV image.
|
||||
|
||||
@param FvbHandle Handle of FVB protocol for the updated flash range.
|
||||
@param FvbProtocol FVB protocol.
|
||||
@param ConfigData Config data on updating driver.
|
||||
@param ImageBuffer Image buffer to be updated.
|
||||
@param ImageSize Image size.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Update type is not UpdateWholeFV.
|
||||
Or Image size is not same to the size of whole FV.
|
||||
@retval EFI_OUT_OF_RESOURCES No enoug memory is allocated.
|
||||
@retval EFI_SUCCESS FV image is updated, and its FVB protocol is reinstalled.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformUpdateOnWholeFv (
|
||||
IN EFI_HANDLE FvbHandle,
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,
|
||||
IN UPDATE_CONFIG_DATA *ConfigData,
|
||||
IN UINT8 *ImageBuffer,
|
||||
IN UINTN ImageSize
|
||||
);
|
||||
|
||||
/**
|
||||
Update certain file in the FV.
|
||||
|
||||
@param FvbHandle Handle of FVB protocol for the updated flash range.
|
||||
@param FvbProtocol FVB protocol.
|
||||
@param ConfigData Config data on updating driver.
|
||||
@param ImageBuffer Image buffer to be updated.
|
||||
@param ImageSize Image size.
|
||||
@param FileType FFS file type.
|
||||
@param FileAttributes FFS file attribute
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Update type is not UpdateFvFile.
|
||||
Or Image size is not same to the size of whole FV.
|
||||
@retval EFI_UNSUPPORTED PEIM FFS is unsupported to be updated.
|
||||
@retval EFI_SUCCESS The FFS file is added into FV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformUpdateOnFvFile (
|
||||
IN EFI_HANDLE FvbHandle,
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,
|
||||
IN UPDATE_CONFIG_DATA *ConfigData,
|
||||
IN UINT8 *ImageBuffer,
|
||||
IN UINTN ImageSize,
|
||||
IN EFI_FV_FILETYPE FileType,
|
||||
IN EFI_FV_FILE_ATTRIBUTES FileAttributes
|
||||
);
|
||||
|
||||
/**
|
||||
Update the buffer into flash area in fault tolerant write method.
|
||||
|
||||
@param ImageBuffer Image buffer to be updated.
|
||||
@param SizeLeft Size of the image buffer.
|
||||
@param UpdatedSize Size of the updated buffer.
|
||||
@param ConfigData Config data on updating driver.
|
||||
@param FlashAddress Flash address to be updated as start address.
|
||||
@param FvbProtocol FVB protocol.
|
||||
@param FvbHandle Handle of FVB protocol for the updated flash range.
|
||||
|
||||
@retval EFI_SUCCESS Buffer data is updated into flash.
|
||||
@retval EFI_INVALID_PARAMETER Base flash address is not in FVB flash area.
|
||||
@retval EFI_NOT_FOUND FTW protocol doesn't exist.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough backup space.
|
||||
@retval EFI_ABORTED Error happen when update flash area.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
FaultTolerantUpdateOnPartFv (
|
||||
IN UINT8 *ImageBuffer,
|
||||
IN UINTN SizeLeft,
|
||||
IN OUT UINTN *UpdatedSize,
|
||||
IN UPDATE_CONFIG_DATA *ConfigData,
|
||||
IN EFI_PHYSICAL_ADDRESS FlashAddress,
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,
|
||||
IN EFI_HANDLE FvbHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Directly update the buffer into flash area without fault tolerant write method.
|
||||
|
||||
@param ImageBuffer Image buffer to be updated.
|
||||
@param SizeLeft Size of the image buffer.
|
||||
@param UpdatedSize Size of the updated buffer.
|
||||
@param FlashAddress Flash address to be updated as start address.
|
||||
@param FvbProtocol FVB protocol.
|
||||
@param FvbHandle Handle of FVB protocol for the updated flash range.
|
||||
|
||||
@retval EFI_SUCCESS Buffer data is updated into flash.
|
||||
@retval EFI_INVALID_PARAMETER Base flash address is not in FVB flash area.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough backup space.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
NonFaultTolerantUpdateOnPartFv (
|
||||
IN UINT8 *ImageBuffer,
|
||||
IN UINTN SizeLeft,
|
||||
IN OUT UINTN *UpdatedSize,
|
||||
IN EFI_PHYSICAL_ADDRESS FlashAddress,
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,
|
||||
IN EFI_HANDLE FvbHandle
|
||||
);
|
||||
|
||||
#endif
|
@ -0,0 +1,69 @@
|
||||
## @file
|
||||
# This driver is intended to be put in a capsule (FV). If all goes well,
|
||||
# then it should be dispatched from the capsule FV, then find the image
|
||||
# in the same FV and program it in a target Firmware Volume device.
|
||||
#
|
||||
# Copyright (c) 2006 - 2010, 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.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = UpdateDriverDxe
|
||||
FILE_GUID = 0E84FC69-29CC-4C6D-92AC-6D476921850F
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = InitializeUpdateDriver
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources]
|
||||
UpdateDriver.h
|
||||
UpdateStrings.uni
|
||||
UpdateDispatcher.c
|
||||
ParseUpdateProfile.c
|
||||
FlashUpdate.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
PrintLib
|
||||
HiiLib
|
||||
DxeServicesTableLib
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
UefiRuntimeServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
DevicePathLib
|
||||
|
||||
[Guids]
|
||||
gEfiConfigFileNameGuid ## CONSUMES FileName to store ConfigFile
|
||||
|
||||
[Protocols]
|
||||
gEfiFaultTolerantWriteProtocolGuid ## CONSUMES
|
||||
gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
|
||||
gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES
|
||||
gEfiLoadedImageProtocolGuid ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiFirmwareVolumeBlockProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user