diff options
author | zwei4 <david.wei@intel.com> | 2017-03-10 16:00:56 +0800 |
---|---|---|
committer | zwei4 <david.wei@intel.com> | 2017-03-16 16:37:54 +0800 |
commit | 71169571606bb31743d950c7d15f4b1554712002 (patch) | |
tree | 20d7e6b680db79918b31261c76dd388e611a3746 /Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster | |
parent | 58b2fa2c79c70d0f90663794a30463c5028a52ec (diff) | |
download | edk2-platforms-71169571606bb31743d950c7d15f4b1554712002.tar.xz |
Add PEI SPI library.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: zwei4 <david.wei@intel.com>
Diffstat (limited to 'Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster')
5 files changed, 598 insertions, 0 deletions
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/PeiSpiInitLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/PeiSpiInitLib.h new file mode 100644 index 0000000000..628de101e1 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/PeiSpiInitLib.h @@ -0,0 +1,35 @@ +/** @file + Prototype of the PeiSpiInitLib library. + + Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR> + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PEI_SPI_INIT_LIBRARY_H_ +#define _PEI_SPI_INIT_LIBRARY_H_ + +#include <Ppi/ScPolicy.h> + +/** + Installs SC SPI PPI. + + @param[in] None + + @retval EFI_SUCCESS SC SPI PPI is installed successfully + @retval EFI_OUT_OF_RESOURCES Can't allocate pool +**/ +EFI_STATUS +EFIAPI +InstallScSpi ( + VOID + ); + +#endif diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Ppi/Spi.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Ppi/Spi.h new file mode 100644 index 0000000000..89c167cec2 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Ppi/Spi.h @@ -0,0 +1,238 @@ +/** @file + This file defines the EFI SPI PPI which implements the + Intel(R) SC SPI Host Controller Compatibility Interface. + + Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.<BR> + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PEI_SPI_H_ +#define _PEI_SPI_H_ + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gScSpiPpiGuid; + +// +// Forward reference for ANSI C compatibility +// +typedef struct _SC_SPI_PROTOCOL SC_SPI_PROTOCOL; + +// +// SPI protocol data structures and definitions +// + +/// +/// Flash Region Type +/// +typedef enum { + FlashRegionDescriptor, + FlashRegionBios, + FlashRegionMe, + FlashRegionGbE, + FlashRegionPlatformData, + FlashRegionAll, + FlashRegionMax +} FLASH_REGION_TYPE; + +// +// Protocol member functions +// + +/** + Read data from the flash part. + + @param[in] This Pointer to the SC_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. +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_FLASH_READ) ( + IN SC_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 SC_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. +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_FLASH_WRITE) ( + IN SC_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 SC_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. +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_FLASH_ERASE) ( + IN SC_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 SC_SPI_PROTOCOL instance. + @param[in] ComponentNumber The Componen Number for chip select + @param[in] ByteCount Number of bytes in SFDP data portion of the SPI cycle, the max number is 64 + @param[out] SfdpData The Pointer to caller-allocated buffer containing the SFDP data received + It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_FLASH_READ_SFDP) ( + IN SC_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 ByteCount, + OUT UINT8 *SfdpData + ); + +/** + Read Jedec Id from the flash part. + + @param[in] This Pointer to the SC_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. +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_FLASH_READ_JEDEC_ID) ( + IN SC_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 SC_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. +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_FLASH_WRITE_STATUS) ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + IN UINT8 *StatusValue + ); + +/** + Read status register in the flash part. + + @param[in] This Pointer to the SC_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. +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_FLASH_READ_STATUS) ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + OUT UINT8 *StatusValue + ); + +/** + Read PCH Soft Strap Values + + @param[in] This Pointer to the SC_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. + It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_READ_PCH_SOFTSTRAP) ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT UINT8 *SoftStrapValue + ); + +/** + These protocols/PPI allows a platform module to perform SPI operations through the + Intel PCH SPI Host Controller Interface. +**/ +struct _SC_SPI_PROTOCOL { + SC_SPI_FLASH_READ FlashRead; ///< Read data from the flash part. + SC_SPI_FLASH_WRITE FlashWrite; ///< Write data to the flash part. + SC_SPI_FLASH_ERASE FlashErase; ///< Erase some area on the flash part. + SC_SPI_FLASH_READ_SFDP FlashReadSfdp; ///< Read SFDP data from the flash part. + SC_SPI_FLASH_READ_JEDEC_ID FlashReadJedecId; ///< Read Jedec Id from the flash part. + SC_SPI_FLASH_WRITE_STATUS FlashWriteStatus; ///< Write the status register in the flash part. + SC_SPI_FLASH_READ_STATUS FlashReadStatus; ///< Read status register in the flash part. + SC_SPI_READ_PCH_SOFTSTRAP ReadPchSoftStrap; ///< Read PCH Soft Strap Values +}; + +#endif diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/PeiSpiInitLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/PeiSpiInitLib.inf new file mode 100644 index 0000000000..561a86a501 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/PeiSpiInitLib.inf @@ -0,0 +1,44 @@ +## @file +# SC SPI Init Lib PEI Phase. +# +# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR> +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiSpiInitLib + FILE_GUID = 91CFD935-551E-439E-B0D6-AE06C3B5E66 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeiSpiInitLib + +[Sources] + ScSpi.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + +[LibraryClasses] + S3BootScriptLib + BaseLib + IoLib + DebugLib + TimerLib + MemoryAllocationLib + BaseMemoryLib + HobLib + PeiServicesLib + ScSpiCommonLib + +[Ppis] + gScSpiPpiGuid ## PRODUCES diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/ScSpi.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/ScSpi.c new file mode 100644 index 0000000000..0c665ab859 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/ScSpi.c @@ -0,0 +1,237 @@ +/** @file + SC SPI PEI Library implements the SPI Host Controller Compatibility Interface. + + Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR> + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "ScSpi.h" + +/** + Hide SPI controller before OS avoid BAR0 changed. + + @param[in] None + + @retval +**/ +VOID +HideSpiController ( + VOID + ) +{ + UINTN ScSpiBase; + + ScSpiBase = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SPI, + PCI_FUNCTION_NUMBER_SPI + ); + + MmioAndThenOr8 ( + ScSpiBase + R_SPI_BCR + 1, + (UINT8)~(B_SPI_BCR_SYNC_SS >> 8), + (B_SPI_BC_OSFH >> 8) + ); +} + +/** + PCI Enumeration is not done till later in DXE. + Initialize SPI BAR0 to a default value till enumeration is done. + Also enable memory space decoding for SPI. + + @param[in] None + + @retval + +**/ +VOID +InitSpiBar0 ( + VOID + ) +{ + UINTN ScSpiBase; + ScSpiBase = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SPI, + PCI_FUNCTION_NUMBER_SPI + ); + MmioWrite32 (ScSpiBase + R_SPI_BASE, SC_SPI_BASE_ADDRESS); + MmioOr32 (ScSpiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE); +} + +/** + Installs SC SPI PPI + + @retval EFI_SUCCESS SC SPI PPI is installed successfully + @retval EFI_OUT_OF_RESOURCES Can't allocate pool +**/ +EFI_STATUS +EFIAPI +InstallScSpi ( + VOID + ) +{ + EFI_STATUS Status; + PEI_SPI_INSTANCE *PeiSpiInstance; + SPI_INSTANCE *SpiInstance; + EFI_PEI_PPI_DESCRIPTOR *OldScSpiPolicyPpiDesc; + + DEBUG ((DEBUG_INFO, "InstallScSpi() Start\n")); + + /// + /// PCI Enumeration is not done till later in DXE. + /// Initialize SPI BAR0 to a default value till enumeration is done. + /// Also enable memory space decoding for SPI. + /// + InitSpiBar0 (); + + PeiSpiInstance = (PEI_SPI_INSTANCE *) AllocateZeroPool (sizeof (PEI_SPI_INSTANCE)); + if (PeiSpiInstance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SpiInstance = &(PeiSpiInstance->SpiInstance); + SpiProtocolConstructor (SpiInstance); + + PeiSpiInstance->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + PeiSpiInstance->PpiDescriptor.Guid = &gScSpiPpiGuid; + PeiSpiInstance->PpiDescriptor.Ppi = &(SpiInstance->SpiProtocol); + + Status = PeiServicesLocatePpi ( + &gScSpiPpiGuid, + 0, + &OldScSpiPolicyPpiDesc, + NULL + ); + if (EFI_ERROR (Status)) { + // + // Install Sc Spi PPI. + // + DEBUG ((DEBUG_INFO, "Locate Old ScSpiPpi fail in Post-Memory\n")); + Status = PeiServicesInstallPpi (&PeiSpiInstance->PpiDescriptor); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Install ScSpiPpi fail in Post-Memory\n")); + } + ASSERT_EFI_ERROR (Status); + } else { + // + // ReInstall Sc Spi PPI. + // + DEBUG ((DEBUG_INFO, "Re-Install ScSpiPpi in Post-Memory\n")); + Status = PeiServicesReInstallPpi (OldScSpiPolicyPpiDesc, &PeiSpiInstance->PpiDescriptor); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Re-Install ScSpiPpi fail in Post-Memory\n")); + } + ASSERT_EFI_ERROR (Status); + } + + DEBUG ((DEBUG_INFO, "InstallScSpi() End\n")); + + // + // Hide SPI controller before OS avoid BAR0 changed. + // + HideSpiController (); + + return Status; +} + +/** + Acquire SC SPI mmio address. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval ScSpiBar0 Return SPI MMIO address +**/ +UINT32 +AcquireSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ) +{ + return MmioRead32 (SpiInstance->PchSpiBase + R_SPI_BASE) & ~(B_SPI_BAR0_MASK); +} + +/** + Release SC SPI mmio address. + + @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 + ) +{ + UINTN SpiBaseAddress; + + SpiBaseAddress = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SPI, + PCI_FUNCTION_NUMBER_SPI + ); + if ((MmioRead8 (SpiBaseAddress + R_SPI_BCR) & B_SPI_BCR_SMM_BWP) != 0) { + return EFI_ACCESS_DENIED; + } + + /// + /// Enable the access to the BIOS space for both read and write cycles + /// + MmioOr8 ( + SpiBaseAddress + R_SPI_BCR, + B_SPI_BCR_BIOSWE + ); + + return EFI_SUCCESS; +} + +/** + This function is a hook for Spi to enable BIOS Write Protect + + @param[in] None + + @retval +**/ +VOID +EFIAPI +EnableBiosWriteProtect ( + VOID + ) +{ + UINTN SpiBaseAddress; + + SpiBaseAddress = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SPI, + PCI_FUNCTION_NUMBER_SPI + ); + /// + /// Disable the access to the BIOS space for write cycles + /// + MmioAnd8 ( + SpiBaseAddress + R_SPI_BCR, + (UINT8) (~B_SPI_BCR_BIOSWE) + ); +} diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/ScSpi.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/ScSpi.h new file mode 100644 index 0000000000..7ae0b21e1a --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/ScSpi.h @@ -0,0 +1,44 @@ +/** @file + Header file for the SC SPI PEI Library. + + Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR> + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SC_SPI_H_ +#define _SC_SPI_H_ + +#include <Ppi/Spi.h> +#include <ScAccess.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PeiServicesLib.h> +#include <Library/MmPciLib.h> +#include <IndustryStandard/Pci30.h> +#include <Library/ScSpiCommonLib.h> + +typedef struct { + EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; + SPI_INSTANCE SpiInstance; +} PEI_SPI_INSTANCE; + +/** + Installs SC SPI PPI + + @retval EFI_SUCCESS PCH SPI PPI is installed successfully + @retval EFI_OUT_OF_RESOURCES Can't allocate pool +**/ +EFI_STATUS +EFIAPI +InstallScSpi ( + VOID + ); +#endif |