📄 testdrv.c
字号:
/*****************************************************************************
FILE NAME: testdrv.c
DESCRIPTION:
For FSM test, simulate intel single bank flash in disk file.
Copyright (c) 2002, VIA Technologies, Inc.
*****************************************************************************/
#include "stdlib.h"
#include "fsmdefs.h"
#include "FsmFlash.h"
#include "ostype.h"
#define BLOCK_SIZE 0x10000
#define FSM_DATA_BLOCKS 8
#define FSM_DATA_START_ADDR 0x0
/* Returns the lesser of the two values passed */
#define GET_MIN(a, b) (((a) < (b)) ? (a) : (b))
uint32 FsmTestInit(FsmDevObjHdrT * DevObjP);
uint32 FsmTestRead(FsmDevObjHdrT * DevObjP, uint8 * buf, uint32 Addr, uint32 length);
uint32 FsmTestWrite(FsmDevObjHdrT * DevObjP, uint8 * buf, uint32 Addr, uint32 length);
uint32 FsmTestErase(FsmDevObjHdrT * DevObjP, uint32 Addr);
uint32 FsmTestCopy(FsmDevObjHdrT * DevObjP, uint32 DstAddr, uint32 SrcAddr, uint32 length);
uint32 FsmTestCtrl(FsmDevObjHdrT * DevObjP, uint32 CtrlCode, void *arg);
// =============== global variables =========================
const FsmDevDrvT TestDrv = \
{
FsmTestRead,
FsmTestWrite,
FsmTestCopy,
FsmTestErase,
FsmTestCtrl,
FsmTestInit
};
FsmFlashDevT TestDev =
{
{ (FsmDevDrvT *)&TestDrv, DEV_TYPE_FLASH, NULL },
NULL,
NULL,
BLOCK_SIZE,
FSM_DATA_BLOCKS,
FSM_DATA_START_ADDR
};
/*#############################################################################
### FsmTestInit
###
### DESCRIPTION:
### Initializes the pointers used by the flash device functions. Though
### the flash device functions do not check, this function must be
### called before any of the flash device functions can be called.
###
### PARAMETERS:
### IN: address (DWORD) - The physical address to where the low-level
### functions will be relocated.
### OUT:
###
### RETURNS:
### success: 0.
### failure: error code.
###
*/
uint32 FsmTestInit(FsmDevObjHdrT * DevObjP)
{
FsmFlashDevT * pDev = (FsmFlashDevT *)DevObjP;
// Initialize Device object...
pDev->DevStartAddr = (uint32) CreateFile("c:\\FsmTest.bin",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(pDev->DevStartAddr == (uint32)INVALID_HANDLE_VALUE)
return HW_ERR_SYSTEM;
SetFilePointer((HANDLE)(pDev->DevStartAddr), pDev->BlockSize * pDev->Blocks, NULL, FILE_BEGIN);
SetEndOfFile((HANDLE)(pDev->DevStartAddr));
srand((pDev->BlockSize * pDev->Blocks) / 3);
return HW_ERR_NONE;
}
/*#############################################################################
### FsmTestRead
###
### DESCRIPTION:
### Fills the specified buffer with the number of bytes defined by 'length'
### from the device's absolute physical address. The FsmFlashRead()
### function verifies the address range and reads the data into
### the buffer and then returns the appropriate value.
###
### PARAMETERS:
### IN: buf (BYTE_PTR) - The buffer to use while reading data.
### address (DWORD) - The starting address within flash to read from.
### length (DWORD) - The amount of data, in bytes, to read.
### OUT: buf - Contains the contents read.
###
### RETURNS:
### If the entire source buffer does not lie within the driver
### managed area, the function returns HW_ERR_PARAM.
### Otherwise, the function returns HW_ERR_NONE.
###
*/
uint32 FsmTestRead(FsmDevObjHdrT * DevObjP, uint8 * buf, uint32 Addr, uint32 length)
{
uint32 temp;
FsmFlashDevT * pDev;
pDev = (FsmFlashDevT *)DevObjP;
/* validate address */
#ifdef VALIDATE_ADDRESS
if((Addr + length) > (pDev->BlockSize * pDev->Blocks))
{
return HW_ERR_PARAM;
}
#endif //VALIDATE_ADDRESS
/* return if nothing to read */
if (length == 0)
{
return HW_ERR_NONE;
}
/* take flash write mutex. */
if(FsmGetMtxSem(pDev->DevWriteLock) != ERR_NONE)
{
return HW_ERR_SYSTEM;
}
SetFilePointer((HANDLE)(pDev->DevStartAddr), Addr, NULL, FILE_BEGIN);
ReadFile((HANDLE)(pDev->DevStartAddr), buf, length, &temp, NULL);
/* post flash write mutex, and return */
FsmReleaseMtxSem(pDev->DevWriteLock);
return HW_ERR_NONE;
}
/*#############################################################################
### FsmTestWrite
###
### DESCRIPTION:
### This function writes 'length' bytes of data from a specified buffer to
### the destination addresss within the device(s). This function verifies
### the address range. After aligning the source and destination buffers,
### the function takes the flash write semaphore and calls the low-level
### function FsmLowLvlWrite() via its function pointer. Upon completion
### of the write, the function releases the flash write semaphore and
### returns the appropriate value.
###
### PARAMETERS:
### IN: buf (BYTE_PTR) - A pointer to the start address of the
### data to be written.
### address (DWORD) - The destination address within the flash
### device(s).
### length (DWORD) - The amount of data, in bytes, to write.
###
### RETURNS:
### If any portion of the data being written does not fall within the
### driver managed area, the function returns HW_ERR_PARAM.
### If an error occurred while writing the data to flash,
### HW_ERR_WRITE is returned.
### Finally, if all the parameters are within the appropriate
### ranges and the data was written successfully,
### the function returns HW_ERR_NONE.
###
*/
uint32 FsmTestWrite(FsmDevObjHdrT * DevObjP, uint8 * buf, uint32 Addr, uint32 length)
{
uint32 status = HW_ERR_NONE;
uint32 temp;
FsmFlashDevT * pDev;
/* power loss simulation for testing purposes */
pDev = (FsmFlashDevT *)DevObjP;
/* validate address */
#ifdef VALIDATE_ADDRESS
if((Addr + length) > (pDev->BlockSize * pDev->Blocks))
{
return HW_ERR_PARAM;
}
#endif //VALIDATE_ADDRESS
/* return if nothing to write */
if (length == 0)
{
return HW_ERR_NONE;
}
/* take flash write mutex. */
if(FsmGetMtxSem(pDev->DevWriteLock) != ERR_NONE)
{
return HW_ERR_SYSTEM;
}
SetFilePointer((HANDLE)(pDev->DevStartAddr), Addr, NULL, FILE_BEGIN);
while ((length > 0) && (status == HW_ERR_NONE))
{
/* write to flash */
WriteFile((HANDLE)(pDev->DevStartAddr), buf, 1, &temp, NULL);
/* power loss simulation for testing purposes */
if((rand() % 0x20000) == 0x18000)
status = HW_ERR_WRITE;
buf++;
length--;
}
/* post flash write mutex, and return */
FsmReleaseMtxSem(pDev->DevWriteLock);
return status;
}
/*#############################################################################
### FsmTestErase
###
### DESCRIPTION:
### This function erases a single flash erase-block beginning at the
### address specified. This function performs several actions before
### calling FsmLowLvlErase() to perform the actual erase.
### First, the function translates the relative address
### into a physical system address and verifies the address range.
### After taking the flash erase semaphore, it calls the low-level
### function FsmLowLvlErase() via its function pointer.
### Upon completion of the erase, the function releases the flash
### erase semaphore and returns the appropriate value.
###
### PARAMETERS:
### IN: address (DWORD) - The starting address of the block within
### flash to be erased.
### OUT:
###
### RETURNS:
### If the address being specified does not fall within the driver
### managed area, the function returns HW_ERR_PARAM.
### If an error occurred while erasing the block, the function
### returns HW_ERR_ERASE. Finally, if all parameters are within
### the appropriate ranges and the block was successfully erased,
### the function returns HW_ERR_NONE.
###
*/
uint32 FsmTestErase(FsmDevObjHdrT * DevObjP, uint32 Addr)
{
uint32 status;
uint32 length;
uint32 temp;
uint32 data = 0xFFFFFFFF;
FsmFlashDevT * pDev;
pDev = (FsmFlashDevT *)DevObjP;
/* power loss simulation for testing purposes */
/* validate address */
#ifdef VALIDATE_ADDRESS
if(Addr > (pDev->BlockSize * pDev->Blocks))
{
return HW_ERR_PARAM;
}
#endif //VALIDATE_ADDRESS
Addr = (Addr / pDev->BlockSize) * pDev->BlockSize;
length = pDev->BlockSize;
/* take flash erase mutex */
if(FsmGetMtxSem(pDev->DevWriteLock) != ERR_NONE)
{
return HW_ERR_SYSTEM;
}
SetFilePointer((HANDLE)(pDev->DevStartAddr), Addr, NULL, FILE_BEGIN);
status = HW_ERR_NONE;
while ((length > 0) && (status == HW_ERR_NONE))
{
/* write to flash */
WriteFile((HANDLE)(pDev->DevStartAddr), &data, 1, &temp, NULL);
/* power loss simulation for testing purposes */
if((rand() % 0x20000) == 0x18000)
status = HW_ERR_ERASE;
length--;
}
/* post flash erase mutex */
FsmReleaseMtxSem(pDev->DevWriteLock);
return status;
}
/*#############################################################################
### FsmTestCopy
###
### DESCRIPTION:
### This function is used to copy valid data during reclaim and during
### updates to copy data that is not changing.
###
### PARAMETERS:
### IN: dst_address (DWORD) - The starting address within flash to copy
### data to.
### src_address (DWORD) - The starting address within flash to read
### the data from.
### length (DWORD) - The amount of data, in bytes, to copy.
###
### RETURNS:
### If the source and destination buffers do not lie entirely within the
### driver managed area, the function returns HW_ERR_PARAM.
### If an error occurred while writing to the flash hardware,
### the function returns HW_ERR_WRITE. Finally, if all
### parameters are within the appropriate ranges and the buffer
### was successfully copied, the funciton returns HW_ERR_NONE.
###
*/
uint32 FsmTestCopy(FsmDevObjHdrT * DevObjP, uint32 DstAddr, uint32 SrcAddr, uint32 length)
{
uint32 temp;
uint32 data;
uint32 status = HW_ERR_NONE;
FsmFlashDevT * pDev;
pDev = (FsmFlashDevT *)DevObjP;
/* power loss simulation for testing purposes */
/* validate address */
#ifdef VALIDATE_ADDRESS
if((SrcAddr + length) > (pDev->BlockSize * pDev->Blocks))
{
return HW_ERR_PARAM;
}
if((DstAddr + length) > (pDev->BlockSize * pDev->Blocks))
{
return HW_ERR_PARAM;
}
#endif //VALIDATE_ADDRESS
/* return if nothing to write */
if (length == 0)
{
return HW_ERR_NONE;
}
/* take flash write mutex. */
if(FsmGetMtxSem(pDev->DevWriteLock) != ERR_NONE)
{
return HW_ERR_SYSTEM;
}
while ((length > 0) && (status == HW_ERR_NONE))
{
/* Read from flash. */
SetFilePointer((HANDLE)(pDev->DevStartAddr), SrcAddr, NULL, FILE_BEGIN);
ReadFile((HANDLE)(pDev->DevStartAddr), &data, 1, &temp, NULL);
/* write to flash */
SetFilePointer((HANDLE)(pDev->DevStartAddr), DstAddr, NULL, FILE_BEGIN);
WriteFile((HANDLE)(pDev->DevStartAddr), &data, 1, &temp, NULL);
/* power loss simulation for testing purposes */
if((rand() % 0x20000) == 0x18000)
status = HW_ERR_WRITE;
SrcAddr++;
DstAddr++;
length--;
}
/* post flash write mutex, and return */
FsmReleaseMtxSem(pDev->DevWriteLock);
return status;
}
uint32 FsmTestCtrl(FsmDevObjHdrT * DevObjP, uint32 CtrlCode, void *arg)
{
FsmFlashDevT * pDev;
pDev = (FsmFlashDevT *)DevObjP;
switch(CtrlCode)
{
case DEV_CTRL_DEVICE_DETACH:
CloseHandle((HANDLE)(pDev->DevStartAddr));
break;
default:
break;
}
return HW_ERR_NONE;
}
/*****************************************************************************
* $Log: testdrv.c $
* Revision 1.3 2004/03/17 12:58:12 zgy
* Revision 1.8 2004/03/16 15:56:29 jjs
* Revision 1.7 2003/10/08 21:37:47 jjs
* Revision 1.6 2003/09/16 17:24:30 jjs
* Revision 1.5 2003/09/16 17:07:38 jjs
* Revision 1.3 2003/09/12 14:23:55 jjs
* Revision 1.2 2003/09/12 11:52:00 jjs
* Revision 1.1 2003/09/09 22:08:42 jjs
* Initial revision
* Revision 1.1 2003/09/09 15:07:32 jjs
* Initial revision
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -