/** @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); }