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

📄 flash.c

📁 omap osk环境下的bootloader,包含完整的uboot源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	ulong mask;	int timeout;	if (info->portwidth == 4)/*		{		printf ("- Warning: erasing of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");		return 1;		}*/	{		/* make sure it's Intel flash */		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {			/* yup! it's an Intel flash */			/* is it 16-bits wide? */			if (info->chipwidth == 2) {				/* yup! it's 16-bits wide */				/* are there any sectors to process? */				if ((s_first < 0) || (s_first > s_last)) {					printf ("Error:  There are no sectors to erase\n");					printf ("Either sector %d is less than zero\n", s_first);					printf ("or sector %d is greater than sector %d\n", s_first, s_last);					return 1;				}				/* check for protected sectors */				prot = 0;				for (sect = s_first; sect <= s_last; ++sect)					if (info->protect[sect])						prot++;				/* if variable "prot" is nonzero, there are protected sectors */				if (prot)					printf ("- Warning: %d protected sectors will not be erased!\n", prot);				/* reset the flash */				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_RST);				/* Disable interrupts which might cause a timeout here */				flag = disable_interrupts ();				/* Clear the status register */				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_CLR_STAT);				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_RST);				/* Start erase on unprotected sectors */				for (sect = s_first; sect <= s_last; sect++) {					/* is the sector unprotected? */					if (info->protect[sect] == 0) {	/* not protected */						/* issue the single block erase command, 0x20 */						flash_cmd (info->portwidth,							   (volatile unsigned							    char *) info->							   start[sect], 0,							   CHIP_CMD_ERASE1);						/* issue the erase confirm command, 0xD0 */						flash_cmd (info->portwidth,							   (volatile unsigned							    char *) info->							   start[sect], 0,							   CHIP_CMD_ERASE2);						l_sect = sect;						/* re-enable interrupts if necessary */						if (flag)							enable_interrupts ();						/* poll for erasure completion */						/* put flash into read status mode by writing 0x70 to it */						flash_cmd (info->portwidth,							   addr, 0,							   CHIP_CMD_RD_STAT);						/* setup the status register mask */						mask = CHIP_STAT_RDY |							(CHIP_STAT_RDY << 16);						/* init. the timeout counter */						start = get_timer (0);						/* keep looping while the flash is not ready */						/* exit the loop by timing out or the flash */						/* becomes ready again */						timeout = 0;						while ((*							(volatile unsigned							 long *) info->							start[sect] & mask) !=						       mask) {							/* has the timeout limit been reached? */							if (get_timer (start)							    >							    CFG_FLASH_ERASE_TOUT)							{								/* timeout limit reached */								printf ("Time out limit reached erasing sector at address %08lx\n", info->start[sect]);								printf ("Continuing with next sector\n");								timeout = 1;								goto timed_out_error;							}							/* put flash into read status mode by writing 0x70 to it */							flash_cmd (info->								   portwidth,								   addr, 0,								   CHIP_CMD_RD_STAT);						}						/* did we timeout? */					      timed_out_error:if (timeout == 0)						{							/* didn't timeout, so check the status register */							/* create the status mask to check for errors */							mask = CHIP_STAT_ECLBS;							mask = mask | (mask <<								       16);							/* put flash into read status mode by writing 0x70 to it */							flash_cmd (info->								   portwidth,								   addr, 0,								   CHIP_CMD_RD_STAT);							/* are there any errors? */							if ((*							     (volatile							      unsigned long *)							     info->							     start[sect] &							     mask) != 0) {								/* We got an erasure error */								printf ("Flash erasure error at address 0x%08lx\n", info->start[sect]);								printf ("Continuing with next sector\n");								/* reset the flash */								flash_cmd									(info->									 portwidth,									 addr,									 0,									 CHIP_CMD_RST);							}						}						/* erasure completed without errors */						/* reset the flash */						flash_cmd (info->portwidth,							   addr, 0,							   CHIP_CMD_RST);					}	/* end if not protected */				}	/* end for loop */				printf ("Flash erasure done\n");				return 0;			} else {				/* The Intel flash is not 16-bit wide */				/* print and error message and return */				/* NOTE: you can add routines here to handle other size flash */				printf ("Error: Intel flash device is only %d-bits wide\n", info->chipwidth * 8);				printf ("The erasure code only handles Intel 16-bit wide flash memory\n");				return 1;			}		} else {			/* Not Intel flash so return an error as a write timeout */			/* NOTE: if it's another type flash, stick its routine here */			printf ("Error: The flash device is not Intel type\n");			printf ("The erasure code only supports Intel flash in a 32-bit port width\n");			return 1;		}	}	/* end 32-bit wide flash code */	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)		return 1;	/* Rom can not be erased */	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {	/* RAM just copy 0s to RAM */		for (sect = s_first; sect <= s_last; sect++) {			int sector_size = info->size / info->sector_count;			addr = (char *) (info->start[sect]);			memset ((void *) addr, 0, sector_size);		}		return 0;	}	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) {	/* Intel works spezial */		return flash_erase_intel (info,					  (unsigned short) s_first,					  (unsigned short) s_last);	}#if 0	if ((info->flash_id == FLASH_UNKNOWN) ||	/* Flash is unknown to PPCBoot */	    (info->flash_id > FLASH_AMD_COMP)) {		printf ("Can't erase unknown flash type %08lx - aborted\n",			info->flash_id);		return 1;	}#endif	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");	}	l_sect = -1;	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts ();	flash_cmd (info->portwidth, addr, 0x555, 0xAA);	/* start erase routine */	flash_cmd (info->portwidth, addr, 0x2AA, 0x55);	flash_cmd (info->portwidth, addr, 0x555, 0x80);	flash_cmd (info->portwidth, addr, 0x555, 0xAA);	flash_cmd (info->portwidth, addr, 0x2AA, 0x55);	/* Start erase on unprotected sectors */	for (sect = s_first; sect <= s_last; sect++) {		if (info->protect[sect] == 0) {	/* not protected */			addr = (char *) (info->start[sect]);			flash_cmd (info->portwidth, addr, 0, 0x30);			l_sect = sect;		}	}	/* re-enable interrupts if necessary */	if (flag)		enable_interrupts ();	/* wait at least 80us - let's wait 1 ms */	udelay (1000);	/*	 * We wait for the last triggered sector	 */	if (l_sect < 0)		goto DONE;	start = get_timer (0);	last = start;	addr = (volatile unsigned char *) (info->start[l_sect]);	/* broken for 2x16: TODO */	while ((addr[0] & 0x80) != 0x80) {		if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {			printf ("Timeout\n");			return 1;		}		/* show that we're waiting */		if ((now - last) > 1000) {	/* every second */			putc ('.');			last = now;		}	}      DONE:	/* reset to read mode */	addr = (volatile unsigned char *) info->start[0];	flash_cmd (info->portwidth, addr, 0, 0xf0);	flash_cmd (info->portwidth, addr, 0, 0xf0);	printf (" done\n");	return 0;}/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased *//* broken for 2x16: TODO */int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt){	ulong cp, wp, data;	int i, l, rc;/* Commented out since the below code should work for 32-bit(2x 16 flash) *//* 10-16-2002 P. Marchese *//*	if(info->portwidth==4) return 1; *//*	if(info->portwidth==4) {		printf ("- Warning: writting of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");		return 1;		}*/	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)		return 0;	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {		memcpy ((void *) addr, src, cnt);		return 0;	}	wp = (addr & ~3);	/* get lower word aligned address */	/*	 * 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 < 4 && cnt > 0; ++i) {			data = (data << 8) | *src++;			--cnt;			++cp;		}		for (; cnt == 0 && i < 4; ++i, ++cp) {			data = (data << 8) | (*(uchar *) cp);		}		if ((rc = write_word (info, wp, data)) != 0) {			return (rc);		}		wp += 4;	}	/*	 * handle word aligned part	 */	while (cnt >= 4) {		data = 0;		for (i = 0; i < 4; ++i) {			data = (data << 8) | *src++;		}		if ((rc = write_word (info, wp, data)) != 0) {			return (rc);		}		wp += 4;		cnt -= 4;	}	if (cnt == 0) {		return (0);	}	/*	 * handle unaligned tail bytes	 */	data = 0;	for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {		data = (data << 8) | *src++;		--cnt;	}	for (; i < 4; ++i, ++cp) {		data = (data << 8) | (*(uchar *) cp);	}	return (write_word (info, wp, data));}/*----------------------------------------------------------------------- * Write a word to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased *//* broken for 2x16: TODO */static int write_word (flash_info_t * info, ulong dest, ulong data){	volatile unsigned char *addr = (char *) (info->start[0]);	ulong start;	int flag, i;	ulong mask;/* modified so that it handles 32-bit(2x16 Intel flash programming *//* 10-16-2002 P. Marchese */	if (info->portwidth == 4)/*		{		printf ("- Warning: writting of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");		return 1;		}*/	{		/* make sure it's Intel flash */		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {			/* yup! it's an Intel flash */			/* is it 16-bits wide? */			if (info->chipwidth == 2) {				/* yup! it's 16-bits wide */				/* so we know how to program it */				/* reset the flash */				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_RST);				/* Disable interrupts which might cause a timeout here */				flag = disable_interrupts ();				/* Clear the status register */				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_CLR_STAT);				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_RST);				/* 1st cycle of word/byte program */				/* write 0x40 to the location to program */				flash_cmd (info->portwidth, (char *) dest, 0,					   CHIP_CMD_PROG);				/* 2nd cycle of word/byte program */				/* write the data to the destination address */				*(ulong *) dest = data;				/* re-enable interrupts if necessary */				if (flag)					enable_interrupts ();				/* setup the status register mask */				mask = CHIP_STAT_RDY | (CHIP_STAT_RDY << 16);				/* put flash into read status mode by writing 0x70 to it */				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_RD_STAT);				/* init. the timeout counter */				start = get_timer (0);				/* keep looping while the flash is not ready */				/* exit the loop by timing out or the flash */				/* becomes ready again *//* 11-13-2002 Paul Marchese *//* modified while loop conditional statement *//* because we were always timing out.  *//* there is a type mismatch, "addr[0]" *//* returns a byte but "mask" is a 32-bit value */				while ((*(volatile unsigned long *) info->					start[0] & mask) != mask)/* original code *//* while (addr[0] & mask) != mask) */				{					/* has the timeout limit been reached? */					if (get_timer (start) >					    CFG_FLASH_WRITE_TOUT) {						/* timeout limit reached */						printf ("Time out limit reached programming address %08lx with data %08lx\n", dest, data);						/* reset the flash */						flash_cmd (info->portwidth,							   addr, 0,							   CHIP_CMD_RST);						return (1);					}					/* put flash into read status mode by writing 0x70 to it */					flash_cmd (info->portwidth, addr, 0,						   CHIP_CMD_RD_STAT);				}				/* flash is ready, so check the status */				/* create the status mask to check for errors */				mask = CHIP_STAT_DPS | CHIP_STAT_VPPS |					CHIP_STAT_PSLBS;				mask = mask | (mask << 16);				/* put flash into read status mode by writing 0x70 to it */				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_RD_STAT);				/* are there any errors? */				if ((addr[0] & mask) != 0) {					/* We got a one of the following errors: */					/* Voltage range, Device protect, or programming */					/* return the error as a device timeout */					/* put flash into read status mode by writing 0x70 to it */					flash_cmd (info->portwidth, addr, 0,						   CHIP_CMD_RD_STAT);					printf ("Flash programming error at address 0x%08lx\n", dest);					printf ("Flash status register contains 0x%08lx\n", (unsigned long) addr[0]);					/* reset the flash */					flash_cmd (info->portwidth, addr, 0,						   CHIP_CMD_RST);					return 1;				}				/* write completed without errors */				/* reset the flash */				flash_cmd (info->portwidth, addr, 0,					   CHIP_CMD_RST);				return 0;			} else {				/* it's not 16-bits wide, so return an error as a write timeout */				/* NOTE: you can add routines here to handle other size flash */				printf ("Error: Intel flash device is only %d-bits wide\n", info->chipwidth * 8);				printf ("The write code only handles Intel 16-bit wide flash memory\n");				return 1;			}		} else {			/* not Intel flash so return an error as a write timeout */			/* NOTE: if it's another type flash, stick its routine here */			printf ("Error: The flash device is not Intel type\n");			printf ("The code only supports Intel flash in a 32-bit port width\n");			return 1;		}	}	/* end of 32-bit flash code */	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)		return 1;	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {		*(unsigned long *) dest = data;		return 0;	}	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {		unsigned short low = data & 0xffff;		unsigned short hi = (data >> 16) & 0xffff;		int ret = write_word_intel ((bank_addr_t) dest, hi);		if (!ret)			ret = write_word_intel ((bank_addr_t) (dest + 2),						low);		return ret;	}	/* Check if Flash is (sufficiently) erased */	if ((*((vu_long *) dest) & data) != data) {		return (2);	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts ();	/* first, perform an unlock bypass command to speed up flash writes */	addr[0x555] = 0xAA;	addr[0x2AA] = 0x55;	addr[0x555] = 0x20;	/* write each byte out */	for (i = 0; i < 4; i++) {		char *data_ch = (char *) &data;		addr[0] = 0xA0;		*(((char *) dest) + i) = data_ch[i];		udelay (10);	/* XXX */	}	/* we're done, now do an unlock bypass reset */	addr[0] = 0x90;	addr[0] = 0x00;	/* re-enable interrupts if necessary */	if (flag)		enable_interrupts ();	/* data polling for D7 */	start = get_timer (0);	while ((*((vu_long *) dest) & 0x00800080) != (data & 0x00800080)) {		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {			return (1);		}	}	return (0);}

⌨️ 快捷键说明

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