📄 sysflashmem.c
字号:
/* sysFlashMem.c - Flash memory library */
/* Copyright 2003-2004 ZTE, Inc. */
/*
modification history
--------------------
01a,17jun03,lzq created.
*/
/*
DESCRIPTION
This library contains routines to manipulate flash memory. Read, write and erase
routines are included.
*/
#include "vxWorks.h"
#include "intLib.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "semLib.h"
#include "taskLib.h"
#include "config.h"
#include "sysFlashMem.h"
#include "sysFlashDev.h"
#include "configFlashMem.h"
/* defines */
#define SYS_FLASH_HW_INIT() \
if (sysFlashHwInit != NULL) \
(sysFlashHwInit)()
#define SYS_FLASH_HW_ENABLE() \
if (sysFlashHwEnable != NULL) \
(sysFlashHwEnable)()
#define SYS_FLASH_HW_DISABLE() \
if (sysFlashHwDisable != NULL) \
(sysFlashHwDisable)()
#define SYS_FLASH_TIMER_RESET() \
if (sysFlashTimerReset != NULL) \
(sysFlashTimerReset)()
#define SYS_FLASH_IO_SYNC() \
__asm__("eieio; isync; sync")
#define SYS_FLASH_BOARD_DELAY() \
if (sysFlashBoardDelay != NULL) \
(sysFlashBoardDelay)()
int flashInited = 0;
static FLASH_ID tempID, buffID;
static FLASH_UNIT flashUnit[FLASH_UNIT_NUM];
/* forward declarations */
static STATUS flashCfgRawGet(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS flashCmdRawSet(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashGetOctet1(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashSetOctet1(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashGetOctet2(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashSetOctet2(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashGetOctet4(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashSetOctet4(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashGetOctet8(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashSetOctet8(FLASH_DEV *dev, UINT32 pos, char *buf);
static void flashPartIdentify(FLASH_DEV *dev, FLASH_PART *unitPart, int partCnt);
static void amdFlashReset(FLASH_DEV *dev);
static STATUS amdFlashProbe(FLASH_DEV *dev);
static STATUS amdFlashErase(FLASH_DEV *dev, UINT32 pos);
static STATUS amdFlashWrite(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS amdFlashBWrite(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS amdFlashCheck(FLASH_DEV *dev, UINT32 pos, char *buf, int option);
static void intelFlashReset(FLASH_DEV *dev);
static STATUS intelFlashProbe(FLASH_DEV *dev);
static STATUS intelFlashUnlock(FLASH_DEV *dev, UINT32 pos);
static STATUS intelFlashUnlockAll(FLASH_DEV *dev);
static STATUS intelFlashErase(FLASH_DEV *dev, UINT32 pos);
static STATUS intelFlashWrite(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS intelFlashBWrite(FLASH_DEV *dev, UINT32 pos, char *buf);
static STATUS intelFlashCheck(FLASH_DEV *dev, UINT32 pos, int option);
static STATUS flashCheck(FLASH_DEV *dev);
/*******************************************************************************
*
* flashCfgRawGet -
*
*/
static STATUS flashCfgRawGet(FLASH_DEV *dev, UINT32 pos, char *buf)
{
pos *= dev->portSize;
switch (dev->portSize)
{
case 8:
*(UINT64 *)buf = *(volatile UINT64 *)(dev->devAddr + pos);
break;
case 4:
*(UINT32 *)buf = *(volatile UINT32 *)(dev->devAddr + pos);
break;
case 2:
*(UINT16 *)buf = *(volatile UINT16 *)(dev->devAddr + pos);
break;
case 1:
*(UINT8 *)buf = *(volatile UINT8 *)(dev->devAddr + pos);
break;
default:
return ERROR;
}
return OK;
}
/*******************************************************************************
*
* flashCmdRawSet -
*
*/
static STATUS flashCmdRawSet(FLASH_DEV *dev, UINT32 pos, char *buf)
{
pos *= dev->portSize;
switch (dev->portSize)
{
case 8:
*(volatile UINT64 *)(dev->devAddr + pos) = *(UINT64 *)buf;
break;
case 4:
*(volatile UINT32 *)(dev->devAddr + pos) = *(UINT32 *)buf;
break;
case 2:
*(volatile UINT16 *)(dev->devAddr + pos) = *(UINT16 *)buf;
break;
case 1:
buf++;
*(volatile UINT8 *)(dev->devAddr + pos) = *(UINT8 *)buf;
break;
default:
return ERROR;
}
return OK;
}
/*******************************************************************************
*
* flashGetOctet1 -
*
*/
static void flashGetOctet1(FLASH_DEV *dev, UINT32 pos, char *buf)
{
*(UINT8 *)buf = *(volatile UINT8 *)(dev->devAddr + pos);
}
/*******************************************************************************
*
* flashSetOctet1 -
*
*/
static void flashSetOctet1(FLASH_DEV *dev, UINT32 pos, char *buf)
{
if ((buf >= (char *)&amdFlashCmd[0] &&
buf < (char *)&amdFlashCmd[sizeof(amdFlashCmd) / sizeof(amdFlashCmd[0])]) ||
(buf >= (char *)&intelFlashCmd[0] &&
buf < (char *)&intelFlashCmd[sizeof(intelFlashCmd) / sizeof(intelFlashCmd[0])]))
buf++;
*(volatile UINT8 *)(dev->devAddr + pos) = *(UINT8 *)buf;
}
/*******************************************************************************
*
* flashGetOctet2 -
*
*/
static void flashGetOctet2(FLASH_DEV *dev, UINT32 pos, char *buf)
{
*(UINT16 *)buf = *(volatile UINT16 *)(dev->devAddr + pos);
}
/*******************************************************************************
*
* flashSetOctet2 -
*
*/
static void flashSetOctet2(FLASH_DEV *dev, UINT32 pos, char *buf)
{
*(volatile UINT16 *)(dev->devAddr + pos) = *(UINT16 *)buf;
}
/*******************************************************************************
*
* flashGetOctet4 -
*
*/
static void flashGetOctet4(FLASH_DEV *dev, UINT32 pos, char *buf)
{
*(UINT32 *)buf = *(volatile UINT32 *)(dev->devAddr + pos);
}
/*******************************************************************************
*
* flashSetOctet4 -
*
*/
static void flashSetOctet4(FLASH_DEV *dev, UINT32 pos, char *buf)
{
*(volatile UINT32 *)(dev->devAddr + pos) = *(UINT32 *)buf;
}
/*******************************************************************************
*
* flashGetOctet8 -
*
*/
static void flashGetOctet8(FLASH_DEV *dev, UINT32 pos, char *buf)
{
*(UINT64 *)buf = *(volatile UINT64 *)(dev->devAddr + pos);
}
/*******************************************************************************
*
* flashSetOctet8 -
*
*/
static void flashSetOctet8(FLASH_DEV *dev, UINT32 pos, char *buf)
{
*(volatile UINT64 *)(dev->devAddr + pos) = *(UINT64 *)buf;
}
/*******************************************************************************
*
* flashPartIdentify -
*
*/
static void flashPartIdentify(FLASH_DEV *dev, FLASH_PART *unitPart, int partCnt)
{
FLASH_PART *part, *devPart;
FLASH_UNIT *unit = &flashUnit[dev->unitNo];
UINT32 keyPos = unit->unitSize;
UINT32 partPos = 0;
UINT32 partCount = 0;
int i;
devPart = (FLASH_PART *)malloc(sizeof(FLASH_PART) * partCnt);
if (devPart == NULL)
{
printf("malloc error!\n");
return;
}
dev->devPart = devPart;
part = unitPart;
for (i = 0; i < partCnt; i++, part++)
{
partPos += dev->bankCount * part->blockSize * part->blockCount;
if (partPos <= unit->unitSize)
continue;
if (dev->devSize + unit->unitSize <= partPos)
{
devPart->blockSize = part->blockSize;
devPart->blockCount = (dev->devSize + unit->unitSize - keyPos) /
(dev->bankCount * part->blockSize);
dev->partCount = partCount + 1;
unit->unitSize += dev->devSize;
break;
}
devPart->blockSize = part->blockSize;
devPart->blockCount = (partPos - keyPos) / (dev->bankCount * part->blockSize);
devPart++;
partCount++;
keyPos = partPos;
}
}
/*******************************************************************************
*
* amdFlashReset -
*
*/
static void amdFlashReset(FLASH_DEV *dev)
{
/*
(*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
(*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
(*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[7]);
*/
(*dev->set)(dev, 0x0, (char *)&amdFlashCmd[7]);
}
/*******************************************************************************
*
* amdFlashProbe -
*
*/
static STATUS amdFlashProbe(FLASH_DEV *dev)
{
FLASH_UNIT *unit = &flashUnit[dev->unitNo];
FLASH_PHY *phy = flashPhy;
UINT8 offset = dev->portSize > 1 ? 0 : 1;
if (unit->inited && !unit->phy->isAmdType)
return ERROR;
if (!unit->inited)
{
unit->unitAddr = dev->devAddr;
memset(&tempID, 0, sizeof(tempID));
memset(&buffID, 0, sizeof(buffID));
flashCmdRawSet(dev, 0x5555, (char *)&amdFlashCmd[0]);
flashCmdRawSet(dev, 0x2AAA, (char *)&amdFlashCmd[1]);
flashCmdRawSet(dev, 0x5555, (char *)&amdFlashCmd[6]);
taskDelay(1);
flashCfgRawGet(dev, 0x0, (char *)&tempID.vendorID);
flashCfgRawGet(dev, 0x1, (char *)&tempID.deviceID);
flashCfgRawGet(dev, 0xE, (char *)&tempID.subdevID1);
flashCfgRawGet(dev, 0xF, (char *)&tempID.subdevID2);
flashCmdRawSet(dev, 0x0, (char *)&amdFlashCmd[7]);
if (*(char *)&tempID.vendorID != (char)0xFF)
buffID = tempID;
do
{
if ((memcmp((char *)&tempID.vendorID, (char *)&phy->flashID->vendorID + offset, dev->portSize) == OK) &&
(memcmp((char *)&tempID.deviceID, (char *)&phy->flashID->deviceID + offset, dev->portSize) == OK) &&
phy->isAmdType)
{
if ((phy->flashID->subdevID1 == (UINT64)0x0) ||
((memcmp((char *)&tempID.subdevID1, (char *)&phy->flashID->subdevID1 + offset, dev->portSize) == OK) &&
(memcmp((char *)&tempID.subdevID2, (char *)&phy->flashID->subdevID2 + offset, dev->portSize) == OK)))
{
unit->phy = phy;
unit->inited = 1;
break;
}
}
phy++;
} while (phy->flashID != (FLASH_ID *)-1);
if (!unit->inited)
return ERROR;
}
flashPartIdentify(dev, unit->phy->flashPart, unit->phy->partCount);
unit->devCount++;
switch (dev->portSize)
{
case 8:
dev->get = flashGetOctet8;
dev->set = flashSetOctet8;
break;
case 4:
dev->get = flashGetOctet4;
dev->set = flashSetOctet4;
break;
case 2:
dev->get = flashGetOctet2;
dev->set = flashSetOctet2;
break;
case 1:
dev->get = flashGetOctet1;
dev->set = flashSetOctet1;
break;
default:
return ERROR;
}
if (dev->writeBufMod && unit->phy->writeBufMod)
dev->write = amdFlashBWrite;
else
{
dev->write = amdFlashWrite;
dev->writeBufMod = 0;
}
dev->erase = amdFlashErase;
if (!unit->unitSem)
{
unit->unitSem = semBCreate(SEM_Q_FIFO, SEM_FULL);
if (unit->unitSem == NULL)
return ERROR;
}
dev->devSem = unit->unitSem;
dev->unit = unit;
dev->inited = 1;
return OK;
}
/*******************************************************************************
*
* amdFlashErase -
*
*/
static STATUS amdFlashErase(FLASH_DEV *dev, UINT32 pos)
{
UINT8 temp[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
(*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
(*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
(*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[3]);
(*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
(*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
(*dev->set)(dev, pos, (char *)&amdFlashCmd[4]);
return amdFlashCheck(dev, pos, temp, FLASH_POLL_ERASE);
}
/*******************************************************************************
*
* amdFlashWrite -
*
*/
static STATUS amdFlashWrite(FLASH_DEV *dev, UINT32 pos, char *buf)
{
(*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
(*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
(*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[2]);
(*dev->set)(dev, pos, buf);
return amdFlashCheck(dev, pos, buf, FLASH_POLL_WRITE);
}
/*******************************************************************************
*
* amdFlashBWrite -
*
*/
static STATUS amdFlashBWrite(FLASH_DEV *dev, UINT32 pos, char *buf)
{
UINT32 curPos = pos;
char *tempBuf = buf;
int intLevel;
UINT32 i;
(*dev->set)(dev, 0x5555 * dev->portSize, (char *)&amdFlashCmd[0]);
(*dev->set)(dev, 0x2AAA * dev->portSize, (char *)&amdFlashCmd[1]);
(*dev->set)(dev, pos, (char *)&amdFlashCmd[8]);
if (dev->portSize != 1)
(*dev->set)(dev, pos, (char *)&amdFlashCmd[9]);
else
(*dev->set)(dev, pos, (char *)&amdFlashCmd[10]);
intLevel = intLock();
for (i = 0; i < WRITE_BUF_SIZE * dev->bankCount / dev->portSize; i++)
{
(*dev->set)(dev, curPos, tempBuf);
curPos += dev->portSize;
tempBuf += dev->portSize;
}
intUnlock(intLevel);
(*dev->set)(dev, pos, (char *)&amdFlashCmd[11]);
return amdFlashCheck(dev, pos, buf, FLASH_POLL_WRITE);
}
/*******************************************************************************
*
* amdFlashCheck -
*
*/
static STATUS amdFlashCheck(FLASH_DEV *dev, UINT32 pos, char *buf, int option)
{
UINT32 curPos = pos;
char *tempBuf = buf;
char stat[8];
UINT32 dataSize;
UINT32 polls;
UINT32 i, j;
if (option == FLASH_POLL_ERASE)
{
polls = FLASH_ERASE_TIMEOUT;
dataSize = dev->portSize;
}
else
{
polls = FLASH_WRITE_TIMEOUT;
dataSize = dev->writeBufMod ? WRITE_BUF_SIZE * dev->bankCount : dev->portSize;
}
for (i = 0; i < polls; i++)
{
if (option == FLASH_POLL_ERASE)
{
taskDelay(1);
}
SYS_FLASH_TIMER_RESET();
curPos = pos;
tempBuf = buf;
for (j = 0; j < dataSize; j += dev->portSize)
{
(*dev->get)(dev, curPos, stat);
if (memcmp(stat, tempBuf, dev->portSize) != OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -