⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
					*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 + -