Skip to content

Commit

Permalink
fix: split ftw writes if they span blocks
Browse files Browse the repository at this point in the history
FTW writes from the variable driver could span block boundaries
as the driver won't divvy up the transaction like it does for FVB
writes.
Add logic to the FtwWrite to split the writes if they span block
boundaries.

Signed-off-by: Girish Mahadevan <gmahadevan@nvidia.com>
Reviewed-by: Jeff Brasen <jbrasen@nvidia.com>
  • Loading branch information
gmahadevan authored and jgarver committed Jan 15, 2025
1 parent ec9a7d5 commit 98c480c
Showing 1 changed file with 66 additions and 9 deletions.
75 changes: 66 additions & 9 deletions Silicon/NVIDIA/Drivers/FvbDxe/FvbDxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
Fvb Driver
Copyright (c) 2018-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
SPDX-FileCopyrightText: Copyright (c) 2018-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -866,13 +865,71 @@ FtwWrite (
IN VOID *Buffer
)
{
return Private->FvbInstance.Write (
&Private->FvbInstance,
Lba,
Offset,
&Length,
Buffer
);
EFI_STATUS Status;
UINTN BytesRemaining;
UINTN CurOffset;
UINT32 BlockSize;
UINTN WriteSize;
UINTN ActualWriteSize;
EFI_LBA CurLba;
VOID *BufferPtr;

BlockSize = Private->BlockIo->Media->BlockSize;

if (Offset >= BlockSize) {
DEBUG ((DEBUG_ERROR, "%a: Invalid Offset value %u BlockSize %u\n", __FUNCTION__, Offset, BlockSize));
return EFI_BAD_BUFFER_SIZE;
}

BytesRemaining = Length;
CurOffset = Offset;
CurLba = Lba;
BufferPtr = Buffer;
Status = EFI_SUCCESS;

while (BytesRemaining > 0) {
/* Ensure Writes don't cross Block boundaries.*/
if ((CurOffset + BytesRemaining) > BlockSize) {
WriteSize = (BlockSize - CurOffset);
} else {
WriteSize = BytesRemaining;
}

ActualWriteSize = WriteSize;
Status = Private->FvbInstance.Write (
&Private->FvbInstance,
CurLba,
CurOffset,
&ActualWriteSize,
BufferPtr
);
if (EFI_ERROR (Status) || (ActualWriteSize != WriteSize)) {
DEBUG ((
DEBUG_ERROR,
"%a: WriteFailed(%r): LBA %lu Offset %u Actual/Expected:%u/%u\n",
__FUNCTION__,
Status,
CurLba,
CurOffset,
ActualWriteSize,
WriteSize
));

if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Setting Return To BAD BUFFER SIZE\n"));
Status = EFI_BAD_BUFFER_SIZE;
}

break;
}

CurOffset = 0;
BytesRemaining -= WriteSize;
CurLba++;
BufferPtr = ((UINT8 *)BufferPtr + WriteSize);
}

return Status;
}

/**
Expand Down

0 comments on commit 98c480c

Please sign in to comment.