📄 flashdrvlib.c
字号:
/* flashDrvLib.c - Flash memory device driver */
/* Copyright 1984-2000 Wind River Systems, Inc. */
#include "copyright_wrs.h"
/*
modification history
--------------------
V1.09:---------------------------------------------------------------------
05/13/2004 pcd
1. modify to support ks8695 board with AMD AM29LV033 flash memory .
*/
#include "types.h"
#include "vxWorks.h"
#include "taskLib.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "config.h"
#include "drv/mem/flashDev.h"
#include "drv/mem/flash29.h"
#include "flash28.h"
#include "flashFsLib.h"
#include "flashMem.h"
/* Driver debug control */
#define FLASH_DEBUGDRV
/* Driver debug control */
#ifdef FLASH_DEBUGDRV
#define FLASHDRV_DEBUG_OFF 0x0000
#define FLASHDRV_DEBUG_ERROR 0x0001
#define FLASHDRV_DEBUG_BLKWRITE 0x0002
#define FLASHDRV_DEBUG_BLKREAD 0x0004
#define FLASHDRV_DEBUG_ERASE 0x0008
#define FLASHDRV_DEBUG_TYPEGET 0x0010
#define FLASHDRV_DEBUG_INIT 0x0020
#define FLASHDRV_DEBUG_DIAG 0x0040
#define FLASHDRV_DEBUG_CHECK 0x0080
#define FLASHDRV_DEBUG_ALL 0xffff
LOCAL int flashDrvDebug = ( FLASHDRV_DEBUG_ERROR | FLASHDRV_DEBUG_DIAG ) ;
#define FD_DRV_PRINT(FLG, X) \
do { \
if (flashDrvDebug & FLG) \
printf X; \
} while (0)
#else /* FLASH_DEBUGDRV */
#define FD_DRV_PRINT(FLG, X)
#endif /* FLASH_DEBUGDRV */
/*
* The FLASH_BASE_ADDRS is 0x02800000 for flash boot.
*/
/* LOCAL */
static int flashSectorCount = 0;
static int flashLoadedSector = -1;
static int flashLoadedSectorDirty = 0;
static char *flashLoadedSectorBuffer;
/* forward declarations */
IMPORT UINT8 sysFlashTypeGet (void);
IMPORT int AmdflashEraseDevice(FLASH_DEF *, int);
IMPORT int AmdflashWrite(int, char *, unsigned int, unsigned int);
int flashDrvLibInit();
int flashEraseSector(int);
int flashEraseBank();
int flashBlkRead(int, char *, unsigned int, unsigned int);
int flashBlkWrite(int, char *, unsigned int, unsigned int);
int flashDiagnostic();
int flashSyncFilesystem();
LOCAL int flashGetSectorCount();
LOCAL int flashRead(int, char *, unsigned int, unsigned int);
LOCAL int flashCheckCanProgram(int, unsigned int, unsigned int);
LOCAL int flashFlushLoadedSector();
int flashDrvLibInit()
{
UINT8 flashtype ;
/* GET the manufacturer id and device id */
flashtype = sysFlashTypeGet ();
switch( flashtype )
{
case FLASH_29LV033:
flashSectorCount = EB_FLASH_SECTORS;
FD_DRV_PRINT (FLASHDRV_DEBUG_INIT,
( "flashInit(): AM29LV033 Found\n" ));
break;
default:
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashInit(): Unrecognized Device (0x%02X)\n", flashtype ));
return( ERROR );
}
flashLoadedSectorBuffer = malloc( FLASH_BANK_SECTOR_SIZE );
if( !flashLoadedSectorBuffer )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashInit(): malloc() failed\n" ));
return( ERROR );
}
return( 0 );
}
LOCAL int flashGetSectorCount()
{
UINT8 flashtype ;
int flashSectorCount = 0;
/* GET the manufacturer id and device id */
flashtype = sysFlashTypeGet ();
switch( flashtype )
{
case FLASH_29LV033:
flashSectorCount = EB_FLASH_SECTORS;
FD_DRV_PRINT (FLASHDRV_DEBUG_INIT,
( "flashGetSectorCount(): AMD AM29LV033 Found\n" ));
break;
default:
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashGetSectorCount(): Unrecognized Device (0x%02X)\n", flashtype ));
return( ERROR );
}
return( flashSectorCount );
}
int flashEraseSector( int sectorNum )
{
int totalSectors = flashGetSectorCount();
FLASH_DEF * sectorBasePtr = (FLASH_DEF *)(FLASH_BASE_ADDRESS + \
(int)(sectorNum * (int)FLASH_BANK_SECTOR_SIZE));
int device;
/* Don't erase the very last sector bank; those are reserved
* for BSP usage (registers, exception reports, etc...).
*/
totalSectors--;
if( (sectorNum >= 0) && (sectorNum < totalSectors) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERASE,
( "flashEraseSector(): Sector %d erased, SectorAddr=0x%08X\n", (int)sectorNum, (int)sectorBasePtr ));
for( device = 0; device < FLASH_BANK_WIDTH; device++ )
{
if( AmdflashEraseDevice( (FLASH_DEF *)sectorBasePtr, device ) == ERROR )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashEraseSector(): device %d failed\n", device));
return( ERROR );
}
}
return( OK );
} /* if( (sectorNum >= 0) && (sectorNum < totalSectors) ) */
else
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashEraseSector(): Sector %d invalid\n", sectorNum ));
return( ERROR );
}
}
int flashEraseBank()
{
int totalSectors = flashGetSectorCount();
int sectorNum;
int errCnt = 0;
FD_DRV_PRINT (FLASHDRV_DEBUG_ERASE,
( "flashEraseBank(): erased flash\n"));
/* Don't erase the very last sector bank; those are reserved
* for BSP usage (registers, exception reports, etc...).
*/
totalSectors--;
for( sectorNum = 0; sectorNum < totalSectors ; sectorNum++ )
{
/* print out '.' every sector */
/*printf("."); */
if( flashEraseSector( sectorNum ) == ERROR )
errCnt++;
}
if( errCnt ) {
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashEraseBank(): failed, ERROR count = %d\n", errCnt));
return( ERROR );
}
else
return( 0 );
}
LOCAL int flashRead( int sectorNum, char *buff, unsigned int offset, unsigned int count )
{
bcopy( (char *)(FLASH_BASE_ADDRESS + (sectorNum * FLASH_BANK_SECTOR_SIZE) + offset), buff, count );
return( 0 );
}
int flashBlkRead( int sectorNum, char *buff, unsigned int offset, unsigned int count )
{
if( (sectorNum < 0) || (sectorNum >= flashSectorCount) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashBlkRead(): Sector %d invalid\n", sectorNum ));
return( ERROR );
}
if( (offset < 0) || (offset >= FLASH_BANK_SECTOR_SIZE) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashBlkRead(): Offset 0x%08X invalid\n", offset ));
return( ERROR );
}
if( (count < 0) || (count > (FLASH_BANK_SECTOR_SIZE - offset)) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashBlkRead(): Count 0x%08X invalid\n", count ));
return( ERROR );
}
if( flashLoadedSector == sectorNum )
{
bcopy( &flashLoadedSectorBuffer[ offset ], buff, count );
FD_DRV_PRINT (FLASHDRV_DEBUG_BLKREAD,
( "flashBlkRead(): bcopy() Sector %d, offset %d, count %d\n", sectorNum, offset, count ));
return( 0 );
}
else
{
flashRead( sectorNum, buff, offset, count );
FD_DRV_PRINT (FLASHDRV_DEBUG_BLKREAD,
( "flashBlkRead(): flashRead() Sector %d, offset %d, count %d\n", sectorNum, offset, count ));
return( 0 );
}
}
LOCAL int flashCheckCanProgram( int sectorNum, unsigned int offset, unsigned int count )
{
FLASH_DEF *flashBuffPtr;
int i, dataCount;
dataCount = (count / sizeof(FLASH_DEF) );
flashBuffPtr = (FLASH_DEF *)(FLASH_BASE_ADDRESS + (sectorNum * FLASH_BANK_SECTOR_SIZE) + offset);
for( i = 0; i < dataCount; i++ )
{
if ( (FLASH_DEF)flashBuffPtr[ i ] != (FLASH_DEF)0xFFFFFFFF )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_CHECK,
( "flashCheckCanProgram(): flashAddr 0x%08X is 0x%02x (not 0xFF)\n",
(int)flashBuffPtr, *flashBuffPtr ));
return( ERROR );
}
}
FD_DRV_PRINT (FLASHDRV_DEBUG_CHECK,
( "flashCheckCanProgram(): flashAddr 0x%08X is 0x%02x (0xFF)\n",
(int)flashBuffPtr, *flashBuffPtr ));
return( OK );
}
LOCAL int flashFlushLoadedSector()
{
int status;
FD_DRV_PRINT (FLASHDRV_DEBUG_BLKWRITE,
( "flashFllushLoadedSector(): Flushing %d\n", flashLoadedSector ));
if( (flashLoadedSector < 0) || (flashLoadedSector >= flashSectorCount) ) {
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashFlushLoadedSector(): Sector %d invalid\n", flashLoadedSector ));
return( ERROR );
}
if (flashEraseSector( flashLoadedSector ) == ERROR)
return (ERROR);
status = AmdflashWrite( flashLoadedSector, flashLoadedSectorBuffer, 0, FLASH_BANK_SECTOR_SIZE );
return( status) ;
}
int flashBlkWrite( int sectorNum, char *buff, unsigned int offset, unsigned int count )
{
if( (sectorNum < 0) || (sectorNum >= flashSectorCount) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashBlkWrite(): Sector %d invalid\n", sectorNum ));
return( ERROR );
}
if( (offset < 0) || (offset >= FLASH_BANK_SECTOR_SIZE) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashBlkWrite(): Offset 0x%08X invalid\n", offset ));
return( ERROR );
}
/* Count must be within range, but more so, must be a long word
* multiple, as we always program long words.
*/
if( (count < 0) || (count > (FLASH_BANK_SECTOR_SIZE - offset)) || (count % sizeof(FLASH_DEF)) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashBlkWrite(): Count 0x%08X invalid\n", count ));
return( ERROR );
}
if( sectorNum == flashLoadedSector )
{
bcopy( buff, &flashLoadedSectorBuffer[ offset ], count );
flashLoadedSectorDirty = 1;
return( 0 );
}
else if( flashCheckCanProgram( sectorNum, offset, count ) != ERROR )
{
return( AmdflashWrite( sectorNum, buff, offset, count ) );
}
else
{
if( flashLoadedSectorDirty )
{
if( flashFlushLoadedSector() == ERROR )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashBlkWrite(): flashFlushLoadedSector() err\n" ));
return( ERROR );
}
else
{
flashLoadedSectorDirty = 0;
flashLoadedSector = -1;
}
}
flashRead( sectorNum, flashLoadedSectorBuffer, 0, FLASH_BANK_SECTOR_SIZE );
flashLoadedSector = sectorNum;
bcopy( buff, &flashLoadedSectorBuffer[ offset ], count );
flashLoadedSectorDirty = 1;
return( 0 );
}
return( 0 );
}
int flashSyncFilesystem()
{
if( (flashLoadedSector != -1) && flashLoadedSectorDirty )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_INIT,
( "flashSyncFilesystem(): flushing dirty sector %d\n", flashLoadedSector ));
if( flashFlushLoadedSector() == ERROR )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
("flashSyncFilesystem(): flashFlushLoadedSector() failed\n" ));
return( ERROR );
}
flashLoadedSectorDirty = 0;
}
else
{
FD_DRV_PRINT (FLASHDRV_DEBUG_INIT,
( "flashSyncFilesystem(): no dirty sector to flush\n" ));
}
return( 0 );
}
/*-- Debug Functions -----------------------------------------------------*/
int flashDiagnostic
(
int sector
)
{
FLASH_DEF * flashSectorBuff;
int sectorNum, i, min, max;
int length = FLASH_BANK_SECTOR_SIZE;
FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
( "flashDiagnostic(): Executing ...\n" ));
/* can't erase Boot sectors */
if ( (sector >= BOOT_BEGIN_SECTOR) && (sector < (BOOT_BEGIN_SECTOR + FLASH_RAW_NUM_SEC)) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
( "flashDiagnostic(): can't erase Boot sectors !\n" ));
return (ERROR);
}
min = sector;
max = sector+1;
length = 0x100;
/* Erase each sector.
*/
for( sectorNum = min; sectorNum < max ; sectorNum++ )
{
if( flashEraseSector( sectorNum ) == ERROR )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagnostic(): flashEraseBank() fail on sector %d\n", sectorNum ));
return( ERROR );
}
FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
( "flashDiagnostic(): flashEraseBank() OK on sector %d\n", sectorNum ));
}
flashSectorBuff = (FLASH_DEF *)malloc( length );
if( !flashSectorBuff ) {
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagnostic(): malloc() failed\n" ));
return( ERROR );
}
/* Write unique counting pattern to each sector.
*/
for( sectorNum = min; sectorNum < max; sectorNum++ )
{
for( i = 0; i < length / sizeof(FLASH_DEF); i++ )
flashSectorBuff[ i ] = (i + sectorNum-min);
if( AmdflashWrite( sectorNum, (FLASH_DEF *)flashSectorBuff, 0, length ) == ERROR )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagnostic(): flashWrite() failed on %d\n", sectorNum ));
return( ERROR );
}
FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
( "flashDiagnostic(): flashWrite() ok on sector %d\n", sectorNum ));
}
/* Verify each sector.
*/
for( sectorNum = min; sectorNum < max; sectorNum++ )
{
if( flashRead( sectorNum, (FLASH_DEF *)flashSectorBuff, 0, length ) == ERROR ) {
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagnostic(): flashRead() failed on sector %d\n", sectorNum ));
return( ERROR );
}
FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
( "flashDiagnostic(): flashRead() ok on sector %d\n", sectorNum ));
for( i = 0; i < length / sizeof(FLASH_DEF); i++ ) {
if( flashSectorBuff[ i ] != (i + sectorNum-min) )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagnostic(): verification failed\n" ));
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagnostic(): sector %d, offset 0x%08X\n", sectorNum, (int)(i * sizeof( long )) ));
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagnostic(): expected 0x%08X, got 0x%08X\n", (i + sectorNum), (int)flashSectorBuff[ i ] ));
return( ERROR );
}
}
}
/* Erase each sector after finished diagnostic it .
*/
for( sectorNum = min; sectorNum < max ; sectorNum++ )
{
if( flashEraseSector( sectorNum ) == ERROR )
{
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagnostic(): flashEraseBank() #2 failed\n" ));
return( ERROR );
}
}
free( flashSectorBuff );
FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
( "flashDiagnostic(): Completed without error\n" ));
return( 0 );
}
int flashDiagEraseAppSectors
(
)
{
int sectorNum;
int errCnt = 0;
for (sectorNum = APPLICATION_BEGIN_SECTOR;
sectorNum < (APPLICATION_BEGIN_SECTOR+FLASH_FS2_NUM_SEC);
sectorNum++)
{
if( flashEraseSector( sectorNum ) == ERROR )
errCnt++;
}
if( errCnt ) {
FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
( "flashDiagEraseAppSectors(): failed, ERROR count = %d\n", errCnt));
return( ERROR );
}
else
{
FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
( "flashDiagEraseAppSectors(): Completed without error\n" ));
return ( 0 );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -