From nobody Sat Nov 2 14:35:49 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1486954143551799.639348098878; Sun, 12 Feb 2017 18:49:03 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id E86DC820DA; Sun, 12 Feb 2017 18:49:01 -0800 (PST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 7EE8D820D8 for ; Sun, 12 Feb 2017 18:49:01 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Feb 2017 18:49:01 -0800 Received: from zwei4-mobl.ccr.corp.intel.com ([10.239.198.23]) by orsmga001.jf.intel.com with ESMTP; 12 Feb 2017 18:48:59 -0800 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,155,1484035200"; d="scan'208";a="1094001447" From: zwei4 To: edk2-devel@lists.01.org Date: Mon, 13 Feb 2017 10:48:51 +0800 Message-Id: <20170213024851.38240-1-david.wei@intel.com> X-Mailer: git-send-email 2.11.0.windows.1 Subject: [edk2] [Patch][edk2-platforms/devel-MinnowBoard3] Add SPI modules. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lushifex , David Wei MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: lushifex Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: lushifex Signed-off-by: David Wei --- .../SouthCluster/Include/Library/ScSpiCommonLib.h | 361 ++++++++ .../SouthCluster/Include/Protocol/Spi.h | 359 ++++++++ .../BaseScSpiCommonLib/BaseScSpiCommonLib.inf | 40 + .../Library/BaseScSpiCommonLib/SpiCommon.c | 994 +++++++++++++++++= ++++ .../SouthCluster/Spi/RuntimeDxe/ScSpi.c | 313 +++++++ .../SouthCluster/Spi/RuntimeDxe/ScSpi.h | 50 ++ .../SouthCluster/Spi/RuntimeDxe/ScSpiRuntime.inf | 60 ++ .../BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpi.c | 249 ++++++ .../BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpi.h | 33 + .../BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpiSmm.inf | 49 + 10 files changed, 2508 insertions(+) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Li= brary/ScSpiCommonLib.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Pr= otocol/Spi.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/Ba= seScSpiCommonLib/BaseScSpiCommonLib.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/Ba= seScSpiCommonLib/SpiCommon.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Runtim= eDxe/ScSpi.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Runtim= eDxe/ScSpi.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Runtim= eDxe/ScSpiRuntime.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/Sc= Spi.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/Sc= Spi.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/Sc= SpiSmm.inf diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/S= cSpiCommonLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Libr= ary/ScSpiCommonLib.h new file mode 100644 index 0000000..3587bab --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/ScSpiCom= monLib.h @@ -0,0 +1,361 @@ +/** @file + Header file for the SC SPI Common Driver. + + Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#ifndef _SC_SPI_COMMON_LIB_H_ +#define _SC_SPI_COMMON_LIB_H_ + +/// +/// Maximum time allowed while waiting the SPI cycle to complete +/// Wait Time =3D 6 seconds =3D 6000000 microseconds +/// Wait Period =3D 10 microseconds +/// +#define WAIT_TIME 6000000 ///< Wait Time =3D 6 seconds =3D 6000000 m= icroseconds +#define WAIT_PERIOD 10 ///< Wait Period =3D 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 SC_SPI_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'S', 'P', 'I') + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + SC_SPI_PROTOCOL SpiProtocol; + UINT16 PchAcpiBase; + UINTN PchSpiBase; + UINT16 RegionPermission; + UINT32 SfdpVscc0Value; + UINT32 SfdpVscc1Value; + UINT32 StrapBaseAddress; + UINT8 NumberOfComponents; + UINT32 Component1StartAddr; +} SPI_INSTANCE; + +#define SPI_INSTANCE_FROM_SPIPROTOCOL(a) CR (a, SPI_INSTANCE, SpiProtocol= , SC_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 in= itialized + @retval EFI_UNSUPPORTED The SC 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 ini= tialized + @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 SC spi mmio address. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval UINT32 Return SPI MMIO address + +**/ +UINT32 +AcquireSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ); + +/** + Release SC spi mmio address. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + +**/ +VOID +ReleaseSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ); + +/** + Read data from the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL insta= nce. + @param[in] FlashRegionType The Flash Region type for flash cycl= e which is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall w= ithin 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 buff= er containing the 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashRead ( + 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 instan= ce. + @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 wi= thin a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion o= f the SPI cycle. + @param[in] Buffer Pointer to caller-allocated buffer co= ntaining the data sent during the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashWrite ( + 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 instan= ce. + @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 wi= thin a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion o= f the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashErase ( + 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 insta= nce. + @param[in] ComponentNumber The Component 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 buff= er 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadSfdp ( + 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 insta= nce. + @param[in] ComponentNumber The Component Number for chip select + @param[in] ByteCount Number of bytes in JedecId data port= ion of the SPI cycle, the data size is 3 typically + @param[out] JedecId The Pointer to caller-allocated buff= er 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadJedecId ( + 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 instan= ce. + @param[in] ByteCount Number of bytes in Status data portio= n of the SPI cycle, the data size is 1 typically + @param[in] StatusValue The Pointer to caller-allocated buffe= r containing the value of Status register writing + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashWriteStatus ( + 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 insta= nce. + @param[in] ByteCount Number of bytes in Status data porti= on of the SPI cycle, the data size is 1 typically + @param[out] StatusValue The Pointer to caller-allocated buff= er containing the value of Status register received. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadStatus ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + OUT UINT8 *StatusValue + ); + +/** + Read SC Soft Strap Values. + + @param[in] This Pointer to the SC_SPI_PROTOCOL insta= nce. + @param[in] SoftStrapAddr SC Soft Strap address offset from FP= SBA. + @param[in] ByteCount Number of bytes in SoftStrap data po= rtion of the SPI cycle + @param[out] SoftStrapValue The Pointer to caller-allocated buff= er containing SC 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolReadPchSoftStrap ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT UINT8 *SoftStrapValue + ); + +/** + This function sends the programmed SPI command to the slave device. + + @param[in] This Pointer to the SC_SPI_PROTOCOL i= nstance. + @param[in] SpiRegionType The SPI Region type for flash cy= cle 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 fa= ll within a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data port= ion of the SPI cycle. + @param[in, out] Buffer Pointer to caller-allocated buff= er containing the data received or sent during the SPI cycle. + + @retval EFI_SUCCESS SPI command completes successful= ly. + @retval EFI_DEVICE_ERROR Device error, the command aborts= abnormally. + @retval EFI_ACCESS_DENIED Some unrecognized command encoun= tered in hardware sequencing mode + @retval EFI_INVALID_PARAMETER The parameters specified are not= valid. + +**/ +EFI_STATUS +SendSpiCmd ( + IN SC_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN FLASH_CYCLE_TYPE FlashCycleType, + IN UINT32 Address, + IN UINT32 ByteCount, + IN OUT UINT8 *Buffer + ); + +/** + 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 err= or 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 comman= d on the SPI interface. + +**/ +BOOLEAN +WaitForSpiCycleComplete ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 PchSpiBar0, + IN BOOLEAN ErrorCheck + ); + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Protocol/= Spi.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Protocol/Spi.h new file mode 100644 index 0000000..b761ad2 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Protocol/Spi.h @@ -0,0 +1,359 @@ +/** @file + This file defines the EFI SPI Protocol which implements the + Intel(R) ICH SPI Host Controller Compatibility Interface. + + Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#ifndef _SC_SPI_PROTOCOL_H_ +#define _SC_SPI_PROTOCOL_H_ + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gScSpiProtocolGuid; +extern EFI_GUID gScSmmSpiProtocolGuid; + +// +// 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; + + +/// +/// SPI protocol data structures and definitions +/// +/// +/// Number of Prefix Opcodes allowed on the SPI interface +/// +#define SPI_NUM_PREFIX_OPCODE 2 + +/// +/// Number of Opcodes in the Opcode Menu +/// +#define SPI_NUM_OPCODE 8 + +/// +/// Opcode Type +/// EnumSpiOpcodeCommand: Command without address +/// EnumSpiOpcodeRead: Read with address +/// EnumSpiOpcodeWrite: Write with address +/// +typedef enum { + EnumSpiOpcodeReadNoAddr, + EnumSpiOpcodeWriteNoAddr, + EnumSpiOpcodeRead, + EnumSpiOpcodeWrite, + EnumSpiOpcodeMax +} SPI_OPCODE_TYPE; + +typedef enum { + EnumSpiCycle20MHz, + EnumSpiCycle33MHz, + EnumSpiCycle66MHz, /// Not supported by BXT + EnumSpiCycle50MHz, + EnumSpiCycleMax +} SPI_CYCLE_FREQUENCY; + +/// +/// Hardware Sequencing required operations (as listed in Broxton EDS "Har= dware +/// Sequencing Commands and Opcode Requirements" +/// +typedef enum { + EnumSpiOperationWriteStatus, + EnumSpiOperationProgramData_1_Byte, + EnumSpiOperationProgramData_64_Byte, + EnumSpiOperationReadData, + EnumSpiOperationWriteDisable, + EnumSpiOperationReadStatus, + EnumSpiOperationWriteEnable, + EnumSpiOperationFastRead, + EnumSpiOperationEnableWriteStatus, + EnumSpiOperationErase_256_Byte, + EnumSpiOperationErase_4K_Byte, + EnumSpiOperationErase_8K_Byte, + EnumSpiOperationErase_64K_Byte, + EnumSpiOperationFullChipErase, + EnumSpiOperationJedecId, + EnumSpiOperationDualOutputFastRead, + EnumSpiOperationDiscoveryParameters, + EnumSpiOperationOther, + EnumSpiOperationMax +} SPI_OPERATION; + +/// +/// SPI Command Configuration +/// Frequency The expected frequency to be used (value to be progr= ammed to the SSFC +/// Register) +/// Operation Which Hardware Sequencing required operation this op= code respoinds to. +/// The required operations are listed in EDS Table 5-55= : "Hardware +/// Sequencing Commands and Opcode Requirements" +/// If the opcode does not corresponds to any operation = listed, use +/// EnumSpiOperationOther, and provides TYPE and Code fo= r it in +/// SpecialOpcodeEntry. +/// +typedef struct _SPI_OPCODE_MENU_ENTRY { + SPI_OPCODE_TYPE Type; + UINT8 Code; + SPI_CYCLE_FREQUENCY Frequency; + SPI_OPERATION Operation; +} SPI_OPCODE_MENU_ENTRY; + +// +// Initialization data table loaded to the SPI host controller +// VendorId Vendor ID of the SPI device +// DeviceId0 Device ID0 of the SPI device +// DeviceId1 Device ID1 of the SPI device +// PrefixOpcode Prefix opcodes which are loaded into the SPI host co= ntroller +// OpcodeMenu Opcodes which are loaded into the SPI host controlle= r Opcode Menu +// BiosStartOffset The offset of the start of the BIOS image relative t= o the flash device. +// Please note this is a Flash Linear Address, NOT a me= mory space address. +// This value is platform specific and depends on the s= ystem flash map. +// This value is only used on non Descriptor mode. +// BiosSize The the BIOS Image size in flash. This value is plat= form specific +// and depends on the system flash map. Please note BIO= S Image size may +// be smaller than BIOS Region size (in Descriptor Mode= ) or the flash size +// (in Non Descriptor Mode), and in this case, BIOS Ima= ge is supposed to be +// placed at the top end of the BIOS Region (in Descrip= tor Mode) or the flash +// (in Non Descriptor Mode) +// +typedef struct _SPI_INIT_TABLE { + UINT8 VendorId; + UINT8 DeviceId0; + UINT8 DeviceId1; + UINT8 PrefixOpcode[SPI_NUM_PREFIX_OPCODE]; + SPI_OPCODE_MENU_ENTRY OpcodeMenu[SPI_NUM_OPCODE]; + UINTN BiosStartOffset; + UINTN BiosSize; +} SPI_INIT_TABLE; + +// +// Protocol member functions +// +/** + Read data from the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL insta= nce. + @param[in] FlashRegionType The Flash Region type for flash cycl= e which is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall w= ithin 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 buff= er 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +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 instan= ce. + @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 wi= thin a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion o= f the SPI cycle. + @param[in] Buffer Pointer to caller-allocated buffer co= ntaining the data sent during the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +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 instan= ce. + @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 wi= thin a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion o= f the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +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 insta= nce. + @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 buff= er 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +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 insta= nce. + @param[in] ComponentNumber The Componen Number for chip select + @param[in] ByteCount Number of bytes in JedecId data port= ion of the SPI cycle, the data size is 3 typically + @param[out] JedecId The Pointer to caller-allocated buff= er 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +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 instan= ce. + @param[in] ByteCount Number of bytes in Status data portio= n of the SPI cycle, the data size is 1 typically + @param[in] StatusValue The Pointer to caller-allocated buffe= r containing the value of Status register writing + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +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 insta= nce. + @param[in] ByteCount Number of bytes in Status data porti= on of the SPI cycle, the data size is 1 typically + @param[out] StatusValue The Pointer to caller-allocated buff= er containing the value of Status register received. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +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 insta= nce. + @param[in] SoftStrapAddr PCH Soft Strap address offset from F= PSBA. + @param[in] ByteCount Number of bytes in SoftStrap data po= rtion of the SPI cycle + @param[out] SoftStrapValue The Pointer to caller-allocated buff= er 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +typedef +EFI_STATUS +(EFIAPI *SC_SPI_READ_PCH_SOFTSTRAP) ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT UINT8 *SoftStrapValue + ); + +/** + The SC SPI protocol implement the South Cluster SPI Host Controller Inte= rface + for DXE, SMM, and PEI environments, respectively. + + These protocols/PPI allows a platform module to perform SPI operations t= hrough 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 are= a 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 stat= us register in the flash part. + SC_SPI_FLASH_READ_STATUS FlashReadStatus; ///< Read status re= gister in the flash part. + SC_SPI_READ_PCH_SOFTSTRAP ReadPchSoftStrap; ///< Read PCH Soft = Strap Values +}; + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/BaseScSpi= CommonLib/BaseScSpiCommonLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthClu= ster/Library/BaseScSpiCommonLib/BaseScSpiCommonLib.inf new file mode 100644 index 0000000..97aec77 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/BaseScSpiCommonL= ib/BaseScSpiCommonLib.inf @@ -0,0 +1,40 @@ +## @file +# Library for ScSpiCommon +# +# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may b= e 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 IM= PLIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D ScSpiCommonLib + FILE_GUID =3D A37CB67E-7D85-45B3-B07E-BF65BDB603E8 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D ScSpiCommonLib + +[Sources] + SpiCommon.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + BroxtonSiPkg/BroxtonSiPrivate.dec + +[LibraryClasses] + IoLib + DebugLib + PcdLib + ScPlatformLib + +[Pcd] + gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress ## CONSUMES + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/BaseScSpi= CommonLib/SpiCommon.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Librar= y/BaseScSpiCommonLib/SpiCommon.c new file mode 100644 index 0000000..97a13fa --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/BaseScSpiCommonL= ib/SpiCommon.c @@ -0,0 +1,994 @@ +/** @file + SC SPI Common Driver implements the SPI Host Controller Compatibility In= terface. + + Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Initialize an SPI protocol instance. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval EFI_SUCCESS The protocol instance was properly initi= alized + @retval EFI_UNSUPPORTED The SC is not supported by this module + +**/ +EFI_STATUS +SpiProtocolConstructor ( + IN SPI_INSTANCE *SpiInstance + ) +{ + UINT32 ScSpiBar0; + UINT8 Comp0Density; + + // + // Initialize the SPI protocol instance + // + SpiInstance->Signature =3D SC_SPI_PRIVATE_DATA_SIGNAT= URE; + SpiInstance->Handle =3D NULL; + SpiInstance->SpiProtocol.FlashRead =3D SpiProtocolFlashRead; + SpiInstance->SpiProtocol.FlashWrite =3D SpiProtocolFlashWrite; + SpiInstance->SpiProtocol.FlashErase =3D SpiProtocolFlashErase; + SpiInstance->SpiProtocol.FlashReadSfdp =3D SpiProtocolFlashReadSfdp; + SpiInstance->SpiProtocol.FlashReadJedecId =3D SpiProtocolFlashReadJedecI= d; + SpiInstance->SpiProtocol.FlashWriteStatus =3D SpiProtocolFlashWriteStatu= s; + SpiInstance->SpiProtocol.FlashReadStatus =3D SpiProtocolFlashReadStatus; + SpiInstance->SpiProtocol.ReadPchSoftStrap =3D SpiProtocolReadPchSoftStra= p; + + SpiInstance->PchSpiBase =3D MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SPI, + PCI_FUNCTION_NUMBER_SPI + ); + + SpiInstance->PchAcpiBase =3D (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddre= ss); + ASSERT (SpiInstance->PchAcpiBase !=3D 0); + + ScSpiBar0 =3D MmioRead32 (SpiInstance->PchSpiBase + R_SPI_BASE) & ~(B_SP= I_BAR0_MASK); + if (ScSpiBar0 =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "ERROR : ScSpiBar0 is invalid!\n")); + ASSERT (FALSE); + } + + MmioOr32 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_= MEMORY_SPACE); + + SpiInstance->RegionPermission =3D MmioRead16 (ScSpiBar0 + R_SPI_FRAP); + DEBUG ((DEBUG_INFO, "Flash RegionPermission : %0x\n", SpiInstance->Regio= nPermission)); + + SpiInstance->SfdpVscc0Value =3D MmioRead32 (ScSpiBar0 + R_SPI_LVSCC); + DEBUG ((DEBUG_INFO, "Component 0 SFDP VSCC value : %0x\n", SpiInstance->= SfdpVscc0Value)); + SpiInstance->SfdpVscc1Value =3D MmioRead32 (ScSpiBar0 + R_SPI_UVSCC); + 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 ( + ScSpiBar0 + R_SPI_FDOC, + (UINT32) (~(B_SPI_FDOC_FDSS_MASK | B_SPI_FDOC_FDSI_MASK)), + (UINT32) (V_SPI_FDOC_FDSS_FSDM | R_SPI_FDBAR_FLASH_MAP0) + ); + + // + // Copy Zero based Number Of Components + // + SpiInstance->NumberOfComponents =3D (UINT8) ((MmioRead16 (ScSpiBar0 + R_= SPI_FDOD) & B_SPI_FDBAR_NC) >> N_SPI_FDBAR_NC); + DEBUG ((DEBUG_INFO, "Component Number : %0x\n", SpiInstance->NumberOfCom= ponents + 1)); + + MmioAndThenOr32 ( + ScSpiBar0 + R_SPI_FDOC, + (UINT32) (~(B_SPI_FDOC_FDSS_MASK | B_SPI_FDOC_FDSI_MASK)), + (UINT32) (V_SPI_FDOC_FDSS_COMP | R_SPI_FCBA_FLCOMP) + ); + + // + // Copy Component 0 Density + // + Comp0Density =3D (UINT8) MmioRead32 (ScSpiBar0 + R_SPI_FDOD) & B_SPI_FLC= OMP_COMP1_MASK; + SpiInstance->Component1StartAddr =3D (UINT32) (V_SPI_FLCOMP_COMP1_512KB = << Comp0Density); + DEBUG ((DEBUG_INFO, "Component 1 StartAddr : %0x\n", SpiInstance->Compon= ent1StartAddr)); + + // + // Select FLASH_MAP1 to get Flash SC Strap Base Address + // + MmioAndThenOr32 ( + (ScSpiBar0 + R_SPI_FDOC), + (UINT32) (~(B_SPI_FDOC_FDSS_MASK | B_SPI_FDOC_FDSI_MASK)), + (UINT32) (V_SPI_FDOC_FDSS_FSDM | R_SPI_FDBAR_FLASH_MAP1) + ); + + SpiInstance->StrapBaseAddress =3D MmioRead32 (ScSpiBar0 + R_SPI_FDOD) & = B_SPI_FDBAR_FPSBA; + + // + // Align FPSBA with address bits for the SC Strap portion of flash descr= iptor + // + SpiInstance->StrapBaseAddress &=3D B_SPI_FDBAR_FPSBA; + DEBUG ((DEBUG_INFO, "StrapBaseAddress : %0x\n", SpiInstance->StrapBaseAd= dress)); + + 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. + + @retval None +**/ +VOID +EFIAPI +PchPmTimerStallRuntimeSafe ( + IN UINT16 ABase, + IN UINTN Microseconds + ) +{ + UINTN Ticks; + UINTN Counts; + UINTN CurrentTick; + UINTN OriginalTick; + UINTN RemainingTick; + +#ifdef SLE_FLAG + Microseconds =3D 0; +#endif + if (Microseconds =3D=3D 0) { + return; + } + + OriginalTick =3D IoRead32 ((UINTN) (ABase + R_ACPI_PM1_TMR)) & B_ACPI_= PM1_TMR_VAL; + CurrentTick =3D OriginalTick; + + // + // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks + // + Ticks =3D Microseconds * 358 / 100 + OriginalTick + 1; + + // + // The loops needed by timer overflow + // + Counts =3D Ticks / V_ACPI_PM1_TMR_MAX_VAL; + + // + // Remaining clocks within one loop + // + RemainingTick =3D Ticks % V_ACPI_PM1_TMR_MAX_VAL; + + // + // not intend to use TMROF_STS bit of register PM1_STS, because this add= s extra + // one I/O operation, and maybe generate SMI + // + while ((Counts !=3D 0) || (RemainingTick > CurrentTick)) { + CurrentTick =3D IoRead32 ((UINTN) (ABase + R_ACPI_PM1_TMR)) & B_ACPI_P= M1_TMR_VAL; + // + // Check if timer overflow + // + if ((CurrentTick < OriginalTick)) { + if (Counts !=3D 0) { + Counts--; + } else { + // + // If timer overflow and Counts equal to 0, that means we already = stalled more than + // RemainingTick, break the loop here + // + break; + } + } + + OriginalTick =3D CurrentTick; + } +} + + +/** + Read data from the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL insta= nce. + @param[in] FlashRegionType The Flash Region type for flash cycl= e which is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall w= ithin 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 buff= er containing the 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashRead ( + IN SC_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 =3D SendSpiCmd ( + This, + FlashRegionType, + FlashCycleRead, + Address, + ByteCount, + Buffer + ); + return Status; +} + + +/** + Write data to the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL instan= ce. + @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 wi= thin a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion o= f the SPI cycle. + @param[in] Buffer Pointer to caller-allocated buffer co= ntaining the data sent during the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashWrite ( + IN SC_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 =3D SendSpiCmd ( + This, + FlashRegionType, + FlashCycleWrite, + Address, + ByteCount, + Buffer + ); + return Status; +} + + +/** + Erase some area on the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL instan= ce. + @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 wi= thin a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion o= f the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashErase ( + IN SC_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 =3D SendSpiCmd ( + This, + FlashRegionType, + FlashCycleErase, + Address, + ByteCount, + NULL + ); + return Status; +} + + +/** + Read SFDP data from the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL insta= nce. + @param[in] ComponentNumber The Component 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 buff= er 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadSfdp ( + IN SC_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 ByteCount, + OUT UINT8 *SfdpData + ) +{ + SPI_INSTANCE *SpiInstance; + EFI_STATUS Status; + UINT32 Address; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + Status =3D EFI_SUCCESS; + + if ((ByteCount > 64) || (ComponentNumber > SpiInstance->NumberOfComponen= ts)) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + Address =3D 0; + if (ComponentNumber =3D=3D FlashComponent1) { + Address =3D SpiInstance->Component1StartAddr; + } + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + 0, + FlashCycleReadSfdp, + Address, + ByteCount, + SfdpData + ); + + return Status; +} + + +/** + Read Jedec Id from the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL insta= nce. + @param[in] ComponentNumber The Component Number for chip select + @param[in] ByteCount Number of bytes in JedecId data port= ion of the SPI cycle, the data size is 3 typically + @param[out] JedecId The Pointer to caller-allocated buff= er 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadJedecId ( + IN SC_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 ByteCount, + OUT UINT8 *JedecId + ) +{ + SPI_INSTANCE *SpiInstance; + EFI_STATUS Status; + UINT32 Address; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + Status =3D EFI_SUCCESS; + + if (ComponentNumber > SpiInstance->NumberOfComponents) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + Address =3D 0; + if (ComponentNumber =3D=3D FlashComponent1) { + Address =3D SpiInstance->Component1StartAddr; + } + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + 0, + FlashCycleReadJedecId, + Address, + ByteCount, + JedecId + ); + + return Status; +} + + +/** + Write the status register in the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL instan= ce. + @param[in] ByteCount Number of bytes in Status data portio= n of the SPI cycle, the data size is 1 typically + @param[in] StatusValue The Pointer to caller-allocated buffe= r containing the value of Status register writing + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not vali= d. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormal= ly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashWriteStatus ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + IN UINT8 *StatusValue + ) +{ + EFI_STATUS Status; + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + 0, + FlashCycleWriteStatus, + 0, + ByteCount, + StatusValue + ); + + return Status; +} + + +/** + Read status register in the flash part. + + @param[in] This Pointer to the SC_SPI_PROTOCOL insta= nce. + @param[in] ByteCount Number of bytes in Status data porti= on of the SPI cycle, the data size is 1 typically + @param[out] StatusValue The Pointer to caller-allocated buff= er containing the value of Status register received. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadStatus ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + OUT UINT8 *StatusValue + ) +{ + EFI_STATUS Status; + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + 0, + FlashCycleReadStatus, + 0, + ByteCount, + StatusValue + ); + + return Status; +} + + +/** + Read SC Soft Strap Values. + + @param[in] This Pointer to the SC_SPI_PROTOCOL insta= nce. + @param[in] SoftStrapAddr SC Soft Strap address offset from FP= SBA. + @param[in] ByteCount Number of bytes in SoftStrap data po= rtion of the SPI cycle + @param[out] SoftStrapValue The Pointer to caller-allocated buff= er containing SC 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 val= id. + @retval EFI_DEVICE_ERROR Device error, command aborts abnorma= lly. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolReadPchSoftStrap ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT UINT8 *SoftStrapValue + ) +{ + SPI_INSTANCE *SpiInstance; + UINT32 StrapFlashAddr; + EFI_STATUS Status; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + + ASSERT (SpiInstance->StrapBaseAddress !=3D 0); + + // + // SC Strap Flash Address =3D FPSBA + RamAddr + // + StrapFlashAddr =3D SpiInstance->StrapBaseAddress + SoftStrapAddr; + + // + // Read SC Soft straps from using execute command + // + Status =3D SendSpiCmd ( + This, + FlashRegionDescriptor, + FlashCycleRead, + StrapFlashAddr, + ByteCount, + SoftStrapValue + ); + + return Status; +} + + +/** + This function sends the programmed SPI command to the slave device. + + @param[in] This Pointer to the SC_SPI_PROTOCOL i= nstance. + @param[in] SpiRegionType The SPI Region type for flash cy= cle 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 fa= ll within a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data port= ion of the SPI cycle. + @param[in, out] Buffer Pointer to caller-allocated buff= er containing the data received or sent during the SPI cycle. + + @retval EFI_SUCCESS SPI command completes successful= ly. + @retval EFI_DEVICE_ERROR Device error, the command aborts= abnormally. + @retval EFI_ACCESS_DENIED Some unrecognized command encoun= tered in hardware sequencing mode + @retval EFI_INVALID_PARAMETER The parameters specified are not= valid. + +**/ +EFI_STATUS +SendSpiCmd ( + IN SC_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; + UINTN SpiBaseAddress; + UINT32 ScSpiBar0; + UINT32 LimitAddress; + UINT32 HardwareSpiAddr; + UINT16 PermissionBit; + UINT32 SpiDataCount; + UINT32 FlashCycle; + UINT8 BiosCtlSave; + UINT32 SmiEnSave; + UINT16 ABase; + + Status =3D EFI_SUCCESS; + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + SpiBaseAddress =3D SpiInstance->PchSpiBase; + ScSpiBar0 =3D AcquireSpiBar0 (SpiInstance); + SpiBaseAddress =3D SpiInstance->PchSpiBase; + ABase =3D SpiInstance->PchAcpiBase; + + DEBUG ((EFI_D_ERROR, "SendSpiCmd Start. \n")); + + // + // 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]=3D= '1'), + // clearing B_GBL_SMI_EN will not have effect. In this situation, some o= ther + // 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 th= e SMI + // sources after the flash cycle . + // + SmiEnSave =3D IoRead32 ((UINTN) (ABase + R_SMI_EN)); + IoWrite32 ((UINTN) (ABase + R_SMI_EN), SmiEnSave & (UINT32) (~B_SMI_EN_G= BL_SMI)); + BiosCtlSave =3D MmioRead8 (SpiBaseAddress + R_SPI_BCR) & B_SPI_BCR_SRC; + + // + // If it's write cycle, disable Prefetching, Caching and disable BIOS Wr= ite Protect + // + if ((FlashCycleType =3D=3D FlashCycleWrite) || + (FlashCycleType =3D=3D FlashCycleErase)) { + DEBUG ((EFI_D_ERROR, "DisableBiosWriteProtect Start. \n")); + Status =3D DisableBiosWriteProtect (); + DEBUG ((EFI_D_ERROR, "DisableBiosWriteProtect End. Status =3D 0x%x\n",= Status)); + + if (EFI_ERROR (Status)) { + goto SendSpiCmdEnd; + } + MmioAndThenOr32 ( + SpiBaseAddress + R_SPI_BCR, + (UINT32) (~B_SPI_BCR_SRC), + (UINT32) (V_SPI_BCR_SRC_PREF_DIS_CACHE_DIS << B_SPI_BCR_SRC) + ); + } + + // + // Make sure it's safe to program the command. + // + if (!WaitForSpiCycleComplete (This, ScSpiBar0, FALSE)) { + Status =3D EFI_DEVICE_ERROR; + goto SendSpiCmdEnd; + } + + HardwareSpiAddr =3D Address; + if ((FlashCycleType =3D=3D FlashCycleRead) || + (FlashCycleType =3D=3D FlashCycleWrite) || + (FlashCycleType =3D=3D FlashCycleErase)) { + switch (FlashRegionType) { + case FlashRegionDescriptor: + if (FlashCycleType =3D=3D FlashCycleRead) { + PermissionBit =3D B_SPI_FRAP_BRRA_FLASHD; + } else { + PermissionBit =3D B_SPI_FRAP_BRRA_FLASHD; + } + HardwareSpiAddr +=3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG0_FLASHD) & + B_SPI_FREG0_BASE_MASK) << N_SPI_FREG0_BASE; + LimitAddress =3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG0_FLASHD) & + B_SPI_FREG0_LIMIT_MASK) >> N_SPI_FREG0_LIMIT; + break; + case FlashRegionBios: + if (FlashCycleType =3D=3D FlashCycleRead) { + PermissionBit =3D B_SPI_FRAP_BRRA_BIOS; + } else { + PermissionBit =3D B_SPI_FRAP_BRRA_BIOS; + } + HardwareSpiAddr +=3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG1_BIOS) & + B_SPI_FREG1_BASE_MASK) << N_SPI_FREG1_BASE; + LimitAddress =3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG1_BIOS) & + B_SPI_FREG1_LIMIT_MASK) >> N_SPI_FREG1_LIMIT; + break; + case FlashRegionMe: + if (FlashCycleType =3D=3D FlashCycleRead) { + PermissionBit =3D B_SPI_FRAP_BRRA_SEC; + } else { + PermissionBit =3D B_SPI_FRAP_BRWA_SEC; + } + HardwareSpiAddr +=3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG2_SEC) & + B_SPI_FREG2_BASE_MASK) << N_SPI_FREG2_BASE; + LimitAddress =3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG2_SEC) & + B_SPI_FREG2_LIMIT_MASK) >> N_SPI_FREG2_LIMIT; + break; + case FlashRegionGbE: + if (FlashCycleType =3D=3D FlashCycleRead) { + PermissionBit =3D B_SPI_FRAP_BRRA_GBE; + } else { + PermissionBit =3D B_SPI_FRAP_BRWA_GBE; + } + HardwareSpiAddr +=3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG3_GBE) & + B_SPI_FREG3_BASE_MASK) << N_SPI_FREG3_BASE; + LimitAddress =3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG3_GBE) & + B_SPI_FREG3_LIMIT_MASK) >> N_SPI_FREG3_LIMIT; + break; + case FlashRegionPlatformData: + if (FlashCycleType =3D=3D FlashCycleRead) { + PermissionBit =3D B_SPI_FRAP_BRRA_PLATFORM; + } else { + PermissionBit =3D B_SPI_FRAP_BRWA_PLATFORM; + } + HardwareSpiAddr +=3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG4_PLATFORM= _DATA) & + B_SPI_FREG4_BASE_MASK) << N_SPI_FREG4_BASE; + LimitAddress =3D (MmioRead32 (ScSpiBar0 + R_SPI_FREG4_PLATFORM_DAT= A) & + B_SPI_FREG4_LIMIT_MASK) >> N_SPI_FREG4_LIMIT; + break; + case FlashRegionAll: + // + // FlashRegionAll indicates address is relative to flash device (i= .e., address is Flash Linear Address) + // No error checking for this case + // + LimitAddress =3D 0; + PermissionBit =3D 0; + break; + default: + Status =3D EFI_UNSUPPORTED; + goto SendSpiCmdEnd; + } + if ((LimitAddress !=3D 0) && (Address > LimitAddress)) { + Status =3D EFI_INVALID_PARAMETER; + goto SendSpiCmdEnd; + } + + // + // If the operation is read, but the region attribute is not read allo= wed, return error. + // If the operation is write, but the region attribute is not write al= lowed, return error. + // + if ((PermissionBit !=3D 0) && ((SpiInstance->RegionPermission & Permis= sionBit) =3D=3D 0)) { + Status =3D EFI_ACCESS_DENIED; + DEBUG ((EFI_D_ERROR, " if ((PermissionBit !=3D 0) && ((SpiInstance->= RegionPermission & PermissionBit) =3D=3D 0)) { Status =3D EFI_ACCESS_DENIE= D \n")); + goto SendSpiCmdEnd; + } + } + + // + // Check for SC SPI hardware sequencing required commands + // + FlashCycle =3D 0; + switch (FlashCycleType) { + case FlashCycleRead: + FlashCycle =3D (UINT32) (V_SPI_HSFS_CYCLE_READ << N_SPI_HSFS_CYCLE); + break; + case FlashCycleWrite: + FlashCycle =3D (UINT32) (V_SPI_HSFS_CYCLE_WRITE << N_SPI_HSFS_CYCLE); + break; + case FlashCycleErase: + if (((ByteCount % SIZE_4KB) !=3D 0) || + ((HardwareSpiAddr % SIZE_4KB) !=3D 0)) { + ASSERT (FALSE); + Status =3D EFI_INVALID_PARAMETER; + goto SendSpiCmdEnd; + } + break; + case FlashCycleReadSfdp: + FlashCycle =3D (UINT32) (V_SPI_HSFS_CYCLE_READ_SFDP << N_SPI_HSFS_CY= CLE); + break; + case FlashCycleReadJedecId: + FlashCycle =3D (UINT32) (V_SPI_HSFS_CYCLE_READ_JEDEC_ID << N_SPI_HSF= S_CYCLE); + break; + case FlashCycleWriteStatus: + FlashCycle =3D (UINT32) (V_SPI_HSFS_CYCLE_WRITE_STATUS << N_SPI_HSFS= _CYCLE); + break; + case FlashCycleReadStatus: + FlashCycle =3D (UINT32) (V_SPI_HSFS_CYCLE_READ_STATUS << N_SPI_HSFS_= CYCLE); + break; + default: + // + // Unrecognized Operation + // + ASSERT (FALSE); + Status =3D EFI_INVALID_PARAMETER; + goto SendSpiCmdEnd; + break; + } + + do { + SpiDataCount =3D ByteCount; + if ((FlashCycleType =3D=3D FlashCycleRead) || (FlashCycleType =3D=3D F= lashCycleWrite)) { + // + // Trim at 256 byte boundary per operation, + // - SC 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 = at most 64 byte + // per operation + // + if (HardwareSpiAddr + ByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 = - 1))) { + SpiDataCount =3D (((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 during each data portion o= f the + // SC SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48,= 56, 64 + // + if (SpiDataCount >=3D 64) { + SpiDataCount =3D 64; + } else if ((SpiDataCount &~0x07) !=3D 0) { + SpiDataCount =3D SpiDataCount &~0x07; + } + } + if (FlashCycleType =3D=3D FlashCycleErase) { + if (((ByteCount / SIZE_64KB) !=3D 0) && + ((ByteCount % SIZE_64KB) =3D=3D 0) && + ((HardwareSpiAddr % SIZE_64KB) =3D=3D 0)) { + if (HardwareSpiAddr < SpiInstance->Component1StartAddr) { + // + // Check whether Component0 support 64k Erase + // + if ((SpiInstance->SfdpVscc0Value & B_SPI_LVSCC_EO_64K) !=3D 0) { + SpiDataCount =3D SIZE_64KB; + } else { + SpiDataCount =3D SIZE_4KB; + } + } else { + // + // Check whether Component1 support 64k Erase + // + if ((SpiInstance->SfdpVscc1Value & B_SPI_LVSCC_EO_64K) !=3D 0) { + SpiDataCount =3D SIZE_64KB; + } else { + SpiDataCount =3D SIZE_4KB; + } + } + } else { + SpiDataCount =3D SIZE_4KB; + } + if (SpiDataCount =3D=3D SIZE_4KB) { + FlashCycle =3D (UINT32) (V_SPI_HSFS_CYCLE_4K_ERASE << N_SPI_HSFS_C= YCLE); + } else { + FlashCycle =3D (UINT32) (V_SPI_HSFS_CYCLE_64K_ERASE << N_SPI_HSFS_= CYCLE); + } + } + // + // If it's write cycle, load data into the SPI data buffer. + // + if ((FlashCycleType =3D=3D FlashCycleWrite) || (FlashCycleType =3D=3D = FlashCycleWriteStatus)) { + if ((SpiDataCount & 0x07) !=3D 0) { + // + // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7 + // + for (Index =3D 0; Index < SpiDataCount; Index++) { + MmioWrite8 (ScSpiBar0 + R_SPI_FDATA00 + Index, Buffer[Index]); + } + } else { + // + // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64 + // + for (Index =3D 0; Index < SpiDataCount; Index +=3D sizeof (UINT32)= ) { + MmioWrite32 (ScSpiBar0 + R_SPI_FDATA00 + Index, *(UINT32 *) (Buf= fer + Index)); + } + } + } + + // + // Set the Flash Address + // + MmioWrite32 ( + (ScSpiBar0 + R_SPI_FADDR), + (UINT32) (HardwareSpiAddr & B_SPI_FADDR_MASK) + ); + + // + // Set Data count, Flash cycle, and Set Go bit to start a cycle + // + MmioAndThenOr32 ( + ScSpiBar0 + R_SPI_HSFS, + (UINT32) (~(B_SPI_HSFS_FDBC_MASK | B_SPI_HSFS_CYCLE_MASK)), + (UINT32) (((SpiDataCount - 1) << N_SPI_HSFS_FDBC) | FlashCycle | B_S= PI_HSFS_CYCLE_FGO) + ); + + // + // end of command execution + // + // Wait the SPI cycle to complete. + // + if (!WaitForSpiCycleComplete (This, ScSpiBar0, TRUE)) { + ASSERT (FALSE); + Status =3D EFI_DEVICE_ERROR; + goto SendSpiCmdEnd; + } + + // + // If it's read cycle, load data into the caller's buffer. + // + if ((FlashCycleType =3D=3D FlashCycleRead) || + (FlashCycleType =3D=3D FlashCycleReadSfdp) || + (FlashCycleType =3D=3D FlashCycleReadJedecId) || + (FlashCycleType =3D=3D FlashCycleReadStatus)) { + if ((SpiDataCount & 0x07) !=3D 0) { + // + // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7 + // + for (Index =3D 0; Index < SpiDataCount; Index++) { + Buffer[Index] =3D MmioRead8 (ScSpiBar0 + R_SPI_FDATA00 + Index); + } + } else { + // + // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64 + // + for (Index =3D 0; Index < SpiDataCount; Index +=3D sizeof (UINT32)= ) { + *(UINT32 *) (Buffer + Index) =3D MmioRead32 (ScSpiBar0 + R_SPI_F= DATA00 + Index); + } + } + } + + HardwareSpiAddr +=3D SpiDataCount; + Buffer +=3D SpiDataCount; + ByteCount -=3D SpiDataCount; + } while (ByteCount > 0); + +SendSpiCmdEnd: + DEBUG ((EFI_D_ERROR, "SendSpiCmd End. Status =3D 0x%x\n", Status)); + + // + // Restore the settings for SPI Prefetching and Caching and enable BIOS = Write Protect. + // + if ((FlashCycleType =3D=3D FlashCycleWrite) || + (FlashCycleType =3D=3D FlashCycleErase)) { + EnableBiosWriteProtect (); + MmioAndThenOr8 ( + SpiBaseAddress + R_SPI_BCR, + (UINT8) ~B_SPI_BCR_SRC, + BiosCtlSave + ); + } + + // + // Restore SMIs. + // + IoWrite32 ((UINTN) (ABase + R_SMI_EN), SmiEnSave); + ReleaseSpiBar0 (SpiInstance); + + return Status; +} + + +/** + Wait execution cycle to complete on the SPI interface. + + @param[in] This The SPI protocol instance + @param[in] ScSpiBar0 Spi MMIO base address + @param[in] ErrorCheck TRUE if the SpiCycle needs to do the err= or 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 comman= d on the SPI interface. + +**/ +BOOLEAN +WaitForSpiCycleComplete ( + IN SC_SPI_PROTOCOL *This, + IN UINT32 ScSpiBar0, + IN BOOLEAN ErrorCheck + ) +{ + UINT64 WaitTicks; + UINT64 WaitCount; + UINT32 Data32; + SPI_INSTANCE *SpiInstance; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + + // + // Convert the wait period allowed into to tick count + // + WaitCount =3D WAIT_TIME / WAIT_PERIOD; + + // + // Wait for the SPI cycle to complete. + // + for (WaitTicks =3D 0; WaitTicks < WaitCount; WaitTicks++) { + Data32 =3D MmioRead32 (ScSpiBar0 + R_SPI_HSFS); + if ((Data32 & B_SPI_HSFS_SCIP) =3D=3D 0) { + MmioWrite32 (ScSpiBar0 + R_SPI_HSFS, B_SPI_HSFS_FCERR | B_SPI_HSFS_F= DONE); + if ( ((Data32 & B_SPI_HSFS_FCERR) !=3D 0) && (ErrorCheck =3D=3D TRUE= )) { + return FALSE; + } else { + return TRUE; + } + } + PchPmTimerStallRuntimeSafe (SpiInstance->PchAcpiBase, WAIT_PERIOD); + } + + return FALSE; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/RuntimeDxe/Sc= Spi.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/RuntimeDxe/ScSpi.c new file mode 100644 index 0000000..f2a15ea --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/RuntimeDxe/ScSpi.c @@ -0,0 +1,313 @@ +/** @file + SC SPI Runtime Driver implements the SPI Host Controller Compatibility I= nterface. + + Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#include "ScSpi.h" + +/// +/// Global variables +/// +GLOBAL_REMOVE_IF_UNREFERENCED SPI_INSTANCE *mSpiInstance; + +/// +/// PchSpiBar0PhysicalAddr keeps the reserved MMIO range assiged to SPI fr= om PEI. +/// It won't be updated no matter the SPI MMIO is reallocated by BIOS PCI = enum. +/// And it's used to override the SPI BAR0 register in runtime environment, +/// +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mPchSpiBar0Phy= sicalAddr; + +/// +/// PchSpiBar0VirtualAddr keeps the virtual address of PchSpiBar0PhysicalA= ddr. +/// And it's used to provide the SPI BAR0 virtual address mapping to PchSp= iBar0PhysicalAddr +/// in runtime environment. +/// +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mPchSpiBar0Vir= tualAddr; +GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mRuntimeFlag; + +// +// Function implementations +// +/** + Fixup internal data pointers so that the services can be called in virtu= al mode. + + @param[in] Event The event registered. + @param[in] Context Event context. Not used in this event ha= ndler. + +**/ +VOID +EFIAPI +PchSpiVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + mRuntimeFlag =3D TRUE; + + EfiConvertPointer (0x0, (VOID **) &mPchSpiBar0VirtualAddr); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->PchSpiBase)); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->SpiProtocol.FlashRead)= ); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->SpiProtocol.FlashWrite= )); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->SpiProtocol.FlashErase= )); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->SpiProtocol.FlashReadS= fdp)); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->SpiProtocol.FlashReadJ= edecId)); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->SpiProtocol.FlashWrite= Status)); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->SpiProtocol.FlashReadS= tatus)); + EfiConvertPointer (0x0, (VOID **) &(mSpiInstance->SpiProtocol.ReadPchSof= tStrap)); + EfiConvertPointer (0x0, (VOID **) &mSpiInstance); +} + + +/** + SPI Runtime DXE Module Entry Point. + + Introduction: + The SPI Runtime DXE module provide a standard way for other modules to= use the PCH SPI Interface in DXE/Runtime. + + Pre: + If SPI Runtime DXE driver is run before Status Code Runtime Protocol i= s installed + and there is the need to use Status code in the driver, it will be nec= essary + to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file. + + Result: + The SPI Runtime DXE driver produces SC_SPI_PROTOCOL. + + Integration Check List: + This driver supports Descriptor Mode only. + This driver supports Hardware Sequence only. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @retval EFI_UNSUPPORTED The chipset is unsupported by this dr= iver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initi= alize the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. + +**/ +EFI_STATUS +EFIAPI +InstallScSpi ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT64 BaseAddress; + UINT64 Length; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR SpiPciMemorySpaceDescriptor; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR SpiBar0MemorySpaceDescriptor; + UINT64 Attributes; + EFI_EVENT AddressChangeEvent; + + DEBUG ((DEBUG_INFO, "InstallScSpi() Start\n")); + + // + // Allocate Runtime memory for the SPI protocol instance. + // + mSpiInstance =3D AllocateRuntimeZeroPool (sizeof (SPI_INSTANCE)); + if (mSpiInstance =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the SPI protocol instance + // + Status =3D SpiProtocolConstructor (mSpiInstance); + if (EFI_ERROR (Status)) { + return Status; + } + mPchSpiBar0PhysicalAddr =3D SC_SPI_BASE_ADDRESS; + mPchSpiBar0VirtualAddr =3D mPchSpiBar0PhysicalAddr; + + // + // Install the PCH_SPI_PROTOCOL interface + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &(mSpiInstance->Handle), + &gScSpiProtocolGuid, + &(mSpiInstance->SpiProtocol), + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (mSpiInstance); + return EFI_DEVICE_ERROR; + } + + // + // Create Address Change event + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + PchSpiVirtualAddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &AddressChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Set SPI space in GCD to be RUNTIME so that the range will be supporte= d in + // virtual address mode in EFI aware OS runtime. + // It will assert if SPI Memory Space is not allocated + // The caller is responsible for the existence and allocation of the SPi= Memory Spaces + // + // + // SPI memory space + // + BaseAddress =3D (EFI_PHYSICAL_ADDRESS) mSpiInstance->PchSpiBase; + Length =3D 0x1000; + + Status =3D gDS->GetMemorySpaceDescriptor (BaseAddress, &SpiPciMemor= ySpaceDescriptor); + ASSERT_EFI_ERROR (Status); + + Attributes =3D SpiPciMemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNT= IME; + Status =3D gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + Attributes + ); + ASSERT_EFI_ERROR (Status); + + // + // SPI MMIO memory space + // + BaseAddress =3D (EFI_PHYSICAL_ADDRESS) mPchSpiBar0PhysicalAddr; + Length =3D 0x1000; + + Status =3D gDS->GetMemorySpaceDescriptor (BaseAddress, &SpiBar0Memo= rySpaceDescriptor); + ASSERT_EFI_ERROR (Status); + + Attributes =3D SpiBar0MemorySpaceDescriptor.Attributes | EFI_MEMORY_RUN= TIME; + Status =3D gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + Attributes + ); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "InstallScSpi() End\n")); + + return EFI_SUCCESS; +} + + +/** + Acquire SC SPI MMIO address. + It is not expected for this BAR0 to change because the SPI device is hid= den + from the OS for SKL PCH LP/H B stepping and above (refer to section 3.5.= 1), + but if it is ever different from the preallocated address, reassign it b= ack. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval UINT32 Return SPI MMIO address + +**/ +UINT32 +AcquireSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ) +{ + UINT32 SpiBar0; + + // + // Save original SPI MMIO address + // + SpiBar0 =3D MmioRead32 (SpiInstance->PchSpiBase + R_SPI_BASE) & ~(B_SPI_= BAR0_MASK); + + if (SpiBar0 !=3D mPchSpiBar0PhysicalAddr) { + // + // Temporary disable MSE, and override with SPI reserved MMIO address,= then enable MSE. + // + MmioAnd8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_P= CI_COMMAND_MEMORY_SPACE); + MmioWrite32 (SpiInstance->PchSpiBase + R_SPI_BASE, mPchSpiBar0Physical= Addr); + MmioOr8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND= _MEMORY_SPACE); + } + + if (mRuntimeFlag) { + return mPchSpiBar0VirtualAddr; + } else { + return mPchSpiBar0PhysicalAddr; + } +} + + +/** + Release SC spi mmio address. Do nothing. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + +**/ +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 initi= alized + @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in S= MM phase + +**/ +EFI_STATUS +EFIAPI +DisableBiosWriteProtect ( + VOID + ) +{ + UINTN SpiBaseAddress; + + SpiBaseAddress =3D mSpiInstance->PchSpiBase; + if ((MmioRead8 (SpiBaseAddress + R_SPI_BCR) & B_SPI_BCR_EISS) !=3D 0) { + return EFI_ACCESS_DENIED; + } + + // + // Enable the access to the BIOS space for both read and write cycles + // + MmioOr8 ( + SpiBaseAddress + R_SPI_BCR, + (UINT8) (B_SPI_BCR_BIOSWE) + ); + + return EFI_SUCCESS; +} + + +/** + This function is a hook for Spi to enable BIOS Write Protect. + +**/ +VOID +EFIAPI +EnableBiosWriteProtect ( + VOID + ) +{ + UINTN SpiBaseAddress; + + SpiBaseAddress =3D mSpiInstance->PchSpiBase; + + // + // 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/Spi/RuntimeDxe/Sc= Spi.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/RuntimeDxe/ScSpi.h new file mode 100644 index 0000000..ad2cb45 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/RuntimeDxe/ScSpi.h @@ -0,0 +1,50 @@ +/** @file + Header file for the SC SPI Runtime Driver. + + Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#ifndef _SC_SPI_RT_H_ +#define _SC_SPI_RT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Function prototypes used by the SPI protocol. +// +/** + Fixup internal data pointers so that the services can be called in virtu= al mode. + + @param[in] Event The event registered. + @param[in] Context Event context. Not used in this event ha= ndler. + +**/ +VOID +EFIAPI +PchSpiVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/RuntimeDxe/Sc= SpiRuntime.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/RuntimeDx= e/ScSpiRuntime.inf new file mode 100644 index 0000000..ea8f42a --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/RuntimeDxe/ScSpiRunt= ime.inf @@ -0,0 +1,60 @@ +## @file +# Component description file for SPI Runtime driver. +# +# Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may b= e 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 IM= PLIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D ScSpiRuntime + FILE_GUID =3D C194C6EA-B68C-4981-B64B-9BD271474B20 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InstallScSpi + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC + +[Sources] + ScSpi.h + ScSpi.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + BroxtonSiPkg/BroxtonSiPrivate.dec + +[LibraryClasses] + UefiRuntimeServicesTableLib + UefiRuntimeLib + UefiBootServicesTableLib + UefiDriverEntryPoint + DxeServicesTableLib + UefiLib + DebugLib + MemoryAllocationLib + IoLib + MmPciLib + ScSpiCommonLib + +[Guids] + gEfiEventVirtualAddressChangeGuid ## UNDEFINED + +[Protocols] + gScSpiProtocolGuid ## PRODUCES + +[Depex] + gEfiStatusCodeRuntimeProtocolGuid AND + TRUE + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpi.c b= /Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpi.c new file mode 100644 index 0000000..1a84f6f --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpi.c @@ -0,0 +1,249 @@ +/** @file + SC SPI SMM Driver implements the SPI Host Controller Compatibility Inter= face. + + Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#include "ScSpi.h" + +/// +/// Global variables +/// +GLOBAL_REMOVE_IF_UNREFERENCED SPI_INSTANCE *mSpiInstance; + +/// +/// mPchSpiResvMmioAddr keeps the reserved MMIO range assiged to SPI. +/// In SMM it always set back the reserved MMIO address to SPI BAR0 to ens= ure the MMIO range +/// won't overlap with SMRAM range, and trusted. +/// +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSpiResvMmioAddr; + +/** + SPI Runtime SMM Module Entry Point. + + Introduction: + 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 PCH_SPI_PROTOCOL with GUID + gPchSmmSpiProtocolGuid which is different from SPI RUNTIME driver. + + Integration Check List: + 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 bef= ore + 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. + @retval EFI_UNSUPPORTED The chipset is unsupported by this dr= iver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initi= alize the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. + +**/ +EFI_STATUS +EFIAPI +InstallScSpi ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Init PCH spi reserved MMIO address. + // + mSpiResvMmioAddr =3D SC_SPI_BASE_ADDRESS; + + // + // Allocate pool for SPI protocol instance + // + Status =3D gSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + sizeof (SPI_INSTANCE), + (VOID **) &mSpiInstance + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (mSpiInstance =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE)); + + // + // Initialize the SPI protocol instance + // + Status =3D SpiProtocolConstructor (mSpiInstance); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Install the SMM SC_SPI_PROTOCOL interface + // + Status =3D gSmst->SmmInstallProtocolInterface ( + &(mSpiInstance->Handle), + &gScSmmSpiProtocolGuid, + EFI_NATIVE_INTERFACE, + &(mSpiInstance->SpiProtocol) + ); + if (EFI_ERROR (Status)) { + gSmst->SmmFreePool (mSpiInstance); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + + +/** + Acquire SC spi mmio address. + It is not expected for this BAR0 to change because the SPI device is hid= den + from the OS for SKL PCH LP/H B stepping and above (refer to section 3.5.= 1), + but if it is ever different from the preallocated address, reassign it b= ack. + 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 + +**/ +UINT32 +AcquireSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ) +{ + UINT32 SpiBar0; + + // + // Save original SPI MMIO address + // + SpiBar0 =3D MmioRead32 (SpiInstance->PchSpiBase + R_SPI_BASE) & B_SPI_BA= SE_BAR; + + if (SpiBar0 !=3D mSpiResvMmioAddr) { + // + // Temporary disable MSE, and override with SPI reserved MMIO address,= then enable MSE. + // + MmioAnd8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_P= CI_COMMAND_MEMORY_SPACE); + MmioWrite32 (SpiInstance->PchSpiBase + R_SPI_BASE, mSpiResvMmioAddr); + MmioOr8 (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 SC 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. + + @param[in] None + + @retval EFI_SUCCESS The protocol instance was properly in= itialized + @retval EFI_ACCESS_DENIED The BIOS Region can only be updated i= n SMM phase + +**/ +EFI_STATUS +EFIAPI +DisableBiosWriteProtect ( + VOID + ) +{ + UINTN SpiBaseAddress; + UINT32 Data32; + + SpiBaseAddress =3D MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SPI, + PCI_FUNCTION_NUMBER_SPI + ); + + // + // Set BIOSWE bit (SPI PCI Offset DCh [0]) =3D 1b + // 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 None + +**/ +VOID +EFIAPI +EnableBiosWriteProtect ( + VOID + ) +{ + UINTN SpiBaseAddress; + UINT32 Data32; + + SpiBaseAddress =3D MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SPI, + PCI_FUNCTION_NUMBER_SPI + ); + + // + // Clear BIOSWE bit (SPI PCI Offset DCh [0]) =3D 0b + // Disable the access to the BIOS space for write cycles + // + MmioAnd8 ( + SpiBaseAddress + R_SPI_BCR, + (UINT8) (~N_SPI_BCR_BIOSWE) + ); +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpi.h b= /Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpi.h new file mode 100644 index 0000000..7b27974 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpi.h @@ -0,0 +1,33 @@ +/** @file + Header file for the SC SPI SMM Driver. + + Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#ifndef _SC_SPI_SMM_H_ +#define _SC_SPI_SMM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpiSmm.= inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpiSmm.inf new file mode 100644 index 0000000..9c82067 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Spi/Smm/ScSpiSmm.inf @@ -0,0 +1,49 @@ +## @file +# Component description file for SPI SMM driver. +# +# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may b= e 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 IM= PLIED. +# +## + +[defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D ScSpiSmm + FILE_GUID =3D 27F4917B-A707-4aad-9676-26DF168CBF0D + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 1.0 + PI_SPECIFICATION_VERSION =3D 0x0001000A + ENTRY_POINT =3D InstallScSpi + +[Sources] + ScSpi.h + ScSpi.c + +[Packages] + MdePkg/MdePkg.dec + Silicon/BroxtonSiPkg/BroxtonSiPkg.dec + Silicon/BroxtonSiPkg/BroxtonSiPrivate.dec + +[LibraryClasses] + DebugLib + IoLib + UefiDriverEntryPoint + UefiBootServicesTableLib + BaseLib + SmmServicesTableLib + ScSpiCommonLib + MmPciLib + +[Protocols] + gScSmmSpiProtocolGuid ## PRODUCES + +[Depex] + TRUE + --=20 2.7.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel