public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Leif Lindholm" <leif@nuviainc.com>
To: Ling Jia <jialing@phytium.com.cn>
Cc: devel@edk2.groups.io
Subject: Re: [PATCH v1 08/10] Silicon/Phytium: Added fvb driver for norflash
Date: Wed, 10 Feb 2021 19:33:52 +0000	[thread overview]
Message-ID: <20210210193352.GT1664@vanye> (raw)
In-Reply-To: <20210205100630.46848-20-jialing@phytium.com.cn>

On Fri, Feb 05, 2021 at 18:06:28 +0800, Ling Jia wrote:
> The FlashFvbDxe provided the fvb protocol,
> which requested by the flash operators.
> 
> Signed-off-by: Ling Jia <jialing@phytium.com.cn>
> ---
>  Platform/Phytium/DurianPkg/DurianPkg.dsc                             |    1 +
>  Platform/Phytium/DurianPkg/DurianPkg.fdf                             |    1 +
>  Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf |   61 +
>  Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.h   |  104 ++
>  Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c   | 1196 ++++++++++++++++++++
>  5 files changed, 1363 insertions(+)
> 
> diff --git a/Platform/Phytium/DurianPkg/DurianPkg.dsc b/Platform/Phytium/DurianPkg/DurianPkg.dsc
> index 884e01643498..48fe1b4fd4ad 100644
> --- a/Platform/Phytium/DurianPkg/DurianPkg.dsc
> +++ b/Platform/Phytium/DurianPkg/DurianPkg.dsc
> @@ -233,6 +233,7 @@ [Components.common]
>    # NOR Flash driver
>    #
>    Silicon/Phytium/FT2000-4Pkg/Drivers/SpiNorFlashDxe/SpiNorFlashDxe.inf
> +  Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>  
>    #
>    # Usb Support
> diff --git a/Platform/Phytium/DurianPkg/DurianPkg.fdf b/Platform/Phytium/DurianPkg/DurianPkg.fdf
> index 76b02417344d..863f4fb831c2 100644
> --- a/Platform/Phytium/DurianPkg/DurianPkg.fdf
> +++ b/Platform/Phytium/DurianPkg/DurianPkg.fdf
> @@ -103,6 +103,7 @@ [FV.FvMain]
>  
>    INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
>    INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
> +  INF Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>    INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
>    INF ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
>  
> diff --git a/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf b/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
> new file mode 100644
> index 000000000000..f818c8944bcb
> --- /dev/null
> +++ b/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
> @@ -0,0 +1,61 @@
> +#/** @file
> +#  Phytium NorFlash Fvb Drivers.
> +#
> +#  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
> +#  Copyright (C) 2020, Phytium Technology Co,Ltd. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001b
> +  BASE_NAME                      = FlashFvbDxe
> +  FILE_GUID                      = b8923820-3e7c-11eb-b12c-17525e90ecc8
> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> +  VERSION_STRING                 = 0.1
> +  ENTRY_POINT                    = FvbEntryPoint
> +
> +[Sources]
> +  FlashFvbDxe.c
> +  FlashFvbDxe.h
> +
> +[Packages]
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Silicon/Phytium/PhytiumCommonPkg/PhytiumCommonPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  DxeServicesTableLib
> +  HobLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeLib
> +  UefiDriverEntryPoint
> +
> +[Guids]
> +  gEfiSystemNvDataFvGuid
> +  gEfiVariableGuid
> +  gEfiEventVirtualAddressChangeGuid
> +  gEfiAuthenticatedVariableGuid
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid
> +  gEfiFirmwareVolumeBlockProtocolGuid
> +  gSpiNorFlashProtocolGuid
> +
> +[Pcd.common]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +  gPhytiumPlatformTokenSpaceGuid.PcdSpiFlashBase
> +  gPhytiumPlatformTokenSpaceGuid.PcdSpiFlashSize
> +
> +[Depex]
> +  gSpiNorFlashProtocolGuid
> diff --git a/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.h b/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.h
> new file mode 100644
> index 000000000000..36ce1e87acce
> --- /dev/null
> +++ b/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.h
> @@ -0,0 +1,104 @@
> +/** @file
> +  Phytium NorFlash Fvb Drivers Header.
> +
> +  Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef FVB_FLASH_DXE_H_
> +#define FVB_FLASH_DXE_H_
> +
> +#include <Protocol/BlockIo.h>
> +#include <Protocol/FirmwareVolumeBlock.h>
> +#include <Protocol/SpiNorFlashProtocol.h>
> +
> +#define GET_DATA_OFFSET(BaseAddr, Lba, LbaSize) ((BaseAddr) + (UINTN)((Lba) * (LbaSize)))
> +#define FVB_FLASH_SIGNATURE                       SIGNATURE_32('S', 'N', 'O', 'R')
> +#define INSTANCE_FROM_FVB_THIS(a)                 CR(a, FT_FVB_DEVICE, FvbProtocol, FVB_FLASH_SIGNATURE)
> +
> +typedef struct _FT_FVB_DEVICE    FT_FVB_DEVICE;
> +
> +#define NOR_FLASH_ERASE_RETRY         10
> +
> +typedef struct {
> +  VENDOR_DEVICE_PATH                  Vendor;
> +  EFI_DEVICE_PATH_PROTOCOL            End;
> +  } FT_FVB_DEVICE_PATH;
> +
> +struct _FT_FVB_DEVICE {
> +  UINT32                              Signature;
> +  EFI_HANDLE                          Handle;
> +
> +  UINTN                               DeviceBaseAddress;
> +  UINTN                               RegionBaseAddress;
> +  UINTN                               Size;
> +  EFI_LBA                             StartLba;
> +  EFI_BLOCK_IO_MEDIA                  Media;
> +
> +  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
> +
> +  FT_FVB_DEVICE_PATH                  DevicePath;
> +  EFI_NORFLASH_DRV_PROTOCOL          *SpiFlashProtocol;
> +  VOID                               *ShadowBuffer;
> +  UINTN                               FvbSize;
> +  };
> +
> +EFI_STATUS
> +EFIAPI
> +FvbGetAttributes(
> +    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
> +    OUT       EFI_FVB_ATTRIBUTES_2*                    Attributes
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbSetAttributes(
> +    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
> +    IN OUT    EFI_FVB_ATTRIBUTES_2*                    Attributes
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbGetPhysicalAddress(
> +    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
> +    OUT       EFI_PHYSICAL_ADDRESS*                    Address
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbGetBlockSize(
> +    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
> +    IN        EFI_LBA                                  Lba,
> +    OUT       UINTN*                                   BlockSize,
> +    OUT       UINTN*                                   NumberOfBlocks
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbRead(
> +    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
> +    IN        EFI_LBA                                  Lba,
> +    IN        UINTN                                    Offset,
> +    IN OUT    UINTN*                                   NumBytes,
> +    IN OUT    UINT8*                                   Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbWrite(
> +    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
> +    IN        EFI_LBA                                  Lba,
> +    IN        UINTN                                    Offset,
> +    IN OUT    UINTN*                                   NumBytes,
> +    IN        UINT8*                                   Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FvbEraseBlocks(
> +    IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL*     This,
> +    ...
> +  );
> +
> +#endif // FVB_FLASH_DXE_H_
> diff --git a/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c b/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
> new file mode 100644
> index 000000000000..e6777a136707
> --- /dev/null
> +++ b/Silicon/Phytium/PhytiumCommonPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
> @@ -0,0 +1,1196 @@
> +/** @file
> +  Phytium NorFlash Fvb Drivers.
> +
> +  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
> +  Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Guid/VariableFormat.h>
> +
> +#include "FlashFvbDxe.h"
> +
> +STATIC EFI_EVENT       FvbVirtualAddrChangeEvent;
> +STATIC FT_FVB_DEVICE   *FvbDevice;
> +STATIC UINTN           mFlashNvStorageVariableBase;
> +
> +STATIC FT_FVB_DEVICE FvbFlashInstanceTemplate = {
> +  FVB_FLASH_SIGNATURE, // Signature
> +  NULL,                // Handle ... NEED TO BE FILLED
> +  0,                   // DeviceBaseAddress ... NEED TO BE FILLED
> +  0,                   // RegionBaseAddress ... NEED TO BE FILLED
> +  0,                   // Size ... NEED TO BE FILLED
> +  0,                   // StartLba
> +  {
> +    0,                 // MediaId ... NEED TO BE FILLED
> +    FALSE,             // RemovableMedia
> +    TRUE,              // MediaPresent
> +    FALSE,             // LogicalPartition
> +    FALSE,             // ReadOnly
> +    FALSE,             // WriteCaching;
> +    0,                 // BlockSize ... NEED TO BE FILLED
> +    4,                 // IoAlign
> +    0,                 // LastBlock ... NEED TO BE FILLED
> +    0,                 // LowestAlignedLba
> +    1,                 // LogicalBlocksPerPhysicalBlock
> +  },                   //Media;
> +  {
> +    FvbGetAttributes,      // GetAttributes
> +    FvbSetAttributes,      // SetAttributes
> +    FvbGetPhysicalAddress, // GetPhysicalAddress
> +    FvbGetBlockSize,       // GetBlockSize
> +    FvbRead,               // Read
> +    FvbWrite,              // Write
> +    FvbEraseBlocks,        // EraseBlocks
> +    NULL,                  // ParentHandle
> +  },                       // FvbProtoccol;
> +
> +  {
> +    {
> +      {
> +        HARDWARE_DEVICE_PATH,
> +        HW_VENDOR_DP,
> +        {
> +          (UINT8) sizeof (VENDOR_DEVICE_PATH),
> +          (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +        }
> +      },
> +      {
> +        0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
> +      }, // GUID ... NEED TO BE FILLED
> +    },
> +    {
> +      END_DEVICE_PATH_TYPE,
> +      END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +      {
> +        sizeof (EFI_DEVICE_PATH_PROTOCOL),
> +        0
> +      }
> +    }
> +  },     // DevicePath
> +
> +  NULL,  // SpiFlashProtocol ... NEED TO BE FILLED
> +  NULL,  // ShadowBuffer     ... NEED TO BE FILLED
> +  0      // Fvb Size
> +};
> +
> +
> +/**
> +  Erases a single block of flash.
> +
> +  @param[in] FlashInstance      The poiter of the fvb device sturct.
> +
> +  @param[in] BlockAddress       Physical address of Lba to be erased.
> +
> +  @retval EFI_SUCCESS           The erase single block request successfully completed.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +FvbFlashEraseSingleBlock (
> +  IN FT_FVB_DEVICE     *FlashInstance,
> +  IN UINTN             BlockAddress
> +  )
> +{
> +  EFI_STATUS      Status;
> +  UINTN           Index;
> +  EFI_TPL         OriginalTPL;
> +
> +  if (!EfiAtRuntime ()) {
> +     OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +  } else {
> +    OriginalTPL = TPL_HIGH_LEVEL;
> +  }
> +
> +  Index = 0;
> +
> +  do {
> +    Status = FlashInstance->SpiFlashProtocol->EraseSingleBlock(BlockAddress);
> +    Index++;
> +  } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));
> +
> +  if (Index == NOR_FLASH_ERASE_RETRY) {
> +    DEBUG ((DEBUG_ERROR, "EraseSingleBlock(BlockAddress=0x%08x: Block\
> +      Locked Error (try to erase %d times)\n", BlockAddress, Index));

Please don't break the format string with \. just move it to a
separate line:

   DEBUG ((DEBUG_ERROR,
           "EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n",
           BlockAddress, Index));

I see this pattern again below.
If the intent was to print a line break, write '\n' without breaking
the format string. Or split the DEBUG up into two DEBUG statements.
Please apply in all instances below too.

> +  }
> +
> +  if (!EfiAtRuntime ()) {
> +    // Interruptions can resume.
> +    gBS->RestoreTPL (OriginalTPL);
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Readed the specified number of bytes from the form the block to output buffer.
> +
> +  @param[in]  FlashInstance        The pointer of FT_FVB_DEVICE instance.
> +
> +  @param[in]  Lba                  The starting logical block index to write to.
> +
> +  @param[in]  Offset               Offset into the block at which to begin writing.
> +
> +  @param[in]  BufferSizeInBytes    The number of bytes to be writed.
> +
> +  @param[out] Buffer               The pointer to a caller-allocated buffer that
> +                                   contains the source for the write.
> +
> +  @retval EFI_SUCCESS              FvbFlashRead() is executed successfully.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +FvbFlashRead (
> +  IN FT_FVB_DEVICE   *FlashInstance,
> +  IN EFI_LBA          Lba,
> +  IN UINTN            Offset,
> +  IN UINTN            BufferSizeInBytes,
> +  OUT VOID            *Buffer
> +  )
> +{
> +  UINTN Address;
> +
> +  Address = GET_DATA_OFFSET(FlashInstance->RegionBaseAddress, \

This is not a macro, you do not need the '\'.

> +              Lba, FlashInstance->Media.BlockSize)  + Offset;

Drop the double space.

> +
> +  if (BufferSizeInBytes == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  // The buffer must be valid
> +  if (Buffer == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return FlashInstance->SpiFlashProtocol->Read (Address, Buffer, BufferSizeInBytes);
> +}
> +
> +
> +/**
> +  Write a full or portion of a block. It must not span block boundaries; that is,
> +  Offset + *NumBytes <= FlashInstance->Media.BlockSize.
> +
> +  @param[in]  FlashInstance        The pointer of FT_FVB_DEVICE instance.
> +
> +  @param[in]  Lba                  The starting logical block index to write to.
> +
> +  @param[in]  Offset               Offset into the block at which to begin writing.
> +
> +  @param[in]  BufferSizeInBytes    The number of bytes to be writed.
> +
> +  @param[out] Buffer               The pointer to a caller-allocated buffer that
> +                                   contains the source for the write.
> +
> +  @retval EFI_SUCCESS              FvbWriteBlock() is executed successfully.
> +
> +  @retval EFI_BAD_BUFFER_SIZE      The write spaned block boundaries.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +FvbWriteBlock (
> +  IN FT_FVB_DEVICE   *FlashInstance,
> +  IN EFI_LBA          Lba,
> +  IN UINTN            Offset,
> +  IN UINTN            BufferSizeInBytes,
> +  IN UINT8            *Buffer
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINTN       BlockSize;
> +  UINTN       BlockAddress;
> +
> +  // Detect WriteDisabled state
> +  if (FlashInstance->Media.ReadOnly == TRUE) {
> +    DEBUG ((DEBUG_ERROR, "FvbWriteBlock: ERROR - Can not write: \
> +      Device is in WriteDisabled state.\n"));
> +    // It is in WriteDisabled state, return an error right away
> +    return EFI_ACCESS_DENIED;
> +  }
> +
> +  // Cache the block size to avoid de-referencing pointers all the time
> +  BlockSize = FlashInstance->Media.BlockSize;
> +
> +  // The write must not span block boundaries.
> +  // We need to check each variable individually because adding two large values together overflows.
> +  if ((Offset                       >= BlockSize) ||
> +      (BufferSizeInBytes            >  BlockSize) ||
> +      ((Offset + BufferSizeInBytes) >  BlockSize)) {
> +    DEBUG ((DEBUG_ERROR, "FvbWriteBlock: ERROR - EFI_BAD_BUFFER_SIZE: \
> +      (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, BufferSizeInBytes, BlockSize));
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  // We must have some bytes to write
> +  if (BufferSizeInBytes == 0) {
> +    DEBUG ((DEBUG_ERROR, "FvbWriteBlock: ERROR - EFI_BAD_BUFFER_SIZE: NumBytes == 0\n"));
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  // Check we did get some memory. Buffer is BlockSize.
> +  if (FlashInstance->ShadowBuffer == NULL) {
> +    DEBUG ((DEBUG_ERROR, "FvbWriteBlock: ERROR - ShadowBuffer is NULL!\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Write the word to NOR.
> +  //
> +  BlockAddress = GET_DATA_OFFSET (FlashInstance->RegionBaseAddress, Lba, FlashInstance->Media.BlockSize);
> +
> +  // Read NOR Flash data into shadow buffer
> +  Status = FlashInstance->SpiFlashProtocol->Read (BlockAddress, FlashInstance->ShadowBuffer, BlockSize);
> +  if (EFI_ERROR (Status)) {
> +    // Return one of the pre-approved error statuses
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  // Put the data at the appropriate location inside the buffer area
> +  CopyMem ((VOID*)((UINTN)FlashInstance->ShadowBuffer + Offset), Buffer, BufferSizeInBytes);
> +
> +  Status = FlashInstance->SpiFlashProtocol->EraseSingleBlock (BlockAddress);
> +  if (EFI_ERROR (Status)) {
> +    // Return one of the pre-approved error statuses
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  // Write the modified buffer back to the NorFlash
> +  Status = FlashInstance->SpiFlashProtocol->Write (BlockAddress, FlashInstance->ShadowBuffer, BlockSize);
> +  if (EFI_ERROR (Status)) {
> +    // Return one of the pre-approved error statuses
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Writes the specified number of bytes from the input buffer to the block.
> +
> +  @param[in] FlashInstance        The pointer of FT_FVB_DEVICE instance.
> +
> +  @param[in] Lba                  The starting logical block index to write to.
> +
> +  @param[in] Offset               Offset into the block at which to begin writing.
> +
> +  @param[in] BufferSizeInBytes    The number of bytes to be writed.
> +
> +  @param[in] Buffer               The pointer to a caller-allocated buffer that
> +                                  contains the source for the write.
> +
> +  @retval EFI_SUCCESS             FvbFlashWrite() is executed successfully.
> +
> +  @retval EFI_WRITE_PROTECTED     Flash state is in the WriteDisabled state.
> +
> +  @retval EFI_INVALID_PARAMETER   The pointer of Buffer is NULL.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +FvbFlashWrite (
> +  IN FT_FVB_DEVICE    *FlashInstance,
> +  IN EFI_LBA          Lba,
> +  IN UINTN            Offset,
> +  IN UINTN            BufferSizeInBytes,
> +  IN VOID             *Buffer
> +  )
> +{
> +  EFI_STATUS      Status;
> +  UINT32          BlockSize;
> +  UINT32          BlockOffset;
> +  UINTN           RemainingBytes;
> +  UINTN           WriteSize;
> +
> +  if (FlashInstance->Media.ReadOnly == TRUE) {
> +    return EFI_WRITE_PROTECTED;
> +  }
> +
> +  if (BufferSizeInBytes == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (Buffer == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status         = EFI_SUCCESS;
> +  BlockSize      = FlashInstance->Media.BlockSize;
> +  BlockOffset    = Offset;
> +  RemainingBytes = BufferSizeInBytes;
> +
> +  // The write must not span block boundaries.
> +  // We need to check each variable individually because adding
> +  // two large values together overflows.
> +  if (Offset >= BlockSize) {
> +    DEBUG ((DEBUG_ERROR, "FvbFlashWrite: ERROR - EFI_BAD_BUFFER_SIZE: \
> +      Offset=0x%x > BlockSize=0x%x\n", Offset, BlockSize));
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  // We must have some bytes to read
> +  // Write either all the remaining bytes, or the number of bytes that bring
> +  // us up to a block boundary, whichever is less.
> +  // (DiskOffset | (BlockSize - 1)) + 1) rounds DiskOffset up to the next
> +  // block boundary (even if it is already on one).
> +  WriteSize = MIN (RemainingBytes, BlockSize - BlockOffset);
> +
> +  do {
> +    Status = FvbWriteBlock (FlashInstance, Lba, BlockOffset, WriteSize, Buffer);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    // Now continue writing either all the remaining bytes or single blocks.
> +    RemainingBytes -= WriteSize;
> +    Buffer = (UINT8 *) Buffer + WriteSize;
> +    Lba++;
> +    BlockOffset = 0;
> +    WriteSize = MIN (RemainingBytes, BlockSize);
> +  } while (RemainingBytes);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Initialises the FV Header and Variable Store Header
> +  to support variable operations.
> +
> +  @param[in] Ptr       Location to initialise the headers.
> +
> +  @retval EFI_SUCCESS  FvbInitFvAndVariableStoreHeaders()
> +                       is executed successfully.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +FvbInitFvAndVariableStoreHeaders (
> +  IN FT_FVB_DEVICE *FlashInstance
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  VOID*                       Headers;
> +  UINTN                       HeadersLength;
> +  EFI_FIRMWARE_VOLUME_HEADER  *FirmwareVolumeHeader;
> +  VARIABLE_STORE_HEADER       *VariableStoreHeader;
> +
> +  HeadersLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY) \
> +                    + sizeof (VARIABLE_STORE_HEADER);

Lots of very long lines in this function.
Please wrap them all, and get rid of the '\'s.

> +  Headers = AllocateZeroPool (HeadersLength);
> +
> +  // FirmwareVolumeHeader->FvLength is declared to have the Variable area
> +  // AND the FTW working area AND the FTW Spare contiguous.
> +  ASSERT (PcdGet64 (PcdFlashNvStorageVariableBase64) + PcdGet32 (PcdFlashNvStorageVariableSize) \
> +           == PcdGet64 (PcdFlashNvStorageFtwWorkingBase64));
> +  ASSERT(PcdGet64 (PcdFlashNvStorageFtwWorkingBase64) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) \
> +           == PcdGet64 (PcdFlashNvStorageFtwSpareBase64));
> +
> +  // Check if the size of the area is at least one block size
> +  ASSERT((PcdGet32 (PcdFlashNvStorageVariableSize) > 0) && (PcdGet32 (PcdFlashNvStorageVariableSize) \
> +           / FlashInstance->Media.BlockSize > 0));
> +  ASSERT((PcdGet32 (PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) \
> +           / FlashInstance->Media.BlockSize > 0));
> +  ASSERT((PcdGet32 (PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32 (PcdFlashNvStorageFtwSpareSize) \
> +           / FlashInstance->Media.BlockSize > 0));
> +
> +  // Ensure the Variable area Base Addresses are aligned on a block size boundaries
> +  ASSERT (PcdGet64 (PcdFlashNvStorageVariableBase64) % FlashInstance->Media.BlockSize == 0);
> +  ASSERT (PcdGet64 (PcdFlashNvStorageFtwWorkingBase64) % FlashInstance->Media.BlockSize == 0);
> +  ASSERT (PcdGet64 (PcdFlashNvStorageFtwSpareBase64) % FlashInstance->Media.BlockSize == 0);
> +
> +  //
> +  // EFI_FIRMWARE_VOLUME_HEADER
> +  //
> +  FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers;
> +  CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid);
> +  FirmwareVolumeHeader->FvLength = FlashInstance->FvbSize;
> +
> +  FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE;
> +  FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) (
> +                                          EFI_FVB2_READ_ENABLED_CAP   | // Reads may be enabled
> +                                          EFI_FVB2_READ_STATUS        | // Reads are currently enabled
> +                                          EFI_FVB2_STICKY_WRITE       | // A block erase is required to
> +                                                                        // flip bits into EFI_FVB2_ERASE_POLARITY
> +                                          EFI_FVB2_MEMORY_MAPPED      | // It is memory mapped
> +                                          EFI_FVB2_ERASE_POLARITY     | // After erasure all bits take this value
> +                                          EFI_FVB2_WRITE_STATUS       | // Writes are currently enabled
> +                                          EFI_FVB2_WRITE_ENABLED_CAP    // Writes may be enabled

Please use a temporary variable to reduce the indentation here.

> +                                      );
> +
> +  FirmwareVolumeHeader->HeaderLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY);
> +  FirmwareVolumeHeader->Revision = EFI_FVH_REVISION;
> +  FirmwareVolumeHeader->BlockMap[0].NumBlocks = FlashInstance->Media.LastBlock + 1;
> +  FirmwareVolumeHeader->BlockMap[0].Length    = FlashInstance->Media.BlockSize;
> +  FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
> +  FirmwareVolumeHeader->BlockMap[1].Length    = 0;
> +  FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader, FirmwareVolumeHeader->HeaderLength);
> +
> +  //
> +  // VARIABLE_STORE_HEADER
> +  //
> +  VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength);
> +  CopyGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid);
> +  VariableStoreHeader->Size   = PcdGet32 (PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength;
> +  VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED;
> +  VariableStoreHeader->State  = VARIABLE_STORE_HEALTHY;
> +
> +  // Install the combined super-header in the NorFlash
> +  Status = FvbWrite (&FlashInstance->FvbProtocol, 0, 0, &HeadersLength, Headers);
> +
> +  FreePool (Headers);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Check the integrity of firmware volume header.
> +
> +  @param[in] FwVolHeader   A pointer to a firmware volume header
> +
> +  @retval  EFI_SUCCESS     The firmware volume is consistent
> +
> +  @retval  EFI_NOT_FOUND   The firmware volume has been corrupted.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +FvbValidateFvHeader (
> +  IN  FT_FVB_DEVICE *FlashInstance
> +  )
> +{
> +  UINT16                      Checksum;
> +  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;
> +  VARIABLE_STORE_HEADER       *VariableStoreHeader;
> +  UINTN                       VariableStoreLength;
> +  UINTN                       FvLength;
> +
> +  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)GET_DATA_OFFSET (FlashInstance->RegionBaseAddress, \
> +                  FlashInstance->StartLba, FlashInstance->Media.BlockSize);

More very long lines, with pointless '\' characters.

/
    Leif

> +  FvLength = FlashInstance->FvbSize;
> +
> +  //
> +  // Verify the header revision, header signature, length
> +  // Length of FvBlock cannot be 2**64-1
> +  // HeaderLength cannot be an odd number
> +  //
> +  if ((FwVolHeader->Revision  != EFI_FVH_REVISION)  ||
> +      (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
> +      (FwVolHeader->FvLength  != FvLength))
> +  {
> +    DEBUG ((DEBUG_ERROR, "ValidateFvHeader: No Firmware Volume header present\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  // Check the Firmware Volume Guid
> +  if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) {
> +    DEBUG ((DEBUG_ERROR, "ValidateFvHeader: Firmware Volume Guid non-compatible\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  // Verify the header checksum
> +  Checksum = CalculateSum16 ((UINT16*)FwVolHeader, FwVolHeader->HeaderLength);
> +  if (Checksum != 0) {
> +    DEBUG ((DEBUG_ERROR, "ValidateFvHeader: FV checksum is invalid (Checksum:0x%X)\n", Checksum));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)FwVolHeader + FwVolHeader->HeaderLength);
> +
> +  // Check the Variable Store Guid
> +  if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) &&
> +      !CompareGuid (&VariableStoreHeader->Signature,
> +                    &gEfiAuthenticatedVariableGuid)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Variable Store Guid non-compatible\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength;
> +  if (VariableStoreHeader->Size != VariableStoreLength) {
> +    DEBUG ((DEBUG_ERROR, "ValidateFvHeader: Variable Store Length does not match\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  The FvbGetAttributes() function retrieves the attributes and
> +  current settings of the block.
> +
> +  @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Attributes   Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and
> +                      current settings are returned.
> +                      Type EFI_FVB_ATTRIBUTES_2 is defined in
> +                      EFI_FIRMWARE_VOLUME_HEADER.
> +
> +  @retval EFI_SUCCESS The firmware volume attributes were returned.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvbGetAttributes (
> +  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL    *This,
> +  OUT       EFI_FVB_ATTRIBUTES_2                   *Attributes
> +  )
> +{
> +  EFI_FVB_ATTRIBUTES_2  FlashFvbAttributes;
> +  CONST FT_FVB_DEVICE    *FlashInstance;
> +
> +  FlashInstance = INSTANCE_FROM_FVB_THIS (This);
> +
> +  FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) (
> +
> +      EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
> +      EFI_FVB2_READ_STATUS      | // Reads are currently enabled
> +      EFI_FVB2_STICKY_WRITE     | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
> +      EFI_FVB2_MEMORY_MAPPED    | // It is memory mapped
> +      EFI_FVB2_ERASE_POLARITY     // After erasure all bits take this value (i.e. '1')
> +
> +      );
> +
> +  // Check if it is write protected
> +  if (FlashInstance->Media.ReadOnly != TRUE) {
> +
> +    FlashFvbAttributes = FlashFvbAttributes         |
> +                         EFI_FVB2_WRITE_STATUS      | // Writes are currently enabled
> +                         EFI_FVB2_WRITE_ENABLED_CAP;  // Writes may be enabled
> +  }
> +
> +  *Attributes = FlashFvbAttributes;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  The FvbSetAttributes() function sets configurable firmware volume attributes
> +  and returns the new settings of the firmware volume.
> +
> +  @param This                     EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Attributes               On input, Attributes is a pointer to
> +                                  EFI_FVB_ATTRIBUTES_2 that contains the desired
> +                                  firmware volume settings.
> +                                  On successful return, it contains the new
> +                                  settings of the firmware volume.
> +
> +  @retval EFI_SUCCESS             The firmware volume attributes were returned.
> +
> +  @retval EFI_INVALID_PARAMETER   The attributes requested are in conflict with
> +                                  the capabilities as declared in the firmware
> +                                  volume header.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvbSetAttributes (
> +  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL  *This,
> +  IN OUT    EFI_FVB_ATTRIBUTES_2                 *Attributes
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> +/**
> +  The FvbGetPhysicalAddress() function retrieves the base address of
> +  a memory-mapped firmware volume. This function should be called
> +  only for memory-mapped firmware volumes.
> +
> +  @param This               EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Address            Pointer to a caller-allocated
> +                            EFI_PHYSICAL_ADDRESS that, on successful
> +                            return from GetPhysicalAddress(), contains the
> +                            base address of the firmware volume.
> +
> +  @retval EFI_SUCCESS       The firmware volume base address was returned.
> +
> +  @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvbGetPhysicalAddress (
> +  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL  *This,
> +  OUT       EFI_PHYSICAL_ADDRESS                 *Address
> +  )
> +{
> +  ASSERT (Address != NULL);
> +
> +  *Address = mFlashNvStorageVariableBase;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  The FvbGetBlockSize() function retrieves the size of the requested
> +  block. It also returns the number of additional blocks with
> +  the identical size. The FvbGetBlockSize() function is used to
> +  retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
> +
> +
> +  @param This                     EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Lba                      Indicates the block whose size to return.
> +
> +  @param BlockSize                Pointer to a caller-allocated UINTN in which
> +                                  the size of the block is returned.
> +
> +  @param NumberOfBlocks           Pointer to a caller-allocated UINTN in
> +                                  which the number of consecutive blocks,
> +                                  starting with Lba, is returned. All
> +                                  blocks in this range have a size of
> +                                  BlockSize.
> +
> +
> +  @retval EFI_SUCCESS             The firmware volume base address was returned.
> +
> +  @retval EFI_INVALID_PARAMETER   The requested LBA is out of range.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvbGetBlockSize (
> +  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL  *This,
> +  IN        EFI_LBA                              Lba,
> +  OUT       UINTN                                *BlockSize,
> +  OUT       UINTN                                *NumberOfBlocks
> +  )
> +{
> +  EFI_STATUS Status;
> +  FT_FVB_DEVICE *FlashInstance;
> +
> +  FlashInstance = INSTANCE_FROM_FVB_THIS (This);
> +
> +  if (Lba > FlashInstance->Media.LastBlock) {
> +    Status = EFI_INVALID_PARAMETER;
> +  } else {
> +    // This is easy because in this platform each NorFlash device has equal sized blocks.
> +    *BlockSize = (UINTN) FlashInstance->Media.BlockSize;
> +    *NumberOfBlocks = (UINTN) (FlashInstance->Media.LastBlock - Lba + 1);
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Reads the specified number of bytes into a buffer from the specified block.
> +
> +  The FvbRead() function reads the requested number of bytes from the
> +  requested block and stores them in the provided buffer.
> +
> +  @param This                 EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Lba                  The starting logical block index from which to read.
> +
> +  @param Offset               Offset into the block at which to begin reading.
> +
> +  @param NumBytes             Pointer to a UINTN.
> +                              At entry, *NumBytes contains the total size of the
> +                              buffer.
> +                              At exit, *NumBytes contains the total number of
> +                              bytes read.
> +
> +  @param Buffer               Pointer to a caller-allocated buffer that will be
> +                              used to hold the data that is read.
> +
> +  @retval EFI_SUCCESS         The firmware volume was read successfully, and
> +                              contents are in Buffer.
> +
> +  @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary.
> +                              On output, NumBytes contains the total number of
> +                              bytes returned in Buffer.
> +
> +  @retval EFI_ACCESS_DENIED   The firmware volume is in the ReadDisabled state.
> +
> +  @retval EFI_DEVICE_ERROR    The block device is not functioning correctly and
> +                              could not be read.
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvbRead (
> +  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL   *This,
> +  IN        EFI_LBA                               Lba,
> +  IN        UINTN                                 Offset,
> +  IN OUT    UINTN                                 *NumBytes,
> +  IN OUT    UINT8                                 *Buffer
> +  )
> +{
> +  UINTN              BlockSize;
> +  FT_FVB_DEVICE      *FlashInstance;
> +  EFI_STATUS         Status;
> +
> +  FlashInstance = INSTANCE_FROM_FVB_THIS (This);
> +
> +  // Cache the block size to avoid de-referencing pointers all the time
> +  BlockSize = FlashInstance->Media.BlockSize;
> +
> +  // The read must not span block boundaries.
> +  // We need to check each variable individually because adding two large values together overflows.
> +  if ((Offset               >= BlockSize) ||
> +      (*NumBytes            >  BlockSize) ||
> +      ((Offset + *NumBytes) >  BlockSize)) {
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  // We must have some bytes to read
> +  if (*NumBytes == 0) {
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  Status = FvbFlashRead (FlashInstance, FlashInstance->StartLba + Lba, Offset, *NumBytes, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Writes the specified number of bytes from the input buffer to the block.
> +
> +  The FvbWrite() function writes the specified number of bytes from
> +  the provided buffer to the specified block and offset.
> +
> +  @param This                 EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Lba                  The starting logical block index to write to.
> +
> +  @param Offset               Offset into the block at which to begin writing.
> +
> +  @param NumBytes             The pointer to a UINTN.
> +                              At entry, *NumBytes contains the total size of the
> +                              buffer.
> +                              At exit, *NumBytes contains the total number of
> +                              bytes actually written.
> +
> +  @param Buffer               The pointer to a caller-allocated buffer that
> +                              contains the source for the write.
> +
> +  @retval EFI_SUCCESS         The firmware volume was written successfully.
> +
> +  @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary.
> +                              On output, NumBytes contains the total number of
> +                              bytes actually written.
> +
> +  @retval EFI_ACCESS_DENIED   The firmware volume is in the WriteDisabled state.
> +
> +  @retval EFI_DEVICE_ERROR    The block device is malfunctioning and could not be
> +                              written.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvbWrite (
> +  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL   *This,
> +  IN        EFI_LBA                               Lba,
> +  IN        UINTN                                 Offset,
> +  IN OUT    UINTN                                 *NumBytes,
> +  IN        UINT8                                 *Buffer
> +  )
> +{
> +  FT_FVB_DEVICE *FlashInstance;
> +
> +  FlashInstance = INSTANCE_FROM_FVB_THIS (This);
> +
> +  return FvbFlashWrite (FlashInstance, FlashInstance->StartLba + Lba, Offset, *NumBytes, Buffer);
> +}
> +
> +
> +/**
> +  Erases and initialises a firmware volume block.
> +
> +  The FvbEraseBlocks() function erases one or more blocks as denoted
> +  by the variable argument list.
> +
> +  @param This                     EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
> +                                  instance.
> +
> +  @param ...                      The variable argument list is a list of tuples.
> +                                  Each tuple describes a range of LBAs to erase
> +                                  and consists of the following:
> +                                  An EFI_LBA that indicates the starting LBA
> +                                  A UINTN that indicates the number of blocks
> +                                  to erase.
> +
> +                                  The list is terminated with an
> +                                  EFI_LBA_LIST_TERMINATOR.
> +
> +  @retval EFI_SUCCESS             The erase request successfully completed.
> +
> +  @retval EFI_ACCESS_DENIED       The firmware volume is in the WriteDisabled
> +                                  state.
> +
> +  @retval EFI_DEVICE_ERROR        The block device is not functioning correctly
> +                                  and could not be written.
> +                                  The firmware device may have been partially
> +                                  erased.
> +
> +  @retval EFI_INVALID_PARAMETER   One or more of the LBAs listed in the variable
> +                                  argument list do not exist in the firmware
> +                                  volume.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvbEraseBlocks (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
> +  ...
> +  )
> +{
> +  EFI_STATUS         Status;
> +  VA_LIST            Args;
> +  UINTN              BlockAddress; // Physical address of Lba to erase
> +  EFI_LBA            StartingLba;  // Lba from which we start erasing
> +  UINTN              NumOfLba;     // Number of Lba blocks to erase
> +  FT_FVB_DEVICE      *Instance;
> +
> +  Instance = INSTANCE_FROM_FVB_THIS (This);
> +
> +  Status = EFI_SUCCESS;
> +
> +  // Detect WriteDisabled state
> +  if (Instance->Media.ReadOnly == TRUE) {
> +    // Firmware volume is in WriteDisabled state
> +    DEBUG ((DEBUG_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n"));
> +    return EFI_ACCESS_DENIED;
> +  }
> +
> +  // Before erasing, check the entire list of parameters to ensure all specified blocks are valid
> +
> +  VA_START (Args, This);
> +  do {
> +    // Get the Lba from which we start erasing
> +    StartingLba = VA_ARG (Args, EFI_LBA);
> +
> +    // Have we reached the end of the list?
> +    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
> +      //Exit the while loop
> +      break;
> +    }
> +
> +    // How many Lba blocks are we requested to erase?
> +    NumOfLba = VA_ARG (Args, UINT32);
> +
> +    // All blocks must be within range
> +    if ((NumOfLba == 0) || ((Instance->StartLba + StartingLba + NumOfLba - 1) \
> +       > Instance->Media.LastBlock)) {
> +      VA_END (Args);
> +      DEBUG ((DEBUG_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n"));
> +      Status = EFI_INVALID_PARAMETER;
> +      goto EXIT;
> +    }
> +  } while (TRUE);
> +
> +  VA_END (Args);
> +
> +  //
> +  // To get here, all must be ok, so start erasing
> +  //
> +  VA_START (Args, This);
> +  do {
> +    // Get the Lba from which we start erasing
> +    StartingLba = VA_ARG (Args, EFI_LBA);
> +
> +    // Have we reached the end of the list?
> +    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
> +      // Exit the while loop
> +      break;
> +    }
> +
> +    // How many Lba blocks are we requested to erase?
> +    NumOfLba = VA_ARG (Args, UINT32);
> +
> +    // Go through each one and erase it
> +    while (NumOfLba > 0) {
> +      // Get the physical address of Lba to erase
> +      BlockAddress = GET_DATA_OFFSET (
> +                       Instance->RegionBaseAddress,
> +                       Instance->StartLba + StartingLba,
> +                       Instance->Media.BlockSize
> +                       );
> +
> +      // Erase it
> +      Status = FvbFlashEraseSingleBlock (Instance, BlockAddress);
> +      if (EFI_ERROR (Status)) {
> +        VA_END (Args);
> +        Status = EFI_DEVICE_ERROR;
> +        goto EXIT;
> +      }
> +
> +      // Move to the next Lba
> +      StartingLba++;
> +      NumOfLba--;
> +    }
> +  } while (TRUE);
> +
> +  VA_END (Args);
> +
> +EXIT:
> +  return Status;
> +}
> +
> +
> +/**
> +  This function inited the NorFlash instance.
> +
> +  @param[in][out] FlashInstance   The pointer of FT_FVB_DEVICE instance.
> +
> +  @retval EFI_SUCCESS             PhytNorFlashFvbInitialize() is executed successfully.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +PhytNorFlashFvbInitialize (
> +  IN OUT FT_FVB_DEVICE *FlashInstance
> +  )
> +{
> +  EFI_STATUS     Status;
> +  UINT32         FvbNumLba;
> +  EFI_BOOT_MODE  BootMode;
> +  UINTN          TotalFvbSize;
> +
> +  mFlashNvStorageVariableBase = FixedPcdGet64 (PcdFlashNvStorageVariableBase64);
> +
> +  // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
> +  Status = gDS->AddMemorySpace (
> +                  EfiGcdMemoryTypeMemoryMappedIo,
> +                  mFlashNvStorageVariableBase, FlashInstance->FvbSize,
> +                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = gDS->SetMemorySpaceAttributes (
> +                  mFlashNvStorageVariableBase, FlashInstance->FvbSize,
> +                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  TotalFvbSize = FlashInstance->FvbSize;
> +
> +  // Set the index of the first LBA for the FVB
> +  FlashInstance->StartLba = (PcdGet64 (PcdFlashNvStorageVariableBase64) - \
> +    FlashInstance->RegionBaseAddress) / FlashInstance->Media.BlockSize;
> +
> +  BootMode = GetBootModeHob ();
> +  if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
> +    Status = EFI_INVALID_PARAMETER;
> +  } else {
> +    // Determine if there is a valid header at the beginning of the NorFlash
> +    Status = FvbValidateFvHeader (FlashInstance);
> +  }
> +
> +  // Install the Default FVB header if required
> +  if (EFI_ERROR (Status)) {
> +    // There is no valid header, so time to install one.
> +    DEBUG ((DEBUG_ERROR,"NorFlashFvbInitialize: ERROR - The FVB Header is invalid. \
> +      Installing a correct one for this volume.\n"));
> +
> +    // Erase all the NorFlash that is reserved for variable storage
> +    FvbNumLba = TotalFvbSize / FlashInstance->Media.BlockSize;
> +
> +    Status = FvbEraseBlocks (&FlashInstance->FvbProtocol, (EFI_LBA)0,\
> +               FvbNumLba, EFI_LBA_LIST_TERMINATOR);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    // Install all appropriate headers
> +    Status = FvbInitFvAndVariableStoreHeaders (FlashInstance);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  The CreateInstance() function Create Fvb Instance.
> +
> +  @retval  EFI_SUCCESS         Create Instance successfully.
> +
> +  @retval  other               Create Instance failed.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +CreateInstance (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  NOR_FLASH_DEVICE_DESCRIPTION   *NorFlashDevice;
> +
> +  // Locate flash protocols
> +  Status = gBS->LocateProtocol (&gSpiNorFlashProtocolGuid,
> +                  NULL,
> +                  (VOID **)&FvbDevice->SpiFlashProtocol);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Cannot locate NorFlash protocol.\n"));
> +    return Status;
> +  }
> +
> +  NorFlashDevice = AllocateRuntimePool (sizeof (NOR_FLASH_DEVICE_DESCRIPTION));
> +  if (NorFlashDevice == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Cannot Allocate NorFlashDevice Pool.\n"));
> +    return Status;
> +  }
> +
> +  Status = FvbDevice->SpiFlashProtocol->GetDevices (NorFlashDevice);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = FvbDevice->SpiFlashProtocol->Initialization();
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  FvbDevice->DeviceBaseAddress = NorFlashDevice->DeviceBaseAddress;
> +  FvbDevice->RegionBaseAddress = NorFlashDevice->RegionBaseAddress;
> +  FvbDevice->Size = NorFlashDevice->Size;
> +
> +  FvbDevice->Media.MediaId = 0;
> +  FvbDevice->Media.BlockSize = NorFlashDevice->BlockSize;
> +  FvbDevice->Media.LastBlock = (FvbDevice->Size / FvbDevice->Media.BlockSize) - 1;
> +  FvbDevice->FvbSize = PcdGet32 (PcdFlashNvStorageVariableSize) +
> +                       PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
> +                       PcdGet32 (PcdFlashNvStorageFtwSpareSize);
> +
> +  CopyGuid (&FvbDevice->DevicePath.Vendor.Guid, &NorFlashDevice->Guid);
> +
> +  FvbDevice->ShadowBuffer = AllocateRuntimePool (FvbDevice->Media.BlockSize);
> +  if (FvbDevice->ShadowBuffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +             &FvbDevice->Handle,
> +             &gEfiDevicePathProtocolGuid, &FvbDevice->DevicePath,
> +             &gEfiFirmwareVolumeBlockProtocolGuid, &FvbDevice->FvbProtocol,
> +             NULL
> +             );
> +  if (EFI_ERROR (Status)) {
> +    FreePool (FvbDevice);
> +    return Status;
> +  }
> +
> +  Status = PhytNorFlashFvbInitialize (FvbDevice);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "PhytNorFlashFvbInitialize: Fail to init NorFlash devices\n"));
> +    return Status;
> +  }
> +
> +  FreePool (NorFlashDevice);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Fixup internal data so that EFI can be call in virtual mode.
> +  Call the passed in Child Notify event and convert any pointers
> +  in lib to virtual mode.
> +
> +  @param[in]    Event   The Event that is being processed.
> +
> +  @param[in]    Context Event Context.
> +
> +  @retval       None.
> +
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +FvbVirtualNotifyEvent (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  )
> +{
> +  // Convert SpiFlashProtocol
> +  EfiConvertPointer (0x0, (VOID**)&FvbDevice->SpiFlashProtocol->Erase);
> +  EfiConvertPointer (0x0, (VOID**)&FvbDevice->SpiFlashProtocol->Write);
> +  EfiConvertPointer (0x0, (VOID**)&FvbDevice->SpiFlashProtocol->Read);
> +  EfiConvertPointer (0x0, (VOID**)&FvbDevice->SpiFlashProtocol->GetDevices);
> +  EfiConvertPointer (0x0, (VOID**)&FvbDevice->SpiFlashProtocol->Initialization);
> +  EfiConvertPointer (0x0, (VOID**)&FvbDevice->SpiFlashProtocol->EraseSingleBlock);
> +  EfiConvertPointer (0x0, (VOID**)&FvbDevice->SpiFlashProtocol);
> +
> +  EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase);
> +  EfiConvertPointer (0x0, (VOID**)&FvbDevice);
> +
> +  return;
> +}
> +
> +
> +/**
> +  This function is the entrypoint of the fvb driver.
> +
> +  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
> +
> +  @param[in] SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS       The entry point is executed successfully.
> +
> +  @retval other             Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvbEntryPoint (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE    *SystemTable
> +  )
> +{
> +  EFI_STATUS                     Status;
> +
> +  FvbDevice = AllocateRuntimeCopyPool (sizeof (FvbFlashInstanceTemplate), \
> +                &FvbFlashInstanceTemplate);
> +  if (FvbDevice == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Cannot allocate memory\n", __FUNCTION__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Status = CreateInstance ();
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "CreateInstance: Fail to create instance for NorFlash\n"));
> +  }
> +
> +//
> +// Register for the virtual address change event
> +//
> +  Status = gBS->CreateEventEx (
> +             EVT_NOTIFY_SIGNAL,
> +             TPL_NOTIFY,
> +             FvbVirtualNotifyEvent,
> +             NULL,
> +             &gEfiEventVirtualAddressChangeGuid,
> +             &FvbVirtualAddrChangeEvent
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> -- 
> 2.25.1
> 

  parent reply	other threads:[~2021-02-10 19:33 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20210205100630.46848-1-jialing@phytium.com.cn>
     [not found] ` <20210205100630.46848-13-jialing@phytium.com.cn>
2021-02-10 15:24   ` [PATCH v1 01/10] Silicon/Phytium: Added PlatformLib to FT2000/4 Leif Lindholm
2021-02-18  2:47     ` 贾玲
2021-02-18 19:07       ` Leif Lindholm
     [not found] ` <20210205100630.46848-14-jialing@phytium.com.cn>
2021-02-10 18:51   ` [PATCH v1 02/10] Silicon/Phytium: Added Acpi support " Leif Lindholm
     [not found] ` <20210205100630.46848-15-jialing@phytium.com.cn>
2021-02-10 18:52   ` [PATCH v1 03/10] Silicon/Phytium: Added SMBIOS " Leif Lindholm
     [not found] ` <20210205100630.46848-16-jialing@phytium.com.cn>
2021-02-10 18:59   ` [PATCH v1 04/10] Silicon/Phytium: Added PciSegmentLib " Leif Lindholm
     [not found] ` <20210205100630.46848-17-jialing@phytium.com.cn>
2021-02-10 19:04   ` [PATCH v1 05/10] Silicon/Phytium: Added PciHostBridgeLib " Leif Lindholm
     [not found] ` <20210205100630.46848-18-jialing@phytium.com.cn>
2021-02-10 19:06   ` [PATCH v1 06/10] Silicon/Phytium: Added Spi driver support " Leif Lindholm
     [not found] ` <20210205100630.46848-19-jialing@phytium.com.cn>
2021-02-10 19:23   ` [PATCH v1 07/10] Silicon/Phytium: Added flash driver support to Phytium Silicon Leif Lindholm
     [not found] ` <20210205100630.46848-20-jialing@phytium.com.cn>
2021-02-10 19:33   ` Leif Lindholm [this message]
     [not found] ` <20210205100630.46848-21-jialing@phytium.com.cn>
2021-02-10 19:40   ` [PATCH v1 09/10] Silicon/Phytium: Added Rtc driver to FT2000/4 Leif Lindholm
     [not found] ` <20210205100630.46848-22-jialing@phytium.com.cn>
2021-02-10 19:41   ` [PATCH v1 10/10] Maintainers.txt: Added maintainers and reviewers for the DurianPkg Leif Lindholm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210210193352.GT1664@vanye \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox