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

📄 flash.c

📁 u-boot 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	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		printf("\n");	start = get_timer(0);	last = start;	/* Start erase on unprotected sectors */	for (sect = s_first; sect <= s_last; sect++) {		if (info->protect[sect] == 0) {	/* not protected */			FPWV *addr = (FPWV *) (info->start[sect]);			int min = 0;			printf(".");			/* arm simple, non interrupt dependent timer */			start = get_timer(0);			if (intel) {				*addr = (FPW) INTEL_READID;				min = addr[INTEL_CFI_TERB] & 0xff;				min = 1 << min;	/* ms */				min = (min / info->sector_count) * 1000;				/* start erase block */				*addr = (FPW) INTEL_CLEAR;	/* clear status register */				*addr = (FPW) INTEL_ERASE;	/* erase setup */				*addr = (FPW) INTEL_CONFIRM;	/* erase confirm */				while ((*addr & (FPW) INTEL_FINISHED) !=				       (FPW) INTEL_FINISHED) {					if (get_timer(start) >					    CFG_FLASH_ERASE_TOUT) {						printf("Timeout\n");						*addr = (FPW) INTEL_SUSERASE;	/* suspend erase     */						*addr = (FPW) INTEL_RESET;	/* reset to read mode */						rcode = 1;						break;					}				}				*addr = (FPW) INTEL_RESET;	/* resest to read mode          */			} else {				FPWV *base;	/* first address in bank */				FPWV *atmeladdr;				flag = disable_interrupts();				atmeladdr = (FPWV *) addr;	/* concatenate to 8 bit */				base = (FPWV *) (CFG_ATMEL_BASE);	/* First sector */				base[FLASH_CYCLE1] = (u8) 0x00AA00AA;	/* unlock */				base[FLASH_CYCLE2] = (u8) 0x00550055;	/* unlock */				base[FLASH_CYCLE1] = (u8) 0x00800080;	/* erase mode */				base[FLASH_CYCLE1] = (u8) 0x00AA00AA;	/* unlock */				base[FLASH_CYCLE2] = (u8) 0x00550055;	/* unlock */				*atmeladdr = (u8) 0x00300030;	/* erase sector */				if (flag)					enable_interrupts();				while ((*atmeladdr & (u8) 0x00800080) !=				       (u8) 0x00800080) {					if (get_timer(start) >					    CFG_FLASH_ERASE_TOUT) {						printf("Timeout\n");						*atmeladdr = (u8) 0x00F000F0;	/* reset to read mode */						rcode = 1;						break;					}				}				*atmeladdr = (u8) 0x00F000F0;	/* reset to read mode */			}	/* Atmel or Intel */		}	}	printf(" done\n");	return rcode;}int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt){	if (info->flash_id == FLASH_UNKNOWN)		return 4;	switch (info->flash_id & FLASH_VENDMASK) {	case FLASH_MAN_ATM:		{			u16 data = 0;			int bytes;	/* number of bytes to program in current word */			int left;	/* number of bytes left to program */			int i, res;			for (left = cnt, res = 0;			     left > 0 && res == 0;			     addr += sizeof(data), left -=			     sizeof(data) - bytes) {				bytes = addr & (sizeof(data) - 1);				addr &= ~(sizeof(data) - 1);				/* combine source and destination data so can program				 * an entire word of 16 or 32 bits				 */				for (i = 0; i < sizeof(data); i++) {					data <<= 8;					if (i < bytes || i - bytes >= left)						data += *((uchar *) addr + i);					else						data += *src++;				}				data = (data >> 8) | (data << 8);				res = write_word_atm(info, (FPWV *) addr, data);			}			return res;		}		/* case FLASH_MAN_ATM */	case FLASH_MAN_INTEL:		{			ulong cp, wp;			u16 data;			int count, i, l, rc, port_width;			/* get lower word aligned address */			wp = addr;			port_width = sizeof(FPW);			/*			 * handle unaligned start bytes			 */			if ((l = addr - wp) != 0) {				data = 0;				for (i = 0, cp = wp; i < l; ++i, ++cp) {					data = (data << 8) | (*(uchar *) cp);				}				for (; i < port_width && cnt > 0; ++i) {					data = (data << 8) | *src++;					--cnt;					++cp;				}				for (; cnt == 0 && i < port_width; ++i, ++cp)					data = (data << 8) | (*(uchar *) cp);				if ((rc = write_data(info, wp, data)) != 0)					return (rc);				wp += port_width;			}			if (cnt > WR_BLOCK) {				/*				 * handle word aligned part				 */				count = 0;				while (cnt >= WR_BLOCK) {					if ((rc =					     write_data_block(info,							      (ulong) src,							      wp)) != 0)						return (rc);					wp += WR_BLOCK;					src += WR_BLOCK;					cnt -= WR_BLOCK;					if (count++ > 0x800) {						spin_wheel();						count = 0;					}				}			}			/* handle word aligned part */			if (cnt < WR_BLOCK) {				/*				 * handle word aligned part				 */				count = 0;				while (cnt >= port_width) {					data = 0;					for (i = 0; i < port_width; ++i)						data = (data << 8) | *src++;					if ((rc =					     write_data(info,							(ulong) ((FPWV *) wp),							(FPW) (data))) != 0)						return (rc);					wp += port_width;					cnt -= port_width;					if (count++ > 0x800) {						spin_wheel();						count = 0;					}				}			}			if (cnt == 0)				return ERR_OK;			/*			 * handle unaligned tail bytes			 */			data = 0;			for (i = 0, cp = wp; i < port_width && cnt > 0;			     ++i, ++cp) {				data = (data << 8) | (*src++);				--cnt;			}			for (; i < port_width; ++i, ++cp) {				data = (data << 8) | (*(uchar *) cp);			}			return write_data(info, (ulong) ((FPWV *) wp),					  (FPW) data);		}		/* case FLASH_MAN_INTEL */	}			/* switch */	return ERR_OK;}/*----------------------------------------------------------------------- * Write a word or halfword to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_data_block(flash_info_t * info, ulong src, ulong dest){	FPWV *srcaddr = (FPWV *) src;	FPWV *dstaddr = (FPWV *) dest;	ulong start;	int flag, i;	/* Check if Flash is (sufficiently) erased */	for (i = 0; i < WR_BLOCK; i++)		if ((*dstaddr++ & 0xff) != 0xff) {			printf("not erased at %08lx (%lx)\n",			       (ulong) dstaddr, *dstaddr);			return (2);		}	dstaddr = (FPWV *) dest;	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();	*dstaddr = (FPW) INTEL_WRBLK;	/* write block setup */	if (flag)		enable_interrupts();	/* arm simple, non interrupt dependent timer */	start = get_timer(0);	/* wait while polling the status register */	while ((*dstaddr & (FPW) INTEL_FINISHED) != (FPW) INTEL_OK) {		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {			*dstaddr = (FPW) INTEL_RESET;	/* restore read mode */			return (1);		}	}	*dstaddr = (FPW) WR_BLOCK - 1;	/* write 32 to buffer */	for (i = 0; i < WR_BLOCK; i++)		*dstaddr++ = *srcaddr++;	dstaddr -= 1;	*dstaddr = (FPW) INTEL_CONFIRM;	/* write 32 to buffer */	/* arm simple, non interrupt dependent timer */	start = get_timer(0);	/* wait while polling the status register */	while ((*dstaddr & (FPW) INTEL_FINISHED) != (FPW) INTEL_OK) {		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {			*dstaddr = (FPW) INTEL_RESET;	/* restore read mode */			return (1);		}	}	*dstaddr = (FPW) INTEL_RESET;	/* restore read mode */	return (0);}/*----------------------------------------------------------------------- * Write a word or halfword to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_data(flash_info_t * info, ulong dest, FPW data){	FPWV *addr = (FPWV *) dest;	ulong start;	int flag;	/* Check if Flash is (sufficiently) erased */	if ((*addr & data) != data) {		printf("not erased at %08lx (%lx)\n", (ulong) addr,		       (ulong) * addr);		return (2);	}	/* Disable interrupts which might cause a timeout here */	flag = (int)disable_interrupts();	*addr = (FPW) INTEL_CLEAR;	*addr = (FPW) INTEL_RESET;	*addr = (FPW) INTEL_WRSETUP;	/* write setup */	*addr = data;	if (flag)		enable_interrupts();	/* arm simple, non interrupt dependent timer */	start = get_timer(0);	/* wait while polling the status register */	while ((*addr & (FPW) INTEL_OK) != (FPW) INTEL_OK) {		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {			*addr = (FPW) INTEL_SUSERASE;	/* suspend mode */			*addr = (FPW) INTEL_CLEAR;	/* clear status */			*addr = (FPW) INTEL_RESET;	/* reset */			return (1);		}	}	*addr = (FPW) INTEL_CLEAR;	/* clear status */	*addr = (FPW) INTEL_RESET;	/* restore read mode */	return (0);}/*----------------------------------------------------------------------- * Write a word to Flash for ATMEL FLASH * A word is 16 bits, whichever the bus width of the flash bank * (not an individual chip) is. * * returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_word_atm(flash_info_t * info, volatile u8 * dest, u16 data){	ulong start;	int flag, i;	int res = 0;		/* result, assume success */	FPWV *base;		/* first address in flash bank */	/* Check if Flash is (sufficiently) erased */	if ((*((volatile u16 *)dest) & data) != data) {		return (2);	}	base = (FPWV *) (CFG_ATMEL_BASE);	for (i = 0; i < sizeof(u16); i++) {		/* Disable interrupts which might cause a timeout here */		flag = disable_interrupts();		base[FLASH_CYCLE1] = (u8) 0x00AA00AA;	/* unlock */		base[FLASH_CYCLE2] = (u8) 0x00550055;	/* unlock */		base[FLASH_CYCLE1] = (u8) 0x00A000A0;	/* selects program mode */		*dest = data;	/* start programming the data */		/* re-enable interrupts if necessary */		if (flag)			enable_interrupts();		start = get_timer(0);		/* data polling for D7 */		while (res == 0		       && (*dest & (u8) 0x00800080) !=		       (data & (u8) 0x00800080)) {			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {				*dest = (u8) 0x00F000F0;	/* reset bank */				res = 1;			}		}		*dest++ = (u8) 0x00F000F0;	/* reset bank */		data >>= 8;	}	return (res);}void inline spin_wheel(void){	static int p = 0;	static char w[] = "\\/-";	printf("\010%c", w[p]);	(++p == 3) ? (p = 0) : 0;}#ifdef CFG_FLASH_PROTECTION/*----------------------------------------------------------------------- */int flash_real_protect(flash_info_t * info, long sector, int prot){	int rcode = 0;		/* assume success */	FPWV *addr;		/* address of sector */	FPW value;	addr = (FPWV *) (info->start[sector]);	switch (info->flash_id & FLASH_TYPEMASK) {	case FLASH_28F160C3B:	case FLASH_28F160C3T:	case FLASH_28F320C3B:	case FLASH_28F320C3T:	case FLASH_28F640C3B:	case FLASH_28F640C3T:		*addr = (FPW) INTEL_RESET;	/* make sure in read mode */		*addr = (FPW) INTEL_LOCKBIT;	/* lock command setup */		if (prot)			*addr = (FPW) INTEL_PROTECT;	/* lock sector */		else			*addr = (FPW) INTEL_CONFIRM;	/* unlock sector */		/* now see if it really is locked/unlocked as requested */		*addr = (FPW) INTEL_READID;		/* read sector protection at sector address, (A7 .. A0) = 0x02.		 * D0 = 1 for each device if protected.		 * If at least one device is protected the sector is marked		 * protected, but return failure. Mixed protected and		 * unprotected devices within a sector should never happen.		 */		value = addr[2] & (FPW) INTEL_PROTECT;		if (value == 0)			info->protect[sector] = 0;		else if (value == (FPW) INTEL_PROTECT)			info->protect[sector] = 1;		else {			/* error, mixed protected and unprotected */			rcode = 1;			info->protect[sector] = 1;		}		if (info->protect[sector] != prot)			rcode = 1;	/* failed to protect/unprotect as requested */		/* reload all protection bits from hardware for now */		flash_sync_real_protect(info);		break;	default:		/* no hardware protect that we support */		info->protect[sector] = prot;		break;	}	return rcode;}#endif#endif

⌨️ 快捷键说明

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