From: "Nate DeSimone" <nathaniel.l.desimone@intel.com>
To: "Luo, Heng" <heng.luo@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>
Subject: Re: [PATCH 29/40] TigerlakeSiliconPkg/IpBlock: Add Spi component
Date: Thu, 4 Feb 2021 03:56:27 +0000 [thread overview]
Message-ID: <BN6PR1101MB2147C853F8F22F4825260E03CDB39@BN6PR1101MB2147.namprd11.prod.outlook.com> (raw)
In-Reply-To: <20210201013657.1833-29-heng.luo@intel.com>
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
> -----Original Message-----
> From: Luo, Heng <heng.luo@intel.com>
> Sent: Sunday, January 31, 2021 5:37 PM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>
> Subject: [PATCH 29/40] TigerlakeSiliconPkg/IpBlock: Add Spi component
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171
>
> Adds the following files:
> * IpBlock/Spi/IncludePrivate
> * IpBlock/Spi/Library
> * IpBlock/Spi/LibraryPrivate
> * IpBlock/Spi/Smm
>
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Signed-off-by: Heng Luo <heng.luo@intel.com>
> ---
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiAcces
> sPrivateLib.h | 40 ++++++++++++++++++++++++++++++++
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiCom
> monLib.h | 364
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Register/SpiRegs
> .h | 136
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib
> /PeiDxeSmmSpiAccessLib.inf | 33
> ++++++++++++++++++++++++++
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib
> /SpiAccessLib.c | 477
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommon
> Lib/BaseSpiCommonLib.inf | 31
> +++++++++++++++++++++++++
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommon
> Lib/SpiCommon.c | 1115
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAc
> cessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf | 40
> ++++++++++++++++++++++++++++++++
>
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAc
> cessPrivateLib/SpiAccessPrivateLib.c | 133
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/Spi.c
> | 296
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/SpiSmm.inf
> | 47 +++++++++++++++++++++++++++++++++++++
> 11 files changed, 2712 insertions(+)
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiAcc
> essPrivateLib.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiAcc
> essPrivateLib.h
> new file mode 100644
> index 0000000000..6da88a9047
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiAcc
> essPrivateLib.h
> @@ -0,0 +1,40 @@
> +/** @file
>
> + SPI library header for abstraction of SPI HW registers accesses
>
> +
>
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +
>
> +#ifndef _SPI_ACCESS_PRIVATE_LIB_H_
>
> +#define _SPI_ACCESS_PRIVATE_LIB_H_
>
> +
>
> +/**
>
> + Disable EISS (Enable InSMM.STS)
>
> +**/
>
> +VOID
>
> +SpiDisableEiss (
>
> + VOID
>
> + );
>
> +
>
> +/**
>
> + Configure BiosLockEnable bit and BiosInterfaceLock bit according to policy
> setting.
>
> +
>
> + @param[in] BiosLockEnable Policy for BiosLockEnable bit programming
>
> + @param[in] BiosInterfaceLock Policy for BiosInterfaceLock bit
> programming
>
> +
>
> +**/
>
> +VOID
>
> +SpiBiosLockEnableAndBiosInterfaceLockWithS3BootScript (
>
> + IN BOOLEAN BiosLockEnable,
>
> + IN BOOLEAN BiosInterfaceLock
>
> + );
>
> +
>
> +/**
>
> + Clears BIOS Write Protect Disable bit
>
> +**/
>
> +VOID
>
> +SpiClearBiosWriteProtectDisable (
>
> + VOID
>
> + );
>
> +
>
> +#endif // _SPI_ACCESS_PRIVATE_LIB_H_
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiCo
> mmonLib.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiCo
> mmonLib.h
> new file mode 100644
> index 0000000000..3290f77122
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiCo
> mmonLib.h
> @@ -0,0 +1,364 @@
> +/** @file
>
> + Header file for the PCH SPI Common Driver.
>
> +
>
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +#ifndef _SPI_COMMON_LIB_H_
>
> +#define _SPI_COMMON_LIB_H_
>
> +
>
> +#include <Protocol/Spi.h>
>
> +
>
> +//
>
> +// Maximum time allowed while waiting the SPI cycle to complete
>
> +// Wait Time = 6 seconds = 6000000 microseconds
>
> +// Wait Period = 10 microseconds
>
> +//
>
> +#define SPI_WAIT_TIME 6000000 ///< Wait Time = 6 seconds = 6000000
> microseconds
>
> +#define SPI_WAIT_PERIOD 10 ///< Wait Period = 10 microseconds
>
> +
>
> +///
>
> +/// Flash cycle Type
>
> +///
>
> +typedef enum {
>
> + FlashCycleRead,
>
> + FlashCycleWrite,
>
> + FlashCycleErase,
>
> + FlashCycleReadSfdp,
>
> + FlashCycleReadJedecId,
>
> + FlashCycleWriteStatus,
>
> + FlashCycleReadStatus,
>
> + FlashCycleMax
>
> +} FLASH_CYCLE_TYPE;
>
> +
>
> +///
>
> +/// Flash Component Number
>
> +///
>
> +typedef enum {
>
> + FlashComponent0,
>
> + FlashComponent1,
>
> + FlashComponentMax
>
> +} FLASH_COMPONENT_NUM;
>
> +
>
> +///
>
> +/// Private data structure definitions for the driver
>
> +///
>
> +#define PCH_SPI_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'S', 'P',
> 'I')
>
> +
>
> +typedef struct {
>
> + UINT32 Signature;
>
> + EFI_HANDLE Handle;
>
> + PCH_SPI_PROTOCOL SpiProtocol;
>
> + UINT16 PchAcpiBase;
>
> + UINT64 PchSpiBase;
>
> + UINT8 ReadPermission;
>
> + UINT8 WritePermission;
>
> + UINT32 SfdpVscc0Value;
>
> + UINT32 SfdpVscc1Value;
>
> + UINT16 PchStrapBaseAddr;
>
> + UINT16 PchStrapSize;
>
> + UINT16 CpuStrapBaseAddr;
>
> + UINT16 CpuStrapSize;
>
> + UINT8 NumberOfComponents;
>
> + UINT32 Component1StartAddr;
>
> + UINT32 TotalFlashSize;
>
> +} SPI_INSTANCE;
>
> +
>
> +#define SPI_INSTANCE_FROM_SPIPROTOCOL(a) CR (a, SPI_INSTANCE,
> SpiProtocol, PCH_SPI_PRIVATE_DATA_SIGNATURE)
>
> +
>
> +//
>
> +// Function prototypes used by the SPI protocol.
>
> +//
>
> +
>
> +/**
>
> + Initialize an SPI protocol instance.
>
> +
>
> + @param[in] SpiInstance Pointer to SpiInstance to initialize
>
> +
>
> + @retval EFI_SUCCESS The protocol instance was properly initialized
>
> + @exception EFI_UNSUPPORTED The PCH is not supported by this
> module
>
> +**/
>
> +EFI_STATUS
>
> +SpiProtocolConstructor (
>
> + IN SPI_INSTANCE *SpiInstance
>
> + );
>
> +
>
> +/**
>
> + This function is a hook for Spi to disable BIOS Write Protect
>
> +
>
> + @retval EFI_SUCCESS The protocol instance was properly initialized
>
> + @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in
> SMM phase
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +DisableBiosWriteProtect (
>
> + VOID
>
> + );
>
> +
>
> +/**
>
> + This function is a hook for Spi to enable BIOS Write Protect
>
> +
>
> +
>
> +**/
>
> +VOID
>
> +EFIAPI
>
> +EnableBiosWriteProtect (
>
> + VOID
>
> + );
>
> +
>
> +/**
>
> + Acquire pch spi mmio address.
>
> +
>
> + @param[in] SpiInstance Pointer to SpiInstance to initialize
>
> +
>
> + @retval PchSpiBar0 return SPI MMIO address
>
> +**/
>
> +UINTN
>
> +AcquireSpiBar0 (
>
> + IN SPI_INSTANCE *SpiInstance
>
> + );
>
> +
>
> +/**
>
> + Release pch spi mmio address.
>
> +
>
> + @param[in] SpiInstance Pointer to SpiInstance to initialize
>
> +
>
> + @retval None
>
> +**/
>
> +VOID
>
> +ReleaseSpiBar0 (
>
> + IN SPI_INSTANCE *SpiInstance
>
> + );
>
> +
>
> +/**
>
> + Check if it's granted to do flash write.
>
> +
>
> + @retval TRUE It's secure to do flash write.
>
> + @retval FALSE It's not secure to do flash write.
>
> +**/
>
> +BOOLEAN
>
> +IsSpiFlashWriteGranted (
>
> + VOID
>
> + );
>
> +
>
> +/**
>
> + Read data from the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] FlashRegionType The Flash Region type for flash cycle which
> is listed 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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashRead (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + IN UINT32 Address,
>
> + IN UINT32 ByteCount,
>
> + OUT UINT8 *Buffer
>
> + );
>
> +
>
> +/**
>
> + Write data to the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] FlashRegionType The Flash Region type for flash cycle which
> is listed 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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashWrite (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + IN UINT32 Address,
>
> + IN UINT32 ByteCount,
>
> + IN UINT8 *Buffer
>
> + );
>
> +
>
> +/**
>
> + Erase some area on the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] FlashRegionType The Flash Region type for flash cycle which
> is listed 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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashErase (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + IN UINT32 Address,
>
> + IN UINT32 ByteCount
>
> + );
>
> +
>
> +/**
>
> + Read SFDP data from the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] ComponentNumber The Componen 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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashReadSfdp (
>
> + IN PCH_SPI_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_SPI_PROTOCOL instance.
>
> + @param[in] ComponentNumber The Componen 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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashReadJedecId (
>
> + IN PCH_SPI_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_SPI_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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashWriteStatus (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT32 ByteCount,
>
> + IN UINT8 *StatusValue
>
> + );
>
> +
>
> +/**
>
> + Read status register in the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashReadStatus (
>
> + IN PCH_SPI_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_SPI_PROTOCOL instance.
>
> + @param[in] FlashRegionType The Flash Region type for for the base
> address which is listed 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
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolGetRegionAddress (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + OUT UINT32 *BaseAddress,
>
> + OUT UINT32 *RegionSize
>
> + );
>
> +
>
> +/**
>
> + Read PCH Soft Strap Values
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolReadPchSoftStrap (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT32 SoftStrapAddr,
>
> + IN UINT32 ByteCount,
>
> + OUT VOID *SoftStrapValue
>
> + );
>
> +
>
> +/**
>
> + Read CPU Soft Strap Values
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolReadCpuSoftStrap (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT32 SoftStrapAddr,
>
> + IN UINT32 ByteCount,
>
> + OUT VOID *SoftStrapValue
>
> + );
>
> +
>
> +#endif
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Register/SpiRe
> gs.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Register/SpiR
> egs.h
> new file mode 100644
> index 0000000000..8e2029500c
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Register/SpiR
> egs.h
> @@ -0,0 +1,136 @@
> +/** @file
>
> + Register names for PCH SPI device.
>
> +
>
> + Conventions:
>
> +
>
> + - Register definition format:
>
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterS
> pace_RegisterName
>
> + - Prefix:
>
> + Definitions beginning with "R_" are registers
>
> + Definitions beginning with "B_" are bits within registers
>
> + Definitions beginning with "V_" are meaningful values within the bits
>
> + Definitions beginning with "S_" are register size
>
> + Definitions beginning with "N_" are the bit position
>
> + - [GenerationName]:
>
> + Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
>
> + Register name without GenerationName applies to all generations.
>
> + - [ComponentName]:
>
> + This field indicates the component name that the register belongs to (e.g.
> PCH, SA etc.)
>
> + Register name without ComponentName applies to all components.
>
> + Register that is specific to -LP denoted by "_PCH_LP_" in component
> name.
>
> + - SubsystemName:
>
> + This field indicates the subsystem name of the component that the
> register belongs to
>
> + (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
>
> + - RegisterSpace:
>
> + MEM - MMIO space register of subsystem.
>
> + IO - IO space register of subsystem.
>
> + PCR - Private configuration register of subsystem.
>
> + CFG - PCI configuration space register of subsystem.
>
> + - RegisterName:
>
> + Full register name.
>
> +
>
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +#ifndef _SPI_REGS_H_
>
> +#define _SPI_REGS_H_
>
> +
>
> +//
>
> +// SPI Registers
>
> +//
>
> +#define R_SPI_CFG_BAR0 0x10
>
> +#define B_SPI_CFG_BAR0_MASK 0x0FFF
>
> +
>
> +#define R_SPI_CFG_BDE 0xD8
>
> +
>
> +#define R_SPI_CFG_BC 0xDC
>
> +#define S_SPI_CFG_BC 4
>
> +#define N_SPI_CFG_BC_ASE_BWP 11
>
> +#define B_SPI_CFG_BC_ASE_BWP BIT11
>
> +#define N_SPI_CFG_BC_ASYNC_SS 10
>
> +#define B_SPI_CFG_BC_ASYNC_SS BIT10
>
> +#define N_SPI_CFG_BC_SYNC_SS 8
>
> +#define B_SPI_CFG_BC_SYNC_SS BIT8
>
> +#define B_SPI_CFG_BC_BILD BIT7
>
> +#define B_SPI_CFG_BC_BBS BIT6 ///< Boot BIOS strap
>
> +#define N_SPI_CFG_BC_BBS 6
>
> +#define V_SPI_CFG_BC_BBS_SPI 0 ///< Boot BIOS strapped
> to SPI
>
> +#define B_SPI_CFG_BC_EISS BIT5 ///< Enable InSMM.STS
>
> +#define B_SPI_CFG_BC_TSS BIT4
>
> +#define B_SPI_CFG_BC_SRC (BIT3 | BIT2)
>
> +#define N_SPI_CFG_BC_SRC 2
>
> +#define V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_DIS 0x01 ///< No
> prefetching and no caching
>
> +#define B_SPI_CFG_BC_LE BIT1 ///< Lock Enable
>
> +#define N_SPI_CFG_BC_BLE 1
>
> +#define B_SPI_CFG_BC_WPD BIT0 ///< Write Protect Disable
>
> +
>
> +//
>
> +// BIOS Flash Program Registers (based on SPI_BAR0)
>
> +//
>
> +#define R_SPI_MEM_HSFSC 0x04 ///< Hardware
> Sequencing Flash Status and Control Register(32bits)
>
> +#define B_SPI_MEM_HSFSC_FDBC_MASK 0x3F000000 ///<
> Flash Data Byte Count ( <= 64), Count = (Value in this field) + 1.
>
> +#define N_SPI_MEM_HSFSC_FDBC 24
>
> +#define B_SPI_MEM_HSFSC_CYCLE_MASK 0x001E0000 ///<
> Flash Cycle.
>
> +#define N_SPI_MEM_HSFSC_CYCLE 17
>
> +#define V_SPI_MEM_HSFSC_CYCLE_READ 0 ///< Flash
> Cycle Read
>
> +#define V_SPI_MEM_HSFSC_CYCLE_WRITE 2 ///< Flash
> Cycle Write
>
> +#define V_SPI_MEM_HSFSC_CYCLE_4K_ERASE 3 ///< Flash
> Cycle 4K Block Erase
>
> +#define V_SPI_MEM_HSFSC_CYCLE_64K_ERASE 4 ///<
> Flash Cycle 64K Sector Erase
>
> +#define V_SPI_MEM_HSFSC_CYCLE_READ_SFDP 5 ///<
> Flash Cycle Read SFDP
>
> +#define V_SPI_MEM_HSFSC_CYCLE_READ_JEDEC_ID 6 ///<
> Flash Cycle Read JEDEC ID
>
> +#define V_SPI_MEM_HSFSC_CYCLE_WRITE_STATUS 7 ///<
> Flash Cycle Write Status
>
> +#define V_SPI_MEM_HSFSC_CYCLE_READ_STATUS 8 ///<
> Flash Cycle Read Status
>
> +#define B_SPI_MEM_HSFSC_CYCLE_FGO BIT16 ///< Flash
> Cycle Go.
>
> +#define B_SPI_MEM_HSFSC_FLOCKDN BIT15 ///< Flash
> Configuration Lock-Down
>
> +#define B_SPI_MEM_HSFSC_FDV BIT14 ///< Flash
> Descriptor Valid, once valid software can use hareware sequencing regs
>
> +#define B_SPI_MEM_HSFSC_FDOPSS BIT13 ///< Flash
> Descriptor Override Pin-Strap Status
>
> +#define B_SPI_MEM_HSFSC_WRSDIS BIT11 ///< Write
> Status Disable
>
> +#define B_SPI_MEM_HSFSC_SAF_MODE_ACTIVE BIT7 ///<
> Indicates flash is attached either directly to the PCH via the SPI bus or
> EC/BMC
>
> +#define B_SPI_MEM_HSFSC_SCIP BIT5 ///< SPI cycle in
> progress
>
> +#define B_SPI_MEM_HSFSC_SAF_DLE BIT4 ///< SAF Data
> length error
>
> +#define B_SPI_MEM_HSFSC_SAF_ERROR BIT3 ///< SAF
> Error
>
> +#define B_SPI_MEM_HSFSC_AEL BIT2 ///< Access Error
> Log
>
> +#define B_SPI_MEM_HSFSC_FCERR BIT1 ///< Flash
> Cycle Error
>
> +#define B_SPI_MEM_HSFSC_FDONE BIT0 ///< Flash
> Cycle Done
>
> +#define R_SPI_MEM_FADDR 0x08 ///< SPI Flash
> Address
>
> +#define B_SPI_MEM_FADDR_MASK 0x07FFFFFF ///< SPI
> Flash Address Mask (0~26bit)
>
> +#define R_SPI_MEM_DLOCK 0x0C ///< Discrete Lock
> Bits
>
> +#define B_SPI_MEM_DLOCK_PR0LOCKDN BIT8 ///<
> PR0LOCKDN
>
> +#define R_SPI_MEM_FDATA00 0x10 ///< SPI Data 00
> (32 bits)
>
> +#define R_SPI_MEM_FRAP 0x50 ///< Flash Region
> Access Permissions Register
>
> +#define B_SPI_MEM_FRAP_BRWA_MASK 0x0000FF00 ///<
> BIOS Region Write Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2:
> ME; 3: GbE; 4: PlatformData
>
> +#define N_SPI_MEM_FRAP_BRWA 8 ///< BIOS
> Region Write Access bit position
>
> +#define B_SPI_MEM_FRAP_BRRA_MASK 0x000000FF ///<
> BIOS Region Read Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2:
> ME; 3: GbE; 4: PlatformData
>
> +#define B_SPI_MEM_FRAP_BMRAG_MASK 0x00FF0000 ///<
> BIOS Master Read Access Grant
>
> +#define B_SPI_MEM_FRAP_BMWAG_MASK 0xFF000000 ///<
> BIOS Master Write Access Grant
>
> +#define R_SPI_MEM_FREG0_FLASHD 0x54 ///< Flash
> Region 0(Flash Descriptor)(32bits)
>
> +#define R_SPI_MEM_FREG3_GBE 0x60 ///< Flash
> Region 3(GbE)(32bits)
>
> +#define S_SPI_MEM_FREGX 4 ///< Size of Flash
> Region register
>
> +#define B_SPI_MEM_FREGX_LIMIT_MASK 0x7FFF0000 ///<
> Flash Region Limit [30:16] represents [26:12], [11:0] are assumed to be FFFh
>
> +#define N_SPI_MEM_FREGX_LIMIT 16 ///< Region limit
> bit position
>
> +#define N_SPI_MEM_FREGX_LIMIT_REPR 12 ///< Region
> limit bit represents position
>
> +#define B_SPI_MEM_FREGX_BASE_MASK 0x00007FFF ///<
> Flash Region Base, [14:0] represents [26:12]
>
> +#define N_SPI_MEM_FREGX_BASE 0 ///< Region base
> bit position
>
> +#define N_SPI_MEM_FREGX_BASE_REPR 12 ///< Region
> base bit represents position
>
> +#define R_SPI_MEM_PR0 0x84 ///< Protected
> Region 0 Register
>
> +#define S_SPI_MEM_PRX 4 ///< Protected Region
> X Register size
>
> +#define B_SPI_MEM_PRX_WPE BIT31 ///< Write
> Protection Enable
>
> +#define B_SPI_MEM_PRX_PRL_MASK 0x7FFF0000 ///<
> Protected Range Limit Mask, [30:16] here represents upper limit of address
> [26:12]
>
> +#define N_SPI_MEM_PRX_PRL 16 ///< Protected
> Range Limit bit position
>
> +#define B_SPI_MEM_PRX_RPE BIT15 ///< Read
> Protection Enable
>
> +#define B_SPI_MEM_PRX_PRB_MASK 0x00007FFF ///<
> Protected Range Base Mask, [14:0] here represents base limit of address
> [26:12]
>
> +#define N_SPI_MEM_PRX_PRB 0 ///< Protected
> Range Base bit position
>
> +#define R_SPI_MEM_FDOC 0xB4 ///< Flash
> Descriptor Observability Control Register(32 bits)
>
> +#define B_SPI_MEM_FDOC_FDSS_MASK (BIT14 | BIT13 | BIT12)
> ///< Flash Descritor Section Select
>
> +#define V_SPI_MEM_FDOC_FDSS_FSDM 0x0000 ///< Flash
> Signature and Descriptor Map
>
> +#define V_SPI_MEM_FDOC_FDSS_COMP 0x1000 ///<
> Component
>
> +#define V_SPI_MEM_FDOC_FDSS_MSTR 0x3000 ///<
> Master
>
> +#define B_SPI_MEM_FDOC_FDSI_MASK 0x0FFC ///< Flash
> Descriptor Section Index
>
> +#define R_SPI_MEM_FDOD 0xB8 ///< Flash
> Descriptor Observability Data Register(32 bits)
>
> +#define R_SPI_MEM_SFDP0_VSCC0 0xC4 ///< Vendor
> Specific Component Capabilities Register(32 bits)
>
> +#define B_SPI_MEM_SFDPX_VSCCX_CPPTV BIT31 ///<
> Component Property Parameter Table Valid
>
> +#define B_SPI_MEM_SFDP0_VSCC0_VCL BIT30 ///<
> Vendor Component Lock
>
> +#define B_SPI_MEM_SFDPX_VSCCX_EO_64K BIT29 ///< 64k
> Erase valid (EO_64k_valid)
>
> +#define R_SPI_MEM_SFDP1_VSCC1 0xC8 ///< Vendor
> Specific Component Capabilities Register(32 bits)
>
> +
>
> +#endif
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccess
> Lib/PeiDxeSmmSpiAccessLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccess
> Lib/PeiDxeSmmSpiAccessLib.inf
> new file mode 100644
> index 0000000000..bba0b1fef3
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccess
> Lib/PeiDxeSmmSpiAccessLib.inf
> @@ -0,0 +1,33 @@
> +## @file
>
> +# Component description file for PCH SPI access library
>
> +#
>
> +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +
>
> +[Defines]
>
> +INF_VERSION = 0x00010017
>
> +BASE_NAME = PeiDxeSmmSpiAccessLib
>
> +FILE_GUID = A6D4C05A-F6CB-46D5-4BA1-8C47B139DCA6
>
> +VERSION_STRING = 1.0
>
> +MODULE_TYPE = BASE
>
> +LIBRARY_CLASS = SpiAccessLib
>
> +
>
> +
>
> +[LibraryClasses]
>
> +BaseLib
>
> +IoLib
>
> +DebugLib
>
> +PciSegmentLib
>
> +PchPciBdfLib
>
> +PchPcrLib
>
> +
>
> +[Packages]
>
> +MdePkg/MdePkg.dec
>
> +TigerlakeSiliconPkg/SiPkg.dec
>
> +
>
> +
>
> +[Sources]
>
> +SpiAccessLib.c
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccess
> Lib/SpiAccessLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccess
> Lib/SpiAccessLib.c
> new file mode 100644
> index 0000000000..c91b9aaf4d
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccess
> Lib/SpiAccessLib.c
> @@ -0,0 +1,477 @@
> +/** @file
>
> + SPI library for abstraction of SPI HW registers accesses
>
> +
>
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +
>
> +#include <Base.h>
>
> +#include <Uefi/UefiBaseType.h>
>
> +#include <IndustryStandard/Pci22.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/IoLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/PciSegmentLib.h>
>
> +#include <Library/SpiAccessLib.h>
>
> +#include <Library/PchPciBdfLib.h>
>
> +#include <Library/PchPcrLib.h>
>
> +#include <Register/SpiRegs.h>
>
> +#include <Register/FlashRegs.h>
>
> +#include <Register/PchRegs.h>
>
> +#include <Register/PchPcrRegs.h>
>
> +#include <Register/PchDmiRegs.h>
>
> +
>
> +/**
>
> + Checks if PCH SPI Controler is present and available
>
> +
>
> + @retval TRUE PCH SPI controller is avaialable
>
> + @retval FALSE PCH SPI controller is not available
>
> +**/
>
> +BOOLEAN
>
> +SpiIsControllerAvailable (
>
> + VOID
>
> + )
>
> +{
>
> + //
>
> + // Checks for SPI controller
>
> + //
>
> + return (PciSegmentRead16 (SpiPciCfgBase () + PCI_VENDOR_ID_OFFSET)
> != 0xFFFF);
>
> +}
>
> +
>
> +/**
>
> + Returns PCH SPI BAR0 value
>
> +
>
> + @retval UINT32 PCH SPI BAR0 value
>
> +**/
>
> +UINT32
>
> +SpiGetBar0 (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> +
>
> + ASSERT (SpiIsControllerAvailable ());
>
> + SpiBar0 = PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BAR0) &
> ~B_SPI_CFG_BAR0_MASK;
>
> + ASSERT (SpiBar0 != 0);
>
> +
>
> + return SpiBar0;
>
> +}
>
> +
>
> +/**
>
> + Reads given descriptor section and returns value
>
> +
>
> + @param[in] UINT16 Descriptor section
>
> + @param[in] UINT16 Offset
>
> +
>
> + @retval UINT32 Read value from a section under given offset
>
> +**/
>
> +STATIC
>
> +UINT32
>
> +SpiReadDescriptor (
>
> + IN UINT16 DescriptorSection,
>
> + IN UINT16 Offset
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> + SpiBar0 = SpiGetBar0 ();
>
> +
>
> + MmioWrite32 (SpiBar0 + R_SPI_MEM_FDOC, (DescriptorSection | Offset));
>
> + return MmioRead32 (SpiBar0 + R_SPI_MEM_FDOD);
>
> +}
>
> +
>
> +/**
>
> + Returns descriptor signature
>
> +
>
> + @retval UINT32 Descriptor signature
>
> +**/
>
> +UINT32
>
> +SpiGetDescriptorSignature (
>
> + VOID
>
> + )
>
> +{
>
> + //
>
> + // Read Descriptor offset 0x10 - To get Descriptor Signature
>
> + // Signature section 0x0000 + offset 0x0 which points to Descriptor offset
> 0x10
>
> + //
>
> + return SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM, 0x0);
>
> +}
>
> +
>
> +/**
>
> + Returns supported features and R/W frequencies of Flash Component
>
> +
>
> + @retval UINT32 Flash Component features descriptor
>
> +**/
>
> +UINT32
>
> +SpiGetFlashComponentDescription (
>
> + VOID
>
> + )
>
> +{
>
> + //
>
> + // Read Descriptor offset 0x30 - To get supported features and R/W
> frequencies
>
> + // Component section 0x1000 + offset 0x0 which points to Descriptor
> offset 0x30
>
> + //
>
> + return SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_COMP, 0x0);
>
> +}
>
> +
>
> +/**
>
> + Returns number of Flash Components
>
> +
>
> + @retval UINT32 Flash components number
>
> +**/
>
> +UINT32
>
> +SpiGetFlashComponentsNumber (
>
> + VOID
>
> + )
>
> +{
>
> + //
>
> + // Read Descriptor offset 0x14 - To get number of components
>
> + // Signature section 0x0000 + offset 0x4 which points to Descriptor offset
> 0x14
>
> + //
>
> + return ((SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM,
> R_FLASH_FDBAR_FLASH_MAP0) & B_FLASH_FDBAR_NC) >>
> N_FLASH_FDBAR_NC);
>
> +}
>
> +
>
> +/**
>
> + Returns total Flash size with regards to number of flash components
>
> +
>
> + @retval UINT32 Total Flash Memory size
>
> +**/
>
> +UINT32
>
> +SpiGetTotalFlashSize (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 Data32;
>
> + UINT32 ComponentsNumber;
>
> + UINT32 TotalFlashSize;
>
> +
>
> + Data32 = SpiGetFlashComponentDescription ();
>
> + ComponentsNumber = SpiGetFlashComponentsNumber ();
>
> +
>
> + TotalFlashSize = (V_FLASH_FLCOMP_COMP_512KB << ((UINT8) (Data32 &
> B_FLASH_FLCOMP_COMP0_MASK)));
>
> + if (ComponentsNumber == 1) {
>
> + TotalFlashSize += (V_FLASH_FLCOMP_COMP_512KB << ((UINT8) ((Data32
> & B_FLASH_FLCOMP_COMP1_MASK) >> 4)));
>
> + }
>
> +
>
> + return TotalFlashSize;
>
> +}
>
> +
>
> +/**
>
> + Checks BIOS lock bits for proper value and checks if write protection is
> enabled
>
> + Expected vales are: LE bit set, EISS bit set and WPD bit cleared
>
> +
>
> + @retval TRUE All protection bits are set correctly
>
> + @retval FALSE Not all protection bits had exepcted values
>
> +**/
>
> +BOOLEAN
>
> +SpiIsWriteProtectionEnabled (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 BiosControl;
>
> + BiosControl = PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC);
>
> +
>
> + DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL LE: %x\n", (BiosControl &
> B_SPI_CFG_BC_LE) != 0 ));
>
> + DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL WPD: %x\n", (BiosControl &
> B_SPI_CFG_BC_WPD) != 0 ));
>
> + DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL EISS: %x\n", (BiosControl &
> B_SPI_CFG_BC_EISS) != 0 ));
>
> +
>
> + return (((BiosControl & B_SPI_CFG_BC_LE) != 0) &&
>
> + ((BiosControl & B_SPI_CFG_BC_WPD) == 0) &&
>
> + ((BiosControl & B_SPI_CFG_BC_EISS) != 0));
>
> +}
>
> +
>
> +/**
>
> + Returns status of BIOS Interface Lockdown
>
> +
>
> + @retval TRUE BIOS Interface Lockdown is enabled
>
> + @retval FALSE BIOS Interface Lockdown is disabled
>
> +**/
>
> +BOOLEAN
>
> +SpiIsBiosInterfaceLockdownEnabled (
>
> + VOID
>
> + )
>
> +{
>
> + return !!(PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC) &
> B_SPI_CFG_BC_BILD);
>
> +}
>
> +
>
> +/**
>
> + Returns Flash Descriptor Override Pin Strap status
>
> +
>
> + @retval TRUE Flash Descriptor override is enabled
>
> + @retval FALSE Flash Descriptor override is disabled
>
> +**/
>
> +BOOLEAN
>
> +SpiIsFlashDescriptorOverrideEnabled (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> + SpiBar0 = SpiGetBar0 ();
>
> +
>
> + return !!(MmioRead16 (SpiBar0 + R_SPI_MEM_HSFSC) &
> B_SPI_MEM_HSFSC_FDOPSS);
>
> +}
>
> +
>
> +/**
>
> + Returns Flash Configuration Lock Down bit status
>
> +
>
> + @retval TRUE Flash Configuration Lock Down bit is set
>
> + @retval FALSE Flash Configuration Lock Down bit is not set
>
> +**/
>
> +BOOLEAN
>
> +SpiIsFlashConfigurationLockDownEnabled (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> + SpiBar0 = SpiGetBar0 ();
>
> +
>
> + return !!(MmioRead16 (SpiBar0 + R_SPI_MEM_HSFSC) &
> B_SPI_MEM_HSFSC_FLOCKDN);
>
> +}
>
> +
>
> +/**
>
> + Returns Top Swap functionality enable state
>
> +
>
> + @retval TRUE Top Swap is enabled
>
> + @retval FALSE Top Swap is disabled
>
> +**/
>
> +BOOLEAN
>
> +SpiIsTopSwapEnabled (
>
> + VOID
>
> + )
>
> +{
>
> + return !!(PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC) &
> B_SPI_CFG_BC_TSS);
>
> +}
>
> +
>
> +/**
>
> + Return Component Property Parameter Table for a given component
> number
>
> +
>
> + @param[in] ComponentNumber SPI Component number
>
> + @param[out] CppTable Component Poperty Parameter Table value
>
> +
>
> + @retval TRUE Vendor Specific Component Capabilities Register value was
> read
>
> + @reval FALSE Vendor Specific Component Capabilities Register value was
> not present
>
> +**/
>
> +BOOLEAN
>
> +SpiGetComponentPropertyParameterTable (
>
> + IN UINT8 ComponentNumber,
>
> + OUT UINT32 *CppTable
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> + UINT32 Data32;
>
> + SpiBar0 = SpiGetBar0 ();
>
> +
>
> + //
>
> + // More than 2 components not supported
>
> + //
>
> + switch (ComponentNumber) {
>
> + case 0:
>
> + *CppTable = MmioRead32 (SpiBar0 + R_SPI_MEM_SFDP0_VSCC0);
>
> + return TRUE;
>
> + case 1:
>
> + Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM,
> R_FLASH_FDBAR_FLASH_MAP0);
>
> + *CppTable = MmioRead32 (SpiBar0 + R_SPI_MEM_SFDP1_VSCC1);
>
> + return !!(Data32 & BIT8);
>
> + default:
>
> + return FALSE;
>
> + }
>
> +}
>
> +
>
> +/**
>
> + Returns valid bit status in given Component Property Parameter Table
>
> +
>
> + @param[in] CppTable Component Poperty Parameter Table value
>
> +
>
> + @retval TRUE Valid bit is set
>
> + @reval FALSE Valid bit is not set
>
> +**/
>
> +BOOLEAN
>
> +SpiIsCppValidBitSet (
>
> + IN UINT32 CppTable
>
> + )
>
> +{
>
> + return !!(CppTable & B_SPI_MEM_SFDPX_VSCCX_CPPTV);
>
> +}
>
> +
>
> +/**
>
> + Checks if Flash Descriptor is valid
>
> +
>
> + @retval TRUE Flash Descriptor is valid
>
> + @retval FALSE Flash Descriptor is invalid
>
> +**/
>
> +BOOLEAN
>
> +SpiIsFlashDescriptorValid (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> + SpiBar0 = SpiGetBar0 ();
>
> +
>
> + return !!(MmioRead32 (SpiBar0 + R_SPI_MEM_HSFSC) &
> B_SPI_MEM_HSFSC_FDV);
>
> +}
>
> +
>
> +/**
>
> + Reads and returns value from Flash Region Access Permissions Register
> (FRAP)
>
> +
>
> + @retval UINT32 Flash Region Access Permissions Register value
>
> +**/
>
> +STATIC
>
> +UINT32
>
> +SpiGetFlashRegionAccessPermissions (
>
> + VOID
>
> + )
>
> +{
>
> + return MmioRead32 (SpiGetBar0 () + R_SPI_MEM_FRAP);
>
> +}
>
> +
>
> +/**
>
> + Returns masked BIOS Master Read Access
>
> +
>
> + @retval UINT32 Already masked BIOS Master Read Access
>
> +**/
>
> +UINT32
>
> +SpiGetMasterReadAccess (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 Data32;
>
> + Data32 = SpiGetFlashRegionAccessPermissions () &
> B_SPI_MEM_FRAP_BMRAG_MASK;
>
> + DEBUG ((DEBUG_INFO, "BMRAG 0x%x\n", Data32));
>
> +
>
> + return Data32;
>
> +}
>
> +
>
> +/**
>
> + Returns masked BIOS Master Write Access
>
> +
>
> + @retval UINT32 Already masked BIOS Master Write Access
>
> +**/
>
> +UINT32
>
> +SpiGetMasterWriteAccess (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 Data32;
>
> + Data32 = SpiGetFlashRegionAccessPermissions () &
> B_SPI_MEM_FRAP_BMWAG_MASK;
>
> + DEBUG ((DEBUG_INFO, "BMWAG 0x%x\n", Data32));
>
> +
>
> + return Data32;
>
> +}
>
> +
>
> +/**
>
> + Returns GbE Region Access rights
>
> +
>
> + @retval UINT32 GbE Region access rights
>
> +**/
>
> +UINT32
>
> +SpiGetGbeRegionAccess (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 Data32;
>
> +
>
> + Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x8);
>
> + DEBUG ((DEBUG_INFO, "GbE Region Access 0x%x\n", Data32));
>
> +
>
> + return Data32;
>
> +}
>
> +
>
> +/**
>
> + Returns CSME region access rights
>
> +
>
> + @retval UINT32 CSME Region Access rights
>
> +**/
>
> +UINT32
>
> +SpiGetCsmeRegionAccess (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 Data32;
>
> +
>
> + Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x4);
>
> + DEBUG ((DEBUG_INFO, "CSME Region Access 0x%x\n", Data32));
>
> +
>
> + return Data32;
>
> +}
>
> +
>
> +/**
>
> + Returns EC region access right
>
> +
>
> + @retval UINT32 EC Region access rights
>
> +**/
>
> +UINT32
>
> +SpiGetEcRegionAccess (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 Data32;
>
> +
>
> + Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x10);
>
> + DEBUG ((DEBUG_INFO, "EC Region Access 0x%x\n", Data32));
>
> +
>
> + return Data32;
>
> +}
>
> +
>
> +/**
>
> + Checks if Slave Attached Flash (SAF) mode is active
>
> +
>
> + @retval TRUE SAF mode is active
>
> + @retval FALSE SAF mode is not active
>
> +**/
>
> +BOOLEAN
>
> +SpiIsSafModeActive (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> + SpiBar0 = SpiGetBar0 ();
>
> +
>
> + return !!(MmioRead32 (SpiBar0 + R_SPI_MEM_HSFSC) &
> B_SPI_MEM_HSFSC_SAF_MODE_ACTIVE);
>
> +}
>
> +
>
> +/**
>
> + Checks validity of GbE region
>
> +
>
> + @retval TRUE GbE region is valid
>
> + @retval FALSE GbE regios in invalid
>
> +**/
>
> +BOOLEAN
>
> +SpiIsGbeRegionValid (
>
> + VOID
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> + SpiBar0 = SpiGetBar0 ();
>
> +
>
> + if (MmioRead32 (SpiBar0 + R_SPI_MEM_FREG3_GBE) !=
> B_SPI_MEM_FREGX_BASE_MASK) {
>
> + return TRUE;
>
> + }
>
> + return FALSE;
>
> +}
>
> +
>
> +/**
>
> + Returns TRUE if BIOS Boot Strap is set to SPI
>
> +
>
> + @retval TRUE BIOS Boot strap is set to SPI
>
> + @retval FALSE BIOS Boot strap is set to LPC/eSPI
>
> +**/
>
> +BOOLEAN
>
> +SpiIsBiosBootFromSpi (
>
> + VOID
>
> + )
>
> +{
>
> + return !!(((PciSegmentRead8 (SpiPciCfgBase () + R_SPI_CFG_BC) &
> B_SPI_CFG_BC_BBS) >> N_SPI_CFG_BC_BBS) == V_SPI_CFG_BC_BBS_SPI);
>
> +}
>
> +
>
> +/**
>
> + Check SPI write status disable is set
>
> +
>
> + @retval TRUE Write status disable is set
>
> + @retval FALSE Write status disable is not set
>
> +**/
>
> +BOOLEAN
>
> +SpiIsWriteStatusDisable (
>
> + VOID
>
> + )
>
> +{
>
> + return !!(MmioRead32 (SpiGetBar0 () + R_SPI_MEM_HSFSC) &
> B_SPI_MEM_HSFSC_WRSDIS);
>
> +}
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiComm
> onLib/BaseSpiCommonLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiComm
> onLib/BaseSpiCommonLib.inf
> new file mode 100644
> index 0000000000..a1a5467745
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiComm
> onLib/BaseSpiCommonLib.inf
> @@ -0,0 +1,31 @@
> +## @file
>
> +# Component description file for the PchSpiCommonLib
>
> +#
>
> +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = BaseSpiCommonLib
>
> + FILE_GUID = A37CB67E-7D85-45B3-B07E-BF65BDB603E8
>
> + MODULE_TYPE = BASE
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = SpiCommonLib
>
> +
>
> +[Sources]
>
> + SpiCommon.c
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + TigerlakeSiliconPkg/SiPkg.dec
>
> +
>
> +[LibraryClasses]
>
> + IoLib
>
> + DebugLib
>
> + PmcLib
>
> + PchPciBdfLib
>
> + SpiAccessLib
>
> +
>
> +[Pcd]
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiComm
> onLib/SpiCommon.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiComm
> onLib/SpiCommon.c
> new file mode 100644
> index 0000000000..954b349e7c
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiComm
> onLib/SpiCommon.c
> @@ -0,0 +1,1115 @@
> +/** @file
>
> + PCH SPI Common Driver implements the SPI Host Controller Compatibility
> Interface.
>
> +
>
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +#include <Uefi/UefiBaseType.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/IoLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <IndustryStandard/Pci30.h>
>
> +#include <Library/PmcLib.h>
>
> +#include <Library/PciSegmentLib.h>
>
> +#include <Protocol/Spi.h>
>
> +#include <Library/SpiCommonLib.h>
>
> +#include <Register/PchRegs.h>
>
> +#include <Register/SpiRegs.h>
>
> +#include <Register/FlashRegs.h>
>
> +#include <Register/PmcRegs.h>
>
> +#include <Library/PchPciBdfLib.h>
>
> +#include <Library/SpiAccessLib.h>
>
> +
>
> +/**
>
> + Initialize an SPI protocol instance.
>
> +
>
> + @param[in] SpiInstance Pointer to SpiInstance to initialize
>
> +
>
> + @retval EFI_SUCCESS The protocol instance was properly initialized
>
> + @exception EFI_UNSUPPORTED The PCH is not supported by this
> module
>
> +**/
>
> +EFI_STATUS
>
> +SpiProtocolConstructor (
>
> + IN SPI_INSTANCE *SpiInstance
>
> + )
>
> +{
>
> + UINTN PchSpiBar0;
>
> + UINT32 Data32;
>
> + UINT16 Mdtba;
>
> + EFI_STATUS Status;
>
> +
>
> + //
>
> + // Initialize the SPI protocol instance
>
> + //
>
> + SpiInstance->Signature = PCH_SPI_PRIVATE_DATA_SIGNATURE;
>
> + SpiInstance->Handle = NULL;
>
> + SpiInstance->SpiProtocol.Revision = PCH_SPI_SERVICES_REVISION;
>
> + SpiInstance->SpiProtocol.FlashRead = SpiProtocolFlashRead;
>
> + SpiInstance->SpiProtocol.FlashWrite = SpiProtocolFlashWrite;
>
> + SpiInstance->SpiProtocol.FlashErase = SpiProtocolFlashErase;
>
> + SpiInstance->SpiProtocol.FlashReadSfdp = SpiProtocolFlashReadSfdp;
>
> + SpiInstance->SpiProtocol.FlashReadJedecId =
> SpiProtocolFlashReadJedecId;
>
> + SpiInstance->SpiProtocol.FlashWriteStatus = SpiProtocolFlashWriteStatus;
>
> + SpiInstance->SpiProtocol.FlashReadStatus = SpiProtocolFlashReadStatus;
>
> + SpiInstance->SpiProtocol.GetRegionAddress =
> SpiProtocolGetRegionAddress;
>
> + SpiInstance->SpiProtocol.ReadPchSoftStrap =
> SpiProtocolReadPchSoftStrap;
>
> + SpiInstance->SpiProtocol.ReadCpuSoftStrap =
> SpiProtocolReadCpuSoftStrap;
>
> +
>
> + SpiInstance->PchSpiBase = SpiPciCfgBase ();
>
> +
>
> + SpiInstance->PchAcpiBase = PmcGetAcpiBase ();
>
> + ASSERT (SpiInstance->PchAcpiBase != 0);
>
> +
>
> + PchSpiBar0 = PciSegmentRead32 (SpiInstance->PchSpiBase +
> R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
>
> + if (PchSpiBar0 == 0) {
>
> + DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
>
> + ASSERT (FALSE);
>
> + }
>
> +
>
> + if ((MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC) &
> B_SPI_MEM_HSFSC_FDV) == 0) {
>
> + DEBUG ((DEBUG_ERROR, "ERROR : SPI Flash Signature invalid, cannot use
> the Hardware Sequencing registers!\n"));
>
> + ASSERT (FALSE);
>
> + }
>
> +
>
> + //
>
> + // Get Region 0 - 7 read Permission bits, region 8 and above are not
> permitted.
>
> + //
>
> + SpiInstance->ReadPermission = MmioRead8 (PchSpiBar0 +
> R_SPI_MEM_FRAP) & B_SPI_MEM_FRAP_BRRA_MASK;
>
> + DEBUG ((DEBUG_INFO, "Flash Region read Permission : %0x\n",
> SpiInstance->ReadPermission));
>
> + //
>
> + // Get Region 0 - 7 write Permission bits, region 8 and above are not
> permitted.
>
> + //
>
> + SpiInstance->WritePermission = (UINT8) ((MmioRead16 (PchSpiBar0 +
> R_SPI_MEM_FRAP) &
>
> + B_SPI_MEM_FRAP_BRWA_MASK) >>
> N_SPI_MEM_FRAP_BRWA);
>
> + DEBUG ((DEBUG_INFO, "Flash Region write Permission : %0x\n",
> SpiInstance->WritePermission));
>
> +
>
> + SpiInstance->SfdpVscc0Value = MmioRead32 (PchSpiBar0 +
> R_SPI_MEM_SFDP0_VSCC0);
>
> + DEBUG ((DEBUG_INFO, "Component 0 SFDP VSCC value : %0x\n",
> SpiInstance->SfdpVscc0Value));
>
> + SpiInstance->SfdpVscc1Value = MmioRead32 (PchSpiBar0 +
> R_SPI_MEM_SFDP1_VSCC1);
>
> + DEBUG ((DEBUG_INFO, "Component 1 SFDP VSCC value : %0x\n",
> SpiInstance->SfdpVscc1Value));
>
> +
>
> + //
>
> + // Select to Flash Map 0 Register to get the number of flash Component
>
> + //
>
> + MmioAndThenOr32 (
>
> + PchSpiBar0 + R_SPI_MEM_FDOC,
>
> + (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK |
> B_SPI_MEM_FDOC_FDSI_MASK)),
>
> + (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM |
> R_FLASH_FDBAR_FLASH_MAP0)
>
> + );
>
> +
>
> + //
>
> + // Copy Zero based Number Of Components
>
> + //
>
> + SpiInstance->NumberOfComponents = (UINT8) ((MmioRead16
> (PchSpiBar0 + R_SPI_MEM_FDOD) & B_FLASH_FDBAR_NC) >>
> N_FLASH_FDBAR_NC);
>
> + DEBUG ((DEBUG_INFO, "Component Number : %0x\n", SpiInstance-
> >NumberOfComponents + 1));
>
> +
>
> + MmioAndThenOr32 (
>
> + PchSpiBar0 + R_SPI_MEM_FDOC,
>
> + (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK |
> B_SPI_MEM_FDOC_FDSI_MASK)),
>
> + (UINT32) (V_SPI_MEM_FDOC_FDSS_COMP | R_FLASH_FCBA_FLCOMP)
>
> + );
>
> +
>
> + //
>
> + // Copy Component 0 Density
>
> + //
>
> + Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
>
> + if (SpiInstance->NumberOfComponents > 0) {
>
> + SpiInstance->Component1StartAddr = V_FLASH_FLCOMP_COMP_512KB
> <<
>
> + (Data32 & B_FLASH_FLCOMP_COMP0_MASK);
>
> + DEBUG ((DEBUG_INFO, "Component 1 StartAddr : %0x\n", SpiInstance-
> >Component1StartAddr));
>
> + SpiInstance->TotalFlashSize = SpiInstance->Component1StartAddr +
>
> + (V_FLASH_FLCOMP_COMP_512KB <<
>
> + ((Data32 & B_FLASH_FLCOMP_COMP1_MASK) >>
>
> + N_FLASH_FLCOMP_COMP1));
>
> + } else {
>
> + SpiInstance->TotalFlashSize = V_FLASH_FLCOMP_COMP_512KB <<
>
> + (Data32 & B_FLASH_FLCOMP_COMP0_MASK);
>
> + }
>
> + DEBUG ((DEBUG_INFO, "Total Flash Size : %0x\n", SpiInstance-
> >TotalFlashSize));
>
> +
>
> + //
>
> + // Select FLASH_MAP1 to get Flash PCH Strap Base Address
>
> + //
>
> + MmioAndThenOr32 (
>
> + (PchSpiBar0 + R_SPI_MEM_FDOC),
>
> + (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK |
> B_SPI_MEM_FDOC_FDSI_MASK)),
>
> + (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM |
> R_FLASH_FDBAR_FLASH_MAP1)
>
> + );
>
> + //
>
> + // Align FPSBA with address bits for the PCH Strap portion of flash
> descriptor
>
> + //
>
> + Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
>
> + SpiInstance->PchStrapBaseAddr = (UINT16) (((Data32 &
> B_FLASH_FDBAR_FPSBA)
>
> + >> N_FLASH_FDBAR_FPSBA)
>
> + << N_FLASH_FDBAR_FPSBA_REPR);
>
> + DEBUG ((DEBUG_INFO, "PchStrapBaseAddr : %0x\n", SpiInstance-
> >PchStrapBaseAddr));
>
> + ASSERT (SpiInstance->PchStrapBaseAddr != 0);
>
> + //
>
> + // PCH Strap Length, [31:24] represents number of Dwords
>
> + //
>
> + SpiInstance->PchStrapSize = (UINT16) (((Data32 &
> B_FLASH_FDBAR_PCHSL)
>
> + >> N_FLASH_FDBAR_PCHSL)
>
> + * sizeof (UINT32));
>
> + DEBUG ((DEBUG_INFO, "PchStrapSize : %0x\n", SpiInstance-
> >PchStrapSize));
>
> +
>
> + //
>
> + // Select FLASH_MAP2 to get Flash CPU Strap Base Address
>
> + //
>
> + MmioAndThenOr32 (
>
> + (PchSpiBar0 + R_SPI_MEM_FDOC),
>
> + (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK |
> B_SPI_MEM_FDOC_FDSI_MASK)),
>
> + (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM |
> R_FLASH_FDBAR_FLASH_MAP2)
>
> + );
>
> + //
>
> + // Align FPSBA with address bits for the CPU Strap portion of flash
> descriptor
>
> + //
>
> + Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
>
> + //
>
> + // CPU Strap Length, [23:16] represents number of Dwords
>
> + //
>
> + SpiInstance->CpuStrapSize = (UINT16) (((Data32 &
> B_FLASH_FDBAR_CPUSL)
>
> + >> N_FLASH_FDBAR_CPUSL)
>
> + * sizeof (UINT32));
>
> +
>
> + //
>
> + // CPU Strap Address [11:2] represent offset from MDTBA
>
> + //
>
> + SpiInstance->CpuStrapBaseAddr = (UINT16) ((Data32 &
> B_FLASH_FDBAR_FCPUSBA) >> N_FLASH_FDBAR_FCPUSBA);
>
> + ASSERT (SpiInstance->CpuStrapBaseAddr != 0);
>
> +
>
> + if (SpiInstance->CpuStrapBaseAddr != 0x300) {
>
> + Status = SpiProtocolFlashRead (&(SpiInstance->SpiProtocol),
> FlashRegionAll, R_FLASH_UMAP1, sizeof (Data32), (UINT8 *) (&Data32));
>
> + ASSERT_EFI_ERROR (Status);
>
> + Mdtba = (UINT16)(((Data32 & B_FLASH_UMAP1_MDTBA) >>
> N_FLASH_UMAP1_MDTBA) << N_FLASH_UMAP1_MDTBA_REPR);
>
> + DEBUG ((DEBUG_INFO, "Mdtba : %0x\n", Mdtba));
>
> + // Add MDTBA offset for final address of CPU Straps
>
> + SpiInstance->CpuStrapBaseAddr += Mdtba;
>
> + }
>
> +
>
> + DEBUG ((DEBUG_INFO, "CpuStrapBaseAddr : %0x\n", SpiInstance-
> >CpuStrapBaseAddr));
>
> + DEBUG ((DEBUG_INFO, "CpuStrapSize : %0x\n", SpiInstance-
> >CpuStrapSize));
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Delay for at least the request number of microseconds for Runtime usage.
>
> +
>
> + @param[in] ABase Acpi base address
>
> + @param[in] Microseconds Number of microseconds to delay.
>
> +
>
> +**/
>
> +VOID
>
> +EFIAPI
>
> +PchPmTimerStallRuntimeSafe (
>
> + IN UINT16 ABase,
>
> + IN UINTN Microseconds
>
> + )
>
> +{
>
> + UINTN Ticks;
>
> + UINTN Counts;
>
> + UINTN CurrentTick;
>
> + UINTN OriginalTick;
>
> + UINTN RemainingTick;
>
> +
>
> + if (Microseconds == 0) {
>
> + return;
>
> + }
>
> +
>
> + OriginalTick = IoRead32 ((UINTN) (ABase + R_ACPI_IO_PM1_TMR)) &
> B_ACPI_IO_PM1_TMR_VAL;
>
> + CurrentTick = OriginalTick;
>
> +
>
> + //
>
> + // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
>
> + //
>
> + Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
>
> +
>
> + //
>
> + // The loops needed by timer overflow
>
> + //
>
> + Counts = Ticks / V_ACPI_IO_PM1_TMR_MAX_VAL;
>
> +
>
> + //
>
> + // Remaining clocks within one loop
>
> + //
>
> + RemainingTick = Ticks % V_ACPI_IO_PM1_TMR_MAX_VAL;
>
> +
>
> + //
>
> + // not intend to use TMROF_STS bit of register PM1_STS, because this
> adds extra
>
> + // one I/O operation, and maybe generate SMI
>
> + //
>
> + while ((Counts != 0) || (RemainingTick > CurrentTick)) {
>
> + CurrentTick = IoRead32 ((UINTN) (ABase + R_ACPI_IO_PM1_TMR)) &
> B_ACPI_IO_PM1_TMR_VAL;
>
> + //
>
> + // Check if timer overflow
>
> + //
>
> + if ((CurrentTick < OriginalTick)) {
>
> + if (Counts != 0) {
>
> + Counts--;
>
> + } else {
>
> + //
>
> + // If timer overflow and Counts equ to 0, that means we already stalled
> more than
>
> + // RemainingTick, break the loop here
>
> + //
>
> + break;
>
> + }
>
> + }
>
> +
>
> + OriginalTick = CurrentTick;
>
> + }
>
> +}
>
> +
>
> +/**
>
> + Wait execution cycle to complete on the SPI interface.
>
> +
>
> + @param[in] This The SPI protocol instance
>
> + @param[in] PchSpiBar0 Spi MMIO base address
>
> + @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error
> check
>
> +
>
> + @retval TRUE SPI cycle completed on the interface.
>
> + @retval FALSE Time out while waiting the SPI cycle to complete.
>
> + It's not safe to program the next command on the SPI
> interface.
>
> +**/
>
> +STATIC
>
> +BOOLEAN
>
> +WaitForSpiCycleComplete (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINTN PchSpiBar0,
>
> + IN BOOLEAN ErrorCheck
>
> + )
>
> +{
>
> + UINT64 WaitTicks;
>
> + UINT64 WaitCount;
>
> + UINT32 Data32;
>
> + SPI_INSTANCE *SpiInstance;
>
> +
>
> + SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
>
> +
>
> + //
>
> + // Convert the wait period allowed into to tick count
>
> + //
>
> + WaitCount = SPI_WAIT_TIME / SPI_WAIT_PERIOD;
>
> + //
>
> + // Wait for the SPI cycle to complete.
>
> + //
>
> + for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
>
> + Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC);
>
> + if ((Data32 & B_SPI_MEM_HSFSC_SCIP) == 0) {
>
> + MmioWrite32 (PchSpiBar0 + R_SPI_MEM_HSFSC,
> B_SPI_MEM_HSFSC_FCERR | B_SPI_MEM_HSFSC_FDONE);
>
> + if (((Data32 & B_SPI_MEM_HSFSC_FCERR) != 0) && (ErrorCheck ==
> TRUE)) {
>
> + return FALSE;
>
> + } else {
>
> + return TRUE;
>
> + }
>
> + }
>
> + PchPmTimerStallRuntimeSafe (SpiInstance->PchAcpiBase,
> SPI_WAIT_PERIOD);
>
> + }
>
> + return FALSE;
>
> +}
>
> +
>
> +/**
>
> + This function sends the programmed SPI command to the slave device.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] SpiRegionType The SPI Region type for flash cycle which is
> listed in the Descriptor
>
> + @param[in] FlashCycleType The Flash SPI cycle type list in HSFC
> (Hardware Sequencing Flash Control Register) register
>
> + @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,out] Buffer Pointer to caller-allocated buffer containing
> the dada received or sent during the SPI cycle.
>
> +
>
> + @retval EFI_SUCCESS SPI command completes successfully.
>
> + @retval EFI_DEVICE_ERROR Device error, the command aborts
> abnormally.
>
> + @retval EFI_ACCESS_DENIED Some unrecognized or blocked command
> encountered in hardware sequencing mode
>
> + @retval EFI_INVALID_PARAMETER The parameters specified are not
> valid.
>
> +**/
>
> +STATIC
>
> +EFI_STATUS
>
> +SendSpiCmd (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + IN FLASH_CYCLE_TYPE FlashCycleType,
>
> + IN UINT32 Address,
>
> + IN UINT32 ByteCount,
>
> + IN OUT UINT8 *Buffer
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINT32 Index;
>
> + SPI_INSTANCE *SpiInstance;
>
> + UINT64 SpiBaseAddress;
>
> + UINTN PchSpiBar0;
>
> + UINT32 HardwareSpiAddr;
>
> + UINT32 FlashRegionSize;
>
> + UINT32 SpiDataCount;
>
> + UINT32 FlashCycle;
>
> + UINT8 BiosCtlSave;
>
> + UINT32 SmiEnSave;
>
> + UINT16 ABase;
>
> + UINT32 HsfstsCtl;
>
> +
>
> + //
>
> + // For flash write, there is a requirement that all CPU threads are in SMM
>
> + // before the flash protection is disabled.
>
> + //
>
> + if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType ==
> FlashCycleErase)) {
>
> + if (!IsSpiFlashWriteGranted ()) {
>
> + return EFI_ACCESS_DENIED;
>
> + }
>
> + }
>
> +
>
> + Status = EFI_SUCCESS;
>
> + SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
>
> + SpiBaseAddress = SpiInstance->PchSpiBase;
>
> + PchSpiBar0 = AcquireSpiBar0 (SpiInstance);
>
> + ABase = SpiInstance->PchAcpiBase;
>
> +
>
> + //
>
> + // Disable SMIs to make sure normal mode flash access is not interrupted
> by an SMI
>
> + // whose SMI handler accesses flash (e.g. for error logging)
>
> + //
>
> + // *** NOTE: if the SMI_LOCK bit is set (i.e., PMC PCI Offset A0h [4]='1'),
>
> + // clearing B_GBL_SMI_EN will not have effect. In this situation, some
> other
>
> + // synchronization methods must be applied here or in the consumer of
> the
>
> + // SendSpiCmd. An example method is disabling the specific SMI sources
>
> + // whose SMI handlers access flash before flash cycle and re-enabling the
> SMI
>
> + // sources after the flash cycle .
>
> + //
>
> + SmiEnSave = IoRead32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN));
>
> + IoWrite32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN), SmiEnSave & (UINT32)
> (~B_ACPI_IO_SMI_EN_GBL_SMI));
>
> + BiosCtlSave = PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) &
> B_SPI_CFG_BC_SRC;
>
> +
>
> + //
>
> + // If it's write cycle, disable Prefetching, Caching and disable BIOS Write
> Protect
>
> + //
>
> + if ((FlashCycleType == FlashCycleWrite) ||
>
> + (FlashCycleType == FlashCycleErase)) {
>
> + Status = DisableBiosWriteProtect ();
>
> + if (EFI_ERROR (Status)) {
>
> + goto SendSpiCmdEnd;
>
> + }
>
> + PciSegmentAndThenOr8 (
>
> + SpiBaseAddress + R_SPI_CFG_BC,
>
> + (UINT8) (~B_SPI_CFG_BC_SRC),
>
> + (UINT8) (V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_DIS <<
> N_SPI_CFG_BC_SRC)
>
> + );
>
> + }
>
> + //
>
> + // Make sure it's safe to program the command.
>
> + //
>
> + if (!WaitForSpiCycleComplete (This, PchSpiBar0, FALSE)) {
>
> + Status = EFI_DEVICE_ERROR;
>
> + goto SendSpiCmdEnd;
>
> + }
>
> +
>
> + //
>
> + // Check if Write Status isn't disabled in HW Sequencing
>
> + //
>
> + if (FlashCycleType == FlashCycleWriteStatus) {
>
> + HsfstsCtl = MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC);
>
> + if ((HsfstsCtl & B_SPI_MEM_HSFSC_WRSDIS) != 0) {
>
> + Status = EFI_ACCESS_DENIED;
>
> + goto SendSpiCmdEnd;
>
> + }
>
> + }
>
> +
>
> + Status = SpiProtocolGetRegionAddress (This, FlashRegionType,
> &HardwareSpiAddr, &FlashRegionSize);
>
> + if (EFI_ERROR (Status)) {
>
> + goto SendSpiCmdEnd;
>
> + }
>
> + HardwareSpiAddr += Address;
>
> + if ((Address + ByteCount) > FlashRegionSize) {
>
> + Status = EFI_INVALID_PARAMETER;
>
> + goto SendSpiCmdEnd;
>
> + }
>
> +
>
> + //
>
> + // Check for PCH SPI hardware sequencing required commands
>
> + //
>
> + FlashCycle = 0;
>
> + switch (FlashCycleType) {
>
> + case FlashCycleRead:
>
> + FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ <<
> N_SPI_MEM_HSFSC_CYCLE);
>
> + break;
>
> + case FlashCycleWrite:
>
> + FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_WRITE <<
> N_SPI_MEM_HSFSC_CYCLE);
>
> + break;
>
> + case FlashCycleErase:
>
> + if (((ByteCount % SIZE_4KB) != 0) ||
>
> + ((HardwareSpiAddr % SIZE_4KB) != 0)) {
>
> + ASSERT (FALSE);
>
> + Status = EFI_INVALID_PARAMETER;
>
> + goto SendSpiCmdEnd;
>
> + }
>
> + break;
>
> + case FlashCycleReadSfdp:
>
> + FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_SFDP <<
> N_SPI_MEM_HSFSC_CYCLE);
>
> + break;
>
> + case FlashCycleReadJedecId:
>
> + FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_JEDEC_ID <<
> N_SPI_MEM_HSFSC_CYCLE);
>
> + break;
>
> + case FlashCycleWriteStatus:
>
> + FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_WRITE_STATUS <<
> N_SPI_MEM_HSFSC_CYCLE);
>
> + break;
>
> + case FlashCycleReadStatus:
>
> + FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_STATUS <<
> N_SPI_MEM_HSFSC_CYCLE);
>
> + break;
>
> + default:
>
> + //
>
> + // Unrecognized Operation
>
> + //
>
> + ASSERT (FALSE);
>
> + Status = EFI_INVALID_PARAMETER;
>
> + goto SendSpiCmdEnd;
>
> + break;
>
> + }
>
> +
>
> + do {
>
> + SpiDataCount = ByteCount;
>
> + if ((FlashCycleType == FlashCycleRead) ||
>
> + (FlashCycleType == FlashCycleWrite) ||
>
> + (FlashCycleType == FlashCycleReadSfdp)) {
>
> + //
>
> + // Trim at 256 byte boundary per operation,
>
> + // - PCH SPI controller requires trimming at 4KB boundary
>
> + // - Some SPI chips require trimming at 256 byte boundary for write
> operation
>
> + // - Trimming has limited performance impact as we can read / write
> atmost 64 byte
>
> + // per operation
>
> + //
>
> + if (HardwareSpiAddr + ByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 -
> 1))) {
>
> + SpiDataCount = (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)) -
> (UINT32) (HardwareSpiAddr);
>
> + }
>
> + //
>
> + // Calculate the number of bytes to shift in/out during the SPI data cycle.
>
> + // Valid settings for the number of bytes duing each data portion of the
>
> + // PCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, 56, 64
>
> + //
>
> + if (SpiDataCount >= 64) {
>
> + SpiDataCount = 64;
>
> + } else if ((SpiDataCount &~0x07) != 0) {
>
> + SpiDataCount = SpiDataCount &~0x07;
>
> + }
>
> + }
>
> + if (FlashCycleType == FlashCycleErase) {
>
> + if (((ByteCount / SIZE_64KB) != 0) &&
>
> + ((ByteCount % SIZE_64KB) == 0) &&
>
> + ((HardwareSpiAddr % SIZE_64KB) == 0)) {
>
> + if ((SpiInstance->NumberOfComponents == 0) ||
>
> + (HardwareSpiAddr < SpiInstance->Component1StartAddr)) {
>
> + //
>
> + // Check whether Component0 support 64k Erase
>
> + //
>
> + if ((SpiInstance->SfdpVscc0Value &
> B_SPI_MEM_SFDPX_VSCCX_EO_64K) != 0) {
>
> + SpiDataCount = SIZE_64KB;
>
> + } else {
>
> + SpiDataCount = SIZE_4KB;
>
> + }
>
> + } else {
>
> + //
>
> + // Check whether Component1 support 64k Erase
>
> + //
>
> + if ((SpiInstance->SfdpVscc1Value &
> B_SPI_MEM_SFDPX_VSCCX_EO_64K) != 0) {
>
> + SpiDataCount = SIZE_64KB;
>
> + } else {
>
> + SpiDataCount = SIZE_4KB;
>
> + }
>
> + }
>
> + } else {
>
> + SpiDataCount = SIZE_4KB;
>
> + }
>
> + if (SpiDataCount == SIZE_4KB) {
>
> + FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_4K_ERASE <<
> N_SPI_MEM_HSFSC_CYCLE);
>
> + } else {
>
> + FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_64K_ERASE <<
> N_SPI_MEM_HSFSC_CYCLE);
>
> + }
>
> + }
>
> + //
>
> + // If it's write cycle, load data into the SPI data buffer.
>
> + //
>
> + if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType ==
> FlashCycleWriteStatus)) {
>
> + if ((SpiDataCount & 0x07) != 0) {
>
> + //
>
> + // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
>
> + //
>
> + for (Index = 0; Index < SpiDataCount; Index++) {
>
> + MmioWrite8 (PchSpiBar0 + R_SPI_MEM_FDATA00 + Index,
> Buffer[Index]);
>
> + }
>
> + } else {
>
> + //
>
> + // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
>
> + //
>
> + for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
>
> + MmioWrite32 (PchSpiBar0 + R_SPI_MEM_FDATA00 + Index, *(UINT32
> *) (Buffer + Index));
>
> + }
>
> + }
>
> + }
>
> +
>
> + //
>
> + // Set the Flash Address
>
> + //
>
> + MmioWrite32 (
>
> + (PchSpiBar0 + R_SPI_MEM_FADDR),
>
> + (UINT32) (HardwareSpiAddr & B_SPI_MEM_FADDR_MASK)
>
> + );
>
> +
>
> + //
>
> + // Set Data count, Flash cycle, and Set Go bit to start a cycle
>
> + //
>
> + MmioAndThenOr32 (
>
> + PchSpiBar0 + R_SPI_MEM_HSFSC,
>
> + (UINT32) (~(B_SPI_MEM_HSFSC_FDBC_MASK |
> B_SPI_MEM_HSFSC_CYCLE_MASK)),
>
> + (UINT32) ((((SpiDataCount - 1) << N_SPI_MEM_HSFSC_FDBC) &
> B_SPI_MEM_HSFSC_FDBC_MASK) | FlashCycle |
> B_SPI_MEM_HSFSC_CYCLE_FGO)
>
> + );
>
> + //
>
> + // end of command execution
>
> + //
>
> + // Wait the SPI cycle to complete.
>
> + //
>
> + if (!WaitForSpiCycleComplete (This, PchSpiBar0, TRUE)) {
>
> + ASSERT (FALSE);
>
> + Status = EFI_DEVICE_ERROR;
>
> + goto SendSpiCmdEnd;
>
> + }
>
> + //
>
> + // If it's read cycle, load data into the call's buffer.
>
> + //
>
> + if ((FlashCycleType == FlashCycleRead) ||
>
> + (FlashCycleType == FlashCycleReadSfdp) ||
>
> + (FlashCycleType == FlashCycleReadJedecId) ||
>
> + (FlashCycleType == FlashCycleReadStatus)) {
>
> + if ((SpiDataCount & 0x07) != 0) {
>
> + //
>
> + // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
>
> + //
>
> + for (Index = 0; Index < SpiDataCount; Index++) {
>
> + Buffer[Index] = MmioRead8 (PchSpiBar0 + R_SPI_MEM_FDATA00 +
> Index);
>
> + }
>
> + } else {
>
> + //
>
> + // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
>
> + //
>
> + for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
>
> + *(UINT32 *) (Buffer + Index) = MmioRead32 (PchSpiBar0 +
> R_SPI_MEM_FDATA00 + Index);
>
> + }
>
> + }
>
> + }
>
> +
>
> + HardwareSpiAddr += SpiDataCount;
>
> + Buffer += SpiDataCount;
>
> + ByteCount -= SpiDataCount;
>
> + } while (ByteCount > 0);
>
> +
>
> +SendSpiCmdEnd:
>
> + //
>
> + // Restore the settings for SPI Prefetching and Caching and enable BIOS
> Write Protect
>
> + //
>
> + if ((FlashCycleType == FlashCycleWrite) ||
>
> + (FlashCycleType == FlashCycleErase)) {
>
> + EnableBiosWriteProtect ();
>
> + PciSegmentAndThenOr8 (
>
> + SpiBaseAddress + R_SPI_CFG_BC,
>
> + (UINT8) ~B_SPI_CFG_BC_SRC,
>
> + BiosCtlSave
>
> + );
>
> + }
>
> + //
>
> + // Restore SMIs.
>
> + //
>
> + IoWrite32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN), SmiEnSave);
>
> +
>
> + ReleaseSpiBar0 (SpiInstance);
>
> +
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Read data from the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] FlashRegionType The Flash Region type for flash cycle which
> is listed 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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashRead (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + IN UINT32 Address,
>
> + IN UINT32 ByteCount,
>
> + OUT UINT8 *Buffer
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + //
>
> + // Sends the command to the SPI interface to execute.
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionType,
>
> + FlashCycleRead,
>
> + Address,
>
> + ByteCount,
>
> + Buffer
>
> + );
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Write data to the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] FlashRegionType The Flash Region type for flash cycle which
> is listed 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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashWrite (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + IN UINT32 Address,
>
> + IN UINT32 ByteCount,
>
> + IN UINT8 *Buffer
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + //
>
> + // Sends the command to the SPI interface to execute.
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionType,
>
> + FlashCycleWrite,
>
> + Address,
>
> + ByteCount,
>
> + Buffer
>
> + );
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Erase some area on the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] FlashRegionType The Flash Region type for flash cycle which
> is listed 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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashErase (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + IN UINT32 Address,
>
> + IN UINT32 ByteCount
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + //
>
> + // Sends the command to the SPI interface to execute.
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionType,
>
> + FlashCycleErase,
>
> + Address,
>
> + ByteCount,
>
> + NULL
>
> + );
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Read SFDP data from the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] ComponentNumber The Componen 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.
>
> + @retval EFI_UNSUPPORTED Unsupported operation with SAF Mode
> enabled
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashReadSfdp (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT8 ComponentNumber,
>
> + IN UINT32 Address,
>
> + IN UINT32 ByteCount,
>
> + OUT UINT8 *SfdpData
>
> + )
>
> +{
>
> + SPI_INSTANCE *SpiInstance;
>
> + EFI_STATUS Status;
>
> + UINT32 FlashAddress;
>
> +
>
> + if (SpiIsSafModeActive ()) {
>
> + DEBUG ((DEBUG_ERROR, "Unallowed call to %a while SAF Mode is
> active.\n", __FUNCTION__));
>
> + return EFI_UNSUPPORTED;
>
> + }
>
> +
>
> + SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
>
> + Status = EFI_SUCCESS;
>
> +
>
> + if (ComponentNumber > SpiInstance->NumberOfComponents) {
>
> + ASSERT (FALSE);
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + FlashAddress = 0;
>
> + if (ComponentNumber == FlashComponent1) {
>
> + FlashAddress = SpiInstance->Component1StartAddr;
>
> + }
>
> + FlashAddress += Address;
>
> + //
>
> + // Sends the command to the SPI interface to execute.
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionAll,
>
> + FlashCycleReadSfdp,
>
> + FlashAddress,
>
> + ByteCount,
>
> + SfdpData
>
> + );
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Read Jedec Id from the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] ComponentNumber The Componen 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.
>
> + @retval EFI_UNSUPPORTED Unsupported operation with SAF Mode
> enabled
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashReadJedecId (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT8 ComponentNumber,
>
> + IN UINT32 ByteCount,
>
> + OUT UINT8 *JedecId
>
> + )
>
> +{
>
> + SPI_INSTANCE *SpiInstance;
>
> + EFI_STATUS Status;
>
> + UINT32 Address;
>
> +
>
> + if (SpiIsSafModeActive ()) {
>
> + DEBUG ((DEBUG_ERROR, "Unallowed call to %a while SAF Mode is
> active.\n", __FUNCTION__));
>
> + return EFI_UNSUPPORTED;
>
> + }
>
> +
>
> + SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
>
> + Status = EFI_SUCCESS;
>
> +
>
> + if (ComponentNumber > SpiInstance->NumberOfComponents) {
>
> + ASSERT (FALSE);
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + Address = 0;
>
> + if (ComponentNumber == FlashComponent1) {
>
> + Address = SpiInstance->Component1StartAddr;
>
> + }
>
> +
>
> + //
>
> + // Sends the command to the SPI interface to execute.
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionAll,
>
> + FlashCycleReadJedecId,
>
> + Address,
>
> + ByteCount,
>
> + JedecId
>
> + );
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Write the status register in the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_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.
>
> + @retval EFI_UNSUPPORTED Unsupported operation with SAF Mode
> enabled
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashWriteStatus (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT32 ByteCount,
>
> + IN UINT8 *StatusValue
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + if (SpiIsSafModeActive ()) {
>
> + DEBUG ((DEBUG_ERROR, "Unallowed call to %a while SAF Mode is
> active.\n", __FUNCTION__));
>
> + return EFI_UNSUPPORTED;
>
> + }
>
> +
>
> + //
>
> + // Sends the command to the SPI interface to execute.
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionAll,
>
> + FlashCycleWriteStatus,
>
> + 0,
>
> + ByteCount,
>
> + StatusValue
>
> + );
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Read status register in the flash part.
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_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.
>
> + @retval EFI_UNSUPPORTED Unsupported operation with SAF Mode
> enabled
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolFlashReadStatus (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT32 ByteCount,
>
> + OUT UINT8 *StatusValue
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + if (SpiIsSafModeActive ()) {
>
> + DEBUG ((DEBUG_ERROR, "Unallowed call to %a while SAF Mode is
> active.\n", __FUNCTION__));
>
> + return EFI_UNSUPPORTED;
>
> + }
>
> +
>
> + //
>
> + // Sends the command to the SPI interface to execute.
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionAll,
>
> + FlashCycleReadStatus,
>
> + 0,
>
> + ByteCount,
>
> + StatusValue
>
> + );
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Get the SPI region base and size, based on the enum type
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
>
> + @param[in] FlashRegionType The Flash Region type for for the base
> address which is listed 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
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolGetRegionAddress (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN FLASH_REGION_TYPE FlashRegionType,
>
> + OUT UINT32 *BaseAddress,
>
> + OUT UINT32 *RegionSize
>
> + )
>
> +{
>
> + SPI_INSTANCE *SpiInstance;
>
> + UINTN PchSpiBar0;
>
> + UINT32 ReadValue;
>
> +
>
> + SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
>
> +
>
> + if (FlashRegionType >= FlashRegionMax) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + if (FlashRegionType == FlashRegionAll) {
>
> + *BaseAddress = 0;
>
> + *RegionSize = SpiInstance->TotalFlashSize;
>
> + return EFI_SUCCESS;
>
> + }
>
> +
>
> + PchSpiBar0 = AcquireSpiBar0 (SpiInstance);
>
> + ReadValue = MmioRead32 (PchSpiBar0 + (R_SPI_MEM_FREG0_FLASHD +
> (S_SPI_MEM_FREGX * ((UINT32) FlashRegionType))));
>
> + ReleaseSpiBar0 (SpiInstance);
>
> +
>
> + //
>
> + // If the region is not used, the Region Base is 7FFFh and Region Limit is
> 0000h
>
> + //
>
> + if (ReadValue == B_SPI_MEM_FREGX_BASE_MASK) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> + *BaseAddress = ((ReadValue & B_SPI_MEM_FREGX_BASE_MASK) >>
> N_SPI_MEM_FREGX_BASE) <<
>
> + N_SPI_MEM_FREGX_BASE_REPR;
>
> + //
>
> + // Region limit address Bits[11:0] are assumed to be FFFh
>
> + //
>
> + *RegionSize = ((((ReadValue & B_SPI_MEM_FREGX_LIMIT_MASK) >>
> N_SPI_MEM_FREGX_LIMIT) + 1) <<
>
> + N_SPI_MEM_FREGX_LIMIT_REPR) - *BaseAddress;
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Read PCH Soft Strap Values
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolReadPchSoftStrap (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT32 SoftStrapAddr,
>
> + IN UINT32 ByteCount,
>
> + OUT VOID *SoftStrapValue
>
> + )
>
> +{
>
> + SPI_INSTANCE *SpiInstance;
>
> + UINT32 StrapFlashAddr;
>
> + EFI_STATUS Status;
>
> +
>
> + SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
>
> +
>
> + if (ByteCount == 0) {
>
> + *(UINT16 *) SoftStrapValue = SpiInstance->PchStrapSize;
>
> + return EFI_SUCCESS;
>
> + }
>
> +
>
> + if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->PchStrapSize) {
>
> + ASSERT (FALSE);
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + //
>
> + // PCH Strap Flash Address = FPSBA + RamAddr
>
> + //
>
> + StrapFlashAddr = SpiInstance->PchStrapBaseAddr + SoftStrapAddr;
>
> +
>
> + //
>
> + // Read PCH Soft straps from using execute command
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionDescriptor,
>
> + FlashCycleRead,
>
> + StrapFlashAddr,
>
> + ByteCount,
>
> + SoftStrapValue
>
> + );
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Read CPU Soft Strap Values
>
> +
>
> + @param[in] This Pointer to the PCH_SPI_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.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +SpiProtocolReadCpuSoftStrap (
>
> + IN PCH_SPI_PROTOCOL *This,
>
> + IN UINT32 SoftStrapAddr,
>
> + IN UINT32 ByteCount,
>
> + OUT VOID *SoftStrapValue
>
> + )
>
> +{
>
> + SPI_INSTANCE *SpiInstance;
>
> + UINT32 StrapFlashAddr;
>
> + EFI_STATUS Status;
>
> +
>
> + SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
>
> +
>
> + if (ByteCount == 0) {
>
> + *(UINT16 *) SoftStrapValue = SpiInstance->CpuStrapSize;
>
> + return EFI_SUCCESS;
>
> + }
>
> +
>
> + if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->CpuStrapSize) {
>
> + ASSERT (FALSE);
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + //
>
> + // CPU Strap Flash Address = FCPUSBA + RamAddr
>
> + //
>
> + StrapFlashAddr = SpiInstance->CpuStrapBaseAddr + SoftStrapAddr;
>
> +
>
> + //
>
> + // Read Cpu Soft straps from using execute command
>
> + //
>
> + Status = SendSpiCmd (
>
> + This,
>
> + FlashRegionDescriptor,
>
> + FlashCycleRead,
>
> + StrapFlashAddr,
>
> + ByteCount,
>
> + SoftStrapValue
>
> + );
>
> + return Status;
>
> +}
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpi
> AccessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpi
> AccessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf
> new file mode 100644
> index 0000000000..4e059494d8
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpi
> AccessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf
> @@ -0,0 +1,40 @@
> +## @file
>
> +# Component description file for PCH SPI access private library
>
> +#
>
> +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +
>
> +[Defines]
>
> +INF_VERSION = 0x00010017
>
> +BASE_NAME = PeiDxeSmmSpiAccessPrivateLib
>
> +FILE_GUID = 2CD382D7-9928-C32A-601D-69797C618A6D
>
> +VERSION_STRING = 1.0
>
> +MODULE_TYPE = BASE
>
> +LIBRARY_CLASS = SpiAccessPrivateLib
>
> +
>
> +
>
> +[LibraryClasses]
>
> +BaseLib
>
> +IoLib
>
> +DebugLib
>
> +PciSegmentLib
>
> +SpiAccessLib
>
> +PcdLib
>
> +S3BootScriptLib
>
> +PchPciBdfLib
>
> +
>
> +
>
> +[Packages]
>
> +MdePkg/MdePkg.dec
>
> +TigerlakeSiliconPkg/SiPkg.dec
>
> +
>
> +
>
> +[Sources]
>
> +SpiAccessPrivateLib.c
>
> +
>
> +
>
> +[Pcd]
>
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
>
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpi
> AccessPrivateLib/SpiAccessPrivateLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpi
> AccessPrivateLib/SpiAccessPrivateLib.c
> new file mode 100644
> index 0000000000..de1f3d3f86
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpi
> AccessPrivateLib/SpiAccessPrivateLib.c
> @@ -0,0 +1,133 @@
> +/** @file
>
> + SPI library for abstraction of SPI HW registers accesses
>
> +
>
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +
>
> +#include <Base.h>
>
> +#include <Uefi/UefiBaseType.h>
>
> +#include <Library/SpiAccessLib.h>
>
> +#include <Library/PciSegmentLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/S3BootScriptLib.h>
>
> +#include <Register/SpiRegs.h>
>
> +#include <Register/PchRegs.h>
>
> +#include <Register/PchPcrRegs.h>
>
> +#include <Library/PchPciBdfLib.h>
>
> +
>
> +/**
>
> + Disable EISS (Enable InSMM.STS)
>
> +**/
>
> +VOID
>
> +SpiDisableEiss (
>
> + VOID
>
> + )
>
> +{
>
> + UINT64 SpiBaseAddress;
>
> + SpiBaseAddress = SpiPciCfgBase ();
>
> +
>
> + ASSERT ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) &
> B_SPI_CFG_BC_LE) == 0);
>
> +
>
> + PciSegmentAnd8 (SpiBaseAddress + R_SPI_CFG_BC, (UINT8)
> ~(B_SPI_CFG_BC_EISS));
>
> +}
>
> +
>
> +/**
>
> + Configure BiosLockEnable bit and BiosInterfaceLock bit according to policy
> setting.
>
> +
>
> + @param[in] BiosLockEnable Policy for BiosLockEnable bit programming
>
> + @param[in] BiosInterfaceLock Policy for BiosInterfaceLock bit
> programming
>
> +
>
> +**/
>
> +VOID
>
> +SpiBiosLockEnableAndBiosInterfaceLockWithS3BootScript (
>
> + IN BOOLEAN BiosLockEnable,
>
> + IN BOOLEAN BiosInterfaceLock
>
> + )
>
> +{
>
> + UINT64 SpiBaseAddress;
>
> + UINT8 SpiData8;
>
> +
>
> + if (!BiosLockEnable && !BiosInterfaceLock) {
>
> + return;
>
> + }
>
> +
>
> + SpiBaseAddress = SpiPciCfgBase ();
>
> +
>
> + ///
>
> + /// PCH BIOS Spec Flash Security Recommendation
>
> + ///
>
> + /// BIOS needs to enable the BIOS Lock Enable (BLE) feature of the PCH by
> setting
>
> + /// SPI/eSPI/LPC PCI offset DCh[1] = 1b.
>
> + /// When this bit is set, attempts to write the Write Protect Disable (WPD)
> bit
>
> + /// in PCH will cause a SMI which will allow the BIOS to verify that the write
> is
>
> + /// from a valid source.
>
> + /// Remember that BIOS needs to set SPI/LPC/eSPI PCI Offset DC [0] = 0b
> to enable
>
> + /// BIOS region protection before exiting the SMI handler.
>
> + /// Also, TCO_EN bit needs to be set (SMI_EN Register, ABASE + 30h[13] =
> 1b) to keep
>
> + /// BLE feature enabled after booting to the OS.
>
> + /// Intel requires that BIOS enables the Lock Enable (LE) feature of the PCH
> to
>
> + /// ensure SMM protection of flash.
>
> + /// RC installs a default SMI handler that clears WPD.
>
> + /// There could be additional SMI handler to log such attempt if desired.
>
> + ///
>
> + /// BIOS needs to enable the "Enable in SMM.STS" (EISS) feature of the
> PCH by setting
>
> + /// SPI PCI offset DCh[5] = 1b for SPI or setting eSPI PCI offset DCh[5] = 1b
> for eSPI.
>
> + /// When this bit is set, the BIOS region is not writable until SMM sets the
> InSMM.STS bit,
>
> + /// to ensure BIOS can only be modified from SMM. Please refer to CPU
> BWG for more details
>
> + /// on InSMM.STS bit.
>
> + /// Intel requires that BIOS enables the Lock Enable (LE) feature of the PCH
> to ensure
>
> + /// SMM protection of flash.
>
> + /// SPI PCI offset DCh[1] = 1b for SPI or setting eSPI PCI offset DCh[1] = 1b
> for eSPI.
>
> + /// When this bit is set, EISS is locked down.
>
> + ///
>
> + SpiData8 = 0;
>
> + if (BiosLockEnable) {
>
> + SpiData8 |= B_SPI_CFG_BC_EISS | B_SPI_CFG_BC_LE;
>
> + }
>
> + ///
>
> + /// BIOS also needs to set the BIOS Interface Lock Down bit in multiple
> locations
>
> + /// (PCR[DMI] + 274Ch[0], LPC/eSPI PCI offset DCh[7] and SPI PCI offset
> DCh[7]).
>
> + /// (done in PchInit/Dxe/PchInit.c by
> PchDmiSetBiosLockDownWithS3BootScript ()) for PCR[DMI] 274Ch)
>
> + /// Setting these bits will prevent writes to the Top Swap bit (under their
> respective locations)
>
> + /// and the Boot BIOS Straps. Enabling this bit will mitigate malicious
> software
>
> + /// attempts to replace the system BIOS option ROM with its own code.
>
> + ///
>
> + if (BiosInterfaceLock) {
>
> + SpiData8 |= B_SPI_CFG_BC_BILD;
>
> + }
>
> +
>
> + PciSegmentOr8 (SpiBaseAddress + R_SPI_CFG_BC, SpiData8);
>
> + S3BootScriptSaveMemWrite (
>
> + S3BootScriptWidthUint8,
>
> + PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress +
> R_SPI_CFG_BC,
>
> + 1,
>
> + (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) +
> SpiBaseAddress + R_SPI_CFG_BC)
>
> + );
>
> + //
>
> + // Reads back for posted write to take effect
>
> + //
>
> + SpiData8 = PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC);
>
> + S3BootScriptSaveMemPoll (
>
> + S3BootScriptWidthUint8,
>
> + PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress +
> R_SPI_CFG_BC,
>
> + &SpiData8,
>
> + &SpiData8,
>
> + 1,
>
> + 1
>
> + );
>
> +}
>
> +
>
> +/**
>
> + Clears BIOS Write Protect Disable bit
>
> +**/
>
> +VOID
>
> +SpiClearBiosWriteProtectDisable (
>
> + VOID
>
> + )
>
> +{
>
> + //
>
> + // Disable BIOSWE bit to protect BIOS
>
> + //
>
> + PciSegmentAnd8 (SpiPciCfgBase () + R_SPI_CFG_BC, (UINT8)
> ~B_SPI_CFG_BC_WPD);
>
> +}
>
> diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/Spi.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/Spi.c
> new file mode 100644
> index 0000000000..419eddaff3
> --- /dev/null
> +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/Spi.c
> @@ -0,0 +1,296 @@
> +/** @file
>
> + PCH SPI SMM Driver implements the SPI Host Controller Compatibility
> Interface.
>
> +
>
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +
>
> +#include <Library/IoLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/UefiDriverEntryPoint.h>
>
> +#include <Library/UefiBootServicesTableLib.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/SmmServicesTableLib.h>
>
> +#include <Library/PciSegmentLib.h>
>
> +#include <Protocol/Spi.h>
>
> +#include <Protocol/SmmCpu.h>
>
> +#include <Library/SpiCommonLib.h>
>
> +#include <PchReservedResources.h>
>
> +#include <Library/SmmPchPrivateLib.h>
>
> +#include <Library/PchPciBdfLib.h>
>
> +#include <IndustryStandard/Pci30.h>
>
> +#include <Register/PchRegs.h>
>
> +#include <Register/SpiRegs.h>
>
> +
>
> +//
>
> +// Global variables
>
> +//
>
> +GLOBAL_REMOVE_IF_UNREFERENCED SPI_INSTANCE *mSpiInstance;
>
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_CPU_PROTOCOL
> *mSmmCpuProtocol;
>
> +//
>
> +// mPchSpiResvMmioAddr keeps the reserved MMIO range assiged to SPI.
>
> +// In SMM it always set back the reserved MMIO address to SPI BAR0 to
> ensure the MMIO range
>
> +// won't overlap with SMRAM range, and trusted.
>
> +//
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSpiResvMmioAddr;
>
> +
>
> +/**
>
> + <b>SPI Runtime SMM Module Entry Point</b>\n
>
> + - <b>Introduction</b>\n
>
> + The SPI SMM module provide a standard way for other modules to use
> the PCH SPI Interface in SMM.
>
> +
>
> + - @pre
>
> + - EFI_SMM_BASE2_PROTOCOL
>
> + - Documented in System Management Mode Core Interface
> Specification .
>
> +
>
> + - @result
>
> + The SPI SMM driver produces @link _PCH_SPI_PROTOCOL
> PCH_SPI_PROTOCOL @endlink with GUID
>
> + gPchSmmSpiProtocolGuid which is different from SPI RUNTIME driver.
>
> +
>
> + - <b>Integration Check List</b>\n
>
> + - This driver supports Descriptor Mode only.
>
> + - This driver supports Hardware Sequence only.
>
> + - When using SMM SPI Protocol to perform flash access in an SMI handler,
>
> + and the SMI occurrence is asynchronous to normal mode code
> execution,
>
> + proper synchronization mechanism must be applied, e.g. disable SMI
> before
>
> + the normal mode SendSpiCmd() starts and re-enable SMI after
>
> + the normal mode SendSpiCmd() completes.
>
> + @note The implementation of SendSpiCmd() uses GBL_SMI_EN in
>
> + SMI_EN register (ABase + 30h) to disable and enable SMIs. But this may
>
> + not be effective as platform may well set the SMI_LOCK bit (i.e., PMC
> PCI Offset A0h [4]).
>
> + So the synchronization at caller level is likely needed.
>
> +
>
> + @param[in] ImageHandle Image handle of this driver.
>
> + @param[in] SystemTable Global system service table.
>
> +
>
> + @retval EFI_SUCCESS Initialization complete.
>
> + @exception EFI_UNSUPPORTED The chipset is unsupported by this
> driver.
>
> + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to
> initialize the driver.
>
> + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +InstallPchSpi (
>
> + IN EFI_HANDLE ImageHandle,
>
> + IN EFI_SYSTEM_TABLE *SystemTable
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + //
>
> + // Init PCH spi reserved MMIO address.
>
> + //
>
> + mSpiResvMmioAddr = PCH_SPI_BASE_ADDRESS;
>
> +
>
> + ///
>
> + /// Allocate pool for SPI protocol instance
>
> + ///
>
> + Status = gSmst->SmmAllocatePool (
>
> + EfiRuntimeServicesData, /// MemoryType don't care
>
> + sizeof (SPI_INSTANCE),
>
> + (VOID **) &mSpiInstance
>
> + );
>
> + if (EFI_ERROR (Status)) {
>
> + return Status;
>
> + }
>
> +
>
> + if (mSpiInstance == NULL) {
>
> + return EFI_OUT_OF_RESOURCES;
>
> + }
>
> +
>
> + ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE));
>
> + ///
>
> + /// Initialize the SPI protocol instance
>
> + ///
>
> + Status = SpiProtocolConstructor (mSpiInstance);
>
> + if (EFI_ERROR (Status)) {
>
> + return Status;
>
> + }
>
> + ///
>
> + /// Install the SMM PCH_SPI_PROTOCOL interface
>
> + ///
>
> + Status = gSmst->SmmInstallProtocolInterface (
>
> + &(mSpiInstance->Handle),
>
> + &gPchSmmSpiProtocolGuid,
>
> + EFI_NATIVE_INTERFACE,
>
> + &(mSpiInstance->SpiProtocol)
>
> + );
>
> + if (EFI_ERROR (Status)) {
>
> + gSmst->SmmFreePool (mSpiInstance);
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Acquire PCH spi mmio address.
>
> + If it is ever different from the preallocated address, reassign it back.
>
> + In SMM, it always override the BAR0 and returns the reserved MMIO
> range for SPI.
>
> +
>
> + @param[in] SpiInstance Pointer to SpiInstance to initialize
>
> +
>
> + @retval PchSpiBar0 return SPI MMIO address
>
> +**/
>
> +UINTN
>
> +AcquireSpiBar0 (
>
> + IN SPI_INSTANCE *SpiInstance
>
> + )
>
> +{
>
> + UINT32 SpiBar0;
>
> + //
>
> + // Save original SPI physical MMIO address
>
> + //
>
> + SpiBar0 = PciSegmentRead32 (SpiInstance->PchSpiBase +
> R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
>
> +
>
> + if (SpiBar0 != mSpiResvMmioAddr) {
>
> + //
>
> + // Temporary disable MSE, and override with SPI reserved MMIO
> address, then enable MSE.
>
> + //
>
> + PciSegmentAnd8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET,
> (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE);
>
> + PciSegmentWrite32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0,
> mSpiResvMmioAddr);
>
> + PciSegmentOr8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET,
> EFI_PCI_COMMAND_MEMORY_SPACE);
>
> + }
>
> + //
>
> + // SPIBAR0 will be different before and after PCI enum so need to get it
> from SPI BAR0 reg.
>
> + //
>
> + return mSpiResvMmioAddr;
>
> +}
>
> +
>
> +/**
>
> + Release pch spi mmio address. Do nothing.
>
> +
>
> + @param[in] SpiInstance Pointer to SpiInstance to initialize
>
> +
>
> + @retval None
>
> +**/
>
> +VOID
>
> +ReleaseSpiBar0 (
>
> + IN SPI_INSTANCE *SpiInstance
>
> + )
>
> +{
>
> +}
>
> +
>
> +/**
>
> + This function is a hook for Spi to disable BIOS Write Protect
>
> +
>
> + @retval EFI_SUCCESS The protocol instance was properly initialized
>
> + @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in
> SMM phase
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +DisableBiosWriteProtect (
>
> + VOID
>
> + )
>
> +{
>
> + UINT64 SpiBaseAddress;
>
> +
>
> + SpiBaseAddress = SpiPciCfgBase ();
>
> + // Write clear BC_SYNC_SS prior to change WPD from 0 to 1.
>
> + //
>
> + PciSegmentOr8 (
>
> + SpiBaseAddress + R_SPI_CFG_BC + 1,
>
> + (B_SPI_CFG_BC_SYNC_SS >> 8)
>
> + );
>
> + ///
>
> + /// Set BIOSWE bit (SPI PCI Offset DCh [0]) = 1b
>
> + /// Enable the access to the BIOS space for both read and write cycles
>
> + ///
>
> + PciSegmentOr8 (
>
> + SpiBaseAddress + R_SPI_CFG_BC,
>
> + B_SPI_CFG_BC_WPD
>
> + );
>
> +
>
> + ///
>
> + /// PCH BIOS Spec Section 3.7 BIOS Region SMM Protection Enabling
>
> + /// If the following steps are implemented:
>
> + /// - Set the EISS bit (SPI PCI Offset DCh [5]) = 1b
>
> + /// - Follow the 1st recommendation in section 3.6
>
> + /// the BIOS Region can only be updated by following the steps bellow:
>
> + /// - Once all threads enter SMM
>
> + /// - Read memory location FED30880h OR with 00000001h, place the
> result in EAX,
>
> + /// and write data to lower 32 bits of MSR 1FEh (sample code available)
>
> + /// - Set BIOSWE bit (SPI PCI Offset DCh [0]) = 1b
>
> + /// - Modify BIOS Region
>
> + /// - Clear BIOSWE bit (SPI PCI Offset DCh [0]) = 0b
>
> + ///
>
> + if ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) &
> B_SPI_CFG_BC_EISS) != 0) {
>
> + PchSetInSmmSts ();
>
> + }
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + This function is a hook for Spi to enable BIOS Write Protect
>
> +**/
>
> +VOID
>
> +EFIAPI
>
> +EnableBiosWriteProtect (
>
> + VOID
>
> + )
>
> +{
>
> + UINT64 SpiBaseAddress;
>
> +
>
> + SpiBaseAddress = SpiPciCfgBase ();
>
> + ///
>
> + /// Clear BIOSWE bit (SPI PCI Offset DCh [0]) = 0b
>
> + /// Disable the access to the BIOS space for write cycles
>
> + ///
>
> + PciSegmentAnd8 (
>
> + SpiBaseAddress + R_SPI_CFG_BC,
>
> + (UINT8) (~B_SPI_CFG_BC_WPD)
>
> + );
>
> +
>
> + ///
>
> + /// Check if EISS bit is set
>
> + ///
>
> + if (((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC)) &
> B_SPI_CFG_BC_EISS) == B_SPI_CFG_BC_EISS) {
>
> + PchClearInSmmSts ();
>
> + }
>
> +}
>
> +
>
> +/**
>
> + Check if it's granted to do flash write.
>
> +
>
> + @retval TRUE It's secure to do flash write.
>
> + @retval FALSE It's not secure to do flash write.
>
> +**/
>
> +BOOLEAN
>
> +IsSpiFlashWriteGranted (
>
> + VOID
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINT32 CpuIndex;
>
> + UINT64 ProcessorId;
>
> +
>
> + if (mSmmCpuProtocol == NULL) {
>
> + Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL,
> (VOID **)&mSmmCpuProtocol);
>
> + ASSERT_EFI_ERROR (Status);
>
> + if (mSmmCpuProtocol == NULL) {
>
> + return TRUE;
>
> + }
>
> + }
>
> +
>
> + for (CpuIndex = 0; CpuIndex < gSmst->NumberOfCpus; CpuIndex++) {
>
> + Status = mSmmCpuProtocol->ReadSaveState (
>
> + mSmmCpuProtocol,
>
> + sizeof (ProcessorId),
>
> + EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID,
>
> + CpuIndex,
>
> + &ProcessorId
>
> + );
>
> + //
>
> + // If the processor is in SMM at the time the SMI occurred,
>
> + // it will return success. Otherwise, EFI_NOT_FOUND is returned.
>
> + //
>
> + if (EFI_ERROR (Status)) {
>
> + return FALSE;
>
> + }
>
> + }
>
> +
>
> + return TRUE;
>
> +}
>
> diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/SpiSmm.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/SpiSmm.inf
> new file mode 100644
> index 0000000000..033134cea1
> --- /dev/null
> +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/SpiSmm.inf
> @@ -0,0 +1,47 @@
> +## @file
>
> +# Component description file for the SPI SMM driver.
>
> +#
>
> +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +
>
> +[Defines]
>
> +INF_VERSION = 0x00010017
>
> +BASE_NAME = SpiSmm
>
> +FILE_GUID = 27F4917B-A707-4aad-9676-26DF168CBF0D
>
> +VERSION_STRING = 1.0
>
> +MODULE_TYPE = DXE_SMM_DRIVER
>
> +PI_SPECIFICATION_VERSION = 1.10
>
> +ENTRY_POINT = InstallPchSpi
>
> +
>
> +
>
> +[LibraryClasses]
>
> +DebugLib
>
> +IoLib
>
> +UefiDriverEntryPoint
>
> +UefiBootServicesTableLib
>
> +BaseLib
>
> +SmmServicesTableLib
>
> +SpiCommonLib
>
> +SmmPchPrivateLib
>
> +PchPciBdfLib
>
> +
>
> +[Packages]
>
> +MdePkg/MdePkg.dec
>
> +TigerlakeSiliconPkg/SiPkg.dec
>
> +
>
> +
>
> +[Sources]
>
> +Spi.c
>
> +
>
> +
>
> +[Protocols]
>
> +gPchSmmSpiProtocolGuid ## PRODUCES
>
> +gEfiSmmCpuProtocolGuid ## CONSUMES
>
> +
>
> +
>
> +[Depex]
>
> +gEfiSmmBase2ProtocolGuid AND # This is for SmmServicesTableLib
>
> +gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect()
>
> --
> 2.24.0.windows.2
next prev parent reply other threads:[~2021-02-04 3:56 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-01 1:36 [PATCH 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
2021-02-01 1:36 ` [PATCH 02/40] TigerlakeSiliconPkg/Include: Add Library, PPI and Protocol include headers Heng Luo
2021-02-04 3:51 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 03/40] TigerlakeSiliconPkg/Include: Add Pins, Register and other " Heng Luo
2021-02-04 3:52 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 04/40] TigerlakeSiliconPkg/Cpu: Add Include headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 05/40] TigerlakeSiliconPkg/Pch: Add include headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 06/40] TigerlakeSiliconPkg/Pch: Add IncludePrivate headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 07/40] TigerlakeSiliconPkg/SystemAgent: Add include headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 08/40] TigerlakeSiliconPkg/SystemAgent: Add IncludePrivate headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 09/40] TigerlakeSiliconPkg/Fru: Add TglCpu/Include headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 10/40] TigerlakeSiliconPkg/Fru: Add TglCpu/IncludePrivate headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 11/40] TigerlakeSiliconPkg/Fru: Add TglPch/Include headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 12/40] TigerlakeSiliconPkg/Fru: Add TglPch/IncludePrivate headers Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 13/40] TigerlakeSiliconPkg/IpBlock: Add Cnvi component Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 14/40] TigerlakeSiliconPkg/IpBlock: Add CpuPcieRp component Heng Luo
2021-02-04 3:53 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 15/40] TigerlakeSiliconPkg/IpBlock: Add Espi component Heng Luo
2021-02-04 3:54 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 16/40] TigerlakeSiliconPkg/IpBlock: Add Gbe component Heng Luo
2021-02-04 3:54 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component Heng Luo
2021-02-04 3:54 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 18/40] TigerlakeSiliconPkg/IpBlock: Add Graphics component Heng Luo
2021-02-04 3:54 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 19/40] TigerlakeSiliconPkg/IpBlock: Add Hda component Heng Luo
2021-02-04 3:54 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 20/40] TigerlakeSiliconPkg/IpBlock: Add HostBridge component Heng Luo
2021-02-04 3:54 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component Heng Luo
2021-02-04 3:54 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 22/40] TigerlakeSiliconPkg/IpBlock: Add PchDmi component Heng Luo
2021-02-04 3:54 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 23/40] TigerlakeSiliconPkg/IpBlock: Add PcieRp component Heng Luo
2021-02-04 3:55 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 24/40] TigerlakeSiliconPkg/IpBlock: Add Pmc component Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 25/40] TigerlakeSiliconPkg/IpBlock: Add Psf component Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 26/40] TigerlakeSiliconPkg/IpBlock: Add Sata component Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 27/40] TigerlakeSiliconPkg/IpBlock: Add SerialIo component Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 28/40] TigerlakeSiliconPkg/IpBlock: Add Smbus component Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 29/40] TigerlakeSiliconPkg/IpBlock: Add Spi component Heng Luo
2021-02-04 3:56 ` Nate DeSimone [this message]
2021-02-01 1:36 ` [PATCH 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 31/40] TigerlakeSiliconPkg/Library: Add package common library instances Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 32/40] TigerlakeSiliconPkg/Pch: Add Pch " Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 33/40] TigerlakeSiliconPkg/Pch: Add Pch private " Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 34/40] TigerlakeSiliconPkg/SystemAgent: Add Acpi Tables and " Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 35/40] TigerlakeSiliconPkg/Fru/TglCpu: Add CpuPcieRp and Vtd " Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 36/40] TigerlakeSiliconPkg/Pch: Add Pch modules Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 37/40] TigerlakeSiliconPkg/SystemAgent: Add SystemAgent modules Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 38/40] TigerlakeSiliconPkg/Fru: Add Fru DSC files Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 39/40] TigerlakeSiliconPkg: Add package " Heng Luo
2021-02-04 3:56 ` Nate DeSimone
2021-02-01 1:36 ` [PATCH 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers Heng Luo
2021-02-04 3:51 ` Nate DeSimone
2021-02-04 8:24 ` Heng Luo
2021-02-04 3:51 ` [PATCH 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Nate DeSimone
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=BN6PR1101MB2147C853F8F22F4825260E03CDB39@BN6PR1101MB2147.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