[edk2-platforms][PATCH v3 09/41] IntelSiliconPkg: Add SmmSpiFlashCommonLib


Michael Kubacki
 

From: Michael Kubacki <michael.kubacki@microsoft.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D3307

Adds the SMM instance of SpiFlashCommonLib. The code is based on
refactoring existing library instances into a consolidated version
with no functional impact.

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>
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
---
Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCo=
mmonLib.c | 58 ++++++
Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SpiFlashCommo=
n.c | 209 ++++++++++++++++++++
Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc =
| 5 +
Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCo=
mmonLib.inf | 48 +++++
4 files changed, 320 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/S=
mmSpiFlashCommonLib.c b/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlash=
CommonLib/SmmSpiFlashCommonLib.c
new file mode 100644
index 000000000000..7941b8f8720c
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SmmSpiFl=
ashCommonLib.c
@@ -0,0 +1,58 @@
+/** @file
+ SMM Library instance of SPI Flash Common Library Class
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/Spi.h>
+#include <Library/DebugLib.h>
+
+extern PCH_SPI_PROTOCOL *mSpiProtocol;
+
+extern UINTN mBiosAreaBaseAddress;
+extern UINTN mBiosSize;
+extern UINTN mBiosOffset;
+
+/**
+ The library constructuor.
+
+ The function does the necessary initialization work for this library
+ instance.
+
+ @param[in] ImageHandle The firmware allocated handle for the UE=
FI image.
+ @param[in] SystemTable A pointer to the EFI system table.
+
+ @retval EFI_SUCCESS The function always return EFI_SUCCESS f=
or now.
+ It will ASSERT on error for debug versio=
n.
+ @retval EFI_ERROR Please reference LocateProtocol for erro=
r code details.
+**/
+EFI_STATUS
+EFIAPI
+SmmSpiFlashCommonLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT32 BaseAddr;
+ UINT32 RegionSize;
+
+ mBiosAreaBaseAddress =3D (UINTN)PcdGet32 (PcdBiosAreaBaseAddress);
+ mBiosSize =3D (UINTN)PcdGet32 (PcdBiosSize);
+
+ //
+ // Locate the SMM SPI protocol.
+ //
+ Status =3D gSmst->SmmLocateProtocol (
+ &gPchSmmSpiProtocolGuid,
+ NULL,
+ (VOID **) &mSpiProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mSpiProtocol->GetRegionAddress (mSpiProtocol, FlashRegionBios, &BaseAd=
dr, &RegionSize);
+ mBiosOffset =3D BaseAddr;
+ return Status;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/S=
piFlashCommon.c b/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommon=
Lib/SpiFlashCommon.c
new file mode 100644
index 000000000000..daebaf8e5e33
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SpiFlash=
Common.c
@@ -0,0 +1,209 @@
+/** @file
+ Wrap PCH_SPI_PROTOCOL to provide some library level interfaces
+ for module use.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/IoLib.h>
+#include <Protocol/Spi.h>
+
+PCH_SPI_PROTOCOL *mSpiProtocol;
+
+//
+// Variables for boottime and runtime usage.
+//
+UINTN mBiosAreaBaseAddress =3D 0;
+UINTN mBiosSize =3D 0;
+UINTN mBiosOffset =3D 0;
+
+/**
+ Enable block protection on the Serial Flash device.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Read NumBytes bytes of data from the address specified by
+ PAddress into Buffer.
+
+ @param[in] Address The starting physical address of the rea=
d.
+ @param[in,out] NumBytes On input, the number of bytes to read. O=
n output, the number
+ of bytes actually read.
+ @param[out] Buffer The destination data buffer for the read=
.
+
+ @retval EFI_SUCCESS Operation is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ OUT UINT8 *Buffer
+ )
+{
+ ASSERT ((NumBytes !=3D NULL) && (Buffer !=3D NULL));
+ if ((NumBytes =3D=3D NULL) || (Buffer =3D=3D NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // This function is implemented specifically for those platforms
+ // at which the SPI device is memory mapped for read. So this
+ // function just do a memory copy for Spi Flash Read.
+ //
+ CopyMem (Buffer, (VOID *) Address, *NumBytes);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write NumBytes bytes of data from Buffer to the address specified by
+ PAddresss.
+
+ @param[in] Address The starting physical address of the w=
rite.
+ @param[in,out] NumBytes On input, the number of bytes to write=
. On output,
+ the actual number of bytes written.
+ @param[in] Buffer The source data buffer for the write.
+
+ @retval EFI_SUCCESS Operation is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Offset;
+ UINT32 Length;
+ UINT32 RemainingBytes;
+
+ ASSERT ((NumBytes !=3D NULL) && (Buffer !=3D NULL));
+ if ((NumBytes =3D=3D NULL) || (Buffer =3D=3D NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ASSERT (Address >=3D mBiosAreaBaseAddress);
+ if (Address < mBiosAreaBaseAddress) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Offset =3D Address - mBiosAreaBaseAddress;
+
+ ASSERT ((*NumBytes + Offset) <=3D mBiosSize);
+ if ((*NumBytes + Offset) > mBiosSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status =3D EFI_SUCCESS;
+ RemainingBytes =3D *NumBytes;
+
+
+ while (RemainingBytes > 0) {
+ if (RemainingBytes > SECTOR_SIZE_4KB) {
+ Length =3D SECTOR_SIZE_4KB;
+ } else {
+ Length =3D RemainingBytes;
+ }
+ Status =3D mSpiProtocol->FlashWrite (
+ mSpiProtocol,
+ FlashRegionBios,
+ (UINT32) Offset,
+ Length,
+ Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ RemainingBytes -=3D Length;
+ Offset +=3D Length;
+ Buffer +=3D Length;
+ }
+
+ //
+ // Actual number of bytes written
+ //
+ *NumBytes -=3D RemainingBytes;
+
+ return Status;
+}
+
+/**
+ Erase the block starting at Address.
+
+ @param[in] Address The starting physical address of the block=
to be erased.
+ This library assume that caller garantee t=
hat the PAddress
+ is at the starting address of this block.
+ @param[in] NumBytes On input, the number of bytes of the logic=
al block to be erased.
+ On output, the actual number of bytes eras=
ed.
+
+ @retval EFI_SUCCESS. Operation is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+ IN UINTN Address,
+ IN UINTN *NumBytes
+ )
+{
+ EFI_STATUS Status;
+ UINTN Offset;
+ UINTN RemainingBytes;
+
+ ASSERT (NumBytes !=3D NULL);
+ if (NumBytes =3D=3D NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ASSERT (Address >=3D mBiosAreaBaseAddress);
+ if (Address < mBiosAreaBaseAddress) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Offset =3D Address - mBiosAreaBaseAddress;
+
+ ASSERT ((*NumBytes % SECTOR_SIZE_4KB) =3D=3D 0);
+ if ((*NumBytes % SECTOR_SIZE_4KB) !=3D 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ASSERT ((*NumBytes + Offset) <=3D mBiosSize);
+ if ((*NumBytes + Offset) > mBiosSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status =3D EFI_SUCCESS;
+ RemainingBytes =3D *NumBytes;
+
+
+ Status =3D mSpiProtocol->FlashErase (
+ mSpiProtocol,
+ FlashRegionBios,
+ (UINT32) Offset,
+ (UINT32) RemainingBytes
+ );
+ return Status;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc b/Silicon/=
Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
index aeed452ed521..d4e15100bfde 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc
@@ -59,6 +59,10 @@ [LibraryClasses.common.DXE_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryA=
llocationLib.inf
=20
+[LibraryClasses.common.DXE_SMM_DRIVER]
+ MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAll=
ocationLib.inf
+ SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTabl=
eLib.inf
+
########################################################################=
###########################
#
# Components Section - list of the modules and components that will be p=
rocessed by compilation
@@ -95,6 +99,7 @@ [Components]
IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
IntelSiliconPkg/Library/ReportCpuHobLib/ReportCpuHobLib.inf
IntelSiliconPkg/Library/SpiFlashCommonLibNull/SpiFlashCommonLibNull.in=
f
+ IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
=20
[BuildOptions]
*_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/S=
mmSpiFlashCommonLib.inf b/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFla=
shCommonLib/SmmSpiFlashCommonLib.inf
new file mode 100644
index 000000000000..f6a06351ace5
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SmmSpiFl=
ashCommonLib.inf
@@ -0,0 +1,48 @@
+## @file
+# SMM Library instance of Spi Flash Common Library Class
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION =3D 0x00010017
+ BASE_NAME =3D SmmSpiFlashCommonLib
+ FILE_GUID =3D 99721728-C39D-4600-BD38-71E8238FEEF=
2
+ VERSION_STRING =3D 1.0
+ MODULE_TYPE =3D DXE_SMM_DRIVER
+ LIBRARY_CLASS =3D SpiFlashCommonLib|DXE_SMM_DRIVER
+ CONSTRUCTOR =3D SmmSpiFlashCommonLibConstructor
+#
+# The following information is for reference only and not required by th=
e build tools.
+#
+# VALID_ARCHITECTURES =3D IA32 X64
+#
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ MemoryAllocationLib
+ SmmServicesTableLib
+ UefiLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+ gIntelSiliconPkgTokenSpaceGuid.PcdBiosAreaBaseAddress ## CONSUMES
+ gIntelSiliconPkgTokenSpaceGuid.PcdBiosSize ## CONSUMES
+
+[Sources]
+ SmmSpiFlashCommonLib.c
+ SpiFlashCommon.c
+
+[Protocols]
+ gPchSmmSpiProtocolGuid ## CONSUMES
+
+[Depex.X64.DXE_SMM_DRIVER]
+ gPchSmmSpiProtocolGuid
--=20
2.28.0.windows.1