From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- Board/Flash/FWH/FwhFlash.cif | 11 + Board/Flash/FWH/FwhFlash.mak | 94 +++ Board/Flash/FWH/FwhFlash.sdl | 113 +++ Board/Flash/FWH/FwhIntelFlashWrite.c | 769 +++++++++++++++++ Board/Flash/FWH/FwhSstFlashWrite.c | 695 ++++++++++++++++ Board/Flash/Flash.chm | Bin 0 -> 113742 bytes Board/Flash/Flash.cif | 18 + Board/Flash/Flash.mak | 118 +++ Board/Flash/Flash.sdl | 212 +++++ Board/Flash/FlashUpdate.c | 367 +++++++++ Board/Flash/FlashWrite.c | 697 ++++++++++++++++ Board/Flash/LPC/LpcFlash.cif | 11 + Board/Flash/LPC/LpcFlash.mak | 99 +++ Board/Flash/LPC/LpcFlash.sdl | 114 +++ Board/Flash/LPC/LpcFlashWrite.c | 715 ++++++++++++++++ Board/Flash/LPC/LpcSst2MblFlashWrite.c | 734 +++++++++++++++++ Board/Flash/SPI/ICHx/ICHxSpi.sdl | 86 ++ Board/Flash/SPI/ICHx/SPIFlash.c | 1369 +++++++++++++++++++++++++++++++ Board/Flash/SPI/ICHx/SpiCspSrc.cif | 9 + Board/Flash/SPI/SpiFlash.cif | 14 + Board/Flash/SPI/SpiFlash.h | 531 ++++++++++++ Board/Flash/SPI/SpiFlash.mak | 115 +++ Board/Flash/SPI/SpiFlash.sdl | 232 ++++++ Board/Flash/SPI/SpiIdentify.c | 865 +++++++++++++++++++ Board/Flash/SPI/Template/SPIFlash.c | 1038 +++++++++++++++++++++++ Board/Flash/SPI/Template/SpiCspSrc.cif | 8 + Board/Flash/STD/STDIntelFlashWrite.c | 699 ++++++++++++++++ Board/Flash/STD/StdFlash.cif | 12 + Board/Flash/STD/StdFlash.mak | 71 ++ Board/Flash/STD/StdFlash.sdl | 133 +++ Board/Flash/STD/StdMxicFlashWrite.c | 698 ++++++++++++++++ Board/Flash/STD/StdSpansionFlashWrite.c | 669 +++++++++++++++ 32 files changed, 11316 insertions(+) create mode 100644 Board/Flash/FWH/FwhFlash.cif create mode 100644 Board/Flash/FWH/FwhFlash.mak create mode 100644 Board/Flash/FWH/FwhFlash.sdl create mode 100644 Board/Flash/FWH/FwhIntelFlashWrite.c create mode 100644 Board/Flash/FWH/FwhSstFlashWrite.c create mode 100644 Board/Flash/Flash.chm create mode 100644 Board/Flash/Flash.cif create mode 100644 Board/Flash/Flash.mak create mode 100644 Board/Flash/Flash.sdl create mode 100644 Board/Flash/FlashUpdate.c create mode 100644 Board/Flash/FlashWrite.c create mode 100644 Board/Flash/LPC/LpcFlash.cif create mode 100644 Board/Flash/LPC/LpcFlash.mak create mode 100644 Board/Flash/LPC/LpcFlash.sdl create mode 100644 Board/Flash/LPC/LpcFlashWrite.c create mode 100644 Board/Flash/LPC/LpcSst2MblFlashWrite.c create mode 100644 Board/Flash/SPI/ICHx/ICHxSpi.sdl create mode 100644 Board/Flash/SPI/ICHx/SPIFlash.c create mode 100644 Board/Flash/SPI/ICHx/SpiCspSrc.cif create mode 100644 Board/Flash/SPI/SpiFlash.cif create mode 100644 Board/Flash/SPI/SpiFlash.h create mode 100644 Board/Flash/SPI/SpiFlash.mak create mode 100644 Board/Flash/SPI/SpiFlash.sdl create mode 100644 Board/Flash/SPI/SpiIdentify.c create mode 100644 Board/Flash/SPI/Template/SPIFlash.c create mode 100644 Board/Flash/SPI/Template/SpiCspSrc.cif create mode 100644 Board/Flash/STD/STDIntelFlashWrite.c create mode 100644 Board/Flash/STD/StdFlash.cif create mode 100644 Board/Flash/STD/StdFlash.mak create mode 100644 Board/Flash/STD/StdFlash.sdl create mode 100644 Board/Flash/STD/StdMxicFlashWrite.c create mode 100644 Board/Flash/STD/StdSpansionFlashWrite.c (limited to 'Board/Flash') diff --git a/Board/Flash/FWH/FwhFlash.cif b/Board/Flash/FWH/FwhFlash.cif new file mode 100644 index 0000000..cda4bdf --- /dev/null +++ b/Board/Flash/FWH/FwhFlash.cif @@ -0,0 +1,11 @@ + + name = "FWH Interface - Source" + category = ModulePart + LocalRoot = "Board\Flash\FWH" + RefName = "FWH_INTERFACE_SOURCE" +[files] +"FwhFlash.sdl" +"FwhFlash.mak" +"FwhSstFlashWrite.c" +"FwhIntelFlashWrite.c" + diff --git a/Board/Flash/FWH/FwhFlash.mak b/Board/Flash/FWH/FwhFlash.mak new file mode 100644 index 0000000..0b00b49 --- /dev/null +++ b/Board/Flash/FWH/FwhFlash.mak @@ -0,0 +1,94 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Flash_Combined_2/Core/FWH/FwhFlash.mak 5 10/25/10 5:54a Calvinchen $ +# +# $Revision: 5 $ +# +# $Date: 10/25/10 5:54a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Flash_Combined_2/Core/FWH/FwhFlash.mak $ +# +# 5 10/25/10 5:54a Calvinchen +# Added support for PEI Flash Library. +# +# 4 6/24/09 3:12a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# 3 1/20/09 11:58p Calvinchen +# +# 1 12/18/06 3:39p Robert +# Initial Check in +# +# 1 10/31/06 2:30p Sivagarn +# Initial Checkin +# +# +#********************************************************************** +#********************************************************************** +# +# +# Name: FWHFlash.mak +# +# Description: +# +# +#********************************************************************** +all : FWHFlash + +FWHFlash : $(BUILD_DIR)\FWHFlash.mak FWHFlashBin + +#--------------------------------------------------------------------------- +# Generic FWH FLASH dependencies +#--------------------------------------------------------------------------- +$(BUILD_DIR)\FWHFlash.mak : $(FWHFlash_DIR)\$(@B).cif $(FWHFlash_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(FWHFlash_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +#--------------------------------------------------------------------------- +# Create FWH Flash Library +#--------------------------------------------------------------------------- +FWHFlashBin : + @set INCLUDE=%%INCLUDE%% + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\FWHFlash.mak all\ + "CFLAGS=$(CFLAGS:/W4=/W3)" \ + NAME=FWHFlash \ + TYPE=LIBRARY LIBRARY_NAME=$(FWHFLASHLIB) +!IF "$(x64_BUILD)"=="1" && "$(BUILD_PEI_FLASH_LIB)"=="1" + $(MAKE) /$(MAKEFLAGS) BUILD_ROOT=$(BUILD_DIR)\ + "EXT_OBJS=$(**:Build\=Build\IA32\)" PROJECT_DIR=$(PROJECT_DIR)\ + /f $(BUILD_DIR)\FWHFlash.mak all\ + "CFLAGS=$(CFLAGS:/W4=/W3)"\ + BUILD_DIR=$(BUILD_DIR)\IA32\ + TYPE=PEI_LIBRARY NAME=FWHFlash +!ENDIF + +$(FWHFLASHLIB) : FWHFlash + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* \ No newline at end of file diff --git a/Board/Flash/FWH/FwhFlash.sdl b/Board/Flash/FWH/FwhFlash.sdl new file mode 100644 index 0000000..d38d4c4 --- /dev/null +++ b/Board/Flash/FWH/FwhFlash.sdl @@ -0,0 +1,113 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Flash_Combined_2/Core/FWH/FwhFlash.sdl 5 6/24/09 3:12a Calvinchen $ +# +# $Revision: 5 $ +# +# $Date: 6/24/09 3:12a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Flash_Combined_2/Core/FWH/FwhFlash.sdl $ +# +# 5 6/24/09 3:12a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# +#********************************************************************** +TOKEN + Name = "FWHFlash_SUPPORT" + Value = "1" + Help = "Main switch to enable FWH Flash support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "FWHFLASHLIB" + Value = "$(BUILD_DIR)\FWHFlash.lib" + TokenType = Expression + TargetMAK = Yes +End + +TOKEN + Name = "Intel_82802Ax" + Value = "1" + Help = "This token enables support for the N82802AC/AB, ATMEL 49LW080, STM M50FW080/016 and SST 49LF016C flash parts" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "SST_49LF00x" + Value = "1" + Help = "This enables support for the SST 49LF008 and 004 FWH flash parts" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +PATH + Name = "FWHFlash_DIR" +End + +MODULE + Help = "Includes FlashSrc.mak to Project" + File = "FWHFlash.mak" +End + +ELINK + Name = "mSstFwhIdentify," + Parent = "FlashList" + Token = "SST_49LF00x" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "mIntelIdentify," + Parent = "FlashList" + Token = "Intel_82802Ax" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(BUILD_DIR)\FWHFlash.lib" + Parent = "$(Flash_DIR)\FWHFlash.lib" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(Flash_DIR)\FWHFlash.lib" + Parent = "FLASHLISTLIB" + InvokeOrder = AfterParent +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Board/Flash/FWH/FwhIntelFlashWrite.c b/Board/Flash/FWH/FwhIntelFlashWrite.c new file mode 100644 index 0000000..4541975 --- /dev/null +++ b/Board/Flash/FWH/FwhIntelFlashWrite.c @@ -0,0 +1,769 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/FWH/FwhIntelFlashWrite.c 16 12/23/09 6:12a Calvinchen $ +// +// $Revision: 16 $ +// +// $Date: 12/23/09 6:12a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/FWH/FwhIntelFlashWrite.c $ +// +// 16 12/23/09 6:12a Calvinchen +// Improvement: +// 1.Added FWH/LPC/STD Flash Device Number support. +// 2.Changed for SMIFlash module Label "4.6.3.6_SMIFLASH_12" or later +// +// 15 12/15/09 5:47a Calvinchen +// Modified for adding flash chip name support. +// +// 14 6/24/09 3:12a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 13 1/20/09 11:58p Calvinchen +// +// 10 6/19/08 3:53a Calvinchen +// Added support for SST 49LF016C 2MB FWH flash part. +// +// 9 5/09/08 3:33a Calvinchen +// +// 8 11/09/07 4:16p Alexp +// Added dummy FlashRead function. Not supported by this type of flash +// module +// +// 7 5/24/07 12:08p Fasihm +// Updated code to match the code review standards. +// +// 6 3/26/07 7:22p Robert +// Coding standard updates +// +// 5 2/16/07 3:47p Robert +// Updated the Flash Part Data Structure to contain the Sector Size +// Parameter. This is just a dummy parameter for Firmware Hub +// +// 4 1/05/07 5:11p Felixp +// Bug fix in ProgramCommand +// +// 3 1/05/07 2:54p Felixp +// Don't program if new data is the same as flash content +// +// 2 12/20/06 10:16a Felixp +// Bug fix in SetLockState. Function updated to work in virtual addressing +// mode +// (after SetVirtualAddress map has been called). +// +// 1 12/18/06 3:39p Robert +// Initial Check in +// +// 2 11/01/06 4:22p Robert +// Updated file for coding standard +// +// 1 10/31/06 2:30p Sivagarn +// Initial Checkin +// +// +//********************************************************************** +// +// +// Name: FlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include +#include +#include +#include "token.h" + + +//---------------------------------------------------------------------- +// define local MACROS + +//Flash Part Specific Tokens +#define VENDOR_ID 0x89 // Intel Manufacturers ID +#define DEVICE_ID0 0xad // 512K Firmware Hub +#define DEVICE_ID1 0xac // 1 Meg Firmware Hub +#define Intel_82802AB 0xad89 // Intel 4Mb Firmware Hub +#define Intel_82802AC 0xac89 // Intel 8Mb Firmware Hub + +#define VENDOR_ID2 0x1f // Atmel Manufacturers ID +#define DEVICE_ID3 0xe1 // AT49LW080 +#define ATMEL_49LW080 0xe11f // ATMEL 8Mb Firmware Hub + +#define VENDOR_ID_ST 0x20 // ST Manufacturers ID +#define DEVICE_ID_ST0 0x2d // M50FW080 +#define DEVICE_ID_ST1 0x2e // M50FW016 - 2MB +#define STM_50FW080 0x2d20 // STM 8Mb Firmware Hub +#define STM_50FW016 0x2e20 // STM 16Mb Firmware Hub + +#define SST_49LF016 0x5cbf // SST 16Mb Firmware Hub + +#define READ_ARRAY_CMD 0xff +#define RD_STATUS_CMD 0x70 +#define CLR_STATUS_CMD 0x50 +#define ERASE_SET_CMD 0x20 +#define ERASE_CNF_CMD 0xd0 +#define PRG_SETUP_CMD 0x40 +#define SECTOR_ERASE_SET_CMD 0x30 // SST 49LF016 only + +#define RD_ID_CODE 0x90 + +// Intel Status Register Bits +#define VPP_LOW 0x08 +#define PROGRAM_FAIL 0x10 +#define ERASE_FAIL 0x20 +#define WSM_BUSY 0x80 + +// Intel Lock Commands +#define UNLOCK 0 +#define WRITE_LOCK 1 + +#define SECTOR_SIZE_4KB 0x1000 // Common 4kBytes sector size +#define SECTOR_SIZE_64KB 0x10000 // Common 64kBytes sector size + +//---------------------------------------------------------------------------- +// Module level global data +extern FLASH_PART *FlashAPI; +extern UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; + +//---------------------------------------------------------------------------- +// Function Prototypes +VOID +IntelFlashEraseCommand ( + volatile UINT8 *pBlockAddress + ); +VOID +IntelFlashReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +VOID +IntelFlashProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +BOOLEAN +IntelFlashIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus + ); +BOOLEAN +IntelFlashIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus + ); +VOID +IntelFlashBlockWriteEnable ( + UINT8* pBlockAddress + ); +VOID +IntelFlashBlockWriteDisable ( + UINT8* pBlockAddress + ); +VOID +IntelFlashDeviceWriteEnable ( + VOID + ); +VOID +IntelFlashDeviceWriteDisable ( + VOID + ); +VOID +IntelFlashVirtualFixup(EFI_RUNTIME_SERVICES *pRS); + + +//======================================================================== +// Local Variable definitions +UINT8 gAtmel = 0; +UINT8 gbEraseSetCmd = ERASE_SET_CMD; +// Flash Part Data structure fo the intel 82802ACC +FLASH_PART mIntelFirmwareHub = + { + IntelFlashReadCommand, + IntelFlashEraseCommand, + IntelFlashProgramCommand, + IntelFlashIsEraseCompleted, + IntelFlashIsProgramCompleted, + IntelFlashBlockWriteEnable, + IntelFlashBlockWriteDisable, + IntelFlashDeviceWriteEnable, + IntelFlashDeviceWriteDisable, + IntelFlashVirtualFixup, + 1, // Number of bytes to program to the + // Flash part in each program command + SECTOR_SIZE_64KB, // Dummy value to hold place - only used in SPI + NULL // Flash Part Number Pointer + }; + + + +//======================================================================== +// Function Definitions +// +//---------------------------------------------------------------------------- +// Procedure: IntelFwhCmdDelay +// +// Description: This function resets the Sst flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +IntelFwhCmdDelay (VOID) +{ + IoWrite8 ( 0xeb, 0x55 ); + IoWrite8 ( 0xeb, 0xaa ); +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFwhResetFlash +// +// Description: This function resets the Sst flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFwhResetFlash ( + IN volatile UINT8* pAddress +) +{ + *pAddress = READ_ARRAY_CMD;// Return to read mode + IntelFwhCmdDelay (); + *pAddress = CLR_STATUS_CMD;// clear status + IntelFwhCmdDelay (); +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFwhOperationCompleted +// +// Description: +// This function verifies whether the command sent to the FWH part +// has completed and returns the status of the command +// +// Input: +// IN volatile UINT8* pAddress Location to check the device status +// +// Output: +// EFI_SUCCESS - +// EFI_TIMEOUT - +// EFI_DEVICE_ERROR - +// +//---------------------------------------------------------------------------- +// +static +EFI_STATUS +IntelFwhOperationCompleted ( + IN volatile UINT8* pAddress +) +{ + UINT8 bFwhStatus; + UINT32 dTimeout = FLASH_RETRIES * 0x10000; + + do { + *pAddress = RD_STATUS_CMD; // read status. + IntelFwhCmdDelay (); + bFwhStatus = *pAddress; + if ( bFwhStatus & WSM_BUSY ) { + if ( bFwhStatus & ( VPP_LOW + PROGRAM_FAIL + ERASE_FAIL ) ) + return EFI_DEVICE_ERROR; + else return EFI_SUCCESS; + } + dTimeout--; + } while ( dTimeout != 0 ); + return EFI_TIMEOUT; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +// +// Returns: None +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + EFI_STATUS Status; + UINT8 bFlashRetry; + UINTN nSectorAddr; + UINT16 wNumSectors, wSectorCount; + + IntelFwhResetFlash( pBlockAddress ); + wNumSectors = ( FlashBlockSize / FlashAPI->FlashSectorSize ); + for ( wSectorCount = 0; wSectorCount < wNumSectors; wSectorCount++ ) { + nSectorAddr = (UINTN)( wSectorCount * FlashAPI->FlashSectorSize ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + *(UINT8*)( (UINTN)pBlockAddress + nSectorAddr ) = gbEraseSetCmd; + IntelFwhCmdDelay (); + *(UINT8*)( (UINTN)pBlockAddress + nSectorAddr ) = ERASE_CNF_CMD; + IntelFwhCmdDelay (); + Status = IntelFwhOperationCompleted ( \ + (UINT8*)((UINTN)pBlockAddress + nSectorAddr) ); + IntelFwhResetFlash( (UINT8*)((UINTN)pBlockAddress + nSectorAddr) ); + if ( Status != EFI_SUCCESS ) continue; + if (*(volatile UINT8*)((UINTN)pBlockAddress + nSectorAddr) != 0xFF) + Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +IntelFlashIsEraseCompleted( + IN volatile UINT8* pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// *Byte - Byte to be written +// *Length - Number of bytes to write +// +// Output: *Length - Number of bytes still left to write +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashProgramCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT8 bFlashRetry; + EFI_STATUS Status; + + if (*pByteAddress != *Byte) { + IntelFwhResetFlash( pByteAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + *pByteAddress = PRG_SETUP_CMD; // Issue program command + IntelFwhCmdDelay (); + *pByteAddress = *Byte; // Program a byte + IntelFwhCmdDelay (); + // Check for completion of the program operation + Status = IntelFwhOperationCompleted( pByteAddress ); + if ( Status != EFI_SUCCESS ) continue; + *pByteAddress = READ_ARRAY_CMD; // read mode + if ( *pByteAddress != *Byte ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + } else Status = EFI_SUCCESS; + *Length = *Length - 1; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// Byte Last data byte written +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +IntelFlashIsProgramCompleted ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashReadCommand ( + IN volatile UINT8* pByteAddress, + IN OUT UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT32 dNumBytes = 0; + + // Changes for SMIFlash module label "4.6.3.6_SMIFLASH_12" or later. + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = *(UINT8*)((UINT32)pByteAddress + dNumBytes ); + *Length = 0; + return ; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SetBlockLock +// +// Description: This function programs a page of data at a time +// +// Input: *pBlockAddress - This is location where the data +// is to be written +// LockState - Value to use to set the Lock register for the +// block defined by pBlockAddress +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +void +SetBlockLock ( + IN volatile UINT8* pBlockAddress, + IN UINT8 LockState +) +{ + // Update the block lock register + ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase))[2] = LockState; + ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase + 0x8000))[2] = LockState; + ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase + 0xA000))[2] = LockState; + ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase + 0xC000))[2] = LockState; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ + SetBlockLock(pBlockAddress, UNLOCK); +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ + SetBlockLock(pBlockAddress, WRITE_LOCK); +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +static +VOID +IntelFlashVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: mIntelIdentify +// +// Description: This function identifies the supported LPC flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +mIntelIdentify ( + IN volatile UINT8* pBlockAddress, + OUT FLASH_PART **Struct +) +{ + UINT8 VID, DID; + + SetBlockLock(pBlockAddress, UNLOCK); + + *pBlockAddress = READ_ARRAY_CMD;// Return to read mode + IntelFwhCmdDelay (); + + *pBlockAddress = RD_ID_CODE;// Set to read ID code mode + IntelFwhCmdDelay (); + VID = *pBlockAddress; + DID = *(pBlockAddress + 1); + + *pBlockAddress = READ_ARRAY_CMD;// Return to read mode + + switch ( (DID << 8) + VID ) { + + case ATMEL_49LW080 : + MemCpy ( pFlashDeviceNumber, "ATMEL 49LW080", 13 ); + gAtmel = 1; + break; + case Intel_82802AB : + case Intel_82802AC : + MemCpy ( pFlashDeviceNumber, "Intel N82802AB/C", 16 ); + break; + case STM_50FW080 : + case STM_50FW016 : + MemCpy ( pFlashDeviceNumber, "ST M25FW080/016", 15 ); + break; + case SST_49LF016 : + gbEraseSetCmd = SECTOR_ERASE_SET_CMD; + mIntelFirmwareHub.FlashSectorSize = SECTOR_SIZE_4KB; + MemCpy ( pFlashDeviceNumber, "SST 49LF016C", 12 ); + break; + default: + return FALSE; + } + mIntelFirmwareHub.FlashPartNumber = pFlashDeviceNumber; + *Struct = &mIntelFirmwareHub; + return TRUE; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Board/Flash/FWH/FwhSstFlashWrite.c b/Board/Flash/FWH/FwhSstFlashWrite.c new file mode 100644 index 0000000..01a31ab --- /dev/null +++ b/Board/Flash/FWH/FwhSstFlashWrite.c @@ -0,0 +1,695 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/FWH/FwhSstFlashWrite.c 13 12/23/09 6:12a Calvinchen $ +// +// $Revision: 13 $ +// +// $Date: 12/23/09 6:12a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/FWH/FwhSstFlashWrite.c $ +// +// 13 12/23/09 6:12a Calvinchen +// Improvement: +// 1.Added FWH/LPC/STD Flash Device Number support. +// 2.Changed for SMIFlash module Label "4.6.3.6_SMIFLASH_12" or later +// +// 12 12/15/09 5:47a Calvinchen +// Modified for adding flash chip name support. +// +// 11 6/24/09 3:12a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 10 6/26/08 6:59a Calvinchen +// Generic bug fixed. +// +// 8 5/09/08 3:33a Calvinchen +// +// 7 12/07/07 1:47p Stacyh +// Updated to differentiate between LPC and FWH SST parts. +// +// 6 11/09/07 4:15p Alexp +// Added dummy FlashRead function. Not supported by this type of flash +// module +// +// 5 5/24/07 12:07p Fasihm +// Updated code to match the code review standards. +// +// 4 3/26/07 7:22p Robert +// Coding standard updates +// +// 3 2/16/07 3:47p Robert +// Updated the Flash Part Data Structure to contain the Sector Size +// Parameter. This is just a dummy parameter for Firmware Hub +// +// 2 12/20/06 10:16a Felixp +// Bug fix in SetLockState. Function updated to work in virtual addressing +// mode +// (after SetVirtualAddress map has been called). +// +// 1 12/18/06 3:39p Robert +// Initial Check in +// +// +//********************************************************************** + +// +// +// Name: FlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include +#include //QUANTA_CHANGES +#include "FlashPart.h" +#include "token.h" + + +//---------------------------------------------------------------------- +// Local MACRO Definitions +#define UNLOCK 0 +#define LOCK 1 + +//---------------------------------------------------------------------------- +// Flash Part Specific Definitions + +#define VENDOR_ID 0xbf // Intel Manufacturers ID +#define DEVICE_ID0 0x60 // 512K Firmware Hub +#define DEVICE_ID1 0x5a // 1 Meg Firmware Hub + +#define READ_ARRAY_CMD 0xff +#define RD_STATUS_CMD 0x70 +#define CLR_STATUS_CMD 0x50 +#define ERASE_SET_CMD 0x20 +#define ERASE_CNF_CMD 0xd0 +#define PRG_SETUP_CMD 0x40 + +// Intel Status Register Bits +#define VPP_LOW 0x08 +#define PROGRAM_FAIL 0x10 +#define ERASE_FAIL 0x20 +#define WSM_BUSY 0x80 + +// Intel Lock Commands +#define UNLOCK 0 +#define WRITE_LOCK 1 + +//---------------------------------------------------------------------------- +// Module level global data +extern UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; + +//---------------------------------------------------------------------------- +// Function Prototypes +VOID +SstFlashEraseCommand ( + volatile UINT8 *pBlockAddress +); +VOID +SstFlashReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length +); +VOID +SstFlashProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length +); +BOOLEAN +SstFlashIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus +); +BOOLEAN +SstFlashIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus +); +VOID +SstFlashBlockWriteEnable ( + UINT8* pBlockAddress +); +VOID +SstFlashBlockWriteDisable ( + UINT8* pBlockAddress +); +VOID +SstFlashDeviceWriteEnable ( + VOID +); +VOID +SstFlashDeviceWriteDisable ( + VOID +); +VOID +SstFlashVirtualFixup ( + EFI_RUNTIME_SERVICES *pRS +); + + + +//---------------------------------------------------------------------------- +// Module specific variables +FLASH_PART mSstFirmwareHub = + { + SstFlashReadCommand, + SstFlashEraseCommand, + SstFlashProgramCommand, + SstFlashIsEraseCompleted, + SstFlashIsProgramCompleted, + SstFlashBlockWriteEnable, + SstFlashBlockWriteDisable, + SstFlashDeviceWriteEnable, + SstFlashDeviceWriteDisable, + SstFlashVirtualFixup, // SST flash device virtual address + // fix up routine + 1, // Number of bytes to program to the + // Flash part in each program command + 0, // Dummy value to hold place - only used in SPI + NULL // Flash Part Number Pointer + }; + +//---------------------------------------------------------------------------- +// Function definitions + +// +//---------------------------------------------------------------------------- +// Procedure: SstFwhResetFlash +// +// Description: This function resets the SST flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstFwhResetFlash ( + IN volatile UINT8* pAddress +) +{ + pAddress[0x5555] = 0xaa; + pAddress[0x2aaa] = 0x55; + pAddress[0x5555] = 0xf0; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstFlashReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstFlashReadCommand ( + IN volatile UINT8* pByteAddress, + IN OUT UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT32 dNumBytes = 0; + + // Changes for SMIFlash module label "4.6.3.6_SMIFLASH_12" or later. + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = *(UINT8*)((UINT32)pByteAddress + dNumBytes ); + *Length = 0; + return ; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: SstFwhWaitForOperationCompleted +// +// Description: +// This function verifies whether the command sent to the FWH part +// has completed and returns the status of the command +// +// Input: +// IN volatile UINT8* pAddress Location to check the device status +// +// Output: +// EFI_SUCCESS - +// EFI_TIMEOUT - +// EFI_DEVICE_ERROR - +// +//---------------------------------------------------------------------------- +// +static +EFI_STATUS +SstFwhWaitForOperationCompleted ( + IN volatile UINT8* pAddress +) +{ + UINT8 bData1, bData2; + UINT32 dTimeout = FLASH_RETRIES * 0x10000; + EFI_STATUS Status = EFI_TIMEOUT; + + do { + bData1 = (*pAddress) & 0x40; + bData2 = (*pAddress) & 0x40; + if ( bData1 == bData2 ) return EFI_SUCCESS; + dTimeout--; + } while ( dTimeout != 0 ); // Check for Bit 6 Toggle + + return EFI_TIMEOUT; +} +// +//---------------------------------------------------------------------------- +// Procedure: SstFlashEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +// +// Returns: None +//---------------------------------------------------------------------------- +// +static +VOID +SstFlashEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + EFI_STATUS Status; + UINT8 bFlashRetry; + + SstFwhResetFlash ( pBlockAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + pBlockAddress[0x5555] = 0xaa; + pBlockAddress[0x2aaa] = 0x55; + pBlockAddress[0x5555] = 0x80; + pBlockAddress[0x5555] = 0xaa; + pBlockAddress[0x2aaa] = 0x55; + *pBlockAddress=0x50; + Status = SstFwhWaitForOperationCompleted ( pBlockAddress ); + SstFwhResetFlash ( pBlockAddress ); + if ( Status != EFI_SUCCESS ) continue; + if ( *pBlockAddress != 0xFF ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } +//- return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SSTFlashIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +SstFlashIsEraseCompleted ( + IN volatile UINT8 *pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: SSTFlashProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress - Location where the data to be written +// *Byte - Byte to be written +// *Length - Number of bytes to write +// +// Output: *Length - Number of bytes still left to write +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstFlashProgramCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + volatile UINT8* pBlockAddress = (volatile UINT8*)BLOCK(pByteAddress); + UINT8 bFlashRetry; + EFI_STATUS Status; + + if ( *Byte != *pByteAddress ) { + SstFwhResetFlash ( pBlockAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + // Program Command Sequence + pBlockAddress[0x5555] = 0xaa; + pBlockAddress[0x2aaa] = 0x55; + pBlockAddress[0x5555] = 0xa0; + *pByteAddress = *Byte; + Status = SstFwhWaitForOperationCompleted ( pByteAddress ); + SstFwhResetFlash ( pBlockAddress ); + if ( Status != EFI_SUCCESS ) continue; + if ( *pByteAddress != *Byte ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + } else Status = EFI_SUCCESS; + *Length = *Length - 1; +//- return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstFlashIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// *Byte Pointer to data written +// Length Amount of data to check +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +SstFlashIsProgramCompleted ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: SetBlockLock +// +// Description: This function programs a page of data at a time +// +// Input: volatile UINT8* pBlockAddress - This is location where the data +// is to be written +// UINT8 LockState - Value to use to set the Lock register for the +// block defined by pBlockAddress +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +void +SetBlockLock ( + IN volatile UINT8* pBlockAddress, + IN UINT8 LockState +) +{ + // Update the block lock register + ((UINT8*)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase))[2] = LockState; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SSTFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstFlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ + SetBlockLock(pBlockAddress, UNLOCK); +} + +// +//---------------------------------------------------------------------------- +// Procedure: SSTFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstFlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ + SetBlockLock(pBlockAddress, WRITE_LOCK); +} + +// +//---------------------------------------------------------------------------- +// Procedure: SSTFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstFlashDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +// +//---------------------------------------------------------------------------- +// Procedure: SSTFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstFlashDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + +// +//---------------------------------------------------------------------------- +// Procedure: SSTFlashVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +static +VOID +SstFlashVirtualFixup( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: mSstFwhIdentify +// +// Description: This function identifies the supported SST flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +mSstFwhIdentify ( + IN volatile UINT8* pBlockAddress, + OUT FLASH_PART **Struct +) +{ + UINT8 VID; + UINT8 DID; + + SstFwhResetFlash( pBlockAddress ); + + pBlockAddress[0x5555] = 0xaa; + pBlockAddress[0x2aaa] = 0x55; + pBlockAddress[0x5555] = 0x90; + + VID = *pBlockAddress; + DID = *(pBlockAddress + 1); + + SstFwhResetFlash( pBlockAddress ); + + // check for valid ID + if ((VID == VENDOR_ID) && ((DID == DEVICE_ID0) || (DID == DEVICE_ID1))) + { + MemCpy ( pFlashDeviceNumber, "SST 49LF004/008", 15 ); + mSstFirmwareHub.FlashPartNumber = pFlashDeviceNumber; + *Struct = &mSstFirmwareHub; + return TRUE; + } + else + return FALSE; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Board/Flash/Flash.chm b/Board/Flash/Flash.chm new file mode 100644 index 0000000..3685392 Binary files /dev/null and b/Board/Flash/Flash.chm differ diff --git a/Board/Flash/Flash.cif b/Board/Flash/Flash.cif new file mode 100644 index 0000000..34a7a94 --- /dev/null +++ b/Board/Flash/Flash.cif @@ -0,0 +1,18 @@ + + name = "Flash - Source" + category = FLASH + LocalRoot = "Board\Flash\" + RefName = "FLASH_COMBINED_SOURCE" +[files] +"Flash.sdl" +"Flash.mak" +"FlashWrite.c" +"FlashUpdate.c" +"Flash.chm" +[parts] +"FWH_INTERFACE_SOURCE" +"LPC_INTERFACE_SOURCE" +"STD_INTERFACE_SOURCE" +"SPI_INTERFACE_SOURCE" +"FLASH_INCLUDES" + diff --git a/Board/Flash/Flash.mak b/Board/Flash/Flash.mak new file mode 100644 index 0000000..d3f8d4a --- /dev/null +++ b/Board/Flash/Flash.mak @@ -0,0 +1,118 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Flash_Combined_2/Core/Flash.mak 6 7/21/11 5:09a Calvinchen $ +# +# $Revision: 6 $ +# +# $Date: 7/21/11 5:09a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Flash_Combined_2/Core/Flash.mak $ +# +# 6 7/21/11 5:09a Calvinchen +# [TAG] EIP60956 +# [Category] Improvement +# [Description] Added "OemFlashValidTableList" eLink for OEM/ODM +# invalidates the flash part supports those they don't needed. +# [Files] Flash.sdl +# Flash.mak +# FlashWrite.c +# Flash.chm +# +# 5 10/25/10 5:56a Calvinchen +# Added support for PEI Flash Library. +# +# 4 1/14/09 10:43p Calvinchen +# Added support for OemflashWriteEnable/Disable eLink. +# +# 3 8/26/08 2:53a Calvinchen +# Fixed Building failed if $(CFLAGS) = /W4. +# +# 1 12/18/06 3:39p Robert +# Initial Check in +# +# 1 10/31/06 2:30p Sivagarn +# Initial Checkin +# +# +#********************************************************************** + +# +# +# Name: Flash.mak +# +# Description: +# +# +#********************************************************************** +all : Flash + +!IF "$(x64_BUILD)"=="1" && "$(BUILD_PEI_FLASH_LIB)"=="1" +Flash : $(BUILD_DIR)\Flash.mak FlashBin FlashPeiBin +!ELSE +Flash : $(BUILD_DIR)\Flash.mak FlashBin +!ENDIF +#--------------------------------------------------------------------------- +# Generic FLASH dependencies +#--------------------------------------------------------------------------- +$(BUILD_DIR)\Flash.mak : $(Flash_DIR)\$(@B).cif $(Flash_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(Flash_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +#--------------------------------------------------------------------------- +# Generic FLASH eList +#--------------------------------------------------------------------------- +FLASH_E_LISTS = \ +/D\"FLASH_LIST=$(FlashList)\"\ +/D\"OEM_FLASH_WRITE_ENABLE_LIST=$(OemFlashWriteEnableList)\"\ +/D\"OEM_FLASH_WRITE_DISABLE_LIST=$(OemFlashWriteDisableList)\"\ +/D\"OEM_FLASH_VALID_TABLE_LIST=$(OemFlashValidTableList)\" + +#--------------------------------------------------------------------------- +# Create Flash Library +#--------------------------------------------------------------------------- +FlashBin : $(AMIDXELIB) $(AMICSPLib) $(FLASHLISTLIB) + @set INCLUDE=%%INCLUDE%% + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\Flash.mak all LIBRARIES= \ + TYPE=LIBRARY NAME=Flash LIBRARY_NAME=$(FLASHLIB)\ + "CFLAGS=$(CFLAGS:/W4=/W3) $(FLASH_E_LISTS) /D_DXE_FLASH_LIB_" + +!IF "$(x64_BUILD)"=="1" && "$(BUILD_PEI_FLASH_LIB)"=="1" +FlashPeiBin: $(AMICSPLib) $(FLASHLISTLIB) + $(MAKE) /$(MAKEFLAGS) BUILD_ROOT=$(BUILD_DIR)\ + "EXT_OBJS=$(**:Build\=Build\IA32\)" PROJECT_DIR=$(PROJECT_DIR)\ + /f $(BUILD_DIR)\Flash.mak all\ + BUILD_DIR=$(BUILD_DIR)\IA32\ + TYPE=PEI_LIBRARY NAME=Flash\ + "CFLAGS=$(CFLAGS:/W4=/W3) $(FLASH_E_LISTS)" +!ENDIF + +$(FLASHLIB) : Flash + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Board/Flash/Flash.sdl b/Board/Flash/Flash.sdl new file mode 100644 index 0000000..9f95aaa --- /dev/null +++ b/Board/Flash/Flash.sdl @@ -0,0 +1,212 @@ +#**************************************************************************** +#**************************************************************************** +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30071 ** +#** ** +#** Phone (770)-246-8600 ** +#** ** +#**************************************************************************** +#**************************************************************************** + +#**************************************************************************** +# $Header: /Alaska/SOURCE/Flash_Combined_2/Core/Flash.sdl 9 7/21/11 5:09a Calvinchen $ +# +# $Revision: 9 $ +# +# $Date: 7/21/11 5:09a $ +# +#**************************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Flash_Combined_2/Core/Flash.sdl $ +# +# 9 7/21/11 5:09a Calvinchen +# [TAG] EIP60956 +# [Category] Improvement +# [Description] Added "OemFlashValidTableList" eLink for OEM/ODM +# invalidates the flash part supports those they don't needed. +# [Files] Flash.sdl +# Flash.mak +# FlashWrite.c +# Flash.chm +# +# 8 10/25/10 5:56a Calvinchen +# Added support for PEI Flash Library. +# +# 7 8/06/10 12:03a Calvinchen +# Added the "DIRECT_FLASH_MEMORY_ACCESS" Token. (Default setting is "ON", +# "OFF" for specific EC SPIs.) +# +# 6 12/15/09 5:46a Calvinchen +# Improvement : Added Flash Chip Name support. +# +# 5 6/24/09 3:11a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# +#**************************************************************************** +TOKEN + Name = "Flash_SUPPORT" + Value = "1" + Help = "Main switch to enable FLASH support in Project." + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "FLASH_BLOCK_SIZE" + Value = "0x10000" + Help = "Size of the Flash Device Block" + TokenType = Integer + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "FLASH_ERASE_POLARITY" + Value = "1" + Help = "Flash Device Erase Polarity" + TokenType = Integer + TargetMAK = Yes + TargetH = Yes + Range = "0 or 1" +End + +TOKEN + Name = "FLASH_RETRIES" + Value = "3" + Help = "Number of retries attempted for the failed flash update operation" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "FLASH_ERASE_TIMEOUT" + Value = "50000000" + Help = "The number of 100ns units until the timeout for the flash erase operation expires." + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "FLASH_PROGRAM_TIMEOUT" + Value = "50000000" + Help = "The number of 100ns units until the timeout for the flash programming operation expires." + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "NUMBER_OF_BYTES_PER_PAGE" + Value = "64" + Help = "Number of bytes per Page" + TokenType = Integer + TargetEQU = Yes + TargetH = Yes +End + +TOKEN + Name = "FLASH_PART_STRING_LENGTH" + Value = "48" + Help = "Number of bytes per Page" + TokenType = Integer + TargetH = Yes + Lock = Yes +End + +TOKEN + Name = "DIRECT_FLASH_MEMORY_ACCESS" + Value = "1" + Help = "Direct flash memory access support while flashing." + TokenType = Boolean + TargetH = Yes + Lock = Yes +End + +TOKEN + Name = "BUILD_PEI_FLASH_LIB" + Value = "0" + Help = "Switch to build the FLASH LIB for PEI Phase." + TokenType = Boolean + TargetMAK = Yes +End + +TOKEN + Name = "FLASHLIB" + Value = "$(BUILD_DIR)\Flash.lib" + TokenType = Expression + TargetMAK = Yes +End + +TOKEN + Name = "FLASHPEILIB" + Value = "$(BUILD_DIR)\IA32\Flash.lib" + TokenType = Expression + TargetMAK = Yes + Token = "x64_BUILD" "=" "1" + Token = "BUILD_PEI_FLASH_LIB" "=" "1" +End + +TOKEN + Name = "FLASHPEILIB" + Value = "$(FLASHLIB)" + TokenType = Expression + TargetMAK = Yes + Token = "x64_BUILD" "=" "0" + Token = "BUILD_PEI_FLASH_LIB" "=" "1" +End + +PATH + Name = "Flash_DIR" +End + +MODULE + Help = "Includes Flash.mak to Project" + File = "Flash.mak" +End + +ELINK + Name = "FlashList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "OemFlashWriteEnableList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "OemFlashWriteDisableList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "OemFlashValidTableList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "FLASHLISTLIB" + InvokeOrder = ReplaceParent +End + +#**************************************************************************** +#**************************************************************************** +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30071 ** +#** ** +#** Phone (770)-246-8600 ** +#** ** +#**************************************************************************** +#**************************************************************************** \ No newline at end of file diff --git a/Board/Flash/FlashUpdate.c b/Board/Flash/FlashUpdate.c new file mode 100644 index 0000000..0c6bec6 --- /dev/null +++ b/Board/Flash/FlashUpdate.c @@ -0,0 +1,367 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/FlashUpdate.c 11 8/06/10 12:03a Calvinchen $ +// +// $Revision: 11 $ +// +// $Date: 8/06/10 12:03a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/FlashUpdate.c $ +// +// 11 8/06/10 12:03a Calvinchen +// Added the "DIRECT_FLASH_MEMORY_ACCESS" Token. (Default setting is "ON", +// "OFF" for specific EC SPIs.) +// +// 10 6/24/09 3:11a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 8 1/07/08 2:36p Robert +// Updates for coding standrad +// +// 7 11/09/07 3:52p Alexp +// Added FlashRead common function +// +// 6 3/26/07 7:21p Robert +// Coding standard updates +// +// +//********************************************************************** +// +// +// Name: FlashUpdate.c +// +// Description: Provides the rom flashing functions to the system +// +// +//********************************************************************** + +// header includes +#include +#include +#include + +//---------------------------------------------------------------------- +// external variable defines +extern const UINTN FlashEmpty; + +//---------------------------------------------------------------------- +// global variable for the module +#define INT_SIZE sizeof(INTN) +#define FLASH_EMPTY_BYTE (UINT8)FlashEmpty + +//---------------------------------------------------------------------- +// Function prototypes +VOID +FlashEraseCommand ( + volatile UINT8* pBlockAddress + ); +VOID +FlashProgramCommand ( + volatile UINT8* pByteAddress, + UINT8 *Byte, UINT32 Length + ); +VOID +FlashReadCommand ( + volatile UINT8* pByteAddress, + UINT8 *Byte, UINT32 Length + ); +BOOLEAN +FlashIsEraseCompleted ( + volatile UINT8* pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus + ); +BOOLEAN +FlashIsProgramCompleted ( + volatile UINT8* pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus + ); + + +//---------------------------------------------------------------------- +// Function definitions + +// +//---------------------------------------------------------------------------- +// Procedure: IsCleanOrEqual +// +// Description: Verifies if the device has been erased properly or if the +// current byte is the same as the byte to be written at this location +// +// +// Input: UINT8 *pDest - starting address of where the data will be written +// const UINT8 *pSource - starting address of the data that +// is supposed to be written +// UINTN Size - length of the data set to check +// BOOLEAN *pIsClean - return value to indicate that the data area +// that will be written to has already been erased +// BOOLEAN *pIsEqual - return value to indicate that the data to be +// written is the same as the data that is already there +// +// Output: see info on pIsClean and pIsEqual above +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +IsCleanOrEqual ( + IN UINT8 *pDest, + IN const UINT8 *pSource, + IN UINTN Size, + OUT BOOLEAN *pIsClean, + OUT BOOLEAN *pIsEqual +) +{ + *pIsEqual = TRUE; + *pIsClean = TRUE; + +#if DIRECT_FLASH_MEMORY_ACCESS + // loops through the destination looking to see if the data is the same + // as the source, or if the Destination has already bee erased + if (!( (UINTN)pDest & (INT_SIZE-1) || (UINTN)pSource & (INT_SIZE-1) )) + { + UINTN *Dest = (UINTN*)pDest, *Source = (UINTN*)pSource; + + for( ; Size >= INT_SIZE; Size -= INT_SIZE) + { + if (*Dest != FlashEmpty) + *pIsClean = FALSE; + if (*Dest++ != *Source++) + *pIsEqual = FALSE; + if ( !(*pIsEqual || *pIsClean) ) + return; + } + } + + // since the address may not be INT_SIZE aligned, this checks + // the rest of the data + for( ; Size > 0; Size--) + { + if (*pDest != FLASH_EMPTY_BYTE) + *pIsClean = FALSE; + if (*pDest++ != *pSource++) + *pIsEqual = FALSE; + if ( !(*pIsEqual || *pIsClean) ) + return; + } +#else + { + UINT8 bData = 0; + for( ; Size > 0; Size--) { + FlashReadCommand(pDest, &bData, sizeof(UINT8)); + if (bData != FLASH_EMPTY_BYTE) *pIsClean = FALSE; + if (bData != *pSource++) *pIsEqual = FALSE; + if (!(*pIsEqual || *pIsClean)) return; + } + } +#endif +} +// +//---------------------------------------------------------------------------- +// Procedure: FlashEraseBlock +// +// Description: Erases the block pointed to by BlockAddress +// +// Input: *BlockAddress - Address within the block to be erased +// +// Output: TRUE - Erase completed successfully +// FALSE - Erase did not complete properly +//---------------------------------------------------------------------------- +// +BOOLEAN +FlashEraseBlock ( + IN volatile UINT8* BlockAddress +) +{ + BOOLEAN Error = FALSE; + BOOLEAN Completed = TRUE; + + FlashEraseCommand(BlockAddress); + + while(!(Completed = FlashIsEraseCompleted(BlockAddress, &Error, NULL))); + + return Completed && !Error; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: FlashProgram +// +// Description: Programs the area pointed to by BlockAddress and defined +// by Length with the data pointed to by Data +// +// Input: *Address - Address where to write the Data +// *Data - pointer to the data to write +// Length - length of the data to write +// +// Output: None +// +// Return: TRUE - Program completed successfully +// FALSE - Program did not complete properly +// +//---------------------------------------------------------------------------- +// +BOOLEAN +FlashProgram ( + IN volatile UINT8* Address, + IN UINT8 *Data, + IN UINT32 Length +) +{ + BOOLEAN Error=FALSE; + BOOLEAN Completed=TRUE; + + FlashProgramCommand(Address,Data,Length); + + while(!(Completed = \ + FlashIsProgramCompleted(Address, Data, Length, &Error,NULL))); + + if (Error) return FALSE; + + return Completed && !Error; +} + +// +//---------------------------------------------------------------------------- +// Procedure: FlashRead +// +// Description: This function returns the read data from the location +// indicated +// +// Input: *Address - Address where to write the Data +// *Data - pointer to the data to write +// Length - length of the data to write +// +// Output: None +// +// Return: TRUE - Program completed successfully +// FALSE - Program did not complete properly +// +//---------------------------------------------------------------------------- +// +BOOLEAN +FlashRead ( + IN volatile UINT8* Address, + OUT UINT8 *Data, + IN UINT32 Length +) +{ + FlashReadCommand(Address,Data,Length); + + return TRUE; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: FlashProgramBlock +// +// Description: Programs the Block pointed to by pBlock with the data +// pointed to by pData +// +// Input: *pBlock - Address of the beginning of the block +// *Data - pointer to the data to write +// +// Output: None +// +// Return: TRUE - Program completed successfully +// FALSE - Program did not complete properly +//---------------------------------------------------------------------------- +// +BOOLEAN +FlashProgramBlock ( + IN UINT8* pBlock, + IN UINT8* pData +) +{ + return FlashProgram(pBlock,pData,FlashBlockSize); +} + + +// +//---------------------------------------------------------------------------- +// Procedure: FlashWriteBlock +// +// Description: Enables the ability to write to the flash part and +// programs the Block pointed to by pBlock with the data +// pointed to by Data and then sets the block to read only +// +// Input: *pBlock - Address of the beginning of the block +// *Data - pointer to the data to write +// +// Output: None +// +// Return: TRUE - Program completed successfully +// FALSE - Program did not complete properly +//---------------------------------------------------------------------------- +// +BOOLEAN +FlashWriteBlock ( + IN UINT8* pBlock, + IN UINT8* pData +) +{ + BOOLEAN IsClean; + BOOLEAN IsEqual; + BOOLEAN Result; + // This checks to see if the data in the flash part has already been + // erased or if it is already the same as what will be programmed there + IsCleanOrEqual(pBlock, pData, FlashBlockSize, &IsClean, &IsEqual); + + // If it is already the same then exit + if (IsEqual) + return TRUE; + + // if not the same enable the block for writing + FlashBlockWriteEnable(pBlock); + + // This loop checks IsClean to see if the block area that is to be written to + // has already been erased. If it hasn't then, the FlashEraseBlock() is called + // to erase the block. + // If it is either clean or is erased, then it calls the program function + if (IsClean || FlashEraseBlock(pBlock)) + Result = FlashProgramBlock(pBlock,pData); + // If it is not clean and the erase block function does not finish properly + // then set result to return false + else + Result = FALSE; + + // disable the ability to write to the block + FlashBlockWriteDisable(pBlock); + + return Result; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* \ No newline at end of file diff --git a/Board/Flash/FlashWrite.c b/Board/Flash/FlashWrite.c new file mode 100644 index 0000000..b77f971 --- /dev/null +++ b/Board/Flash/FlashWrite.c @@ -0,0 +1,697 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/FlashWrite.c 23 3/29/12 6:02a Klzhan $ +// +// $Revision: 23 $ +// +// $Date: 3/29/12 6:02a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/FlashWrite.c $ +// +// 23 3/29/12 6:02a Klzhan +// [TAG] EIP86044 +// [Category] Improvement +// [Description] customized AFUWIN to support a parameter to display the +// current SPI part's name and Size +// +// 22 7/21/11 5:09a Calvinchen +// [TAG] EIP60956 +// [Category] Improvement +// [Description] Added "OemFlashValidTableList" eLink for OEM/ODM +// invalidates the flash part supports those they don't needed. +// [Files] Flash.sdl +// Flash.mak +// FlashWrite.c +// Flash.chm +// +// 21 10/25/10 5:56a Calvinchen +// Added support for PEI Flash Library. +// +// 20 8/06/10 12:04a Calvinchen +// Changed the priority for oem hook "OemFlashDeviceWriteEnable" in +// FlashDeviceWriteEnable procedure. +// +// 19 3/11/10 6:44a Calvinchen +// Improvement : +// 1.With Core 4.6.3.7 or later, the FlashVirtualFixup function gets +// called from Nvramdxe.c and flash.c, do anything when the function is +// called second time. +// 2.Added SST AAIWordProgram SPI command to speed up the programming +// time. +// +// 18 12/23/09 6:13a Calvinchen +// Improvement: +// 1.Added FWH/LPC/STD Flash Device Number support. +// 2.Changed for SMIFlash module Label "4.6.3.6_SMIFLASH_12" or later +// +// 17 12/15/09 5:46a Calvinchen +// Improvement : Added Flash Chip Name support. +// +// 16 6/24/09 3:11a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 14 6/26/08 6:58a Calvinchen +// Added convert FlashBlockSize for virtual mode. +// +// 12 1/07/08 2:32p Robert +// updated to doing standard +// +// 11 11/09/07 3:52p Alexp +// New CommonFlashRead function. +// +// 10 4/09/07 11:36a Robert +// +// 9 3/26/07 7:21p Robert +// Coding standard updates +// +// 7 3/12/07 4:33p Robert +// Added porting hooks in the FlashDeviceWriteEnable() and +// FlashDeviceWriteDisable() functions +// +//********************************************************************** +// +// +// Name: FlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include +#include +#include +#include +#if defined _DXE_FLASH_LIB_ +#include +#endif +//---------------------------------------------------------------------- +// component MACROs + + +//---------------------------------------------------------------------- +// Module defined global variables +FLASH_PART *FlashAPI = NULL; + +// flash part list creation code must be in this order +typedef BOOLEAN (IDENTIFY)( + volatile UINT8* pBlockAddress, + FLASH_PART **Struct + ); + +extern IDENTIFY FLASH_LIST EndOfInitList; + +IDENTIFY* FlashList[] = {FLASH_LIST NULL}; + +// oem flash write enable/disable list creation code must be in this order +typedef VOID (OEM_FLASH_WRITE) (VOID); +extern OEM_FLASH_WRITE OEM_FLASH_WRITE_ENABLE_LIST EndOfOemFlashList; +extern OEM_FLASH_WRITE OEM_FLASH_WRITE_DISABLE_LIST EndOfOemFlashList; +OEM_FLASH_WRITE* OemFlashWriteEnable[] = {OEM_FLASH_WRITE_ENABLE_LIST NULL}; +OEM_FLASH_WRITE* OemFlashWriteDisable[] = {OEM_FLASH_WRITE_DISABLE_LIST NULL}; +UINT16 OemFlashValidTable[] = {OEM_FLASH_VALID_TABLE_LIST NULL}; +// END flash part list creation code +//---------------------------------------------------------------------- +// Module specific global variable +UINT16 gFlashId = 0; +UINT8 gbDeviceWriteState = FALSE; +UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; + +//---------------------------------------------------------------------- +// externally defined variables +extern VOID ChipsetFlashDeviceWriteEnable(); +extern VOID ChipsetFlashDeviceWriteDisable(); + +//---------------------------------------------------------------------- +// Function definitions +VOID OemFlashDeviceWriteEnable ( VOID ); +VOID OemFlashDeviceWriteDisable ( VOID ); + +// +//---------------------------------------------------------------------------- +// Procedure: OemIsFlashValid +// +// Description: This function identifies the supported SPI flash parts and +// returns TRUE. If flash part is not supported by this +// module it will return FALSE. +// +// Input: dFlashId Present Flash Part ID +// +// Output: None +// +// Return: TRUE Flash part is Valid. +// FALSE Flash part is not Valid. +//---------------------------------------------------------------------------- +// +BOOLEAN +OemIsFlashValid(VOID) +{ + UINTN i = 0; + if (OemFlashValidTable[0] == NULL) return TRUE; + for (i = 0; OemFlashValidTable[i] != NULL; i++) { + if (gFlashId == OemFlashValidTable[i]) return TRUE; + } + return FALSE; +} +// +//---------------------------------------------------------------------- +// Procedure: FlashInit +// +// Description: This function goes through the elinked list of identify +// functions giving control until one part is identified properly +// +// Input: *pBlockAddress - Address to access the flash part +// +// Output: None +// +// Returns: EFI_SUCCESS +// +//---------------------------------------------------------------------- +// +EFI_STATUS +FlashInit ( + IN volatile UINT8* pBlockAddress +) +{ + UINTN i; + BOOLEAN found = FALSE; + + for(i=0; !found && FlashList[i]; i++) + { + found=FlashList[i](pBlockAddress, &FlashAPI); + } + if (found && !OemIsFlashValid()) FlashAPI = NULL; + return EFI_SUCCESS; +} + + +// +//---------------------------------------------------------------------- +// Procedure: FlashEraseCommand +// +// Description: This function Chooses the correct flash part to call and then +// initiates flash block erase command +// +// Input: *pBlockAddress - Address to access flash part +// +// Output: None +// +// Returns: None +// +//---------------------------------------------------------------------- +// +VOID +FlashEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + if ( FlashAPI == NULL) + FlashInit(pBlockAddress); + + // if FlashAPI is still NULL return + if ( FlashAPI == NULL) + return; + + FlashAPI->FlashEraseCommand(pBlockAddress); + +} + + +// +//---------------------------------------------------------------------- +// Procedure: FlashIsEraseCompleted +// +// Description: This function chooses the correct flash part to call and +// then checks current status of the last erase operation +// +// Input: *pBlockAddress - Address to access flash part +// *pError - Boolean that tells if fatal error occured +// *pStatus - Status of the erase command +// +// Output: *pError - Boolean that tells if fatal error occured +// *pStatus - Status of the erase command +// +// Returns: TRUE - erase complete +// FALSE - erase not completed +// +//---------------------------------------------------------------------- +// +BOOLEAN +FlashIsEraseCompleted ( + IN volatile UINT8 *pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus) +{ + BOOLEAN Temp; + + if ( FlashAPI == NULL) + FlashInit(pBlockAddress); + + Temp = FlashAPI->FlashIsEraseCompleted(pBlockAddress, pError, pStatus); + + return Temp; +} + + +// +//---------------------------------------------------------------------- +// Procedure: FlashProgramCommand +// +// Description: This function chooses the correct flash part to call and +// then initiates the program command +// +// Input: *pBlockAddress - Address to access flash part +// *Byte - pointer to data to write to the flash part +// Length - The total amount of data that Byte points to +// +// Output: None +// +// Return: None +//---------------------------------------------------------------------- +// +VOID +FlashProgramCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length +) +{ + volatile UINT8 *a=(volatile UINT8 *) pByteAddress; + UINT32 TempLength = Length; + UINT8 *DataPtr = Byte; + + if ( FlashAPI == NULL) + FlashInit((volatile UINT8*)BLOCK(pByteAddress)); + + // if FlashAPI is still NULL return + if ( FlashAPI == NULL) + return; + + do { + FlashAPI->FlashProgramCommand(a, DataPtr, &TempLength); + a += (Length - TempLength); + DataPtr += (Length - TempLength); + Length = TempLength; + } while (TempLength != 0); +} + +// +//---------------------------------------------------------------------- +// Procedure: FlashReadCommand +// +// Description: This function chooses the correct flash part to call and +// then initiates the program command +// +// Input: *pBlockAddress - Address to access flash part +// *Byte - pointer to data to write to the flash part +// Length - The total amount of data that Byte points to +// +// Output: None +// +// Return: None +//---------------------------------------------------------------------- +// +VOID +FlashReadCommand ( + IN volatile UINT8* pByteAddress, + OUT UINT8 *Byte, + IN UINT32 Length +) +{ + volatile UINT8 *a=(volatile UINT8 *) pByteAddress; + UINT32 TempLength = Length; + UINT8 *DataPtr = Byte; + + if ( FlashAPI == NULL) + FlashInit((volatile UINT8*)BLOCK(pByteAddress)); + + // if FlashAPI is still NULL return + if ( FlashAPI == NULL) + return; + + do { + FlashAPI->FlashReadCommand(a, DataPtr, &TempLength); + a += (Length - TempLength); + DataPtr += (Length - TempLength); + Length = TempLength; + } while (TempLength != 0); +} + +// +//---------------------------------------------------------------------- +// Procedure: FlashIsProgramCompleted +// +// Description: This function chooses the correct flash part to call +// and then checks current status of the last program operation +// +// Input: *pBlockAddress - Address to access flash part +// *Byte - values previously written to the Flash Device +// Length - The amount of data that needs to be checked +// *pError - Boolean that tells if fatal error occured +// *pStatus - Status of the erase command +// +// Output: *pError - Boolean that tells if fatal error occured +// *pStatus - Status of the erase command +// +// Return: TRUE - Program completed, check pError for fatal error +// FALSE - programming in progress +// +//---------------------------------------------------------------------- +// +BOOLEAN +FlashIsProgramCompleted ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ +//FlashProgramCommand implementation already checks the status +//So this function is no longer needed +//Just return success + if (pError) *pError = FALSE; + return TRUE; +} + + +// +//---------------------------------------------------------------------- +// Procedure: FlashBlockWriteEnable +// +// Description: This function chooses the correct flash part to call and +// then enables write operations(erase/programming) for a specific block +// +// Input: *pBlockAddress - Address to access flash part +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------- +// +VOID +FlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ + if ( FlashAPI == NULL) + FlashInit(pBlockAddress); + + // if FlashAPI is still NULL return + if ( FlashAPI == NULL) + return; + + FlashAPI->FlashBlockWriteEnable(pBlockAddress); +} + + +// +//---------------------------------------------------------------------- +// Procedure: FlashBlockWriteDisable +// +// Description: This function chooses the correct flash part to call and +// then disables write operations(erase/programming) for a specific +// block +// +// Input: *pBlockAddress - Address to access flash part +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------- +// +VOID +FlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ + if ( FlashAPI == NULL) + FlashInit(pBlockAddress); + + // if FlashAPI is still NULL return + if ( FlashAPI == NULL) + return; + + FlashAPI->FlashBlockWriteDisable(pBlockAddress); + +} + + +// +//---------------------------------------------------------------------- +// Procedure: FlashDeviceWriteEnable +// +// Description: This function chooses the correct flash part to call and +// then enables write operation for a flash device +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------- +// +VOID +FlashDeviceWriteEnable (VOID) +{ + OemFlashDeviceWriteEnable (); + + ChipsetFlashDeviceWriteEnable(); + + if ( FlashAPI == NULL) + FlashInit((UINT8 *)FlashDeviceBase); + + // if FlashAPI is still NULL return + if ( FlashAPI == NULL) + return; + + FlashAPI->FlashDeviceWriteEnable(); + +} + +// +//---------------------------------------------------------------------- +// Procedure: FlashDeviceWriteDisable +// +// Description: This function chooses the correct flash part to call and +// then disables write operation for a flash device +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------- +// +VOID +FlashDeviceWriteDisable (VOID) +{ + ChipsetFlashDeviceWriteDisable(); + + if ( FlashAPI == NULL) + FlashInit((UINT8 *)FlashDeviceBase); + + // if FlashAPI is still NULL return + if ( FlashAPI == NULL) + return; + + FlashAPI->FlashDeviceWriteDisable(); + + OemFlashDeviceWriteDisable (); +} +// +//---------------------------------------------------------------------- +// Procedure: OemFlashDeviceWriteEnable +// +// Description: This function goes through the elinked list of oem flash +// write enable functions giving control. +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------- +// +VOID +OemFlashDeviceWriteEnable (VOID) +{ + UINT8 i; + + if ( gbDeviceWriteState != TRUE ) { + gbDeviceWriteState = TRUE; + for(i = 0; OemFlashWriteEnable[i] != NULL; i++) + OemFlashWriteEnable[i](); + } +} +// +//---------------------------------------------------------------------- +// Procedure: OemFlashDeviceWriteDisable +// +// Description: This function goes through the elinked list of oem flash +// write disable functions giving control. +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------- +// +VOID +OemFlashDeviceWriteDisable (VOID) +{ + UINT8 i; + + if ( gbDeviceWriteState != FALSE ) { + gbDeviceWriteState = FALSE; + for(i = 0; OemFlashWriteDisable[i] != NULL; i++) + OemFlashWriteDisable[i](); + } +} + +// +//---------------------------------------------------------------------- +// Procedure: FlashVirtualFixup +// +// Description: Fixup global data for for a virtual address space. +// This routine must be called by the library consumer in the +// EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event handler +// +// Input: EFI_RUNTIME_SERVICES *pRS - pointer to the Runtime Services Table +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------- +// +VOID +FlashVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + static BOOLEAN bFlashVirtual = FALSE; + VOID **p; + UINT8 i; + + //if FlashAPI is NULL, nothing to fix up + //TODO: Current implementation of Identify routines + //will not work in virtual mode since absolute addresses are used + //That's Ok for now since current flash library consumers + //call flash routines at boot time, so we should have FlashAPI + //initialized at this point + if (!FlashAPI) return; + + // This function gets called from Nvramdxe.c and flash.c, do anything when + // the function is called second time. + if (bFlashVirtual == TRUE) return; + else bFlashVirtual = TRUE; + + //Do device specific fixups + FlashAPI->FlashVirtualFixup(pRS); + + //Fixup FlashAPI member functions + for(p = (VOID**)FlashAPI; p < (VOID**)(FlashAPI + 1); p++) + pRS->ConvertPointer(0, p); + + //Fixup FlashAPI pointer + pRS->ConvertPointer(0, &FlashAPI); + + //convert FeatureSpaceBase address + pRS->ConvertPointer(0, (VOID**)&FwhFeatureSpaceBase); + + //convert FlashDeviceBase address + pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + //convert FlashBlockSize address + pRS->ConvertPointer(0, (VOID**)&FlashBlockSize); + + //Fixup OemFlashWriteEnable list + for(i = 0; OemFlashWriteEnable[i] != NULL; i++) + pRS->ConvertPointer(0, (VOID**)&OemFlashWriteEnable[i]); + + //Fixup OemFlashWriteDisable list + for(i = 0; OemFlashWriteDisable[i] != NULL; i++) + pRS->ConvertPointer(0, (VOID**)&OemFlashWriteDisable[i]); +} + +#if defined _DXE_FLASH_LIB_ +// +//---------------------------------------------------------------------- +// Procedure: GetFlashPartInfomation +// +// Description: +// +// Input: *pBlockAddress - Address to access the flash part +// *Buffer - Buffer to write the flash part number string. +// +// Output: None +// +// Returns: EFI_SUCCESS +// +//---------------------------------------------------------------------- +// +VOID +GetFlashPartInfomation ( + IN UINT8* pBlockAddress, + IN UINT8* Buffer +) +{ + UINT8 bFlashStringSign[4] = {'$','F','P','S'}; + UINT32 dFlashCapacity; + + if ( FlashAPI == NULL) { + MemSet( &pFlashDeviceNumber, FLASH_PART_STRING_LENGTH, 0 ); + FlashInit(pBlockAddress); + } + if ((FlashAPI != NULL) && ( FlashAPI->FlashPartNumber != NULL )) { + MemCpy ( Buffer, bFlashStringSign, 4 ); + Buffer += sizeof (UINT32); + *(UINT32*)Buffer = FLASH_PART_STRING_LENGTH; + dFlashCapacity = *(UINT32*)(FlashAPI->FlashPartNumber + \ + FLASH_PART_STRING_LENGTH - 4); + + if ((dFlashCapacity != 0) && !(dFlashCapacity % FlashAPI->FlashSectorSize)) + *(UINT32*)Buffer = FLASH_PART_STRING_LENGTH + (dFlashCapacity >> 4); + Buffer += sizeof (UINT32); + MemCpy ( Buffer, FlashAPI->FlashPartNumber, FLASH_PART_STRING_LENGTH ); + } +} +#endif // #ifdef _DXE_FLASHLIB_ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Board/Flash/LPC/LpcFlash.cif b/Board/Flash/LPC/LpcFlash.cif new file mode 100644 index 0000000..5049487 --- /dev/null +++ b/Board/Flash/LPC/LpcFlash.cif @@ -0,0 +1,11 @@ + + name = "LPC Interface - Source" + category = ModulePart + LocalRoot = "Board\Flash\LPC" + RefName = "LPC_INTERFACE_SOURCE" +[files] +"LpcFlash.sdl" +"LpcFlash.mak" +"LpcFlashWrite.c" +"LpcSst2MblFlashWrite.c" + diff --git a/Board/Flash/LPC/LpcFlash.mak b/Board/Flash/LPC/LpcFlash.mak new file mode 100644 index 0000000..3860fdc --- /dev/null +++ b/Board/Flash/LPC/LpcFlash.mak @@ -0,0 +1,99 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Flash_Combined_2/Core/LPC/LpcFlash.mak 5 10/25/10 5:55a Calvinchen $ +# +# $Revision: 5 $ +# +# $Date: 10/25/10 5:55a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Flash_Combined_2/Core/LPC/LpcFlash.mak $ +# +# 5 10/25/10 5:55a Calvinchen +# Added support for PEI Flash Library. +# +# 4 6/24/09 3:13a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# 3 11/13/08 1:33a Calvinchen +# Fixed Boot Block recovery and re-flash BIOS failed with using SST +# 49LF160C. +# +# 1 12/18/06 3:39p Robert +# Initial Check in +# +# 2 11/22/06 10:46a Robert +# removed redundant addition of AMIDXELIB. It is included in main make +# file for the component +# +# 1 10/31/06 2:30p Sivagarn +# Initial Checkin +# +# +#********************************************************************** + +# +# +# Name: FlashSrc.mak +# +# Description: +# +# +#********************************************************************** +all : LPCFlash + +LPCFlash : $(BUILD_DIR)\LPCFlash.mak LPCFlashBin + +#--------------------------------------------------------------------------- +# Generic LPC FLASH dependencies +#--------------------------------------------------------------------------- +$(BUILD_DIR)\LPCFlash.mak : $(LPCFlash_DIR)\LPCFlash.cif $(LPCFlash_DIR)\LPCFlash.mak $(BUILD_RULES) + $(CIF2MAK) $(LPCFlash_DIR)\LPCFlash.cif $(CIF2MAK_DEFAULTS) + +#--------------------------------------------------------------------------- +# Create LPC Flash Library +#--------------------------------------------------------------------------- +LPCFlashBin : + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\LPCFlash.mak all\ + "CFLAGS=$(CFLAGS:/W4=/W3)" \ + NAME=LPCFlash \ + TYPE=LIBRARY LIBRARY_NAME=$(LPCFLASHLIB) +!IF "$(x64_BUILD)"=="1" && "$(BUILD_PEI_FLASH_LIB)"=="1" + $(MAKE) /$(MAKEFLAGS) BUILD_ROOT=$(BUILD_DIR)\ + "EXT_OBJS=$(**:Build\=Build\IA32\)" PROJECT_DIR=$(PROJECT_DIR)\ + /f $(BUILD_DIR)\LPCFlash.mak all\ + "CFLAGS=$(CFLAGS:/W4=/W3)"\ + BUILD_DIR=$(BUILD_DIR)\IA32\ + TYPE=PEI_LIBRARY NAME=LPCFlash +!ENDIF + +$(LPCFLASHLIB) : LPCFlash + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* \ No newline at end of file diff --git a/Board/Flash/LPC/LpcFlash.sdl b/Board/Flash/LPC/LpcFlash.sdl new file mode 100644 index 0000000..a5c972c --- /dev/null +++ b/Board/Flash/LPC/LpcFlash.sdl @@ -0,0 +1,114 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Flash_Combined_2/Core/LPC/LpcFlash.sdl 6 6/24/09 3:13a Calvinchen $ +# +# $Revision: 6 $ +# +# $Date: 6/24/09 3:13a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Flash_Combined_2/Core/LPC/LpcFlash.sdl $ +# +# 6 6/24/09 3:13a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# +#********************************************************************** + +TOKEN + Name = "LPCFlash_SUPPORT" + Value = "1" + Help = "Main switch to enable LPC Flash support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "SST_49LF160C" + Value = "1" + Help = "This enables support for the SST 49LF160C and 004 LPC flash parts" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "SST_49LF080A" + Value = "1" + Help = "This enables support for the SST 49LF008 and 004 LPC flash parts" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "LPCFLASHLIB" + Value = "$(BUILD_DIR)\LPCFlash.lib" + TokenType = Expression + TargetMAK = Yes +End + +PATH + Name = "LPCFlash_DIR" +End + +MODULE + Help = "Includes FlashSrc.mak to Project" + File = "LPCFlash.mak" +End + +ELINK + Name = "$(BUILD_DIR)\LPCFlash.lib" + Parent = "$(Flash_DIR)\LPCFlash.lib" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(Flash_DIR)\LPCFlash.lib" + Parent = "FLASHLISTLIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "mLpcFlashIdentify," + Parent = "FlashList" + Token = "SST_49LF080A" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "mSstLpcIdentify," + Parent = "FlashList" + Token = "SST_49LF160C" "=" "1" + InvokeOrder = AfterParent +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* \ No newline at end of file diff --git a/Board/Flash/LPC/LpcFlashWrite.c b/Board/Flash/LPC/LpcFlashWrite.c new file mode 100644 index 0000000..ceccca8 --- /dev/null +++ b/Board/Flash/LPC/LpcFlashWrite.c @@ -0,0 +1,715 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/LPC/LpcFlashWrite.c 15 12/23/09 6:12a Calvinchen $ +// +// $Revision: 15 $ +// +// $Date: 12/23/09 6:12a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/LPC/LpcFlashWrite.c $ +// +// 15 12/23/09 6:12a Calvinchen +// Improvement: +// 1.Added FWH/LPC/STD Flash Device Number support. +// 2.Changed for SMIFlash module Label "4.6.3.6_SMIFLASH_12" or later +// +// 14 12/15/09 5:47a Calvinchen +// Modified for adding Flash chip name support. +// +// 13 6/24/09 3:13a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 12 6/26/08 7:00a Calvinchen +// Generic bug fixed. +// +// 10 5/09/08 3:34a Calvinchen +// Added support for Winbond 39V080AP and STM M50LPW080. +// +// 9 1/11/08 11:33a Robert +// +// 8 1/07/08 3:28p Robert +// Updated for coding standard +// +// 7 11/09/07 4:16p Alexp +// Added dummy FlashRead function. Not supported by this type of flash +// module +// +// 6 3/30/07 12:41p Robert +// coding standard errors +// +// 5 3/26/07 7:22p Robert +// Coding standard updates +// +// 4 2/16/07 3:47p Robert +// Updated the Flash Part Data Structure to contain the Sector Size +// Parameter. This is just a dummy parameter for LPC parts +// +// 2 1/05/07 3:14p Felixp +// 1. Support for SST49LF080A Device added +// 2. Bug fix in ProgramCommand function +// 3. Clean up +// +// 1 12/18/06 3:39p Robert +// Initial Check in +// +//********************************************************************** +// +// +// Name: LPCFlashWrite.C +// +// Description: This file contains LPC flash write related code. The +// following are the flash parts currently supported and/or tested: +// SST 49LF020A Tested +// +// +//********************************************************************** + +//---------------------------------------------------------------------------- +// Includes +#include +#include +#include +#include + +//---------------------------------------------------------------------------- +// Flash part related tokens +#define SST_MANUFACTURER_ID 0xbf +#define SST49LF020A_DEVICE_ID 0x52 +#define SST49LF080A_DEVICE_ID 0x5b +#define SST49LF020A 0x52bf +#define SST49LF080A 0x5bbf +#define WINBOND_W39V080A 0xd0da + +#define COMMAND_SEQUENCE_1 0xaa +#define COMMAND_SEQUENCE_2 0x55 +#define BYTE_PROGRAM_CMD 0xa0 +#define BLOCK_ERASE_CMD_1 0x80 +#define BLOCK_ERASE_CMD_2 0x30 +#define LPC_ID_CMD 0x90 +#define LPC_RESET_CMD 0xf0 + +#define UNLOCK 0 +#define WRITE_LOCK 1 + +//---------------------------------------------------------------------------- +// Module level global data +extern UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; + +//---------------------------------------------------------------------------- +// Function prototypes +EFI_STATUS +InitSstAndCheckId ( + volatile UINT8 *pBlockAddress + ); +VOID +LpcFlashEraseCommand ( + volatile UINT8 *pBlockAddress + ); +VOID +LpcFlashReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +VOID +LpcFlashProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +BOOLEAN +LpcFlashIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus + ); +BOOLEAN +LpcFlashIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus + ); +VOID +LpcFlashBlockWriteEnable ( + UINT8 *pBlockAddress + ); +VOID +LpcFlashBlockWriteDisable ( + UINT8 *pBlockAddress + ); +VOID +LpcFlashDeviceWriteEnable ( + VOID + ); +VOID +LpcFlashDeviceWriteDisable ( + VOID + ); +EFI_STATUS +LpcOperationCompleted ( + volatile UINT8 *pAddress + );//, +VOID +LpcResetFlash ( + volatile UINT8 *pBlockAddress + ); +VOID +LpcFlashVirtualFixup ( + EFI_RUNTIME_SERVICES *pRS + ); +UINT8 gbLpcFlashEraseCommand; +//---------------------------------------------------------------------------- +// Module specific variables +FLASH_PART mCommonLpcFlash = { + LpcFlashReadCommand, // dummy byte read command + LpcFlashEraseCommand, // block erase command + LpcFlashProgramCommand, // byte program command + LpcFlashIsEraseCompleted, // erase complete identifier command + LpcFlashIsProgramCompleted, // program complete identifier command + LpcFlashBlockWriteEnable, // block write enable command + LpcFlashBlockWriteDisable, // block write disable command + LpcFlashDeviceWriteEnable, // write enable command + LpcFlashDeviceWriteDisable, // write disable command + LpcFlashVirtualFixup, // virtual address fix up routine + 1, // Number of bytes to program to the + // Flash part in each program command + 0, // Dummy value to hold place - only used in SPI + NULL // Flash Part Number Pointer + }; + +//---------------------------------------------------------------------------- +// Function Definitions + +// +//---------------------------------------------------------------------------- +// Procedure: mLpcFlashIdentify +// +// Description: This function identifies the supported Lpc flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +mLpcFlashIdentify ( + IN volatile UINT8 *pBlockAddress, + OUT FLASH_PART **FlashApi +) +{ + EFI_STATUS Status; + + Status = InitSstAndCheckId( pBlockAddress ); + if ( Status != EFI_SUCCESS ) return FALSE; + else { + mCommonLpcFlash.FlashPartNumber = pFlashDeviceNumber; + *FlashApi = &mCommonLpcFlash; + } + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +VOID +LpcFlashReadCommand ( + IN volatile UINT8 *pByteAddress, + IN OUT UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT32 dNumBytes = 0; + + // Changes for SMIFlash module label "4.6.3.6_SMIFLASH_12" or later. + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = *(UINT8*)((UINT32)pByteAddress + dNumBytes ); + *Length = 0; + return ; +} + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +// +// Return: Nothing +// +//---------------------------------------------------------------------------- +// +VOID +LpcFlashEraseCommand ( + IN volatile UINT8 *pBlockAddress +) +{ + EFI_STATUS Status; + UINT8 bFlashRetry; + + LpcResetFlash ( pBlockAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + pBlockAddress[0x5555] = COMMAND_SEQUENCE_1; + pBlockAddress[0x2aaa] = COMMAND_SEQUENCE_2; + pBlockAddress[0x5555] = BLOCK_ERASE_CMD_1; + pBlockAddress[0x5555] = COMMAND_SEQUENCE_1; + pBlockAddress[0x2aaa] = COMMAND_SEQUENCE_2; + *pBlockAddress = gbLpcFlashEraseCommand; + Status = LpcOperationCompleted( pBlockAddress ); + LpcResetFlash ( pBlockAddress ); + if ( Status != EFI_SUCCESS ) continue; + if ( *pBlockAddress != 0xFF ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } +//- return Status; +} +// +//---------------------------------------------------------------------------- +// Procedure: LpcOperationCompleted +// +// Description: This function verifies whether the previous (erase or +// program) command is completed and returns the status +// of the command +// +// Input: *pAddress Location of the previous operation +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +LpcOperationCompleted ( + IN volatile UINT8 *pAddress +) +{ + UINT8 bData1, bData2; + UINT32 dTimeout = FLASH_RETRIES * 0x10000; + EFI_STATUS Status = EFI_TIMEOUT; + + do { + bData1 = (*pAddress) & 0x40; + bData2 = (*pAddress) & 0x40; + if ( bData1 == bData2 ) return EFI_SUCCESS; + dTimeout--; + } while ( dTimeout != 0 ); // Check for Bit 6 Toggle + return EFI_TIMEOUT; +} +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// *Data - Byte to be written +// *Length - Number of bytes to write +// +// Output: *Length - Number of bytes left to write +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +LpcFlashProgramCommand ( + IN volatile UINT8 *pByteAddress, + IN UINT8 *Data, + IN OUT UINT32 *Length +) +{ + volatile UINT8* pBlockAddress = (volatile UINT8 *)BLOCK(pByteAddress); + UINT8 bFlashRetry; + EFI_STATUS Status; + + if (*Data != *pByteAddress) + { + LpcResetFlash ( pBlockAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + // Program Command Sequence + pBlockAddress[0x5555] = COMMAND_SEQUENCE_1; + pBlockAddress[0x2aaa] = COMMAND_SEQUENCE_2; + pBlockAddress[0x5555] = BYTE_PROGRAM_CMD; + *pByteAddress=*Data; + Status = LpcOperationCompleted ( pByteAddress ); + if ( Status != EFI_SUCCESS ) continue; + if ( *pByteAddress != *Data ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + LpcResetFlash ( pBlockAddress ); + } else Status = EFI_SUCCESS; + *Length = *Length - 1; +//- return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +BOOLEAN +LpcFlashIsEraseCompleted ( + IN volatile UINT8 *pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress - Location of the program command +// *Byte - Last data byte written +// Length - Amount of data that was written +// +// Output: *pError - True on error and false on success +// *Status - Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +BOOLEAN +LpcFlashIsProgramCompleted ( + IN volatile UINT8 *pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} +// +//---------------------------------------------------------------------------- +// Procedure: SetBlockLock +// +// Description: This function programs a page of data at a time +// +// Input: volatile UINT8* pBlockAddress - This is location where the data +// is to be written +// UINT8 LockState - Value to use to set the Lock register for the +// block defined by pBlockAddress +// +// Output: None +// +// Modified: +// +// Referrals: +// +// Notes: +//---------------------------------------------------------------------------- +// +static +void +SetBlockLock ( + IN volatile UINT8* pBlockAddress, + IN UINT8 LockState +) +{ + // Update the block lock register + ((UINT8*)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase))[2] = LockState; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +LpcFlashBlockWriteEnable ( + IN UINT8 *pBlockAddress +) +{ + SetBlockLock(pBlockAddress, UNLOCK); +} + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +LpcFlashBlockWriteDisable ( + IN UINT8 *pBlockAddress +) +{ + SetBlockLock(pBlockAddress, WRITE_LOCK); +} + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +LpcFlashDeviceWriteEnable (VOID) +{ + // Flash device does not support this feature +} + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +// +VOID +LpcFlashDeviceWriteDisable (VOID) +{ + // Flash device does not support this feature +} + +// +//---------------------------------------------------------------------------- +// Procedure: LpcFlashVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +LpcFlashVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: LpcResetFlash +// +// Description: This function resets the Lpc flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +LpcResetFlash ( + IN volatile UINT8* pBlockAddress) +{ + pBlockAddress[0x5555] = COMMAND_SEQUENCE_1; + pBlockAddress[0x2aaa] = COMMAND_SEQUENCE_2; + pBlockAddress[0x5555] = LPC_RESET_CMD; +} + +// +//---------------------------------------------------------------------------- +// Procedure: InitSstAndCheckId +// +// Description: This function checks whether the flash device on the system +// is SST Lpc flash +// +// +// Input: None +// +// Output: None +// +// Return: TRUE If flash part is identified as SST +// FALSE If non-SST Lpc flash part identified +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +InitSstAndCheckId ( + IN volatile UINT8* pBlockAddress +) +{ + UINT8 ManfactureID, DeviceID; + + LpcResetFlash(pBlockAddress); + pBlockAddress[0x5555] = COMMAND_SEQUENCE_1; + pBlockAddress[0x2aaa] = COMMAND_SEQUENCE_2; + pBlockAddress[0x5555] = LPC_ID_CMD; + ManfactureID = *pBlockAddress; + DeviceID = *(pBlockAddress + 1); + LpcResetFlash(pBlockAddress); + switch ( ( DeviceID << 8 ) + ManfactureID ) { + case SST49LF020A : + case SST49LF080A : + gbLpcFlashEraseCommand = 0x50; + MemCpy ( pFlashDeviceNumber, "SST 49LF020/080A", 16 ); + break; + case WINBOND_W39V080A : + gbLpcFlashEraseCommand = 0x30; + MemCpy ( pFlashDeviceNumber, "Winbond W39V080A", 16 ); + break; + default : + return EFI_NOT_FOUND; + } + return EFI_SUCCESS; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* \ No newline at end of file diff --git a/Board/Flash/LPC/LpcSst2MblFlashWrite.c b/Board/Flash/LPC/LpcSst2MblFlashWrite.c new file mode 100644 index 0000000..954eaba --- /dev/null +++ b/Board/Flash/LPC/LpcSst2MblFlashWrite.c @@ -0,0 +1,734 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/LPC/LpcSst2MblFlashWrite.c 15 12/23/09 6:12a Calvinchen $ +// +// $Revision: 15 $ +// +// $Date: 12/23/09 6:12a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/LPC/LpcSst2MblFlashWrite.c $ +// +// 15 12/23/09 6:12a Calvinchen +// Improvement: +// 1.Added FWH/LPC/STD Flash Device Number support. +// 2.Changed for SMIFlash module Label "4.6.3.6_SMIFLASH_12" or later +// +// 14 12/15/09 5:47a Calvinchen +// Modified for adding Flash chip name support. +// +// 13 6/24/09 3:13a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 12 11/13/08 1:33a Calvinchen +// Fixed Boot Block recovery and re-flash BIOS failed with using SST +// 49LF160C. +// +// 11 6/26/08 7:00a Calvinchen +// Generic bug fixed. +// +// 9 5/09/08 3:34a Calvinchen +// Added support for Winbond 39V080AP and STM M50LPW080. +// +// 8 1/07/08 3:28p Robert +// Updated for coding standard +// +// 7 12/07/07 1:45p Stacyh +// Updated to differentiate between LPC and FWH SST parts. +// +// 6 11/09/07 4:17p Alexp +// Added dummy FlashRead function. Not supported by this type of flash +// module +// +// 5 10/25/07 1:14p Fasihm +// Removed the directive AmiCspLib.h as it is not needed and is causing +// other Build Errors. +// +// 4 10/19/07 6:29p Robert +// +// 3 8/20/07 4:13p Radhikav +// Flash Part Data structure for SST 49LF160C changed. +// +// 2 7/09/07 10:05a Radhikav +// modified flashdevicewriteenable and disable functions. +// +// 1 5/16/07 1:00p Radhikav +// +// +// +// +//********************************************************************** +// +// +// Name: LpcSst2MblFlashWrite.c +// +// Description: Support routines for the LPC Sst 2Mb part +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include +#include +#include +#include "token.h" + +//---------------------------------------------------------------------- +// define local MACROS + +//Flash Part Specific Tokens +#define SST_MANUFACTURER_ID 0xbf // SST manufacturer ID +#define SST49LF160C_DEVICE_ID 0x4c // 2MB LPC +#define SST49LF160C 0x4cbf // SST 49LF160C +#define SST49LF016C 0x5cbf +#define STM50LPW080 0x2f20 // ST M50LPW080 + + +#define READ_ARRAY_CMD 0xff +#define RD_STATUS_CMD 0x70 +#define CLR_STATUS_CMD 0x50 +#define ERASE_SET_CMD 0x20 +#define ERASE_CNF_CMD 0xd0 +#define PRG_SETUP_CMD 0x40 +#define SECTOR_ERASE_SET_CMD 0x30 // SST 49LF160C only + +#define RD_ID_CODE 0x90 + +// SST49LF160C Status Register Bits + +#define VPP_LOW 0x08 +#define PROGRAM_FAIL 0x10 +#define ERASE_FAIL 0x20 +#define WSM_BUSY 0x80 + +// Intel Lock Commands +#define UNLOCK 0 +#define WRITE_LOCK 1 + +#define SECTOR_SIZE_4KB 0x1000 // Common 4kBytes sector size +#define SECTOR_SIZE_64KB 0x10000 // Common 64kBytes sector size + +//---------------------------------------------------------------------------- +// Module level global data +extern FLASH_PART *FlashAPI; +extern UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; + +//---------------------------------------------------------------------------- +// Local Variable definitions + +EFI_STATUS +InitSst2MbCheckId ( + volatile UINT8* pBlockAddress + ); +BOOLEAN +SstLpcIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus + ); +BOOLEAN +SstLpcIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus + ); + +static UINT8 gbEraseSetCmd = ERASE_SET_CMD; + +//---------------------------------------------------------------------------- +// Function Definitions + +// +//---------------------------------------------------------------------------- +// Procedure: Sst2mLpcCmdDelay +// +// Description: This function resets the Sst flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +Sst2mLpcCmdDelay (VOID) +{ + IoWrite8 ( 0xeb, 0x55 ); + IoWrite8 ( 0xeb, 0xaa ); +} +// +//---------------------------------------------------------------------------- +// Procedure: Sst2mLpcResetFlash +// +// Description: This function resets the Sst flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +Sst2mLpcResetFlash ( + IN volatile UINT8* pAddress +) +{ + *pAddress = READ_ARRAY_CMD;// Return to read mode + Sst2mLpcCmdDelay (); + *pAddress = CLR_STATUS_CMD;// clear status + Sst2mLpcCmdDelay (); +} +// +//---------------------------------------------------------------------------- +// Procedure: Sst2mLpcOperationCompleted +// +// Description: +// This function verifies whether the command sent to the FWH part +// has completed and returns the status of the command +// +// Input: +// IN volatile UINT8* pAddress Location to check the device status +// +// Output: +// EFI_SUCCESS - +// EFI_TIMEOUT - +// EFI_DEVICE_ERROR - +// +//---------------------------------------------------------------------------- +// +static +EFI_STATUS +Sst2mLpcOperationCompleted ( + IN volatile UINT8* pAddress +) +{ + UINT8 bLpcStatus; + UINT32 dTimeout = FLASH_RETRIES * 0x10000; + + do { + *pAddress = RD_STATUS_CMD; // read status. + Sst2mLpcCmdDelay (); + bLpcStatus = *pAddress; + if ( bLpcStatus & WSM_BUSY ) { + if ( bLpcStatus & ( VPP_LOW + PROGRAM_FAIL + ERASE_FAIL ) ) + return EFI_DEVICE_ERROR; + else return EFI_SUCCESS; + } + dTimeout--; + } while ( dTimeout != 0 ); + return EFI_TIMEOUT; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +//---------------------------------------------------------------------------- +// +static +VOID +SstLpcEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + EFI_STATUS Status; + UINT8 bFlashRetry; + UINTN nSectorAddr; + UINT16 wNumSectors, wSectorCount; + + Sst2mLpcResetFlash( pBlockAddress ); + wNumSectors = ( FlashBlockSize / FlashAPI->FlashSectorSize ); + for ( wSectorCount = 0; wSectorCount < wNumSectors; wSectorCount++ ) { + nSectorAddr = (UINTN)( wSectorCount * FlashAPI->FlashSectorSize ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + *(UINT8*)( (UINTN)pBlockAddress + nSectorAddr ) = gbEraseSetCmd; + Sst2mLpcCmdDelay (); + *(UINT8*)( (UINTN)pBlockAddress + nSectorAddr ) = ERASE_CNF_CMD; + Sst2mLpcCmdDelay (); + Status = Sst2mLpcOperationCompleted ( \ + (UINT8*)((UINTN)pBlockAddress + nSectorAddr) ); + Sst2mLpcResetFlash( (UINT8*)((UINTN)pBlockAddress + nSectorAddr) ); + if ( Status != EFI_SUCCESS ) continue; + if ( 0xFF == \ + *(volatile UINT8*)((UINTN)pBlockAddress + nSectorAddr) ) { + Status = EFI_SUCCESS; + break; + } else Status = EFI_DEVICE_ERROR; + } + } +//- return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Output: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +SstLpcIsEraseCompleted ( + IN volatile UINT8* pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstLpcReadCommand ( + IN volatile UINT8* pByteAddress, + IN OUT UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT32 dNumBytes = 0; + + // Changes for SMIFlash module label "4.6.3.6_SMIFLASH_12" or later. + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = *(UINT8*)((UINT32)pByteAddress + dNumBytes ); + *Length = 0; + return ; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Data Byte to be written +// +// Output: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstLpcProgramCommand ( + IN volatile UINT8* pByteAddress, + OUT UINT8 *Byte, + OUT UINT32 *Length +) +{ + EFI_STATUS Status; + UINT8 bFlashRetry; + + if ( *pByteAddress != *Byte ) { + + Sst2mLpcResetFlash( pByteAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + *pByteAddress = PRG_SETUP_CMD; // Issue program command + Sst2mLpcCmdDelay (); + *pByteAddress = *Byte; // Program a byte + Sst2mLpcCmdDelay (); + // Check for completion of the program operation + Status = Sst2mLpcOperationCompleted( pByteAddress ); + Sst2mLpcResetFlash( pByteAddress ); + if ( Status != EFI_SUCCESS ) continue; + if ( *pByteAddress != *Byte ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + } else Status = EFI_SUCCESS; + *Length = *Length - 1; +//- return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// Byte Last data byte written +// *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Output: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +SstLpcIsProgramCompleted ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: SetBlockLock +// +// Description: This function programs a page of data at a time +// +// Input: volatile UINT8* pBlockAddress - This is location where the data +// is to be written +// UINT8 LockState - Value to use to set the Lock register for the +// block defined by pBlockAddress +// +// Output: None +// +// Modified: +// +// Referrals: +// +// Notes: +//---------------------------------------------------------------------------- +// +static +void +SetBlockLock ( + IN volatile UINT8* pBlockAddress, + IN UINT8 LockState +) +{ + // Update the block lock register + ((UINT8*)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase))[2] = LockState; + ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase + 0x8000))[2] = LockState; + ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase + 0xA000))[2] = LockState; + ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \ + FwhFeatureSpaceBase + 0xC000))[2] = LockState; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstLpcBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ + SetBlockLock(pBlockAddress, UNLOCK); +//- return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstLpcBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ + SetBlockLock(pBlockAddress, WRITE_LOCK); +//- return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstLpcDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SstLpcDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + + +// +//---------------------------------------------------------------------------- +// Procedure: SstLpcVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +//---------------------------------------------------------------------------- +// + +static +VOID +SstLpcVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + + +// Flash Part Data structure for SST 49LF160C + +FLASH_PART mSstLpc2Mb = + { + SstLpcReadCommand, + SstLpcEraseCommand, + SstLpcProgramCommand, + SstLpcIsEraseCompleted, + SstLpcIsProgramCompleted, + SstLpcBlockWriteEnable, + SstLpcBlockWriteDisable, + SstLpcDeviceWriteEnable, + SstLpcDeviceWriteDisable, + SstLpcVirtualFixup, + 1, // Number of bytes to program to the + SECTOR_SIZE_64KB, // Dummy value to hold place - + NULL // Flash Part Number Pointer + }; // Flash part in each program command + + +// +//---------------------------------------------------------------------------- +// Procedure: mSstLpcIdentify +// +// Description: This function identifies the supported LPC flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// **FlashApi Pointer to hold the returned flash API +// +// Output: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSe Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +mSstLpcIdentify ( + IN volatile UINT8* pBlockAddress, + IN FLASH_PART **Struct +) +{ + EFI_STATUS Status = EFI_NOT_FOUND; + + Status = InitSst2MbCheckId( pBlockAddress ); + if ( Status != EFI_SUCCESS ) return FALSE; + else { + mSstLpc2Mb.FlashPartNumber = pFlashDeviceNumber; + *Struct = &mSstLpc2Mb; + } + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: InitSst2MbCheckId +// +// Description: This function identifies the supported LPC flash parts. +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: EFI_SUCCESS If flash part is supported +// EFI_NOT_FOUND Flash part is not supported +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +InitSst2MbCheckId ( + IN volatile UINT8* pBlockAddress +) +{ + UINT8 VID, DID; + EFI_STATUS Status = EFI_NOT_FOUND; + + *pBlockAddress = READ_ARRAY_CMD;// Return to read mode + Sst2mLpcCmdDelay (); + + *pBlockAddress = RD_ID_CODE;// Set to read ID code mode + Sst2mLpcCmdDelay (); + + VID = *pBlockAddress; + DID = *(pBlockAddress + 1); + + *pBlockAddress = READ_ARRAY_CMD;// Return to read mode + + switch ( ( DID << 8 ) + VID ) { + case SST49LF160C : + case SST49LF016C : + gbEraseSetCmd = SECTOR_ERASE_SET_CMD; + mSstLpc2Mb.FlashSectorSize = SECTOR_SIZE_4KB; + MemCpy ( pFlashDeviceNumber, "SST 49LF016/160C", 16 ); + Status = EFI_SUCCESS; + break; + case STM50LPW080 : + gbEraseSetCmd = ERASE_SET_CMD; + mSstLpc2Mb.FlashSectorSize = SECTOR_SIZE_64KB; + MemCpy ( pFlashDeviceNumber, "ST M50LPW080", 12 ); + Status = EFI_SUCCESS; + break; + default : + Status = EFI_NOT_FOUND; + } + return Status; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* \ No newline at end of file diff --git a/Board/Flash/SPI/ICHx/ICHxSpi.sdl b/Board/Flash/SPI/ICHx/ICHxSpi.sdl new file mode 100644 index 0000000..d145678 --- /dev/null +++ b/Board/Flash/SPI/ICHx/ICHxSpi.sdl @@ -0,0 +1,86 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Flash_Combined_2/CSP_SPI/Intel/ICHx/ICHxSpi.sdl 3 9/14/10 3:25a Calvinchen $ +# +# $Revision: 3 $ +# +# $Date: 9/14/10 3:25a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Flash_Combined_2/CSP_SPI/Intel/ICHx/ICHxSpi.sdl $ +# +# 3 9/14/10 3:25a Calvinchen +# Added the "SPI_INITIALIAL_WITH_VSCC" token for VSCC register +# initialize. +# +# 2 6/24/09 3:25a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# +#********************************************************************** + +TOKEN + Name = "ICHx_SPI_SUPPORT" + Value = "1" + Help = "Main switch to enable ICHx SPI support in Project" + TokenType = Boolean + Master = Yes +End + +TOKEN + Name = "SPI_INITIALIZE_WITH_VSCC" + Value = "0" + Help = "Program Host Lower/Upper Vendor Specific Component Capabilities Register." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "LOWER_VSCC_REG" + Value = "0xC4" + Help = "Host Lower Vendor Specific Component Capabilities Register." + TokenType = Integer + TargetH = Yes + Token = "SPI_INITIALIZE_WITH_VSCC" "=" "1" +End + +TOKEN + Name = "UPPER_VSCC_REG" + Value = "0xC8" + Help = "Host Upper Vendor Specific Component Capabilities Register." + TokenType = Integer + TargetH = Yes + Token = "SPI_INITIALIZE_WITH_VSCC" "=" "1" +End + +PATH + Name = "SPI_CSP_DIR" +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* \ No newline at end of file diff --git a/Board/Flash/SPI/ICHx/SPIFlash.c b/Board/Flash/SPI/ICHx/SPIFlash.c new file mode 100644 index 0000000..022e2ae --- /dev/null +++ b/Board/Flash/SPI/ICHx/SPIFlash.c @@ -0,0 +1,1369 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/ICHx/SPIFlash.c 1 11/02/17 1:44a Chienhsieh $ +// +// $Revision: 1 $ +// +// $Date: 11/02/17 1:44a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/ICHx/SPIFlash.c $ +// +// 1 11/02/17 1:44a Chienhsieh +// [TAG] EIP358409 +// [Category] Improvement +// [Description] [SAx0039][Flash_17/16/14/11/10/09/08/7] SPI security +// [Files] Board\Flash\SPI\ICHx\SPIFlash.c +// +// 19 6/10/13 5:26a Calvinchen +// [TAG] EIPNone +// [Category] Bug Fix +// [Severity] Important +// [Symptom] System hangs in EFI OS if Nvram Garbage collection occurred +// [RootCause] RCBA base don't convert to virtual address causes system +// hangs at checking TOP_SWAP bit. +// [Solution] Need to convert RCBA base. +// [Files] SPIFlash.c +// +// 18 3/08/13 3:37a Calvinchen +// [TAG] EIP110515 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Microchip SST26VF064B & SST26VF064BA 8MB SPI Flash part +// support +// [RootCause] Need "Global Block Protection Unlock" before programming. +// [Solution] Added "Global Block Protection Unlock" before programming. +// [Files] SPIFlash.c +// +// 17 12/11/12 5:54a Calvinchen +// [TAG] EIP108531 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Unable to use AMI Flash Lib inside DXE Core +// [RootCause] Procedure Name duplicated +// [Solution] Rename IoDelay to SpiIoDelay +// [Files] SpiFlash.c +// +// 16 10/31/12 3:08a Calvinchen +// [TAG] EIP104018 +// [Category] Improvement +// [Description] Changes for Top Swap enabled. +// [Files] SpiFlash.c +// +// 15 10/18/12 3:05a Calvinchen +// Added SFDP support for VSCC. +// +// 14 9/25/12 12:10a Calvinchen +// [TAG] EIP97017 +// [Category] Improvement +// [Description] 1. MahoBay Flash error fail save +// 2. Keep Quad Enable bit (Bit6) of Status Register for MXIC flash. +// [Files] SPIFlash.c +// +// 13 1/12/12 1:08a Calvinchen +// [TAG] EIP80707 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Flash Error +// [RootCause] Coding Mistake. +// [Solution] Fix coding mistake. +// [Files] SPIFlash.c +// +// 12 2/10/11 3:27a Calvinchen +// Bug Fixed : (EIP#53185)Reading 64 Bytes failed if cross over 4K +// boundary. +// Description : This is supposed to be an ICH/PCH limitation. +// +// 11 10/25/10 9:41a Calvinchen +// Very Slow SPI Read Byte Access. +// +// 10 10/25/10 6:22a Calvinchen +// (EIP45843)Very Slow SPI Read Byte Access. +// +// 9 9/14/10 3:25a Calvinchen +// Added the "SPI_INITIALIAL_WITH_VSCC" token for VSCC register +// initialize. +// +// 8 5/21/10 2:14a Calvinchen +// Bug fixed: Build failed with "undeclared identifier". +// +// 7 3/11/10 6:41a Calvinchen +// Improvement : Added SST AAIWordProgram SPI command to speed up the +// programming time with Intel chipset. +// +// 6 6/24/09 3:25a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 5 4/27/09 3:30a Calvinchen +// 2.(EIP20459) Added Multiple SPI CSP component support. +// +// 4 12/03/08 1:00a Calvinchen +// (EIP17945)Bug Fixed : Fail to unlock the BIOS region of Flash +// Descriptor. +// +// 3 8/26/08 3:02a Calvinchen +// 1.Fixed Fail to un-protect ATMEL flash. +// 2.Fixed Building failed if ICH_FDOC/FDOD not defined. +// 3.Increase the Timeout counter for waiting the ICH SPI cycle done. +// +// 2 6/26/08 6:56a Calvinchen +// Generic bug fixed. +// +// 1 3/13/08 6:37a Calvinchen +// Added support for Intel ICHx SPI. +// +//********************************************************************** +// +// +// Name: FlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** +//---------------------------------------------------------------------------- +// Includes +#include +#include +#include "FlashPart.h" +#include "SpiFlash.h" +#include "token.h" +//---------------------------------------------------------------------------- +// Local defines for transaction types +// ICH8/9/10 SPI register defines. +#define SPI_STS 0x90 // SPI Status +#define SPI_CTL 0x91 // SPI Control +#define SPI_ADR 0x08 // SPI Address +#define SPI_DAT0 0x10 // SPI Data 0 +#define SPI_PREOP 0x94 // Prefix Opcode Configuration +#define SPI_OPTYPE 0x96 // Opcode Type Configuration +#define SPI_OPMENU 0x98 // Opcode Menu Configuration +#define RCRB_MMIO_BUC 0x3414 // Backed Up Control Register +// SPI default opcode slots +#define SPI_OPCODE_WRITE_INDEX 0x0 +#define SPI_OPCODE_READ_INDEX 0x1 +#define SPI_OPCODE_ERASE_INDEX 0x2 +#define SPI_OPCODE_READ_S_INDEX 0x3 +#define SPI_OPCODE_READ_ID_INDEX 0x4 +#define SPI_OPCODE_WRITE_S_INDEX 0x5 +#define SPI_OPCODE_WRITE_S_E_INDEX 0x6 +#define SPI_OPCODE_WRITE_E_INDEX 0x7 +#define SPI_OPCODE_AAI_INDEX 0x6 +#define SPI_OPCODE_WRITE_D_INDEX 0x7 +#define SPI_PREFIX_WRITE_S_EN 0x1 +#define SPI_PREFIX_WRITE_EN 0x0 +#define SPI_MAX_DATA_TRANSFER 0x40 +#define ICHX_FDOC 0xb0 // Flash Descriptor Observability Control Register +#define ICHX_FDOD 0xb4 // Flash Descriptor Observability Data Register +#define FLASH_VALID_SIGNATURE 0x0ff0a55a +#define NO_ADDRESS_UPDATE 0 +#ifndef SPI_OPCODE_TYPE_READ_NO_ADDRESS +#define SPI_OPCODE_TYPE_READ_NO_ADDRESS 0x0 +#define SPI_OPCODE_TYPE_WRITE_NO_ADDRESS 0x1 +#define SPI_OPCODE_TYPE_READ_WITH_ADDRESS 0x2 +#define SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS 0x3 +#endif +#define SPI_FLASH_DEVICE_BASE_ADDRESS (0xFFFFFFFF-FLASH_SIZE+1) // [ EIP358409 ] +//---------------------------------------------------------------------------- +// Module level global data +extern UINT16 gFlashId; +extern FLASH_PART *FlashAPI; +//---------------------------------------------------------------------------- +// Function Externs +extern +VOID +SpiChipsetVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +); +//---------------------------------------------------------------------------- +// Local prototypes +VOID +CommonSpiEraseCommand ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 *Length +); +VOID +CommonSpiReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 *Length +); +BOOLEAN +CommonSpiIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus +); +BOOLEAN +CommonSpiIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus +); +VOID +CommonSpiBlockWriteEnable ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiBlockWriteDisable ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiDeviceWriteEnable ( + VOID +); +VOID +CommonSpiDeviceWriteDisable ( + VOID +); +VOID +CommonSpiDeviceVirtualFixup ( + EFI_RUNTIME_SERVICES *pRS +); +// [ EIP358409 ]+>>> +VOID +SpiBlockProtectUpdate ( + IN volatile UINT8 *pBlockAddress, + IN UINT8 bStatusData +); +// [ EIP358409 ]+<<< +//---------------------------------------------------------------------------- +// Local Variables +FLASH_PART mCommonSpiFlash ={ + CommonSpiReadCommand, + CommonSpiEraseCommand, + CommonSpiProgramCommand, + CommonSpiIsEraseCompleted, + CommonSpiIsProgramCompleted, + CommonSpiBlockWriteEnable, + CommonSpiBlockWriteDisable, + CommonSpiDeviceWriteEnable, + CommonSpiDeviceWriteDisable, + CommonSpiDeviceVirtualFixup, + 1, // default value, should be changed in Init function + SECTOR_SIZE_4KB +}; +EX_FLASH_PART mExFlashPart = { + {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},0,0}, + FLASH_SIZE, // flash size, should be changed in Init function + 0, // flash part id, should be changed in Init function + 0 // flash part string, should be changed in + // Init function +}; +volatile UINT8 *gSPIBASE = (UINT8*)(UINTN)(SB_RCBA + SPI_BASE_ADDRESS); +volatile UINT8 *gRCBABASE = (UINT8*)(UINTN)SB_RCBA; +UINT8 gbDeviceVirtual = 0; +UINT8 gbDeviceWriteEnabled = 0; +//---------------------------------------------------------------------------- +// Function Definitions + +// +//---------------------------------------------------------------------------- +// +// Procedure: SpiIoDelay +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +SpiIoDelay (VOID) +{ + UINT8 bTimeout; + for ( bTimeout = 0; bTimeout < 33; bTimeout++ ) { + IoWrite8( 0xEB, 0x55 ); + IoWrite8( 0xEB, 0xAA ); + } + return ; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: WaitForSpiCycleDone +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +WaitForSpiCycleDone (VOID) +{ + UINT32 dTimeout; + UINT8 bCyclyDone; + + for ( dTimeout = 0, bCyclyDone = 0; dTimeout < 0x4000000; dTimeout++ ) { + bCyclyDone = *(volatile UINT8*)( gSPIBASE + SPI_STS ); + if ( bCyclyDone & BIT02 ) break; + } + // write BIT2 to clear CycleDone status + *(volatile UINT8*)( gSPIBASE + SPI_STS ) = BIT02; + +} +// +//---------------------------------------------------------------------------- +// +// Procedure: SpiWriteDisable +// +// Description: This procedure issuess SPI Write Disable if AAIWordProgram. +// +// Input: None. +// +// Output: None. +// +//---------------------------------------------------------------------------- +// +VOID SpiWriteDisable (VOID) +{ + // Opcode menu slot 7 is configured as "Write Disable" if AAIWordProgram. + *(volatile UINT16*)(gSPIBASE + SPI_CTL) = \ + ( SPI_OPCODE_WRITE_D_INDEX << 4) + BIT01; + // wait for chipset SPI cycle completed. + WaitForSpiCycleDone(); + return ; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CheckAaiWordProram +// +// Description: This procedure checks whether issues the AAIWordProgram command. +// +// Input: dAddr - Start address to be written. +// dLength - Number of bytes to be written. +// +// Output: TRUE - Yes +// FALSE - No +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CheckAaiWordProram ( + IN UINT32 dAddr, + IN UINT32 dLength +) +{ + if ((mExFlashPart.AAIWordProgram != 0) && !(dAddr & 1) && (dLength >= 2)) + return TRUE; + return FALSE; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadStatus +// +// Description: +// +// Input: None. +// +// Output: Status Register which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +UINT8 +CommonSpiReadStatus ( + IN UINT32 dUpdateAddr +) +{ + UINT16 wSpiCmd; + + if( dUpdateAddr ) *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dUpdateAddr; + // Opcode menu slot 3 is configured as "Read Status Register" + wSpiCmd = SPI_OPCODE_READ_S_INDEX << 4; + // indicate that data phase is required + wSpiCmd += (1 << 14); + // Set BIT1 (Go) + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // return status register. + return ( *(volatile UINT8*)( gSPIBASE + SPI_DAT0 ) ); +} +// +//---------------------------------------------------------------------------- +// +// Procedure: WaitForWriteOperationCompleted +// +// Description: +// +// Input: None. +// +// Output: None. +// +//---------------------------------------------------------------------------- +// +VOID +WaitForWriteOperationCompleted (VOID) +{ + UINT16 wWaitStsRetry; + UINT8 bStatus; + + for( wWaitStsRetry = 0; wWaitStsRetry < 0xFFFF; wWaitStsRetry++ ) { + // read flash status register. + bStatus = CommonSpiReadStatus( NO_ADDRESS_UPDATE ); + // Is operation busy ? + if( !( bStatus & 0x1 ) ) break; + } +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiWriteStatus +// +// Description: Routine for Write SPI Status Register. +// +// Input: None. +// +// Output: Status Register which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiWriteStatus ( + IN UINT8 bWriteData, + IN UINT8 bOpcodeIndex, + IN UINT8 bIsDataPhase, + IN UINT8 bPrefixOp, + IN UINT32 dSectorAddress +) +{ + UINT16 wSpiCmd; + + *(volatile UINT8*)( gSPIBASE + SPI_DAT0 ) = bWriteData; + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dSectorAddress; + // Opcode menu slot 3 is configured as "Read Status Register" + wSpiCmd = bOpcodeIndex << 4; + // indicate that data phase is required + wSpiCmd += ( bIsDataPhase << 14 ); + // BIT3(Preop 1) + wSpiCmd += ( bPrefixOp << 3 ); + // Set BIT1 (Go), BIT2(Atomic w/ Prefix), + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01 + BIT02; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // wait for SPI flash operation completed. + WaitForWriteOperationCompleted(); + // return status register. + return ; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadByte +// +// Description: +// +// Input: dByteAddress Address that need to be read. +// +// Output: BYTE Value which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +UINT8 +CommonSpiReadByte ( + IN UINT32 dByteAddress +) +{ + UINT8 bData; + UINT32 dLength = sizeof(UINT8); + CommonSpiReadCommand((volatile UINT8*)dByteAddress, &bData, &dLength); + return bData; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonConvertSpiAddress +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +CommonConvertSpiAddress ( + IN volatile UINT8 *pAddress, + OUT UINT32 *pdCnvtAddress +) +{ + UINT32 dIchSpiFDOD; + static UINT32 gBiosRegionBase = 0, gBiosRegionLimit = 0; + + // if flash identified, here checks the BIOS region of Flash + // Descriptor Table. + if ( mExFlashPart.FlashVenDevId ) { + if ( !gBiosRegionBase ) { + *(volatile UINT32*)( gSPIBASE + ICHX_FDOC ) = 0; + dIchSpiFDOD = *(volatile UINT32*)( gSPIBASE + ICHX_FDOD ); + if ( dIchSpiFDOD == FLASH_VALID_SIGNATURE ) { + *(volatile UINT32*)( gSPIBASE + ICHX_FDOC ) = ( BIT13 + BIT02 ); + do { + dIchSpiFDOD = *(volatile UINT32*)( gSPIBASE + ICHX_FDOD ); + } while( dIchSpiFDOD == FLASH_VALID_SIGNATURE ); + gBiosRegionBase = ( ( (dIchSpiFDOD >> 16) + 1 ) << 12 ); + gBiosRegionLimit = ((dIchSpiFDOD >> 4) | 0xfff) + 1; + } + else { + gBiosRegionBase = mExFlashPart.FlashCapacity; + gBiosRegionLimit = mExFlashPart.FlashCapacity; + } + } + } + if ( gbDeviceVirtual ) { + // pAddress - offset from Flash Device Base. + pAddress -= FlashDeviceBase; + // pAddress - 32bit memory mapping address. + pAddress += (0xFFFFFFFF - FLASH_SIZE) + 1; + } + // pAddress - physical address in flash. + pAddress += gBiosRegionBase; + if ((UINT32)pAddress >= gBiosRegionLimit) return EFI_INVALID_PARAMETER; + *pdCnvtAddress = (UINT32)pAddress; + return EFI_SUCCESS; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: InitializeSpiEnvironment +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +InitializeSpiEnvironment ( + IN OUT FLASH_INFO *FlashInfo +) +{ + //Program first DWORD of opcode commands + *((volatile UINT32*)( gSPIBASE + R_RCRB_SPI_OPMENU + 0 )) = (UINT32) + // Write Byte + ( (FlashInfo->Write.Opcode << (SPI_OPCODE_WRITE_INDEX * 8)) | \ + // Read Data + (FlashInfo->Read.Opcode << (SPI_OPCODE_READ_INDEX * 8)) | \ + // Erase 64k Sector + (FlashInfo->Erase.Opcode << (SPI_OPCODE_ERASE_INDEX * 8)) | \ + // Read Device Status Reg + (FlashInfo->ReadStatus.Opcode << (SPI_OPCODE_READ_S_INDEX * 8)) ); + + //Program second DWORD of Opcode commands + *((volatile UINT32*)( gSPIBASE + R_RCRB_SPI_OPMENU + 4 )) = (UINT32) + // Read device ID + ((FlashInfo->ReadId.Opcode << ((SPI_OPCODE_READ_ID_INDEX - 4) * 8)) | \ + // Write Status Register + (FlashInfo->WriteStatus.Opcode << \ + ((SPI_OPCODE_WRITE_S_INDEX - 4) * 8)) | \ + // Write Status Enable Register + (FlashInfo->WriteStatusEnable.Opcode << \ + ((SPI_OPCODE_WRITE_S_E_INDEX - 4) * 8))); + + //Program opcode types + *((volatile UINT16*)( gSPIBASE + R_RCRB_SPI_OPTYPE )) = (UINT16) + // write with address. + (FlashInfo->Write.OpcodeType << (SPI_OPCODE_WRITE_INDEX * 2) | \ + // read with address. + FlashInfo->Read.OpcodeType << (SPI_OPCODE_READ_INDEX * 2) | \ + // write with address. + FlashInfo->Erase.OpcodeType << (SPI_OPCODE_ERASE_INDEX * 2) | \ + // read w/o no adress. + FlashInfo->ReadStatus.OpcodeType << (SPI_OPCODE_READ_S_INDEX * 2) | \ + // read with address. + FlashInfo->ReadId.OpcodeType << (SPI_OPCODE_READ_ID_INDEX * 2) | \ + // write w/o address. + FlashInfo->WriteStatus.OpcodeType << (SPI_OPCODE_WRITE_S_INDEX * 2) | \ + // write w/o address. + FlashInfo->WriteStatusEnable.OpcodeType << \ + (SPI_OPCODE_WRITE_S_E_INDEX * 2)); + + //set up the prefix opcodes for commands + *((volatile UINT16*)( gSPIBASE + R_RCRB_SPI_PREOP )) = (UINT16) + ( ( FlashInfo->WriteStatusEnable.Opcode << 8 ) | \ + ( FlashInfo->WriteEnable.Opcode ) ); + + //set up Program Opcode and Optype if AAIWordProgram. + if (mExFlashPart.AAIWordProgram != 0) { + UINT8 bOpType = 0; + *((volatile UINT16*)(gSPIBASE + R_RCRB_SPI_OPMENU + 6)) = 0x4ad; + bOpType = *((volatile UINT8*)(gSPIBASE + R_RCRB_SPI_OPTYPE + 1)); + bOpType = ((bOpType & 0xf) | \ + (SPI_OPCODE_TYPE_WRITE_NO_ADDRESS << 6) | \ + (SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS << 4)); + *((volatile UINT8*)(gSPIBASE + R_RCRB_SPI_OPTYPE + 1)) = bOpType; + } + return ; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: SerialFlashDiscoveryForQuadRead +// +// Description: This procedure checks SPI Quad Read support through SFDP. +// +// Input: None. +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +SerialFlashDiscoveryForQuadRead (VOID) +{ +#if defined SPI_INITIALIZE_WITH_VSCC && SPI_INITIALIZE_WITH_VSCC == 1 + UINT8 SfdpData[256]; + UINT16 wSpiCmd, wOffset, j; + UINT32 Index; + // Serial Flash Discoverable Parameters Command "0x5A". + *(volatile UINT8*)(gSPIBASE + SPI_OPMENU + 7) = 0x5a; + // Do nothing if SPI Registers is locked. + if (*(volatile UINT8*)(gSPIBASE + SPI_OPMENU + 7) != 0x5a) + return EFI_WRITE_PROTECTED; + // Update SPI OpMenu[7] to "READ WITH ADDRESS". + SfdpData[0] = *(volatile UINT8*)(gSPIBASE + SPI_OPTYPE + 1); + *(volatile UINT8*)(gSPIBASE + SPI_OPTYPE + 1) = (SfdpData[0] & 0x3f) | 0x80; + MemSet(SfdpData, 256, 0); + for (Index = 0; Index < 256; Index += 64) { + // Set SPI read-address = 0, 64, 128, 256 + *(volatile UINT32*)(gSPIBASE + SPI_ADR) = Index; + // set opcode for "5A" + wSpiCmd = SPI_OPCODE_WRITE_E_INDEX << 4; + // set transaction = 64 bytes + wSpiCmd += ((64 - 1) << 8); + // indicate that data phase is required + wSpiCmd += (1 << 14); + // Go (BIT1) + *(volatile UINT16*)(gSPIBASE + SPI_CTL) = wSpiCmd + BIT01; + WaitForSpiCycleDone(); + for (j = 0; j < 64; j++) + *(SfdpData + Index + j) = *(volatile UINT8*)(gSPIBASE + SPI_DAT0 + j); + // Serial Flash Discoverable Parameters (SFDP) Signature = 50444653h + if (Index == 0) { + wOffset = 0; + if (*(UINT32*)&SfdpData[wOffset] != 0x50444653) { + if (*(UINT32*)&SfdpData[++wOffset] != 0x50444653) + return EFI_UNSUPPORTED; + } + } + } + // SFDP opode at address Ch bits 23:00 = Parameter ID 0 table Address + Index = (*(UINT32*)&SfdpData[wOffset + 0xC] & 0x00FFFFFF); + // SFDP opode at address 05h(SFPD Major Revisions) must = 0001h + // SFDP opode at address 0Ah(Serial Flash Basic Major Revisions) must = 0001h + if ((SfdpData[wOffset + 5] != 0x1) || (SfdpData[wOffset + 0xA] != 0x1) || \ + ((Index + 0x10) > 256)) return EFI_UNSUPPORTED; + // Parameter ID 0 Table BIT[21] - Fast Read Quad I/O. + // Parameter ID 0 Table BIT[22] - Fast Read Quad Output. + if (*(UINT32*)&SfdpData[Index + 1] & (BIT21 + BIT22)) return EFI_SUCCESS; +#endif + return EFI_UNSUPPORTED; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: GlobalBlockProtectionUnlock +// +// Description: This procedure unlocks "Global Block Protection" for Microchip +// 26VF series flash parts. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +// +VOID +GlobalBlockProtectionUnlock (VOID) +{ + UINT8 SavedOpType; + + if (mExFlashPart.GlobalBlockUnlock != TRUE) return; + // Serial Flash Discoverable Parameters Command "0x5A". + *(volatile UINT8*)(gSPIBASE + SPI_OPMENU + 7) = 0x98; + // Do nothing if SPI Registers is locked. + if (*(volatile UINT8*)(gSPIBASE + SPI_OPMENU + 7) != 0x98) return; + // Update SPI OpMenu[7] to "WRITE W/O ADDRESS". + SavedOpType = *(volatile UINT8*)(gSPIBASE + SPI_OPTYPE + 1); + *(volatile UINT8*)(gSPIBASE + SPI_OPTYPE + 1) = (SavedOpType & 0x3f) | BIT06; + // Opcode menu slot 7 is configured as "Write Disable" if AAIWordProgram. + *(volatile UINT16*)(gSPIBASE + SPI_CTL) = \ + (SPI_OPCODE_WRITE_D_INDEX << 4) + BIT01; + // wait for chipset SPI cycle completed. + WaitForSpiCycleDone(); + return ; +} +// [ EIP358409 ]+>>> +// +//---------------------------------------------------------------------------- +// +// Procedure: RemoveWriteStatusOpcode +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +RemoveWriteStatusOpcode ( + IN OUT FLASH_INFO *FlashInfo +) +{ + + FlashInfo->WriteStatus.Opcode = FlashInfo->ReadId.Opcode; + FlashInfo->WriteStatus.OpcodeType = FlashInfo->ReadId.OpcodeType; + + //Program second DWORD of Opcode commands + *((volatile UINT32*)( gSPIBASE + R_RCRB_SPI_OPMENU + 4 )) = (UINT32) + // Read device ID + ((FlashInfo->ReadId.Opcode << ((SPI_OPCODE_READ_ID_INDEX - 4) * 8)) | \ + // Write Status Register + (FlashInfo->WriteStatus.Opcode << \ + ((SPI_OPCODE_WRITE_S_INDEX - 4) * 8)) | \ + // Write Status Enable Register + (FlashInfo->WriteStatusEnable.Opcode << \ + ((SPI_OPCODE_WRITE_S_E_INDEX - 4) * 8))); + + //Program opcode types + *((volatile UINT16*)( gSPIBASE + R_RCRB_SPI_OPTYPE )) = (UINT16) + // write with address. + (FlashInfo->Write.OpcodeType << (SPI_OPCODE_WRITE_INDEX * 2) | \ + // read with address. + FlashInfo->Read.OpcodeType << (SPI_OPCODE_READ_INDEX * 2) | \ + // write with address. + FlashInfo->Erase.OpcodeType << (SPI_OPCODE_ERASE_INDEX * 2) | \ + // read w/o no adress. + FlashInfo->ReadStatus.OpcodeType << (SPI_OPCODE_READ_S_INDEX * 2) | \ + // read with address. + FlashInfo->ReadId.OpcodeType << (SPI_OPCODE_READ_ID_INDEX * 2) | \ + // write w/o address. + FlashInfo->WriteStatus.OpcodeType << (SPI_OPCODE_WRITE_S_INDEX * 2) | \ + // write w/o address. + FlashInfo->WriteStatusEnable.OpcodeType << \ + (SPI_OPCODE_WRITE_S_E_INDEX * 2)); + + + return ; +} +// [ EIP358409 ]+<<< +// +//---------------------------------------------------------------------------- +// +// Procedure: ReinitializeSpiEnvironment +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +ReinitializeSpiEnvironment ( + IN OUT FLASH_INFO *FlashInfo +) +{ + UINT8 *BlockAddress; // [ EIP358409 ] +#if defined SPI_INITIALIZE_WITH_VSCC && SPI_INITIALIZE_WITH_VSCC == 1 + // Program UPPER/LOWER VSCC register. + UINT32 dVSCC = 0; + EFI_STATUS Status; + // Erase Opcode. + dVSCC = FlashInfo->Erase.Opcode << 8; + // Block/Sector Erase Size. + if (FlashInfo->SectorSize == SECTOR_SIZE_4KB) dVSCC |= BIT00; + else if (FlashInfo->SectorSize == SECTOR_SIZE_8KB) dVSCC |= BIT01; + else if (FlashInfo->SectorSize == SECTOR_SIZE_64KB) dVSCC |= (BIT00 + BIT01); + // Write Granularity. + if (FlashInfo->PageSize != 1) dVSCC |= BIT02; + // Write Status Required. + if (FlashInfo->WriteStatusEnable.Opcode == 0x50) dVSCC |= BIT03; + // Write Enable On Write Status. + if (FlashInfo->WriteStatusEnable.Opcode == 0x39) dVSCC |= BIT04; + Status = SerialFlashDiscoveryForQuadRead(); + if (!EFI_ERROR(Status)) { + switch ((UINT8)mExFlashPart.FlashVenDevId) { + case 0xEF : // Winbond + case 0x37 : // AMIC + case 0x01 : // Spansion + dVSCC |= BIT5; break; + case 0xC2 : // MXIC + dVSCC |= BIT6; break; + case 0x1F : // Atmel + dVSCC |= (BIT5 + BIT6); break; + case 0xBF : // SST/Microchip + dVSCC |= BIT7; break; + break; + default : break; + } + } + if (Status != EFI_WRITE_PROTECTED) { +#if LOWER_VSCC_REG != 0 + *(volatile UINT32*)(gSPIBASE + LOWER_VSCC_REG) = dVSCC; +#endif +#if UPPER_VSCC_REG != 0 + *(volatile UINT32*)(gSPIBASE + UPPER_VSCC_REG) = dVSCC; +#endif + } +#endif + GlobalBlockProtectionUnlock(); + InitializeSpiEnvironment ( FlashInfo ); +// [ EIP358409 ]+>>> + BlockAddress = (UINT8*)SPI_FLASH_DEVICE_BASE_ADDRESS; + SpiBlockProtectUpdate (BlockAddress, 0); + RemoveWriteStatusOpcode(FlashInfo); +// [ EIP358409 ]+<<< +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadId +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiReadId ( + IN FLASH_INFO *FlashInfo, + IN OUT UINT32 *dFlashId +) +{ + UINT16 wSpiCmd = 0xFFFF; + + InitializeSpiEnvironment( FlashInfo ); + // Set SPI read-address = 0 + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = 0; + // set opcode for "Read ID" + wSpiCmd = SPI_OPCODE_READ_ID_INDEX << 4; + // set transaction = 3 bytes + wSpiCmd += ( ( 3 - 1 ) << 8 ); + // indicate that data phase is required + wSpiCmd += ( 1 << 14 ); + // Go (BIT1) + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01; + WaitForSpiCycleDone(); + SpiIoDelay(); + *dFlashId = *(volatile UINT32*)( gSPIBASE + SPI_DAT0 ) & 0x00FFFFFF; + return TRUE; +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +//---------------------------------------------------------------------------- +// +VOID +CommonSpiEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + volatile UINT32 dSectorAddr; + UINT32 dNByte, dPhyAddress; + UINT16 wEraseRetry, wNumSectors, wSector; + UINT16 wSpiCmd; + + // These parts only erase in 64K sectors + InitializeSpiEnvironment( &mExFlashPart.FlashCommandMenu ); + wNumSectors = ( FlashBlockSize / FlashAPI->FlashSectorSize ); + for ( wSector = 0; wSector < wNumSectors ; wSector++ ) { + dSectorAddr = (UINT32)(pBlockAddress + \ + (wSector * FlashAPI->FlashSectorSize)); + if (EFI_ERROR(CommonConvertSpiAddress( \ + (volatile UINT8*)dSectorAddr, &dPhyAddress))) return; + for ( dNByte = 0; dNByte < FlashAPI->FlashSectorSize; dNByte++ ) { + if (0xFF != CommonSpiReadByte(dSectorAddr + dNByte)) break; + } + if ( dNByte == FlashAPI->FlashSectorSize ) continue; + for ( wEraseRetry = 0; wEraseRetry < FLASH_RETRIES; wEraseRetry++ ) { + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dPhyAddress; + // opcode index 2 is programmed for erase command. + // Set BIT1 (Go), BIT2(Atomic w/ Prefix) + wSpiCmd = ( SPI_OPCODE_ERASE_INDEX << 4) + BIT01 + BIT02; + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for chipset SPI cycle completed. + WaitForSpiCycleDone(); + // wait for SPI flash operation completed. + WaitForWriteOperationCompleted(); + // write operation appeared to succeed, now read back byte + // and compare. + if (CommonSpiReadByte(dSectorAddr) == 0xFF) break; + } + } +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiProgramCommand ( + IN volatile UINT8 *pByteAddress, + IN UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT8 bFlashRetry = 0; + UINT16 wProgBytes = 0, wNumBytes = 0; + UINT16 wSpiCmd = 0, wRetry = 0, wMaxNumBytes = 0; + UINT32 dPhyAddress = 0; + + + InitializeSpiEnvironment( &mExFlashPart.FlashCommandMenu ); + wProgBytes = mCommonSpiFlash.FlashProgramSize; + if ( mCommonSpiFlash.FlashProgramSize != 1 ) { + // Limit the max transfer to the number of bytes the chipset can + // transfer per cycle + if ( *Length >= SPI_MAX_DATA_TRANSFER ) + wProgBytes = SPI_MAX_DATA_TRANSFER; + else wProgBytes = *Length; + // this is currently for the WINBOND parts only + // mask off lowest 8 bits of address so that we can determine how + // many bytes we can write before we hit the end of a page + wMaxNumBytes = 0x100 - ((UINT32)pByteAddress & 0xFF); + if ( (UINT32)pByteAddress & 0x1 ) wProgBytes = 1; + else if ( wProgBytes > wMaxNumBytes ) wProgBytes = wMaxNumBytes; + } else if(CheckAaiWordProram((UINT32)pByteAddress, *Length)) wProgBytes = 2; + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + // check if do the data need to be programmed ? + for ( wNumBytes = 0; wNumBytes < wProgBytes; wNumBytes++ ) { + if ( *( Byte + wNumBytes ) != 0xFF ) break; + } + // The data is empty and don't need to be programmed. + if ( wNumBytes == wProgBytes ) break; + // update data to chipset SPI data transfer registers. + for ( wNumBytes = 0; wNumBytes < wProgBytes; wNumBytes++ ) { + for ( wRetry = 0; wRetry < 0x400; wRetry ++ ) { + *(volatile UINT8*)( gSPIBASE + SPI_DAT0 + wNumBytes ) = \ + *( Byte + wNumBytes ); + // verified for checking the data is correct. + if ( *( Byte + wNumBytes ) == \ + *(volatile UINT8*)( gSPIBASE + SPI_DAT0 + wNumBytes ) ) + break; + } + } + if (EFI_ERROR(CommonConvertSpiAddress( \ + (volatile UINT8*)pByteAddress, &dPhyAddress))) return; + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dPhyAddress; + // BIT14 - indicate that it's data cycle. + wSpiCmd = ( 1 << 14 ); + // BIT[8..13] - update the number of bytes to be written. + wSpiCmd += ( wProgBytes - 1 ) << 8; + // opcode index 0 is programmed for program command. + // Set BIT1 (Go), BIT2(Atomic w/ Prefix) + if (CheckAaiWordProram(dPhyAddress, wProgBytes)) + wSpiCmd += ( SPI_OPCODE_AAI_INDEX << 4) + BIT01 + BIT02; + else wSpiCmd += ( SPI_OPCODE_WRITE_INDEX << 4) + BIT01 + BIT02; + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for chipset SPI cycle completed. + WaitForSpiCycleDone(); + // wait for chipset SPI flash operation completed. + WaitForWriteOperationCompleted(); + // Issue SPI Write Disable if SST AAIWordProgram supported. + if (CheckAaiWordProram(dPhyAddress, wProgBytes)) SpiWriteDisable(); + // write operation appeared to succeed, now read back byte and compare + // set control for 1-byte data read, no prefix + for ( wNumBytes = 0; wNumBytes < wProgBytes; wNumBytes++ ) { + if (*(Byte + wNumBytes) != \ + CommonSpiReadByte((UINT32)(pByteAddress + wNumBytes))) break; + } + if ( wNumBytes == wProgBytes ) break; + } + // Don't forget to return the number of bytes not written + *Length = *Length - (UINT32)wProgBytes; + return; +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID CommonSpiReadCommand ( + IN volatile UINT8 *pByteAddress, + OUT UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT32 dReadAddress = 0; + UINT16 wSpiCmd, i, wMaxRead = 0; + + InitializeSpiEnvironment( &mExFlashPart.FlashCommandMenu ); + if (EFI_ERROR(CommonConvertSpiAddress( \ + (volatile UINT8*)pByteAddress, &dReadAddress))) return; + wMaxRead = 0x100 - (dReadAddress & 0xff); + if (wMaxRead > SPI_MAX_DATA_TRANSFER) wMaxRead = SPI_MAX_DATA_TRANSFER; + if (wMaxRead > *Length) wMaxRead = (UINT16)*Length; + // update the read address. + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dReadAddress; + // Opcode menu slot 1 is configured as "Read Flash" + wSpiCmd = ( SPI_OPCODE_READ_INDEX << 4 ) + BIT01; + // indicate that data phase is required + wSpiCmd += (1 << 14); + // BIT[8..13] - update the number of bytes to be read. + wSpiCmd += (wMaxRead - 1) << 8; + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // read data + for (i = 0; i < wMaxRead; i++) + *(Byte + i) = *(volatile UINT8*)(gSPIBASE + SPI_DAT0 + i); + *Length = *Length - (UINT32)wMaxRead; +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiIsEraseCompleted ( + IN volatile UINT8 *pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + // Check for Top Swap enabled + if (*(volatile UINT8*)(gRCBABASE + RCRB_MMIO_BUC) & BIT00) + bByte = CommonSpiReadByte((UINT32)(pBlockAddress + dNumBytes)); + else bByte = *(volatile UINT8*)(pBlockAddress + dNumBytes); + if (bByte != 0xFF) { + if ( pStatus ) *pStatus = EFI_NOT_READY; + if ( pError ) *pError = TRUE; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// Byte Last data byte written +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiIsProgramCompleted ( + IN volatile UINT8 *pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte, bReadByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = *(Byte + dNumBytes); + // Check for Top Swap enabled + if (*(volatile UINT8*)(gRCBABASE + RCRB_MMIO_BUC) & BIT00) + bReadByte = CommonSpiReadByte((UINT32)(pByteAddress + dNumBytes)); + else bReadByte = *(volatile UINT8*)(pByteAddress + dNumBytes); + if (bByte != bReadByte) { + if ( pStatus ) *pStatus = EFI_NOT_READY; + if ( pError ) *pError = TRUE; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} +// +//---------------------------------------------------------------------------- +// Procedure: SpiBlockProtectUpdate +// +// Description: This function writes the status register. +// +// Input: *pBlockAddress - Address within the block to write enable. +// bStatusData - Value to be written to Status Register. +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +SpiBlockProtectUpdate ( + IN volatile UINT8 *pBlockAddress, + IN UINT8 bStatusData +) +{ + UINT8 bStatusReg = 0, bPrefixOp, bDataPhase = 1, bBPbits; + UINT32 dSectorAddr = 0; + + if (EFI_ERROR(CommonConvertSpiAddress(pBlockAddress, &dSectorAddr))) return; + bStatusReg = CommonSpiReadStatus (dSectorAddr); + bPrefixOp = SPI_PREFIX_WRITE_EN; // Use Prefix 0 w/o address + switch ( (UINT8)mExFlashPart.FlashVenDevId ) { + case 0xBF : + // if SST flash, prefix 1 w/o address + if (mExFlashPart.GlobalBlockUnlock == TRUE) return; + bBPbits = (BIT02 + BIT03 + BIT04 + BIT05); + bPrefixOp = SPI_PREFIX_WRITE_S_EN; + break; + case 0x1F : + // if ATMEL flash, prefix 0 w/ address + bBPbits = (BIT02 + BIT03); + break; + case 0x20 : + // if MXIC flash, keep Quad Enable bit (BIT6) state. + bBPbits = (BIT02 + BIT03 + BIT04 + BIT06); + break; + default : + bBPbits = (BIT02 + BIT03 + BIT04); + } + bStatusReg &= bBPbits; // keep valid bits. + bStatusData &= bBPbits; // keep valid bits. + if (bStatusReg != bStatusData) { + CommonSpiWriteStatus ( bStatusData, \ + SPI_OPCODE_WRITE_S_INDEX, \ + bDataPhase, \ + bPrefixOp, \ + dSectorAddr ); + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: *pBlockAddress - Address within the block to write enable +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiBlockWriteEnable ( + IN volatile UINT8 *pBlockAddress +) +{ + SpiBlockProtectUpdate (pBlockAddress, 0); +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: *pBlockAddress - Address within the block to write disable +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiBlockWriteDisable ( + IN volatile UINT8 *pBlockAddress +) +{ +#if BLOCK_PROTECT_ENABLE + SpiBlockProtectUpdate (pBlockAddress, 0xff); +#endif +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiDeviceWriteEnable (VOID) +{ + // check is DeviceWrite enabled, if yes, don't enable it again, + // else, enable it. + if ( !gbDeviceWriteEnabled ) { + gbDeviceWriteEnabled = 1; + } +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiDeviceWriteDisable (VOID) +{ + // check is DeviceWrite enabled, if yes, disable it, + // if no, don't disable it. + if ( gbDeviceWriteEnabled ) { + gbDeviceWriteEnabled = 0; + } +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +CommonSpiDeviceVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + +//- SpiChipsetVirtualFixup(pRS); + pRS->ConvertPointer(0, (VOID **)&gSPIBASE); + pRS->ConvertPointer(0, (VOID **)&gRCBABASE); + gbDeviceVirtual = 1; + + return; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* \ No newline at end of file diff --git a/Board/Flash/SPI/ICHx/SpiCspSrc.cif b/Board/Flash/SPI/ICHx/SpiCspSrc.cif new file mode 100644 index 0000000..c32774f --- /dev/null +++ b/Board/Flash/SPI/ICHx/SpiCspSrc.cif @@ -0,0 +1,9 @@ + + name = "CSP : Intel ICHx SPI - Source" + category = ModulePart + LocalRoot = "Board\Flash\SPI\ICHx" + RefName = "ICHX_SPI_CSP_SOURCE" +[files] +"ICHxSpi.sdl" +"SPIFlash.c" + diff --git a/Board/Flash/SPI/SpiFlash.cif b/Board/Flash/SPI/SpiFlash.cif new file mode 100644 index 0000000..fef787f --- /dev/null +++ b/Board/Flash/SPI/SpiFlash.cif @@ -0,0 +1,14 @@ + + name = "SPI Interface - Source" + category = ModulePart + LocalRoot = "Board\Flash\SPI" + RefName = "SPI_INTERFACE_SOURCE" +[files] +"SpiFlash.sdl" +"SpiFlash.mak" +"SpiFlash.h" +"SpiIdentify.c" +[parts] +"DUMMY_SPI_CSP_SOURCE" +"ICHX_SPI_CSP_SOURCE" + diff --git a/Board/Flash/SPI/SpiFlash.h b/Board/Flash/SPI/SpiFlash.h new file mode 100644 index 0000000..9aca707 --- /dev/null +++ b/Board/Flash/SPI/SpiFlash.h @@ -0,0 +1,531 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2008, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/SpiFlash.h 2 4/24/13 11:10p Thomaschen $ +// +// $Revision: 2 $ +// +// $Date: 4/24/13 11:10p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/SpiFlash.h $ +// +// 2 4/24/13 11:10p Thomaschen +// +// 29 3/08/13 3:12a Calvinchen +// [TAG] EIP110515 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Microchip SST26VF064B & SST26VF064BA 8MB SPI Flash part +// support +// [RootCause] Need "Global Block Protection Unlock" before programming. +// [Solution] Added "Global Block Protection Unlock" before programming. +// [Files] SpiFlash.h +// SpiIdentify.c +// SpiFlash.cif +// +// 28 2/18/13 5:14a Calvinchen +// [TAG] EIP114488 +// [Category] Improvement +// [Description] 1. Added MXIC MX25U6435F SPI Flash part support +// 2. Added GigaDevice 25LQ series flash part. +// [Files] SpiFlash.h +// SpiIdentify.c +// +// 27 1/14/13 5:40a Calvinchen +// [TAG] EIP110515 +// [Category] Improvement +// [Description] Microchip SST26VF064B & SST26VF064BA 8MB SPI Flash part +// support +// [Files] SpiFlash.h +// SpiIdentify.c +// +// 26 12/13/12 2:22a Calvinchen +// Added support for winbond W25Q F and W series Flash Parts. +// +// 25 7/18/12 6:10a Calvinchen +// 1. Changed N25Q128 to 4K erase. +// 2. Added N25Q128A support. +// +// 24 10/31/11 6:46a Calvinchen +// [TAG] EIP68872 +// [Category] Improvement +// [Description] Added ESMT 25L64QA. +// [Files] SpiFlash.h +// SpiIdentify.c +// +// 23 8/24/11 7:58a Calvinchen +// Improvement : +// Added Token "FAST_READ_SUPPORT" for switching the SPI +// Read(03)/FastRead(0B)/DualOutputFastRead(3B) command. To use the +// FastRead and the Dual Output Fast Read command MUST have Hardware SPI +// support. **Only validated with Intel Mahobay platform (Southbridge: +// PatherPoint)** +// +// 22 7/21/11 5:07a Calvinchen +// [TAG] EIP65366 +// [Category] Improvement +// [Description] New SPI Flash supports for EON 25QH and ESMT 25L PA +// flash part. +// [Files] SpiFlash.h +// SpiIdentify.c +// +// 21 4/08/11 3:05a Chunweitseng +// [TAG] EIP57327 +// [Category] Improvement +// [Description] Added Support for FIDELIX FM25Q32A/64A and AMIC +// 25LQ032. +// +// [Files] SpiFlash.h, SpiIdentify.c +// +// 20 2/10/11 5:43a Calvinchen +// [TAG] EIP53437 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Corrected Numonyx M25P128 Minimum Sector Size to 256K. +// [RootCause] None. +// [Solution] None. +// [Files] SpiFlash.sdl +// SpiFlash.mak +// SpiFlash.h +// SpiIdentify.c +// SpiFlash.cif +// +// 19 11/30/10 3:28a Calvinchen +// Added Numonyx N25Q Series. +// +// 17 3/11/10 6:43a Calvinchen +// Improvement : Added SST AAIWordProgram SPI command to speed up the +// programming time. +// +// 16 1/07/10 5:34a Calvinchen +// Addes support for Spansion S25FL128/129P. +// +// 15 12/31/09 1:50a Klzhan +// Improvement : Support EON 25Q32/64. +// +// 14 12/23/09 6:13a Calvinchen +// Improvement:1.Added FWH/LPC/STD Flash Device Number support. +// +// 13 12/22/09 2:30a Calvinchen +// Added support for ATMEL 25DQ161. +// +// 12 12/16/09 3:45a Calvinchen +// +// 11 12/15/09 5:49a Calvinchen +// Improvement : +// 1.Added support for GigaDevie 25Q80/16. +// 2.Added Flash Chip Name support. +// +// 9 6/24/09 3:14a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 8 5/11/09 7:21a Calvinchen +// Added support for SST 25VF064C and MXIC MX25L1635/3235/6435.. +// +// 7 4/27/09 3:19a Calvinchen +// 1.Added support for Winbond 25Q128 +// 2.(EIP20459) Added Multiple SPI CSP component support. +// +// 6 12/10/08 5:53a Calvinchen +// Added support for Winbond W25Q80/16 1M/2M SPI flash. +// +// 5 9/30/08 10:09a Calvinchen +// According to Intel ICH7/ICH8/ICH9/ICH10 - SPI Family Flash Programming +// Guide Application Note - Rev#2.4, +// Section#5.3 Software Sequencing Opcode Requirements and +// Recommendations,It is strongly recommended that the "9Fh" JEDEC ID be +// used instead of "90h" or "AB". +// Intel utilities such as the Flash Programming tool (Fprog.exe and +// fpt.exe) will incorrectly detect the flash part in the system and it +// may lead to undesired program operation. +// +// 4 9/11/08 2:30a Calvinchen +// Added support for EON 25F32. +// +// 3 8/26/08 2:54a Calvinchen +// 1.Added support for AMTME 25DF641. +// 2.Fixed Fail to un-protect ATMEL flash. +// 3.Fixed building failed if $(CFLAGS) = /W4. +// +// 2 5/09/08 3:35a Calvinchen +// Added support for STM M25PF32. +// +// 1 3/13/08 6:31a Calvinchen +// +// 12 3/05/08 9:11a Robert +// +// 11 2/13/08 6:14p Robert +// +// 2 2/13/08 6:03p Robert +// coding updates and addition of Intel SPI part +// +// 10 1/07/08 3:05p Robert +// updated for coding standard +// +// 9 1/02/08 12:04p Robert +// Added the MX25L1605 device ID +// +// 8 11/09/07 3:49p Alexp +// Added SPI opcode Read Index +// +// 7 10/24/07 4:23p Robert +// Needed to add a function prototype for SpiTransfer() +// +// 6 10/09/07 1:11p Robert +// added a new VID/DID and cleaned up other additions of parts +// +// 5 10/01/07 4:19a Klzhan +// Added support for AMIC A25L080 , MXIC 25L6405 25L3205 , ST 25P32 . +// +// 4 8/20/07 2:22p Robert +// Added support for Atmel AT26DF321 and for winbond w25x32 parts +// +// 3 8/02/07 2:51p Artems +// Added support Atmel 1MB +// +// 2 2/20/07 6:44p Robert +// removed some unneeded definitions and added a few new ones +// +// 1 12/18/06 3:39p Robert +// Initial Check in +// +// 2 11/16/06 6:27p Robert +// removed unused definition +// +// 1 10/31/06 2:30p Sivagarn +// Initial Checkin +// +// +//********************************************************************** +// +// +// Name: SpiFlash.h +// +// Description: Contains Vendor IDs and Device IDs for ths supported +// parts. also contains the command values for each supported part +// +// +//********************************************************************** + +#ifndef _SPIFlash_H_ +#define _SPIFlash_H_ + + +#include +#include "Board\Sb\Sb.h" + + +VOID SpiFlashLock(UINT16 MfgDevId, BOOLEAN Lock); + + +//------------------------------------------------------------------- +// Supported SPI devices +// MFG and Device code +#define SST_25LF040A 0x44bf +#define SST_25LF040 0x40bf +#define SST_25LF080A 0x80bf + +#define SST_25VF040B 0x8dbf +#define SST_25VF080B 0x8ebf +#define SST_25VF016B 0x41bf +#define SST_25VF032B 0x4abf +#define SST_25VFxxx_ID 0x25bf +#define SST_26VFxxx_ID 0x26bf + + +//PMC 25LVxxx Device ID/Manufacturer ID +#define PMC_25LV040 0x7e9d +#define PMC_25LVxxx_ID 0x9d7f + +#define ATMEL_26DF041 0x441f +#define ATMEL_26DF081 0x451f +#define ATMEL_26DF161 0x461f +#define ATMEL_26DF321 0x471f // ATMEL 26DF321 32Mbit +#define ATMEL_25DF641 0x481f // ATMEL 25DF641 64Mbit +#define ATMEL_25DQ161 0x861f + +//Winbond W25Xxx Device ID/Manufacturer ID +#define WINBOND_W25X10 0x10ef +#define WINBOND_W25X20 0x11ef +#define WINBOND_W25X40 0x12ef +#define WINBOND_W25X80 0x13ef +#define WINBOND_W25X16 0x14ef +#define WINBOND_25Xxx_ID 0x30ef +#define WINBOND_25Qxx_ID 0x40ef +#define WINBOND_25QxxW_ID 0x50ef +#define WINBOND_25QxxF_ID 0x60ef + +// MXIC Device ID/Manufacturer ID +#define MX25L4005_DEVICE_ID 0x13c2 +#define MX25L8005_DEVICE_ID 0x14c2 +#define MX25L1605_DEVICE_ID 0x15c2 +#define MX25L3205_DEVICE_ID 0x16c2 +#define MX25L6405_DEVICE_ID 0x17c2 +#define MXIC_25Lxxxx_ID 0x20c2 +#define MXIC_25Lxx35_ID 0x24c2 +#define MXIC_25Lxx36_ID 0x5ec2 +#define MXIC_25Uxx35_ID 0x25c2 + +// Spansion S25FL008A Device ID/Manufacturer ID +#define SPANSION_25FL004A 0x1201 +#define SPANSION_25FL008A 0x1301 +#define SPANSION_25FLxxx_ID 0x0201 +#define SPANSION_25FLxxxP_ID 0x2001 + +// ESMT F25L00xA Device ID/Manufacturer ID +#define ESMT_25L004A 0x128c +#define ESMT_25L008A 0x138c +#define ESMT_25L016A 0x148c +#define ESMT_25L032A 0x158c +#define ESMT_25LxxxT_ID 0x208c +#define ESMT_25LxxxB_ID 0x218c +#define ESMT_25Lxx_ID 0x408c +#define ESMT_25LxxQ_ID 0x418c + +// ST Micro/Micron/Numonyx M25Pxx Device ID/Manufacturer ID +#define STM_M25P40 0x1320 +#define STM_M25P80 0x1420 +#define STM_M25P32 0x2020 +#define STM_25PExx_ID 0x8020 +#define STM_25PXxx_ID 0x7120 // M25PX16/32 +#define STM_25PFxx_ID 0x7020 // M25PF32 +#define STM_25Pxx_ID 0x2020 // M25P16/32/64 +#define Numonyx_25Qxx_ID 0xBA20 // N25Q16/32/64/128 +#define Numonyx_25QxxA_ID 0xBB20 // N25Q16/32/64/128 + +// AMIC 25Lxx Device ID/Manufacturer ID +#define AMIC_25Lxx_ID 0x377f +#define AMIC_25Lxxx_ID 0x3037 +#define AMIC_25LQxxx_ID 0x4037 + +// EON 25P/Fxx Device ID/Manufacturer ID +#define EON_25Fxx_ID 0x311c +#define EON_25Pxx_ID 0x201c +#define EON_25Qxx_ID 0x301c +#define EON_25QHxx_ID 0x701c + +// INTEL 25Fxxx Device ID/Manufacturer ID +#define INTEL_25Fxxx_ID 0x8989 +#define INTEL_25Fxxx_ID 0x8989 + +// Giga Device GD25Qxx Device ID/Manufacturer ID +#define GD_25Qxx_ID 0x40C8 +#define GD_25LQxx_ID 0x60C8 + +// FIDELIX Device FM_25Qxx Device ID/Manufacturer ID +#define FM_25Qxx_ID 0x32F8 + +//------------------------------------------------------------------- +// NOTE: Assuming that 8Mbit flash will only contain a 4Mbit binary. +// Treating 4Mbit and 8Mbit devices the same. + +//------------------------------------------------------------------- +// BIOS Base Address +#define BIOS_BASE_ADDRESS_4M 0xfff80000 +#define BIOS_BASE_ADDRESS_8M 0xfff00000 + +//------------------------------------------------------------------- +// block and sector sizes +#define SECTOR_SIZE_256B 0x100 // 4kBytes sector size +#define SECTOR_SIZE_4KB 0x1000 // 4kBytes sector size +#define SECTOR_SIZE_8KB 0x2000 // 8kbytes sector size +#define SECTOR_SIZE_64KB 0x10000 // 64kBytes sector size +#define SECTOR_SIZE_256KB 0x40000 // 256kBytes sector size +#define BLOCK_SIZE_32KB 0x8000 // 32Kbytes block size + +//------------------------------------------------------------------- +// Flash commands + +// Commands for SST 25LFxx and 25VFxx parts +#define SPI_SST25LF_COMMAND_WRITE 0x02 +#define SPI_SST25LF_COMMAND_READ 0x03 +#if FAST_READ_SUPPORT == 0 +#define SPI_SST25VF_COMMAND_READ 0x03 // Read Byte +#elif FAST_READ_SUPPORT == 1 +#define SPI_SST25VF_COMMAND_READ 0x0B // Fast Read +#elif FAST_READ_SUPPORT == 2 +#define SPI_SST25VF_COMMAND_READ 0x3B // Dual Output Fast Read +#endif +#define SPI_SST25LF_COMMAND_ERASE 0x20 +#define SPI_SST25LF_COMMAND_WRITE_DISABLE 0x04 +#define SPI_SST25LF_COMMAND_READ_STATUS 0x05 +#define SPI_SST25LF_COMMAND_WRITE_ENABLE 0x06 +//#define SPI_SST25LF_COMMAND_READ_ID 0xab +#define SPI_SST25LF_COMMAND_READ_ID 0x90 +#define SPI_SST25VF_COMMAND_READ_ID 0x9f +#define SPI_SST25LF_COMMAND_WRITE_S_EN 0x50 +#define SPI_SST25LF_COMMAND_WRITE_S 0x01 + +// PMC commands +#define SPI_PMC25LV_COMMAND_WRITE 0x02 +#define SPI_PMC25LV_COMMAND_READ 0x03 +#define SPI_PMC25LV_COMMAND_ERASE 0xd7 +#define SPI_PMC25LV_COMMAND_WRITE_DISABLE 0x04 +#define SPI_PMC25LV_COMMAND_READ_STATUS 0x05 +#define SPI_PMC25LV_COMMAND_WRITE_ENABLE 0x06 +#define SPI_PMC25LV_COMMAND_READ_ID 0xab +#define SPI_PMC25LV_COMMAND_WRITE_S_EN 0x06 +#define SPI_PMC25LV_COMMAND_WRITE_S 0x01 + +// Atmel commands +#define SPI_AT26DF_COMMAND_WRITE 0x02 +#if FAST_READ_SUPPORT == 0 +#define SPI_AT26DF_COMMAND_READ 0x03 // Read Byte +#elif FAST_READ_SUPPORT == 1 +#define SPI_AT26DF_COMMAND_READ 0x0B // Fast Read +#elif FAST_READ_SUPPORT == 2 +#define SPI_AT26DF_COMMAND_READ 0x3B // Dual Output Fast Read +#endif +#define SPI_AT26DF_COMMAND_ERASE 0x20 +#define SPI_AT26DF_COMMAND_WRITE_DISABLE 0x04 +#define SPI_AT26DF_COMMAND_READ_STATUS 0x05 +#define SPI_AT26DF_COMMAND_WRITE_ENABLE 0x06 +#define SPI_AT26DF_COMMAND_READ_ID 0x9f +#define SPI_AT26DF_COMMAND_WRITE_S_EN 0x00 +#define SPI_AT26DF_COMMAND_WRITE_S 0x01 +// ATMEL 26DF321 32Mbit SPI Flash part support +#define SPI_AT26DF_COMMAND_PROTECT 0x36 +#define SPI_AT26DF_COMMAND_UNPROTECT 0x39 + +// Winbond W25Xxx serial flash commands +#define SPI_WIN_W25X_COMMAND_WRITE 0x02 // page program +#define SPI_WIN_W25X_COMMAND_READ 0x03 // Read Byte +#define SPI_WIN_W25X_COMMAND_ERASE 0x20 // erase 4K sectors +#define SPI_WIN_W25X_COMMAND_WRITE_DISABLE 0x04 // Write Disable +#define SPI_WIN_W25X_COMMAND_READ_STATUS 0x05 // read Status Register +#define SPI_WIN_W25X_COMMAND_WRITE_ENABLE 0x06 // Write Enable +#define SPI_WIN_W25X_COMMAND_READ_ID 0x90 // Manufacturer/Device ID +#define SPI_WIN_W25X_COMMAND_WRITE_S 0x01 // Write Status register + +// MXIC MX25Lx005 commands +#define SPI_MXIC_M25L_COMMAND_WRITE 0x02 // page program +#define SPI_MXIC_M25L_COMMAND_READ 0x03 // Read Byte +#define SPI_MXIC_M25L_COMMAND_ERASE 0x20 // erase 4K sectors +#define SPI_MXIC_M25L_COMMAND_WRITE_DISABLE 0x04 // Write Disable +#define SPI_MXIC_M25L_COMMAND_READ_STATUS 0x05 // read Status Register +#define SPI_MXIC_M25L_COMMAND_WRITE_ENABLE 0x06 // Write Enable +#define SPI_MXIC_M25L_COMMAND_READ_ID 0x9f // Manufacturer/Device ID +#define SPI_MXIC_M25L_COMMAND_WRITE_S 0x01 // Write Status register + +// Spansion S25FL00xA commands +#define SPI_S25FL00xA_COMMAND_WRITE 0x02 // page program +#define SPI_S25FL00xA_COMMAND_READ 0x03 // Read Byte +#define SPI_S25FL00xA_COMMAND_ERASE 0xd8 // erase 64K sectors +#define SPI_S25FL00xA_COMMAND_WRITE_DISABLE 0x04 // Write Disable +#define SPI_S25FL00xA_COMMAND_READ_STATUS 0x05 // read Status Register +#define SPI_S25FL00xA_COMMAND_WRITE_ENABLE 0x06 // Write Enable +#define SPI_S25FL00xA_COMMAND_READ_ID 0x9f // Manufacturer/Device ID +#define SPI_S25FL00xA_COMMAND_WRITE_S 0x01 // Write Status register + +// ESMT F25L00xA commands +#define SPI_ESMT_F25L00x_COMMAND_WRITE 0x02 // page program +#define SPI_ESMT_F25L00x_COMMAND_READ 0x03 // Read Byte +#define SPI_ESMT_F25L00x_COMMAND_ERASE 0x20 // erase 4K sectors +#define SPI_ESMT_F25L00x_COMMAND_WRITE_DISABLE 0x04 // Write Disable +#define SPI_ESMT_F25L00x_COMMAND_READ_STATUS 0x05 // read Status Register +#define SPI_ESMT_F25L00x_COMMAND_WRITE_ENABLE 0x06 // Write Enable +#define SPI_ESMT_F25L00x_COMMAND_READ_ID 0x90 // Manufacturer/Device ID +#define SPI_ESMT_F25L00x_COMMAND_WRITE_S_EN 0x50 // Write Status Enable register +#define SPI_ESMT_F25L00x_COMMAND_WRITE_S 0x01 // Write Status register + +// ST Micro M25Pxx commands +#define SPI_M25Pxx_COMMAND_WRITE 0x02 // page program +#define SPI_M25Pxx_COMMAND_READ 0x03 // Read Byte +#define SPI_M25Pxx_COMMAND_ERASE 0xd8 // erase 64K sectors +#define SPI_M25Pxx_COMMAND_WRITE_DISABLE 0x04 // Write Disable +#define SPI_M25Pxx_COMMAND_READ_STATUS 0x05 // read Status Register +#define SPI_M25Pxx_COMMAND_WRITE_ENABLE 0x06 // Write Enable +#define SPI_M25Pxx_COMMAND_READ_ID 0x9f // Manufacturer/Device ID +#define SPI_M25Pxx_COMMAND_WRITE_S 0x01 // Write Status register + +// ST Micro M25Pxx commands +#define SPI_M25PExx_COMMAND_WRITE 0x02 // page program +#if FAST_READ_SUPPORT == 0 +#define SPI_M25PExx_COMMAND_READ 0x03 // Read Byte +#elif FAST_READ_SUPPORT == 1 +#define SPI_M25PExx_COMMAND_READ 0x0B // Fast Read +#elif FAST_READ_SUPPORT == 2 +#define SPI_M25PExx_COMMAND_READ 0x3B // Dual Output Fast Read +#endif +#define SPI_M25PExx_COMMAND_ERASE 0xD8 // erase 64K sectors +#define SPI_M25PExx_COMMAND_PAGE_ERASE 0xDB // erase 256 byte pages +#define SPI_M25PExx_COMMAND_WRITE_DISABLE 0x04 // Write Disable +#define SPI_M25PExx_COMMAND_READ_STATUS 0x05 // read Status Register +#define SPI_M25PExx_COMMAND_WRITE_ENABLE 0x06 // Write Enable +#define SPI_M25PExx_COMMAND_READ_ID 0x9F // Manufacturer/Device ID +#define SPI_M25PExx_COMMAND_WRITE_S 0x01 // Write Status register + + +//#define SECTOR_SIZE_4KB 0x1000 // Common 4kBytes sector size +//#define SECTOR_SIZE_64KB 0x10000 // Common 64kBytes sector size +#define BLOCK_SIZE_64KB 0x00010000 // Common 64kBytes block size +#define MAX_FWH_SIZE 0x00100000 // 8Mbit (Note that this can also be used for the 4Mbit ) + + +extern const UINT8 SpiMaxTransfer; + +// SPI default opcode slots +extern const UINT8 SpiOpcodeWriteIndex; +extern const UINT8 SpiOpcodeReadIndex; +extern const UINT8 SpiOpcodeEraseIndex; +extern const UINT8 SpiOpcodeWriteStatusIndex; + +#endif + +// +//============================================================================ +// Structure: EX_FLASH_PART +// +// Description: This structure contains variables that define the detals and +// and command set of flash part. +// +// Fields: +// FlashCommandMenu - FLASH_INFO - Defines the flash part command sets. +// FlashCapacity - UINT32 - Defines the Capacity of flash part. +// FlashVenDevId - UINT32 - Defines the Vendor and Device ID of flash part. +// DeviceName - UINT8 * - Pointer to a buffer that can contain the part +// number of flash part (Reserved for future used). +// +// Referral: +// None +//============================================================================ +// +#pragma pack(push, 1) + +typedef struct _EX_FLASH_PART { + FLASH_INFO FlashCommandMenu; + UINT32 FlashCapacity; + UINT32 FlashVenDevId; + UINT8 AAIWordProgram; + UINT8 GlobalBlockUnlock; + UINT8 bReserved[2]; +} EX_FLASH_PART; + +#pragma pack(pop) +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2008, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Board/Flash/SPI/SpiFlash.mak b/Board/Flash/SPI/SpiFlash.mak new file mode 100644 index 0000000..33003e8 --- /dev/null +++ b/Board/Flash/SPI/SpiFlash.mak @@ -0,0 +1,115 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* +#********************************************************************** +# $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/SpiFlash.mak 2 4/24/13 11:11p Thomaschen $ +# +# $Revision: 2 $ +# +# $Date: 4/24/13 11:11p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/SpiFlash.mak $ +# +# 2 4/24/13 11:11p Thomaschen +# +# 5 10/25/10 5:55a Calvinchen +# Added support for PEI Flash Library. +# +# 4 6/24/09 3:14a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# 3 4/27/09 3:19a Calvinchen +# 1.Added support for Winbond 25Q128 +# 2.(EIP20459) Added Multiple SPI CSP component support. +# +# 2 8/26/08 2:54a Calvinchen +# 1.Added support for AMTME 25DF641. +# 2.Fixed Fail to un-protect ATMEL flash. +# 3.Fixed building failed if $(CFLAGS) = /W4. +# +# 1 3/13/08 6:31a Calvinchen +# +# 1 12/18/06 3:39p Robert +# Initial Check in +# +# 1 10/31/06 2:30p Sivagarn +# Initial Checkin +# +# +#********************************************************************** + + +# +# +# Name: FlashSrc.mak +# +# Description: +# +# +#********************************************************************** +all : SPIFlash + +!IFNDEF SPI_CSP_DIR +SPI_CSP_DIR = $(SPIFlash_DIR)\Template +!ENDIF +SPIFlash : $(BUILD_DIR)\SPIFlash.mak SPIFlashBin + +#--------------------------------------------------------------------------- +# Generic SPIFLASH dependencies +#--------------------------------------------------------------------------- +$(BUILD_DIR)\SPIFlash.mak : $(SPIFlash_DIR)\$(@B).cif $(SPI_CSP_DIR)\SpiCspSrc.cif $(SPIFlash_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SPIFlash_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) $(SPI_CSP_DIR)\SpiCspSrc.cif + +#--------------------------------------------------------------------------- +# Create SPIFlash Library +#--------------------------------------------------------------------------- +SPI_INCLUDES = \ +/I $(SPIFlash_DIR) + +SPIFLASH_OBJECTS = $(BUILD_DIR)\$(SPIFlash_DIR)\SpiIdentify.obj \ + $(BUILD_DIR)\$(SPI_CSP_DIR)\SpiFlash.obj + +SPIFlashBin : + @set INCLUDE=%%INCLUDE%% + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SPIFlash.mak all\ + "CFLAGS=$(CFLAGS:/W4=/W3) $(SPI_INCLUDES)"\ + NAME=SPIFlash \ + OBJECTS="$(SPIFLASH_OBJECTS)" \ + TYPE=LIBRARY LIBRARY_NAME=$(SPIFLASHLIB) +!IF "$(x64_BUILD)"=="1" && "$(BUILD_PEI_FLASH_LIB)"=="1" + $(MAKE) /$(MAKEFLAGS) BUILD_ROOT=$(BUILD_DIR)\ + "EXT_OBJS=$(**:Build\=Build\IA32\)" PROJECT_DIR=$(PROJECT_DIR)\ + /f $(BUILD_DIR)\SPIFlash.mak all\ + "CFLAGS=$(CFLAGS:/W4=/W3) $(SPI_INCLUDES)"\ + BUILD_DIR=$(BUILD_DIR)\IA32\ + TYPE=PEI_LIBRARY NAME=SPIFlash +!ENDIF + +$(SPIFLASHLIB) : SPIFlash + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Board/Flash/SPI/SpiFlash.sdl b/Board/Flash/SPI/SpiFlash.sdl new file mode 100644 index 0000000..aa4b757 --- /dev/null +++ b/Board/Flash/SPI/SpiFlash.sdl @@ -0,0 +1,232 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* +#********************************************************************** +# $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/SpiFlash.sdl 2 4/24/13 11:11p Thomaschen $ +# +# $Revision: 2 $ +# +# $Date: 4/24/13 11:11p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/SpiFlash.sdl $ +# +# 2 4/24/13 11:11p Thomaschen +# +# 8 4/27/12 5:12a Calvinchen +# [TAG] EIP86044 +# [Category] Improvement +# [Description] [Pegatron-DT] SMIFlash module update for display SPIROM +# size in AFU +# [Files] SpiFlash.sdl +# SpiIdentify.c +# +# 7 8/24/11 7:58a Calvinchen +# Improvement : +# Added Token "FAST_READ_SUPPORT" for switching the SPI +# Read(03)/FastRead(0B)/DualOutputFastRead(3B) command. To use the +# FastRead and the Dual Output Fast Read command MUST have Hardware SPI +# support. **Only validated with Intel Mahobay platform (Southbridge: +# PatherPoint)** +# +# 6 2/10/11 5:43a Calvinchen +# [TAG] EIP53437 +# [Category] Bug Fix +# [Severity] Minor +# [Symptom] Corrected Numonyx M25P128 Minimum Sector Size to 256K. +# [RootCause] None. +# [Solution] None. +# [Files] SpiFlash.sdl +# SpiFlash.mak +# SpiFlash.h +# SpiIdentify.c +# SpiFlash.cif +# +# 5 10/25/10 5:55a Calvinchen +# Added support for PEI Flash Library. +# +# 4 6/24/09 3:14a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# +#********************************************************************** +TOKEN + Name = "SPIFlash_SUPPORT" + Value = "1" + Help = "Main switch to enable SPI Flash support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "SPIFLASHLIB" + Value = "$(BUILD_DIR)\SPIFlash.lib" + TokenType = Expression + TargetMAK = Yes +End + +TOKEN + Name = "SST_25VFxxx" + Value = "1" + Help = "Support for SST 25VF series and ESMT SPI flash parts." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "SST_25LFxxx" + Value = "1" + Help = "Support for SST 25LF040, 25LF080A SPI flash parts." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "STM_25PExx" + Value = "1" + Help = "Support for ST-Micro, SPANSION, Winbond, PMC, Eon, AMIC, MXIC and Intel SPI flash parts." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "ATMEL_26DFxxx" + Value = "1" + Help = "Support for ATMEL SPI flash parts." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "Numonyx_M25P128" + Value = "0" + Help = "Support for Numonyx M25P128 SPI flash parts." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "FLASH_BLOCK_SIZE" + Value = "0x40000" + Help = "Size of the Flash Device Block" + TokenType = Integer + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Lock = Yes + Token = "Numonyx_M25P128" "=" "1" +End + +TOKEN + Name = "SPI_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "FAST_READ_SUPPORT" + Value = "0" + Help = "Fast Read Support(Need Hardware SPI Support). 0 - Read(03), 1 - Fast Read(0B), 2 - Dual Output Fast Read(3B)." + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "AAI_WORD_PROGRAM" + Value = "0" + Help = "AAI Word Program Support(SST/PCT only)." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "BLOCK_PROTECT_ENABLE" + Value = "0" + Help = "Support for enabling the softwaft block protect mode. ON : set BP 0,1,2 of flash status register." + TokenType = Boolean + TargetH = Yes +End + +PATH + Name = "SPIFlash_DIR" +End + +MODULE + Help = "Includes FlashSrc.mak to Project" + File = "SPIFlash.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SPIFlash.lib" + Parent = "$(Flash_DIR)\SPIFlash.lib" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(Flash_DIR)\SPIFlash.lib" + Parent = "FLASHLISTLIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "IdentifySst_25VF," + Parent = "FlashList" + Token = "SST_25VFxxx" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "IdentifyStm_25PExx," + Parent = "FlashList" + Token = "STM_25PExx" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "IdentifyAtmel_26DF," + Parent = "FlashList" + Token = "ATMEL_26DFxxx" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "IdentifySst_25LF," + Parent = "FlashList" + Token = "SST_25LFxxx" "=" "1" + InvokeOrder = AfterParent +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Board/Flash/SPI/SpiIdentify.c b/Board/Flash/SPI/SpiIdentify.c new file mode 100644 index 0000000..fd0d37f --- /dev/null +++ b/Board/Flash/SPI/SpiIdentify.c @@ -0,0 +1,865 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/SpiIdentify.c 2 4/24/13 11:11p Thomaschen $ +// +// $Revision: 2 $ +// +// $Date: 4/24/13 11:11p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Board/Flash/SPI/SpiIdentify.c $ +// +// 2 4/24/13 11:11p Thomaschen +// +// 37 3/08/13 3:12a Calvinchen +// [TAG] EIP110515 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Microchip SST26VF064B & SST26VF064BA 8MB SPI Flash part +// support +// [RootCause] Need "Global Block Protection Unlock" before programming. +// [Solution] Added "Global Block Protection Unlock" before programming. +// [Files] SpiFlash.h +// SpiIdentify.c +// SpiFlash.cif +// +// 36 2/18/13 5:15a Calvinchen +// [TAG] EIP114488 +// [Category] Improvement +// [Description] 1. Added MXIC MX25U6435F SPI Flash part support +// 2. Added GigaDevice 25LQ series flash part. +// [Files] SpiFlash.h +// SpiIdentify.c +// +// 35 1/14/13 5:40a Calvinchen +// [TAG] EIP110515 +// [Category] Improvement +// [Description] Microchip SST26VF064B & SST26VF064BA 8MB SPI Flash part +// support +// [Files] SpiFlash.h +// SpiIdentify.c +// +// 34 12/13/12 2:23a Calvinchen +// Added support for winbond W25Q F and W series Flash Parts. +// +// 33 10/18/12 3:29a Calvinchen +// Improvement: +// 1. Changed N25Q128 to 4K erase. +// 2. Added N25Q128A support. +// Bug Fixed :1. Fixed for ESMT 25L B Series. +// +// 32 7/18/12 6:10a Calvinchen +// 1. Changed N25Q128 to 4K erase. +// 2. Added N25Q128A support. +// +// 31 4/27/12 5:12a Calvinchen +// [TAG] EIP86044 +// [Category] Improvement +// [Description] [Pegatron-DT] SMIFlash module update for display SPIROM +// size in AFU +// [Files] SpiFlash.sdl +// SpiIdentify.c +// +// 30 4/02/12 1:41a Klzhan +// [TAG] EIP86044 +// [Category] Improvement +// [Description] Customized AFU to support a parameter to display the +// current SPI's name and size +// +// 29 10/31/11 6:46a Calvinchen +// [TAG] EIP68872 +// [Category] Improvement +// [Description] Added ESMT 25L64QA. +// [Files] SpiFlash.h +// SpiIdentify.c +// +// 28 8/24/11 7:58a Calvinchen +// Improvement : +// Added Token "FAST_READ_SUPPORT" for switching the SPI +// Read(03)/FastRead(0B)/DualOutputFastRead(3B) command. To use the +// FastRead and the Dual Output Fast Read command MUST have Hardware SPI +// support. **Only validated with Intel Mahobay platform (Southbridge: +// PatherPoint)** +// +// 27 8/02/11 12:05a Calvinchen +// [TAG] EIP48934 +// [Category] Improvement +// [Description] Missing support for flash device Numonyx NX25Q064 on +// Sugarbay platform +// [Files] SpiIdentify.c +// +// 26 7/21/11 5:07a Calvinchen +// [TAG] EIP65366 +// [Category] Improvement +// [Description] New SPI Flash supports for EON 25QH and ESMT 25L PA +// flash part. +// [Files] SpiFlash.h +// SpiIdentify.c +// +// 25 4/08/11 3:08a Chunweitseng +// [TAG] EIP57327 +// [Category] Improvement +// [Description] Added Support for FIDELIX FM25Q32A/64A and AMIC +// 25LQ032. +// +// [Files] SpiFlash.h, SpiIdentify.c +// +// 24 2/17/11 3:36a Klzhan +// Add support 64K flash. +// +// 23 2/10/11 5:43a Calvinchen +// [TAG] EIP53437 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Corrected Numonyx M25P128 Minimum Sector Size to 256K. +// [RootCause] None. +// [Solution] None. +// [Files] SpiFlash.sdl +// SpiFlash.mak +// SpiFlash.h +// SpiIdentify.c +// SpiFlash.cif +// +// 22 11/25/10 3:02a Calvinchen +// Added Support for Micron/Numonyx N25Q128. +// +// 19 9/14/10 3:31a Calvinchen +// Improved for adding the "SPI_INITIALIAL_WITH_VSCC" token support for +// Intel ICHx SPI. +// +// 18 5/21/10 2:13a Calvinchen +// Bug fixed: Build failed with "undeclared identifier". +// +// 17 3/11/10 6:43a Calvinchen +// Improvement : Added SST AAIWordProgram SPI command to speed up the +// programming time. +// +// 16 1/07/10 5:34a Calvinchen +// Addes support for Spansion S25FL128/129P. +// +// 15 12/31/09 1:50a Klzhan +// Improvement : Support EON 25Q32/64. +// +// 14 12/23/09 6:13a Calvinchen +// Improvement:1.Added FWH/LPC/STD Flash Device Number support. +// +// 13 12/22/09 2:30a Calvinchen +// Added support for ATMEL 25DQ161. +// +// 12 12/15/09 5:49a Calvinchen +// Improvement : +// 1.Added support for GigaDevie 25Q80/16. +// 2.Added Flash Chip Name support. +// +// 10 6/24/09 3:14a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 9 5/11/09 7:21a Calvinchen +// Added support for SST 25VF064C and MXIC MX25L1635/3235/6435.. +// +// 7 3/12/09 4:47a Calvinchen +// Improvement : Added Unprotect Command OpCode (39h) to AMTEL SPI +// FLASH_INFO structure. +// Bug Fixed : Sometimes failed to unlock the Block Protect of SST SPI +// flash if Label "4.6.3_Flash_Combined_2_6" or later. +// +// 6 12/10/08 5:53a Calvinchen +// Added support for Winbond W25Q80/16 1M/2M SPI flash. +// +// 5 9/30/08 10:09a Calvinchen +// According to Intel ICH7/ICH8/ICH9/ICH10 - SPI Family Flash Programming +// Guide Application Note - Rev#2.4, +// Section#5.3 Software Sequencing Opcode Requirements and +// Recommendations,It is strongly recommended that the "9Fh" JEDEC ID be +// used instead of "90h" or "AB". +// Intel utilities such as the Flash Programming tool (Fprog.exe and +// fpt.exe) will incorrectly detect the flash part in the system and it +// may lead to undesired program operation. +// +// 4 9/11/08 2:30a Calvinchen +// Added support for EON 25F32. +// +// 3 8/26/08 2:54a Calvinchen +// 1.Added support for AMTME 25DF641. +// 2.Fixed Fail to un-protect ATMEL flash. +// 3.Fixed building failed if $(CFLAGS) = /W4. +// +// 2 5/09/08 3:35a Calvinchen +// Added support for STM M25PF32. +// +// 1 3/13/08 6:31a Calvinchen +// +// 7 3/26/07 7:22p Robert +// Coding standard updates +// +// 6 2/20/07 6:45p Robert +// added support for the new sector size variable in the data structure +// and added support for the changed lock functionality +// +// 5 2/13/07 3:45p Robert +// added support for SST 25VF016B and fixed a coding error in one of the +// identify functions prototype +// +// 4 2/13/07 11:30a Robert +// +// 1 12/18/06 3:39p Robert +// Initial Check in +// +// +//********************************************************************** +// +// +// Name: SpiIdentify.c +// +// Description: Provides device specific indentify functions for the +// supported spi parts +// +// +//********************************************************************** + +//---------------------------------------------------------------------------- +// Includes +#include +#include +#include "FlashPart.h" +#include "SpiFlash.h" +#include "token.h" +//---------------------------------------------------------------------------- +// Local defines for transaction types +#ifndef SPI_OPCODE_TYPE_READ_NO_ADDRESS +#define SPI_OPCODE_TYPE_READ_NO_ADDRESS 0x0 +#define SPI_OPCODE_TYPE_WRITE_NO_ADDRESS 0x1 +#define SPI_OPCODE_TYPE_READ_WITH_ADDRESS 0x2 +#define SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS 0x3 +#endif +//---------------------------------------------------------------------------- +// Module level global data +UINT32 MfgDevId = 0; +extern UINT16 gFlashId; +extern FLASH_PART mCommonSpiFlash; +extern EX_FLASH_PART mExFlashPart; +extern UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; +//---------------------------------------------------------------------------- +// Extern Function Prototypes +extern +BOOLEAN +CommonSpiReadId ( + FLASH_INFO *FlashInfo, + UINT32 *dFlashId +); +extern +VOID +ReinitializeSpiEnvironment ( + FLASH_INFO *FlashInfo +); +//---------------------------------------------------------------------------- +// Flash Part Data Structures +FLASH_INFO Sst_25VF = + { + // Write Byte + {SPI_SST25LF_COMMAND_WRITE, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS}, + // Read Data + {SPI_SST25VF_COMMAND_READ, SPI_OPCODE_TYPE_READ_WITH_ADDRESS}, + // Erase 4k Sector + {SPI_SST25LF_COMMAND_ERASE, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS}, + // Read Device Status Reg + {SPI_SST25LF_COMMAND_READ_STATUS, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Read device ID + {SPI_SST25VF_COMMAND_READ_ID, SPI_OPCODE_TYPE_READ_WITH_ADDRESS}, + // Write Status Register + {SPI_SST25LF_COMMAND_WRITE_S, SPI_OPCODE_TYPE_WRITE_NO_ADDRESS}, + // Write Status Enable + {SPI_SST25LF_COMMAND_WRITE_S_EN, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Write Enable + {SPI_SST25LF_COMMAND_WRITE_ENABLE, SPI_OPCODE_TYPE_WRITE_NO_ADDRESS}, + 1, // Page Size + SECTOR_SIZE_4KB + }; + +FLASH_INFO Sst_25LF = + { + // Write Byte + {SPI_SST25LF_COMMAND_WRITE, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS}, + // Read Data + {SPI_SST25LF_COMMAND_READ, SPI_OPCODE_TYPE_READ_WITH_ADDRESS}, + // Erase 4k Sector + {SPI_SST25LF_COMMAND_ERASE, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS}, + // Read Device Status Reg + {SPI_SST25LF_COMMAND_READ_STATUS, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Read device ID + {SPI_SST25LF_COMMAND_READ_ID, SPI_OPCODE_TYPE_READ_WITH_ADDRESS}, + // Write Status Register + {SPI_SST25LF_COMMAND_WRITE_S, SPI_OPCODE_TYPE_WRITE_NO_ADDRESS}, + // Write Status Enable + {SPI_SST25LF_COMMAND_WRITE_S_EN, SPI_OPCODE_TYPE_WRITE_NO_ADDRESS}, + // Write Enable + {SPI_SST25LF_COMMAND_WRITE_ENABLE, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + 1, // Page Size + SECTOR_SIZE_4KB + }; + +FLASH_INFO Stm_25PE = + { + // Write Byte + {SPI_M25PExx_COMMAND_WRITE, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS}, + // Read Data + {SPI_M25PExx_COMMAND_READ, SPI_OPCODE_TYPE_READ_WITH_ADDRESS}, + // Erase 64k Sector + {SPI_M25PExx_COMMAND_ERASE, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS}, + // Read Device Status Reg + {SPI_M25PExx_COMMAND_READ_STATUS, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Read device ID + {SPI_M25PExx_COMMAND_READ_ID, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Write Status Register + {SPI_M25PExx_COMMAND_WRITE_S, SPI_OPCODE_TYPE_WRITE_NO_ADDRESS}, + // Write Status Enable - Not available on this part + {0, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Write Enable + {SPI_M25PExx_COMMAND_WRITE_ENABLE, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + 256, + SECTOR_SIZE_64KB + }; + +FLASH_INFO Atmel_26DF = + { + // Write Byte + {SPI_AT26DF_COMMAND_WRITE, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS}, + // Read Data + {SPI_AT26DF_COMMAND_READ, SPI_OPCODE_TYPE_READ_WITH_ADDRESS}, + // Erase 4k Sector + {SPI_AT26DF_COMMAND_ERASE, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS}, + // Read Device Status Reg + {SPI_AT26DF_COMMAND_READ_STATUS, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Read device ID + {SPI_AT26DF_COMMAND_READ_ID, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Write Status Register + {SPI_AT26DF_COMMAND_WRITE_S, SPI_OPCODE_TYPE_WRITE_NO_ADDRESS}, + // Write Status Enable + {SPI_AT26DF_COMMAND_UNPROTECT, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + // Write Enable + {SPI_AT26DF_COMMAND_WRITE_ENABLE, SPI_OPCODE_TYPE_READ_NO_ADDRESS}, + 256, + SECTOR_SIZE_4KB + }; +//---------------------------------------------------------------------------- +// Functions Definitions + +//---------------------------------------------------------------------------- +// Identify Functions + +// +//---------------------------------------------------------------------------- +// Procedure: IdentifySst_25LF +// +// Description: This function identifies the supported SPI flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// Supports the following SPI parts +// SST 25LF040/080/106A, ESMT 25L004/008/016A +// +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +IdentifySst_25LF ( + IN volatile UINT8 *pBlockAddress, + OUT FLASH_PART **FlashStruct +) +{ + if ( !CommonSpiReadId( &Sst_25LF, &MfgDevId ) ) return FALSE; + switch ( (UINT16)MfgDevId ) { + // Is SST 4M SPI flash part ? + case SST_25LF040A : + mExFlashPart.FlashCapacity = 0x80000; + MemCpy ( pFlashDeviceNumber, "SST 25LF040", 14 ); + break; + // Is SST 8M SPI flash part ? + case SST_25LF080A : + mExFlashPart.FlashCapacity = 0x100000; + MemCpy ( pFlashDeviceNumber, "SST 25LF080", 14 ); + break; + default : + return FALSE; + } + *FlashStruct = &mCommonSpiFlash; + MemCpy( &mExFlashPart.FlashCommandMenu, &Sst_25LF, sizeof(FLASH_INFO) ); + mExFlashPart.FlashVenDevId = MfgDevId; + gFlashId = MfgDevId; + *(UINT32*)(pFlashDeviceNumber + FLASH_PART_STRING_LENGTH - 4) = \ + mExFlashPart.FlashCapacity; + (*FlashStruct)->FlashProgramSize = Sst_25LF.PageSize; + (*FlashStruct)->FlashSectorSize = Sst_25LF.SectorSize; + (*FlashStruct)->FlashPartNumber = pFlashDeviceNumber; + // Update the OpCode to OpMenu immediately if need. + // ReinitializeSpiEnvironment ( &mExFlashPart.FlashCommandMenu ); + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IdentifyAtmel_26DF +// +// Description: This function identifies the supported LPC flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// Supports the following SPI parts +// ATMEL 26DFxx parts +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +IdentifyAtmel_26DF ( + IN volatile UINT8 *pBlockAddress, + OUT FLASH_PART **FlashStruct +) +{ + if ( !CommonSpiReadId( &Atmel_26DF, &MfgDevId ) ) return FALSE; + switch ( (UINT16)MfgDevId ) { + // Is Atmel 4M SPI flash part ? + case ATMEL_26DF041 : + mExFlashPart.FlashCapacity = 0x80000; + MemCpy ( pFlashDeviceNumber, "ATMEL 26DF041/25DF041", 21 ); + break; + // Is Atmel 8M SPI flash part ? + case ATMEL_26DF081 : + mExFlashPart.FlashCapacity = 0x100000; + MemCpy ( pFlashDeviceNumber, "ATMEL 26DF081/25DF081", 21 ); + break; + // Is Atmel 16M SPI flash part ? + case ATMEL_26DF161 : + case ATMEL_25DQ161 : + mExFlashPart.FlashCapacity = 0x200000; + MemCpy ( pFlashDeviceNumber, "ATMEL 26DF161/25DQ161", 21 ); + break; + // Is Atmel 32M SPI flash part ? + case ATMEL_26DF321 : + mExFlashPart.FlashCapacity = 0x400000; + MemCpy ( pFlashDeviceNumber, "ATMEL 26DF321/25DF321", 21 ); + break; + // Is Atmel 64M SPI flash part ? + case ATMEL_25DF641 : + mExFlashPart.FlashCapacity = 0x800000; + MemCpy ( pFlashDeviceNumber, "ATMEL 26DF641/25DF641", 21 ); + break; + default : return FALSE; + } + *FlashStruct = &mCommonSpiFlash; + MemCpy( &mExFlashPart.FlashCommandMenu, &Atmel_26DF, sizeof(FLASH_INFO) ); + mExFlashPart.FlashVenDevId = MfgDevId; + gFlashId = MfgDevId; + *(UINT32*)(pFlashDeviceNumber + FLASH_PART_STRING_LENGTH - 4) = \ + mExFlashPart.FlashCapacity; + (*FlashStruct)->FlashProgramSize = Atmel_26DF.PageSize; + (*FlashStruct)->FlashSectorSize = Atmel_26DF.SectorSize; + (*FlashStruct)->FlashPartNumber = pFlashDeviceNumber; + // Update the OpCode to OpMenu immediately if need. + ReinitializeSpiEnvironment ( &mExFlashPart.FlashCommandMenu ); + return TRUE; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: StmCheckMemoryCapacity +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +UINT32 +StmCheckMemoryCapacity ( + IN UINT32 dVenDevId +) +{ + switch ( ( dVenDevId & 0x00FF0000 ) >> 16 ) { + case 0x10 : return ( 0x10000 ); + case 0x11 : return ( 0x20000 ); + case 0x12 : return ( 0x40000 ); + case 0x13 : return ( 0x80000 ); + case 0x14 : return ( 0x100000 ); + case 0x15 : return ( 0x200000 ); + case 0x36 : // MX25U32xx + case 0x16 : return ( 0x400000 ); + case 0x37 : // MX25U64xx + case 0x17 : return ( 0x800000 ); + case 0x18 : return ( 0x1000000 ); + } + return ( FLASH_SIZE ); +} +// +//---------------------------------------------------------------------------- +// +// Procedure: SpansionCheckMemoryCapacity +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +UINT32 +SpansionCheckMemoryCapacity ( + IN UINT32 dVenDevId +) +{ + switch ( ( dVenDevId & 0x00FF0000 ) >> 16 ) { + case 0x12 : return ( 0x80000 ); + case 0x13 : return ( 0x100000 ); + case 0x14 : return ( 0x200000 ); + case 0x46 : // PMC 25LQ032 + case 0x15 : return ( 0x400000 ); + case 0x16 : return ( 0x800000 ); + case 0x17 : return ( 0x1000000 ); + } + return ( FLASH_SIZE ); +} +// +//---------------------------------------------------------------------------- +// +// Procedure: IntelCheckMemoryCapacity +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +UINT32 +IntelCheckMemoryCapacity ( + IN UINT32 dVenDevId +) +{ + switch ( ( dVenDevId & 0x00FF0000 ) >> 16 ) { + case 0x11 : + case 0x15 : return ( 0x200000 ); + case 0x12 : + case 0x16 : return ( 0x400000 ); + case 0x13 : + case 0x17 : return ( 0x800000 ); + } + return ( FLASH_SIZE ); +} +// +//---------------------------------------------------------------------------- +// +// Procedure: SstCheckMemoryCapacity +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +UINT32 +SstCheckMemoryCapacity ( + IN UINT32 dVenDevId +) +{ + switch ( ( dVenDevId & 0x00FF0000 ) >> 16 ) { + case 0x8c : return ( 0x40000 ); + case 0x8d : return ( 0x80000 ); + case 0x8e : return ( 0x100000 ); + case 0x01 : // SST 26VF016 + case 0x41 : return ( 0x200000 ); + case 0x02 : // SST 26VF032 + case 0x4a : return ( 0x400000 ); + case 0x43 : // SST 26VF064 + case 0x4b : return ( 0x800000 ); + } + return ( FLASH_SIZE ); +} +// +//---------------------------------------------------------------------------- +// Procedure: IdentifySTM_25PExx +// +// Description: This function identifies the supported SPI flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// Supports the following SPI parts +// ST Micro M25P80, M25P40 +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +IdentifyStm_25PExx ( + IN volatile UINT8 *pBlockAddress, + OUT FLASH_PART **FlashStruct +) +{ + if ( !CommonSpiReadId( &Stm_25PE, &MfgDevId ) ) return FALSE; + switch ( (UINT16)MfgDevId ) { + // erase page size = 256 bytes. + case STM_25PExx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_256B; + Stm_25PE.Erase.Opcode = SPI_M25PExx_COMMAND_PAGE_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "STM/Numonyx 25PE Series", 23 ); + break; + // erase sector size = 4K bytes. + case SST_26VFxxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + mExFlashPart.GlobalBlockUnlock = TRUE; + mExFlashPart.FlashCapacity = SstCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "SST 26VF Series", 15 ); + break; + case PMC_25LVxxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_PMC25LV_COMMAND_ERASE; + mExFlashPart.FlashCapacity = \ + SpansionCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "PMC 25LV/LQ Series", 18 ); + break; + case AMIC_25Lxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + mExFlashPart.FlashCapacity = \ + SpansionCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "AMIC 25L Series", 15 ); + break; + case AMIC_25Lxxx_ID : + case AMIC_25LQxxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "AMIC 25L/LQ Series", 18 ); + break; + case EON_25Fxx_ID : + case EON_25Qxx_ID : + case EON_25QHxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "EON 25F/Q/QH Series", 19 ); + break; + case STM_25PXxx_ID : + case STM_25PFxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy (pFlashDeviceNumber, "STM/Micron/Numonyx 25PF/PX Series", 33); + break; + case MXIC_25Lxxxx_ID : + case MXIC_25Lxx35_ID : + case MXIC_25Lxx36_ID : + case MXIC_25Uxx35_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "MXIC 25L/U Series", 17 ); + break; + case WINBOND_25Xxx_ID : + case WINBOND_25Qxx_ID : + case WINBOND_25QxxF_ID : + case WINBOND_25QxxW_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "Winbond 25X/Q Series", 20 ); + break; + case GD_25Qxx_ID : + case GD_25LQxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "GigaDevice 25Q Series", 21 ); + break; + // erase block size = 64K bytes. + case EON_25Pxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_64KB; + Stm_25PE.Erase.Opcode = SPI_M25PExx_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "EON 25P Series", 14 ); + break; + case STM_25Pxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_64KB; + Stm_25PE.Erase.Opcode = SPI_M25PExx_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + if (mExFlashPart.FlashCapacity == 0x1000000) { + Stm_25PE.SectorSize = SECTOR_SIZE_256KB; + } + MemCpy (pFlashDeviceNumber, "STM/Micron/Numonyx 25P Series", 29); + break; + case Numonyx_25Qxx_ID : + case Numonyx_25QxxA_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy (pFlashDeviceNumber, "Micron/Numonyx 25Q Series", 25); + break; + case SPANSION_25FLxxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_64KB; + mExFlashPart.FlashCapacity = \ + SpansionCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "Spansion 25FL Series", 19 ); + break; + case SPANSION_25FLxxxP_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_64KB; + mExFlashPart.FlashCapacity = \ + StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "Spansion 25FL(P) Series", 23 ); + break; + case INTEL_25Fxxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_64KB; + mExFlashPart.FlashCapacity = IntelCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "Intel/Numonyx 25F160/320", 24 ); + break; + case FM_25Qxx_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "FIDELIX 25Q Series", 18 ); + break; + case ESMT_25Lxx_ID : + case ESMT_25LxxQ_ID : + Stm_25PE.SectorSize = SECTOR_SIZE_4KB; + Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE; + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "ESMT 25L QA/PA Series", 21 ); + break; + default : + return FALSE; + } + *FlashStruct = &mCommonSpiFlash; + MemCpy( &mExFlashPart.FlashCommandMenu, &Stm_25PE, sizeof(FLASH_INFO) ); + mExFlashPart.FlashVenDevId = MfgDevId; + gFlashId = MfgDevId; + *(UINT32*)(pFlashDeviceNumber + FLASH_PART_STRING_LENGTH - 4) = \ + mExFlashPart.FlashCapacity; + (*FlashStruct)->FlashProgramSize = Stm_25PE.PageSize; + (*FlashStruct)->FlashSectorSize = Stm_25PE.SectorSize; + (*FlashStruct)->FlashPartNumber = pFlashDeviceNumber; + // Update the OpCode to OpMenu immediately if need. + ReinitializeSpiEnvironment ( &mExFlashPart.FlashCommandMenu ); + return TRUE; +} +// +//---------------------------------------------------------------------------- +// Procedure: IdentifySst_25VF +// +// Description: This function identifies the supported SPI flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// Supports the following SPI parts +// SST 25VF040B/080B/016B/032B, ESMT +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +IdentifySst_25VF ( + IN volatile UINT8 *pBlockAddress, + OUT FLASH_PART **FlashStruct +) +{ + if ( !CommonSpiReadId( &Sst_25VF, &MfgDevId ) ) return FALSE; + switch ( (UINT16)MfgDevId ) { + case SST_25VFxxx_ID : + mExFlashPart.FlashCapacity = SstCheckMemoryCapacity( MfgDevId ); + if (mExFlashPart.FlashCapacity >= 0x800000) Sst_25VF.PageSize = 256; +#if defined AAI_WORD_PROGRAM && AAI_WORD_PROGRAM == 1 + else mExFlashPart.AAIWordProgram = TRUE; +#endif + MemCpy ( pFlashDeviceNumber, "SST 25VF Series", 15 ); + break; + case ESMT_25LxxxT_ID : + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + MemCpy ( pFlashDeviceNumber, "ESMT 25L T Series", 17 ); + break; + case ESMT_25LxxxB_ID : + mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId ); + Sst_25VF.WriteStatusEnable.Opcode = 0; + MemCpy ( pFlashDeviceNumber, "ESMT 25L B Series", 17 ); + break; + default : return FALSE; + } + *FlashStruct = &mCommonSpiFlash; + MemCpy( &mExFlashPart.FlashCommandMenu, &Sst_25VF, sizeof(FLASH_INFO) ); + mExFlashPart.FlashVenDevId = MfgDevId; + *(UINT32*)(pFlashDeviceNumber + FLASH_PART_STRING_LENGTH - 4) = \ + mExFlashPart.FlashCapacity; + gFlashId = MfgDevId; + (*FlashStruct)->FlashProgramSize = Sst_25VF.PageSize; + (*FlashStruct)->FlashSectorSize = Sst_25VF.SectorSize; + (*FlashStruct)->FlashPartNumber = pFlashDeviceNumber; + // Update the OpCode to OpMenu immediately if need. + ReinitializeSpiEnvironment ( &mExFlashPart.FlashCommandMenu ); + return TRUE; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Board/Flash/SPI/Template/SPIFlash.c b/Board/Flash/SPI/Template/SPIFlash.c new file mode 100644 index 0000000..d7677b5 --- /dev/null +++ b/Board/Flash/SPI/Template/SPIFlash.c @@ -0,0 +1,1038 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/SPI/Template/SpiFlash.c 4 6/24/09 3:14a Calvinchen $ +// +// $Revision: 4 $ +// +// $Date: 6/24/09 3:14a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/SPI/Template/SpiFlash.c $ +// +// 4 6/24/09 3:14a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 3 4/27/09 3:24a Calvinchen +// 2.(EIP20459) Added Multiple SPI CSP component support. +// +// 2 6/19/08 4:30a Calvinchen +// +// 1 3/13/08 6:32a Calvinchen +// +//********************************************************************** +// +// +// Name: FlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** +//---------------------------------------------------------------------------- +// Includes +#include +#include +#include "FlashPart.h" +#include "SpiFlash.h" +#include "token.h" +//---------------------------------------------------------------------------- +// Local defines for transaction types +/* --------------------- PORTING REQUIRED --------------------- + +// ICH8/9/10 SPI register defines. +#define SPI_STS 0x90 // SPI Status +#define SPI_CTL 0x91 // SPI Control +#define SPI_ADR 0x08 // SPI Address +#define SPI_DAT0 0x10 // SPI Data 0 +#define SPI_PREOP 0x94 // Prefix Opcode Configuration +#define SPI_OPTYPE 0x96 // Opcode Type Configuration +#define SPI_OPMENU 0x98 // Opcode Menu Configuration +// SPI default opcode slots +#define SPI_OPCODE_WRITE_INDEX 0x0 +#define SPI_OPCODE_READ_INDEX 0x1 +#define SPI_OPCODE_ERASE_INDEX 0x2 +#define SPI_OPCODE_READ_S_INDEX 0x3 +#define SPI_OPCODE_READ_ID_INDEX 0x4 +#define SPI_OPCODE_WRITE_S_INDEX 0x5 +#define SPI_OPCODE_WRITE_E_INDEX 0x6 +#define SPI_OPCODE_WRITE_S_E_INDEX 0x7 +#define SPI_PREFIX_WRITE_S_EN 0x1 +#define SPI_PREFIX_WRITE_EN 0x0 +#define SPI_MAX_DATA_TRANSFER 0x40 + --------------------- PORTING REQUIRED ---------------------*/ +//---------------------------------------------------------------------------- +// Module level global data +//============================================================================ +extern UINT16 gFlashId; +extern FLASH_PART *FlashAPI; +//---------------------------------------------------------------------------- +// Function Externs +//-extern +//-VOID +//-SpiChipsetVirtualFixup ( +//- IN EFI_RUNTIME_SERVICES *pRS +//-); +//---------------------------------------------------------------------------- +// Local prototypes +VOID +CommonSpiEraseCommand ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 *Length +); +VOID +CommonSpiReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 *Length +); +BOOLEAN +CommonSpiIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus +); +BOOLEAN +CommonSpiIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus +); +VOID +CommonSpiBlockWriteEnable ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiBlockWriteDisable ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiDeviceWriteEnable ( + VOID +); +VOID +CommonSpiDeviceWriteDisable ( + VOID +); +VOID +CommonSpiDeviceVirtualFixup ( + EFI_RUNTIME_SERVICES *pRS +); +//============================================================================ +// Local Variables +//============================================================================ +FLASH_PART mCommonSpiFlash ={ + CommonSpiReadCommand, + CommonSpiEraseCommand, + CommonSpiProgramCommand, + CommonSpiIsEraseCompleted, + CommonSpiIsProgramCompleted, + CommonSpiBlockWriteEnable, + CommonSpiBlockWriteDisable, + CommonSpiDeviceWriteEnable, + CommonSpiDeviceWriteDisable, + CommonSpiDeviceVirtualFixup, + 1, // default value, should be changed in Init function + SECTOR_SIZE_4KB +}; +EX_FLASH_PART mExFlashPart = { + {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},0,0}, + FLASH_SIZE, // flash size, should be changed in Init function + 0, // flash part id, should be changed in Init function + 0 // flash part string, should be changed in Init function +}; +UINT8 gbDeviceVirtual = 0; +UINT8 gbDeviceWriteEnabled = 0; +//---------------------------------------------------------------------------- +// Function Definitions + +// +//---------------------------------------------------------------------------- +// +// Procedure: IoDelay +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +IoDelay (VOID) +{ + UINT8 bTimeout; + for ( bTimeout = 0; bTimeout < 33; bTimeout++ ) { + IoWrite8( 0xEB, 0x55 ); + IoWrite8( 0xEB, 0xAA ); + } + return ; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: WaitForSpiCycleDone +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +WaitForSpiCycleDone (VOID) +{ +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wTimeout; + UINT8 bCyclyDone; + + for ( wTimeout = 0, bCyclyDone = 0; wTimeout < 0xFFFF; wTimeout++ ) { + bCyclyDone = *(volatile UINT8*)( gSPIBASE + SPI_STS ); + if ( bCyclyDone & BIT02 ) break; + } + // write BIT2 to clear CycleDone status + *(volatile UINT8*)( gSPIBASE + SPI_STS ) = BIT02; + + --------------------- PORTING REQUIRED ---------------------*/ +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadStatus +// +// Description: +// +// Input: None. +// +// Output: Status Register which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +UINT8 +CommonSpiReadStatus (VOID) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wSpiCmd; + // Opcode menu slot 3 is configured as "Read Status Register" + wSpiCmd = SPI_OPCODE_READ_S_INDEX << 4; + // indicate that data phase is required + wSpiCmd += (1 << 14); + // Set BIT1 (Go) + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // return status register. + return ( *(volatile UINT8*)( gSPIBASE + SPI_DAT0 ) ); + + --------------------- PORTING REQUIRED ---------------------*/ + + return ( (UINT8)EFI_NOT_READY ); // For Template compiling only. +} +// +//---------------------------------------------------------------------------- +// +// Procedure: WaitForWriteOperationCompleted +// +// Description: +// +// Input: None. +// +// Output: None. +// +//---------------------------------------------------------------------------- +// +VOID +WaitForWriteOperationCompleted (VOID) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wWaitStsRetry; + UINT8 bStatus; + + for( wWaitStsRetry = 0; wWaitStsRetry < 0xFFFF; wWaitStsRetry++ ) { + // read flash status register. + bStatus = CommonSpiReadStatus(); + // Is operation busy ? + if( !( bStatus & 0x1 ) ) break; + } + + --------------------- PORTING REQUIRED ---------------------*/ +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiWriteStatus +// +// Description: Routine for Write SPI Status Register. +// +// Input: None. +// +// Output: Status Register which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiWriteStatus ( + IN UINT8 bWriteData, + IN UINT8 bOpcodeIndex, + IN UINT8 bIsDataPhase, + IN UINT8 bPrefixOp, + IN UINT32 dSectorAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wSpiCmd; + + *(volatile UINT8*)( gSPIBASE + SPI_DAT0 ) = bWriteData; + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dSectorAddress; + // Opcode menu slot 3 is configured as "Read Status Register" + wSpiCmd = bOpcodeIndex << 4; + // indicate that data phase is required + wSpiCmd += ( bIsDataPhase << 14 ); + // BIT3(Preop 1) + wSpiCmd += ( bPrefixOp << 3 ); + // Set BIT1 (Go), BIT2(Atomic w/ Prefix), + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01 + BIT02; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // wait for SPI flash operation completed. + WaitForWriteOperationCompleted(); + // return status register. + return ; + + --------------------- PORTING REQUIRED ---------------------*/ +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadByte +// +// Description: +// +// Input: dByteAddress Address that need to be read. +// +// Output: BYTE Value which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +UINT8 +CommonSpiReadByte ( + IN UINT32 dByteAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + UINT16 wSpiCmd; + + // update the + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dByteAddress; + // Opcode menu slot 1 is configured as "Read Flash" + wSpiCmd = ( SPI_OPCODE_READ_INDEX << 4 ) + BIT01; + // indicate that data phase is required + wSpiCmd += (1 << 14); + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // return data. + return( *(volatile UINT8*)( gSPIBASE + SPI_DAT0 ) ); + + --------------------- PORTING REQUIRED ---------------------*/ + return ( (UINT8)EFI_NOT_READY ); // For Template compiling only. +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonConvertSpiAddress +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +UINT32 +CommonConvertSpiAddress ( + IN volatile UINT8 *pAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + if ( gbDeviceVirtual ) { + // pAddress - offset from Flash Device Base. + pAddress -= FlashDeviceBase; + // pAddress - 32bit memory mapping address. + pAddress += (0xFFFFFFFF - FLASH_SIZE) + 1; + } + --------------------- PORTING REQUIRED ---------------------*/ + + return ((UINT32)pAddress); +} +// +//---------------------------------------------------------------------------- +// +// Procedure: InitializeSpiEnvironment +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +InitializeSpiEnvironment ( + IN FLASH_INFO *FlashInfo +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT32 dIchSpiFDOD; + + //Program first DWORD of opcode commands + *((volatile UINT32*)( gSPIBASE+R_RCRB_SPI_OPMENU+0 )) = (UINT32) + // Write Byte + ( (FlashInfo->Write.Opcode << (SPI_OPCODE_WRITE_INDEX * 8)) + // Read Data + | (FlashInfo->Read.Opcode << (SPI_OPCODE_READ_INDEX * 8)) + // Erase 64k Sector + | (FlashInfo->Erase.Opcode << (SPI_OPCODE_ERASE_INDEX * 8)) + // Read Device Status Reg + | (FlashInfo->ReadStatus.Opcode << (SPI_OPCODE_READ_S_INDEX * 8)) ); + + //Program second DWORD of Opcode commands + *((volatile UINT32*)( gSPIBASE+R_RCRB_SPI_OPMENU+4 )) = (UINT32) + // Read device ID + ( (FlashInfo->ReadId.Opcode << ((SPI_OPCODE_READ_ID_INDEX - 4) * 8)) + // Write Status Register + | (FlashInfo->WriteStatus.Opcode << ((SPI_OPCODE_WRITE_S_INDEX - 4) * 8)) + // Write Status Enable Register + | (FlashInfo->WriteStatusEnable.Opcode << ((SPI_OPCODE_WRITE_E_INDEX - 4) * 8))); + + //Program opcode types + *((volatile UINT16*)( gSPIBASE+R_RCRB_SPI_OPTYPE )) = (UINT16) + // write with address. + ( FlashInfo->Write.OpcodeType << (SPI_OPCODE_WRITE_INDEX*2) + // read with address. + | FlashInfo->Read.OpcodeType << (SPI_OPCODE_READ_INDEX*2) + // write with address. + | FlashInfo->Erase.OpcodeType << (SPI_OPCODE_ERASE_INDEX*2) + // read w/o no adress. + | FlashInfo->ReadStatus.OpcodeType << (SPI_OPCODE_READ_S_INDEX*2) + // read with address. + | FlashInfo->ReadId.OpcodeType << (SPI_OPCODE_READ_ID_INDEX*2) + // write w/o address. + | FlashInfo->WriteStatus.OpcodeType << (SPI_OPCODE_WRITE_S_INDEX*2) + // write w/o address. + | FlashInfo->WriteStatusEnable.OpcodeType << (SPI_OPCODE_WRITE_E_INDEX*2) ); + + //set up the prefix opcodes for commands + *((volatile UINT16*)( gSPIBASE+R_RCRB_SPI_PREOP )) = (UINT16) + ( ( FlashInfo->WriteStatusEnable.Opcode << 8 ) + | ( FlashInfo->WriteEnable.Opcode ) ); + + // Here checks the BIOS region of Flash Descriptor Table. + if ( mExFlashPart.FlashCommandMenu != NULL ) { + if ( !gBiosRegionBase ) { + *(volatile UINT32*)( gSPIBASE + ICH_SPI_FDOC ) = 0; + dIchSpiFDOD = *(volatile UINT32*)( gSPIBASE + ICH_SPI_FDOD ); + if ( dIchSpiFDOD == 0x0FF0A55A ) + { + *(volatile UINT32 *)( gSPIBASE + ICH_SPI_FDOC ) = (BIT13+BIT02); + do { + dIchSpiFDOD = *(volatile UINT32*)( gSPIBASE+ICH_SPI_FDOD ); + } while( dIchSpiFDOD == 0x0FF0A55A ); + gBiosRegionBase = ( ( (dIchSpiFDOD >> 16) + 1 ) << 12 ); + } + else + gBiosRegionBase = mExFlashPart.FlashCapacity; + } + } + return ; + + --------------------- PORTING REQUIRED ---------------------*/ + +} +// +//---------------------------------------------------------------------------- +// +// Procedure: ReinitializeSpiEnvironment +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +ReinitializeSpiEnvironment ( + IN FLASH_INFO *FlashInfo +) +{ + return ; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadId +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiReadId ( + IN FLASH_INFO *FlashInfo, + IN UINT32 *dFlashId +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wSpiCmd = 0xFFFF; + + InitializeSpiEnvironment( FlashInfo ); + // Set SPI read-address = 0 + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = 0; + // set opcode for "Read ID" + wSpiCmd = SPI_OPCODE_READ_ID_INDEX << 4; + // set transaction = 3 bytes + wSpiCmd += ( ( 3 - 1 ) << 8 ); + // indicate that data phase is required + wSpiCmd += ( 1 << 14 ); + // Go (BIT1) + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01; + WaitForSpiCycleDone(); + IoDelay(); + *dFlashId = *(volatile UINT32*)( gSPIBASE + SPI_DAT0 ) & 0x00FFFFFF; + TRACE ((-1, " FLASH ID - %08X\n", *dFlashId)); + return TRUE; + + --------------------- PORTING REQUIRED ---------------------*/ + + return ( (UINT8)EFI_NOT_READY ); // For Template compiling only. +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +//---------------------------------------------------------------------------- +// +VOID +CommonSpiEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + volatile UINT32 dSectorAddr; + UINT32 dNByte; + UINT16 wEraseRetry, wNumSectors, wSector; + UINT16 wSpiCmd; + + // These parts only erase in 64K sectors + InitializeSpiEnvironment( mExFlashPart.FlashCommandMenu ); + wNumSectors = ( FlashBlockSize / FlashAPI->FlashSectorSize ); + for ( wSector = 0; wSector < wNumSectors ; wSector++ ) { + dSectorAddr = (UINT32) + ( pBlockAddress + wSector * FlashAPI->FlashSectorSize ); + for ( dNByte = 0; dNByte < FlashAPI->FlashSectorSize; dNByte++ ) { + if ( *(volatile UINT8*)( dSectorAddr + dNByte ) != 0xFF ) break; + } + if ( dNByte == FlashAPI->FlashSectorSize ) break; + for ( wEraseRetry = 0; wEraseRetry < FLASH_RETRIES; wEraseRetry++ ) { + dSectorAddr += gBiosRegionBase; + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dSectorAddr; + // opcode index 2 is programmed for erase command. + // Set BIT1 (Go), BIT2(Atomic w/ Prefix) + wSpiCmd = ( SPI_OPCODE_ERASE_INDEX << 4) + BIT01 + BIT02; + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for chipset SPI cycle completed. + WaitForSpiCycleDone(); + // wait for SPI flash operation completed. + WaitForWriteOperationCompleted(); + // write operation appeared to succeed, now read back byte and compare. + if ( CommonSpiReadByte( dSectorAddr ) == 0xFF ) break; + } + } + + --------------------- PORTING REQUIRED ---------------------*/ + +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiProgramCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT8 bFlashRetry = 0, bProgBytes = 0, bNumBytes = 0; + UINT16 wSpiCmd = 0, wRetry = 0, wMaxNumBytes = 0; + + InitializeSpiEnvironment( mExFlashPart.FlashCommandMenu ); + bProgBytes = mCommonSpiFlash.FlashProgramSize; + if ( mCommonSpiFlash.FlashProgramSize != 1 ) { + // Limit the max transfer to the number of bytes the chipset can + // transfer per cycle + if ( *Length >= SPI_MAX_DATA_TRANSFER ) + bProgBytes = SPI_MAX_DATA_TRANSFER; + else + bProgBytes = *Length; + // this is currently for the WINBOND parts only + // mask off lowest 8 bits of address so that we can determine how + // many bytes we can write before we hit the end of a page + wMaxNumBytes = 0x100 - ((UINT8)pByteAddress & 0xFF); + if ( (UINT32)pByteAddress & 0x1 ) bProgBytes = 1; + else if ( (UINT16)bProgBytes > wMaxNumBytes ) + bProgBytes = (UINT8)wMaxNumBytes; + } + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + // check if do the data need to be programmed ? + for ( bNumBytes = 0; bNumBytes < bProgBytes; bNumBytes++ ) { + if ( *( Byte + bNumBytes ) != 0xFF ) break; + } + + // The data is empty and don't need to be programmed. + if ( bNumBytes == bProgBytes ) break; + // update data to chipset SPI data transfer registers. + for ( bNumBytes = 0; bNumBytes < bProgBytes; bNumBytes++ ) { + for ( wRetry = 0; wRetry < 0x400; wRetry ++ ) { + *(volatile UINT8*)( gSPIBASE+SPI_DAT0+bNumBytes ) = + *( Byte+bNumBytes ); + // verified for checking the data is correct. + if ( *(Byte+bNumBytes) == *(volatile UINT8*) + ( gSPIBASE+SPI_DAT0+bNumBytes ) ) + break; + } + } + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = + (UINT32)( pByteAddress + gBiosRegionBase ); + // BIT14 - indicate that it's data cycle. + wSpiCmd = ( 1 << 14 ); + // BIT[8..13] - update the number of bytes to be written. + wSpiCmd += ( bProgBytes - 1 ) << 8; + // opcode index 0 is programmed for program command. + // Set BIT1 (Go), BIT2(Atomic w/ Prefix) + wSpiCmd += ( SPI_OPCODE_WRITE_INDEX << 4) + BIT01 + BIT02; + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for chipset SPI cycle completed. + WaitForSpiCycleDone(); + // wait for chipset SPI flash operation completed. + WaitForWriteOperationCompleted(); + // write operation appeared to succeed, now read back byte and compare + // set control for 1-byte data read, no prefix + for ( bNumBytes = 0; bNumBytes < bProgBytes; bNumBytes++ ) { + if (*(Byte + bNumBytes) != CommonSpiReadByte ( + (UINT32)( pByteAddress + bNumBytes + gBiosRegionBase ))) + break; + } + if ( bNumBytes == bProgBytes ) break; + } + // Don't forget to return the number of bytes not written + *Length = *Length - (UINT32)bProgBytes; + return; + + --------------------- PORTING REQUIRED ---------------------*/ + +} + + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiReadCommand ( + IN volatile UINT8 *pByteAddress, + OUT UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT32 dReadAddress = 0, dNumBytes = 0; + + InitializeSpiEnvironment( &mExFlashPart.FlashCommandMenu ); + dReadAddress = CommonConvertSpiAddress ( pByteAddress ); + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = CommonSpiReadByte( dReadAddress + dNumBytes ); + *Length = 0; +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiIsEraseCompleted ( + IN volatile UINT8 *pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + *pStatus = EFI_NOT_READY; + *pError = TRUE; + break; + } + } + *pError = FALSE; + *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// Byte Last data byte written +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiIsProgramCompleted ( + IN volatile UINT8 *pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + *pStatus = EFI_NOT_READY; + *pError = TRUE; + break; + } + } + *pError = FALSE; + *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: *pBlockAddress - Address within the block to write enable +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiBlockWriteEnable ( + IN volatile UINT8 *pBlockAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT8 bStatusReg = 0, bPrefixOp, bDataPhase = 1; + UINT16 wNumSector = 1; + UINT32 dSectorAddr = 0; + + bStatusReg = CommonSpiReadStatus(); + switch ( (UINT8)mExFlashPart.FlashVenDevId ) { + // if SST flash, prefix 1 w/o address + case 0xBF : + bStatusReg &= 0x1C; + bPrefixOp = SPI_PREFIX_WRITE_S_EN; + break; + // if ATMEL flash, prefix 0 w/ address + case 0x1F : + bStatusReg &= 0xC; + dSectorAddr = ~(UINT32)mExFlashPart.FlashCapacity + 1; + wNumSector = ( mExFlashPart.FlashCapacity/FlashAPI->FlashSectorSize ); + bPrefixOp = SPI_PREFIX_WRITE_EN; + bDataPhase = 0; + break; + default : + // default flash, prefix 0 w/o address + bStatusReg &= 0x1C; + bPrefixOp = SPI_PREFIX_WRITE_EN; + } + if ( bStatusReg ) { + for ( ; wNumSector > 0; wNumSector-- ) { + CommonSpiWriteStatus ( 0, + SPI_OPCODE_WRITE_S_INDEX, + bDataPhase, + bPrefixOp, + dSectorAddr ); + dSectorAddr += FlashAPI->FlashSectorSize; + } + } + + --------------------- PORTING REQUIRED ---------------------*/ + +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: *pBlockAddress - Address within the block to write disable +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiBlockWriteDisable ( + IN volatile UINT8 *pBlockAddress +) +{ +#if BLOCK_PROTECT_ENABLE +/* --------------------- PORTING REQUIRED --------------------- + + UINT8 bStatusReg = 0, bPrefixOp, bDataPhase = 1; + UINT8 bOpmenuIndex; + UINT16 wNumSector = 1; + UINT32 dSectorAddr = 0; + + bStatusReg = CommonSpiReadStatus(); + bOpmenuIndex = SPI_OPCODE_WRITE_S_INDEX; + switch ( (UINT8)mExFlashPart.FlashVenDevId ) { + // if SST flash, prefix 1 w/o address + case 0xBF : + bStatusReg &= 0x1C; + bPrefixOp = SPI_PREFIX_WRITE_S_EN; + break; + // if ATMEL flash, prefix 0 w/ address + case 0x1F : + bStatusReg &= 0xC; + dSectorAddr = ~(UINT32)mExFlashPart.FlashCapacity + 1; + wNumSector = ( mExFlashPart.FlashCapacity/FlashAPI->FlashSectorSize ); + bPrefixOp = SPI_PREFIX_WRITE_EN; + bOpmenuIndex = SPI_OPCODE_WRITE_E_INDEX; + bDataPhase = 0; + break; + default : + // default flash, prefix 0 w/o address + bStatusReg &= 0x1C; + bPrefixOp = SPI_PREFIX_WRITE_EN; + } + if ( !bStatusReg ) { + for ( ; wNumSector > 0; wNumSector-- ) { + CommonSpiWriteStatus ( 0x1C, + bOpmenuIndex, + bDataPhase, + bPrefixOp, + dSectorAddr ); + dSectorAddr += FlashAPI->FlashSectorSize; + } + } + + --------------------- PORTING REQUIRED ---------------------*/ +#endif +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiDeviceWriteEnable (VOID) +{ + // check is DeviceWrite enabled, if yes, don't enable it again, else, enable it. + if ( !gbDeviceWriteEnabled ) { + gbDeviceWriteEnabled = 1; + } +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiDeviceWriteDisable (VOID) +{ + // check is DeviceWrite enabled, if yes, disable it, + // if no, don't disable it. + if ( gbDeviceWriteEnabled ) { + gbDeviceWriteEnabled = 0; + } +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +CommonSpiDeviceVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + +//- SpiChipsetVirtualFixup(pRS); + gbDeviceVirtual = 1; + + return; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* \ No newline at end of file diff --git a/Board/Flash/SPI/Template/SpiCspSrc.cif b/Board/Flash/SPI/Template/SpiCspSrc.cif new file mode 100644 index 0000000..e50f0c3 --- /dev/null +++ b/Board/Flash/SPI/Template/SpiCspSrc.cif @@ -0,0 +1,8 @@ + + name = "CSP : DUMMY SPI - Do Not Delete" + category = ModulePart + LocalRoot = "Board\Flash\SPI\Template" + RefName = "DUMMY_SPI_CSP_SOURCE" +[files] +"SPIFlash.c" + diff --git a/Board/Flash/STD/STDIntelFlashWrite.c b/Board/Flash/STD/STDIntelFlashWrite.c new file mode 100644 index 0000000..2d1dbfc --- /dev/null +++ b/Board/Flash/STD/STDIntelFlashWrite.c @@ -0,0 +1,699 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2008, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/STD/STDIntelFlashWrite.c 6 12/23/09 6:13a Calvinchen $Revision: +// +// $Revision: 6 $ +// +// $Date: 12/23/09 6:13a $Log: $ +// +// +// +//********************************************************************** + +//********************************************************************** +// +// +// Name: StdIntelFlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include +#include +#include +#include "token.h" + +//---------------------------------------------------------------------- +// define local MACROS + +//Flash Part Specific Tokens +#define VENDOR_ID 0x88 // Intel Manufacturers ID +#define DEVICE_ID64T 0x17 // 64M TB +#define DEVICE_ID128T 0x18 // 128M TB +#define DEVICE_ID256T 0x19 // 256M TB +#define DEVICE_ID64B 0x1A // 64M BB +#define DEVICE_ID128B 0x1B // 128M BB +#define DEVICE_ID256B 0x1C // 256M BB + +//Flash Part Specific Tokens +#define READ_ARRAY_CMD 0xff +#define RD_STATUS_CMD 0x70 +#define CLR_STATUS_CMD 0x50 +#define ERASE_SET_CMD 0x20 +#define ERASE_CNF_CMD 0xd0 +#define PRG_SETUP_CMD 0x40 + +#define RD_ID_CODE 0x90 + +// Intel Status Register Bits +#define VPP_LOW 0x08 +#define PROGRAM_FAIL 0x10 +#define ERASE_FAIL 0x20 +#define WSM_BUSY 0x80 + +// Intel Lock Commands +#define UNLOCK 0 +#define WRITE_LOCK 1 + +//---------------------------------------------------------------------------- +// Module level global data +extern UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; + +//---------------------------------------------------------------------------- +// Function Prototypes +VOID +IntelFlashEraseCommand ( + volatile UINT8 *pBlockAddress + ); +VOID +IntelFlashReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + );//{}; +VOID +IntelFlashProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +BOOLEAN +IntelFlashIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus + ); +BOOLEAN +IntelFlashIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus + ); +VOID +IntelFlashBlockWriteEnable ( + UINT8* pBlockAddress + ); +VOID +IntelFlashBlockWriteDisable ( + UINT8* pBlockAddress + ); +VOID +IntelFlashDeviceWriteEnable ( + VOID + ); +VOID +IntelFlashDeviceWriteDisable ( + VOID + ); +VOID +IntelFlashVirtualFixup ( + EFI_RUNTIME_SERVICES *pRS + ); + + +//======================================================================== +// Local Variable definitions + +// Flash Part Data structure fo the intel 82802ACC +FLASH_PART mIntelSTD = + { + IntelFlashReadCommand, + IntelFlashEraseCommand, + IntelFlashProgramCommand, + IntelFlashIsEraseCompleted, + IntelFlashIsProgramCompleted, + IntelFlashBlockWriteEnable, + IntelFlashBlockWriteDisable, + IntelFlashDeviceWriteEnable, + IntelFlashDeviceWriteDisable, + IntelFlashVirtualFixup, + 1, // Number of bytes to program to the + // Flash part in each program command + 0, // Dummy value to hold place - only used in SPI + NULL // Flash Part Number Pointer + }; + + + +//======================================================================== +// Function Definitions +// +//---------------------------------------------------------------------------- +// Procedure: IntelSTDCmdDelay +// +// Description: This function resets the Sst flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +VOID +IntelSTDCmdDelay (VOID) +{ + IoWrite8 ( 0xeb, 0x55 ); + IoWrite8 ( 0xeb, 0xaa ); +} +// +//---------------------------------------------------------------------------- +// Procedure: IntelSTDResetFlash +// +// Description: This function resets the Sst flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelSTDResetFlash ( + IN volatile UINT8* pAddress +) +{ + *pAddress = READ_ARRAY_CMD;// Return to read mode + IntelSTDCmdDelay (); + *pAddress = CLR_STATUS_CMD;// clear status + IntelSTDCmdDelay (); +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelSTDOperationCompleted +// +// Description: +// This function verifies whether the command sent to the FWH part +// has completed and returns the status of the command +// +// Input: +// IN volatile UINT8* pAddress Location to check the device status +// +// Output: +// EFI_SUCCESS - +// EFI_TIMEOUT - +// EFI_DEVICE_ERROR - +// +//---------------------------------------------------------------------------- +// +static +EFI_STATUS +IntelSTDOperationCompleted ( + IN volatile UINT8* pAddress +) +{ + UINT8 bSTDStatus; + UINT32 dTimeout = FLASH_RETRIES * 0x10000; + + do { + *pAddress = RD_STATUS_CMD; // read status. + IntelSTDCmdDelay (); + bSTDStatus = *pAddress; + if ( bSTDStatus & WSM_BUSY ) { + if ( bSTDStatus & ( VPP_LOW + PROGRAM_FAIL + ERASE_FAIL ) ) + return EFI_DEVICE_ERROR; + else return EFI_SUCCESS; + } + dTimeout--; + } while ( dTimeout != 0 ); + return EFI_TIMEOUT; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +// +// Returns: None +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + EFI_STATUS Status; + UINT8 bFlashRetry; + UINT8 i; + + for(i=0 ; i<4 ; i++) { + // Some block size is 32K + (UINT32)pBlockAddress += 0x8000; + IntelSTDResetFlash( pBlockAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + *pBlockAddress = ERASE_SET_CMD; + IntelSTDCmdDelay (); + *pBlockAddress = ERASE_CNF_CMD; + IntelSTDCmdDelay (); + Status = IntelSTDOperationCompleted( pBlockAddress ); + IntelSTDResetFlash( pBlockAddress ); + if ( Status != EFI_SUCCESS ) continue; + if ( *pBlockAddress != 0xFF ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + } +//- return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +IntelFlashIsEraseCompleted ( + IN volatile UINT8* pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// *Byte - Byte to be written +// *Length - Number of bytes to write +// +// Output: *Length - Number of bytes still left to write +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashProgramCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT8 bFlashRetry; + EFI_STATUS Status; + UINT16 Word = 0; + UINT16* adjAddress; + BOOLEAN Program_Word = FALSE; + + (UINT32)adjAddress = (UINT32)pByteAddress & 0xFFFFFFFE; + if (*pByteAddress != *Byte) { + // Word Program Only , Adjust Input word data + if((UINT32)pByteAddress & 1) { + // Get Last Byte of current address + Word = (*Byte) << 8; + Word += *(UINT8*)((UINT32)pByteAddress - 1); + } else { + if(*Length > 1) { + // Get Next Byte from Input Buffer + Word = *(Byte + 1) << 8; + Program_Word = TRUE; + } else { + // Get Next Byte of current address + Word = (*(UINT8*)((UINT32)pByteAddress + 1)) << 8; + } + Word += *Byte; + } + IntelSTDResetFlash( (volatile UINT8*)adjAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + *(UINT16*)adjAddress = PRG_SETUP_CMD; // Issue program command + IntelSTDCmdDelay (); + *(UINT16*)adjAddress = Word; // Program a Word + IntelSTDCmdDelay (); + // Check for completion of the program operation + Status = IntelSTDOperationCompleted( (volatile UINT8*)adjAddress ); + IntelSTDResetFlash( (volatile UINT8*)adjAddress ); + if ( Status != EFI_SUCCESS ) continue; + if ( *adjAddress != Word ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + // Input data is match + } else Status = EFI_SUCCESS; + if ( !Program_Word ) *Length = *Length - 1; + else *Length = *Length - 2; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// Byte Last data byte written +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +IntelFlashIsProgramCompleted ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashReadCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 *Length +) +{ + UINT32 dNumBytes = 0; + + // Changes for SMIFlash module label "4.6.3.6_SMIFLASH_12" or later. + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = *(UINT8*)((UINT32)pByteAddress + dNumBytes ); + *Length = 0; + return ; +//- return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SetBlockLock +// +// Description: This function programs a page of data at a time +// +// Input: *pBlockAddress - This is location where the data +// is to be written +// LockState - Value to use to set the Lock register for the +// block defined by pBlockAddress +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +void +SetBlockLock ( + IN volatile UINT8* pBlockAddress, + IN UINT8 LockState +) +{ +//- // Update the block lock register +//- ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase +//- + FwhFeatureSpaceBase))[2] = LockState; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ +//- SetBlockLock(pBlockAddress, UNLOCK); +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ +//- SetBlockLock(pBlockAddress, WRITE_LOCK); +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +IntelFlashDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + + +// +//---------------------------------------------------------------------------- +// Procedure: IntelFlashVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +static +VOID +IntelFlashVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: IntelSTDIdentify +// +// Description: This function identifies the supported LPC flash parts and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +IntelSTDIdentify ( + IN volatile UINT8* pBlockAddress, + OUT FLASH_PART **Struct +) +{ + UINT8 VID, DID; + +//- SetBlockLock(pBlockAddress, UNLOCK); + + *pBlockAddress = RD_ID_CODE;// Set to read ID code mode + VID = *pBlockAddress; + DID = *(pBlockAddress + 2); + *pBlockAddress = READ_ARRAY_CMD;// Return to read mode + + if ((VID == VENDOR_ID) && + (DID == DEVICE_ID64T || DID == DEVICE_ID128T || \ + DID == DEVICE_ID256T || DID == DEVICE_ID64B || \ + DID == DEVICE_ID128B || DID == DEVICE_ID256B)) { + // If your Block size is 128K, please modify your FLASH_BLOCK_SIZE + // to 128K in flash.sdl . + MemCpy ( pFlashDeviceNumber, "Numonyx 28F640/128/256P30B/T", 28 ); + mIntelSTD.FlashPartNumber = pFlashDeviceNumber; + *Struct = &mIntelSTD; + return TRUE; + } else return FALSE; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2008, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Board/Flash/STD/StdFlash.cif b/Board/Flash/STD/StdFlash.cif new file mode 100644 index 0000000..aee139f --- /dev/null +++ b/Board/Flash/STD/StdFlash.cif @@ -0,0 +1,12 @@ + + name = "STD Interface - Source" + category = ModulePart + LocalRoot = "Board\Flash\STD" + RefName = "STD_INTERFACE_SOURCE" +[files] +"StdFlash.sdl" +"StdFlash.mak" +"StdSpansionFlashWrite.c" +"STDIntelFlashWrite.c" +"StdMxicFlashWrite.c" + diff --git a/Board/Flash/STD/StdFlash.mak b/Board/Flash/STD/StdFlash.mak new file mode 100644 index 0000000..cd8af53 --- /dev/null +++ b/Board/Flash/STD/StdFlash.mak @@ -0,0 +1,71 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* +# $Header: /Alaska/SOURCE/Flash_Combined_2/Core/STD/StdFlash.mak 3 10/25/10 5:55a Calvinchen $Revision: +# +# $Date: 10/25/10 5:55a $Log: +# +#********************************************************************** + +# +# +# Name: FlashSrc.mak +# +# Description: +# +# +#********************************************************************** +all : STDFlash + +STDFlash : $(BUILD_DIR)\StdFlash.mak StdFlashBin + +#--------------------------------------------------------------------------- +# Generic STD FLASH dependencies +#--------------------------------------------------------------------------- +$(BUILD_DIR)\StdFlash.mak : $(STDFlash_DIR)\$(@B).cif $(STDFlash_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(STDFlash_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +#--------------------------------------------------------------------------- +# Create STD Flash Library +#--------------------------------------------------------------------------- +StdFlashBin : + @set INCLUDE=%%INCLUDE%% + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\STDFlash.mak all\ + "CFLAGS=$(CFLAGS:/W4=/W3)" \ + NAME=STDFlash \ + TYPE=LIBRARY LIBRARY_NAME=$(STDFLASHLIB) +!IF "$(x64_BUILD)"=="1" && "$(BUILD_PEI_FLASH_LIB)"=="1" + $(MAKE) /$(MAKEFLAGS) BUILD_ROOT=$(BUILD_DIR)\ + "EXT_OBJS=$(**:Build\=Build\IA32\)" PROJECT_DIR=$(PROJECT_DIR)\ + /f $(BUILD_DIR)\STDFlash.mak all\ + "CFLAGS=$(CFLAGS:/W4=/W3)"\ + BUILD_DIR=$(BUILD_DIR)\IA32\ + TYPE=PEI_LIBRARY NAME=STDFlash +!ENDIF + +$(STDFLASHLIB) : STDFlash + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* \ No newline at end of file diff --git a/Board/Flash/STD/StdFlash.sdl b/Board/Flash/STD/StdFlash.sdl new file mode 100644 index 0000000..298abaf --- /dev/null +++ b/Board/Flash/STD/StdFlash.sdl @@ -0,0 +1,133 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Flash_Combined_2/Core/STD/StdFlash.sdl 4 11/02/09 4:35a Calvinchen $ +# +# $Revision: 4 $ +# +# $Date: 11/02/09 4:35a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Flash_Combined_2/Core/STD/StdFlash.sdl $ +# +# 4 11/02/09 4:35a Calvinchen +# Added support for MXIC 29LV640DB/T and SST SST39VF1681/1682. +# +# 3 6/24/09 3:15a Calvinchen +# (EIP22177) Updated for Aptio Source Enhancement. +# +# +#********************************************************************** + +TOKEN + Name = "STDFlash_SUPPORT" + Value = "1" + Help = "Main switch to enable STD Flash support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "STDFLASHLIB" + Value = "$(BUILD_DIR)\STDFlash.lib" + TokenType = Expression + TargetMAK = Yes +End + +TOKEN + Name = "Spansion_29GLxxx" + Value = "1" + Help = "This enables support for the SPANSION 29GL01G/512/256/128P STD flash parts" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "Numonyx_256P30x" + Value = "1" + Help = "This token enables support for the Numonyx 256P30x and AB flash parts" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "Mxic_29LVxxx" + Value = "1" + Help = "This token enables support for the MXIC 29LVxxx and SST 39VF16xx flash parts" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +PATH + Name = "STDFlash_DIR" +End + +MODULE + Help = "Includes FlashSrc.mak to Project" + File = "STDFlash.mak" +End + +ELINK + Name = "mStdSpansionIdentify," + Parent = "FlashList" + Token = "Spansion_29GLxxx" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "IntelSTDIdentify," + Parent = "FlashList" + Token = "Numonyx_256P30x" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "mStdMxicIdentify," + Parent = "FlashList" + Token = "Mxic_29LVxxx" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(BUILD_DIR)\STDFlash.lib" + Parent = "$(Flash_DIR)\STDFlash.lib" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(Flash_DIR)\STDFlash.lib" + Parent = "FLASHLISTLIB" + InvokeOrder = AfterParent +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* \ No newline at end of file diff --git a/Board/Flash/STD/StdMxicFlashWrite.c b/Board/Flash/STD/StdMxicFlashWrite.c new file mode 100644 index 0000000..8271952 --- /dev/null +++ b/Board/Flash/STD/StdMxicFlashWrite.c @@ -0,0 +1,698 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/STD/StdMxicFlashWrite.c 7 1/20/12 5:00a Calvinchen $ +// +// $Revision: 7 $ +// +// $Date: 1/20/12 5:00a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/STD/StdMxicFlashWrite.c $ +// +// 7 1/20/12 5:00a Calvinchen +// Added support for SST 39VF160x/320x. +// +// 6 7/21/11 5:11a Calvinchen +// +// 5 2/10/11 5:39a Calvinchen +// [TAG] EIP50771 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Sometime vendor id return incorrect value. +// [RootCause] There should have a 10ns delay according SSTVF1681 +// specification. +// [Solution] Added an IO delay before read Vendor/Device ID. +// [Files] StdMxicFlashWrite.c +// +// 4 12/23/09 6:13a Calvinchen +// Improvement: +// 1.Added FWH/LPC/STD Flash Device Number support. +// 2.Changed for SMIFlash module Label "4.6.3.6_SMIFLASH_12" or later +// +// 3 12/15/09 5:50a Calvinchen +// 1. Modified for adding flash chip name support. +// 2. Bug fixed : Programming failed with SST 39VF1681. +// +// 2 11/16/09 1:51a Calvinchen +// +// 1 11/02/09 4:34a Calvinchen +// Added support for MXIC 29LV640DB/T and SST SST39VF1681/1682. +// +// +// +//************************************************************************* +// +// +// Name: MxicFlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include +#include +#include "FlashPart.h" +#include "token.h" + + +//---------------------------------------------------------------------- +// Local MACRO Definitions +#define UNLOCK 0 +#define LOCK 1 +#define SECTOR_SIZE_8KB 0x2000 // 8kbytes sector size +#define SECTOR_SIZE_64KB 0x10000 // 64kBytes sector size + +//---------------------------------------------------------------------------- +// Flash Part Specific Definitions + +#define Mx29LV640DB 0xcbc2 +#define Mx29LV640DT 0xc9c2 +#define Sst39VF1601 0x4bbf +#define Sst39VF1602 0x4abf +#define Sst39VF1681 0xc8bf +#define Sst39VF1682 0xc9bf +#define Sst39VF3201 0x5bbf +#define Sst39VF3202 0x5abf +#define Stm29W160ET 0xc420 +#define Stm29W160EB 0x4920 + +//---------------------------------------------------------------------------- +// Module level global data +extern UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; + +//---------------------------------------------------------------------------- +// Function Prototypes +VOID +MxicFlashEraseCommand ( + volatile UINT8 *pBlockAddress + ); +VOID +MxicFlashReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +VOID +MxicFlashProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +BOOLEAN +MxicFlashIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus + ); +BOOLEAN +MxicFlashIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus + ); +VOID +MxicFlashBlockWriteEnable ( + UINT8* pBlockAddress + ); +VOID +MxicFlashBlockWriteDisable ( + UINT8* pBlockAddress + ); +VOID +MxicFlashDeviceWriteEnable ( + VOID + ); +VOID +MxicFlashDeviceWriteDisable ( + VOID + ); +VOID +MxicFlashVirtualFixup ( + EFI_RUNTIME_SERVICES *pRS + ); + +extern FLASH_PART *FlashAPI; +//---------------------------------------------------------------------------- +// Module specific variables +FLASH_PART mStdMxicFlash = + { + MxicFlashReadCommand, + MxicFlashEraseCommand, + MxicFlashProgramCommand, + MxicFlashIsEraseCompleted, + MxicFlashIsProgramCompleted, + MxicFlashBlockWriteEnable, + MxicFlashBlockWriteDisable, + MxicFlashDeviceWriteEnable, + MxicFlashDeviceWriteDisable, + MxicFlashVirtualFixup, // Mxic flash device virtual address + // fix up routine + 1, // Number of bytes to program to the + // Flash part in each program command + SECTOR_SIZE_64KB, // Dummy value to hold place - only used in SPI + NULL // Flash Part Number Pointer + }; + +//---------------------------------------------------------------------------- +// Function definitions + +// +//---------------------------------------------------------------------------- +// Procedure: MxicResetFlash +// +// Description: This function resets the Mxic flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +MxicResetFlash ( + IN volatile UINT8* pAddress +) +{ + *pAddress = 0xf0; +} +// +//---------------------------------------------------------------------------- +// Procedure: MxicWriteBufferAbortReset +// +// Description: This function resets the Mxic flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +MxicWriteBufferAbortReset ( + IN volatile UINT8* pAddress +) +{ + pAddress[0xaaa] = 0xaa; + pAddress[0x555] = 0x55; + pAddress[0xaaa] = 0xf0; +} +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +static +VOID +MxicFlashReadCommand ( + IN volatile UINT8* pByteAddress, + OUT UINT8 *Byte, + OUT UINT32 *Length +) +{ + UINT32 dNumBytes = 0; + + // Changes for SMIFlash module label "4.6.3.6_SMIFLASH_12" or later. + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = *(UINT8*)((UINT32)pByteAddress + dNumBytes ); + *Length = 0; + return ; +} +// +//---------------------------------------------------------------------------- +// Procedure: MxicStdWaitForOperationCompleted +// +// Description: +// This function verifies whether the command sent to the FWH part +// has completed and returns the status of the command +// +// Input: +// IN volatile UINT8* pAddress Location to check the device status +// +// Output: +// EFI_SUCCESS - +// EFI_TIMEOUT - +// EFI_DEVICE_ERROR - +// +//---------------------------------------------------------------------------- +// +static +EFI_STATUS +MxicStdWaitForOperationCompleted ( + IN volatile UINT8* pAddress +) +{ + UINT8 bData1, bData2; + UINT32 dTimeout = FLASH_RETRIES * 0x1000000; + EFI_STATUS Status = EFI_TIMEOUT; + + do { + bData1 = (*pAddress) & 0x40; + bData2 = (*pAddress) & 0x40; + if ( bData1 == bData2 ) return EFI_SUCCESS; + dTimeout--; + } while ( dTimeout != 0 ); // Check for Bit 6 Toggle + + return EFI_TIMEOUT; +} + +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +// +// Returns: None +//---------------------------------------------------------------------------- +// +static +VOID +MxicFlashEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + EFI_STATUS Status; + UINT8 bFlashRetry; + UINT16 wNumSectors, wSector; + UINT32 i; + volatile UINT8* pSectorAddr; + + MxicWriteBufferAbortReset ( pBlockAddress ); + wNumSectors = ( FlashBlockSize / FlashAPI->FlashSectorSize ); + for ( wSector = 0; wSector < wNumSectors; wSector++ ) { + pSectorAddr = pBlockAddress + wSector * FlashAPI->FlashSectorSize; + for ( i = 0; i < FlashAPI->FlashSectorSize; i++ ) { + if ( *(pSectorAddr + i) != 0xFF ) break; + } + if ( i == FlashAPI->FlashSectorSize ) break; + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + pSectorAddr[0xaaa] = 0xaa; + pSectorAddr[0x555] = 0x55; + pSectorAddr[0xaaa] = 0x80; + pSectorAddr[0xaaa] = 0xaa; + pSectorAddr[0x555] = 0x55; + *pSectorAddr = 0x30; + Status = MxicStdWaitForOperationCompleted ( pSectorAddr ); + MxicWriteBufferAbortReset ( pSectorAddr ); + if ( Status != EFI_SUCCESS ) continue; + if ( *pSectorAddr != 0xFF ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + } +//- return Status; +} +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +MxicFlashIsEraseCompleted ( + IN volatile UINT8 *pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress - Location where the data to be written +// *Byte - Byte to be written +// *Length - Number of bytes to write +// +// Output: *Length - Number of bytes still left to write +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +MxicFlashProgramCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + volatile UINT8* pBlockAddress = (volatile UINT8*)BLOCK(pByteAddress); + UINT8 bFlashRetry; + EFI_STATUS Status = EFI_SUCCESS; + + + if ( *Byte != *pByteAddress ) { + MxicWriteBufferAbortReset ( pBlockAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + // Program Command Sequence + pBlockAddress[0xaaa] = 0xaa; + pBlockAddress[0x555] = 0x55; + pBlockAddress[0xaaa] = 0xa0; + *pByteAddress = *Byte; + Status = MxicStdWaitForOperationCompleted ( pBlockAddress ); +// MxicWriteBufferAbortReset ( pBlockAddress ); + if ( Status != EFI_SUCCESS ) continue; + if ( *pByteAddress != *Byte ) Status = EFI_DEVICE_ERROR; + else { + Status = EFI_SUCCESS; + break; + } + } + } else Status = EFI_SUCCESS; + *Length = *Length - 1; +} + +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// *Byte Pointer to data written +// Length Amount of data to check +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +MxicFlashIsProgramCompleted ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +MxicFlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ + +} + +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +MxicFlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ + +} + +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +MxicFlashDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +MxicFlashDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + +// +//---------------------------------------------------------------------------- +// Procedure: MxicFlashVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +static +VOID +MxicFlashVirtualFixup( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: mStdMxicIdentify +// +// Description: This function identifies the supported Mxic flash part and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +mStdMxicIdentify ( + IN volatile UINT8* pBlockAddress, + OUT FLASH_PART **Struct +) +{ + UINT8 bVenID, bDevID_1, bDevID_2; + + MxicWriteBufferAbortReset( pBlockAddress ); + + pBlockAddress[0xaaa] = 0xaa; + pBlockAddress[0x555] = 0x55; + pBlockAddress[0xaaa] = 0x90; + // Delay before read flash ID. + IoWrite8 ( 0xeb, 0x55 ); + bVenID = *pBlockAddress; + bDevID_1 = *(pBlockAddress + 0x01); + bDevID_2 = *(pBlockAddress + 0x02); + + MxicWriteBufferAbortReset( pBlockAddress ); + + // Check for SST39VF1681/1682 support. + switch ((bDevID_1 << 8) + bVenID) { + case Sst39VF1601: + case Sst39VF1602: + case Sst39VF1681: + case Sst39VF1682: + case Sst39VF3201: + case Sst39VF3202: + MemCpy ( pFlashDeviceNumber, "SST 39VF1681/1682/3201/3202", 27 ); + mStdMxicFlash.FlashPartNumber = pFlashDeviceNumber; + *Struct = &mStdMxicFlash; + return TRUE; + case Stm29W160ET: + case Stm29W160EB: + MemCpy ( pFlashDeviceNumber, "ST M29W160B/T", 13 ); + mStdMxicFlash.FlashSectorSize = SECTOR_SIZE_8KB; + mStdMxicFlash.FlashPartNumber = pFlashDeviceNumber; + *Struct = &mStdMxicFlash; + return TRUE; + } + // Check for Mxic 29LV640DB/T support. + switch ((bDevID_2 << 8) + bVenID) { + case Mx29LV640DB: + case Mx29LV640DT: + MemCpy ( pFlashDeviceNumber, "MXIC 29LV640B/T", 15 ); + mStdMxicFlash.FlashPartNumber = pFlashDeviceNumber; + *Struct = &mStdMxicFlash; + return TRUE; + } + return FALSE; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Board/Flash/STD/StdSpansionFlashWrite.c b/Board/Flash/STD/StdSpansionFlashWrite.c new file mode 100644 index 0000000..1bb80d5 --- /dev/null +++ b/Board/Flash/STD/StdSpansionFlashWrite.c @@ -0,0 +1,669 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2008, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/STD/StdSpansionFlashWrite.c 8 2/10/11 5:37a Calvinchen $ +// +// $Revision: 8 $ +// +// $Date: 2/10/11 5:37a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/STD/StdSpansionFlashWrite.c $ +// +// 8 2/10/11 5:37a Calvinchen +// [TAG] EIP50771 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Sometime vendor id return incorrect value. +// [RootCause] There should have a 10ns delay according SSTVF1681 +// specification. +// [Solution] Added an IO Delay before get vendor/Device i. +// [Files] StdSpansionFlashWrite.c +// +// 7 12/23/09 6:13a Calvinchen +// Improvement: +// 1.Added FWH/LPC/STD Flash Device Number support. +// 2.Changed for SMIFlash module Label "4.6.3.6_SMIFLASH_12" or later +// +// 6 12/15/09 5:50a Calvinchen +// 1. Modified for adding flash chip name support. +// 2. Bug fixed : Programming failed with SST 39VF1681. +// +// 5 6/24/09 3:15a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 2 1/14/09 10:37p Calvinchen +// +// 1 12/11/08 2:18a Calvinchen +// Added support for Spansion 29GL128/256/512/01GP STD flash. +// +// +// +//********************************************************************** + +// +// +// Name: SpansionFlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include +#include +#include "FlashPart.h" +#include "token.h" + + +//---------------------------------------------------------------------- +// Local MACRO Definitions +#define UNLOCK 0 +#define LOCK 1 + +//---------------------------------------------------------------------------- +// Flash Part Specific Definitions + +#define S29GL01GP_MANID 0x01 // offset 0x00 = Manufacturers ID +#define S29GL01GP_DEVID1 0x7e // offset 0x02 = Device ID byte 1 +#define S29GL01GP_DEVID2 0x28 // offset 0x1c = Device ID byte 2 +#define S29GL01GP_DEVID3 0x01 // offset 0x1e = Device ID byte 3 +#define Spansion29GLxxx 0x7e01 + +//---------------------------------------------------------------------------- +// Module level global data +extern UINT8 pFlashDeviceNumber[FLASH_PART_STRING_LENGTH]; + +//---------------------------------------------------------------------------- +// Function Prototypes +VOID +SpansionFlashEraseCommand ( + volatile UINT8 *pBlockAddress + ); +VOID +SpansionFlashReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +VOID +SpansionFlashProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Data, + UINT32 *Length + ); +BOOLEAN +SpansionFlashIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus + ); +BOOLEAN +SpansionFlashIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus + ); +VOID +SpansionFlashBlockWriteEnable ( + UINT8* pBlockAddress + ); +VOID +SpansionFlashBlockWriteDisable ( + UINT8* pBlockAddress + ); +VOID +SpansionFlashDeviceWriteEnable ( + VOID + ); +VOID +SpansionFlashDeviceWriteDisable ( + VOID + ); +VOID +SpansionFlashVirtualFixup ( + EFI_RUNTIME_SERVICES *pRS + ); + + + +//---------------------------------------------------------------------------- +// Module specific variables +FLASH_PART mStdSpansionFlash = + { + SpansionFlashReadCommand, + SpansionFlashEraseCommand, + SpansionFlashProgramCommand, + SpansionFlashIsEraseCompleted, + SpansionFlashIsProgramCompleted, + SpansionFlashBlockWriteEnable, + SpansionFlashBlockWriteDisable, + SpansionFlashDeviceWriteEnable, + SpansionFlashDeviceWriteDisable, + SpansionFlashVirtualFixup, // Spansion flash device virtual address + // fix up routine + 1, // Number of bytes to program to the + // Flash part in each program command + 0, // Dummy value to hold place - only used in SPI + NULL // Flash Part Number Pointer + }; + +//---------------------------------------------------------------------------- +// Function definitions + +// +//---------------------------------------------------------------------------- +// Procedure: SpansionResetFlash +// +// Description: This function resets the Spansion flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SpansionResetFlash ( + IN volatile UINT8* pAddress +) +{ + *pAddress = 0xf0; +} +// +//---------------------------------------------------------------------------- +// Procedure: SpansionWriteBufferAbortReset +// +// Description: This function resets the Spansion flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SpansionWriteBufferAbortReset ( + IN volatile UINT8* pAddress +) +{ + pAddress[0xaaa] = 0xaa; + pAddress[0x555] = 0x55; + pAddress[0x555] = 0xf0; +} +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +static +VOID +SpansionFlashReadCommand ( + IN volatile UINT8* pByteAddress, + OUT UINT8 *Byte, + OUT UINT32 *Length +) +{ + UINT32 dNumBytes = 0; + + // Changes for SMIFlash module label "4.6.3.6_SMIFLASH_12" or later. + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = *(UINT8*)((UINT32)pByteAddress + dNumBytes ); + *Length = 0; + return ; +} + +// +//---------------------------------------------------------------------------- +// Procedure: WaitForPollingCompleted +// +// Description: +// This function waits until the command sent to the flash part +// has completed +// +// Input: +// IN volatile UINT8* pAddress Location to check the device status +// IN UINT8 bData Polling Data +// +// Output: Nothing +// +//---------------------------------------------------------------------------- +// +static +EFI_STATUS +WaitForPollingCompleted ( + IN volatile UINT8* pAddress, + IN UINT8 bData +) +{ + UINT8 bStatus; + UINT32 dTimeout = FLASH_RETRIES * 0x10000; + EFI_STATUS Status = EFI_TIMEOUT; + + for ( ; dTimeout > 0; dTimeout-- ) { + // Read DQ0~7 + bStatus = *(volatile UINT8*)pAddress; + // Check DQ7 for Polling completed. + if ((bStatus & BIT07) == (bData & BIT07)) return EFI_SUCCESS; + // Check DQ5(Write Timeout),DQ3(Erase Timeout) and DQ1(Abort) for + // error occured. + if ( (bStatus & BIT05) || (bStatus & BIT03) || (bStatus & BIT01) ) { + bStatus = *(volatile UINT8*)pAddress; + if ((bStatus & BIT07) == (bData & BIT07)) return EFI_SUCCESS; + else return EFI_TIMEOUT; + } + } + return EFI_DEVICE_ERROR; +} +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +// +// Returns: None +//---------------------------------------------------------------------------- +// +static +VOID +SpansionFlashEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + EFI_STATUS Status; + UINT8 bFlashRetry; + + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + SpansionResetFlash ( pBlockAddress ); + pBlockAddress[0xaaa] = 0xaa; + pBlockAddress[0x555] = 0x55; + pBlockAddress[0xaaa] = 0x80; + pBlockAddress[0xaaa] = 0xaa; + pBlockAddress[0x555] = 0x55; + *pBlockAddress = 0x30; + Status = WaitForPollingCompleted ( pBlockAddress, 0xff ); + if ( Status != EFI_SUCCESS ) SpansionResetFlash ( pBlockAddress ); + if ( *pBlockAddress == 0xFF ) { + Status = EFI_SUCCESS; + break; + } else Status = EFI_DEVICE_ERROR; + } +//- return Status; +} +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +SpansionFlashIsEraseCompleted ( + IN volatile UINT8 *pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress - Location where the data to be written +// *Byte - Byte to be written +// *Length - Number of bytes to write +// +// Output: *Length - Number of bytes still left to write +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SpansionFlashProgramCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + volatile UINT8* pBlockAddress = (volatile UINT8*)BLOCK(pByteAddress); + UINT8 bFlashRetry; + EFI_STATUS Status = EFI_SUCCESS; + + + if ( *Byte != *pByteAddress ) { + SpansionResetFlash ( pBlockAddress ); + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + // Program Command Sequence - Write to Buffer + pBlockAddress[0xaaa] = 0xaa; + pBlockAddress[0x555] = 0x55; + *pByteAddress = 0x25; // write to buffer command. + *pByteAddress = 0; // write count - 1 + *pByteAddress = *Byte; // + *pByteAddress = 0x29; // program buffer to flash command. + Status = WaitForPollingCompleted ( pByteAddress, *Byte ); + if ( Status == EFI_TIMEOUT ) { + SpansionWriteBufferAbortReset ( pBlockAddress ); + continue; + } + if ( Status == EFI_DEVICE_ERROR ) + SpansionResetFlash ( pByteAddress ); + if ( *pByteAddress == *Byte ) { + Status = EFI_SUCCESS; + break; + } else Status = EFI_DEVICE_ERROR; + } + } else Status = EFI_SUCCESS; + *Length = *Length - 1; + //- return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// *Byte Pointer to data written +// Length Amount of data to check +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +static +BOOLEAN +SpansionFlashIsProgramCompleted ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + if ( pError ) *pError = TRUE; + if ( pStatus ) *pStatus = EFI_DEVICE_ERROR; + return FALSE; + } + } + if ( pError ) *pError = FALSE; + if ( pStatus ) *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SpansionFlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ + +} + +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SpansionFlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ + +} + +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SpansionFlashDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +SpansionFlashDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + +// +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// + +static +VOID +SpansionFlashVirtualFixup( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: mStdSpansionIdentify +// +// Description: This function identifies the supported Spansion flash part and +// returns appropriate flash device API pointer. If flash part is +// not supported by this module it will return FALSE. +// +// +// Input: pBlockAddress Block address of the flash part. Can be used to +// send ID command +// +// Output: **FlashApi Pointer to hold the returned flash API +// +// Return: TRUE If flash part is supported, FlashApi contains +// routines to handle the flash requests +// FALSE Flash part is not supported +// +// Note: This routine is part of the global flash init list. Make sure +// it is properly linked to the init list "FlashList" (in SDL file) +//---------------------------------------------------------------------------- +// +BOOLEAN +mStdSpansionIdentify ( + IN volatile UINT8* pBlockAddress, + OUT FLASH_PART **Struct +) +{ + UINT8 MID; + UINT8 DID1, DID2, DID3; + + SpansionResetFlash( pBlockAddress ); + + pBlockAddress[0xaaa] = 0xaa; + pBlockAddress[0x555] = 0x55; + pBlockAddress[0xaaa] = 0x90; + // Delay before read flash ID. + IoWrite8 ( 0xeb, 0x55 ); + MID = *pBlockAddress; + DID1 = *(pBlockAddress + 0x02); + DID2 = *(pBlockAddress + 0x1c); + DID3 = *(pBlockAddress + 0x1e); + + SpansionResetFlash( pBlockAddress ); + + // Check MID & DID1 for S29GL01G/512/256/128P support. + if ((MID == S29GL01GP_MANID) && (DID1 == S29GL01GP_DEVID1)) { + MemCpy ( pFlashDeviceNumber, "Spansion S29GL128/256/512/01GP", 30 ); + mStdSpansionFlash.FlashPartNumber = pFlashDeviceNumber; + *Struct = &mStdSpansionFlash; + return TRUE; + } + return FALSE; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2008, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* -- cgit v1.2.3