Forráskód Böngészése

IntelSiliconPkg: Identify flash regions by GUID

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

Adds a new SPI 2 protocol (and corresponding PPI) that identify
flash regions by GUID instead of fixed values defined in an enum.

Packages consuming IntelSiliconPkg are able to associate a given
GUID with their chosen values based on their SPI flash details as
implemented in their PCH_SPI2_PROTOCOL instance.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
Michael Kubacki 2 éve
szülő
commit
5ffc54262a

+ 31 - 0
Silicon/Intel/IntelSiliconPkg/Include/Ppi/Spi2.h

@@ -0,0 +1,31 @@
+/** @file
+  This file defines the PCH SPI2 PPI which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+  This SPI Protocol differs from the PCH SPI 1 Protocol interface
+  primarily by identifying SPI flash regions by GUID instead
+  of numeric values.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) Microsoft Corporation.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SPI2_PPI_H_
+#define _PCH_SPI2_PPI_H_
+
+#include <Protocol/Spi2.h>
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID           gPchSpi2PpiGuid;
+
+/**
+  Reuse the PCH_SPI2_PROTOCOL definitions
+  This is possible because the PPI implementation does not rely on a PeiService pointer,
+  as it uses EDKII Glue Lib to do IO accesses
+**/
+typedef PCH_SPI2_PROTOCOL PCH_SPI2_PPI;
+
+#endif

+ 283 - 0
Silicon/Intel/IntelSiliconPkg/Include/Protocol/Spi2.h

@@ -0,0 +1,283 @@
+/** @file
+  This file defines the PCH SPI 2 Protocol which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+  This SPI Protocol differs from the PCH SPI 1 Protocol interface
+  primarily by identifying SPI flash regions by GUID instead
+  of numeric values.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) Microsoft Corporation.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SPI2_PROTOCOL_H_
+#define _PCH_SPI2_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                   gPchSpi2ProtocolGuid;
+extern EFI_GUID                   gPchSmmSpi2ProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_SPI2_PROTOCOL  PCH_SPI2_PROTOCOL;
+
+//
+// Protocol member functions
+//
+
+/**
+  Read data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] FlashRegionGuid      The Flash Region GUID for flash cycle which corresponds to the type in the descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[out] Buffer              The Pointer to caller-allocated buffer containing the dada received.
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     EFI_GUID           *FlashRegionGuid,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *Buffer
+  );
+
+/**
+  Write data to the flash part. Remark: Erase may be needed before write to the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] FlashRegionGuid      The Flash Region GUID for flash cycle which corresponds to the type in the descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[in] Buffer               Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_WRITE) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     EFI_GUID           *FlashRegionGuid,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *Buffer
+  );
+
+/**
+  Erase some area on the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] FlashRegionGuid      The Flash Region GUID for flash cycle which corresponds to the type in the descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_ERASE) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     EFI_GUID           *FlashRegionGuid,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount
+  );
+
+/**
+  Read SFDP data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] ComponentNumber      The Component Number for chip select
+  @param[in] Address              The starting byte address for SFDP data read.
+  @param[in] ByteCount            Number of bytes in SFDP data portion of the SPI cycle
+  @param[out] SfdpData            The Pointer to caller-allocated buffer containing the SFDP data received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_SFDP) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *SfdpData
+  );
+
+/**
+  Read Jedec Id from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] ComponentNumber      The Component Number for chip select
+  @param[in] ByteCount            Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+  @param[out] JedecId             The Pointer to caller-allocated buffer containing JEDEC ID received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_JEDEC_ID) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *JedecId
+  );
+
+/**
+  Write the status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[in] StatusValue          The Pointer to caller-allocated buffer containing the value of Status register writing
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_WRITE_STATUS) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *StatusValue
+  );
+
+/**
+  Read status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[out] StatusValue         The Pointer to caller-allocated buffer containing the value of Status register received.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_STATUS) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *StatusValue
+  );
+
+/**
+  Get the SPI region base and size, based on the enum type
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] FlashRegionGuid      The Flash Region GUID for flash cycle which corresponds to the type in the descriptor.
+  @param[out] BaseAddress         The Flash Linear Address for the Region 'n' Base
+  @param[out] RegionSize          The size for the Region 'n'
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid region type given
+  @retval EFI_DEVICE_ERROR        The region is not used
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_GET_REGION_ADDRESS) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     EFI_GUID           *FlashRegionGuid,
+  OUT    UINT32             *BaseAddress,
+  OUT    UINT32             *RegionSize
+  );
+
+/**
+  Read PCH Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] SoftStrapAddr        PCH Soft Strap address offset from FPSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_READ_PCH_SOFTSTRAP) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  );
+
+/**
+  Read CPU Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI2_PROTOCOL instance.
+  @param[in] SoftStrapAddr        CPU Soft Strap address offset from FCPUSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle.
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_READ_CPU_SOFTSTRAP) (
+  IN     PCH_SPI2_PROTOCOL  *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  );
+
+/**
+  These protocols/PPI allows a platform module to perform SPI operations through the
+  Intel PCH SPI Host Controller Interface.
+
+**/
+struct _PCH_SPI2_PROTOCOL {
+  /**
+    This member specifies the revision of this structure. This field is used to
+    indicate backwards compatible changes to the protocol.
+  **/
+  UINT8                             Revision;
+  PCH_SPI_FLASH_READ                FlashRead;          ///< Read data from the flash part.
+  PCH_SPI_FLASH_WRITE               FlashWrite;         ///< Write data to the flash part. Remark: Erase may be needed before write to the flash part.
+  PCH_SPI_FLASH_ERASE               FlashErase;         ///< Erase some area on the flash part.
+  PCH_SPI_FLASH_READ_SFDP           FlashReadSfdp;      ///< Read SFDP data from the flash part.
+  PCH_SPI_FLASH_READ_JEDEC_ID       FlashReadJedecId;   ///< Read Jedec Id from the flash part.
+  PCH_SPI_FLASH_WRITE_STATUS        FlashWriteStatus;   ///< Write the status register in the flash part.
+  PCH_SPI_FLASH_READ_STATUS         FlashReadStatus;    ///< Read status register in the flash part.
+  PCH_SPI_GET_REGION_ADDRESS        GetRegionAddress;   ///< Get the SPI region base and size
+  PCH_SPI_READ_PCH_SOFTSTRAP        ReadPchSoftStrap;   ///< Read PCH Soft Strap Values
+  PCH_SPI_READ_CPU_SOFTSTRAP        ReadCpuSoftStrap;   ///< Read CPU Soft Strap Values
+};
+
+/**
+  PCH SPI PPI/PROTOCOL revision number
+
+  Revision 1:   Initial version
+  Revision 2:   Identify regions by GUID
+
+**/
+#define PCH_SPI_SERVICES_REVISION       2
+
+#endif

+ 8 - 0
Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec

@@ -96,15 +96,23 @@
   ## Include/Ppi/Spi.h
   gPchSpiPpiGuid = { 0x104c7177, 0xc2e6, 0x44f0, { 0xae, 0xe3, 0x9d, 0x0d, 0x9a, 0x52, 0xca, 0xdf } }
 
+  ## Include/Ppi/Spi2.h
+  gPchSpi2PpiGuid = { 0x63c40580, 0x10c4, 0x4a8e, { 0xb4, 0x16, 0x86, 0x85, 0x25, 0x7e, 0xce, 0x04 } }
+
   gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } }
   gEdkiiVTdNullRootEntryTableGuid = { 0x3de0593f, 0x6e3e, 0x4542, { 0xa1, 0xcb, 0xcb, 0xb2, 0xdb, 0xeb, 0xd8, 0xff } }
 
 [Protocols]
   ## Protocols that provide services for the Intel(R) PCH SPI Host Controller Compatibility Interface
+
   # Include/Protocol/Spi.h
   gPchSpiProtocolGuid  =  { 0xe007dec0, 0xccc3, 0x4c90, { 0x9c, 0xd0, 0xef, 0x99, 0x38, 0x83, 0x28, 0xcf } }
   gPchSmmSpiProtocolGuid = { 0x4840e48e, 0xc264, 0x4fef, { 0xb9, 0x34, 0x14, 0x84, 0x0c, 0x95, 0xd8, 0x3f } }
 
+  # Include/Protocol/Spi2.h
+  gPchSpi2ProtocolGuid = { 0x3a99abd1, 0x096c, 0x4399, { 0xb1, 0x68, 0x52, 0xaa, 0x52, 0x64, 0xce, 0x70 } }
+  gPchSmmSpi2ProtocolGuid = { 0x2d1c0c43, 0x20d3, 0x40ae, { 0x99, 0x07, 0x2d, 0xf0, 0xe7, 0x91, 0x21, 0xa5 } }
+
   gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99, 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
 
   ## Protocol for device security policy.

+ 9 - 7
Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.c

@@ -2,21 +2,23 @@
   SMM Library instance of SPI Flash Common Library Class
 
   Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) Microsoft Corporation.<BR>
+
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
 #include <Library/SmmServicesTableLib.h>
-#include <Protocol/Spi.h>
+#include <Protocol/Spi2.h>
 #include <Library/DebugLib.h>
 
-extern PCH_SPI_PROTOCOL   *mSpiProtocol;
+extern PCH_SPI2_PROTOCOL   *mSpi2Protocol;
 
 extern UINTN mBiosAreaBaseAddress;
 extern UINTN mBiosSize;
 extern UINTN mBiosOffset;
 
 /**
-  The library constructuor.
+  The library constructor.
 
   The function does the necessary initialization work for this library
   instance.
@@ -43,16 +45,16 @@ SmmSpiFlashCommonLibConstructor (
   mBiosSize            = (UINTN)PcdGet32 (PcdBiosSize);
 
   //
-  // Locate the SMM SPI protocol.
+  // Locate the SMM SPI2 protocol.
   //
   Status = gSmst->SmmLocateProtocol (
-                    &gPchSmmSpiProtocolGuid,
+                    &gPchSmmSpi2ProtocolGuid,
                     NULL,
-                    (VOID **) &mSpiProtocol
+                    (VOID **) &mSpi2Protocol
                     );
   ASSERT_EFI_ERROR (Status);
 
-  mSpiProtocol->GetRegionAddress (mSpiProtocol, FlashRegionBios, &BaseAddr, &RegionSize);
+  mSpi2Protocol->GetRegionAddress (mSpi2Protocol, &gFlashRegionBiosGuid, &BaseAddr, &RegionSize);
   mBiosOffset = BaseAddr;
   return Status;
 }

+ 5 - 2
Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf

@@ -37,12 +37,15 @@
   gIntelSiliconPkgTokenSpaceGuid.PcdBiosAreaBaseAddress   ## CONSUMES
   gIntelSiliconPkgTokenSpaceGuid.PcdBiosSize              ## CONSUMES
 
+[Guids]
+  gFlashRegionBiosGuid
+
 [Sources]
   SmmSpiFlashCommonLib.c
   SpiFlashCommon.c
 
 [Protocols]
-  gPchSmmSpiProtocolGuid                                  ## CONSUMES
+  gPchSmmSpi2ProtocolGuid                                 ## CONSUMES
 
 [Depex.X64.DXE_SMM_DRIVER]
-  gPchSmmSpiProtocolGuid
+  gPchSmmSpi2ProtocolGuid

+ 16 - 16
Silicon/Intel/IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c

@@ -1,5 +1,5 @@
 /** @file
-  Wrap PCH_SPI_PROTOCOL to provide some library level interfaces
+  Wrap PCH_SPI2_PROTOCOL to provide some library level interfaces
   for module use.
 
   Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
@@ -8,9 +8,9 @@
 
 #include <Library/SpiFlashCommonLib.h>
 #include <Library/IoLib.h>
-#include <Protocol/Spi.h>
+#include <Protocol/Spi2.h>
 
-PCH_SPI_PROTOCOL       *mSpiProtocol;
+PCH_SPI2_PROTOCOL       *mSpi2Protocol;
 
 //
 // Variables for boottime and runtime usage.
@@ -125,13 +125,13 @@ SpiFlashWrite (
     } else {
       Length = RemainingBytes;
     }
-    Status = mSpiProtocol->FlashWrite (
-                             mSpiProtocol,
-                             FlashRegionBios,
-                             (UINT32) Offset,
-                             Length,
-                             Buffer
-                             );
+    Status = mSpi2Protocol->FlashWrite (
+                              mSpi2Protocol,
+                              &gFlashRegionBiosGuid,
+                              (UINT32) Offset,
+                              Length,
+                              Buffer
+                              );
     if (EFI_ERROR (Status)) {
       break;
     }
@@ -199,11 +199,11 @@ SpiFlashBlockErase (
   RemainingBytes = *NumBytes;
 
 
-  Status = mSpiProtocol->FlashErase (
-                           mSpiProtocol,
-                           FlashRegionBios,
-                           (UINT32) Offset,
-                           (UINT32) RemainingBytes
-                           );
+  Status = mSpi2Protocol->FlashErase (
+                            mSpi2Protocol,
+                            &gFlashRegionBiosGuid,
+                            (UINT32) Offset,
+                            (UINT32) RemainingBytes
+                            );
   return Status;
 }