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
next prev parent 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