📄 flash.c
字号:
*sector = sec;
}
if (base) {
*base = sinfo->begin;
}
if (size) {
*size = sinfo->size;
}
return(0);
}
}
}
printf("addrtosector(0x%lx) failed\n",(ulong)addr);
return(-1);
}
/* addrtobank():
* From the incoming address, return a pointer to the flash bank that
* this address is within.
*/
struct flashinfo *
addrtobank(uchar *addr)
{
struct flashinfo *fbnk;
int dev;
fbnk = FlashBank;
for(dev=0;dev<FLASHBANKS;dev++,fbnk++) {
if ((addr >= fbnk->base) && (addr <= fbnk->end))
return(fbnk);
}
printf("addrtobank(0x%lx) failed\n",(ulong)addr);
return(0);
}
int
sectortoaddr(int sector,int *size,uchar **base)
{
struct flashinfo *fbnk;
struct sectorinfo *sinfo;
int dev, sec, i;
sec = 0;
fbnk = FlashBank;
for(dev=0;dev<FLASHBANKS;dev++,fbnk++) {
for(i=0;i<fbnk->sectorcnt;i++,sec++) {
if (sec == sector) {
sinfo = &fbnk->sectors[i];
if (base) base = sinfo->begin;
if (size) *size = sinfo->size;
return(0);
}
}
}
printf("sectortoaddr(%d) failed\n",sector);
return(-1);
}
/* InFlashSpace():
* Return 1 if the block of memory is within flash space;
* else return 0.
*/
int
InFlashSpace(uchar *begin, int size)
{
int dev;
uchar *end;
struct flashinfo *fbnk;
end = begin+size;
fbnk = FlashBank;
for(dev=0;dev<FLASHBANKS;dev++,fbnk++) {
if (((begin >= fbnk->base) && (begin <= fbnk->end)) ||
((end >= fbnk->base) && (end <= fbnk->end)))
return(1);
}
return(0);
}
/* flashbankinfo():
* Based on the incoming bank number, return the beginning, end and
* number of sectors within that bank.
*/
int
flashbankinfo(int bank,uchar **begin,uchar **end,int *sectorcnt)
{
struct flashinfo *fbnk;
if (bank >= FLASHBANKS)
return(-1);
fbnk = &FlashBank[bank];
if (begin)
*begin = fbnk->base;
if (end)
*end = fbnk->end;
if (sectorcnt)
*sectorcnt = fbnk->sectorcnt;
return(0);
}
/* lastlargesector():
* Incoming bank number is used to populate the sector information
* (sector number, sector size and address) of the last large sector
* in the specified bank.
* Return 0 if successful; else -1.
*/
int
lastlargesector(int bank,int *sector,int *size,uchar **base)
{
struct flashinfo *fbnk;
struct sectorinfo *sinfo;
uchar *largest_sbase;
int i, largest_ssize, largest_snum;
if (bank >= FLASHBANKS) {
printf("lastlargesector(%d) failed\n",bank);
return(-1);
}
fbnk = &FlashBank[bank];
sinfo = fbnk->sectors;
largest_ssize = 0;
largest_snum = 0;
largest_sbase = (uchar *)0;
for(i=0;i<fbnk->sectorcnt;i++,sinfo++) {
if (sinfo->size >= largest_ssize) {
largest_ssize = sinfo->size;
largest_snum = sinfo->snum;
largest_sbase = sinfo->begin;
}
}
if (sector)
*sector = largest_snum;
if (size)
*size = largest_ssize;
if (base)
*base = largest_sbase;
return(0);
}
void
LowerFlashProtectWindow()
{
if (FlashProtectWindow)
FlashProtectWindow--;
}
/* AppFlashWrite():
* Takes in a source, destination and byte count and converts that to
* the appropriate flashwrite() call. This function supports the possibility
* of having one write request span across multiple devices in contiguous
* memory space.
*/
int
AppFlashWrite(uchar *dest,uchar *src,long bytecnt)
{
int ret;
ulong oints;
long tmpcnt;
struct flashinfo *fbnk;
ret = 0;
while(bytecnt > 0) {
fbnk = nametofdev(boot_device_name);
if (!fbnk)
return(-1);
if ((dest + bytecnt) <= fbnk->end)
tmpcnt = bytecnt;
else
tmpcnt = (fbnk->end - dest) + 1;
oints = FLASH_INTSOFF();
ret = flashwrite(fbnk,dest,src,tmpcnt);
FLASH_INTSRESTORE(oints);
if (ret < 0) {
printf("AppFlashWrite(0x%lx,0x%lx,%ld) failed (%d)\n",
(ulong)dest,(ulong)src,bytecnt,ret);
break;
}
src += tmpcnt;
dest += tmpcnt;
bytecnt -= tmpcnt;
}
return(ret);
}
/* AppFlashRead():
* Takes in a source, destination and byte count and converts that to
* the appropriate flashwrite() call. This function supports the possibility
* of having one write request span across multiple devices in contiguous
* memory space.
*/
int
AppFlashRead(uchar *dest,uchar *src,long bytecnt)
{
int ret;
ulong oints;
long tmpcnt;
struct flashinfo *fbnk;
ret = 0;
while(bytecnt > 0) {
fbnk = nametofdev(boot_device_name);
if (!fbnk)
return(-1);
if ((src + bytecnt) <= fbnk->end)
tmpcnt = bytecnt;
else
tmpcnt = (fbnk->end - src) + 1;
oints = FLASH_INTSOFF();
ret = flashread(fbnk,dest,src,tmpcnt);
FLASH_INTSRESTORE(oints);
if (ret < 0) {
printf("AppFlashWrite(0x%lx,0x%lx,%ld) failed (%d)\n",
(ulong)dest,(ulong)src,bytecnt,ret);
break;
}
src += tmpcnt;
dest += tmpcnt;
bytecnt -= tmpcnt;
}
return(ret);
}
int
lastflashsector(void)
{
int lastsnum;
struct flashinfo *lastfbnk;
lastfbnk = &FlashBank[FLASHBANKS-1];
lastsnum = lastfbnk->sectors[lastfbnk->sectorcnt-1].snum;
return(lastsnum);
}
int
AppFlashEraseAll()
{
ulong oints;
int ret, snum, lastsnum;
ret = 0;
oints = FLASH_INTSOFF();
/* Loop through all sectors of all banks...
*/
lastsnum = lastflashsector();
for(snum=0;snum<=lastsnum;snum++) {
WATCHDOG_MACRO;
ret = flasherase(snum);
if (ret <= 0)
break;
}
FLASH_INTSRESTORE(oints);
return(ret);
}
/* Erase the flash sector specified. */
int
AppFlashErase(int snum) /* erase specified sector */
{
int ret;
ulong oints;
oints = FLASH_INTSOFF();
ret = flasherase(snum);
FLASH_INTSRESTORE(oints);
return(ret);
}
/* sectorProtect():
* Set or clear (based on value of protect) the protected flag for the
* specified range of sectors...
* This supports incoming ranges that can be dash and/or comma delimited.
* For example a range can be "0", "0-3", or "0,2-4", etc...
*/
int
sectorProtect(char *range, int protect)
{
struct flashinfo *fbnk;
int i, dev, snum;
snum = 0;
for(dev = 0;dev < FLASHBANKS;dev++) {
fbnk = &FlashBank[dev];
for(i = 0;i < fbnk->sectorcnt;i++,snum++) {
if ((range == 0) || (*range == 0) || inRange(range,snum))
fbnk->sectors[i].protected = protect;
}
}
return(0);
}
#ifdef FLASHRAM_BASE
struct sectorinfo sinfoRAM[FLASHRAM_SECTORCOUNT];
/* FlashRamInit():
* This monitor supports TFS space allocated across multiple flash devices
* that may not be in contiguous memory space. To allow RAM to be seen
* as a "flash-like" device to TFS, we set it up in sectors similar to
* those in a real flash device.
* Input...
* snum: All the "flash" space is broken up into individual sectors.
* This is the starting sector number that is to be used for
* the block of sectors within this RAM space.
* fbnk: Pointer to the structure that must be populated with the
* flash bank information. Usually this contains pointers to the
* functions that operate on the flash; but for RAM they aren't
* necessary.
* sinfo: Table populated with the characteristics (size, start, etc...)
* of each sector.
* ssizes: A table containing the size of each of the sectors. This is
* copied to the sinfo space. If this pointer is NULL, then
* this function sets all sector sizes to FLASHRAM_SECTORSIZE.
*/
int
FlashRamInit(int snum, int scnt, struct flashinfo *fbnk,
struct sectorinfo *sinfo, int *ssizes)
{
int i;
uchar *begin;
/* FLASHRAM_SECTORCOUNT (in config.h) must match the number of sectors
* allocated to the flash ram device in flashdev.c...
*/
if (scnt != FLASHRAM_SECTORCOUNT)
printf("Warning: flashram sector count inconsistency\n");
fbnk->id = FLASHRAM; /* Device id. */
fbnk->base = (uchar *)FLASHRAM_BASE; /* Base address of bank. */
fbnk->end = (uchar *)FLASHRAM_END; /* End address of bank. */
fbnk->sectorcnt = scnt; /* Number of sectors. */
fbnk->width = 1; /* Width (in bytes). */
fbnk->fltype = FlashOpNotSupported; /* Flashtype() function. */
fbnk->flerase = FlashOpNotSupported; /* Flasherase() function. */
fbnk->flwrite = FlashOpNotSupported; /* Flashwrite() function. */
fbnk->flewrite = FlashOpNotSupported; /* Flashewrite() function. */
fbnk->fllock = FlashOpNotSupported; /* Flashlock() function. */
fbnk->sectors = sinfo; /* Ptr to sector size table. */
begin = fbnk->base;
for(i=0;i<fbnk->sectorcnt;i++,snum++) {
sinfo[i].snum = snum;
if (ssizes == 0)
sinfo[i].size = FLASHRAM_SECTORSIZE;
else
sinfo[i].size = ssizes[i];
sinfo[i].begin = begin;
sinfo[i].end = sinfo[i].begin + sinfo[i].size - 1;
sinfo[i].protected = 0;
begin += sinfo[i].size;
}
return(snum);
}
#endif
char *FlashHelp[] = {
"Flash memory operations",
"{op} [args]",
#if INCLUDE_VERBOSEHELP
"Ops...",
" opw",
" init",
" type",
" bank [#]",
" prot {rnge}",
" info [rnge]",
" unprot {rnge}",
" lock {rnge}",
" unlock [rnge]",
" lockdwn {rnge}",
" erase {rnge}",
" trace {lvl}",
" write {dest} {src} {byte_cnt}",
" ewrite {dest} {src} {byte_cnt}",
"",
" rnge = range of affected sectors",
" Range syntax examples: <1> <1-5> <1,3,7> <all>",
#endif
0,
};
/* FlashCmd():
* Code that handles the user interface. See FlashHelp[] below for usage.
*/
int
FlashCmd(int argc,char *argv[])
{
int snum, ret;
//uchar *dest = (uchar *)malloc(sizeof(uchar));
ulong dest,src, oints;
long bytecnt, rslt;
struct flashinfo *fbnk;
if(argc<3)
return(CMD_PARAM_ERROR);
boot_device_name = argv[1];
oints = FLASH_INTSOFF();
//fbnk = &FlashBank[FlashCurrentBank];
fbnk = nametofdev(argv[1]);
if(!fbnk)
return -1;
ret = CMD_SUCCESS;
if (strcmp(argv[2],"init") == 0)
FlashInit();
else if (strcmp(argv[2],"info") == 0) {
showflashinfo(argv[3]);
}
else if (strcmp(argv[2],"type") == 0) {
showflashtype((ulong)flashtype(fbnk),1);
}
else if (strcmp(argv[2],"trace") == 0) {
if (argc == 4)
FlashTrace = atoi(argv[3]);
else if (argc == 3)
printf("Flash trace lvl: %d\n",FlashTrace);
else
return(CMD_PARAM_ERROR);
}
else if (strcmp(argv[2],"bank") == 0) {
int tmpbank;
if (argc == 4) {
tmpbank = atoi(argv[3]);
if (tmpbank < FLASHBANKS) {
FlashCurrentBank = tmpbank;
}
else {
printf("Bank %d out of range\n",tmpbank);
return(CMD_PARAM_ERROR);
}
printf("Subsequent flash ops apply to bank %d\n",
FlashCurrentBank);
}
else {
showflashtotal();
}
}
else if (strcmp(argv[2],"ewrite") == 0) {
if (argc == 6) {
dest = strtoul(argv[3],(char **)0,0);
src = strtoul(argv[4],(char **)0,0);
bytecnt = (long)strtoul(argv[5],(char **)0,0);
rslt = flashewrite((uchar *)dest,(uchar *)src,bytecnt);
if (rslt < 0) {
printf("ewrite failed (%ld)\n",rslt);
ret = CMD_FAILURE;
}
}
else
ret = CMD_PARAM_ERROR;
}
else if (!strcmp(argv[2],"write")) {
if (argc == 6) {
dest = strtoul(argv[3],(char **)0,0);
src = strtoul(argv[4],(char **)0,0);
bytecnt = (long)strtoul(argv[5],(char **)0,0);
//printf("(char)dest=0x%x,(char *)=0x%x",dest,(uchar *)dest);
rslt = AppFlashWrite((uchar *)dest,(uchar *)src,bytecnt);
if (rslt < 0) {
printf("Write failed (%ld)\n",rslt);
ret = CMD_FAILURE;
}
}
else
ret = CMD_PARAM_ERROR;
}
else if (!strcmp(argv[2],"read")) {
if (argc == 6) {
dest = strtoul(argv[3],(char **)0,0);
src = strtoul(argv[4],(char **)0,0);
bytecnt = (long)strtoul(argv[5],(char **)0,0);
//printf("(char)dest=0x%x,(char *)=0x%x",dest,(uchar *)dest);
rslt = AppFlashRead((uchar *)dest,(uchar *)src,bytecnt);
if (rslt < 0) {
printf("Read failed (%ld)\n",rslt);
ret = CMD_FAILURE;
}
}
else
ret = CMD_PARAM_ERROR;
}
else if (!strcmp(argv[2],"opw")) {
if (getUsrLvl() != MAXUSRLEVEL)
printf("Must be user level %d\n",MAXUSRLEVEL);
else
FlashProtectWindow = 2;
}
else if (!strcmp(argv[2],"unprot")) {
if (argc != 4)
ret = CMD_PARAM_ERROR;
else
sectorProtect(argv[3],0);
}
else if (!strcmp(argv[2],"prot")) {
if (argc != 4)
ret = CMD_PARAM_ERROR;
else
sectorProtect(argv[3],1);
}
else if (!strcmp(argv[2],"erase")) {
if (argc != 4) {
ret = CMD_PARAM_ERROR;
}
else {
int last;
last = lastflashsector();
for(snum=0;snum<=last;snum++) {
int rc;
if ((argv[3] == 0) || inRange(argv[3],snum)) {
ticktock();
rc = flasherase(snum);
if (rc != 1) {
printf("Erase failed (%d)\n",rc);
ret = CMD_FAILURE;
break;
}
}
}
}
}
else if ((!strcmp(argv[2],"lock")) || (!strcmp(argv[2],"unlock")) ||
(!strcmp(argv[2],"lockdwn"))) {
int operation, snum;
if (!strcmp(argv[2],"lock"))
operation = FLASH_LOCK;
else if (!strcmp(argv[2],"unlock")) {
operation = FLASH_UNLOCK;
if (argc == 3) {
argv[3] = FLASH_PROTECT_RANGE;
argc = 4;
printf("Unlocking %s...\n",argv[3]);
}
}
else
operation = FLASH_LOCKDWN;
if (argc != 4) {
ret = CMD_PARAM_ERROR;
}
else {
int last;
struct flashinfo *fdev;
last = lastflashsector();
for(snum=0;snum<=last;snum++) {
if (inRange(argv[3],snum)) {
ticktock();
if ((fdev = nametofdev(snum)) == 0) {
ret = CMD_FAILURE;
break;
}
if (flashlock(fdev->sectors[0].snum,FLASH_LOCKABLE) <= 0) {
printf("Sector %d does not support %s\n",snum,argv[2]);
ret = CMD_FAILURE;
break;
}
rslt = flashlock(snum,operation);
if (rslt < 0) {
printf("%s failed (%ld) at sector %d\n",
argv[2],rslt,snum);
ret = CMD_FAILURE;
break;
}
}
}
}
}
else {
ret = CMD_PARAM_ERROR;
}
FLASH_INTSRESTORE(oints);
return(ret);
}
int
FlashOpNotSupported()
{
if (FlashTrace)
printf("flash operation not supported\n");
return(-1);
}
/* Used as a placeholder for the flash drivers that don't
* support flash lock...
*/
int
FlashLockNotSupported(struct flashinfo *fdev,int snum,int operation)
{
if (operation == FLASH_LOCKABLE)
return(0);
else
return(-1);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -