/** @file
SPI library for abstraction of SPI HW registers accesses
Copyright (c) 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
Checks if PCH SPI Controler is present and available
@retval TRUE PCH SPI controller is avaialable
@retval FALSE PCH SPI controller is not available
**/
BOOLEAN
SpiIsControllerAvailable (
VOID
)
{
//
// Checks for SPI controller
//
return (PciSegmentRead16 (SpiPciCfgBase () + PCI_VENDOR_ID_OFFSET) != 0xFFFF);
}
/**
Returns PCH SPI BAR0 value
@retval UINT32 PCH SPI BAR0 value
**/
UINT32
SpiGetBar0 (
VOID
)
{
UINT32 SpiBar0;
ASSERT (SpiIsControllerAvailable ());
SpiBar0 = PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BAR0) & ~B_SPI_CFG_BAR0_MASK;
ASSERT (SpiBar0 != 0);
return SpiBar0;
}
/**
Reads given descriptor section and returns value
@param[in] UINT16 Descriptor section
@param[in] UINT16 Offset
@retval UINT32 Read value from a section under given offset
**/
STATIC
UINT32
SpiReadDescriptor (
IN UINT16 DescriptorSection,
IN UINT16 Offset
)
{
UINT32 SpiBar0;
SpiBar0 = SpiGetBar0 ();
MmioWrite32 (SpiBar0 + R_SPI_MEM_FDOC, (DescriptorSection | Offset));
return MmioRead32 (SpiBar0 + R_SPI_MEM_FDOD);
}
/**
Returns descriptor signature
@retval UINT32 Descriptor signature
**/
UINT32
SpiGetDescriptorSignature (
VOID
)
{
//
// Read Descriptor offset 0x10 - To get Descriptor Signature
// Signature section 0x0000 + offset 0x0 which points to Descriptor offset 0x10
//
return SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM, 0x0);
}
/**
Returns supported features and R/W frequencies of Flash Component
@retval UINT32 Flash Component features descriptor
**/
UINT32
SpiGetFlashComponentDescription (
VOID
)
{
//
// Read Descriptor offset 0x30 - To get supported features and R/W frequencies
// Component section 0x1000 + offset 0x0 which points to Descriptor offset 0x30
//
return SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_COMP, 0x0);
}
/**
Returns number of Flash Components
@retval UINT32 Flash components number
**/
UINT32
SpiGetFlashComponentsNumber (
VOID
)
{
//
// Read Descriptor offset 0x14 - To get number of components
// Signature section 0x0000 + offset 0x4 which points to Descriptor offset 0x14
//
return ((SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM, R_FLASH_FDBAR_FLASH_MAP0) & B_FLASH_FDBAR_NC) >> N_FLASH_FDBAR_NC);
}
/**
Returns total Flash size with regards to number of flash components
@retval UINT32 Total Flash Memory size
**/
UINT32
SpiGetTotalFlashSize (
VOID
)
{
UINT32 Data32;
UINT32 ComponentsNumber;
UINT32 TotalFlashSize;
Data32 = SpiGetFlashComponentDescription ();
ComponentsNumber = SpiGetFlashComponentsNumber ();
TotalFlashSize = (V_FLASH_FLCOMP_COMP_512KB << ((UINT8) (Data32 & B_FLASH_FLCOMP_COMP0_MASK)));
if (ComponentsNumber == 1) {
TotalFlashSize += (V_FLASH_FLCOMP_COMP_512KB << ((UINT8) ((Data32 & B_FLASH_FLCOMP_COMP1_MASK) >> 4)));
}
return TotalFlashSize;
}
/**
Checks BIOS lock bits for proper value and checks if write protection is enabled
Expected vales are: LE bit set, EISS bit set and WPD bit cleared
@retval TRUE All protection bits are set correctly
@retval FALSE Not all protection bits had exepcted values
**/
BOOLEAN
SpiIsWriteProtectionEnabled (
VOID
)
{
UINT32 BiosControl;
BiosControl = PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC);
DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL LE: %x\n", (BiosControl & B_SPI_CFG_BC_LE) != 0 ));
DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL WPD: %x\n", (BiosControl & B_SPI_CFG_BC_WPD) != 0 ));
DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL EISS: %x\n", (BiosControl & B_SPI_CFG_BC_EISS) != 0 ));
return (((BiosControl & B_SPI_CFG_BC_LE) != 0) &&
((BiosControl & B_SPI_CFG_BC_WPD) == 0) &&
((BiosControl & B_SPI_CFG_BC_EISS) != 0));
}
/**
Returns status of BIOS Interface Lockdown
@retval TRUE BIOS Interface Lockdown is enabled
@retval FALSE BIOS Interface Lockdown is disabled
**/
BOOLEAN
SpiIsBiosInterfaceLockdownEnabled (
VOID
)
{
return !!(PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC) & B_SPI_CFG_BC_BILD);
}
/**
Returns Flash Descriptor Override Pin Strap status
@retval TRUE Flash Descriptor override is enabled
@retval FALSE Flash Descriptor override is disabled
**/
BOOLEAN
SpiIsFlashDescriptorOverrideEnabled (
VOID
)
{
UINT32 SpiBar0;
SpiBar0 = SpiGetBar0 ();
return !!(MmioRead16 (SpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_FDOPSS);
}
/**
Returns Flash Configuration Lock Down bit status
@retval TRUE Flash Configuration Lock Down bit is set
@retval FALSE Flash Configuration Lock Down bit is not set
**/
BOOLEAN
SpiIsFlashConfigurationLockDownEnabled (
VOID
)
{
UINT32 SpiBar0;
SpiBar0 = SpiGetBar0 ();
return !!(MmioRead16 (SpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_FLOCKDN);
}
/**
Returns Top Swap functionality enable state
@retval TRUE Top Swap is enabled
@retval FALSE Top Swap is disabled
**/
BOOLEAN
SpiIsTopSwapEnabled (
VOID
)
{
return !!(PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC) & B_SPI_CFG_BC_TSS);
}
/**
Return Component Property Parameter Table for a given component number
@param[in] ComponentNumber SPI Component number
@param[out] CppTable Component Poperty Parameter Table value
@retval TRUE Vendor Specific Component Capabilities Register value was read
@reval FALSE Vendor Specific Component Capabilities Register value was not present
**/
BOOLEAN
SpiGetComponentPropertyParameterTable (
IN UINT8 ComponentNumber,
OUT UINT32 *CppTable
)
{
UINT32 SpiBar0;
UINT32 Data32;
SpiBar0 = SpiGetBar0 ();
//
// More than 2 components not supported
//
switch (ComponentNumber) {
case 0:
*CppTable = MmioRead32 (SpiBar0 + R_SPI_MEM_SFDP0_VSCC0);
return TRUE;
case 1:
Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM, R_FLASH_FDBAR_FLASH_MAP0);
*CppTable = MmioRead32 (SpiBar0 + R_SPI_MEM_SFDP1_VSCC1);
return !!(Data32 & BIT8);
default:
return FALSE;
}
}
/**
Returns valid bit status in given Component Property Parameter Table
@param[in] CppTable Component Poperty Parameter Table value
@retval TRUE Valid bit is set
@reval FALSE Valid bit is not set
**/
BOOLEAN
SpiIsCppValidBitSet (
IN UINT32 CppTable
)
{
return !!(CppTable & B_SPI_MEM_SFDPX_VSCCX_CPPTV);
}
/**
Checks if Flash Descriptor is valid
@retval TRUE Flash Descriptor is valid
@retval FALSE Flash Descriptor is invalid
**/
BOOLEAN
SpiIsFlashDescriptorValid (
VOID
)
{
UINT32 SpiBar0;
SpiBar0 = SpiGetBar0 ();
return !!(MmioRead32 (SpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_FDV);
}
/**
Reads and returns value from Flash Region Access Permissions Register (FRAP)
@retval UINT32 Flash Region Access Permissions Register value
**/
STATIC
UINT32
SpiGetFlashRegionAccessPermissions (
VOID
)
{
return MmioRead32 (SpiGetBar0 () + R_SPI_MEM_FRAP);
}
/**
Returns masked BIOS Master Read Access
@retval UINT32 Already masked BIOS Master Read Access
**/
UINT32
SpiGetMasterReadAccess (
VOID
)
{
UINT32 Data32;
Data32 = SpiGetFlashRegionAccessPermissions () & B_SPI_MEM_FRAP_BMRAG_MASK;
DEBUG ((DEBUG_INFO, "BMRAG 0x%x\n", Data32));
return Data32;
}
/**
Returns masked BIOS Master Write Access
@retval UINT32 Already masked BIOS Master Write Access
**/
UINT32
SpiGetMasterWriteAccess (
VOID
)
{
UINT32 Data32;
Data32 = SpiGetFlashRegionAccessPermissions () & B_SPI_MEM_FRAP_BMWAG_MASK;
DEBUG ((DEBUG_INFO, "BMWAG 0x%x\n", Data32));
return Data32;
}
/**
Returns GbE Region Access rights
@retval UINT32 GbE Region access rights
**/
UINT32
SpiGetGbeRegionAccess (
VOID
)
{
UINT32 Data32;
Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x8);
DEBUG ((DEBUG_INFO, "GbE Region Access 0x%x\n", Data32));
return Data32;
}
/**
Returns CSME region access rights
@retval UINT32 CSME Region Access rights
**/
UINT32
SpiGetCsmeRegionAccess (
VOID
)
{
UINT32 Data32;
Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x4);
DEBUG ((DEBUG_INFO, "CSME Region Access 0x%x\n", Data32));
return Data32;
}
/**
Returns EC region access right
@retval UINT32 EC Region access rights
**/
UINT32
SpiGetEcRegionAccess (
VOID
)
{
UINT32 Data32;
Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x10);
DEBUG ((DEBUG_INFO, "EC Region Access 0x%x\n", Data32));
return Data32;
}
/**
Checks if Slave Attached Flash (SAF) mode is active
@retval TRUE SAF mode is active
@retval FALSE SAF mode is not active
**/
BOOLEAN
SpiIsSafModeActive (
VOID
)
{
UINT32 SpiBar0;
SpiBar0 = SpiGetBar0 ();
return !!(MmioRead32 (SpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_SAF_MODE_ACTIVE);
}
/**
Checks validity of GbE region
@retval TRUE GbE region is valid
@retval FALSE GbE regios in invalid
**/
BOOLEAN
SpiIsGbeRegionValid (
VOID
)
{
UINT32 SpiBar0;
SpiBar0 = SpiGetBar0 ();
if (MmioRead32 (SpiBar0 + R_SPI_MEM_FREG3_GBE) != B_SPI_MEM_FREGX_BASE_MASK) {
return TRUE;
}
return FALSE;
}
/**
Returns TRUE if BIOS Boot Strap is set to SPI
@retval TRUE BIOS Boot strap is set to SPI
@retval FALSE BIOS Boot strap is set to LPC/eSPI
**/
BOOLEAN
SpiIsBiosBootFromSpi (
VOID
)
{
return !!(((PciSegmentRead8 (SpiPciCfgBase () + R_SPI_CFG_BC) & B_SPI_CFG_BC_BBS) >> N_SPI_CFG_BC_BBS) == V_SPI_CFG_BC_BBS_SPI);
}
/**
Check SPI write status disable is set
@retval TRUE Write status disable is set
@retval FALSE Write status disable is not set
**/
BOOLEAN
SpiIsWriteStatusDisable (
VOID
)
{
return !!(MmioRead32 (SpiGetBar0 () + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_WRSDIS);
}