mirror of https://github.com/acidanthera/audk.git
Enhance DXE dispatcher logic to check the duplicated FV image bases on FvHob2 and FvNameGuid per PI spec.
Signed-off-by: lgao4 Reviewed-by: rsun3 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12874 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
22675de35c
commit
2fc46f86f9
|
@ -708,25 +708,102 @@ FvHasBeenProcessed (
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Remember that Fv protocol on FvHandle has had it's drivers placed on the
|
Remember that Fv protocol on FvHandle has had it's drivers placed on the
|
||||||
mDiscoveredList. This fucntion adds entries on the mFvHandleList. Items are
|
mDiscoveredList. This fucntion adds entries on the mFvHandleList if new
|
||||||
never removed/freed from the mFvHandleList.
|
entry is different from one in mFvHandleList by checking FvImage Guid.
|
||||||
|
Items are never removed/freed from the mFvHandleList.
|
||||||
|
|
||||||
@param FvHandle The handle of a FV that has been processed
|
@param FvHandle The handle of a FV that has been processed
|
||||||
|
|
||||||
|
@return A point to new added FvHandle entry. If FvHandle with the same FvImage guid
|
||||||
|
has been added, NULL will return.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
KNOWN_HANDLE *
|
||||||
FvIsBeingProcesssed (
|
FvIsBeingProcesssed (
|
||||||
IN EFI_HANDLE FvHandle
|
IN EFI_HANDLE FvHandle
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
KNOWN_HANDLE *KnownHandle;
|
EFI_STATUS Status;
|
||||||
|
EFI_GUID FvNameGuid;
|
||||||
|
BOOLEAN FvNameGuidIsFound;
|
||||||
|
UINT32 ExtHeaderOffset;
|
||||||
|
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||||
|
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||||
|
EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
|
||||||
|
UINTN LbaOffset;
|
||||||
|
UINTN Index;
|
||||||
|
EFI_LBA LbaIndex;
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
KNOWN_HANDLE *KnownHandle;
|
||||||
|
|
||||||
KnownHandle = AllocatePool (sizeof (KNOWN_HANDLE));
|
//
|
||||||
|
// Get the FirmwareVolumeBlock protocol on that handle
|
||||||
|
//
|
||||||
|
FvNameGuidIsFound = FALSE;
|
||||||
|
Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Get the full FV header based on FVB protocol.
|
||||||
|
//
|
||||||
|
Status = GetFwVolHeader (Fvb, &FwVolHeader);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
FwVolHeader = NULL;
|
||||||
|
} else if (VerifyFvHeaderChecksum (FwVolHeader) && FwVolHeader->ExtHeaderOffset != 0) {
|
||||||
|
ExtHeaderOffset = (UINT32) FwVolHeader->ExtHeaderOffset;
|
||||||
|
BlockMap = FwVolHeader->BlockMap;
|
||||||
|
LbaIndex = 0;
|
||||||
|
LbaOffset = 0;
|
||||||
|
//
|
||||||
|
// Find LbaIndex and LbaOffset for FV extension header based on BlockMap.
|
||||||
|
//
|
||||||
|
while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
|
||||||
|
for (Index = 0; Index < BlockMap->NumBlocks && ExtHeaderOffset >= BlockMap->Length; Index ++) {
|
||||||
|
ExtHeaderOffset -= BlockMap->Length;
|
||||||
|
LbaIndex ++;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check whether FvExtHeader is crossing the multi block range.
|
||||||
|
//
|
||||||
|
if (Index < BlockMap->NumBlocks) {
|
||||||
|
LbaOffset = ExtHeaderOffset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
BlockMap++;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read FvNameGuid from FV extension header.
|
||||||
|
//
|
||||||
|
Status = ReadFvbData (Fvb, &LbaIndex, &LbaOffset, sizeof (FvNameGuid), (UINT8 *) &FvNameGuid);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
FvNameGuidIsFound = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CoreFreePool (FwVolHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FvNameGuidIsFound) {
|
||||||
|
//
|
||||||
|
// Check whether the FV image with the found FvNameGuid has been processed.
|
||||||
|
//
|
||||||
|
for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
|
||||||
|
KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
|
||||||
|
if (CompareGuid (&FvNameGuid, &KnownHandle->FvNameGuid)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "FvImage on FvHandle %p and %p has the same FvNameGuid %g.\n", FvHandle, KnownHandle->Handle, FvNameGuid));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KnownHandle = AllocateZeroPool (sizeof (KNOWN_HANDLE));
|
||||||
ASSERT (KnownHandle != NULL);
|
ASSERT (KnownHandle != NULL);
|
||||||
|
|
||||||
KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
|
KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
|
||||||
KnownHandle->Handle = FvHandle;
|
KnownHandle->Handle = FvHandle;
|
||||||
|
if (FvNameGuidIsFound) {
|
||||||
|
CopyGuid (&KnownHandle->FvNameGuid, &FvNameGuid);
|
||||||
|
}
|
||||||
InsertTailList (&mFvHandleList, &KnownHandle->Link);
|
InsertTailList (&mFvHandleList, &KnownHandle->Link);
|
||||||
|
return KnownHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -844,7 +921,7 @@ CoreAddToDriverList (
|
||||||
Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is
|
Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is
|
||||||
described by a EFI_HOB_FIRMWARE_VOLUME2 Hob.
|
described by a EFI_HOB_FIRMWARE_VOLUME2 Hob.
|
||||||
|
|
||||||
@param FvHandle The handle which FVB protocol installed on.
|
@param FvNameGuid The FV image guid specified.
|
||||||
@param DriverName The driver guid specified.
|
@param DriverName The driver guid specified.
|
||||||
|
|
||||||
@retval TRUE This file is found in a EFI_HOB_FIRMWARE_VOLUME2
|
@retval TRUE This file is found in a EFI_HOB_FIRMWARE_VOLUME2
|
||||||
|
@ -854,7 +931,7 @@ CoreAddToDriverList (
|
||||||
**/
|
**/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
FvFoundInHobFv2 (
|
FvFoundInHobFv2 (
|
||||||
IN EFI_HANDLE FvHandle,
|
IN CONST EFI_GUID *FvNameGuid,
|
||||||
IN CONST EFI_GUID *DriverName
|
IN CONST EFI_GUID *DriverName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -863,7 +940,11 @@ FvFoundInHobFv2 (
|
||||||
HobFv2.Raw = GetHobList ();
|
HobFv2.Raw = GetHobList ();
|
||||||
|
|
||||||
while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
|
while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
|
||||||
if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName)) {
|
//
|
||||||
|
// Compare parent FvNameGuid and FileGuid both.
|
||||||
|
//
|
||||||
|
if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName) &&
|
||||||
|
CompareGuid (FvNameGuid, &HobFv2.FirmwareVolume2->FvName)) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
HobFv2.Raw = GET_NEXT_HOB (HobFv2);
|
HobFv2.Raw = GET_NEXT_HOB (HobFv2);
|
||||||
|
@ -1021,6 +1102,7 @@ CoreFwVolEventProtocolNotify (
|
||||||
UINT32 AuthenticationStatus;
|
UINT32 AuthenticationStatus;
|
||||||
UINTN SizeOfBuffer;
|
UINTN SizeOfBuffer;
|
||||||
VOID *DepexBuffer;
|
VOID *DepexBuffer;
|
||||||
|
KNOWN_HANDLE *KnownHandle;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
BufferSize = sizeof (EFI_HANDLE);
|
BufferSize = sizeof (EFI_HANDLE);
|
||||||
|
@ -1048,7 +1130,14 @@ CoreFwVolEventProtocolNotify (
|
||||||
//
|
//
|
||||||
// Since we are about to process this Fv mark it as processed.
|
// Since we are about to process this Fv mark it as processed.
|
||||||
//
|
//
|
||||||
FvIsBeingProcesssed (FvHandle);
|
KnownHandle = FvIsBeingProcesssed (FvHandle);
|
||||||
|
if (KnownHandle == NULL) {
|
||||||
|
//
|
||||||
|
// The FV with the same FV name guid has already been processed.
|
||||||
|
// So lets skip it!
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
|
Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
|
||||||
if (EFI_ERROR (Status) || Fv == NULL) {
|
if (EFI_ERROR (Status) || Fv == NULL) {
|
||||||
|
@ -1131,7 +1220,7 @@ CoreFwVolEventProtocolNotify (
|
||||||
// Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
|
// Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
|
||||||
// been extracted.
|
// been extracted.
|
||||||
//
|
//
|
||||||
if (FvFoundInHobFv2 (FvHandle, &NameGuid)) {
|
if (FvFoundInHobFv2 (&KnownHandle->FvNameGuid, &NameGuid)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ typedef struct {
|
||||||
UINTN Signature;
|
UINTN Signature;
|
||||||
LIST_ENTRY Link; // mFvHandleList
|
LIST_ENTRY Link; // mFvHandleList
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
|
EFI_GUID FvNameGuid;
|
||||||
} KNOWN_HANDLE;
|
} KNOWN_HANDLE;
|
||||||
|
|
||||||
|
|
||||||
|
@ -2489,4 +2490,64 @@ CoreEmptyCallbackFunction (
|
||||||
IN VOID *Context
|
IN VOID *Context
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read data from Firmware Block by FVB protocol Read.
|
||||||
|
The data may cross the multi block ranges.
|
||||||
|
|
||||||
|
@param Fvb The FW_VOL_BLOCK_PROTOCOL instance from which to read data.
|
||||||
|
@param StartLba Pointer to StartLba.
|
||||||
|
On input, the start logical block index from which to read.
|
||||||
|
On output,the end logical block index after reading.
|
||||||
|
@param Offset Pointer to Offset
|
||||||
|
On input, offset into the block at which to begin reading.
|
||||||
|
On output, offset into the end block after reading.
|
||||||
|
@param DataSize Size of data to be read.
|
||||||
|
@param Data Pointer to Buffer that the data will be read into.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Successfully read data from firmware block.
|
||||||
|
@retval others
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
ReadFvbData (
|
||||||
|
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,
|
||||||
|
IN OUT EFI_LBA *StartLba,
|
||||||
|
IN OUT UINTN *Offset,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *Data
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and
|
||||||
|
copy the real length volume header into it.
|
||||||
|
|
||||||
|
@param Fvb The FW_VOL_BLOCK_PROTOCOL instance from which to
|
||||||
|
read the volume header
|
||||||
|
@param FwVolHeader Pointer to pointer to allocated buffer in which
|
||||||
|
the volume header is returned.
|
||||||
|
|
||||||
|
@retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated.
|
||||||
|
@retval EFI_SUCCESS Successfully read volume header to the allocated
|
||||||
|
buffer.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
GetFwVolHeader (
|
||||||
|
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,
|
||||||
|
OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verify checksum of the firmware volume header.
|
||||||
|
|
||||||
|
@param FvHeader Points to the firmware volume header to be checked
|
||||||
|
|
||||||
|
@retval TRUE Checksum verification passed
|
||||||
|
@retval FALSE Checksum verification failed
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
VerifyFvHeaderChecksum (
|
||||||
|
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -357,7 +357,7 @@ FvCheck (
|
||||||
//
|
//
|
||||||
// Check whether FvHeader is crossing the multi block range.
|
// Check whether FvHeader is crossing the multi block range.
|
||||||
//
|
//
|
||||||
if (HeaderSize > BlockMap->Length) {
|
if (Index >= BlockMap->NumBlocks) {
|
||||||
BlockMap++;
|
BlockMap++;
|
||||||
continue;
|
continue;
|
||||||
} else if (HeaderSize > 0) {
|
} else if (HeaderSize > 0) {
|
||||||
|
|
|
@ -366,22 +366,6 @@ SetFileState (
|
||||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Verify checksum of the firmware volume header.
|
|
||||||
|
|
||||||
@param FvHeader Points to the firmware volume header to be checked
|
|
||||||
|
|
||||||
@retval TRUE Checksum verification passed
|
|
||||||
@retval FALSE Checksum verification failed
|
|
||||||
|
|
||||||
**/
|
|
||||||
BOOLEAN
|
|
||||||
VerifyFvHeaderChecksum (
|
|
||||||
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check if it's a valid FFS file header.
|
Check if it's a valid FFS file header.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue