for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {\r
KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);\r
if (CompareGuid (&FvNameGuid, &KnownHandle->FvNameGuid)) {\r
- DEBUG ((EFI_D_ERROR, "FvImage on FvHandle %p and %p has the same FvNameGuid %g.\n", FvHandle, KnownHandle->Handle, FvNameGuid));\r
+ DEBUG ((EFI_D_ERROR, "FvImage on FvHandle %p and %p has the same FvNameGuid %g.\n", FvHandle, KnownHandle->Handle, &FvNameGuid));\r
return NULL;\r
}\r
}\r
return FALSE;\r
}\r
\r
+/**\r
+ Find USED_SIZE FV_EXT_TYPE entry in FV extension header and get the FV used size.\r
+\r
+ @param[in] FvHeader Pointer to FV header.\r
+ @param[out] FvUsedSize Pointer to FV used size returned,\r
+ only valid if USED_SIZE FV_EXT_TYPE entry is found.\r
+ @param[out] EraseByte Pointer to erase byte returned,\r
+ only valid if USED_SIZE FV_EXT_TYPE entry is found.\r
\r
+ @retval TRUE USED_SIZE FV_EXT_TYPE entry is found,\r
+ FV used size and erase byte are returned.\r
+ @retval FALSE No USED_SIZE FV_EXT_TYPE entry found.\r
+\r
+**/\r
+BOOLEAN\r
+GetFvUsedSize (\r
+ IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,\r
+ OUT UINT32 *FvUsedSize,\r
+ OUT UINT8 *EraseByte\r
+ )\r
+{\r
+ UINT16 ExtHeaderOffset;\r
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHeader;\r
+ EFI_FIRMWARE_VOLUME_EXT_ENTRY *ExtEntryList;\r
+ EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *ExtEntryUsedSize;\r
+\r
+ ExtHeaderOffset = ReadUnaligned16 (&FvHeader->ExtHeaderOffset);\r
+ if (ExtHeaderOffset != 0) {\r
+ ExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) ((UINT8 *) FvHeader + ExtHeaderOffset);\r
+ ExtEntryList = (EFI_FIRMWARE_VOLUME_EXT_ENTRY *) (ExtHeader + 1);\r
+ while ((UINTN) ExtEntryList < ((UINTN) ExtHeader + ReadUnaligned32 (&ExtHeader->ExtHeaderSize))) {\r
+ if (ReadUnaligned16 (&ExtEntryList->ExtEntryType) == EFI_FV_EXT_TYPE_USED_SIZE_TYPE) {\r
+ //\r
+ // USED_SIZE FV_EXT_TYPE entry is found.\r
+ //\r
+ ExtEntryUsedSize = (EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *) ExtEntryList;\r
+ *FvUsedSize = ReadUnaligned32 (&ExtEntryUsedSize->UsedSize);\r
+ if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ERASE_POLARITY) != 0) {\r
+ *EraseByte = 0xFF;\r
+ } else {\r
+ *EraseByte = 0;\r
+ }\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "FV at 0x%x has 0x%x used size, and erase byte is 0x%02x\n",\r
+ FvHeader,\r
+ *FvUsedSize,\r
+ *EraseByte\r
+ ));\r
+ return TRUE;\r
+ }\r
+ ExtEntryList = (EFI_FIRMWARE_VOLUME_EXT_ENTRY *)\r
+ ((UINT8 *) ExtEntryList + ReadUnaligned16 (&ExtEntryList->ExtEntrySize));\r
+ }\r
+ }\r
+\r
+ //\r
+ // No USED_SIZE FV_EXT_TYPE entry found.\r
+ //\r
+ return FALSE;\r
+}\r
\r
/**\r
Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.\r
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
UINT32 FvAlignment;\r
EFI_DEVICE_PATH_PROTOCOL *FvFileDevicePath;\r
+ UINT32 FvUsedSize;\r
+ UINT8 EraseByte;\r
\r
//\r
// Read the first (and only the first) firmware volume section\r
// can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from\r
// its initial linked location and maintain its alignment.\r
//\r
- if ((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
+ if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
//\r
// Get FvHeader alignment\r
//\r
- FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+ FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r
//\r
// FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
//\r
if (FvAlignment < 8) {\r
FvAlignment = 8;\r
}\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a() FV at 0x%x, FvAlignment required is 0x%x\n",\r
+ __FUNCTION__,\r
+ FvHeader,\r
+ FvAlignment\r
+ ));\r
+\r
//\r
- // Allocate the aligned buffer for the FvImage.\r
+ // Check FvImage alignment.\r
//\r
- AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);\r
- if (AlignedBuffer == NULL) {\r
- FreePool (Buffer);\r
- return EFI_OUT_OF_RESOURCES;\r
- } else {\r
+ if ((UINTN) FvHeader % FvAlignment != 0) {\r
//\r
- // Move FvImage into the aligned buffer and release the original buffer.\r
+ // Allocate the aligned buffer for the FvImage.\r
//\r
- CopyMem (AlignedBuffer, Buffer, BufferSize);\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;\r
- CoreFreePool (Buffer);\r
- Buffer = NULL;\r
+ AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);\r
+ if (AlignedBuffer == NULL) {\r
+ FreePool (Buffer);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ //\r
+ // Move FvImage into the aligned buffer and release the original buffer.\r
+ //\r
+ if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {\r
+ //\r
+ // Copy the used bytes and fill the rest with the erase value.\r
+ //\r
+ CopyMem (AlignedBuffer, FvHeader, (UINTN) FvUsedSize);\r
+ SetMem (\r
+ (UINT8 *) AlignedBuffer + FvUsedSize,\r
+ (UINTN) (BufferSize - FvUsedSize),\r
+ EraseByte\r
+ );\r
+ } else {\r
+ CopyMem (AlignedBuffer, Buffer, BufferSize);\r
+ }\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;\r
+ CoreFreePool (Buffer);\r
+ Buffer = NULL;\r
+ }\r
}\r
}\r
//\r