diff options
Diffstat (limited to 'main/common/flash.c')
-rw-r--r-- | main/common/flash.c | 2174 |
1 files changed, 1111 insertions, 1063 deletions
diff --git a/main/common/flash.c b/main/common/flash.c index 9e01586..c8279e4 100644 --- a/main/common/flash.c +++ b/main/common/flash.c @@ -1,7 +1,7 @@ /************************************************************************** * * Copyright (c) 2013 Alcatel-Lucent - * + * * Alcatel Lucent licenses this file to You under the Apache License, * Version 2.0 (the "License"); you may not use this file except in * compliance with the License. A copy of the License is contained the @@ -40,34 +40,34 @@ extern struct flashdesc FlashNamId[]; -int FlashTrace; -int FlashCurrentBank; -int sectortoaddr(int,int *,uchar **); +int FlashTrace; +int FlashCurrentBank; +int sectortoaddr(int,int *,uchar **); + +#define SRANGE_ERROR -1 +#define SRANGE_SINGLE 1 +#define SRANGE_RANGE 2 +#define SRANGE_ALL 3 -#define SRANGE_ERROR -1 -#define SRANGE_SINGLE 1 -#define SRANGE_RANGE 2 -#define SRANGE_ALL 3 - /* FlashProtectWindow: - * Must be set to allow any flash operation to be done on space assumed - * to be software protected. + * Must be set to allow any flash operation to be done on space assumed + * to be software protected. */ int FlashProtectWindow; /* FlashBank[]: - * This table contains all of the information that is needed to keep the - * flash code somewhat generic across multiple flash devices. + * This table contains all of the information that is needed to keep the + * flash code somewhat generic across multiple flash devices. */ -struct flashinfo FlashBank[FLASHBANKS]; +struct flashinfo FlashBank[FLASHBANKS]; #ifdef DISABLE_INTERRUPTS_DURING_FLASHOPS #define FLASH_INTSDECL unsigned long oints -#define FLASH_INTSOFF() oints = intsoff() -#define FLASH_INTSRESTORE(ival) intsrestore(oints) +#define FLASH_INTSOFF() oints = intsoff() +#define FLASH_INTSRESTORE(ival) intsrestore(oints) #else #define FLASH_INTSDECL -#define FLASH_INTSOFF() +#define FLASH_INTSOFF() #define FLASH_INTSRESTORE(ival) #endif @@ -78,58 +78,59 @@ struct flashinfo FlashBank[FLASHBANKS]; char * showlockop(int operation) { - switch(operation) { - case FLASH_LOCK: - return("lock"); - case FLASH_UNLOCK: - return("unlock"); - case FLASH_LOCKDWN: - return("lock_down"); - case FLASH_LOCKQRY: - return("lock_qry"); - case FLASH_LOCKABLE: - return("lockable"); - default: - return("???"); - } + switch(operation) { + case FLASH_LOCK: + return("lock"); + case FLASH_UNLOCK: + return("unlock"); + case FLASH_LOCKDWN: + return("lock_down"); + case FLASH_LOCKQRY: + return("lock_qry"); + case FLASH_LOCKABLE: + return("lockable"); + default: + return("???"); + } } /* showflashtype(): - * Find a match between the incoming id and an entry in the FlashNamId[] - * table. The FlashNamId[] table is part of the device-specific code. + * Find a match between the incoming id and an entry in the FlashNamId[] + * table. The FlashNamId[] table is part of the device-specific code. */ int showflashtype(ulong id, int showid) { - struct flashdesc *fdp; - - if (showid) - printf("Flash ID: 0x%lx\n",id); - - fdp = FlashNamId; - while(fdp->desc) { - if (id == fdp->id) { - printf("Device = %s\n",fdp->desc); - return(0); - } - fdp++; - } - if (id == FLASHRAM) { - printf("Device = FLASH-RAM\n"); - return(0); - } - printf("Flash id 0x%lx not recognized\n",id); - return(-1); + struct flashdesc *fdp; + + if(showid) { + printf("Flash ID: 0x%lx\n",id); + } + + fdp = FlashNamId; + while(fdp->desc) { + if(id == fdp->id) { + printf("Device = %s\n",fdp->desc); + return(0); + } + fdp++; + } + if(id == FLASHRAM) { + printf("Device = FLASH-RAM\n"); + return(0); + } + printf("Flash id 0x%lx not recognized\n",id); + return(-1); } void showflashtotal(void) { #if FLASHBANKS > 1 - printf("Total of %d banks (0-%d), current default bank: %d\n", - FLASHBANKS,FLASHBANKS-1,FlashCurrentBank); + printf("Total of %d banks (0-%d), current default bank: %d\n", + FLASHBANKS,FLASHBANKS-1,FlashCurrentBank); #else - printf("Current flash bank: 0\n"); + printf("Current flash bank: 0\n"); #endif } @@ -139,169 +140,173 @@ showflashtotal(void) int showflashinfo(char *devrange) { - uchar *base; - struct sectorinfo *sp; - struct flashinfo *fdev; - char *range, varname[32]; - int first_sector_of_device, devtot; - int locksupported, sector, lastsector, hdrprinted; - - devtot = 0; - hdrprinted = 0; - lastsector = lastflashsector(); - - /* An incoming NULL range implies "any" sector... - */ - if (devrange == 0) { - showflashtotal(); - range = "any"; - } - else { - range = devrange; - } - - /* Loop through all sectors on all devices, picking only those - * sectors that fall in the specified range. - */ - for(sector = 0; sector <= lastsector; sector++) { - if (gotachar()) { - getchar(); - printf("<break>\n"); - break; - } - if (!inRange(range,sector)) - continue; - - if (!(fdev = snumtofdev(sector))) - return(-1); - - first_sector_of_device = fdev->sectors[0].snum; - - if (flashlock(first_sector_of_device,FLASH_LOCKABLE) > 0) - locksupported = 1; - else - locksupported = 0; - - /* If sector is first sector of a device, then print - * device info also... - */ - if ((sector == first_sector_of_device) && (!strcmp(range,"any"))) { - if (showflashtype(fdev->id,0) < 0) - return(-1); - printf(" Bank width : %d\n",fdev->width); - printf(" Sectors : %d\n",fdev->sectorcnt); - printf(" Base addr : 0x%08lx\n",(ulong)(fdev->base)); - hdrprinted = 0; - - if (devrange == 0) { - sprintf(varname,"FLASH_BASE_%d",devtot); - shell_sprintf(varname,"0x%lx",(ulong)(fdev->base)); - sprintf(varname,"FLASH_SCNT_%d",devtot); - shell_sprintf(varname,"%d",fdev->sectorcnt); - sprintf(varname,"FLASH_END_%d",devtot); - shell_sprintf(varname,"0x%lx",(ulong)(fdev->end)); - } - devtot++; - } - - if (!hdrprinted) { - printf(" Sctr TFS? Begin End Size %s %s%s", - "SWProt?", "Erased?", locksupported ? " Locked?\n" : "\n"); - hdrprinted = 1; - } - - sp = &fdev->sectors[sector - first_sector_of_device]; - sectortoaddr(sp->snum,0,&base); - if ((range == 0) || inRange(range,sp->snum)) { - printf(" %3d %c 0x%08lx 0x%08lx 0x%06lx %s %s ", - sp->snum, tfsspace((char *)base) ? '*' : ' ', - (ulong)(sp->begin), (ulong)(sp->end), sp->size, - sp->protected ? "yes" : " no", - flasherased(sp->begin,sp->end) ? "yes" : " no"); - if (locksupported) { - switch(flashlock(sp->snum,FLASH_LOCKQRY)) { - case -1: - printf("???"); - break; - case 1: - printf("yes"); - break; - case 0: - printf(" no"); - break; - } - } - printf("\n"); - } - } - - if (devrange == 0) - shell_sprintf("FLASH_DEVTOT","%d",devtot); - - return(0); + uchar *base; + struct sectorinfo *sp; + struct flashinfo *fdev; + char *range, varname[32]; + int first_sector_of_device, devtot; + int locksupported, sector, lastsector, hdrprinted; + + devtot = 0; + hdrprinted = 0; + lastsector = lastflashsector(); + + /* An incoming NULL range implies "any" sector... + */ + if(devrange == 0) { + showflashtotal(); + range = "any"; + } else { + range = devrange; + } + + /* Loop through all sectors on all devices, picking only those + * sectors that fall in the specified range. + */ + for(sector = 0; sector <= lastsector; sector++) { + if(gotachar()) { + getchar(); + printf("<break>\n"); + break; + } + if(!inRange(range,sector)) { + continue; + } + + if(!(fdev = snumtofdev(sector))) { + return(-1); + } + + first_sector_of_device = fdev->sectors[0].snum; + + if(flashlock(first_sector_of_device,FLASH_LOCKABLE) > 0) { + locksupported = 1; + } else { + locksupported = 0; + } + + /* If sector is first sector of a device, then print + * device info also... + */ + if((sector == first_sector_of_device) && (!strcmp(range,"any"))) { + if(showflashtype(fdev->id,0) < 0) { + return(-1); + } + printf(" Bank width : %d\n",fdev->width); + printf(" Sectors : %d\n",fdev->sectorcnt); + printf(" Base addr : 0x%08lx\n",(ulong)(fdev->base)); + hdrprinted = 0; + + if(devrange == 0) { + sprintf(varname,"FLASH_BASE_%d",devtot); + shell_sprintf(varname,"0x%lx",(ulong)(fdev->base)); + sprintf(varname,"FLASH_SCNT_%d",devtot); + shell_sprintf(varname,"%d",fdev->sectorcnt); + sprintf(varname,"FLASH_END_%d",devtot); + shell_sprintf(varname,"0x%lx",(ulong)(fdev->end)); + } + devtot++; + } + + if(!hdrprinted) { + printf(" Sctr TFS? Begin End Size %s %s%s", + "SWProt?", "Erased?", locksupported ? " Locked?\n" : "\n"); + hdrprinted = 1; + } + + sp = &fdev->sectors[sector - first_sector_of_device]; + sectortoaddr(sp->snum,0,&base); + if((range == 0) || inRange(range,sp->snum)) { + printf(" %3d %c 0x%08lx 0x%08lx 0x%06lx %s %s ", + sp->snum, tfsspace((char *)base) ? '*' : ' ', + (ulong)(sp->begin), (ulong)(sp->end), sp->size, + sp->protected ? "yes" : " no", + flasherased(sp->begin,sp->end) ? "yes" : " no"); + if(locksupported) { + switch(flashlock(sp->snum,FLASH_LOCKQRY)) { + case -1: + printf("???"); + break; + case 1: + printf("yes"); + break; + case 0: + printf(" no"); + break; + } + } + printf("\n"); + } + } + + if(devrange == 0) { + shell_sprintf("FLASH_DEVTOT","%d",devtot); + } + + return(0); } #ifdef FLASH_COPY_TO_RAM /* flashopload(): - * Copy flash operation to ram space. - * Note that this function assumes that cache is disabled at this point. - * This is important because we are copying text into bss space and if - * cache was on, there could be a coherency problem. + * Copy flash operation to ram space. + * Note that this function assumes that cache is disabled at this point. + * This is important because we are copying text into bss space and if + * cache was on, there could be a coherency problem. */ int flashopload(ulong *begin,ulong *end,ulong *copy,int size) { - /* Some CPUs have 16bit opcodes and can only do aligned accesses. */ - unsigned short *sBegin = (unsigned short *)begin; - unsigned short *sEnd = (unsigned short *)end; - unsigned short *sCopy = (unsigned short *)copy; - - /* Verify space availability: */ - if (((int)end - (int)begin) >= size) { - printf("flashopload overflow ((0x%lx-0x%lx) > 0x%x)\n", - (ulong)end,(ulong)begin,size); - return(-1); - } - - /* Initially fill the copy space with 0xff so that the space - * remaining is viewable... - */ - memset((char *)copy,0xff,size); - - /* Copy function() to RAM, then verify: */ - while(sBegin < sEnd) { - *sCopy = *sBegin; - if (*sCopy++ != *sBegin++) { - printf("flashopload failed\n"); - return(-1); - } - } - - return(0); + /* Some CPUs have 16bit opcodes and can only do aligned accesses. */ + unsigned short *sBegin = (unsigned short *)begin; + unsigned short *sEnd = (unsigned short *)end; + unsigned short *sCopy = (unsigned short *)copy; + + /* Verify space availability: */ + if(((int)end - (int)begin) >= size) { + printf("flashopload overflow ((0x%lx-0x%lx) > 0x%x)\n", + (ulong)end,(ulong)begin,size); + return(-1); + } + + /* Initially fill the copy space with 0xff so that the space + * remaining is viewable... + */ + memset((char *)copy,0xff,size); + + /* Copy function() to RAM, then verify: */ + while(sBegin < sEnd) { + *sCopy = *sBegin; + if(*sCopy++ != *sBegin++) { + printf("flashopload failed\n"); + return(-1); + } + } + + return(0); } #endif /* flashtype(): - * Use the device-specific function pointer to call the routine - * relocated to RAM space. + * Use the device-specific function pointer to call the routine + * relocated to RAM space. */ int flashtype(struct flashinfo *fdev) { - return(fdev->fltype(fdev)); + return(fdev->fltype(fdev)); } /* flasherase(): - * Use the device-specific function pointer to call the routine - * relocated to RAM space. - * Note that flasherase() is called with a sector number. The sector - * number is relative to the entire system, not just the particular device. - * This means that if there is more than one flash device in the system that - * the actual sector number (relative to the device) may not be the same - * value. This adjustment is made here so that the underlying code that is - * pumped into ram for execution does not have to be aware of this. + * Use the device-specific function pointer to call the routine + * relocated to RAM space. + * Note that flasherase() is called with a sector number. The sector + * number is relative to the entire system, not just the particular device. + * This means that if there is more than one flash device in the system that + * the actual sector number (relative to the device) may not be the same + * value. This adjustment is made here so that the underlying code that is + * pumped into ram for execution does not have to be aware of this. * Return... * 1 if successful * -1 if failure @@ -310,196 +315,211 @@ flashtype(struct flashinfo *fdev) int flasherase(int snum) { - uchar *tmp; - ulong *base, *end; - int size, rc, dev_snum; - struct flashinfo *fdev; - struct sectorinfo *sinfo; - - if (FlashTrace) - printf("flasherase(%d)\n",snum); - - if (!(fdev = snumtofdev(snum))) - return(-1); - - /* If the device type is RAM, the erase is a bit different... - */ - if (fdev->id == FLASHRAM) { - // Use 'tmp' here to eliminate a 3.4 toolset warning. - sectortoaddr(snum,&size,&tmp); - base = (ulong *)tmp; - end = base + (size/sizeof(long)); - while(base < end) { - *base = 0xffffffff; - if (*base != 0xffffffff) - return(-1); - base++; - } - return(1); - } - - /* If the sector is soft-protected or locked, return negative - * and print failure. If the sector is already erased, then - * there is no need to issue the device-specific erase algorithm. - */ - dev_snum = snum - fdev->sectors[0].snum; - sinfo = &fdev->sectors[dev_snum]; - if (!flasherased(sinfo->begin,sinfo->end)) { - if ((!FlashProtectWindow) && (sinfo->protected)) { - printf("Sector %d protected\n",snum); - return(0); - } - - if (flashlocked(snum,1)) - return(0); - - rc = fdev->flerase(fdev,dev_snum); - if (rc < 0) - return(rc); - } - return(1); + uchar *tmp; + ulong *base, *end; + int size, rc, dev_snum; + struct flashinfo *fdev; + struct sectorinfo *sinfo; + + if(FlashTrace) { + printf("flasherase(%d)\n",snum); + } + + if(!(fdev = snumtofdev(snum))) { + return(-1); + } + + /* If the device type is RAM, the erase is a bit different... + */ + if(fdev->id == FLASHRAM) { + // Use 'tmp' here to eliminate a 3.4 toolset warning. + sectortoaddr(snum,&size,&tmp); + base = (ulong *)tmp; + end = base + (size/sizeof(long)); + while(base < end) { + *base = 0xffffffff; + if(*base != 0xffffffff) { + return(-1); + } + base++; + } + return(1); + } + + /* If the sector is soft-protected or locked, return negative + * and print failure. If the sector is already erased, then + * there is no need to issue the device-specific erase algorithm. + */ + dev_snum = snum - fdev->sectors[0].snum; + sinfo = &fdev->sectors[dev_snum]; + if(!flasherased(sinfo->begin,sinfo->end)) { + if((!FlashProtectWindow) && (sinfo->protected)) { + printf("Sector %d protected\n",snum); + return(0); + } + + if(flashlocked(snum,1)) { + return(0); + } + + rc = fdev->flerase(fdev,dev_snum); + if(rc < 0) { + return(rc); + } + } + return(1); } /* flashwrite(): - * Use the device-specific function pointer to call the routine - * relocated to RAM space. - * First make a few checks on the request, then write to flash if all - * checks succeed. + * Use the device-specific function pointer to call the routine + * relocated to RAM space. + * First make a few checks on the request, then write to flash if all + * checks succeed. */ int flashwrite(struct flashinfo *fdev,uchar *dest,uchar *src,long bytecnt) { - int j, lowsector, highsector, rc, first_sector_of_device; - register uchar *dp, *sp, *edp; - - if (FlashTrace) - printf("flashwrite(0x%lx,0x%lx,%ld)\n",(long)dest,(long)src,bytecnt); - - if (fdev->id == FLASHRAM) { - uchar *sp, *dp, *end; - sp = src; - dp = dest; - end = dp+bytecnt; - while(dp < end) { - *dp = *sp; - if (*dp != *sp) - return(-1); - dp++; sp++; - } - return(0); - } - - dp = dest; - sp = src; - edp = (dest + bytecnt) - 1; - first_sector_of_device = fdev->sectors[0].snum; - - /* If outside the devices space, return failed.. */ - if ((edp < fdev->sectors[0].begin) || - (dp > fdev->sectors[fdev->sectorcnt-1].end)) { - printf("flashwrite() failed: dest out of flash range\n"); - return(-1); - } - - /* Make sure the destination is not within a protected sector */ - if (FlashProtectWindow == FLASH_PROTECT_WINDOW_CLOSED) { - - /* First determine the sectors that overlap with the - * flash space to be written... - */ - - lowsector = highsector = -1; - for(j=0;j<fdev->sectorcnt;j++) { - if ((dp >= fdev->sectors[j].begin) && - (dp <= fdev->sectors[j].end)) - lowsector = j; - } - for(j=0;j<fdev->sectorcnt;j++) { - if ((edp >= fdev->sectors[j].begin) && - (edp <= fdev->sectors[j].end)) - highsector = j; - } - if ((lowsector == -1) || (highsector == -1)) { - printf("flashwrite() failed: can't find sector\n"); - return(-1); - } - - /* Now that the range of affected sectors is known, - * verify that those sectors are not protected or locked... - */ - for(j=lowsector;j<=highsector;j++) { - if (fdev->sectors[j].protected) { - printf("flashwrite() failed: sector protected\n"); - return(-1); - } - if (flashlocked(j+first_sector_of_device,1)) - return(-1); - } - } - - /* Now make sure that there is no attempt to transition a bit - * in the affected range from 0 to 1... A flash write can only - * bring bits low (erase brings them high). - */ - while(dp < edp) { - if ((*dp & *sp) != *sp) { - printf("flashwrite(0x%lx) failed: bit 0->1 rqst denied.\n", - (long)dp); - return(-1); - } - dp++; - sp++; - WATCHDOG_MACRO; - } - rc = fdev->flwrite(fdev,dest,src,bytecnt); - if (rc < 0) - return(rc); - - /* Assuming everything else appears to have passed, make sure the - * source and destination addresses match... - */ - if (memcmp((char *)dest,(char *)src,(int)bytecnt) != 0) { - printf("flashwrite() post-verify failed.\n"); - return(-1); - } - return(0); + int j, lowsector, highsector, rc, first_sector_of_device; + register uchar *dp, *sp, *edp; + + if(FlashTrace) { + printf("flashwrite(0x%lx,0x%lx,%ld)\n",(long)dest,(long)src,bytecnt); + } + + if(fdev->id == FLASHRAM) { + uchar *sp, *dp, *end; + sp = src; + dp = dest; + end = dp+bytecnt; + while(dp < end) { + *dp = *sp; + if(*dp != *sp) { + return(-1); + } + dp++; + sp++; + } + return(0); + } + + dp = dest; + sp = src; + edp = (dest + bytecnt) - 1; + first_sector_of_device = fdev->sectors[0].snum; + + /* If outside the devices space, return failed.. */ + if((edp < fdev->sectors[0].begin) || + (dp > fdev->sectors[fdev->sectorcnt-1].end)) { + printf("flashwrite() failed: dest out of flash range\n"); + return(-1); + } + + /* Make sure the destination is not within a protected sector */ + if(FlashProtectWindow == FLASH_PROTECT_WINDOW_CLOSED) { + + /* First determine the sectors that overlap with the + * flash space to be written... + */ + + lowsector = highsector = -1; + for(j=0; j<fdev->sectorcnt; j++) { + if((dp >= fdev->sectors[j].begin) && + (dp <= fdev->sectors[j].end)) { + lowsector = j; + } + } + for(j=0; j<fdev->sectorcnt; j++) { + if((edp >= fdev->sectors[j].begin) && + (edp <= fdev->sectors[j].end)) { + highsector = j; + } + } + if((lowsector == -1) || (highsector == -1)) { + printf("flashwrite() failed: can't find sector\n"); + return(-1); + } + + /* Now that the range of affected sectors is known, + * verify that those sectors are not protected or locked... + */ + for(j=lowsector; j<=highsector; j++) { + if(fdev->sectors[j].protected) { + printf("flashwrite() failed: sector protected\n"); + return(-1); + } + if(flashlocked(j+first_sector_of_device,1)) { + return(-1); + } + } + } + + /* Now make sure that there is no attempt to transition a bit + * in the affected range from 0 to 1... A flash write can only + * bring bits low (erase brings them high). + */ + while(dp < edp) { + if((*dp & *sp) != *sp) { + printf("flashwrite(0x%lx) failed: bit 0->1 rqst denied.\n", + (long)dp); + return(-1); + } + dp++; + sp++; + WATCHDOG_MACRO; + } + rc = fdev->flwrite(fdev,dest,src,bytecnt); + if(rc < 0) { + return(rc); + } + + /* Assuming everything else appears to have passed, make sure the + * source and destination addresses match... + */ + if(memcmp((char *)dest,(char *)src,(int)bytecnt) != 0) { + printf("flashwrite() post-verify failed.\n"); + return(-1); + } + return(0); } /* flashewrite(): - * Use the device-specific function pointer to call the routine - * relocated to RAM space. + * Use the device-specific function pointer to call the routine + * relocated to RAM space. */ int flashewrite(uchar *dest,uchar *src,long bytecnt) { - int i; - struct flashinfo *fdev; - - if (FlashTrace) - printf("flashwrite(0x%lx,0x%lx,%ld)\n",(long)dest,(long)src,bytecnt); - - if ((fdev = addrtobank(dest)) == 0) - return(-1); - - /* Source and destination addresses must be long-aligned. */ - if (((int)src & 3) || ((int)dest & 3)) - return(-1); - - /* If the protection window is closed, then verify that no protected - * sectors will be written over... - */ - if (FlashProtectWindow == FLASH_PROTECT_WINDOW_CLOSED) { - for (i=0;i<fdev->sectorcnt;i++) { - if((((uchar *)dest) > (fdev->sectors[i].end)) || - (((uchar *)dest+bytecnt) < (fdev->sectors[i].begin))) - continue; - else - if (fdev->sectors[i].protected) - return(-1); - } - } - return(fdev->flewrite(fdev,dest,src,bytecnt)); + int i; + struct flashinfo *fdev; + + if(FlashTrace) { + printf("flashwrite(0x%lx,0x%lx,%ld)\n",(long)dest,(long)src,bytecnt); + } + + if((fdev = addrtobank(dest)) == 0) { + return(-1); + } + + /* Source and destination addresses must be long-aligned. */ + if(((int)src & 3) || ((int)dest & 3)) { + return(-1); + } + + /* If the protection window is closed, then verify that no protected + * sectors will be written over... + */ + if(FlashProtectWindow == FLASH_PROTECT_WINDOW_CLOSED) { + for(i=0; i<fdev->sectorcnt; i++) { + if((((uchar *)dest) > (fdev->sectors[i].end)) || + (((uchar *)dest+bytecnt) < (fdev->sectors[i].begin))) { + continue; + } else if(fdev->sectors[i].protected) { + return(-1); + } + } + } + return(fdev->flewrite(fdev,dest,src,bytecnt)); } /* flashlock(): @@ -508,27 +528,29 @@ flashewrite(uchar *dest,uchar *src,long bytecnt) int flashlock(int snum,int operation) { - int dev_snum; - struct flashinfo *fdev; + int dev_snum; + struct flashinfo *fdev; - if (FlashTrace) - printf("flashlock(%d,%s)\n",snum,showlockop(operation)); + if(FlashTrace) { + printf("flashlock(%d,%s)\n",snum,showlockop(operation)); + } - fdev = snumtofdev(snum); - dev_snum = snum - fdev->sectors[0].snum; - return(fdev->fllock(fdev,dev_snum,operation)); + fdev = snumtofdev(snum); + dev_snum = snum - fdev->sectors[0].snum; + return(fdev->fllock(fdev,dev_snum,operation)); } int flashlocked(int snum, int verbose) { - if ((flashlock(snum,FLASH_LOCKABLE) > 0) && - (flashlock(snum,FLASH_LOCKQRY) == 1)) { - if (verbose) - printf("Sector %d locked\n",snum); - return(1); - } - return(0); + if((flashlock(snum,FLASH_LOCKABLE) > 0) && + (flashlock(snum,FLASH_LOCKQRY) == 1)) { + if(verbose) { + printf("Sector %d locked\n",snum); + } + return(1); + } + return(0); } /* snumtofdev(): @@ -538,94 +560,100 @@ flashlocked(int snum, int verbose) struct flashinfo * snumtofdev(int snum) { - int dev; - struct flashinfo *fbnk; - - fbnk = FlashBank; - for(dev=0;dev<FLASHBANKS;dev++,fbnk++) { - if ((snum >= fbnk->sectors[0].snum) && - (snum <= fbnk->sectors[fbnk->sectorcnt-1].snum)) - return(fbnk); - } - printf("snumtofdev(%d) failed\n",snum); - return(0); + int dev; + struct flashinfo *fbnk; + + fbnk = FlashBank; + for(dev=0; dev<FLASHBANKS; dev++,fbnk++) { + if((snum >= fbnk->sectors[0].snum) && + (snum <= fbnk->sectors[fbnk->sectorcnt-1].snum)) { + return(fbnk); + } + } + printf("snumtofdev(%d) failed\n",snum); + return(0); } /* addrtosector(): - * Incoming address is translated to sector number, size of sector - * and base of sector. - * Return 0 if successful; else -1. + * Incoming address is translated to sector number, size of sector + * and base of sector. + * Return 0 if successful; else -1. */ int addrtosector(uchar *addr,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++) { - sinfo = &fbnk->sectors[i]; - if ((addr >= sinfo->begin) && (addr <= sinfo->end)) { - if (sector) { - *sector = sec; - } - if (base) { - *base = sinfo->begin; - } - if (size) { - *size = sinfo->size; - } - return(0); - } - } - } - printf("addrtosector(0x%lx) failed\n",(ulong)addr); - return(-1); + 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++) { + sinfo = &fbnk->sectors[i]; + if((addr >= sinfo->begin) && (addr <= sinfo->end)) { + if(sector) { + *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. + * 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); + 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); + 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(): @@ -635,330 +663,349 @@ sectortoaddr(int sector,int *size,uchar **base) 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); + 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. + * 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); + 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. - * * from_addr defines the search start address: - * * from_addr = 0 means start from the first sector; - * * from_addr MUST be sector aligned. - * * sectorcnt defines the numbers of contiguous sectors to search across; - * * sectorcnt = 0 means search to the last sector. - * Return 0 if successful; else -1. + * 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. + * * from_addr defines the search start address: + * * from_addr = 0 means start from the first sector; + * * from_addr MUST be sector aligned. + * * sectorcnt defines the numbers of contiguous sectors to search across; + * * sectorcnt = 0 means search to the last sector. + * Return 0 if successful; else -1. */ int lastlargesector(int bank, uchar *from_addr, - int sectorcnt, int *sector, int *size, uchar **base) + int sectorcnt, int *sector, int *size, uchar **base) { - struct flashinfo *fbnk; - struct sectorinfo *sinfo; - uchar *largest_sbase; - int i, from_sector, to_sector, largest_ssize, largest_snum; - - if (bank >= FLASHBANKS) { - printf("lastlargesector(%d) failed\n",bank); - return(-1); - } - - fbnk = &FlashBank[bank]; - largest_ssize = 0; - largest_snum = 0; - largest_sbase = (uchar *)0; - - if (from_addr) { - if (addrtosector(from_addr, &from_sector, 0, 0) == -1) - return(-1); - if (fbnk->sectors[from_sector].begin != from_addr) { - printf("lastlargesector failed:\n" - " parameter from_addr (%0x08X) must be sector aligned\n", - from_addr); - return(-1); - } - } - else { - from_sector = 0; - } - - to_sector = from_sector + sectorcnt - 1; - if (to_sector > fbnk->sectorcnt - 1) { - to_sector = fbnk->sectorcnt - 1; - } - - //printf("from_addr = 0x%08X\n", from_addr); - //printf("from_sector = %d\n", from_sector); - //printf("to_sector = %d\n", to_sector); - - sinfo = &fbnk->sectors[from_sector]; - for(i=from_sector; i<=to_sector; i++, sinfo++) { - if (sinfo->size >= largest_ssize) { - largest_ssize = sinfo->size; - largest_snum = sinfo->snum; - largest_sbase = sinfo->begin; - } - } - - //printf("largest_sbase = 0x%08X\n", largest_sbase); - //printf("largest_snum = %d\n", largest_snum); - //printf("largest_ssize = 0x%08X\n", largest_ssize); - - if (sector) - *sector = largest_snum; - if (size) - *size = largest_ssize; - if (base) - *base = largest_sbase; - return(0); + struct flashinfo *fbnk; + struct sectorinfo *sinfo; + uchar *largest_sbase; + int i, from_sector, to_sector, largest_ssize, largest_snum; + + if(bank >= FLASHBANKS) { + printf("lastlargesector(%d) failed\n",bank); + return(-1); + } + + fbnk = &FlashBank[bank]; + largest_ssize = 0; + largest_snum = 0; + largest_sbase = (uchar *)0; + + if(from_addr) { + if(addrtosector(from_addr, &from_sector, 0, 0) == -1) { + return(-1); + } + if(fbnk->sectors[from_sector].begin != from_addr) { + printf("lastlargesector failed:\n" + " parameter from_addr (%0x08X) must be sector aligned\n", + from_addr); + return(-1); + } + } else { + from_sector = 0; + } + + to_sector = from_sector + sectorcnt - 1; + if(to_sector > fbnk->sectorcnt - 1) { + to_sector = fbnk->sectorcnt - 1; + } + + //printf("from_addr = 0x%08X\n", from_addr); + //printf("from_sector = %d\n", from_sector); + //printf("to_sector = %d\n", to_sector); + + sinfo = &fbnk->sectors[from_sector]; + for(i=from_sector; i<=to_sector; i++, sinfo++) { + if(sinfo->size >= largest_ssize) { + largest_ssize = sinfo->size; + largest_snum = sinfo->snum; + largest_sbase = sinfo->begin; + } + } + + //printf("largest_sbase = 0x%08X\n", largest_sbase); + //printf("largest_snum = %d\n", largest_snum); + //printf("largest_ssize = 0x%08X\n", largest_ssize); + + if(sector) { + *sector = largest_snum; + } + if(size) { + *size = largest_ssize; + } + if(base) { + *base = largest_sbase; + } + return(0); } void LowerFlashProtectWindow() { - if (FlashProtectWindow) - FlashProtectWindow--; + 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. + * 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; - FLASH_INTSDECL; - long tmpcnt; - struct flashinfo *fbnk; - - ret = 0; - while(bytecnt > 0) { - fbnk = addrtobank((uchar *)dest); - if (!fbnk) - return(-1); - - if ((dest + bytecnt) <= fbnk->end) - tmpcnt = bytecnt; - else - tmpcnt = (fbnk->end - dest) + 1; - - FLASH_INTSOFF(); - ret = flashwrite(fbnk,dest,src,tmpcnt); - FLASH_INTSRESTORE(); - 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 ret; + FLASH_INTSDECL; + long tmpcnt; + struct flashinfo *fbnk; + + ret = 0; + while(bytecnt > 0) { + fbnk = addrtobank((uchar *)dest); + if(!fbnk) { + return(-1); + } + + if((dest + bytecnt) <= fbnk->end) { + tmpcnt = bytecnt; + } else { + tmpcnt = (fbnk->end - dest) + 1; + } + + FLASH_INTSOFF(); + ret = flashwrite(fbnk,dest,src,tmpcnt); + FLASH_INTSRESTORE(); + 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); } #if INCLUDE_FLASHREAD /* flashread(): - * Use the device-specific function pointer to call the routine - * relocated to RAM space. - * First make a few checks on the request, then read from flash + * Use the device-specific function pointer to call the routine + * relocated to RAM space. + * First make a few checks on the request, then read from flash * if the checks succeed. */ int flashread(struct flashinfo *fdev,uchar *dest,uchar *src,long bytecnt) { - int rc, first_sector_of_device; - register uchar *dp, *sp, *edp; - - if (FlashTrace) - printf("flashread(0x%lx,0x%lx,%ld)\n",(long)dest,(long)src,bytecnt); - - if (fdev->id == FLASHRAM) { - uchar *sp, *dp, *end; - sp = src; - dp = dest; - end = dp+bytecnt; - while(dp < end) { - *dp = *sp; - if (*dp != *sp) - return(-1); - dp++; sp++; - } - return(0); - } - - dp = dest; - sp = src; - edp = (dest + bytecnt) - 1; - first_sector_of_device = fdev->sectors[0].snum; - - /* If outside the devices space, return failed.. */ - if ((edp < fdev->sectors[0].begin) || - (dp > fdev->sectors[fdev->sectorcnt-1].end)) { - printf("flashread() failed: dest out of flash range\n"); - return(-1); - } - - rc = fdev->flread(fdev,dest,src,bytecnt); - if (rc < 0) - return(rc); - - /* Assuming everything else appears to have passed, make sure the - * source and destination addresses match... - */ - if (memcmp((char *)dest,(char *)src,(int)bytecnt) != 0) { - printf("flashread() post-verify failed.\n"); - return(-1); - } - return(0); + int rc, first_sector_of_device; + register uchar *dp, *sp, *edp; + + if(FlashTrace) { + printf("flashread(0x%lx,0x%lx,%ld)\n",(long)dest,(long)src,bytecnt); + } + + if(fdev->id == FLASHRAM) { + uchar *sp, *dp, *end; + sp = src; + dp = dest; + end = dp+bytecnt; + while(dp < end) { + *dp = *sp; + if(*dp != *sp) { + return(-1); + } + dp++; + sp++; + } + return(0); + } + + dp = dest; + sp = src; + edp = (dest + bytecnt) - 1; + first_sector_of_device = fdev->sectors[0].snum; + + /* If outside the devices space, return failed.. */ + if((edp < fdev->sectors[0].begin) || + (dp > fdev->sectors[fdev->sectorcnt-1].end)) { + printf("flashread() failed: dest out of flash range\n"); + return(-1); + } + + rc = fdev->flread(fdev,dest,src,bytecnt); + if(rc < 0) { + return(rc); + } + + /* Assuming everything else appears to have passed, make sure the + * source and destination addresses match... + */ + if(memcmp((char *)dest,(char *)src,(int)bytecnt) != 0) { + printf("flashread() post-verify failed.\n"); + return(-1); + } + return(0); } /* 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. + * 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; - FLASH_INTSDECL; - long tmpcnt; - struct flashinfo *fbnk; - - ret = 0; - while(bytecnt > 0) { - fbnk = addrtobank((uchar *)dest); - if (!fbnk) - return(-1); - - if ((dest + bytecnt) <= fbnk->end) - tmpcnt = bytecnt; - else - tmpcnt = (fbnk->end - dest) + 1; - - FLASH_INTSOFF(); - ret = flashread(fbnk,dest,src,tmpcnt); - FLASH_INTSRESTORE(); - if (ret < 0) { - printf("AppFlashRead(0x%lx,0x%lx,%ld) failed (%d)\n", - (ulong)dest,(ulong)src,bytecnt,ret); - break; - } - src += tmpcnt; - dest += tmpcnt; - bytecnt -= tmpcnt; - } - return(ret); + int ret; + FLASH_INTSDECL; + long tmpcnt; + struct flashinfo *fbnk; + + ret = 0; + while(bytecnt > 0) { + fbnk = addrtobank((uchar *)dest); + if(!fbnk) { + return(-1); + } + + if((dest + bytecnt) <= fbnk->end) { + tmpcnt = bytecnt; + } else { + tmpcnt = (fbnk->end - dest) + 1; + } + + FLASH_INTSOFF(); + ret = flashread(fbnk,dest,src,tmpcnt); + FLASH_INTSRESTORE(); + if(ret < 0) { + printf("AppFlashRead(0x%lx,0x%lx,%ld) failed (%d)\n", + (ulong)dest,(ulong)src,bytecnt,ret); + break; + } + src += tmpcnt; + dest += tmpcnt; + bytecnt -= tmpcnt; + } + return(ret); } #endif int lastflashsector(void) { - int lastsnum; - struct flashinfo *lastfbnk; + int lastsnum; + struct flashinfo *lastfbnk; - lastfbnk = &FlashBank[FLASHBANKS-1]; - lastsnum = lastfbnk->sectors[lastfbnk->sectorcnt-1].snum; - return(lastsnum); + lastfbnk = &FlashBank[FLASHBANKS-1]; + lastsnum = lastfbnk->sectors[lastfbnk->sectorcnt-1].snum; + return(lastsnum); } int AppFlashEraseAll() { - FLASH_INTSDECL; - int ret, snum, lastsnum; - - ret = 0; - 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(); - return(ret); + FLASH_INTSDECL; + int ret, snum, lastsnum; + + ret = 0; + 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(); + return(ret); } /* Erase the flash sector specified. */ int -AppFlashErase(int snum) /* erase specified sector */ +AppFlashErase(int snum) /* erase specified sector */ { - int ret; - FLASH_INTSDECL; + int ret; + FLASH_INTSDECL; - FLASH_INTSOFF(); - ret = flasherase(snum); - FLASH_INTSRESTORE(); - return(ret); + FLASH_INTSOFF(); + ret = flasherase(snum); + FLASH_INTSRESTORE(); + return(ret); } /* sectorProtect(): - * Set or clear (based on value of protect) the protected flag for the - * specified range of sectors... + * 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); + 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 @@ -971,310 +1018,304 @@ struct sectorinfo sinfoRAM[FLASHRAM_SECTORCOUNT]; * 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. + * 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) + 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. */ + 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); + 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]", + "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>", + "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, + 0, }; /* FlashCmd(): - * Code that handles the user interface. See FlashHelp[] below for usage. + * Code that handles the user interface. See FlashHelp[] below for usage. */ int FlashCmd(int argc,char *argv[]) { - int ret; - FLASH_INTSDECL; - ulong dest, src; - long bytecnt, rslt; - struct flashinfo *fbnk; - - FLASH_INTSOFF(); - - fbnk = &FlashBank[FlashCurrentBank]; - ret = CMD_SUCCESS; - - if (strcmp(argv[1],"init") == 0) - FlashInit(); - else if (strcmp(argv[1],"info") == 0) { - showflashinfo(argv[2]); - } - else if (strcmp(argv[1],"type") == 0) { - showflashtype((ulong)flashtype(fbnk),1); - } - else if (strcmp(argv[1],"trace") == 0) { - if (argc == 3) - FlashTrace = atoi(argv[2]); - else if (argc == 2) - printf("Flash trace lvl: %d\n",FlashTrace); - else - return(CMD_PARAM_ERROR); - } - else if (strcmp(argv[1],"bank") == 0) { - int tmpbank; - if (argc == 3) { - tmpbank = atoi(argv[2]); - 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[1],"ewrite") == 0) { - if (argc == 5) { - dest = strtoul(argv[2],(char **)0,0); - src = strtoul(argv[3],(char **)0,0); - bytecnt = (long)strtoul(argv[4],(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[1],"write")) { - if (argc == 5) { - dest = strtoul(argv[2],(char **)0,0); - src = strtoul(argv[3],(char **)0,0); - bytecnt = (long)strtoul(argv[4],(char **)0,0); - rslt = AppFlashWrite((uchar *)dest,(uchar *)src,bytecnt); - if (rslt < 0) { - printf("Write failed (%ld)\n",rslt); - ret = CMD_FAILURE; - } - } - else - ret = CMD_PARAM_ERROR; - } + int ret; + FLASH_INTSDECL; + ulong dest, src; + long bytecnt, rslt; + struct flashinfo *fbnk; + + FLASH_INTSOFF(); + + fbnk = &FlashBank[FlashCurrentBank]; + ret = CMD_SUCCESS; + + if(strcmp(argv[1],"init") == 0) { + FlashInit(); + } else if(strcmp(argv[1],"info") == 0) { + showflashinfo(argv[2]); + } else if(strcmp(argv[1],"type") == 0) { + showflashtype((ulong)flashtype(fbnk),1); + } else if(strcmp(argv[1],"trace") == 0) { + if(argc == 3) { + FlashTrace = atoi(argv[2]); + } else if(argc == 2) { + printf("Flash trace lvl: %d\n",FlashTrace); + } else { + return(CMD_PARAM_ERROR); + } + } else if(strcmp(argv[1],"bank") == 0) { + int tmpbank; + if(argc == 3) { + tmpbank = atoi(argv[2]); + 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[1],"ewrite") == 0) { + if(argc == 5) { + dest = strtoul(argv[2],(char **)0,0); + src = strtoul(argv[3],(char **)0,0); + bytecnt = (long)strtoul(argv[4],(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[1],"write")) { + if(argc == 5) { + dest = strtoul(argv[2],(char **)0,0); + src = strtoul(argv[3],(char **)0,0); + bytecnt = (long)strtoul(argv[4],(char **)0,0); + rslt = AppFlashWrite((uchar *)dest,(uchar *)src,bytecnt); + if(rslt < 0) { + printf("Write failed (%ld)\n",rslt); + ret = CMD_FAILURE; + } + } else { + ret = CMD_PARAM_ERROR; + } + } #if INCLUDE_FLASHREAD - else if (!strcmp(argv[1],"read")) { - if (argc == 5) { - dest = strtoul(argv[2],(char **)0,0); - src = strtoul(argv[3],(char **)0,0); - bytecnt = (long)strtoul(argv[4],(char **)0,0); - 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[1],"read")) { + if(argc == 5) { + dest = strtoul(argv[2],(char **)0,0); + src = strtoul(argv[3],(char **)0,0); + bytecnt = (long)strtoul(argv[4],(char **)0,0); + rslt = AppFlashRead((uchar *)dest,(uchar *)src,bytecnt); + if(rslt < 0) { + printf("Read failed (%ld)\n",rslt); + ret = CMD_FAILURE; + } + } else { + ret = CMD_PARAM_ERROR; + } + } #endif - else if (!strcmp(argv[1],"opw")) { - if (getUsrLvl() != MAXUSRLEVEL) - printf("Must be user level %d\n",MAXUSRLEVEL); - else - FlashProtectWindow = 2; - } - else if (!strcmp(argv[1],"unprot")) { - if (argc != 3) - ret = CMD_PARAM_ERROR; - else - sectorProtect(argv[2],0); - } - else if (!strcmp(argv[1],"prot")) { - if (argc != 3) - ret = CMD_PARAM_ERROR; - else - sectorProtect(argv[2],1); - } - else if (!strcmp(argv[1],"erase")) { - if (argc != 3) { - ret = CMD_PARAM_ERROR; - } - else { - uchar *base; - int rc, snum, size, stot = 0; - - if (strncmp(argv[2],"0x",2) == 0) { - ulong begin, end; - char *dash = strchr(argv[2],'-'); - - begin = end = strtoul(argv[2],0,0); - if (dash) - end = strtoul(dash+1,0,0); - - while(begin <= end) { - if (addrtosector((uchar *)begin,&snum,&size,&base) < 0) - break; - begin = (ulong)base; - rc = flasherase(snum); - if (rc != 1) { - printf("Erase failed (%d)\n",rc); - ret = CMD_FAILURE; - break; - } - stot++; - begin += size; - } - } - else { - int last; - - last = lastflashsector(); - for(snum=0;snum<=last;snum++) { - int rc; - - if ((argv[2] == 0) || inRange(argv[2],snum)) { - ticktock(); - rc = flasherase(snum); - if (rc != 1) { - printf("Erase failed (%d)\n",rc); - ret = CMD_FAILURE; - break; - } - stot++; - } - } - } - printf("%d sectors erased\n",stot); - } - } - else if ((!strcmp(argv[1],"lock")) || (!strcmp(argv[1],"unlock")) || - (!strcmp(argv[1],"lockdwn"))) { - int operation, snum; - - if (!strcmp(argv[1],"lock")) - operation = FLASH_LOCK; - else if (!strcmp(argv[1],"unlock")) - operation = FLASH_UNLOCK; - else - operation = FLASH_LOCKDWN; - - if (argc == 2) { + else if(!strcmp(argv[1],"opw")) { + if(getUsrLvl() != MAXUSRLEVEL) { + printf("Must be user level %d\n",MAXUSRLEVEL); + } else { + FlashProtectWindow = 2; + } + } else if(!strcmp(argv[1],"unprot")) { + if(argc != 3) { + ret = CMD_PARAM_ERROR; + } else { + sectorProtect(argv[2],0); + } + } else if(!strcmp(argv[1],"prot")) { + if(argc != 3) { + ret = CMD_PARAM_ERROR; + } else { + sectorProtect(argv[2],1); + } + } else if(!strcmp(argv[1],"erase")) { + if(argc != 3) { + ret = CMD_PARAM_ERROR; + } else { + uchar *base; + int rc, snum, size, stot = 0; + + if(strncmp(argv[2],"0x",2) == 0) { + ulong begin, end; + char *dash = strchr(argv[2],'-'); + + begin = end = strtoul(argv[2],0,0); + if(dash) { + end = strtoul(dash+1,0,0); + } + + while(begin <= end) { + if(addrtosector((uchar *)begin,&snum,&size,&base) < 0) { + break; + } + begin = (ulong)base; + rc = flasherase(snum); + if(rc != 1) { + printf("Erase failed (%d)\n",rc); + ret = CMD_FAILURE; + break; + } + stot++; + begin += size; + } + } else { + int last; + + last = lastflashsector(); + for(snum=0; snum<=last; snum++) { + int rc; + + if((argv[2] == 0) || inRange(argv[2],snum)) { + ticktock(); + rc = flasherase(snum); + if(rc != 1) { + printf("Erase failed (%d)\n",rc); + ret = CMD_FAILURE; + break; + } + stot++; + } + } + } + printf("%d sectors erased\n",stot); + } + } else if((!strcmp(argv[1],"lock")) || (!strcmp(argv[1],"unlock")) || + (!strcmp(argv[1],"lockdwn"))) { + int operation, snum; + + if(!strcmp(argv[1],"lock")) { + operation = FLASH_LOCK; + } else if(!strcmp(argv[1],"unlock")) { + operation = FLASH_UNLOCK; + } else { + operation = FLASH_LOCKDWN; + } + + if(argc == 2) { #ifdef FLASH_PROTECT_RANGE - argv[2] = FLASH_PROTECT_RANGE; - argc = 3; - printf("Applying %s to sector(s) %s...\n",argv[1],argv[2]); + argv[2] = FLASH_PROTECT_RANGE; + argc = 3; + printf("Applying %s to sector(s) %s...\n",argv[1],argv[2]); #else - printf("Monitor not built with specified protection range\n"); - ret = CMD_FAILURE; + printf("Monitor not built with specified protection range\n"); + ret = CMD_FAILURE; #endif - } - - if (argc != 3) { - ret = CMD_PARAM_ERROR; - } - else { - int last; - struct flashinfo *fdev; - - last = lastflashsector(); - for(snum=0;snum<=last;snum++) { - if (inRange(argv[2],snum)) { - ticktock(); - if ((fdev = snumtofdev(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[1]); - ret = CMD_FAILURE; - break; - } - rslt = flashlock(snum,operation); - if (rslt < 0) { - printf("%s failed (%ld) at sector %d\n", - argv[1],rslt,snum); - ret = CMD_FAILURE; - break; - } - } - } - } - } - else { - ret = CMD_PARAM_ERROR; - } - - FLASH_INTSRESTORE(); - return(ret); + } + + if(argc != 3) { + ret = CMD_PARAM_ERROR; + } else { + int last; + struct flashinfo *fdev; + + last = lastflashsector(); + for(snum=0; snum<=last; snum++) { + if(inRange(argv[2],snum)) { + ticktock(); + if((fdev = snumtofdev(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[1]); + ret = CMD_FAILURE; + break; + } + rslt = flashlock(snum,operation); + if(rslt < 0) { + printf("%s failed (%ld) at sector %d\n", + argv[1],rslt,snum); + ret = CMD_FAILURE; + break; + } + } + } + } + } else { + ret = CMD_PARAM_ERROR; + } + + FLASH_INTSRESTORE(); + return(ret); } /* FlashOpOverride(): @@ -1287,33 +1328,34 @@ FlashCmd(int argc,char *argv[]) int FlashOpOverride(void *finfo, int get, int bank) { - char *src, *dst; - struct flashinfo *fdev; - - if ((!finfo) || (bank >= FLASHBANKS)) - return(-1); - - fdev = &FlashBank[bank]; - - if (get) { - src = (char *)fdev; - dst = (char *)finfo; - } - else { - src = (char *)finfo; - dst = (char *)fdev; - } - memcpy(dst,src,sizeof(struct flashinfo)); - return(0); + char *src, *dst; + struct flashinfo *fdev; + + if((!finfo) || (bank >= FLASHBANKS)) { + return(-1); + } + + fdev = &FlashBank[bank]; + + if(get) { + src = (char *)fdev; + dst = (char *)finfo; + } else { + src = (char *)finfo; + dst = (char *)fdev; + } + memcpy(dst,src,sizeof(struct flashinfo)); + return(0); } int FlashOpNotSupported(void) { - if (FlashTrace) - printf("flash operation not supported\n"); + if(FlashTrace) { + printf("flash operation not supported\n"); + } - return(-1); + return(-1); } /* Used as a placeholder for the flash drivers that don't @@ -1322,10 +1364,11 @@ FlashOpNotSupported(void) int FlashLockNotSupported(struct flashinfo *fdev,int snum,int operation) { - if (operation == FLASH_LOCKABLE) - return(0); - else - return(-1); + if(operation == FLASH_LOCKABLE) { + return(0); + } else { + return(-1); + } } #endif @@ -1344,56 +1387,61 @@ FlashLockNotSupported(struct flashinfo *fdev,int snum,int operation) int flasherased(unsigned char *begin, unsigned char *end) { - unsigned long *lp, *lp1, ltmp; - - /* If begin is greater than end, the range is illegal. The only - * exception to this is the case where end may be zero. This is - * considered an exception because in cases where we are dealing - * with the last sector of a device that sits at the end of memory - * space, the end point will wrap. - */ - if ((begin > end) && (end != 0)) { - printf("flasherased(): bad range\n"); - return(0); - } - - /* Get pointers aligned so that we can do the bulk of the comparison - * with long pointers... - */ - while(((long)begin & 3) && (begin <= end)) { - if (*begin != 0xff) - return(0); - begin++; - } - if (begin > end) - return(1); - - lp = (unsigned long *)begin; - ltmp = (unsigned long)end; - ltmp &= ~3; - lp1 = (unsigned long *)ltmp; - - while(lp != lp1) { - if (*lp != 0xffffffff) - return(0); - lp++; + unsigned long *lp, *lp1, ltmp; + + /* If begin is greater than end, the range is illegal. The only + * exception to this is the case where end may be zero. This is + * considered an exception because in cases where we are dealing + * with the last sector of a device that sits at the end of memory + * space, the end point will wrap. + */ + if((begin > end) && (end != 0)) { + printf("flasherased(): bad range\n"); + return(0); + } + + /* Get pointers aligned so that we can do the bulk of the comparison + * with long pointers... + */ + while(((long)begin & 3) && (begin <= end)) { + if(*begin != 0xff) { + return(0); + } + begin++; + } + if(begin > end) { + return(1); + } + + lp = (unsigned long *)begin; + ltmp = (unsigned long)end; + ltmp &= ~3; + lp1 = (unsigned long *)ltmp; + + while(lp != lp1) { + if(*lp != 0xffffffff) { + return(0); + } + lp++; #ifdef WATCHDOG_ENABLED - /* For each 64K through this loop, tickle the watchdog. - */ - if ((0xffff & (unsigned long)lp) == 0) { - WATCHDOG_MACRO; - } + /* For each 64K through this loop, tickle the watchdog. + */ + if((0xffff & (unsigned long)lp) == 0) { + WATCHDOG_MACRO; + } #endif - } - if (lp > (unsigned long *)end) - return(1); - - begin = (unsigned char *)lp; - do { - if (*begin != 0xff) - return(0); - } while(begin++ != end); - return(*end == 0xff); + } + if(lp > (unsigned long *)end) { + return(1); + } + + begin = (unsigned char *)lp; + do { + if(*begin != 0xff) { + return(0); + } + } while(begin++ != end); + return(*end == 0xff); } |