summaryrefslogtreecommitdiff
path: root/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library
diff options
context:
space:
mode:
authorzwei4 <david.wei@intel.com>2017-03-10 16:00:56 +0800
committerGuo Mang <mang.guo@intel.com>2017-05-09 13:03:11 +0800
commit03ef874676a3bf61581996bcf3d8ded1866ddc05 (patch)
treeda9d38fb39b562200e6010f3091539800b005e6a /Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library
parent61e5cdf388f8c748fef3d5f5af82640fa79cc4c5 (diff)
downloadedk2-platforms-03ef874676a3bf61581996bcf3d8ded1866ddc05.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/Library')
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/PeiSpiInitLib.inf44
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/ScSpi.c237
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/PeiSpiInitLib/ScSpi.h44
3 files changed, 325 insertions, 0 deletions
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