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

📄 cfi_flash.c

📁 最新版的u-boot,2008-10-18发布
💻 C
📖 第 1 页 / 共 4 页
字号:
		break;	case FLASH_CFI_32BIT:		debug ("is= %8.8x %8.8lx\n", flash_read32(addr), cword.l);		retval = (flash_read32(addr) == cword.l);		break;	case FLASH_CFI_64BIT:#ifdef DEBUG		{			char str1[20];			char str2[20];			print_longlong (str1, flash_read64(addr));			print_longlong (str2, cword.ll);			debug ("is= %s %s\n", str1, str2);		}#endif		retval = (flash_read64(addr) == cword.ll);		break;	default:		retval = 0;		break;	}	flash_unmap(info, sect, offset, addr);	return retval;}/*----------------------------------------------------------------------- */static int flash_isset (flash_info_t * info, flash_sect_t sect,			uint offset, uchar cmd){	void *addr;	cfiword_t cword;	int retval;	addr = flash_map (info, sect, offset);	flash_make_cmd (info, cmd, &cword);	switch (info->portwidth) {	case FLASH_CFI_8BIT:		retval = ((flash_read8(addr) & cword.c) == cword.c);		break;	case FLASH_CFI_16BIT:		retval = ((flash_read16(addr) & cword.w) == cword.w);		break;	case FLASH_CFI_32BIT:		retval = ((flash_read32(addr) & cword.l) == cword.l);		break;	case FLASH_CFI_64BIT:		retval = ((flash_read64(addr) & cword.ll) == cword.ll);		break;	default:		retval = 0;		break;	}	flash_unmap(info, sect, offset, addr);	return retval;}/*----------------------------------------------------------------------- */static int flash_toggle (flash_info_t * info, flash_sect_t sect,			 uint offset, uchar cmd){	void *addr;	cfiword_t cword;	int retval;	addr = flash_map (info, sect, offset);	flash_make_cmd (info, cmd, &cword);	switch (info->portwidth) {	case FLASH_CFI_8BIT:		retval = flash_read8(addr) != flash_read8(addr);		break;	case FLASH_CFI_16BIT:		retval = flash_read16(addr) != flash_read16(addr);		break;	case FLASH_CFI_32BIT:		retval = flash_read32(addr) != flash_read32(addr);		break;	case FLASH_CFI_64BIT:		retval = flash_read64(addr) != flash_read64(addr);		break;	default:		retval = 0;		break;	}	flash_unmap(info, sect, offset, addr);	return retval;}/* * flash_is_busy - check to see if the flash is busy * * This routine checks the status of the chip and returns true if the * chip is busy. */static int flash_is_busy (flash_info_t * info, flash_sect_t sect){	int retval;	switch (info->vendor) {	case CFI_CMDSET_INTEL_PROG_REGIONS:	case CFI_CMDSET_INTEL_STANDARD:	case CFI_CMDSET_INTEL_EXTENDED:		retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);		break;	case CFI_CMDSET_AMD_STANDARD:	case CFI_CMDSET_AMD_EXTENDED:#ifdef CONFIG_FLASH_CFI_LEGACY	case CFI_CMDSET_AMD_LEGACY:#endif		retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);		break;	default:		retval = 0;	}	debug ("flash_is_busy: %d\n", retval);	return retval;}/*----------------------------------------------------------------------- *  wait for XSR.7 to be set. Time out with an error if it does not. *  This routine does not set the flash to read-array mode. */static int flash_status_check (flash_info_t * info, flash_sect_t sector,			       ulong tout, char *prompt){	ulong start;#if CFG_HZ != 1000	tout *= CFG_HZ/1000;#endif	/* Wait for command completion */	start = get_timer (0);	while (flash_is_busy (info, sector)) {		if (get_timer (start) > tout) {			printf ("Flash %s timeout at address %lx data %lx\n",				prompt, info->start[sector],				flash_read_long (info, sector, 0));			flash_write_cmd (info, sector, 0, info->cmd_reset);			return ERR_TIMOUT;		}		udelay (1);		/* also triggers watchdog */	}	return ERR_OK;}/*----------------------------------------------------------------------- * Wait for XSR.7 to be set, if it times out print an error, otherwise * do a full status check. * * This routine sets the flash to read-array mode. */static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,				    ulong tout, char *prompt){	int retcode;	retcode = flash_status_check (info, sector, tout, prompt);	switch (info->vendor) {	case CFI_CMDSET_INTEL_PROG_REGIONS:	case CFI_CMDSET_INTEL_EXTENDED:	case CFI_CMDSET_INTEL_STANDARD:		if ((retcode != ERR_OK)		    && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {			retcode = ERR_INVAL;			printf ("Flash %s error at address %lx\n", prompt,				info->start[sector]);			if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS |					 FLASH_STATUS_PSLBS)) {				puts ("Command Sequence Error.\n");			} else if (flash_isset (info, sector, 0,						FLASH_STATUS_ECLBS)) {				puts ("Block Erase Error.\n");				retcode = ERR_NOT_ERASED;			} else if (flash_isset (info, sector, 0,						FLASH_STATUS_PSLBS)) {				puts ("Locking Error\n");			}			if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {				puts ("Block locked.\n");				retcode = ERR_PROTECTED;			}			if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))				puts ("Vpp Low Error.\n");		}		flash_write_cmd (info, sector, 0, info->cmd_reset);		break;	default:		break;	}	return retcode;}/*----------------------------------------------------------------------- */static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c){#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)	unsigned short	w;	unsigned int	l;	unsigned long long ll;#endif	switch (info->portwidth) {	case FLASH_CFI_8BIT:		cword->c = c;		break;	case FLASH_CFI_16BIT:#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)		w = c;		w <<= 8;		cword->w = (cword->w >> 8) | w;#else		cword->w = (cword->w << 8) | c;#endif		break;	case FLASH_CFI_32BIT:#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)		l = c;		l <<= 24;		cword->l = (cword->l >> 8) | l;#else		cword->l = (cword->l << 8) | c;#endif		break;	case FLASH_CFI_64BIT:#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)		ll = c;		ll <<= 56;		cword->ll = (cword->ll >> 8) | ll;#else		cword->ll = (cword->ll << 8) | c;#endif		break;	}}/* loop through the sectors from the highest address when the passed * address is greater or equal to the sector address we have a match */static flash_sect_t find_sector (flash_info_t * info, ulong addr){	flash_sect_t sector;	for (sector = info->sector_count - 1; sector >= 0; sector--) {		if (addr >= info->start[sector])			break;	}	return sector;}/*----------------------------------------------------------------------- */static int flash_write_cfiword (flash_info_t * info, ulong dest,				cfiword_t cword){	void *dstaddr;	int flag;	flash_sect_t sect;	dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE);	/* Check if Flash is (sufficiently) erased */	switch (info->portwidth) {	case FLASH_CFI_8BIT:		flag = ((flash_read8(dstaddr) & cword.c) == cword.c);		break;	case FLASH_CFI_16BIT:		flag = ((flash_read16(dstaddr) & cword.w) == cword.w);		break;	case FLASH_CFI_32BIT:		flag = ((flash_read32(dstaddr) & cword.l) == cword.l);		break;	case FLASH_CFI_64BIT:		flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);		break;	default:		flag = 0;		break;	}	if (!flag) {		unmap_physmem(dstaddr, info->portwidth);		return ERR_NOT_ERASED;	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts ();	switch (info->vendor) {	case CFI_CMDSET_INTEL_PROG_REGIONS:	case CFI_CMDSET_INTEL_EXTENDED:	case CFI_CMDSET_INTEL_STANDARD:		flash_write_cmd (info, 0, 0, FLASH_CMD_CLEAR_STATUS);		flash_write_cmd (info, 0, 0, FLASH_CMD_WRITE);		break;	case CFI_CMDSET_AMD_EXTENDED:	case CFI_CMDSET_AMD_STANDARD:#ifdef CONFIG_FLASH_CFI_LEGACY	case CFI_CMDSET_AMD_LEGACY:#endif		sect = find_sector(info, dest);		flash_unlock_seq (info, sect);		flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_WRITE);		break;	}	switch (info->portwidth) {	case FLASH_CFI_8BIT:		flash_write8(cword.c, dstaddr);		break;	case FLASH_CFI_16BIT:		flash_write16(cword.w, dstaddr);		break;	case FLASH_CFI_32BIT:		flash_write32(cword.l, dstaddr);		break;	case FLASH_CFI_64BIT:		flash_write64(cword.ll, dstaddr);		break;	}	/* re-enable interrupts if necessary */	if (flag)		enable_interrupts ();	unmap_physmem(dstaddr, info->portwidth);	return flash_full_status_check (info, find_sector (info, dest),					info->write_tout, "write");}#ifdef CFG_FLASH_USE_BUFFER_WRITEstatic int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,				  int len){	flash_sect_t sector;	int cnt;	int retcode;	void *src = cp;	void *dst = map_physmem(dest, len, MAP_NOCACHE);	void *dst2 = dst;	int flag = 0;	uint offset = 0;	unsigned int shift;	uchar write_cmd;	switch (info->portwidth) {	case FLASH_CFI_8BIT:		shift = 0;		break;	case FLASH_CFI_16BIT:		shift = 1;		break;	case FLASH_CFI_32BIT:		shift = 2;		break;	case FLASH_CFI_64BIT:		shift = 3;		break;	default:		retcode = ERR_INVAL;		goto out_unmap;	}	cnt = len >> shift;	while ((cnt-- > 0) && (flag == 0)) {		switch (info->portwidth) {		case FLASH_CFI_8BIT:			flag = ((flash_read8(dst2) & flash_read8(src)) ==				flash_read8(src));			src += 1, dst2 += 1;			break;		case FLASH_CFI_16BIT:			flag = ((flash_read16(dst2) & flash_read16(src)) ==				flash_read16(src));			src += 2, dst2 += 2;			break;		case FLASH_CFI_32BIT:			flag = ((flash_read32(dst2) & flash_read32(src)) ==				flash_read32(src));			src += 4, dst2 += 4;			break;		case FLASH_CFI_64BIT:			flag = ((flash_read64(dst2) & flash_read64(src)) ==				flash_read64(src));			src += 8, dst2 += 8;			break;		}	}	if (!flag) {		retcode = ERR_NOT_ERASED;		goto out_unmap;	}	src = cp;	sector = find_sector (info, dest);	switch (info->vendor) {	case CFI_CMDSET_INTEL_PROG_REGIONS:	case CFI_CMDSET_INTEL_STANDARD:	case CFI_CMDSET_INTEL_EXTENDED:		write_cmd = (info->vendor == CFI_CMDSET_INTEL_PROG_REGIONS) ?					FLASH_CMD_WRITE_BUFFER_PROG : FLASH_CMD_WRITE_TO_BUFFER;		flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);		flash_write_cmd (info, sector, 0, FLASH_CMD_READ_STATUS);		flash_write_cmd (info, sector, 0, write_cmd);		retcode = flash_status_check (info, sector,					      info->buffer_write_tout,					      "write to buffer");		if (retcode == ERR_OK) {			/* reduce the number of loops by the width of			 * the port */			cnt = len >> shift;			flash_write_cmd (info, sector, 0, cnt - 1);			while (cnt-- > 0) {				switch (info->portwidth) {				case FLASH_CFI_8BIT:					flash_write8(flash_read8(src), dst);					src += 1, dst += 1;					break;				case FLASH_CFI_16BIT:					flash_write16(flash_read16(src), dst);					src += 2, dst += 2;					break;				case FLASH_CFI_32BIT:					flash_write32(flash_read32(src), dst);					src += 4, dst += 4;					break;				case FLASH_CFI_64BIT:					flash_write64(flash_read64(src), dst);					src += 8, dst += 8;					break;				default:					retcode = ERR_INVAL;					goto out_unmap;				}			}			flash_write_cmd (info, sector, 0,					 FLASH_CMD_WRITE_BUFFER_CONFIRM);			retcode = flash_full_status_check (				info, sector, info->buffer_write_tout,				"buffer write");		}		break;	case CFI_CMDSET_AMD_STANDARD:	case CFI_CMDSET_AMD_EXTENDED:		flash_unlock_seq(info,0);#ifdef CONFIG_FLASH_SPANSION_S29WS_N		offset = ((unsigned long)dst - info->start[sector]) >> shift;#endif		flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER);		cnt = len >> shift;		flash_write_cmd(info, sector, offset, (uchar)cnt - 1);		switch (info->portwidth) {		case FLASH_CFI_8BIT:			while (cnt-- > 0) {				flash_write8(flash_read8(src), dst);				src += 1, dst += 1;			}			break;		case FLASH_CFI_16BIT:			while (cnt-- > 0) {				flash_write16(flash_read16(src), dst);				src += 2, dst += 2;			}			break;		case FLASH_CFI_32BIT:			while (cnt-- > 0) {				flash_write32(flash_read32(src), dst);				src += 4, dst += 4;			}			break;		case FLASH_CFI_64BIT:			while (cnt-- > 0) {				flash_write64(flash_read64(src), dst);				src += 8, dst += 8;			}			break;		default:			retcode = ERR_INVAL;			goto out_unmap;		}		flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);		retcode = flash_full_status_check (info, sector,						   info->buffer_write_tout,						   "buffer write");		break;	default:		debug ("Unknown Command Set\n");		retcode = ERR_INVAL;		break;	}out_unmap:	unmap_physmem(dst, len);	return retcode;}#endif /* CFG_FLASH_USE_BUFFER_WRITE *//*----------------------------------------------------------------------- */int flash_erase (flash_info_t * info, int s_first, int s_last)

⌨️ 快捷键说明

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