public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Guo Dong" <guo.dong@intel.com>
To: "Ni, Ray" <ray.ni@intel.com>,
	"mikuback@linux.microsoft.com" <mikuback@linux.microsoft.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>
Subject: Re: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI FVB services
Date: Tue, 20 Apr 2021 03:00:10 +0000	[thread overview]
Message-ID: <BYAPR11MB36220D06FF5DCFCFE9466A899E489@BYAPR11MB3622.namprd11.prod.outlook.com> (raw)
In-Reply-To: <CO1PR11MB4930517882D8481667C3DC608C4C9@CO1PR11MB4930.namprd11.prod.outlook.com>


Hi Ray,

This patch is about FVB module change. It is not related with SPI since it depends on SPI library.
The SPI hardware sequence could be used in SPI library.
I reviewed this patch, I think it is OK to replace the one used in existing platform FVB driver.

Thanks,
Guo

> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Friday, April 16, 2021 4:18 AM
> To: mikuback@linux.microsoft.com; devel@edk2.groups.io; Dong, Guo
> <guo.dong@intel.com>
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>
> Subject: RE: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI
> FVB services
> 
> Guo,
> I remember you mentioned to me there is a standard way to manipulate the
> flash storage because there is a HW between the SW and the real flash that
> does the command translation.
> Is this change related to the standard way what you mentioned to me?
> If yes, can you please help to review and provide comments?
> 
> Michael,
> Having a universal implementation for SPI access is wonderful! Can you
> please share the documentation that explain the Intel Serial Flash Interface
> Compatibility spec?
> 
> > -----Original Message-----
> > From: mikuback@linux.microsoft.com <mikuback@linux.microsoft.com>
> > Sent: Friday, April 16, 2021 10:31 AM
> > To: devel@edk2.groups.io
> > Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>
> > Subject: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI
> FVB services
> >
> > From: Michael Kubacki <michael.kubacki@microsoft.com>
> >
> > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3307
> >
> > Adds a Traditional MM and Standalone MM SPI FVB Service driver to
> > IntelSiliconPkg. These drivers produce the firmware volume block
> > protocol for SPI flash devices compliant with the Intel Serial
> > Flash Interface Compatibility Specification.
> >
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> > Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
> > ---
> >  Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c
> |  94 ++
> >
> Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCom
> mon.c         | 903 ++++++++++++++++++++
> >
> Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.
> c             | 271 ++++++
> >
> Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceStan
> daloneMm.c   |  32 +
> >
> Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTradi
> tionalMm.c  |  32 +
> >
> Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCom
> mon.h         | 158 ++++
> >
> Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.
> h             |  22 +
> >
> Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm
> .inf          |  68 ++
> >
> Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceStan
> daloneMm.inf |  67 ++
> >  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc                                       |  11 +
> >  10 files changed, 1658 insertions(+)
> >
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c
> > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c
> > new file mode 100644
> > index 000000000000..7f2678fa9e5a
> > --- /dev/null
> > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c
> > @@ -0,0 +1,94 @@
> > +/**@file
> > +  Defines data structure that is the volume header found.
> > +  These data is intent to decouple FVB driver with FV header.
> > +
> > +Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "SpiFvbServiceCommon.h"
> > +
> > +#define FIRMWARE_BLOCK_SIZE         0x10000
> > +#define FVB_MEDIA_BLOCK_SIZE        FIRMWARE_BLOCK_SIZE
> > +
> > +#define NV_STORAGE_BASE_ADDRESS
> FixedPcdGet32(PcdFlashNvStorageVariableBase)
> > +#define SYSTEM_NV_BLOCK_NUM
> ((FixedPcdGet32(PcdFlashNvStorageVariableSize)+
> > FixedPcdGet32(PcdFlashNvStorageFtwWorkingSize) +
> FixedPcdGet32(PcdFlashNvStorageFtwSpareSize))/
> > FVB_MEDIA_BLOCK_SIZE)
> > +
> > +typedef struct {
> > +  EFI_PHYSICAL_ADDRESS        BaseAddress;
> > +  EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
> > +  EFI_FV_BLOCK_MAP_ENTRY      End[1];
> > +} EFI_FVB2_MEDIA_INFO;
> > +
> > +//
> > +// This data structure contains a template of all correct FV headers, which
> is used to restore
> > +// Fv header if it's corrupted.
> > +//
> > +EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = {
> > +  //
> > +  // Systen NvStorage FVB
> > +  //
> > +  {
> > +    NV_STORAGE_BASE_ADDRESS,
> > +    {
> > +      {0,}, //ZeroVector[16]
> > +      EFI_SYSTEM_NV_DATA_FV_GUID,
> > +      FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM,
> > +      EFI_FVH_SIGNATURE,
> > +      0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for
> details on EFI_FVB_ATTRIBUTES_2
> > +      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof
> (EFI_FV_BLOCK_MAP_ENTRY),
> > +      0,    //CheckSum which will be calucated dynamically.
> > +      0,    //ExtHeaderOffset
> > +      {0,}, //Reserved[1]
> > +      2,    //Revision
> > +      {
> > +        {
> > +          SYSTEM_NV_BLOCK_NUM,
> > +          FVB_MEDIA_BLOCK_SIZE,
> > +        }
> > +      }
> > +    },
> > +    {
> > +      {
> > +        0,
> > +        0
> > +      }
> > +    }
> > +  }
> > +};
> > +
> > +EFI_STATUS
> > +GetFvbInfo (
> > +  IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
> > +  OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
> > +  )
> > +{
> > +  UINTN                       Index;
> > +  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
> > +
> > +  for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof
> (EFI_FVB2_MEDIA_INFO); Index++) {
> > +    if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) {
> > +      FvHeader = &mPlatformFvbMediaInfo[Index].FvbInfo;
> > +
> > +      //
> > +      // Update the checksum value of FV header.
> > +      //
> > +      FvHeader->Checksum = CalculateCheckSum16 ( (UINT16 *) FvHeader,
> FvHeader->HeaderLength);
> > +
> > +      *FvbInfo = FvHeader;
> > +
> > +      DEBUG ((DEBUG_INFO, "BaseAddr: 0x%lx \n", FvBaseAddress));
> > +      DEBUG ((DEBUG_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
> > +      DEBUG ((DEBUG_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)-
> >HeaderLength));
> > +      DEBUG ((DEBUG_INFO, "Header Checksum: 0x%X\n", (*FvbInfo)-
> >Checksum));
> > +      DEBUG ((DEBUG_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n",
> (*FvbInfo)->BlockMap[0].NumBlocks));
> > +      DEBUG ((DEBUG_INFO, "FvBlockMap[0].BlockLength: 0x%x \n",
> (*FvbInfo)->BlockMap[0].Length));
> > +      DEBUG ((DEBUG_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n",
> (*FvbInfo)->BlockMap[1].NumBlocks));
> > +      DEBUG ((DEBUG_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n",
> (*FvbInfo)->BlockMap[1].Length));
> > +
> > +      return EFI_SUCCESS;
> > +    }
> > +  }
> > +  return EFI_NOT_FOUND;
> > +}
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
> mmon.c
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
> mmon.c
> > new file mode 100644
> > index 000000000000..dab818e98087
> > --- /dev/null
> > +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
> mmon.c
> > @@ -0,0 +1,903 @@
> > +/** @file
> > +  Common driver source for several Serial Flash devices
> > +  which are compliant with the Intel(R) Serial Flash Interface Compatibility
> Specification.
> > +
> > +Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "SpiFvbServiceCommon.h"
> > +
> > +//
> > +// Global variable for this FVB driver  which contains
> > +// the private data of all firmware volume block instances
> > +//
> > +FVB_GLOBAL   mFvbModuleGlobal;
> > +
> > +//
> > +// This platform driver knows there are multiple FVs on FD.
> > +// Now we only provide FVs on Variable region and MicorCode region for
> performance issue.
> > +//
> > +FV_INFO mPlatformFvBaseAddress[] = {
> > +  {0, 0}, // {FixedPcdGet32(PcdFlashNvStorageVariableBase),
> FixedPcdGet32(PcdFlashNvStorageVariableSize)},
> > +  {0, 0}, // {FixedPcdGet32(PcdFlashMicrocodeFvBase),
> FixedPcdGet32(PcdFlashMicrocodeFvSize)},
> > +  {0, 0}
> > +};
> > +
> > +FV_INFO mPlatformDefaultBaseAddress[] = {
> > +  {0, 0}, // {FixedPcdGet32(PcdFlashNvStorageVariableBase),
> FixedPcdGet32(PcdFlashNvStorageVariableSize)},
> > +  {0, 0}, // {FixedPcdGet32(PcdFlashMicrocodeFvBase),
> FixedPcdGet32(PcdFlashMicrocodeFvSize)},
> > +  {0, 0}
> > +};
> > +
> > +FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
> > +  {
> > +    {
> > +      HARDWARE_DEVICE_PATH,
> > +      HW_MEMMAP_DP,
> > +      {
> > +        (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
> > +        (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
> > +      }
> > +    },
> > +    EfiMemoryMappedIO,
> > +    (EFI_PHYSICAL_ADDRESS) 0,
> > +    (EFI_PHYSICAL_ADDRESS) 0,
> > +  },
> > +  {
> > +    END_DEVICE_PATH_TYPE,
> > +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> > +    {
> > +      END_DEVICE_PATH_LENGTH,
> > +      0
> > +    }
> > +  }
> > +};
> > +
> > +FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {
> > +  {
> > +    {
> > +      MEDIA_DEVICE_PATH,
> > +      MEDIA_PIWG_FW_VOL_DP,
> > +      {
> > +        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
> > +        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
> > +      }
> > +    },
> > +    { 0 }
> > +  },
> > +  {
> > +    END_DEVICE_PATH_TYPE,
> > +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> > +    {
> > +      END_DEVICE_PATH_LENGTH,
> > +      0
> > +    }
> > +  }
> > +};
> > +
> > +//
> > +// Template structure used when installing FVB protocol
> > +//
> > +EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFvbProtocolTemplate = {
> > +  FvbProtocolGetAttributes,
> > +  FvbProtocolSetAttributes,
> > +  FvbProtocolGetPhysicalAddress,
> > +  FvbProtocolGetBlockSize,
> > +  FvbProtocolRead,
> > +  FvbProtocolWrite,
> > +  FvbProtocolEraseBlocks,
> > +  NULL
> > +};
> > +
> > +/**
> > +  Get the EFI_FVB_ATTRIBUTES_2 of a FV.
> > +
> > +  @param[in]  FvbInstance The pointer to the EFI_FVB_INSTANCE.
> > +
> > +  @return     Attributes of the FV identified by FvbInstance.
> > +
> > +**/
> > +EFI_FVB_ATTRIBUTES_2
> > +FvbGetVolumeAttributes (
> > +  IN EFI_FVB_INSTANCE         *FvbInstance
> > +  )
> > +{
> > +  return FvbInstance->FvHeader.Attributes;
> > +}
> > +
> > +/**
> > +  Retrieves the starting address of an LBA in an FV. It also
> > +  return a few other attribut of the FV.
> > +
> > +  @param[in]  FvbInstance     The pointer to the EFI_FVB_INSTANCE.
> > +  @param[in]  Lba             The logical block address
> > +  @param[out] LbaAddress      On output, contains the physical starting
> address
> > +                              of the Lba
> > +  @param[out] LbaLength       On output, contains the length of the block
> > +  @param[out] NumOfBlocks     A 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 Successfully returns
> > +  @retval   EFI_INVALID_PARAMETER Instance not found
> > +
> > +**/
> > +EFI_STATUS
> > +FvbGetLbaAddress (
> > +  IN  EFI_FVB_INSTANCE                    *FvbInstance,
> > +  IN  EFI_LBA                             Lba,
> > +  OUT UINTN                               *LbaAddress,
> > +  OUT UINTN                               *LbaLength,
> > +  OUT UINTN                               *NumOfBlocks
> > +  )
> > +{
> > +  UINT32                                  NumBlocks;
> > +  UINT32                                  BlockLength;
> > +  UINTN                                   Offset;
> > +  EFI_LBA                                 StartLba;
> > +  EFI_LBA                                 NextLba;
> > +  EFI_FV_BLOCK_MAP_ENTRY                  *BlockMap;
> > +
> > +  StartLba  = 0;
> > +  Offset    = 0;
> > +  BlockMap  = &(FvbInstance->FvHeader.BlockMap[0]);
> > +
> > +  //
> > +  // Parse the blockmap of the FV to find which map entry the Lba belongs
> to
> > +  //
> > +  while (TRUE) {
> > +    NumBlocks   = BlockMap->NumBlocks;
> > +    BlockLength = BlockMap->Length;
> > +
> > +    if ( NumBlocks == 0 || BlockLength == 0) {
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +
> > +    NextLba = StartLba + NumBlocks;
> > +
> > +    //
> > +    // The map entry found
> > +    //
> > +    if (Lba >= StartLba && Lba < NextLba) {
> > +      Offset = Offset + (UINTN)MultU64x32((Lba - StartLba), BlockLength);
> > +      if (LbaAddress ) {
> > +        *LbaAddress = FvbInstance->FvBase + Offset;
> > +      }
> > +
> > +      if (LbaLength ) {
> > +        *LbaLength = BlockLength;
> > +      }
> > +
> > +      if (NumOfBlocks ) {
> > +        *NumOfBlocks = (UINTN)(NextLba - Lba);
> > +      }
> > +      return EFI_SUCCESS;
> > +    }
> > +
> > +    StartLba  = NextLba;
> > +    Offset    = Offset + NumBlocks * BlockLength;
> > +    BlockMap++;
> > +  }
> > +}
> > +
> > +/**
> > +  Reads specified number of bytes into a buffer from the specified block.
> > +
> > +  @param[in]      FvbInstance           The pointer to the EFI_FVB_INSTANCE
> > +  @param[in]      Lba                   The logical block address to be read from
> > +  @param[in]      BlockOffset           Offset into the block at which to begin
> reading
> > +  @param[in]      NumBytes              Pointer that on input contains the total
> size of
> > +                                        the buffer. On output, it contains the total number
> > +                                        of bytes read
> > +  @param[in]      Buffer                Pointer to a caller allocated buffer that will
> be
> > +                                        used to hold the data read
> > +
> > +
> > +  @retval         EFI_SUCCESS           The firmware volume was read
> successfully and
> > +                                        contents are in Buffer
> > +  @retval         EFI_BAD_BUFFER_SIZE   Read attempted across a 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
> > +  @retval         EFI_INVALID_PARAMETER Instance not found, or NumBytes,
> Buffer are NULL
> > +
> > +**/
> > +EFI_STATUS
> > +FvbReadBlock (
> > +  IN EFI_FVB_INSTANCE                     *FvbInstance,
> > +  IN EFI_LBA                              Lba,
> > +  IN UINTN                                BlockOffset,
> > +  IN OUT UINTN                            *NumBytes,
> > +  IN UINT8                                *Buffer
> > +  )
> > +{
> > +  EFI_FVB_ATTRIBUTES_2                    Attributes;
> > +  UINTN                                   LbaAddress;
> > +  UINTN                                   LbaLength;
> > +  EFI_STATUS                              Status;
> > +  BOOLEAN                                 BadBufferSize = FALSE;
> > +
> > +  if ((NumBytes == NULL) || (Buffer == NULL)) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +  if (*NumBytes == 0) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  Status = FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress,
> &LbaLength, NULL);
> > +  if (EFI_ERROR(Status)) {
> > +    return Status;
> > +  }
> > +
> > +  Attributes = FvbGetVolumeAttributes (FvbInstance);
> > +
> > +  if ((Attributes & EFI_FVB2_READ_STATUS) == 0) {
> > +    return EFI_ACCESS_DENIED;
> > +  }
> > +
> > +  if (BlockOffset > LbaLength) {
> > +   return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (LbaLength < (*NumBytes + BlockOffset)) {
> > +    DEBUG ((DEBUG_INFO,
> > +      "FvReadBlock: Reducing Numbytes from 0x%x to 0x%x\n",
> > +      *NumBytes,
> > +      (UINT32)(LbaLength - BlockOffset))
> > +      );
> > +    *NumBytes     = (UINT32) (LbaLength - BlockOffset);
> > +    BadBufferSize = TRUE;
> > +  }
> > +
> > +  Status = SpiFlashRead (LbaAddress + BlockOffset, (UINT32 *)NumBytes,
> Buffer);
> > +
> > +  if (!EFI_ERROR (Status) && BadBufferSize) {
> > +    return EFI_BAD_BUFFER_SIZE;
> > +  } else {
> > +    return Status;
> > +  }
> > +}
> > +
> > +/**
> > +  Writes specified number of bytes from the input buffer to the block.
> > +
> > +  @param[in]  FvbInstance           The pointer to the EFI_FVB_INSTANCE
> > +  @param[in]  Lba                   The starting logical block index to write to
> > +  @param[in]  BlockOffset           Offset into the block at which to begin
> writing
> > +  @param[in]  NumBytes              Pointer that on input contains the total
> size of
> > +                                    the buffer. On output, it contains the total number
> > +                                    of bytes actually written
> > +  @param[in]  Buffer                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   Write attempted across a 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 not functioning
> correctly and
> > +                                    could not be written
> > +  @retval     EFI_INVALID_PARAMETER Instance not found, or NumBytes,
> Buffer are NULL
> > +
> > +**/
> > +EFI_STATUS
> > +FvbWriteBlock (
> > +  IN EFI_FVB_INSTANCE                     *FvbInstance,
> > +  IN EFI_LBA                              Lba,
> > +  IN UINTN                                BlockOffset,
> > +  IN OUT UINTN                            *NumBytes,
> > +  IN UINT8                                *Buffer
> > +  )
> > +{
> > +  EFI_FVB_ATTRIBUTES_2                    Attributes;
> > +  UINTN                                   LbaAddress;
> > +  UINTN                                   LbaLength;
> > +  EFI_STATUS                              Status;
> > +  BOOLEAN                                 BadBufferSize = FALSE;
> > +
> > +  if ((NumBytes == NULL) || (Buffer == NULL)) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +  if (*NumBytes == 0) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  Status = FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress,
> &LbaLength, NULL);
> > +  if (EFI_ERROR(Status)) {
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Check if the FV is write enabled
> > +  //
> > +  Attributes = FvbGetVolumeAttributes (FvbInstance);
> > +  if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0)  {
> > +    return EFI_ACCESS_DENIED;
> > +  }
> > +
> > +  //
> > +  // Perform boundary checks and adjust NumBytes
> > +  //
> > +  if (BlockOffset > LbaLength) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (LbaLength < (*NumBytes + BlockOffset)) {
> > +    DEBUG ((DEBUG_INFO,
> > +      "FvWriteBlock: Reducing Numbytes from 0x%x to 0x%x\n",
> > +      *NumBytes,
> > +      (UINT32)(LbaLength - BlockOffset))
> > +      );
> > +    *NumBytes     = (UINT32) (LbaLength - BlockOffset);
> > +    BadBufferSize = TRUE;
> > +  }
> > +
> > +  Status = SpiFlashWrite (LbaAddress + BlockOffset, (UINT32 *)NumBytes,
> Buffer);
> > +  if (EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  Status = SpiFlashLock ();
> > +  if (EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  WriteBackInvalidateDataCacheRange ((VOID *) (LbaAddress +
> BlockOffset), *NumBytes);
> > +
> > +  if (!EFI_ERROR (Status) && BadBufferSize) {
> > +    return EFI_BAD_BUFFER_SIZE;
> > +  } else {
> > +    return Status;
> > +  }
> > +}
> > +
> > +
> > +
> > +/**
> > +  Erases and initializes a firmware volume block.
> > +
> > +  @param[in]    FvbInstance       The pointer to the EFI_FVB_INSTANCE
> > +  @param[in]    Lba               The logical block index to be erased
> > +
> > +  @retval   EFI_SUCCESS           The erase request was 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. Firmware device may have been
> > +                                  partially erased
> > +  @retval   EFI_INVALID_PARAMETER Instance not found
> > +
> > +**/
> > +EFI_STATUS
> > +FvbEraseBlock (
> > +  IN EFI_FVB_INSTANCE           *FvbInstance,
> > +  IN EFI_LBA                    Lba
> > +  )
> > +{
> > +
> > +  EFI_FVB_ATTRIBUTES_2                    Attributes;
> > +  UINTN                                   LbaAddress;
> > +  UINTN                                   LbaLength;
> > +  EFI_STATUS                              Status;
> > +
> > +  //
> > +  // Check if the FV is write enabled
> > +  //
> > +  Attributes = FvbGetVolumeAttributes (FvbInstance);
> > +
> > +  if( (Attributes & EFI_FVB2_WRITE_STATUS) == 0)  {
> > +    return EFI_ACCESS_DENIED;
> > +  }
> > +
> > +  //
> > +  // Get the starting address of the block for erase.
> > +  //
> > +  Status = FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress,
> &LbaLength, NULL);
> > +  if (EFI_ERROR(Status)) {
> > +    return Status;
> > +  }
> > +
> > +  Status = SpiFlashBlockErase (LbaAddress, &LbaLength);
> > +  if (EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  Status = SpiFlashLock ();
> > +  if (EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  WriteBackInvalidateDataCacheRange ((VOID *) LbaAddress, LbaLength);
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Modifies the current settings of the firmware volume according to the
> > +  input parameter, and returns the new setting of the volume
> > +
> > +  @param[in]  FvbInstance           The pointer to the EFI_FVB_INSTANCE.
> > +  @param[in]  Attributes            On input, it is a pointer to
> EFI_FVB_ATTRIBUTES_2
> > +                                    containing the desired firmware volume settings.
> > +                                    On successful return, it contains the new settings
> > +                                    of the firmware volume
> > +
> > +  @retval     EFI_SUCCESS           Successfully returns
> > +  @retval     EFI_ACCESS_DENIED     The volume setting is locked and
> cannot be modified
> > +  @retval     EFI_INVALID_PARAMETER Instance not found, or The
> attributes requested are
> > +                                    in conflict with the capabilities as declared in the
> > +                                    firmware volume header
> > +
> > +**/
> > +EFI_STATUS
> > +FvbSetVolumeAttributes (
> > +  IN EFI_FVB_INSTANCE                     *FvbInstance,
> > +  IN OUT EFI_FVB_ATTRIBUTES_2             *Attributes
> > +  )
> > +{
> > +  EFI_FVB_ATTRIBUTES_2                      OldAttributes;
> > +  EFI_FVB_ATTRIBUTES_2                      *AttribPtr;
> > +  EFI_FVB_ATTRIBUTES_2                      UnchangedAttributes;
> > +  UINT32                                    Capabilities;
> > +  UINT32                                    OldStatus, NewStatus;
> > +
> > +  AttribPtr     = (EFI_FVB_ATTRIBUTES_2 *) &(FvbInstance-
> >FvHeader.Attributes);
> > +  OldAttributes = *AttribPtr;
> > +  Capabilities  = OldAttributes & EFI_FVB2_CAPABILITIES;
> > +  OldStatus     = OldAttributes & EFI_FVB2_STATUS;
> > +  NewStatus     = *Attributes & EFI_FVB2_STATUS;
> > +
> > +  UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP  | \
> > +                        EFI_FVB2_READ_ENABLED_CAP   | \
> > +                        EFI_FVB2_WRITE_DISABLED_CAP | \
> > +                        EFI_FVB2_WRITE_ENABLED_CAP  | \
> > +                        EFI_FVB2_LOCK_CAP           | \
> > +                        EFI_FVB2_STICKY_WRITE       | \
> > +                        EFI_FVB2_MEMORY_MAPPED      | \
> > +                        EFI_FVB2_ERASE_POLARITY     | \
> > +                        EFI_FVB2_READ_LOCK_CAP      | \
> > +                        EFI_FVB2_WRITE_LOCK_CAP     | \
> > +                        EFI_FVB2_ALIGNMENT;
> > +
> > +  //
> > +  // Some attributes of FV is read only can *not* be set
> > +  //
> > +  if ((OldAttributes & UnchangedAttributes) ^ (*Attributes &
> UnchangedAttributes)) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // If firmware volume is locked, no status bit can be updated
> > +  //
> > +  if ( OldAttributes & EFI_FVB2_LOCK_STATUS ) {
> > +    if ( OldStatus ^ NewStatus ) {
> > +      return EFI_ACCESS_DENIED;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Test read disable
> > +  //
> > +  if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) {
> > +    if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) {
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Test read enable
> > +  //
> > +  if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) {
> > +    if (NewStatus & EFI_FVB2_READ_STATUS) {
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Test write disable
> > +  //
> > +  if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) {
> > +    if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) {
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Test write enable
> > +  //
> > +  if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) {
> > +    if (NewStatus & EFI_FVB2_WRITE_STATUS) {
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Test lock
> > +  //
> > +  if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) {
> > +    if (NewStatus & EFI_FVB2_LOCK_STATUS) {
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +  }
> > +
> > +  *AttribPtr  = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS));
> > +  *AttribPtr  = (*AttribPtr) | NewStatus;
> > +  *Attributes = *AttribPtr;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Check the integrity of firmware volume header
> > +
> > +  @param[in]  FvHeader   A pointer to a firmware volume header
> > +
> > +  @retval     TRUE          The firmware volume is consistent
> > +  @retval     FALSE         The firmware volume has corrupted.
> > +
> > +**/
> > +BOOLEAN
> > +IsFvHeaderValid (
> > +  IN       EFI_PHYSICAL_ADDRESS          FvBase,
> > +  IN CONST EFI_FIRMWARE_VOLUME_HEADER    *FvHeader
> > +  )
> > +{
> > +  if (FvBase == PcdGet32(PcdFlashNvStorageVariableBase)) {
> > +    if (CompareMem (&FvHeader->FileSystemGuid,
> &gEfiSystemNvDataFvGuid, sizeof(EFI_GUID)) != 0 ) {
> > +      return FALSE;
> > +    }
> > +  } else {
> > +    if (CompareMem (&FvHeader->FileSystemGuid,
> &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
> > +      return FALSE;
> > +    }
> > +  }
> > +  if ( (FvHeader->Revision != EFI_FVH_REVISION)   ||
> > +       (FvHeader->Signature != EFI_FVH_SIGNATURE) ||
> > +       (FvHeader->FvLength == ((UINTN) -1))       ||
> > +       ((FvHeader->HeaderLength & 0x01 ) !=0) )  {
> > +    return FALSE;
> > +  }
> > +
> > +  if (CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader-
> >HeaderLength) != 0) {
> > +    return FALSE;
> > +  }
> > +
> > +  return TRUE;
> > +}
> > +
> > +//
> > +// FVB protocol APIs
> > +//
> > +
> > +/**
> > +  Retrieves the physical address of the device.
> > +
> > +  @param[in]  This    A pointer to
> EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL.
> > +  @param[out] Address Output buffer containing the address.
> > +
> > +  retval      EFI_SUCCESS The function always return successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolGetPhysicalAddress (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
> > +  OUT EFI_PHYSICAL_ADDRESS                     *Address
> > +  )
> > +{
> > +  EFI_FVB_INSTANCE      *FvbInstance;
> > +
> > +  FvbInstance = FVB_INSTANCE_FROM_THIS (This);
> > +
> > +  *Address = FvbInstance->FvBase;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Retrieve the size of a logical block
> > +
> > +  @param[in]  This        Calling context
> > +  @param[in]  Lba         Indicates which block to return the size for.
> > +  @param[out] BlockSize   A pointer to a caller allocated UINTN in which
> > +                          the size of the block is returned
> > +  @param[out] NumOfBlocks A 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 function always return successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolGetBlockSize (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
> > +  IN  EFI_LBA                                  Lba,
> > +  OUT UINTN                                    *BlockSize,
> > +  OUT UINTN                                    *NumOfBlocks
> > +  )
> > +{
> > +  EFI_FVB_INSTANCE                 *FvbInstance;
> > +
> > +  FvbInstance = FVB_INSTANCE_FROM_THIS (This);
> > +
> > +  DEBUG((DEBUG_INFO,
> > +    "FvbProtocolGetBlockSize: Lba: 0x%lx BlockSize: 0x%x NumOfBlocks:
> 0x%x\n",
> > +    Lba,
> > +    BlockSize,
> > +    NumOfBlocks)
> > +    );
> > +
> > +  return FvbGetLbaAddress (
> > +           FvbInstance,
> > +           Lba,
> > +           NULL,
> > +           BlockSize,
> > +           NumOfBlocks
> > +           );
> > +}
> > +
> > +/**
> > +  Retrieves Volume attributes.  No polarity translations are done.
> > +
> > +  @param[in]    This        Calling context
> > +  @param[out]   Attributes  Output buffer which contains attributes
> > +
> > +  @retval       EFI_SUCCESS The function always return successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolGetAttributes (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
> > +  OUT EFI_FVB_ATTRIBUTES_2                *Attributes
> > +  )
> > +{
> > +  EFI_FVB_INSTANCE                 *FvbInstance;
> > +
> > +  FvbInstance = FVB_INSTANCE_FROM_THIS (This);
> > +
> > +  *Attributes = FvbGetVolumeAttributes (FvbInstance);
> > +
> > +  DEBUG ((DEBUG_INFO,
> > +    "FvbProtocolGetAttributes: This: 0x%x Attributes: 0x%x\n",
> > +    This,
> > +    *Attributes)
> > +    );
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Sets Volume attributes. No polarity translations are done.
> > +
> > +  @param[in]  This        Calling context
> > +  @param[out] Attributes  Output buffer which contains attributes
> > +
> > +  @retval     EFI_SUCCESS The function always return successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolSetAttributes (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
> > +  IN OUT EFI_FVB_ATTRIBUTES_2                   *Attributes
> > +  )
> > +{
> > +  EFI_STATUS                       Status;
> > +  EFI_FVB_INSTANCE                 *FvbInstance;
> > +
> > +  DEBUG((DEBUG_INFO,
> > +    "FvbProtocolSetAttributes: Before SET -  This: 0x%x Attributes: 0x%x\n",
> > +    This,
> > +    *Attributes)
> > +    );
> > +
> > +  FvbInstance  = FVB_INSTANCE_FROM_THIS (This);
> > +
> > +  Status = FvbSetVolumeAttributes (FvbInstance, Attributes);
> > +
> > +  DEBUG((DEBUG_INFO,
> > +    "FvbProtocolSetAttributes: After SET -  This: 0x%x Attributes: 0x%x\n",
> > +    This,
> > +    *Attributes)
> > +    );
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  The EraseBlock() function erases one or more blocks as denoted by the
> > +  variable argument list. The entire parameter list of blocks must be
> verified
> > +  prior to erasing any blocks.  If a block is requested that does not exist
> > +  within the associated firmware volume (it has a larger index than the last
> > +  block of the firmware volume), the EraseBlock() function must return
> > +  EFI_INVALID_PARAMETER without modifying the contents of the
> firmware volume.
> > +
> > +  @param[in] This         Calling context
> > +  @param[in] ...          Starting LBA followed by Number of Lba to erase.
> > +                          a -1 to terminate the list.
> > +
> > +  @retval EFI_SUCCESS       The erase request was 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. Firmware device may have been
> > +                            partially erased
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolEraseBlocks (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
> > +  ...
> > +  )
> > +{
> > +  EFI_FVB_INSTANCE                      *FvbInstance;
> > +  UINTN                                 NumOfBlocks;
> > +  VA_LIST                               Args;
> > +  EFI_LBA                               StartingLba;
> > +  UINTN                                 NumOfLba;
> > +  EFI_STATUS                            Status;
> > +
> > +  DEBUG((DEBUG_INFO, "FvbProtocolEraseBlocks: \n"));
> > +
> > +  FvbInstance  = FVB_INSTANCE_FROM_THIS (This);
> > +
> > +  NumOfBlocks = FvbInstance->NumOfBlocks;
> > +
> > +  VA_START (Args, This);
> > +
> > +  do {
> > +    StartingLba = VA_ARG (Args, EFI_LBA);
> > +    if ( StartingLba == EFI_LBA_LIST_TERMINATOR ) {
> > +      break;
> > +    }
> > +
> > +    NumOfLba = VA_ARG (Args, UINT32);
> > +
> > +    //
> > +    // Check input parameters
> > +    //
> > +    if (NumOfLba == 0) {
> > +      VA_END (Args);
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +
> > +    if ( ( StartingLba + NumOfLba ) > NumOfBlocks ) {
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +  } while ( 1 );
> > +
> > +  VA_END (Args);
> > +
> > +  VA_START (Args, This);
> > +  do {
> > +    StartingLba = VA_ARG (Args, EFI_LBA);
> > +    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
> > +      break;
> > +    }
> > +
> > +    NumOfLba = VA_ARG (Args, UINT32);
> > +
> > +    while ( NumOfLba > 0 ) {
> > +      Status = FvbEraseBlock (FvbInstance, StartingLba);
> > +      if ( EFI_ERROR(Status)) {
> > +        VA_END (Args);
> > +        return Status;
> > +      }
> > +      StartingLba ++;
> > +      NumOfLba --;
> > +    }
> > +
> > +  } while ( 1 );
> > +
> > +  VA_END (Args);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Writes data beginning at Lba:Offset from FV. The write terminates either
> > +  when *NumBytes of data have been written, or when a block boundary
> is
> > +  reached.  *NumBytes is updated to reflect the actual number of bytes
> > +  written. The write opertion does not include erase. This routine will
> > +  attempt to write only the specified bytes. If the writes do not stick,
> > +  it will return an error.
> > +
> > +  @param[in]      This      Calling context
> > +  @param[in]      Lba       Block in which to begin write
> > +  @param[in]      Offset    Offset in the block at which to begin write
> > +  @param[in,out]  NumBytes  On input, indicates the requested write size.
> On
> > +                            output, indicates the actual number of bytes written
> > +  @param[in]      Buffer    Buffer containing source data for the write.
> > +
> > +  @retval EFI_SUCCESS           The firmware volume was written successfully
> > +  @retval EFI_BAD_BUFFER_SIZE   Write attempted across a 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 not functioning
> correctly and
> > +                                could not be written
> > +  @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolWrite (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
> > +  IN EFI_LBA                                    Lba,
> > +  IN UINTN                                      Offset,
> > +  IN OUT UINTN                                  *NumBytes,
> > +  IN UINT8                                      *Buffer
> > +  )
> > +{
> > +  EFI_FVB_INSTANCE        *FvbInstance;
> > +
> > +  FvbInstance = FVB_INSTANCE_FROM_THIS (This);
> > +
> > +  DEBUG((DEBUG_INFO,
> > +    "FvbProtocolWrite: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer:
> 0x%x\n",
> > +    Lba,
> > +    Offset,
> > +    *NumBytes,
> > +    Buffer)
> > +    );
> > +
> > +  return FvbWriteBlock (FvbInstance, Lba, Offset, NumBytes, Buffer);
> > +}
> > +
> > +/**
> > +  Reads data beginning at Lba:Offset from FV. The Read terminates either
> > +  when *NumBytes of data have been read, or when a block boundary is
> > +  reached.  *NumBytes is updated to reflect the actual number of bytes
> > +  written. The write opertion does not include erase. This routine will
> > +  attempt to write only the specified bytes. If the writes do not stick,
> > +  it will return an error.
> > +
> > +  @param[in]      This      Calling context
> > +  @param[in]      Lba       Block in which to begin write
> > +  @param[in]      Offset    Offset in the block at which to begin write
> > +  @param[in,out]  NumBytes  On input, indicates the requested write size.
> On
> > +                            output, indicates the actual number of bytes written
> > +  @param[in]      Buffer    Buffer containing source data for the write.
> > +
> > +  @retval EFI_SUCCESS           The firmware volume was read successfully
> and
> > +                                contents are in Buffer
> > +  @retval EFI_BAD_BUFFER_SIZE   Read attempted across a 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
> > +  @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolRead (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
> > +  IN EFI_LBA                                    Lba,
> > +  IN UINTN                                      Offset,
> > +  IN OUT UINTN                                  *NumBytes,
> > +  OUT UINT8                                     *Buffer
> > +  )
> > +{
> > +  EFI_FVB_INSTANCE     *FvbInstance;
> > +  EFI_STATUS           Status;
> > +
> > +  FvbInstance = FVB_INSTANCE_FROM_THIS (This);
> > +  Status = FvbReadBlock (FvbInstance, Lba, Offset, NumBytes, Buffer);
> > +  DEBUG((DEBUG_INFO,
> > +    "FvbProtocolRead: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer:
> 0x%x\n",
> > +    Lba,
> > +    Offset,
> > +    *NumBytes,
> > +    Buffer)
> > +    );
> > +
> > +  return Status;
> > +}
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
> m.c
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
> m.c
> > new file mode 100644
> > index 000000000000..42a0828c6fae
> > --- /dev/null
> > +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
> m.c
> > @@ -0,0 +1,271 @@
> > +/** @file
> > +  MM driver source for several Serial Flash devices
> > +  which are compliant with the Intel(R) Serial Flash Interface Compatibility
> Specification.
> > +
> > +  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> > +  Copyright (c) Microsoft Corporation.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "SpiFvbServiceCommon.h"
> > +#include <Library/MmServicesTableLib.h>
> > +#include <Library/UefiDriverEntryPoint.h>
> > +#include <Protocol/SmmFirmwareVolumeBlock.h>
> > +
> > +/**
> > +  The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol
> > +  for each FV in the system.
> > +
> > +  @param[in]  FvbInstance   The pointer to a FW volume instance structure,
> > +                            which contains the information about one FV.
> > +
> > +  @retval     VOID
> > +
> > +**/
> > +VOID
> > +InstallFvbProtocol (
> > +  IN  EFI_FVB_INSTANCE               *FvbInstance
> > +  )
> > +{
> > +  EFI_FIRMWARE_VOLUME_HEADER            *FvHeader;
> > +  EFI_STATUS                            Status;
> > +  EFI_HANDLE                            FvbHandle;
> > +
> > +  ASSERT (FvbInstance != NULL);
> > +  if (FvbInstance == NULL) {
> > +    return;
> > +  }
> > +
> > +  CopyMem (&FvbInstance->FvbProtocol, &mFvbProtocolTemplate, sizeof
> (EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL));
> > +
> > +  FvHeader = &FvbInstance->FvHeader;
> > +  if (FvHeader == NULL) {
> > +    return;
> > +  }
> > +
> > +  //
> > +  // Set up the devicepath
> > +  //
> > +  DEBUG ((DEBUG_INFO, "FwBlockService.c: Setting up DevicePath for
> 0x%lx:\n", FvbInstance->FvBase));
> > +  if (FvHeader->ExtHeaderOffset == 0) {
> > +    //
> > +    // FV does not contains extension header, then produce
> MEMMAP_DEVICE_PATH
> > +    //
> > +    FvbInstance->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)
> AllocateRuntimeCopyPool (sizeof
> > (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
> > +    if (FvbInstance->DevicePath == NULL) {
> > +      DEBUG ((DEBUG_INFO, "SpiFvbServiceSmm.c: Memory allocation for
> MEMMAP_DEVICE_PATH failed\n"));
> > +      return;
> > +    }
> > +    ((FV_MEMMAP_DEVICE_PATH *) FvbInstance->DevicePath)-
> >MemMapDevPath.StartingAddress = FvbInstance->FvBase;
> > +    ((FV_MEMMAP_DEVICE_PATH *) FvbInstance->DevicePath)-
> >MemMapDevPath.EndingAddress   = FvbInstance->FvBase +
> > FvHeader->FvLength - 1;
> > +  } else {
> > +    FvbInstance->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)
> AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH),
> > &mFvPIWGDevicePathTemplate);
> > +    if (FvbInstance->DevicePath == NULL) {
> > +      DEBUG ((DEBUG_INFO, "SpiFvbServiceSmm.c: Memory allocation for
> FV_PIWG_DEVICE_PATH failed\n"));
> > +      return;
> > +    }
> > +    CopyGuid (
> > +      &((FV_PIWG_DEVICE_PATH *)FvbInstance->DevicePath)-
> >FvDevPath.FvName,
> > +      (GUID *)(UINTN)(FvbInstance->FvBase + FvHeader->ExtHeaderOffset)
> > +      );
> > +  }
> > +
> > +  //
> > +  // LocateDevicePath fails so install a new interface and device path
> > +  //
> > +  FvbHandle = NULL;
> > +
> > +  Status = gMmst->MmInstallProtocolInterface (
> > +                    &FvbHandle,
> > +                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
> > +                    EFI_NATIVE_INTERFACE,
> > +                    &(FvbInstance->FvbProtocol)
> > +                    );
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  Status = gMmst->MmInstallProtocolInterface (
> > +                    &FvbHandle,
> > +                    &gEfiDevicePathProtocolGuid,
> > +                    EFI_NATIVE_INTERFACE,
> > +                    &(FvbInstance->DevicePath)
> > +                    );
> > +  ASSERT_EFI_ERROR (Status);
> > +}
> > +
> > +/**
> > +  The function does the necessary initialization work for
> > +  Firmware Volume Block Driver.
> > +
> > +**/
> > +VOID
> > +FvbInitialize (
> > +  VOID
> > +  )
> > +{
> > +  EFI_FVB_INSTANCE                      *FvbInstance;
> > +  EFI_FIRMWARE_VOLUME_HEADER            *FvHeader;
> > +  EFI_FV_BLOCK_MAP_ENTRY                *PtrBlockMapEntry;
> > +  EFI_PHYSICAL_ADDRESS                  BaseAddress;
> > +  EFI_STATUS                            Status;
> > +  UINTN                                 BufferSize;
> > +  UINTN                                 Idx;
> > +  UINT32                                MaxLbaSize;
> > +  UINT32                                BytesWritten;
> > +  UINTN                                 BytesErased;
> > +
> > +  mPlatformFvBaseAddress[0].FvBase =
> PcdGet32(PcdFlashNvStorageVariableBase);
> > +  mPlatformFvBaseAddress[0].FvSize =
> PcdGet32(PcdFlashNvStorageVariableSize);
> > +  mPlatformFvBaseAddress[1].FvBase =
> PcdGet32(PcdFlashMicrocodeFvBase);
> > +  mPlatformFvBaseAddress[1].FvSize =
> PcdGet32(PcdFlashMicrocodeFvSize);
> > +  mPlatformDefaultBaseAddress[0].FvBase =
> PcdGet32(PcdFlashNvStorageVariableBase);
> > +  mPlatformDefaultBaseAddress[0].FvSize =
> PcdGet32(PcdFlashNvStorageVariableSize);
> > +  mPlatformDefaultBaseAddress[1].FvBase =
> PcdGet32(PcdFlashMicrocodeFvBase);
> > +  mPlatformDefaultBaseAddress[1].FvSize =
> PcdGet32(PcdFlashMicrocodeFvSize);
> > +
> > +  //
> > +  // We will only continue with FVB installation if the
> > +  // SPI is the active BIOS state
> > +  //
> > +  {
> > +    //
> > +    // Make sure all FVB are valid and/or fix if possible
> > +    //
> > +    for (Idx = 0;; Idx++) {
> > +      if (mPlatformFvBaseAddress[Idx].FvSize == 0 &&
> mPlatformFvBaseAddress[Idx].FvBase == 0) {
> > +        break;
> > +      }
> > +
> > +      BaseAddress = mPlatformFvBaseAddress[Idx].FvBase;
> > +      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
> BaseAddress;
> > +
> > +      if (!IsFvHeaderValid (BaseAddress, FvHeader)) {
> > +        BytesWritten = 0;
> > +        BytesErased = 0;
> > +        DEBUG ((DEBUG_ERROR, "ERROR - The FV in 0x%x is invalid!\n",
> FvHeader));
> > +        Status = GetFvbInfo (BaseAddress, &FvHeader);
> > +        if (EFI_ERROR (Status)) {
> > +          DEBUG ((DEBUG_WARN, "ERROR - Can't recovery FV header at 0x%x.
> GetFvbInfo Status %r\n", BaseAddress, Status));
> > +          continue;
> > +        }
> > +        DEBUG ((DEBUG_INFO, "Rewriting FV header at 0x%X with static
> data\n", BaseAddress));
> > +        //
> > +        // Spi erase
> > +        //
> > +        BytesErased = (UINTN) FvHeader->BlockMap->Length;
> > +        Status = SpiFlashBlockErase( (UINTN) BaseAddress, &BytesErased);
> > +        if (EFI_ERROR (Status)) {
> > +          DEBUG ((DEBUG_WARN, "ERROR - SpiFlashBlockErase Error  %r\n",
> Status));
> > +          continue;
> > +        }
> > +        if (BytesErased != FvHeader->BlockMap->Length) {
> > +          DEBUG ((DEBUG_WARN, "ERROR - BytesErased != FvHeader-
> >BlockMap->Length\n"));
> > +          DEBUG ((DEBUG_INFO, " BytesErased = 0x%X\n Length = 0x%X\n",
> BytesErased, FvHeader->BlockMap->Length));
> > +          continue;
> > +        }
> > +        BytesWritten = FvHeader->HeaderLength;
> > +        Status = SpiFlashWrite ((UINTN)BaseAddress, &BytesWritten,
> (UINT8*)FvHeader);
> > +        if (EFI_ERROR (Status)) {
> > +          DEBUG ((DEBUG_WARN, "ERROR - SpiFlashWrite Error  %r\n",
> Status));
> > +          continue;
> > +        }
> > +        if (BytesWritten != FvHeader->HeaderLength) {
> > +          DEBUG ((DEBUG_WARN, "ERROR - BytesWritten !=
> HeaderLength\n"));
> > +          DEBUG ((DEBUG_INFO, " BytesWritten = 0x%X\n HeaderLength =
> 0x%X\n", BytesWritten, FvHeader->HeaderLength));
> > +          continue;
> > +        }
> > +        Status = SpiFlashLock ();
> > +        if (EFI_ERROR (Status)) {
> > +          DEBUG ((DEBUG_WARN, "ERROR - SpiFlashLock Error  %r\n", Status));
> > +          continue;
> > +        }
> > +        DEBUG ((DEBUG_INFO, "FV Header @ 0x%X restored with static
> data\n", BaseAddress));
> > +        //
> > +        // Clear cache for this range.
> > +        //
> > +        WriteBackInvalidateDataCacheRange ( (VOID *) (UINTN) BaseAddress,
> FvHeader->BlockMap->Length);
> > +      }
> > +    }
> > +
> > +    //
> > +    // Calculate the total size for all firmware volume block instances
> > +    //
> > +    BufferSize = 0;
> > +    for (Idx = 0; ; Idx++) {
> > +      if (mPlatformFvBaseAddress[Idx].FvSize == 0 &&
> mPlatformFvBaseAddress[Idx].FvBase == 0) {
> > +        break;
> > +      }
> > +      BaseAddress = mPlatformFvBaseAddress[Idx].FvBase;
> > +      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
> BaseAddress;
> > +
> > +      if (!IsFvHeaderValid (BaseAddress, FvHeader)) {
> > +        DEBUG ((DEBUG_WARN, "ERROR - The FV in 0x%x is invalid!\n",
> FvHeader));
> > +        continue;
> > +      }
> > +
> > +      BufferSize += (FvHeader->HeaderLength +
> > +                    sizeof (EFI_FVB_INSTANCE) -
> > +                    sizeof (EFI_FIRMWARE_VOLUME_HEADER)
> > +                    );
> > +    }
> > +
> > +    mFvbModuleGlobal.FvbInstance =  (EFI_FVB_INSTANCE *)
> AllocateRuntimeZeroPool (BufferSize);
> > +    if (mFvbModuleGlobal.FvbInstance == NULL) {
> > +      ASSERT (FALSE);
> > +      return;
> > +    }
> > +
> > +    MaxLbaSize      = 0;
> > +    FvbInstance     = mFvbModuleGlobal.FvbInstance;
> > +    mFvbModuleGlobal.NumFv   = 0;
> > +
> > +    for (Idx = 0; ; Idx++) {
> > +      if (mPlatformFvBaseAddress[Idx].FvSize == 0 &&
> mPlatformFvBaseAddress[Idx].FvBase == 0) {
> > +        break;
> > +      }
> > +      BaseAddress = mPlatformFvBaseAddress[Idx].FvBase;
> > +      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
> BaseAddress;
> > +
> > +      if (!IsFvHeaderValid (BaseAddress, FvHeader)) {
> > +        DEBUG ((DEBUG_WARN, "ERROR - The FV in 0x%x is invalid!\n",
> FvHeader));
> > +        continue;
> > +      }
> > +
> > +      FvbInstance->Signature = FVB_INSTANCE_SIGNATURE;
> > +      CopyMem (&(FvbInstance->FvHeader), FvHeader, FvHeader-
> >HeaderLength);
> > +
> > +      FvHeader = &(FvbInstance->FvHeader);
> > +      FvbInstance->FvBase = (UINTN)BaseAddress;
> > +
> > +      //
> > +      // Process the block map for each FV
> > +      //
> > +      FvbInstance->NumOfBlocks   = 0;
> > +      for (PtrBlockMapEntry = FvHeader->BlockMap;
> > +           PtrBlockMapEntry->NumBlocks != 0;
> > +           PtrBlockMapEntry++) {
> > +        //
> > +        // Get the maximum size of a block.
> > +        //
> > +        if (MaxLbaSize < PtrBlockMapEntry->Length) {
> > +          MaxLbaSize  = PtrBlockMapEntry->Length;
> > +        }
> > +        FvbInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks;
> > +      }
> > +
> > +      //
> > +      // Add a FVB Protocol Instance
> > +      //
> > +      InstallFvbProtocol (FvbInstance);
> > +      mFvbModuleGlobal.NumFv++;
> > +
> > +      //
> > +      // Move on to the next FvbInstance
> > +      //
> > +      FvbInstance = (EFI_FVB_INSTANCE *) ((UINTN)((UINT8 *)FvbInstance)
> +
> > +                                            FvHeader->HeaderLength +
> > +                                            (sizeof (EFI_FVB_INSTANCE) - sizeof
> (EFI_FIRMWARE_VOLUME_HEADER)));
> > +
> > +    }
> > +  }
> > +}
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
> ndaloneMm.c
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
> ndaloneMm.c
> > new file mode 100644
> > index 000000000000..252c818d6551
> > --- /dev/null
> > +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
> ndaloneMm.c
> > @@ -0,0 +1,32 @@
> > +/** @file
> > +  MM driver source for several Serial Flash devices
> > +  which are compliant with the Intel(R) Serial Flash Interface Compatibility
> Specification.
> > +
> > +  Copyright (c) Microsoft Corporation.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "SpiFvbServiceCommon.h"
> > +#include "SpiFvbServiceMm.h"
> > +
> > +/**
> > +  The driver Standalone MM entry point.
> > +
> > +  @param[in] ImageHandle          Image handle of this driver.
> > +  @param[in] MmSystemTable        A pointer to the MM system table.
> > +
> > +  @retval EFI_SUCCESS             This function always returns EFI_SUCCESS.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SpiFvbStandaloneMmInitialize (
> > +  IN EFI_HANDLE            ImageHandle,
> > +  IN EFI_MM_SYSTEM_TABLE   *MmSystemTable
> > +  )
> > +{
> > +  FvbInitialize ();
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTra
> ditionalMm.c
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTra
> ditionalMm.c
> > new file mode 100644
> > index 000000000000..1c2dac70e3c6
> > --- /dev/null
> > +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTra
> ditionalMm.c
> > @@ -0,0 +1,32 @@
> > +/** @file
> > +  MM driver source for several Serial Flash devices
> > +  which are compliant with the Intel(R) Serial Flash Interface Compatibility
> Specification.
> > +
> > +  Copyright (c) Microsoft Corporation.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "SpiFvbServiceCommon.h"
> > +#include "SpiFvbServiceMm.h"
> > +
> > +/**
> > +  The driver Traditional MM entry point.
> > +
> > +  @param[in] ImageHandle          Image handle of this driver.
> > +  @param[in] SystemTable          A pointer to the EFI system table.
> > +
> > +  @retval EFI_SUCCESS             This function always returns EFI_SUCCESS.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SpiFvbTraditionalMmInitialize (
> > +  IN EFI_HANDLE            ImageHandle,
> > +  IN EFI_SYSTEM_TABLE      *SystemTable
> > +  )
> > +{
> > +  FvbInitialize ();
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
> mmon.h
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
> mmon.h
> > new file mode 100644
> > index 000000000000..e9d69e985814
> > --- /dev/null
> > +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo
> mmon.h
> > @@ -0,0 +1,158 @@
> > +/** @file
> > +  Common source definitions used in serial flash drivers
> > +
> > +Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _SPI_FVB_SERVICE_COMMON_H
> > +#define _SPI_FVB_SERVICE_COMMON_H
> > +
> > +#include <Guid/EventGroup.h>
> > +#include <Guid/FirmwareFileSystem2.h>
> > +#include <Guid/SystemNvDataGuid.h>
> > +#include <Protocol/DevicePath.h>
> > +#include <Protocol/FirmwareVolumeBlock.h>
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/CacheMaintenanceLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/HobLib.h>
> > +
> > +#include <Library/SpiFlashCommonLib.h>
> > +
> > +//
> > +// Define two helper macro to extract the Capability field or Status field in
> FVB
> > +// bit fields
> > +//
> > +#define EFI_FVB2_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \
> > +                              EFI_FVB2_READ_ENABLED_CAP | \
> > +                              EFI_FVB2_WRITE_DISABLED_CAP | \
> > +                              EFI_FVB2_WRITE_ENABLED_CAP | \
> > +                              EFI_FVB2_LOCK_CAP \
> > +                              )
> > +
> > +#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS |
> EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
> > +
> > +#define FVB_INSTANCE_SIGNATURE       SIGNATURE_32('F','V','B','I')
> > +
> > +typedef struct {
> > +  UINT32                                Signature;
> > +  UINTN                                 FvBase;
> > +  UINTN                                 NumOfBlocks;
> > +  EFI_DEVICE_PATH_PROTOCOL              *DevicePath;
> > +  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    FvbProtocol;
> > +  EFI_FIRMWARE_VOLUME_HEADER            FvHeader;
> > +} EFI_FVB_INSTANCE;
> > +
> > +typedef struct {
> > +  EFI_FVB_INSTANCE            *FvbInstance;
> > +  UINT32                      NumFv;
> > +} FVB_GLOBAL;
> > +
> > +//
> > +// Fvb Protocol instance data
> > +//
> > +#define FVB_INSTANCE_FROM_THIS(a) CR(a, EFI_FVB_INSTANCE,
> FvbProtocol, FVB_INSTANCE_SIGNATURE)
> > +
> > +typedef struct {
> > +  MEDIA_FW_VOL_DEVICE_PATH  FvDevPath;
> > +  EFI_DEVICE_PATH_PROTOCOL  EndDevPath;
> > +} FV_PIWG_DEVICE_PATH;
> > +
> > +typedef struct {
> > +  MEMMAP_DEVICE_PATH          MemMapDevPath;
> > +  EFI_DEVICE_PATH_PROTOCOL    EndDevPath;
> > +} FV_MEMMAP_DEVICE_PATH;
> > +
> > +typedef struct {
> > +  UINT32              FvBase;
> > +  UINT32              FvSize;
> > +} FV_INFO;
> > +
> > +//
> > +// Protocol APIs
> > +//
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolGetAttributes (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
> > +  OUT EFI_FVB_ATTRIBUTES_2                      *Attributes
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolSetAttributes (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
> > +  IN OUT EFI_FVB_ATTRIBUTES_2                   *Attributes
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolGetPhysicalAddress (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
> > +       OUT EFI_PHYSICAL_ADDRESS                *Address
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolGetBlockSize (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
> > +  IN  EFI_LBA                                  Lba,
> > +  OUT UINTN                                    *BlockSize,
> > +  OUT UINTN                                    *NumOfBlocks
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolRead (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
> > +  IN EFI_LBA                                    Lba,
> > +  IN UINTN                                      Offset,
> > +  IN OUT UINTN                                  *NumBytes,
> > +  OUT UINT8                                     *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolWrite (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
> > +  IN EFI_LBA                                    Lba,
> > +  IN UINTN                                      Offset,
> > +  IN OUT UINTN                                  *NumBytes,
> > +  IN UINT8                                      *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FvbProtocolEraseBlocks (
> > +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
> > +  ...
> > +  );
> > +
> > +BOOLEAN
> > +IsFvHeaderValid (
> > +  IN       EFI_PHYSICAL_ADDRESS          FvBase,
> > +  IN CONST EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader
> > +  );
> > +
> > +EFI_STATUS
> > +GetFvbInfo (
> > +  IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
> > +  OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
> > +  );
> > +
> > +extern FVB_GLOBAL                         mFvbModuleGlobal;
> > +extern FV_MEMMAP_DEVICE_PATH
> mFvMemmapDevicePathTemplate;
> > +extern FV_PIWG_DEVICE_PATH                mFvPIWGDevicePathTemplate;
> > +extern EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
> mFvbProtocolTemplate;
> > +extern FV_INFO                            mPlatformFvBaseAddress[];
> > +extern FV_INFO                            mPlatformDefaultBaseAddress[];
> > +
> > +#endif
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
> m.h
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
> m.h
> > new file mode 100644
> > index 000000000000..36af1130c8ee
> > --- /dev/null
> > +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM
> m.h
> > @@ -0,0 +1,22 @@
> > +/** @file
> > +  Definitions common to MM implementation in this driver.
> > +
> > +  Copyright (c) Microsoft Corporation.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _SPI_FVB_SERVICE_MM_H_
> > +#define _SPI_FVB_SERVICE_MM_H_
> > +
> > +/**
> > +  The function does the necessary initialization work for
> > +  Firmware Volume Block Driver.
> > +
> > +**/
> > +VOID
> > +FvbInitialize (
> > +  VOID
> > +  );
> > +
> > +#endif
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSm
> m.inf
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSm
> m.inf
> > new file mode 100644
> > index 000000000000..bf1306f00201
> > --- /dev/null
> > +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSm
> m.inf
> > @@ -0,0 +1,68 @@
> > +### @file
> > +# Component description file for the Serial Flash device Runtime driver.
> > +#
> > +# Copyright (c) 2017-2019, Intel Corporation. All rights reserved.<BR>
> > +# Copyright (c) Microsoft Corporation.<BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +###
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010017
> > +  BASE_NAME                      = SpiFvbServiceSmm
> > +  FILE_GUID                      = 68A10D85-6858-4402-B070-028B3EA21747
> > +  VERSION_STRING                 = 1.0
> > +  MODULE_TYPE                    = DXE_SMM_DRIVER
> > +  PI_SPECIFICATION_VERSION       = 1.10
> > +  ENTRY_POINT                    = SpiFvbTraditionalMmInitialize
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +# VALID_ARCHITECTURES = IA32 X64
> > +#
> > +
> > +[LibraryClasses]
> > +  PcdLib
> > +  MemoryAllocationLib
> > +  CacheMaintenanceLib
> > +  BaseMemoryLib
> > +  DebugLib
> > +  BaseLib
> > +  UefiBootServicesTableLib
> > +  UefiDriverEntryPoint
> > +  SpiFlashCommonLib
> > +  MmServicesTableLib
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  IntelSiliconPkg/IntelSiliconPkg.dec
> > +
> > +[Pcd]
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
> ## CONSUMES
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize   ##
> CONSUMES
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> ## CONSUMES
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> ## CONSUMES
> > +  gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase         ##
> CONSUMES
> > +  gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize         ##
> CONSUMES
> > +
> > +[Sources]
> > +  FvbInfo.c
> > +  SpiFvbServiceCommon.h
> > +  SpiFvbServiceCommon.c
> > +  SpiFvbServiceMm.h
> > +  SpiFvbServiceMm.c
> > +  SpiFvbServiceTraditionalMm.c
> > +
> > +[Protocols]
> > +  gEfiDevicePathProtocolGuid                    ## PRODUCES
> > +  gEfiSmmFirmwareVolumeBlockProtocolGuid        ## PRODUCES
> > +
> > +[Guids]
> > +  gEfiFirmwareFileSystem2Guid                   ## CONSUMES
> > +  gEfiSystemNvDataFvGuid                        ## CONSUMES
> > +
> > +[Depex]
> > +  TRUE
> > diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
> ndaloneMm.inf
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
> ndaloneMm.inf
> > new file mode 100644
> > index 000000000000..b66233968247
> > --- /dev/null
> > +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSta
> ndaloneMm.inf
> > @@ -0,0 +1,67 @@
> > +### @file
> > +# Component description file for the Serial Flash device Standalone MM
> driver.
> > +#
> > +# Copyright (c) 2017-2019, Intel Corporation. All rights reserved.<BR>
> > +# Copyright (c) Microsoft Corporation.<BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +###
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x0001001B
> > +  BASE_NAME                      = SpiFvbServiceStandaloneMm
> > +  FILE_GUID                      = E6313655-8BD0-4EAB-B319-AD5E212CE6AB
> > +  VERSION_STRING                 = 1.0
> > +  MODULE_TYPE                    = MM_STANDALONE
> > +  PI_SPECIFICATION_VERSION       = 0x00010032
> > +  ENTRY_POINT                    = SpiFvbStandaloneMmInitialize
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +# VALID_ARCHITECTURES = IA32 X64
> > +#
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  BaseMemoryLib
> > +  CacheMaintenanceLib
> > +  DebugLib
> > +  MemoryAllocationLib
> > +  PcdLib
> > +  MmServicesTableLib
> > +  SpiFlashCommonLib
> > +  StandaloneMmDriverEntryPoint
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  IntelSiliconPkg/IntelSiliconPkg.dec
> > +
> > +[Pcd]
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
> ## CONSUMES
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize   ##
> CONSUMES
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> ## CONSUMES
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> ## CONSUMES
> > +  gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase         ##
> CONSUMES
> > +  gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize         ##
> CONSUMES
> > +
> > +[Sources]
> > +  FvbInfo.c
> > +  SpiFvbServiceCommon.h
> > +  SpiFvbServiceCommon.c
> > +  SpiFvbServiceMm.h
> > +  SpiFvbServiceMm.c
> > +  SpiFvbServiceStandaloneMm.c
> > +
> > +[Protocols]
> > +  gEfiDevicePathProtocolGuid                    ## PRODUCES
> > +  gEfiSmmFirmwareVolumeBlockProtocolGuid        ## PRODUCES
> > +
> > +[Guids]
> > +  gEfiFirmwareFileSystem2Guid                   ## CONSUMES
> > +  gEfiSystemNvDataFvGuid                        ## CONSUMES
> > +
> > +[Depex]
> > +  TRUE
> > diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
> b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
> > index 7eb9c9def60a..7e446c97a5fb 100644
> > --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
> > +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
> > @@ -40,6 +40,9 @@ [LibraryClasses]
> >
> PeiGetVtdPmrAlignmentLib|IntelSiliconPkg/Library/PeiGetVtdPmrAlignment
> Lib/PeiGetVtdPmrAlignmentLib.inf
> >
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
> mMeasurementLibNull.inf
> >    MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
> > +
> SpiFlashCommonLib|IntelSiliconPkg/Library/SpiFlashCommonLibNull/SpiFlas
> hCommonLibNull.inf
> > +
> UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBo
> otServicesTableLib.inf
> > +
> UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry
> Point.inf
> >
> >  [LibraryClasses.common.PEIM]
> >    PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> > @@ -61,8 +64,14 @@ [LibraryClasses.common.DXE_DRIVER]
> >
> >  [LibraryClasses.common.DXE_SMM_DRIVER]
> >
> MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe
> moryAllocationLib.inf
> > +
> MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTabl
> eLib.inf
> >
> SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesT
> ableLib.inf
> >
> > +[LibraryClasses.common.MM_STANDALONE]
> > +
> >
> MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAll
> ocationLib/StandaloneMmMemoryAllocationLib.inf
> > +
> MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Stan
> daloneMmServicesTableLib.inf
> > +
> StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntry
> Point/StandaloneMmDriverEntryPoint.inf
> > +
> >
> ##########################################################
> #########################################
> >  #
> >  # Components Section - list of the modules and components that will be
> processed by compilation
> > @@ -86,6 +95,8 @@ [Components]
> >    IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf
> >
> IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDevi
> ceSecurityDxe.inf
> >
> IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/Sampl
> ePlatformDevicePolicyDxe.inf
> > +  IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf
> > +
> IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceStandaloneMm.in
> f
> >    IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
> >    IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.inf
> >    IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> > --
> > 2.28.0.windows.1


  reply	other threads:[~2021-04-20  3:00 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-16  2:31 [edk2-platforms][PATCH v1 00/35] Consolidate SpiFlashCommonLib instances Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 01/35] CometlakeOpenBoardPkg: Remove redundant IntelSiliconPkg.dec entry Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 02/35] WhiskeylakeOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 03/35] CometlakeOpenBoardPkg/PeiPolicyUpdateLib: Add missing GUID to INF Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 04/35] IntelSiliconPkg: Add BIOS area base address and size PCDs Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 05/35] IntelSiliconPkg: Add microcode FV PCDs Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 06/35] IntelSiliconPkg: Add PCH SPI PPI Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 07/35] IntelSiliconPkg: Add PCH SPI Protocol Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 08/35] IntelSiliconPkg: Add SpiFlashCommonLib Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 09/35] IntelSiliconPkg: Add SmmSpiFlashCommonLib Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI FVB services Michael Kubacki
2021-04-16 11:17   ` Ni, Ray
2021-04-20  3:00     ` Guo Dong [this message]
2021-04-21 18:52       ` [edk2-devel] " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 11/35] CometlakeOpenBoardPkg: Use IntelSiliconPkg BIOS area and ucode PCDs Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 12/35] KabylakeOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 13/35] SimicsOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 14/35] TigerlakeOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 15/35] WhiskeylakeOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 16/35] CoffeelakeSiliconPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 17/35] KabylakeSiliconPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 18/35] SimicsIch10Pkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 19/35] TigerlakeSiliconPkg: Use IntelSiliconPkg BIOS are " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 20/35] CometlakeOpenBoardPkg: Update SpiFvbService & SpiFlashCommonLib Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 21/35] KabylakeOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 22/35] SimicsOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 23/35] TigerlakeOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 24/35] WhiskeylakeOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 25/35] MinPlatformPkg: Remove SpiFvbService modules Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 26/35] CoffeelakeSiliconPkg: Remove SmmSpiFlashCommonLib Michael Kubacki
2021-04-16  2:31 ` Michael Kubacki
2021-04-19  9:07   ` Chiu, Chasel
2021-04-19 21:21     ` [edk2-devel] " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 28/35] SimicsIch10Pkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 29/35] TigerlakeOpenBoardPkg: " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 30/35] MinPlatformPkg: RemoveSpiFlashCommonLibNull Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 31/35] KabylakeOpenBoardPkg/PeiSerialPortLibSpiFlash: Add IntelSiliconPkg.dec Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 32/35] CoffeelakeSiliconPkg: Remove PCH SPI PPI and Protocol from package Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 33/35] KabylakeSiliconPkg: " Michael Kubacki
2021-04-19  9:04   ` Chiu, Chasel
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 34/35] SimicsIch10Pkg: Remove PCH SPI SMM " Michael Kubacki
2021-04-16  2:31 ` [edk2-platforms][PATCH v1 35/35] TigerlakeSiliconPkg: Remove PCH SPI PPI and " Michael Kubacki
2021-05-13 21:18 ` [edk2-devel] [edk2-platforms][PATCH v1 00/35] Consolidate SpiFlashCommonLib instances Nate DeSimone
2021-05-19  4:21   ` Michael Kubacki

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=BYAPR11MB36220D06FF5DCFCFE9466A899E489@BYAPR11MB3622.namprd11.prod.outlook.com \
    --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