summaryrefslogtreecommitdiff
path: root/Board/Flash
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Board/Flash
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Board/Flash')
-rw-r--r--Board/Flash/FWH/FwhFlash.cif11
-rw-r--r--Board/Flash/FWH/FwhFlash.mak94
-rw-r--r--Board/Flash/FWH/FwhFlash.sdl113
-rw-r--r--Board/Flash/FWH/FwhIntelFlashWrite.c769
-rw-r--r--Board/Flash/FWH/FwhSstFlashWrite.c695
-rw-r--r--Board/Flash/Flash.chmbin0 -> 113742 bytes
-rw-r--r--Board/Flash/Flash.cif18
-rw-r--r--Board/Flash/Flash.mak118
-rw-r--r--Board/Flash/Flash.sdl212
-rw-r--r--Board/Flash/FlashUpdate.c367
-rw-r--r--Board/Flash/FlashWrite.c697
-rw-r--r--Board/Flash/LPC/LpcFlash.cif11
-rw-r--r--Board/Flash/LPC/LpcFlash.mak99
-rw-r--r--Board/Flash/LPC/LpcFlash.sdl114
-rw-r--r--Board/Flash/LPC/LpcFlashWrite.c715
-rw-r--r--Board/Flash/LPC/LpcSst2MblFlashWrite.c734
-rw-r--r--Board/Flash/SPI/ICHx/ICHxSpi.sdl86
-rw-r--r--Board/Flash/SPI/ICHx/SPIFlash.c1369
-rw-r--r--Board/Flash/SPI/ICHx/SpiCspSrc.cif9
-rw-r--r--Board/Flash/SPI/SpiFlash.cif14
-rw-r--r--Board/Flash/SPI/SpiFlash.h531
-rw-r--r--Board/Flash/SPI/SpiFlash.mak115
-rw-r--r--Board/Flash/SPI/SpiFlash.sdl232
-rw-r--r--Board/Flash/SPI/SpiIdentify.c865
-rw-r--r--Board/Flash/SPI/Template/SPIFlash.c1038
-rw-r--r--Board/Flash/SPI/Template/SpiCspSrc.cif8
-rw-r--r--Board/Flash/STD/STDIntelFlashWrite.c699
-rw-r--r--Board/Flash/STD/StdFlash.cif12
-rw-r--r--Board/Flash/STD/StdFlash.mak71
-rw-r--r--Board/Flash/STD/StdFlash.sdl133
-rw-r--r--Board/Flash/STD/StdMxicFlashWrite.c698
-rw-r--r--Board/Flash/STD/StdSpansionFlashWrite.c669
32 files changed, 11316 insertions, 0 deletions
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 @@
+<component>
+ name = "FWH Interface - Source"
+ category = ModulePart
+ LocalRoot = "Board\Flash\FWH"
+ RefName = "FWH_INTERFACE_SOURCE"
+[files]
+"FwhFlash.sdl"
+"FwhFlash.mak"
+"FwhSstFlashWrite.c"
+"FwhIntelFlashWrite.c"
+<endComponent>
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
+#
+#
+#**********************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FWHFlash.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+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
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FlashWrite.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 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
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IntelFwhCmdDelay
+//
+// Description: This function resets the Sst flash part
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+IntelFwhCmdDelay (VOID)
+{
+ IoWrite8 ( 0xeb, 0x55 );
+ IoWrite8 ( 0xeb, 0xaa );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IntelFwhResetFlash
+//
+// Description: This function resets the Sst flash part
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+IntelFwhResetFlash (
+ IN volatile UINT8* pAddress
+)
+{
+ *pAddress = READ_ARRAY_CMD;// Return to read mode
+ IntelFwhCmdDelay ();
+ *pAddress = CLR_STATUS_CMD;// clear status
+ IntelFwhCmdDelay ();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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 -
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+
+//<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;
+ 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;
+ }
+ }
+ }
+}
+
+//<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;
+
+ 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;
+}
+
+//<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 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 ;
+}
+
+//<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;
+ ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \
+ FwhFeatureSpaceBase + 0x8000))[2] = LockState;
+ ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \
+ FwhFeatureSpaceBase + 0xA000))[2] = LockState;
+ ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \
+ FwhFeatureSpaceBase + 0xC000))[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: 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)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//
+// Name: FlashWrite.c
+//
+// Description: Flash update routines
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------
+// Includes
+#include <efi.h>
+#include <AmiDxeLib.h> //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
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SstFwhResetFlash
+//
+// Description: This function resets the SST flash part
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+SstFwhResetFlash (
+ IN volatile UINT8* pAddress
+)
+{
+ pAddress[0x5555] = 0xaa;
+ pAddress[0x2aaa] = 0x55;
+ pAddress[0x5555] = 0xf0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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 -
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<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: SSTFlashBlockWriteEnable
+//
+// 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
+SstFlashBlockWriteEnable (
+ IN UINT8* pBlockAddress
+)
+{
+ SetBlockLock(pBlockAddress, UNLOCK);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SSTFlashBlockWriteDisable
+//
+// 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
+SstFlashBlockWriteDisable (
+ IN UINT8* pBlockAddress
+)
+{
+ SetBlockLock(pBlockAddress, WRITE_LOCK);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SSTFlashDeviceWriteEnable
+//
+// Description: This function contains any flash specific code need to
+// enable flash write
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+SstFlashDeviceWriteEnable (VOID)
+{
+ //We don't have to do anything here because
+ //Flash Device is write enabled by the South Bridge driver
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SSTFlashDeviceWriteDisable
+//
+// Description: This function contains any flash specific code need to
+// disable flash write
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+SstFlashDeviceWriteDisable (VOID)
+{
+ //We don't have to do anything here because
+ //we always keep flash device in the write enabled state
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static
+VOID
+SstFlashVirtualFixup(
+ IN EFI_RUNTIME_SERVICES *pRS
+)
+{
+
+// // Following is an example code for virtual address conversion
+// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase);
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
--- /dev/null
+++ b/Board/Flash/Flash.chm
Binary files 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 @@
+<component>
+ 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"
+<endComponent>
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
+#
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#
+# Name: Flash.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+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
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FlashUpdate.c
+//
+// Description: Provides the rom flashing functions to the system
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+// header includes
+#include <EFI.h>
+#include <Flash.h>
+#include <Token.h>
+
+//----------------------------------------------------------------------
+// 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
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FlashEraseBlock (
+ IN volatile UINT8* BlockAddress
+)
+{
+ BOOLEAN Error = FALSE;
+ BOOLEAN Completed = TRUE;
+
+ FlashEraseCommand(BlockAddress);
+
+ while(!(Completed = FlashIsEraseCompleted(BlockAddress, &Error, NULL)));
+
+ return Completed && !Error;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FlashRead (
+ IN volatile UINT8* Address,
+ OUT UINT8 *Data,
+ IN UINT32 Length
+)
+{
+ FlashReadCommand(Address,Data,Length);
+
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FlashProgramBlock (
+ IN UINT8* pBlock,
+ IN UINT8* pData
+)
+{
+ return FlashProgram(pBlock,pData,FlashBlockSize);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FlashWrite.c
+//
+// Description: Flash update routines
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------
+// Includes
+#include <EFI.h>
+#include <Token.h>
+#include <Flash.h>
+#include <FlashPart.h>
+#if defined _DXE_FLASH_LIB_
+#include <AmiDxeLib.h>
+#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 );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+FlashEraseCommand (
+ IN volatile UINT8* pBlockAddress
+)
+{
+ if ( FlashAPI == NULL)
+ FlashInit(pBlockAddress);
+
+ // if FlashAPI is still NULL return
+ if ( FlashAPI == NULL)
+ return;
+
+ FlashAPI->FlashEraseCommand(pBlockAddress);
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+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);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+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);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+FlashBlockWriteEnable (
+ IN UINT8* pBlockAddress
+)
+{
+ if ( FlashAPI == NULL)
+ FlashInit(pBlockAddress);
+
+ // if FlashAPI is still NULL return
+ if ( FlashAPI == NULL)
+ return;
+
+ FlashAPI->FlashBlockWriteEnable(pBlockAddress);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+FlashBlockWriteDisable (
+ IN UINT8* pBlockAddress
+)
+{
+ if ( FlashAPI == NULL)
+ FlashInit(pBlockAddress);
+
+ // if FlashAPI is still NULL return
+ if ( FlashAPI == NULL)
+ return;
+
+ FlashAPI->FlashBlockWriteDisable(pBlockAddress);
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+FlashDeviceWriteEnable (VOID)
+{
+ OemFlashDeviceWriteEnable ();
+
+ ChipsetFlashDeviceWriteEnable();
+
+ if ( FlashAPI == NULL)
+ FlashInit((UINT8 *)FlashDeviceBase);
+
+ // if FlashAPI is still NULL return
+ if ( FlashAPI == NULL)
+ return;
+
+ FlashAPI->FlashDeviceWriteEnable();
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+FlashDeviceWriteDisable (VOID)
+{
+ ChipsetFlashDeviceWriteDisable();
+
+ if ( FlashAPI == NULL)
+ FlashInit((UINT8 *)FlashDeviceBase);
+
+ // if FlashAPI is still NULL return
+ if ( FlashAPI == NULL)
+ return;
+
+ FlashAPI->FlashDeviceWriteDisable();
+
+ OemFlashDeviceWriteDisable ();
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: OemFlashDeviceWriteEnable
+//
+// Description: This function goes through the elinked list of oem flash
+// write enable functions giving control.
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+OemFlashDeviceWriteEnable (VOID)
+{
+ UINT8 i;
+
+ if ( gbDeviceWriteState != TRUE ) {
+ gbDeviceWriteState = TRUE;
+ for(i = 0; OemFlashWriteEnable[i] != NULL; i++)
+ OemFlashWriteEnable[i]();
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: OemFlashDeviceWriteDisable
+//
+// Description: This function goes through the elinked list of oem flash
+// write disable functions giving control.
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+OemFlashDeviceWriteDisable (VOID)
+{
+ UINT8 i;
+
+ if ( gbDeviceWriteState != FALSE ) {
+ gbDeviceWriteState = FALSE;
+ for(i = 0; OemFlashWriteDisable[i] != NULL; i++)
+ OemFlashWriteDisable[i]();
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+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_
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 @@
+<component>
+ name = "LPC Interface - Source"
+ category = ModulePart
+ LocalRoot = "Board\Flash\LPC"
+ RefName = "LPC_INTERFACE_SOURCE"
+[files]
+"LpcFlash.sdl"
+"LpcFlash.mak"
+"LpcFlashWrite.c"
+"LpcSst2MblFlashWrite.c"
+<endComponent>
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
+#
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#
+# Name: FlashSrc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+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
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// 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
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------------
+// Includes
+#include <efi.h>
+#include <AmiDxeLib.h>
+#include <FlashPart.h>
+#include <token.h>
+
+//----------------------------------------------------------------------------
+// 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
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+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 ;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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:
+//----------------------------------------------------------------------------
+//<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: LpcFlashBlockWriteEnable
+//
+// 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>
+VOID
+LpcFlashBlockWriteEnable (
+ IN UINT8 *pBlockAddress
+)
+{
+ SetBlockLock(pBlockAddress, UNLOCK);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LpcFlashBlockWriteDisable
+//
+// 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>
+VOID
+LpcFlashBlockWriteDisable (
+ IN UINT8 *pBlockAddress
+)
+{
+ SetBlockLock(pBlockAddress, WRITE_LOCK);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LpcFlashDeviceWriteEnable
+//
+// Description: This function contains any flash specific code need to
+// enable flash write
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+LpcFlashDeviceWriteEnable (VOID)
+{
+ // Flash device does not support this feature
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LpcFlashDeviceWriteDisable
+//
+// Description: This function contains any flash specific code need to
+// disable flash write
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+LpcFlashDeviceWriteDisable (VOID)
+{
+ // Flash device does not support this feature
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+LpcFlashVirtualFixup (
+ IN EFI_RUNTIME_SERVICES *pRS
+)
+{
+// // Following is an example code for virtual address conversion
+// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase);
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LpcResetFlash
+//
+// Description: This function resets the Lpc flash part
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+LpcResetFlash (
+ IN volatile UINT8* pBlockAddress)
+{
+ pBlockAddress[0x5555] = COMMAND_SEQUENCE_1;
+ pBlockAddress[0x2aaa] = COMMAND_SEQUENCE_2;
+ pBlockAddress[0x5555] = LPC_RESET_CMD;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
+//
+//
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: LpcSst2MblFlashWrite.c
+//
+// Description: Support routines for the LPC Sst 2Mb part
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------
+// Includes
+#include <efi.h>
+#include <FlashPart.h>
+#include <AmiDxeLib.h>
+#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
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Sst2mLpcCmdDelay
+//
+// Description: This function resets the Sst flash part
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+Sst2mLpcCmdDelay (VOID)
+{
+ IoWrite8 ( 0xeb, 0x55 );
+ IoWrite8 ( 0xeb, 0xaa );
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Sst2mLpcResetFlash
+//
+// Description: This function resets the Sst flash part
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+Sst2mLpcResetFlash (
+ IN volatile UINT8* pAddress
+)
+{
+ *pAddress = READ_ARRAY_CMD;// Return to read mode
+ Sst2mLpcCmdDelay ();
+ *pAddress = CLR_STATUS_CMD;// clear status
+ Sst2mLpcCmdDelay ();
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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 -
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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:
+//----------------------------------------------------------------------------
+//<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;
+ ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \
+ FwhFeatureSpaceBase + 0x8000))[2] = LockState;
+ ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \
+ FwhFeatureSpaceBase + 0xA000))[2] = LockState;
+ ((UINT8 *)((UINTN)pBlockAddress - FlashDeviceBase + \
+ FwhFeatureSpaceBase + 0xC000))[2] = LockState;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SstLpcBlockWriteEnable
+//
+// Description: This function contains any flash specific code need to
+// enable a particular flash block write
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+SstLpcBlockWriteEnable (
+ IN UINT8* pBlockAddress
+)
+{
+ SetBlockLock(pBlockAddress, UNLOCK);
+//- return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SstLpcBlockWriteDisable
+//
+// Description: This function contains any flash specific code need to
+// disable a particular flash block write
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+SstLpcBlockWriteDisable (
+ IN UINT8* pBlockAddress
+)
+{
+ SetBlockLock(pBlockAddress, WRITE_LOCK);
+//- return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SstLpcDeviceWriteEnable
+//
+// Description: This function contains any flash specific code need to
+// enable flash write
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+SstLpcDeviceWriteEnable (VOID)
+{
+ //We don't have to do anything here because
+ //Flash Device is write enabled by the South Bridge driver
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SstLpcDeviceWriteDisable
+//
+// Description: This function contains any flash specific code need to
+// disable flash write
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID
+SstLpcDeviceWriteDisable (VOID)
+{
+ //We don't have to do anything here because
+ //we always keep flash device in the write enabled state
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+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
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FlashWrite.c
+//
+// Description: Flash update routines
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+#include <efi.h>
+#include <AmiDxeLib.h>
+#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
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SpiIoDelay
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SpiIoDelay (VOID)
+{
+ UINT8 bTimeout;
+ for ( bTimeout = 0; bTimeout < 33; bTimeout++ ) {
+ IoWrite8( 0xEB, 0x55 );
+ IoWrite8( 0xEB, 0xAA );
+ }
+ return ;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitForSpiCycleDone
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SpiWriteDisable
+//
+// Description: This procedure issuess SPI Write Disable if AAIWordProgram.
+//
+// Input: None.
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+CheckAaiWordProram (
+ IN UINT32 dAddr,
+ IN UINT32 dLength
+)
+{
+ if ((mExFlashPart.AAIWordProgram != 0) && !(dAddr & 1) && (dLength >= 2))
+ return TRUE;
+ return FALSE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonSpiReadStatus
+//
+// Description:
+//
+// Input: None.
+//
+// Output: Status Register which is read from SPI flash.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ) );
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitForWriteOperationCompleted
+//
+// Description:
+//
+// Input: None.
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonSpiWriteStatus
+//
+// Description: Routine for Write SPI Status Register.
+//
+// Input: None.
+//
+// Output: Status Register which is read from SPI flash.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonSpiReadByte
+//
+// Description:
+//
+// Input: dByteAddress Address that need to be read.
+//
+// Output: BYTE Value which is read from SPI flash.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+CommonSpiReadByte (
+ IN UINT32 dByteAddress
+)
+{
+ UINT8 bData;
+ UINT32 dLength = sizeof(UINT8);
+ CommonSpiReadCommand((volatile UINT8*)dByteAddress, &bData, &dLength);
+ return bData;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonConvertSpiAddress
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InitializeSpiEnvironment
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SerialFlashDiscoveryForQuadRead
+//
+// Description: This procedure checks SPI Quad Read support through SFDP.
+//
+// Input: None.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GlobalBlockProtectionUnlock
+//
+// Description: This procedure unlocks "Global Block Protection" for Microchip
+// 26VF series flash parts.
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ]+>>>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: RemoveWriteStatusOpcode
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ]+<<<
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ReinitializeSpiEnvironment
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ]+<<<
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonSpiReadId
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+ }
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 );
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CommonSpiBlockWriteEnable (
+ IN volatile UINT8 *pBlockAddress
+)
+{
+ SpiBlockProtectUpdate (pBlockAddress, 0);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CommonSpiBlockWriteDisable (
+ IN volatile UINT8 *pBlockAddress
+)
+{
+#if BLOCK_PROTECT_ENABLE
+ SpiBlockProtectUpdate (pBlockAddress, 0xff);
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CommonSpiDeviceWriteEnable
+//
+// Description: This function contains any flash specific code need to
+// enable flash write
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CommonSpiDeviceWriteEnable (VOID)
+{
+ // check is DeviceWrite enabled, if yes, don't enable it again,
+ // else, enable it.
+ if ( !gbDeviceWriteEnabled ) {
+ gbDeviceWriteEnabled = 1;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CommonSpiDeviceWriteDisable
+//
+// Description: This function contains any flash specific code need to
+// disable flash write
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CommonSpiDeviceWriteDisable (VOID)
+{
+ // check is DeviceWrite enabled, if yes, disable it,
+ // if no, don't disable it.
+ if ( gbDeviceWriteEnabled ) {
+ gbDeviceWriteEnabled = 0;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 @@
+<component>
+ name = "CSP : Intel ICHx SPI - Source"
+ category = ModulePart
+ LocalRoot = "Board\Flash\SPI\ICHx"
+ RefName = "ICHX_SPI_CSP_SOURCE"
+[files]
+"ICHxSpi.sdl"
+"SPIFlash.c"
+<endComponent>
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 @@
+<component>
+ 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"
+<endComponent>
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
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SpiFlash.h
+//
+// Description: Contains Vendor IDs and Device IDs for ths supported
+// parts. also contains the command values for each supported part
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _SPIFlash_H_
+#define _SPIFlash_H_
+
+
+#include <token.h>
+#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
+
+//<AMI_STHDR_START>
+//============================================================================
+// 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
+//============================================================================
+//<AMI_STHDR_END>
+#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
+#
+#
+#**********************************************************************
+
+
+#<AMI_FHDR_START>
+#
+# Name: FlashSrc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+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
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SpiIdentify.c
+//
+// Description: Provides device specific indentify functions for the
+// supported spi parts
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------------
+// Includes
+#include <efi.h>
+#include <AmiDxeLib.h>
+#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
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: StmCheckMemoryCapacity
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 );
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SpansionCheckMemoryCapacity
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 );
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IntelCheckMemoryCapacity
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 );
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SstCheckMemoryCapacity
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 );
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FlashWrite.c
+//
+// Description: Flash update routines
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+#include <efi.h>
+#include <AmiDxeLib.h>
+#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
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IoDelay
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+IoDelay (VOID)
+{
+ UINT8 bTimeout;
+ for ( bTimeout = 0; bTimeout < 33; bTimeout++ ) {
+ IoWrite8( 0xEB, 0x55 );
+ IoWrite8( 0xEB, 0xAA );
+ }
+ return ;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitForSpiCycleDone
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ---------------------*/
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonSpiReadStatus
+//
+// Description:
+//
+// Input: None.
+//
+// Output: Status Register which is read from SPI flash.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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.
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitForWriteOperationCompleted
+//
+// Description:
+//
+// Input: None.
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ---------------------*/
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonSpiWriteStatus
+//
+// Description: Routine for Write SPI Status Register.
+//
+// Input: None.
+//
+// Output: Status Register which is read from SPI flash.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ---------------------*/
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonSpiReadByte
+//
+// Description:
+//
+// Input: dByteAddress Address that need to be read.
+//
+// Output: BYTE Value which is read from SPI flash.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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.
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonConvertSpiAddress
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InitializeSpiEnvironment
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ---------------------*/
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ReinitializeSpiEnvironment
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ReinitializeSpiEnvironment (
+ IN FLASH_INFO *FlashInfo
+)
+{
+ return ;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CommonSpiReadId
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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.
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ---------------------*/
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ---------------------*/
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 ---------------------*/
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CommonSpiDeviceWriteEnable
+//
+// Description: This function contains any flash specific code need to
+// enable flash write
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CommonSpiDeviceWriteEnable (VOID)
+{
+ // check is DeviceWrite enabled, if yes, don't enable it again, else, enable it.
+ if ( !gbDeviceWriteEnabled ) {
+ gbDeviceWriteEnabled = 1;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CommonSpiDeviceWriteDisable
+//
+// Description: This function contains any flash specific code need to
+// disable flash write
+//
+// Input: None
+//
+// Output: None
+//
+// Return: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CommonSpiDeviceWriteDisable (VOID)
+{
+ // check is DeviceWrite enabled, if yes, disable it,
+ // if no, don't disable it.
+ if ( gbDeviceWriteEnabled ) {
+ gbDeviceWriteEnabled = 0;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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 @@
+<component>
+ name = "CSP : DUMMY SPI - Do Not Delete"
+ category = ModulePart
+ LocalRoot = "Board\Flash\SPI\Template"
+ RefName = "DUMMY_SPI_CSP_SOURCE"
+[files]
+"SPIFlash.c"
+<endComponent>
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 **
+//** **
+//*************************************************************************
+//*************************************************************************