From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- Board/Flash/SPI/Template/SPIFlash.c | 1038 ++++++++++++++++++++++++++++++++ Board/Flash/SPI/Template/SpiCspSrc.cif | 8 + 2 files changed, 1046 insertions(+) create mode 100644 Board/Flash/SPI/Template/SPIFlash.c create mode 100644 Board/Flash/SPI/Template/SpiCspSrc.cif (limited to 'Board/Flash/SPI/Template') diff --git a/Board/Flash/SPI/Template/SPIFlash.c b/Board/Flash/SPI/Template/SPIFlash.c new file mode 100644 index 0000000..d7677b5 --- /dev/null +++ b/Board/Flash/SPI/Template/SPIFlash.c @@ -0,0 +1,1038 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Flash_Combined_2/Core/SPI/Template/SpiFlash.c 4 6/24/09 3:14a Calvinchen $ +// +// $Revision: 4 $ +// +// $Date: 6/24/09 3:14a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Flash_Combined_2/Core/SPI/Template/SpiFlash.c $ +// +// 4 6/24/09 3:14a Calvinchen +// (EIP22177) Updated for Aptio Source Enhancement. +// +// 3 4/27/09 3:24a Calvinchen +// 2.(EIP20459) Added Multiple SPI CSP component support. +// +// 2 6/19/08 4:30a Calvinchen +// +// 1 3/13/08 6:32a Calvinchen +// +//********************************************************************** +// +// +// Name: FlashWrite.c +// +// Description: Flash update routines +// +// +//********************************************************************** +//---------------------------------------------------------------------------- +// Includes +#include +#include +#include "FlashPart.h" +#include "SpiFlash.h" +#include "token.h" +//---------------------------------------------------------------------------- +// Local defines for transaction types +/* --------------------- PORTING REQUIRED --------------------- + +// ICH8/9/10 SPI register defines. +#define SPI_STS 0x90 // SPI Status +#define SPI_CTL 0x91 // SPI Control +#define SPI_ADR 0x08 // SPI Address +#define SPI_DAT0 0x10 // SPI Data 0 +#define SPI_PREOP 0x94 // Prefix Opcode Configuration +#define SPI_OPTYPE 0x96 // Opcode Type Configuration +#define SPI_OPMENU 0x98 // Opcode Menu Configuration +// SPI default opcode slots +#define SPI_OPCODE_WRITE_INDEX 0x0 +#define SPI_OPCODE_READ_INDEX 0x1 +#define SPI_OPCODE_ERASE_INDEX 0x2 +#define SPI_OPCODE_READ_S_INDEX 0x3 +#define SPI_OPCODE_READ_ID_INDEX 0x4 +#define SPI_OPCODE_WRITE_S_INDEX 0x5 +#define SPI_OPCODE_WRITE_E_INDEX 0x6 +#define SPI_OPCODE_WRITE_S_E_INDEX 0x7 +#define SPI_PREFIX_WRITE_S_EN 0x1 +#define SPI_PREFIX_WRITE_EN 0x0 +#define SPI_MAX_DATA_TRANSFER 0x40 + --------------------- PORTING REQUIRED ---------------------*/ +//---------------------------------------------------------------------------- +// Module level global data +//============================================================================ +extern UINT16 gFlashId; +extern FLASH_PART *FlashAPI; +//---------------------------------------------------------------------------- +// Function Externs +//-extern +//-VOID +//-SpiChipsetVirtualFixup ( +//- IN EFI_RUNTIME_SERVICES *pRS +//-); +//---------------------------------------------------------------------------- +// Local prototypes +VOID +CommonSpiEraseCommand ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiProgramCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 *Length +); +VOID +CommonSpiReadCommand ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 *Length +); +BOOLEAN +CommonSpiIsEraseCompleted ( + volatile UINT8 *pBlockAddress, + BOOLEAN *pError, + UINTN *pStatus +); +BOOLEAN +CommonSpiIsProgramCompleted ( + volatile UINT8 *pByteAddress, + UINT8 *Byte, + UINT32 Length, + BOOLEAN *pError, + UINTN *pStatus +); +VOID +CommonSpiBlockWriteEnable ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiBlockWriteDisable ( + volatile UINT8 *pBlockAddress +); +VOID +CommonSpiDeviceWriteEnable ( + VOID +); +VOID +CommonSpiDeviceWriteDisable ( + VOID +); +VOID +CommonSpiDeviceVirtualFixup ( + EFI_RUNTIME_SERVICES *pRS +); +//============================================================================ +// Local Variables +//============================================================================ +FLASH_PART mCommonSpiFlash ={ + CommonSpiReadCommand, + CommonSpiEraseCommand, + CommonSpiProgramCommand, + CommonSpiIsEraseCompleted, + CommonSpiIsProgramCompleted, + CommonSpiBlockWriteEnable, + CommonSpiBlockWriteDisable, + CommonSpiDeviceWriteEnable, + CommonSpiDeviceWriteDisable, + CommonSpiDeviceVirtualFixup, + 1, // default value, should be changed in Init function + SECTOR_SIZE_4KB +}; +EX_FLASH_PART mExFlashPart = { + {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},0,0}, + FLASH_SIZE, // flash size, should be changed in Init function + 0, // flash part id, should be changed in Init function + 0 // flash part string, should be changed in Init function +}; +UINT8 gbDeviceVirtual = 0; +UINT8 gbDeviceWriteEnabled = 0; +//---------------------------------------------------------------------------- +// Function Definitions + +// +//---------------------------------------------------------------------------- +// +// Procedure: IoDelay +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +IoDelay (VOID) +{ + UINT8 bTimeout; + for ( bTimeout = 0; bTimeout < 33; bTimeout++ ) { + IoWrite8( 0xEB, 0x55 ); + IoWrite8( 0xEB, 0xAA ); + } + return ; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: WaitForSpiCycleDone +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +WaitForSpiCycleDone (VOID) +{ +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wTimeout; + UINT8 bCyclyDone; + + for ( wTimeout = 0, bCyclyDone = 0; wTimeout < 0xFFFF; wTimeout++ ) { + bCyclyDone = *(volatile UINT8*)( gSPIBASE + SPI_STS ); + if ( bCyclyDone & BIT02 ) break; + } + // write BIT2 to clear CycleDone status + *(volatile UINT8*)( gSPIBASE + SPI_STS ) = BIT02; + + --------------------- PORTING REQUIRED ---------------------*/ +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadStatus +// +// Description: +// +// Input: None. +// +// Output: Status Register which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +UINT8 +CommonSpiReadStatus (VOID) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wSpiCmd; + // Opcode menu slot 3 is configured as "Read Status Register" + wSpiCmd = SPI_OPCODE_READ_S_INDEX << 4; + // indicate that data phase is required + wSpiCmd += (1 << 14); + // Set BIT1 (Go) + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // return status register. + return ( *(volatile UINT8*)( gSPIBASE + SPI_DAT0 ) ); + + --------------------- PORTING REQUIRED ---------------------*/ + + return ( (UINT8)EFI_NOT_READY ); // For Template compiling only. +} +// +//---------------------------------------------------------------------------- +// +// Procedure: WaitForWriteOperationCompleted +// +// Description: +// +// Input: None. +// +// Output: None. +// +//---------------------------------------------------------------------------- +// +VOID +WaitForWriteOperationCompleted (VOID) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wWaitStsRetry; + UINT8 bStatus; + + for( wWaitStsRetry = 0; wWaitStsRetry < 0xFFFF; wWaitStsRetry++ ) { + // read flash status register. + bStatus = CommonSpiReadStatus(); + // Is operation busy ? + if( !( bStatus & 0x1 ) ) break; + } + + --------------------- PORTING REQUIRED ---------------------*/ +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiWriteStatus +// +// Description: Routine for Write SPI Status Register. +// +// Input: None. +// +// Output: Status Register which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiWriteStatus ( + IN UINT8 bWriteData, + IN UINT8 bOpcodeIndex, + IN UINT8 bIsDataPhase, + IN UINT8 bPrefixOp, + IN UINT32 dSectorAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wSpiCmd; + + *(volatile UINT8*)( gSPIBASE + SPI_DAT0 ) = bWriteData; + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dSectorAddress; + // Opcode menu slot 3 is configured as "Read Status Register" + wSpiCmd = bOpcodeIndex << 4; + // indicate that data phase is required + wSpiCmd += ( bIsDataPhase << 14 ); + // BIT3(Preop 1) + wSpiCmd += ( bPrefixOp << 3 ); + // Set BIT1 (Go), BIT2(Atomic w/ Prefix), + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01 + BIT02; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // wait for SPI flash operation completed. + WaitForWriteOperationCompleted(); + // return status register. + return ; + + --------------------- PORTING REQUIRED ---------------------*/ +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadByte +// +// Description: +// +// Input: dByteAddress Address that need to be read. +// +// Output: BYTE Value which is read from SPI flash. +// +//---------------------------------------------------------------------------- +// +UINT8 +CommonSpiReadByte ( + IN UINT32 dByteAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + UINT16 wSpiCmd; + + // update the + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dByteAddress; + // Opcode menu slot 1 is configured as "Read Flash" + wSpiCmd = ( SPI_OPCODE_READ_INDEX << 4 ) + BIT01; + // indicate that data phase is required + wSpiCmd += (1 << 14); + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for spi cycle completed. + WaitForSpiCycleDone(); + // return data. + return( *(volatile UINT8*)( gSPIBASE + SPI_DAT0 ) ); + + --------------------- PORTING REQUIRED ---------------------*/ + return ( (UINT8)EFI_NOT_READY ); // For Template compiling only. +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonConvertSpiAddress +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +UINT32 +CommonConvertSpiAddress ( + IN volatile UINT8 *pAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + if ( gbDeviceVirtual ) { + // pAddress - offset from Flash Device Base. + pAddress -= FlashDeviceBase; + // pAddress - 32bit memory mapping address. + pAddress += (0xFFFFFFFF - FLASH_SIZE) + 1; + } + --------------------- PORTING REQUIRED ---------------------*/ + + return ((UINT32)pAddress); +} +// +//---------------------------------------------------------------------------- +// +// Procedure: InitializeSpiEnvironment +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +InitializeSpiEnvironment ( + IN FLASH_INFO *FlashInfo +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT32 dIchSpiFDOD; + + //Program first DWORD of opcode commands + *((volatile UINT32*)( gSPIBASE+R_RCRB_SPI_OPMENU+0 )) = (UINT32) + // Write Byte + ( (FlashInfo->Write.Opcode << (SPI_OPCODE_WRITE_INDEX * 8)) + // Read Data + | (FlashInfo->Read.Opcode << (SPI_OPCODE_READ_INDEX * 8)) + // Erase 64k Sector + | (FlashInfo->Erase.Opcode << (SPI_OPCODE_ERASE_INDEX * 8)) + // Read Device Status Reg + | (FlashInfo->ReadStatus.Opcode << (SPI_OPCODE_READ_S_INDEX * 8)) ); + + //Program second DWORD of Opcode commands + *((volatile UINT32*)( gSPIBASE+R_RCRB_SPI_OPMENU+4 )) = (UINT32) + // Read device ID + ( (FlashInfo->ReadId.Opcode << ((SPI_OPCODE_READ_ID_INDEX - 4) * 8)) + // Write Status Register + | (FlashInfo->WriteStatus.Opcode << ((SPI_OPCODE_WRITE_S_INDEX - 4) * 8)) + // Write Status Enable Register + | (FlashInfo->WriteStatusEnable.Opcode << ((SPI_OPCODE_WRITE_E_INDEX - 4) * 8))); + + //Program opcode types + *((volatile UINT16*)( gSPIBASE+R_RCRB_SPI_OPTYPE )) = (UINT16) + // write with address. + ( FlashInfo->Write.OpcodeType << (SPI_OPCODE_WRITE_INDEX*2) + // read with address. + | FlashInfo->Read.OpcodeType << (SPI_OPCODE_READ_INDEX*2) + // write with address. + | FlashInfo->Erase.OpcodeType << (SPI_OPCODE_ERASE_INDEX*2) + // read w/o no adress. + | FlashInfo->ReadStatus.OpcodeType << (SPI_OPCODE_READ_S_INDEX*2) + // read with address. + | FlashInfo->ReadId.OpcodeType << (SPI_OPCODE_READ_ID_INDEX*2) + // write w/o address. + | FlashInfo->WriteStatus.OpcodeType << (SPI_OPCODE_WRITE_S_INDEX*2) + // write w/o address. + | FlashInfo->WriteStatusEnable.OpcodeType << (SPI_OPCODE_WRITE_E_INDEX*2) ); + + //set up the prefix opcodes for commands + *((volatile UINT16*)( gSPIBASE+R_RCRB_SPI_PREOP )) = (UINT16) + ( ( FlashInfo->WriteStatusEnable.Opcode << 8 ) + | ( FlashInfo->WriteEnable.Opcode ) ); + + // Here checks the BIOS region of Flash Descriptor Table. + if ( mExFlashPart.FlashCommandMenu != NULL ) { + if ( !gBiosRegionBase ) { + *(volatile UINT32*)( gSPIBASE + ICH_SPI_FDOC ) = 0; + dIchSpiFDOD = *(volatile UINT32*)( gSPIBASE + ICH_SPI_FDOD ); + if ( dIchSpiFDOD == 0x0FF0A55A ) + { + *(volatile UINT32 *)( gSPIBASE + ICH_SPI_FDOC ) = (BIT13+BIT02); + do { + dIchSpiFDOD = *(volatile UINT32*)( gSPIBASE+ICH_SPI_FDOD ); + } while( dIchSpiFDOD == 0x0FF0A55A ); + gBiosRegionBase = ( ( (dIchSpiFDOD >> 16) + 1 ) << 12 ); + } + else + gBiosRegionBase = mExFlashPart.FlashCapacity; + } + } + return ; + + --------------------- PORTING REQUIRED ---------------------*/ + +} +// +//---------------------------------------------------------------------------- +// +// Procedure: ReinitializeSpiEnvironment +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +VOID +ReinitializeSpiEnvironment ( + IN FLASH_INFO *FlashInfo +) +{ + return ; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: CommonSpiReadId +// +// Description: +// +// Input: +// +// Output: +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiReadId ( + IN FLASH_INFO *FlashInfo, + IN UINT32 *dFlashId +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT16 wSpiCmd = 0xFFFF; + + InitializeSpiEnvironment( FlashInfo ); + // Set SPI read-address = 0 + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = 0; + // set opcode for "Read ID" + wSpiCmd = SPI_OPCODE_READ_ID_INDEX << 4; + // set transaction = 3 bytes + wSpiCmd += ( ( 3 - 1 ) << 8 ); + // indicate that data phase is required + wSpiCmd += ( 1 << 14 ); + // Go (BIT1) + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd + BIT01; + WaitForSpiCycleDone(); + IoDelay(); + *dFlashId = *(volatile UINT32*)( gSPIBASE + SPI_DAT0 ) & 0x00FFFFFF; + TRACE ((-1, " FLASH ID - %08X\n", *dFlashId)); + return TRUE; + + --------------------- PORTING REQUIRED ---------------------*/ + + return ( (UINT8)EFI_NOT_READY ); // For Template compiling only. +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiEraseCommand +// +// Description: This API function erases a block in the flash. Flash model +// specific code will branch out from this routine +// +// Input: pBlockAddress Block that need to be erased +// +// Output: Nothing +//---------------------------------------------------------------------------- +// +VOID +CommonSpiEraseCommand ( + IN volatile UINT8* pBlockAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + volatile UINT32 dSectorAddr; + UINT32 dNByte; + UINT16 wEraseRetry, wNumSectors, wSector; + UINT16 wSpiCmd; + + // These parts only erase in 64K sectors + InitializeSpiEnvironment( mExFlashPart.FlashCommandMenu ); + wNumSectors = ( FlashBlockSize / FlashAPI->FlashSectorSize ); + for ( wSector = 0; wSector < wNumSectors ; wSector++ ) { + dSectorAddr = (UINT32) + ( pBlockAddress + wSector * FlashAPI->FlashSectorSize ); + for ( dNByte = 0; dNByte < FlashAPI->FlashSectorSize; dNByte++ ) { + if ( *(volatile UINT8*)( dSectorAddr + dNByte ) != 0xFF ) break; + } + if ( dNByte == FlashAPI->FlashSectorSize ) break; + for ( wEraseRetry = 0; wEraseRetry < FLASH_RETRIES; wEraseRetry++ ) { + dSectorAddr += gBiosRegionBase; + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = dSectorAddr; + // opcode index 2 is programmed for erase command. + // Set BIT1 (Go), BIT2(Atomic w/ Prefix) + wSpiCmd = ( SPI_OPCODE_ERASE_INDEX << 4) + BIT01 + BIT02; + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for chipset SPI cycle completed. + WaitForSpiCycleDone(); + // wait for SPI flash operation completed. + WaitForWriteOperationCompleted(); + // write operation appeared to succeed, now read back byte and compare. + if ( CommonSpiReadByte( dSectorAddr ) == 0xFF ) break; + } + } + + --------------------- PORTING REQUIRED ---------------------*/ + +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiProgramCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiProgramCommand ( + IN volatile UINT8* pByteAddress, + IN UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT8 bFlashRetry = 0, bProgBytes = 0, bNumBytes = 0; + UINT16 wSpiCmd = 0, wRetry = 0, wMaxNumBytes = 0; + + InitializeSpiEnvironment( mExFlashPart.FlashCommandMenu ); + bProgBytes = mCommonSpiFlash.FlashProgramSize; + if ( mCommonSpiFlash.FlashProgramSize != 1 ) { + // Limit the max transfer to the number of bytes the chipset can + // transfer per cycle + if ( *Length >= SPI_MAX_DATA_TRANSFER ) + bProgBytes = SPI_MAX_DATA_TRANSFER; + else + bProgBytes = *Length; + // this is currently for the WINBOND parts only + // mask off lowest 8 bits of address so that we can determine how + // many bytes we can write before we hit the end of a page + wMaxNumBytes = 0x100 - ((UINT8)pByteAddress & 0xFF); + if ( (UINT32)pByteAddress & 0x1 ) bProgBytes = 1; + else if ( (UINT16)bProgBytes > wMaxNumBytes ) + bProgBytes = (UINT8)wMaxNumBytes; + } + for ( bFlashRetry = 0; bFlashRetry < FLASH_RETRIES; bFlashRetry++ ) { + // check if do the data need to be programmed ? + for ( bNumBytes = 0; bNumBytes < bProgBytes; bNumBytes++ ) { + if ( *( Byte + bNumBytes ) != 0xFF ) break; + } + + // The data is empty and don't need to be programmed. + if ( bNumBytes == bProgBytes ) break; + // update data to chipset SPI data transfer registers. + for ( bNumBytes = 0; bNumBytes < bProgBytes; bNumBytes++ ) { + for ( wRetry = 0; wRetry < 0x400; wRetry ++ ) { + *(volatile UINT8*)( gSPIBASE+SPI_DAT0+bNumBytes ) = + *( Byte+bNumBytes ); + // verified for checking the data is correct. + if ( *(Byte+bNumBytes) == *(volatile UINT8*) + ( gSPIBASE+SPI_DAT0+bNumBytes ) ) + break; + } + } + *(volatile UINT32*)( gSPIBASE + SPI_ADR ) = + (UINT32)( pByteAddress + gBiosRegionBase ); + // BIT14 - indicate that it's data cycle. + wSpiCmd = ( 1 << 14 ); + // BIT[8..13] - update the number of bytes to be written. + wSpiCmd += ( bProgBytes - 1 ) << 8; + // opcode index 0 is programmed for program command. + // Set BIT1 (Go), BIT2(Atomic w/ Prefix) + wSpiCmd += ( SPI_OPCODE_WRITE_INDEX << 4) + BIT01 + BIT02; + *(volatile UINT16*)( gSPIBASE + SPI_CTL ) = wSpiCmd; + // wait for chipset SPI cycle completed. + WaitForSpiCycleDone(); + // wait for chipset SPI flash operation completed. + WaitForWriteOperationCompleted(); + // write operation appeared to succeed, now read back byte and compare + // set control for 1-byte data read, no prefix + for ( bNumBytes = 0; bNumBytes < bProgBytes; bNumBytes++ ) { + if (*(Byte + bNumBytes) != CommonSpiReadByte ( + (UINT32)( pByteAddress + bNumBytes + gBiosRegionBase ))) + break; + } + if ( bNumBytes == bProgBytes ) break; + } + // Don't forget to return the number of bytes not written + *Length = *Length - (UINT32)bProgBytes; + return; + + --------------------- PORTING REQUIRED ---------------------*/ + +} + + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiReadCommand +// +// Description: This function programs a byte data to the specified location +// +// Input: *pByteAddress Location where the data to be written +// Bytes - data to be written. +// Length - number of bytes to write +// +// Output: Length - number of bytes that were not written +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiReadCommand ( + IN volatile UINT8 *pByteAddress, + OUT UINT8 *Byte, + IN OUT UINT32 *Length +) +{ + UINT32 dReadAddress = 0, dNumBytes = 0; + + InitializeSpiEnvironment( &mExFlashPart.FlashCommandMenu ); + dReadAddress = CommonConvertSpiAddress ( pByteAddress ); + for ( dNumBytes = 0; dNumBytes < *Length ; dNumBytes++ ) + *( Byte + dNumBytes ) = CommonSpiReadByte( dReadAddress + dNumBytes ); + *Length = 0; +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiIsEraseCompleted +// +// Description: This function verifies whether the block erase +// command is completed and returns the status of the command +// +// Input: *pBlockAddress Location of the block erase +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiIsEraseCompleted ( + IN volatile UINT8 *pBlockAddress, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + + for ( dNumBytes = 0; dNumBytes < FlashBlockSize; dNumBytes++ ) { + if ( *(volatile UINT8*)( pBlockAddress + dNumBytes ) != 0xFF ) { + *pStatus = EFI_NOT_READY; + *pError = TRUE; + break; + } + } + *pError = FALSE; + *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiIsProgramCompleted +// +// Description: This function verifies whether the program (page or byte) +// command is completed and returns the status of the command +// +// Input: *pByteAddress Location of the program command +// Byte Last data byte written +// +// Output: *pError True on error and false on success +// *Status Error status code (0 - Success) +// +// Return: TRUE If operation completed successfully +// *pError = FALSE, *pStatus = 0 +// FALSE If operation failed +// *pError = TRUE, *pStatus = error status +// +//---------------------------------------------------------------------------- +// +BOOLEAN +CommonSpiIsProgramCompleted ( + IN volatile UINT8 *pByteAddress, + IN UINT8 *Byte, + IN UINT32 Length, + OUT BOOLEAN *pError, + OUT UINTN *pStatus +) +{ + UINT32 dNumBytes; + UINT8 bByte; + + for ( dNumBytes = 0; dNumBytes < Length; dNumBytes++ ) { + bByte = * ( Byte + dNumBytes ); + if ( bByte != *(volatile UINT8*)( pByteAddress + dNumBytes ) ) { + *pStatus = EFI_NOT_READY; + *pError = TRUE; + break; + } + } + *pError = FALSE; + *pStatus = EFI_SUCCESS; + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiBlockWriteEnable +// +// Description: This function contains any flash specific code need to +// enable a particular flash block write +// +// Input: *pBlockAddress - Address within the block to write enable +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiBlockWriteEnable ( + IN volatile UINT8 *pBlockAddress +) +{ + +/* --------------------- PORTING REQUIRED --------------------- + + UINT8 bStatusReg = 0, bPrefixOp, bDataPhase = 1; + UINT16 wNumSector = 1; + UINT32 dSectorAddr = 0; + + bStatusReg = CommonSpiReadStatus(); + switch ( (UINT8)mExFlashPart.FlashVenDevId ) { + // if SST flash, prefix 1 w/o address + case 0xBF : + bStatusReg &= 0x1C; + bPrefixOp = SPI_PREFIX_WRITE_S_EN; + break; + // if ATMEL flash, prefix 0 w/ address + case 0x1F : + bStatusReg &= 0xC; + dSectorAddr = ~(UINT32)mExFlashPart.FlashCapacity + 1; + wNumSector = ( mExFlashPart.FlashCapacity/FlashAPI->FlashSectorSize ); + bPrefixOp = SPI_PREFIX_WRITE_EN; + bDataPhase = 0; + break; + default : + // default flash, prefix 0 w/o address + bStatusReg &= 0x1C; + bPrefixOp = SPI_PREFIX_WRITE_EN; + } + if ( bStatusReg ) { + for ( ; wNumSector > 0; wNumSector-- ) { + CommonSpiWriteStatus ( 0, + SPI_OPCODE_WRITE_S_INDEX, + bDataPhase, + bPrefixOp, + dSectorAddr ); + dSectorAddr += FlashAPI->FlashSectorSize; + } + } + + --------------------- PORTING REQUIRED ---------------------*/ + +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiBlockWriteDisable +// +// Description: This function contains any flash specific code need to +// disable a particular flash block write +// +// Input: *pBlockAddress - Address within the block to write disable +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiBlockWriteDisable ( + IN volatile UINT8 *pBlockAddress +) +{ +#if BLOCK_PROTECT_ENABLE +/* --------------------- PORTING REQUIRED --------------------- + + UINT8 bStatusReg = 0, bPrefixOp, bDataPhase = 1; + UINT8 bOpmenuIndex; + UINT16 wNumSector = 1; + UINT32 dSectorAddr = 0; + + bStatusReg = CommonSpiReadStatus(); + bOpmenuIndex = SPI_OPCODE_WRITE_S_INDEX; + switch ( (UINT8)mExFlashPart.FlashVenDevId ) { + // if SST flash, prefix 1 w/o address + case 0xBF : + bStatusReg &= 0x1C; + bPrefixOp = SPI_PREFIX_WRITE_S_EN; + break; + // if ATMEL flash, prefix 0 w/ address + case 0x1F : + bStatusReg &= 0xC; + dSectorAddr = ~(UINT32)mExFlashPart.FlashCapacity + 1; + wNumSector = ( mExFlashPart.FlashCapacity/FlashAPI->FlashSectorSize ); + bPrefixOp = SPI_PREFIX_WRITE_EN; + bOpmenuIndex = SPI_OPCODE_WRITE_E_INDEX; + bDataPhase = 0; + break; + default : + // default flash, prefix 0 w/o address + bStatusReg &= 0x1C; + bPrefixOp = SPI_PREFIX_WRITE_EN; + } + if ( !bStatusReg ) { + for ( ; wNumSector > 0; wNumSector-- ) { + CommonSpiWriteStatus ( 0x1C, + bOpmenuIndex, + bDataPhase, + bPrefixOp, + dSectorAddr ); + dSectorAddr += FlashAPI->FlashSectorSize; + } + } + + --------------------- PORTING REQUIRED ---------------------*/ +#endif +} + +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceWriteEnable +// +// Description: This function contains any flash specific code need to +// enable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiDeviceWriteEnable (VOID) +{ + // check is DeviceWrite enabled, if yes, don't enable it again, else, enable it. + if ( !gbDeviceWriteEnabled ) { + gbDeviceWriteEnabled = 1; + } +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceWriteDisable +// +// Description: This function contains any flash specific code need to +// disable flash write +// +// Input: None +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +VOID +CommonSpiDeviceWriteDisable (VOID) +{ + // check is DeviceWrite enabled, if yes, disable it, + // if no, don't disable it. + if ( gbDeviceWriteEnabled ) { + gbDeviceWriteEnabled = 0; + } +} +// +//---------------------------------------------------------------------------- +// Procedure: CommonSpiDeviceVirtualFixup +// +// Description: This function will be invoked by the core to convert +// runtime pointers to virtual address +// +// Input: *pRS Pointer to runtime services +// +// Output: None +// +// Return: None +// +//---------------------------------------------------------------------------- +// +static +VOID +CommonSpiDeviceVirtualFixup ( + IN EFI_RUNTIME_SERVICES *pRS +) +{ + +// // Following is an example code for virtual address conversion +// pRS->ConvertPointer(0, (VOID**)&FlashDeviceBase); + +//- SpiChipsetVirtualFixup(pRS); + gbDeviceVirtual = 1; + + return; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* \ No newline at end of file diff --git a/Board/Flash/SPI/Template/SpiCspSrc.cif b/Board/Flash/SPI/Template/SpiCspSrc.cif new file mode 100644 index 0000000..e50f0c3 --- /dev/null +++ b/Board/Flash/SPI/Template/SpiCspSrc.cif @@ -0,0 +1,8 @@ + + name = "CSP : DUMMY SPI - Do Not Delete" + category = ModulePart + LocalRoot = "Board\Flash\SPI\Template" + RefName = "DUMMY_SPI_CSP_SOURCE" +[files] +"SPIFlash.c" + -- cgit v1.2.3