ArmPlatformPkg/BootMonFs: Cache the HW Description address

This fixes a bug whereby the image description is written over file data when
the file's size is close to a multiple of the block size.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brendan Jackman <brendan.jackman@arm.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15517 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Brendan Jackman 2014-05-08 15:08:39 +00:00 committed by oliviermartin
parent e29771bb6e
commit 79e12331ef
4 changed files with 21 additions and 27 deletions

View File

@ -17,13 +17,6 @@
#include <Protocol/SimpleFileSystem.h> #include <Protocol/SimpleFileSystem.h>
EFI_STATUS
BootMonFsDiscoverNextImage (
IN BOOTMON_FS_INSTANCE *Flash,
IN EFI_LBA *LbaStart,
OUT HW_IMAGE_DESCRIPTION *Image
);
EFI_STATUS EFI_STATUS
BootMonFsInitialize ( BootMonFsInitialize (
IN BOOTMON_FS_INSTANCE *Instance IN BOOTMON_FS_INSTANCE *Instance

View File

@ -135,11 +135,12 @@ BootMonFsIsImageValid (
return TRUE; return TRUE;
} }
STATIC
EFI_STATUS EFI_STATUS
BootMonFsDiscoverNextImage ( BootMonFsDiscoverNextImage (
IN BOOTMON_FS_INSTANCE *Instance, IN BOOTMON_FS_INSTANCE *Instance,
IN EFI_LBA *LbaStart, IN OUT EFI_LBA *LbaStart,
OUT HW_IMAGE_DESCRIPTION *ImageDescription IN OUT BOOTMON_FS_FILE *File
) )
{ {
EFI_DISK_IO_PROTOCOL *DiskIo; EFI_DISK_IO_PROTOCOL *DiskIo;
@ -162,17 +163,21 @@ BootMonFsDiscoverNextImage (
Instance->Media->MediaId, Instance->Media->MediaId,
DescOffset, DescOffset,
sizeof (HW_IMAGE_DESCRIPTION), sizeof (HW_IMAGE_DESCRIPTION),
ImageDescription &File->HwDescription
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
// If we found a valid image description... // If we found a valid image description...
if (BootMonFsIsImageValid (ImageDescription, (CurrentLba - Instance->Media->LowestAlignedLba))) { if (BootMonFsIsImageValid (&File->HwDescription, (CurrentLba - Instance->Media->LowestAlignedLba))) {
DEBUG ((EFI_D_ERROR, "Found image: %a in block %d.\n", &(ImageDescription->Footer.Filename), (UINTN)(CurrentLba - Instance->Media->LowestAlignedLba))); DEBUG ((EFI_D_ERROR, "Found image: %a in block %d.\n",
&(File->HwDescription.Footer.Filename),
(UINTN)(CurrentLba - Instance->Media->LowestAlignedLba)
));
File->HwDescAddress = DescOffset;
*LbaStart = ImageDescription->BlockEnd + 1; *LbaStart = CurrentLba + 1;
return EFI_SUCCESS; return EFI_SUCCESS;
} else { } else {
CurrentLba++; CurrentLba++;
@ -202,7 +207,7 @@ BootMonFsInitialize (
return Status; return Status;
} }
Status = BootMonFsDiscoverNextImage (Instance, &Lba, &(NewFile->HwDescription)); Status = BootMonFsDiscoverNextImage (Instance, &Lba, NewFile);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
// Free NewFile allocated by BootMonFsCreateFile () // Free NewFile allocated by BootMonFsCreateFile ()
FreePool (NewFile); FreePool (NewFile);

View File

@ -48,6 +48,7 @@ typedef struct {
LIST_ENTRY Link; LIST_ENTRY Link;
BOOTMON_FS_INSTANCE *Instance; BOOTMON_FS_INSTANCE *Instance;
UINTN HwDescAddress;
HW_IMAGE_DESCRIPTION HwDescription; HW_IMAGE_DESCRIPTION HwDescription;
EFI_FILE_PROTOCOL File; EFI_FILE_PROTOCOL File;

View File

@ -29,24 +29,18 @@ InvalidateImageDescription (
EFI_DISK_IO_PROTOCOL *DiskIo; EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_BLOCK_IO_PROTOCOL *BlockIo;
UINT32 MediaId; UINT32 MediaId;
UINT32 BlockSize;
VOID *Buffer; VOID *Buffer;
EFI_STATUS Status; EFI_STATUS Status;
UINT64 DescriptionAddress;
DiskIo = File->Instance->DiskIo; DiskIo = File->Instance->DiskIo;
BlockIo = File->Instance->BlockIo; BlockIo = File->Instance->BlockIo;
MediaId = BlockIo->Media->MediaId; MediaId = BlockIo->Media->MediaId;
BlockSize = BlockIo->Media->BlockSize;
DescriptionAddress = (File->HwDescription.BlockEnd * BlockSize)
- sizeof (HW_IMAGE_DESCRIPTION);
Buffer = AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION)); Buffer = AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION));
Status = DiskIo->WriteDisk (DiskIo, Status = DiskIo->WriteDisk (DiskIo,
MediaId, MediaId,
DescriptionAddress, File->HwDescAddress,
sizeof (HW_IMAGE_DESCRIPTION), sizeof (HW_IMAGE_DESCRIPTION),
Buffer Buffer
); );
@ -86,7 +80,7 @@ FlushAppendRegion (
// Only invalidate the Image Description of files that have already been // Only invalidate the Image Description of files that have already been
// written in Flash // written in Flash
if (File->HwDescription.RegionCount > 0) { if (File->HwDescAddress != 0) {
Status = InvalidateImageDescription (File); Status = InvalidateImageDescription (File);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
} }
@ -131,11 +125,14 @@ FlushAppendRegion (
if ((NewFileSize % BlockSize) > 0) { if ((NewFileSize % BlockSize) > 0) {
NewFileSize += BlockSize - (NewFileSize % BlockSize); NewFileSize += BlockSize - (NewFileSize % BlockSize);
} }
File->HwDescAddress = (FileStart + NewFileSize) - sizeof (HW_IMAGE_DESCRIPTION);
// Update the file description on the media // Update the file description on the media
Status = DiskIo->WriteDisk ( Status = DiskIo->WriteDisk (
DiskIo, DiskIo,
File->Instance->Media->MediaId, File->Instance->Media->MediaId,
(FileStart + NewFileSize) - sizeof (HW_IMAGE_DESCRIPTION), File->HwDescAddress,
sizeof (HW_IMAGE_DESCRIPTION), sizeof (HW_IMAGE_DESCRIPTION),
Description Description
); );
@ -585,7 +582,6 @@ BootMonFsDelete (
BOOTMON_FS_FILE *File; BOOTMON_FS_FILE *File;
LIST_ENTRY *RegionToFlushLink; LIST_ENTRY *RegionToFlushLink;
BOOTMON_FS_FILE_REGION *Region; BOOTMON_FS_FILE_REGION *Region;
HW_IMAGE_DESCRIPTION *Description;
EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_BLOCK_IO_PROTOCOL *BlockIo;
UINT8 *EmptyBuffer; UINT8 *EmptyBuffer;
@ -613,7 +609,6 @@ BootMonFsDelete (
// If (RegionCount is greater than 0) then the file already exists // If (RegionCount is greater than 0) then the file already exists
if (File->HwDescription.RegionCount > 0) { if (File->HwDescription.RegionCount > 0) {
Description = &File->HwDescription;
BlockIo = File->Instance->BlockIo; BlockIo = File->Instance->BlockIo;
// Create an empty buffer // Create an empty buffer
@ -624,7 +619,7 @@ BootMonFsDelete (
} }
// Invalidate the last Block // Invalidate the last Block
Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, Description->BlockEnd, BlockIo->Media->BlockSize, EmptyBuffer); Status = InvalidateImageDescription (File);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
FreePool (EmptyBuffer); FreePool (EmptyBuffer);