diff options
Diffstat (limited to 'Board/Flash/STD')
-rw-r--r-- | Board/Flash/STD/STDIntelFlashWrite.c | 699 | ||||
-rw-r--r-- | Board/Flash/STD/StdFlash.cif | 12 | ||||
-rw-r--r-- | Board/Flash/STD/StdFlash.mak | 71 | ||||
-rw-r--r-- | Board/Flash/STD/StdFlash.sdl | 133 | ||||
-rw-r--r-- | Board/Flash/STD/StdMxicFlashWrite.c | 698 | ||||
-rw-r--r-- | Board/Flash/STD/StdSpansionFlashWrite.c | 669 |
6 files changed, 2282 insertions, 0 deletions
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: $ +// +// +// +//********************************************************************** + +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: StdIntelFlashWrite.c +// +// Description: Flash update routines +// +//<AMI_FHDR_END> +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include <efi.h> +#include <FlashPart.h> +#include <AmiDxeLib.h> +#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 +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IntelSTDCmdDelay +// +// Description: This function resets the Sst flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID +IntelSTDCmdDelay (VOID) +{ + IoWrite8 ( 0xeb, 0x55 ); + IoWrite8 ( 0xeb, 0xaa ); +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IntelSTDResetFlash +// +// Description: This function resets the Sst flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +IntelSTDResetFlash ( + IN volatile UINT8* pAddress +) +{ + *pAddress = READ_ARRAY_CMD;// Return to read mode + IntelSTDCmdDelay (); + *pAddress = CLR_STATUS_CMD;// clear status + IntelSTDCmdDelay (); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 - +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +void +SetBlockLock ( + IN volatile UINT8* pBlockAddress, + IN UINT8 LockState +) +{ +//- // Update the block lock register +//- ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase +//- + FwhFeatureSpaceBase))[2] = LockState; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IntelFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +IntelFlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ +//- SetBlockLock(pBlockAddress, UNLOCK); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IntelFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +IntelFlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ +//- SetBlockLock(pBlockAddress, WRITE_LOCK); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IntelFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +IntelFlashDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IntelFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +IntelFlashDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +static +VOID +IntelFlashVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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) +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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 @@ +<component> + 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" +<endComponent> 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: +# +#********************************************************************** + +#<AMI_FHDR_START> +# +# Name: FlashSrc.mak +# +# Description: +# +#<AMI_FHDR_END> +#********************************************************************** +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. +// +// +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: MxicFlashWrite.c +// +// Description: Flash update routines +// +//<AMI_FHDR_END> +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include <efi.h> +#include <AmiDxeLib.h> +#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 + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: MxicResetFlash +// +// Description: This function resets the Mxic flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +MxicResetFlash ( + IN volatile UINT8* pAddress +) +{ + *pAddress = 0xf0; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: MxicWriteBufferAbortReset +// +// Description: This function resets the Mxic flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +MxicWriteBufferAbortReset ( + IN volatile UINT8* pAddress +) +{ + pAddress[0xaaa] = 0xaa; + pAddress[0x555] = 0x55; + pAddress[0xaaa] = 0xf0; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +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 ; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 - +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: MxicFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +MxicFlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: MxicFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +MxicFlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: MxicFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +MxicFlashDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: MxicFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +MxicFlashDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +static +VOID +MxicFlashVirtualFixup( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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) +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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. +// +// +// +//********************************************************************** + +//<AMI_FHDR_START> +// +// Name: SpansionFlashWrite.c +// +// Description: Flash update routines +// +//<AMI_FHDR_END> +//********************************************************************** + +//---------------------------------------------------------------------- +// Includes +#include <efi.h> +#include <AmiDxeLib.h> +#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 + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SpansionResetFlash +// +// Description: This function resets the Spansion flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +SpansionResetFlash ( + IN volatile UINT8* pAddress +) +{ + *pAddress = 0xf0; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SpansionWriteBufferAbortReset +// +// Description: This function resets the Spansion flash part +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +SpansionWriteBufferAbortReset ( + IN volatile UINT8* pAddress +) +{ + pAddress[0xaaa] = 0xaa; + pAddress[0x555] = 0x55; + pAddress[0x555] = 0xf0; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +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 ; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +SpansionFlashBlockWriteEnable ( + IN UINT8* pBlockAddress +) +{ + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +SpansionFlashBlockWriteDisable ( + IN UINT8* pBlockAddress +) +{ + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +SpansionFlashDeviceWriteEnable (VOID) +{ + //We don't have to do anything here because + //Flash Device is write enabled by the South Bridge driver +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SpansionFlashDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +SpansionFlashDeviceWriteDisable (VOID) +{ + //We don't have to do anything here because + //we always keep flash device in the write enabled state +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +static +VOID +SpansionFlashVirtualFixup( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + + return; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// 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) +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +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 ** +//** ** +//************************************************************************* +//************************************************************************* |