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

📄 flash.c

📁 u-boot-1.1.6 源码包
💻 C
📖 第 1 页 / 共 2 页
字号:
				base = (FPWV *) (CFG_AMD_BASE);				base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;	/* unlock */				base[FLASH_CYCLE2] = (FPW) 0x00550055;	/* unlock */				base[FLASH_CYCLE1] = (FPW) 0x00800080;	/* erase mode */				base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;	/* unlock */				base[FLASH_CYCLE2] = (FPW) 0x00550055;	/* unlock */				*addr = (FPW) 0x00300030;	/* erase sector */			}			while (((status =				 *addr) & (FPW) 0x00800080) !=			       (FPW) 0x00800080) {				if (get_timer (start) > CFG_FLASH_ERASE_TOUT) {					printf ("Timeout\n");					if (intel) {						*addr = (FPW) 0x00B000B0;	/* suspend erase     */						*addr = (FPW) 0x00FF00FF;	/* reset to read mode */					} else						*addr = (FPW) 0x00F000F0;	/* reset to read mode */					rcode = 1;					break;				}			}			if (intel) {				*addr = (FPW) 0x00500050;	/* clear status register cmd.   */				*addr = (FPW) 0x00FF00FF;	/* resest to read mode          */			} else				*addr = (FPW) 0x00F000F0;	/* reset to read mode */			printf (" done\n");		}	}	return rcode;}/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased * 4 - Flash not identified */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_AMD:	    {		FPW data = 0;	/* 16 or 32 bit word, matches flash bus width */		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++;			}			res = write_word_amd (info, (FPWV *) addr,					      data);		}		return res;	    }		/* case FLASH_MAN_AMD */	case FLASH_MAN_INTEL:	    {		ulong cp, wp;		FPW data;		int count, i, l, rc, port_width;		/* get lower word aligned address */		wp = addr;		port_width = 1;		/*		 * 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, SWAP (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;				}			}		}		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, wp,						 SWAP (data))) != 0)					return (rc);				wp += port_width;				cnt -= port_width;				if (count++ > 0x800) {					spin_wheel ();					count = 0;				}			}		}		if (cnt == 0)			return (0);		/*		 * 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, wp, SWAP (data)));	    }		/* case FLASH_MAN_INTEL */	}			/* switch */	return (0);}/*----------------------------------------------------------------------- * Write a word or halfword to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */static 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, *addr);		return (2);	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts ();	*addr = (FPW) 0x00400040;	/* write setup */	*addr = data;	/* arm simple, non interrupt dependent timer */	start = get_timer (0);	/* wait while polling the status register */	while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {			*addr = (FPW) 0x00FF00FF;	/* restore read mode */			return (1);		}	}	*addr = (FPW) 0x00FF00FF;	/* restore read mode */	return (0);}/*----------------------------------------------------------------------- * Write a word or halfword to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */static 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) 0x00e800e8;	/* write block setup */	/* arm simple, non interrupt dependent timer */	start = get_timer (0);	/* wait while polling the status register */	while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {			*dstaddr = (FPW) 0x00FF00FF;	/* restore read mode */			return (1);		}	}	*dstaddr = (FPW) 0x001f001f;	/* write 32 to buffer */	for (i = 0; i < WR_BLOCK; i++)		*dstaddr++ = *srcaddr++;	dstaddr -= 1;	*dstaddr = (FPW) 0x00d000d0;	/* write 32 to buffer */	/* arm simple, non interrupt dependent timer */	start = get_timer (0);	/* wait while polling the status register */	while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {			*dstaddr = (FPW) 0x00FF00FF;	/* restore read mode */			return (1);		}	}	*dstaddr = (FPW) 0x00FF00FF;	/* restore read mode */	return (0);}/*----------------------------------------------------------------------- * Write a word to Flash for AMD FLASH * A word is 16 or 32 bits, whichever the bus width of the flash bank * (not an individual chip) is. * * returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data){	ulong start;	int flag;	int res = 0;		/* result, assume success */	FPWV *base;		/* first address in flash bank */	/* Check if Flash is (sufficiently) erased */	if ((*dest & data) != data) {		return (2);	}	base = (FPWV *) (CFG_AMD_BASE);	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts ();	base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;	/* unlock */	base[FLASH_CYCLE2] = (FPW) 0x00550055;	/* unlock */	base[FLASH_CYCLE1] = (FPW) 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 & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {			*dest = (FPW) 0x00F000F0;	/* reset bank */			res = 1;		}	}	return (res);}void inline spin_wheel (void){	static int p = 0;	static char w[] = "\\/-";	printf ("\010%c", w[p]);	(++p == 3) ? (p = 0) : 0;}/*----------------------------------------------------------------------- * Set/Clear sector's lock bit, returns: * 0 - OK * 1 - Error (timeout, voltage problems, etc.) */int flash_real_protect (flash_info_t * info, long sector, int prot){	ulong start;	int i, j;	int curr_bank;	int bank;	int rc = 0;	FPWV *addr = (FPWV *) (info->start[sector]);	int flag = disable_interrupts ();	/*	 * 29F040B AMD flash does not support software protection/unprotection,	 * the only way to protect the AMD flash is marked it as prot bit.	 * This flash only support hardware protection, by supply or not supply	 * 12vpp to the flash	 */	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {		info->protect[sector] = prot;		return 0;	}	*addr = INTEL_CLEAR;	/* Clear status register    */	if (prot) {		/* Set sector lock bit      */		*addr = INTEL_LOCKBIT;	/* Sector lock bit          */		*addr = INTEL_PROTECT;	/* set                      */	} else {		/* Clear sector lock bit    */		*addr = INTEL_LOCKBIT;	/* All sectors lock bits    */		*addr = INTEL_CONFIRM;	/* clear                    */	}	start = get_timer (0);	while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {		if (get_timer (start) > CFG_FLASH_UNLOCK_TOUT) {			printf ("Flash lock bit operation timed out\n");			rc = 1;			break;		}	}	if (*addr != INTEL_OK) {		printf ("Flash lock bit operation failed at %08X, CSR=%08X\n",			(uint) addr, (uint) * addr);		rc = 1;	}	if (!rc)		info->protect[sector] = prot;	/*	 * Clear lock bit command clears all sectors lock bits, so	 * we have to restore lock bits of protected sectors.	 */	if (!prot) {		/*		 * re-locking must be done for all banks that belong on one		 * FLASH chip, as all the sectors on the chip were unlocked		 * by INTEL_LOCKBIT/INTEL_CONFIRM commands. (let's hope		 * that banks never span chips, in particular chips which		 * support h/w protection differently).		 */		/* find the current bank number */		curr_bank = CFG_MAX_FLASH_BANKS + 1;		for (j = 0; j < CFG_MAX_FLASH_BANKS; ++j) {			if (&flash_info[j] == info) {				curr_bank = j;			}		}		if (curr_bank == CFG_MAX_FLASH_BANKS + 1) {			printf("Error: can't determine bank number!\n");		}		for (bank = 0; bank < CFG_MAX_FLASH_BANKS; ++bank) {			if (!same_chip_banks(curr_bank, bank)) {				continue;			}			info = &flash_info[bank];			for (i = 0; i < info->sector_count; i++) {				if (info->protect[i]) {					start = get_timer (0);					addr = (FPWV *) (info->start[i]);					*addr = INTEL_LOCKBIT;	/* Sector lock bit  */					*addr = INTEL_PROTECT;	/* set              */					while ((*addr & INTEL_FINISHED) !=					       INTEL_FINISHED) {						if (get_timer (start) >						    CFG_FLASH_UNLOCK_TOUT) {							printf ("Flash lock bit operation timed out\n");							rc = 1;							break;						}					}				}			}		}		/*		 * get the s/w sector protection status in sync with the h/w,		 * in case something went wrong during the re-locking.		 */		flash_sync_real_protect(info); /* resets flash to read  mode */	}	if (flag)		enable_interrupts ();	*addr = INTEL_RESET;	/* Reset to read array mode */	return rc;}

⌨️ 快捷键说明

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