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

📄 cfi_flash.c

📁 最新版的u-boot,2008-10-18发布
💻 C
📖 第 1 页 / 共 4 页
字号:
{	int rcode = 0;	int prot;	flash_sect_t sect;	if (info->flash_id != FLASH_MAN_CFI) {		puts ("Can't erase unknown flash type - aborted\n");		return 1;	}	if ((s_first < 0) || (s_first > s_last)) {		puts ("- no sectors to erase\n");		return 1;	}	prot = 0;	for (sect = s_first; sect <= s_last; ++sect) {		if (info->protect[sect]) {			prot++;		}	}	if (prot) {		printf ("- Warning: %d protected sectors will not be erased!\n",			prot);	} else {		putc ('\n');	}	for (sect = s_first; sect <= s_last; sect++) {		if (info->protect[sect] == 0) { /* not protected */			switch (info->vendor) {			case CFI_CMDSET_INTEL_PROG_REGIONS:			case CFI_CMDSET_INTEL_STANDARD:			case CFI_CMDSET_INTEL_EXTENDED:				flash_write_cmd (info, sect, 0,						 FLASH_CMD_CLEAR_STATUS);				flash_write_cmd (info, sect, 0,						 FLASH_CMD_BLOCK_ERASE);				flash_write_cmd (info, sect, 0,						 FLASH_CMD_ERASE_CONFIRM);				break;			case CFI_CMDSET_AMD_STANDARD:			case CFI_CMDSET_AMD_EXTENDED:				flash_unlock_seq (info, sect);				flash_write_cmd (info, sect,						info->addr_unlock1,						AMD_CMD_ERASE_START);				flash_unlock_seq (info, sect);				flash_write_cmd (info, sect, 0,						 AMD_CMD_ERASE_SECTOR);				break;#ifdef CONFIG_FLASH_CFI_LEGACY			case CFI_CMDSET_AMD_LEGACY:				flash_unlock_seq (info, 0);				flash_write_cmd (info, 0, info->addr_unlock1,						AMD_CMD_ERASE_START);				flash_unlock_seq (info, 0);				flash_write_cmd (info, sect, 0,						AMD_CMD_ERASE_SECTOR);				break;#endif			default:				debug ("Unkown flash vendor %d\n",				       info->vendor);				break;			}			if (flash_full_status_check			    (info, sect, info->erase_blk_tout, "erase")) {				rcode = 1;			} else				putc ('.');		}	}	puts (" done\n");	return rcode;}/*----------------------------------------------------------------------- */void flash_print_info (flash_info_t * info){	int i;	if (info->flash_id != FLASH_MAN_CFI) {		puts ("missing or unknown FLASH type\n");		return;	}	printf ("%s FLASH (%d x %d)",		info->name,		(info->portwidth << 3), (info->chipwidth << 3));	if (info->size < 1024*1024)		printf ("  Size: %ld kB in %d Sectors\n",			info->size >> 10, info->sector_count);	else		printf ("  Size: %ld MB in %d Sectors\n",			info->size >> 20, info->sector_count);	printf ("  ");	switch (info->vendor) {		case CFI_CMDSET_INTEL_PROG_REGIONS:			printf ("Intel Prog Regions");			break;		case CFI_CMDSET_INTEL_STANDARD:			printf ("Intel Standard");			break;		case CFI_CMDSET_INTEL_EXTENDED:			printf ("Intel Extended");			break;		case CFI_CMDSET_AMD_STANDARD:			printf ("AMD Standard");			break;		case CFI_CMDSET_AMD_EXTENDED:			printf ("AMD Extended");			break;#ifdef CONFIG_FLASH_CFI_LEGACY		case CFI_CMDSET_AMD_LEGACY:			printf ("AMD Legacy");			break;#endif		default:			printf ("Unknown (%d)", info->vendor);			break;	}	printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x%02X",		info->manufacturer_id, info->device_id);	if (info->device_id == 0x7E) {		printf("%04X", info->device_id2);	}	printf ("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",		info->erase_blk_tout,		info->write_tout);	if (info->buffer_size > 1) {		printf ("  Buffer write timeout: %ld ms, "			"buffer size: %d bytes\n",		info->buffer_write_tout,		info->buffer_size);	}	puts ("\n  Sector Start Addresses:");	for (i = 0; i < info->sector_count; ++i) {		if ((i % 5) == 0)			printf ("\n");#ifdef CFG_FLASH_EMPTY_INFO		int k;		int size;		int erased;		volatile unsigned long *flash;		/*		 * Check if whole sector is erased		 */		size = flash_sector_size(info, i);		erased = 1;		flash = (volatile unsigned long *) info->start[i];		size = size >> 2;	/* divide by 4 for longword access */		for (k = 0; k < size; k++) {			if (*flash++ != 0xffffffff) {				erased = 0;				break;			}		}		/* print empty and read-only info */		printf ("  %08lX %c %s ",			info->start[i],			erased ? 'E' : ' ',			info->protect[i] ? "RO" : "  ");#else	/* ! CFG_FLASH_EMPTY_INFO */		printf ("  %08lX   %s ",			info->start[i],			info->protect[i] ? "RO" : "  ");#endif	}	putc ('\n');	return;}/*----------------------------------------------------------------------- * This is used in a few places in write_buf() to show programming * progress.  Making it a function is nasty because it needs to do side * effect updates to digit and dots.  Repeated code is nasty too, so * we define it once here. */#ifdef CONFIG_FLASH_SHOW_PROGRESS#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \	dots -= dots_sub; \	if ((scale > 0) && (dots <= 0)) { \		if ((digit % 5) == 0) \			printf ("%d", digit / 5); \		else \			putc ('.'); \		digit--; \		dots += scale; \	}#else#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub)#endif/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt){	ulong wp;	uchar *p;	int aln;	cfiword_t cword;	int i, rc;#ifdef CFG_FLASH_USE_BUFFER_WRITE	int buffered_size;#endif#ifdef CONFIG_FLASH_SHOW_PROGRESS	int digit = CONFIG_FLASH_SHOW_PROGRESS;	int scale = 0;	int dots  = 0;	/*	 * Suppress if there are fewer than CONFIG_FLASH_SHOW_PROGRESS writes.	 */	if (cnt >= CONFIG_FLASH_SHOW_PROGRESS) {		scale = (int)((cnt + CONFIG_FLASH_SHOW_PROGRESS - 1) /			CONFIG_FLASH_SHOW_PROGRESS);	}#endif	/* get lower aligned address */	wp = (addr & ~(info->portwidth - 1));	/* handle unaligned start */	if ((aln = addr - wp) != 0) {		cword.l = 0;		p = map_physmem(wp, info->portwidth, MAP_NOCACHE);		for (i = 0; i < aln; ++i)			flash_add_byte (info, &cword, flash_read8(p + i));		for (; (i < info->portwidth) && (cnt > 0); i++) {			flash_add_byte (info, &cword, *src++);			cnt--;		}		for (; (cnt == 0) && (i < info->portwidth); ++i)			flash_add_byte (info, &cword, flash_read8(p + i));		rc = flash_write_cfiword (info, wp, cword);		unmap_physmem(p, info->portwidth);		if (rc != 0)			return rc;		wp += i;		FLASH_SHOW_PROGRESS(scale, dots, digit, i);	}	/* handle the aligned part */#ifdef CFG_FLASH_USE_BUFFER_WRITE	buffered_size = (info->portwidth / info->chipwidth);	buffered_size *= info->buffer_size;	while (cnt >= info->portwidth) {		/* prohibit buffer write when buffer_size is 1 */		if (info->buffer_size == 1) {			cword.l = 0;			for (i = 0; i < info->portwidth; i++)				flash_add_byte (info, &cword, *src++);			if ((rc = flash_write_cfiword (info, wp, cword)) != 0)				return rc;			wp += info->portwidth;			cnt -= info->portwidth;			continue;		}		/* write buffer until next buffered_size aligned boundary */		i = buffered_size - (wp % buffered_size);		if (i > cnt)			i = cnt;		if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)			return rc;		i -= i & (info->portwidth - 1);		wp += i;		src += i;		cnt -= i;		FLASH_SHOW_PROGRESS(scale, dots, digit, i);	}#else	while (cnt >= info->portwidth) {		cword.l = 0;		for (i = 0; i < info->portwidth; i++) {			flash_add_byte (info, &cword, *src++);		}		if ((rc = flash_write_cfiword (info, wp, cword)) != 0)			return rc;		wp += info->portwidth;		cnt -= info->portwidth;		FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth);	}#endif /* CFG_FLASH_USE_BUFFER_WRITE */	if (cnt == 0) {		return (0);	}	/*	 * handle unaligned tail bytes	 */	cword.l = 0;	p = map_physmem(wp, info->portwidth, MAP_NOCACHE);	for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {		flash_add_byte (info, &cword, *src++);		--cnt;	}	for (; i < info->portwidth; ++i)		flash_add_byte (info, &cword, flash_read8(p + i));	unmap_physmem(p, info->portwidth);	return flash_write_cfiword (info, wp, cword);}/*----------------------------------------------------------------------- */#ifdef CFG_FLASH_PROTECTIONint flash_real_protect (flash_info_t * info, long sector, int prot){	int retcode = 0;	switch (info->vendor) {		case CFI_CMDSET_INTEL_PROG_REGIONS:		case CFI_CMDSET_INTEL_STANDARD:		case CFI_CMDSET_INTEL_EXTENDED:			flash_write_cmd (info, sector, 0,					 FLASH_CMD_CLEAR_STATUS);			flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);			if (prot)				flash_write_cmd (info, sector, 0,					FLASH_CMD_PROTECT_SET);			else				flash_write_cmd (info, sector, 0,					FLASH_CMD_PROTECT_CLEAR);			break;		case CFI_CMDSET_AMD_EXTENDED:		case CFI_CMDSET_AMD_STANDARD:			/* U-Boot only checks the first byte */			if (info->manufacturer_id == (uchar)ATM_MANUFACT) {				if (prot) {					flash_unlock_seq (info, 0);					flash_write_cmd (info, 0,							info->addr_unlock1,							ATM_CMD_SOFTLOCK_START);					flash_unlock_seq (info, 0);					flash_write_cmd (info, sector, 0,							ATM_CMD_LOCK_SECT);				} else {					flash_write_cmd (info, 0,							info->addr_unlock1,							AMD_CMD_UNLOCK_START);					if (info->device_id == ATM_ID_BV6416)						flash_write_cmd (info, sector,							0, ATM_CMD_UNLOCK_SECT);				}			}			break;#ifdef CONFIG_FLASH_CFI_LEGACY		case CFI_CMDSET_AMD_LEGACY:			flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);			flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);			if (prot)				flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);			else				flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);#endif	};	if ((retcode =	     flash_full_status_check (info, sector, info->erase_blk_tout,				      prot ? "protect" : "unprotect")) == 0) {		info->protect[sector] = prot;		/*		 * On some of Intel's flash chips (marked via legacy_unlock)		 * unprotect unprotects all locking.		 */		if ((prot == 0) && (info->legacy_unlock)) {			flash_sect_t i;			for (i = 0; i < info->sector_count; i++) {				if (info->protect[i])					flash_real_protect (info, i, 1);			}		}	}	return retcode;}/*----------------------------------------------------------------------- * flash_read_user_serial - read the OneTimeProgramming cells */void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,			     int len){	uchar *src;	uchar *dst;	dst = buffer;	src = flash_map (info, 0, FLASH_OFFSET_USER_PROTECTION);	flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);	memcpy (dst, src + offset, len);	flash_write_cmd (info, 0, 0, info->cmd_reset);	flash_unmap(info, 0, FLASH_OFFSET_USER_PROTECTION, src);}/* * flash_read_factory_serial - read the device Id from the protection area */void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,				int len){	uchar *src;	src = flash_map (info, 0, FLASH_OFFSET_INTEL_PROTECTION);	flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);	memcpy (buffer, src + offset, len);	flash_write_cmd (info, 0, 0, info->cmd_reset);	flash_unmap(info, 0, FLASH_OFFSET_INTEL_PROTECTION, src);}#endif /* CFG_FLASH_PROTECTION *//*----------------------------------------------------------------------- * Reverse the order of the erase regions in the CFI QRY structure. * This is needed for chips that are either a) correctly detected as * top-boot, or b) buggy. */static void cfi_reverse_geometry(struct cfi_qry *qry){	unsigned int i, j;	u32 tmp;	for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {		tmp = qry->erase_region_info[i];		qry->erase_region_info[i] = qry->erase_region_info[j];		qry->erase_region_info[j] = tmp;	}}/*----------------------------------------------------------------------- * read jedec ids from device and set corresponding fields in info struct * * Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct * */static void cmdset_intel_read_jedec_ids(flash_info_t *info){	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);	flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);	udelay(1000); /* some flash are slow to respond */	info->manufacturer_id = flash_read_uchar (info,					FLASH_OFFSET_MANUFACTURER_ID);	info->device_id = flash_read_uchar (info,					FLASH_OFFSET_DEVICE_ID);	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);}static int cmdset_intel_init(flash_info_t *info, struct cfi_qry *qry){	info->cmd_reset = FLASH_CMD_RESET;	cmdset_intel_read_jedec_ids(info);	flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);#ifdef CFG_FLASH_PROTECTION	/* read legacy lock/unlock bit from intel flash */	if (info->ext_addr) {		info->legacy_unlock = flash_read_uchar (info,				info->ext_addr + 5) & 0x08;	}#endif	return 0;}static void cmdset_amd_read_jedec_ids(flash_info_t *info){	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);	flash_unlock_seq(info, 0);	flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);	udelay(1000); /* some flash are slow to respond */	info->manufacturer_id = flash_read_uchar (info,					FLASH_OFFSET_MANUFACTURER_ID);	switch (info->chipwidth){	case FLASH_CFI_8BIT:		info->device_id = flash_read_uchar (info,						FLASH_OFFSET_DEVICE_ID);		if (info->device_id == 0x7E) {			/* AMD 3-byte (expanded) device ids */			info->device_id2 = flash_read_uchar (info,						FLASH_OFFSET_DEVICE_ID2);			info->device_id2 <<= 8;			info->device_id2 |= flash_read_uchar (info,						FLASH_OFFSET_DEVICE_ID3);		}		break;	case FLASH_CFI_16BIT:		info->device_id = flash_read_word (info,						FLASH_OFFSET_DEVICE_ID);		break;	default:		break;	}	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);}static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)

⌨️ 快捷键说明

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