From 3837e91c58d4b626a91895b68b32cb59679787e8 Mon Sep 17 00:00:00 2001 From: Star Zeng Date: Mon, 16 Sep 2013 01:50:44 +0000 Subject: MdeModulePkg: Add support for weakly aligned FVs. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14671 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c | 63 +++++++++++++++------------ MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c | 31 ++++++++----- 2 files changed, 56 insertions(+), 38 deletions(-) (limited to 'MdeModulePkg/Core/Dxe') diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c index 75d6267f61..a70e2e45d5 100644 --- a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c @@ -1036,39 +1036,48 @@ CoreProcessFvImageFile ( // FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer; // - // Get FvHeader alignment + // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume + // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from + // its initial linked location and maintain its alignment. // - FvAlignment = 1 << ((FvHeader->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; - } - // - // Allocate the aligned buffer for the FvImage. - // - AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment); - if (AlignedBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } else { + if ((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) { // - // Move FvImage into the aligned buffer and release the original buffer. + // Get FvHeader alignment // - CopyMem (AlignedBuffer, Buffer, BufferSize); - CoreFreePool (Buffer); - Buffer = NULL; + FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16); // - // Produce a FVB protocol for the file + // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value. // - Status = ProduceFVBProtocolOnBuffer ( - (EFI_PHYSICAL_ADDRESS) (UINTN) AlignedBuffer, - (UINT64)BufferSize, - FvHandle, - AuthenticationStatus, - NULL - ); + if (FvAlignment < 8) { + FvAlignment = 8; + } + // + // Allocate the aligned buffer for the FvImage. + // + AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment); + if (AlignedBuffer == NULL) { + FreePool (Buffer); + return EFI_OUT_OF_RESOURCES; + } else { + // + // Move FvImage into the aligned buffer and release the original buffer. + // + CopyMem (AlignedBuffer, Buffer, BufferSize); + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer; + CoreFreePool (Buffer); + Buffer = NULL; + } } + // + // Produce a FVB protocol for the file + // + Status = ProduceFVBProtocolOnBuffer ( + (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, + (UINT64)BufferSize, + FvHandle, + AuthenticationStatus, + NULL + ); } if (EFI_ERROR (Status)) { diff --git a/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c b/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c index 523738d52d..27a7f43fe5 100644 --- a/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c +++ b/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c @@ -474,22 +474,31 @@ ProduceFVBProtocolOnBuffer ( if (FwVolHeader->Signature != EFI_FVH_SIGNATURE) { return EFI_VOLUME_CORRUPTED; } + // - // Get FvHeader alignment - // - 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 EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume + // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from + // its initial linked location and maintain its alignment. // - if (FvAlignment < 8) { - FvAlignment = 8; - } - if ((UINTN)BaseAddress % FvAlignment != 0) { + if ((FwVolHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) { // - // FvImage buffer is not at its required alignment. + // Get FvHeader alignment // - 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; + } + if ((UINTN)BaseAddress % FvAlignment != 0) { + // + // FvImage buffer is not at its required alignment. + // + return EFI_VOLUME_CORRUPTED; + } } + // // Allocate EFI_FW_VOL_BLOCK_DEVICE // -- cgit v1.2.3