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

📄 flash.c

📁 U BOOT源码
💻 C
📖 第 1 页 / 共 2 页
字号:
{	int flag, prot, sect;	ulong start, now, last;	if ((s_first < 0) || (s_first > s_last)) {		if (info->flash_id == FLASH_UNKNOWN) {			printf ("- missing\n");		} else {			printf ("- no sectors to erase\n");		}		return 1;	}	if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {		printf ("Can erase only Intel flash types - aborted\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 {		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 */			vu_char *addr = (uchar *)(info->start[sect]);			vu_char status;			/*			 * Disable interrupts which might cause a timeout			 */			flag = disable_interrupts();			*addr = SCS_CLEAR_STATUS_CMD;			*addr = SCS_BLOCK_ERASE_CMD;			*addr = SCS_BLOCK_ERASE_RESUME_CMD;			/*			 * Re-enable interrupts if necessary			 */			if (flag)				enable_interrupts();			/*			 * Wait at least 80us - let's wait 1 ms			 */			udelay (1000);			while (((status = *addr) & SCS_SR7) != SCS_SR7) {				if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {					printf ("Timeout\n");					*addr = SCS_BLOCK_ERASE_SUSPEND_CMD;					*addr = SCS_READ_CMD;					return 1;				}				/*				 * Show that we're waiting				 */				if ((now - last) > 1000) {	/* 1 second */					putc ('.');					last = now;				}			}			*addr = SCS_READ_CMD;		}	}	printf (" done\n");	return 0;}#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER/* * Allocate a flash buffer, fill it with data and write it to the flash. * 0 - OK * 1 - Timeout on buffer request * * NOTE: After the last call to this function, WSM status needs to be checked! */static intwrite_flash_buffer8(flash_info_t *info_p, vu_char *src_p, vu_char *dest_p,				    uint count){	vu_char *block_addr_p = NULL;	vu_char *start_addr_p = NULL;	ulong blocksize = info_p->size / (ulong)info_p->sector_count;	int i;	uint time = get_timer(0);	PRINTF("%s:%d: src: 0x%p dest: 0x%p  count: %d\n",		   __FUNCTION__, __LINE__, src_p, dest_p, count);	/*	 * What block are we in? We already know that the source address is	 * in the flash address range, but we also can't cross a block boundary.	 * We assume that the block does not cross a boundary (we'll check before	 * calling this function).	 */ 	for (i = 0; i < info_p->sector_count; ++i) {		if ( ((ulong)dest_p >= info_p->start[i]) &&		    ((ulong)dest_p < (info_p->start[i] + blocksize)) ) {			PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",				   __FUNCTION__, __LINE__, dest_p, i, info_p->start[i]);			block_addr_p = (vu_char *)info_p->start[i];			break;		}	}	/*	 * Request a buffer	 */	*block_addr_p = SCS_WRITE_BUF_CMD;	while ((*block_addr_p & SCS_XSR7) != SCS_XSR7) {		if (get_timer(time) >  CFG_FLASH_ALLOC_BUFFER_TOUT) {			PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",				   __FUNCTION__, __LINE__, block_addr_p,				   CFG_FLASH_ALLOC_BUFFER_TOUT);			return 1;		}		*block_addr_p = SCS_WRITE_BUF_CMD;	}	/*	 * Fill the buffer with data	 */	start_addr_p = dest_p;	*block_addr_p = count - 1; /* flash device wants count - 1 */	PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",		   __FUNCTION__, __LINE__, block_addr_p);	for (i = 0; i < count; i++) {		*start_addr_p++ = *src_p++;	}	/*	 * Flush buffer to flash	 */	*block_addr_p = SCS_PROGRAM_RESUME_CMD;#if 1	time = get_timer(0);	while ((*block_addr_p & SCS_SR7) != SCS_SR7) {		if (get_timer(time) >  CFG_FLASH_WRITE_TOUT) {			PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",				   __FUNCTION__, __LINE__, block_addr_p, CFG_FLASH_WRITE_TOUT);			return 1;		}	}#endif	return 0;}#endif/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased * 4 - Flash not identified */intwrite_buff(flash_info_t *info_p, uchar *src_p, ulong addr, ulong count){	int rc = 0;#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER#define FLASH_WRITE_BUF_SIZE	0x00000020	/* 32 bytes */	int i;	uint bufs;	ulong buf_count;	vu_char *sp;	vu_char *dp;#else	ulong wp;#endif	PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",		   __FUNCTION__, __LINE__, (ulong)src_p, addr, (uint)count, count);	if (info_p->flash_id == FLASH_UNKNOWN) {		return 4;	}#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER	sp = src_p;	dp = (uchar *)addr;	/*	 * For maximum performance, we want to align the start address to	 * the beginning of a write buffer boundary (i.e. A4-A0 of the	 * start address = 0). See how many bytes are required to get to a	 * write-buffer-aligned address.  If that number is non-zero, do	 * non buffered writes of the non-aligned data.  By doing non-buffered	 * writes, we avoid the problem of crossing a block (sector) boundary	 * with buffered writes.	 */	buf_count = FLASH_WRITE_BUF_SIZE - (addr & (FLASH_WRITE_BUF_SIZE - 1));	if (buf_count == FLASH_WRITE_BUF_SIZE) { /* already on a boundary */		buf_count = 0;	}	if (buf_count > count) { /* not a full buffers worth of data to write */		buf_count = count;	}	count -= buf_count;	PRINTF("%s:%d: Write buffer alignment count = %ld\n",		   __FUNCTION__, __LINE__, buf_count);	while (buf_count-- >= 1) {		if ((rc = write_data8(info_p, (ulong)dp++, *sp++)) != 0)  {			return (rc);		}	}	PRINTF("%s:%d: count = %ld\n", __FUNCTION__, __LINE__, count);	if (count == 0) { /* all done */		PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",			   __FUNCTION__, __LINE__, FLASH_WRITE_BUF_SIZE);		return (rc);	}	/*	 * Now that we are write buffer aligned, write full or partial buffers.	 * The fact that we are write buffer aligned automatically avoids	 * crossing a block address during a write buffer operation.	 */	bufs = count / FLASH_WRITE_BUF_SIZE;	PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__, __LINE__,		   bufs, bufs);	while (bufs >= 1) {		rc = write_flash_buffer8(info_p, sp, dp, FLASH_WRITE_BUF_SIZE);		if (rc != 0) {			PRINTF("%s:%d: ** Error writing buf %d\n",				   __FUNCTION__, __LINE__, bufs);			return (rc);		}		bufs--;		sp += FLASH_WRITE_BUF_SIZE;		dp += FLASH_WRITE_BUF_SIZE;	}	/*	 * Do the leftovers	 */	i = count % FLASH_WRITE_BUF_SIZE;	PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__, __LINE__, i, i);	if (i > 0) {		rc = write_flash_buffer8(info_p, sp, dp, i);	}	sp = (vu_char*)info_p->start[0];	*sp = SCS_READ_CMD;	return (rc);#else	wp = addr;	while (count-- >= 1) {		if((rc = write_data8(info_p, wp++, *src_p++)) != 0)			return (rc);	}	return 0;#endif}/*----------------------------------------------------------------------- * Write a byte to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */static intwrite_data8 (flash_info_t *info, ulong dest, uchar data){	vu_char *addr = (vu_char *)dest;	vu_char status;	ulong start;	int flag;	/* Check if Flash is (sufficiently) erased */	if ((*addr & data) != data) {		return (2);	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();	*addr = SCS_PROGRAM_CMD;	*addr = data;	/* re-enable interrupts if necessary */	if (flag)		enable_interrupts();	start = get_timer (0);	while (((status = *addr) & SCS_SR7) != SCS_SR7) {		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {			*addr = SCS_READ_CMD;			return (1);		}	}	*addr = SCS_READ_CMD;	return (0);}/* vim: set ts=4 sw=4 tw=78: */

⌨️ 快捷键说明

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