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

📄 flash.c

📁 pxa270 的bootloader源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <hardware.h>#include <stdio.h>#include <string.h>#include <time.h>#include <setup.h>#include <command.h>#include <io.h>#define READ_ARRAY				(0x00FF00FF)#define READ_IDCODE				(0x00900090)#define READ_QUERY				(0x00980098)#define	STATUS_READ				(0x00700070)#define	STATUS_CLEAR			(0x00500050)#define WRITE_BUF				(0x00E800E8)#define WRITE_BUF_COMFIRM		(0x00D000D0)#define	PGM_SETUP				(0x00400040)#define ERASE_SETUP				(0x00200020)#define ERASE_CONFIRM			(0x00D000D0)#define ERASE_PROGRAM_SUSPEND	(0x00B000B0)#define ERASE_PROGRAM_RESUME	(0x00D000D0)#define FLASH_CFG				(0x00B800B8)#define FLASH_SETUP				(0x00600060)#define SET_READ_CFG			(0x00030003)#define BLOCK_LOCK_BIT_SET		(0x00010001)#define BLOCK_LOCK_BIT_CLEAR	(0x00D000D0)#define PROTECTION_PROGRAM		(0x00C000C0)/* Status bits */#define STATUS_BUSY				(0x00800080)#define STATUS_ERR_FILTER		(0x007E007E)#define STATUS_LOCK_DETECT		(0x00020002)#define STATUS_VOLT_RANG_ERR	(0x00080008)#define STATUS_CMD_SEQ_ERR		(0x00300030)#define STATUS_PGM_ERR			(0x00100010)#define STATUS_LOCK_ERR			(0x00100010)#define STATUS_ERASE_ERR		(0x00200020)#define STATUS_UNLOCK_ERR		(0x00200020)#define STATUS_LOCK_ERR_FILTER	(0x00380038)#define report(fmt, args...)	printf(fmt, ##args)#define detail(fmt, args...)	//printf(fmt, ##args)#define assert(fmt, args...)	printf(fmt, ##args)#define failed(fmt, args...)	//printf(fmt, ##args)struct iflash {	ulong  base;	ulong  size;	ulong  blksize;	ulong  blocks;	uint   flashcnt;	uint   buswidth;	ushort buff_size;	ushort erase_time;};enum action { ACT_PGM, ACT_ERASE, ACT_LOCK, ACT_UNLOCK, ACT_WRITE_BUF };extern bool iflash_init(void);static bool do_flash(int argc, char **argv);static void flash_usage(void);static bool do_erase(int argc, char **argv);static void erase_usage(void);static bool do_lock(int argc, char **argv);static void lock_usage(void);static bool do_unlock(int argc, char **argv);static void unlock_usage(void);static bool iflash_write_block(void *dest, const void *src);static bool iflash_erase_block(void *addr);static bool iflash_lock_block(void *addr);static bool iflash_unlock_block(void *addr);bool flash_write(void *dest, const void *src, uint cnt);//static ulong iflash_read(void *addr, int buswidth);static void iflash_write_cmd(void *addr, int buswidth, int c);static bool iflash_status_check(void *addr, enum action which);static void wait_while_busy(void *addr);static struct iflash _flash, *flash=&_flash;struct command_t cmd_flash = {	.name  = "flash",	.run   = do_flash,	.usage = flash_usage};struct command_t cmd_erase = {	.name  = "erase",	.run   = do_erase, 	.usage = erase_usage};struct command_t cmd_lock = {	.name  = "lock",	.run   = do_lock,	.usage = lock_usage};struct command_t cmd_unlock = {	.name  = "unlock",	.run   = do_unlock,	.usage = unlock_usage};extern bool iflash_init(void){	int bit_mode;	int buswidth, flashcnt;	int blocks, blksize;	ulong base;	/* check query and find buswidth */	iflash_write_cmd((void *)flash->base, 1, READ_QUERY);	for (buswidth=1; buswidth <= 8; buswidth <<= 1){		if ( *(uint8 *)(flash->base + (0x10 * buswidth)) == 'Q' &&			 *(uint8 *)(flash->base + (0x11 * buswidth)) == 'R' &&			 *(uint8 *)(flash->base + (0x12 * buswidth)) == 'Y' )				break;	}	iflash_write_cmd((void *)flash->base, 1, READ_ARRAY);	if (buswidth > 8) return false;	/* find number of flash */	base = flash->base;	iflash_write_cmd((void *)base, buswidth, READ_QUERY);	for (bit_mode=1; bit_mode < buswidth; bit_mode <<= 1){		int ch = *(uint8 *)(base + (0x10 * buswidth) + bit_mode);		if (ch == 'Q' || ch == 'R') break;	}	flashcnt = buswidth / bit_mode;	/* get flash information from query */	flash->size       = (1 << *(uint8 *)(base + (0x27 * buswidth))) * flashcnt;	blocks = *(uint8 *)(base + 0x2E*buswidth) << 8 | *(uint8 *)(base + 0x2D*buswidth);	flash->blocks = (blocks | (blocks>>2)) + 1;	blksize = *(uint8 *)(base + 0x30*buswidth) << 8 | *(uint8 *)(base + 0x2F*buswidth);	flash->blksize = blksize * 256 * flashcnt;	if (flash->size != flash->blksize * flash->blocks){		blocks = *(uint8 *)(base + 0x32*buswidth) << 8 | *(uint8 *)(base + 0x31*buswidth);		flash->blocks = (blocks | (blocks>>2)) + 1;		blksize = *(uint8 *)(base + 0x34*buswidth) << 8 | *(uint8 *)(base + 0x33*buswidth);		flash->blksize = blksize * 256 * flashcnt;	}	flash->flashcnt   = flashcnt;	flash->buswidth   = buswidth;	flash->buff_size  = (1 << *(uint8 *)(flash->base + (0x2A * buswidth))) * flashcnt;	flash->erase_time = (1 << *(uint8 *)(flash->base + (0x25 * buswidth)));	detail(" strata flash\n");	detail(" base base : 0x%08lX\n", flash->base);	detail(" size      : 0x%08lX\n", flash->size);	detail(" blk size  : 0x%08lX\n", flash->blksize);	detail(" blocks    : 0x%08lX\n", flash->blocks);	detail(" buff size : 0x%08X\n", flash->buff_size);	detail(" erase time: 0x%08X\n", flash->erase_time);	detail(" flash cnt : 0x%08X\n", flash->flashcnt);	detail(" bit width : 0x%08X\n", flash->buswidth);	report(" flash : base=0x%08lX, size=0x%08lX\n", flash->base, flash->size);	iflash_write_cmd((void *)flash->base, buswidth, READ_ARRAY);	//iflash_unlock_all();	return true;}static bool do_flash_by_map(int argc, char **argv){	bool res;	uint n, len;	uchar *to, *from;	void *dest, *src;	struct map *mp;	if (argc != 2) goto invalid;	mp = find_map(argv[1]);	if (!mp) goto invalid;	dest = (void *)mp->sramb;	src  = (void *)mp->dramb;	if (!mp->drams) goto fail1;	/* erase */	to = dest; len = mp->maxs;	if (len) do {		report("\r erase at 0x%p~0x%p : at 0x%p", dest, dest + mp->maxs-1, to);		res =  iflash_erase_block(to);		if (!res){ failed("\n error : failed to erase.\n"); goto fail2; }		to     += flash->blksize;		len -= flash->blksize;	} while (len);	report("\r erase at 0x%p~0x%p : done.        \n", dest, dest + mp->maxs-1);	/* write */	to = dest; from = src; len = mp->drams;	if (len) do {		n = flash->blksize - ((ulong)to & (flash->blksize-1));		n = len < n ? len : n;		report("\r write at 0x%p~0x%p with 0x%p : at 0x%p", dest, dest + mp->drams-1, src, to);		res = flash_write(to, from, n);		if (!res){ failed("write failed"); report("\n"); goto fail2; }		to     += n;		from   += n;		len -= n;	} while (len);	report("\r write at 0x%p~0x%p with 0x%p : done.        \n", dest, dest + mp->drams-1, src);	mp->srams = mp->drams;	save_setup();	return true;fail1 :	printf(" error : image is not exists in dynamic memory.\n");	return false;fail2 :	mp->srams = 0;	save_setup();	return false;invalid :	flash_usage();	return false;}static bool do_flash_by_addr(int argc, char **argv){	bool res;	uint n, size, remain;	ulong tmp;	void *dest, *src;	uchar *to, *from;	/* get information */	if (argc != 4) goto invalid;	res = strtoul(argv[1], &tmp, 16);	if (!res) goto invalid;	dest = (void *)tmp;	res = strtoul(argv[2], &tmp, 16);	if (!res) goto invalid;	src = (void *)tmp;	res = strtoul(argv[3], &tmp, 0);	if (!res) goto invalid;	size = tmp;	/* write */	to = dest; from = src; remain = size;	if (remain) do {		n = flash->blksize - ((ulong)to & (flash->blksize-1));		n = remain < n ? remain : n;		report("\r write at 0x%p~0x%p with 0x%p : at 0x%p", dest, (char *)dest + size-1, src, to);		res = flash_write(to, from, n);		if (!res){ failed("write failed"); report("\n"); return false; }		to     += n;		from   += n;		remain -= n;	} while (remain);	report("\r write at 0x%p~0x%p with 0x%p : done.        \n", dest, dest + size-1, src);	return true;invalid :	flash_usage();	return false;}static bool do_flash(int argc, char **argv){	if (argc == 2)		return do_flash_by_map(argc, argv);	else if (argc == 4)		return do_flash_by_addr(argc, argv);	flash_usage();	return false;}static void flash_usage(void){	usage_format("flash {loader/kernel/root/ramdisk}", "copy to flash from sdram of area");	//usage_format("flash dest src size", "copy to flash from src to dest");	return;}static bool do_erase(int argc, char **argv){	bool res;	ulong addr, size, tmp;	/* get information */	if (argc == 2){		struct map *mp;		mp = find_map(argv[1]);		if (mp){									/* erase {loader/kernel/ramdisk/root} */			addr = mp->sramb;			size = mp->maxs;		} else if (strtoul(argv[1], &tmp, 16)){		/* erase addr */			addr = tmp;			size = flash->blksize;		} else goto invalid;	} else if (argc == 3){							/* erase addr size */		res = strtoul(argv[1], &tmp, 16);		if (!res) goto invalid;		addr = tmp;		res = strtoul(argv[2], &tmp, 16);		if (!res) goto invalid;		size = tmp;	} else goto invalid;	/* check address and size */	if (addr % flash->blksize){		failed(" error : addr is not flash block base.(blksize=%lx)\n", flash->blksize);		return false;	}	if (size % flash->blksize){		failed(" error : size is not multifly of block size.(blksize=%lx)\n", flash->blksize);		return false;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -