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

📄 flash.c

📁 AT91RM9200的完整启动代码:包括loader, boot及U-boot三部分均已编译通过!欢迎下载使用!
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* check for protected sectors */	for (i = 0; i < info->sector_count; i++) {		/* read sector protection at sector address, (A7 .. A0) = 0x02 */		/* D0 = 1 if protected */		addr = (volatile unsigned long *)(info->start[i]);		info->protect[i] = addr[2] & 1;	}	/*	 * Prevent writes to uninitialized FLASH.	 */	if (info->flash_id != FLASH_UNKNOWN) {		addr = (volatile unsigned long *)info->start[0];		*addr = 0x00F000F0;	/* reset bank */	}	return (info->size);}#endif/*----------------------------------------------------------------------- */int	flash_erase (flash_info_t *info, int s_first, int s_last){	vu_long *addr = (vu_long*)(info->start[0]);	int flag, prot, sect, l_sect,in_mid,in_did;	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_UNKNOWN) ||	    (info->flash_id > FLASH_AMD_COMP)) {		printf ("Can't erase unknown flash type %08lx - aborted\n",			info->flash_id);		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");	}	l_sect = -1;	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();#if defined (CONFIG_BOOT_8B )	my_out_8( (unsigned char * )  ((ulong)addr+0x555) , 0xaa );	my_out_8( (unsigned char * )  ((ulong)addr+0x2aa) , 0x55 );	my_out_8( (unsigned char * )  ((ulong)addr+0x555) , 0x90 );	in_mid=my_in_8( (unsigned char * ) addr );	in_did=my_in_8( (unsigned char * ) ((ulong)addr+1) );	printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );	my_out_8( (unsigned char *)addr, 0xf0);	udelay(1);	my_out_8(     (unsigned char *) ((ulong)addr+0x555),0xaa );	my_out_8(     (unsigned char *) ((ulong)addr+0x2aa),0x55 );	my_out_8(     (unsigned char *) ((ulong)addr+0x555),0x80 );	my_out_8(     (unsigned char *) ((ulong)addr+0x555),0xaa );	my_out_8(     (unsigned char *) ((ulong)addr+0x2aa),0x55 );	/* Start erase on unprotected sectors */	for (sect = s_first; sect<=s_last; sect++) {		if (info->protect[sect] == 0) {	/* not protected */			addr = (vu_long*)(info->start[sect]);			//addr[0] = 0x00300030;			my_out_8(     (unsigned char *) ((ulong)addr),0x30 );			l_sect = sect;		}	}#elif defined(CONFIG_BOOT_16B )	my_out_be16( (unsigned short * )  ((ulong)addr+ (0xaaa)) , 0xaa );	my_out_be16( (unsigned short * )  ((ulong)addr+ (0x554)) , 0x55 );	my_out_be16( (unsigned short * )  ((ulong)addr+ (0xaaa)) , 0x90 );	in_mid=my_in_be16( (unsigned short * ) addr );	in_did=my_in_be16 ( (unsigned short * ) ((ulong)addr+2) );	printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );	my_out_be16( (unsigned short *)addr, 0xf0);	udelay(1);	my_out_be16(     (unsigned short *) ((ulong)addr+ 0xaaa),0xaa );	my_out_be16(     (unsigned short *) ((ulong)addr+0x554),0x55 );	my_out_be16(     (unsigned short *) ((ulong)addr+0xaaa),0x80 );	my_out_be16(     (unsigned short *) ((ulong)addr+0xaaa),0xaa );	my_out_be16(     (unsigned short *) ((ulong)addr+0x554),0x55 );	/* Start erase on unprotected sectors */	for (sect = s_first; sect<=s_last; sect++) {		if (info->protect[sect] == 0) {	/* not protected */			addr = (vu_long*)(info->start[sect]);			my_out_be16(     (unsigned short *) ((ulong)addr),0x30 );			l_sect = sect;		}	}#elif defined(CONFIG_BOOT_32B)	my_out_be32( (unsigned * )  ((ulong)addr+0x1554) , 0xaa );	my_out_be32( (unsigned * )  ((ulong)addr+0xaa8) , 0x55 );	my_out_be32( (unsigned  *)  ((ulong)addr+0x1554) , 0x90 );	in_mid=my_in_be32( (unsigned  * ) addr );	in_did=my_in_be32( (unsigned  * ) ((ulong)addr+4) );	printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );	my_out_be32( (unsigned *)addr, 0xf0);	udelay(1);	my_out_be32(     (unsigned  *) ((ulong)addr+0x1554),0xaa );	my_out_be32(     (unsigned  *) ((ulong)addr+0xaa8),0x55 );	my_out_be32(     (unsigned  *) ((ulong)addr+0x1554),0x80 );	my_out_be32(     (unsigned  *) ((ulong)addr+0x1554),0xaa );	my_out_be32(     (unsigned  *) ((ulong)addr+0xaa8),0x55 );	/* Start erase on unprotected sectors */	for (sect = s_first; sect<=s_last; sect++) {		if (info->protect[sect] == 0) {	/* not protected */			addr = (vu_long*)(info->start[sect]);			my_out_be32(     (unsigned *) ((ulong)addr),0x00300030 );			l_sect = sect;		}	}#else# error CONFIG_BOOT_(size)B missing.#endif	/* 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 = (vu_long*)(info->start[l_sect]);#if defined (CONFIG_BOOT_8B)	while (  (my_in_8((unsigned char *)addr) & 0x80) != 0x80 ) #elif defined(CONFIG_BOOT_16B )	while (  (my_in_be16((unsigned short *)addr) & 0x0080) != 0x0080 ) #elif defined(CONFIG_BOOT_32B)	while (  (my_in_be32((unsigned  *)addr) & 0x00800080) != 0x00800080 ) #else# error CONFIG_BOOT_(size)B missing.#endif	{		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 long *)info->start[0];#if defined (CONFIG_BOOT_8B)	my_out_8( (unsigned char *)addr, 0xf0);#elif defined(CONFIG_BOOT_16B )	my_out_be16( (unsigned short * ) addr , 0x00f0 );#elif defined(CONFIG_BOOT_32B)	my_out_be32 ( (unsigned *)addr,  0x00F000F0 );	/* reset bank */#else# error CONFIG_BOOT_(size)B missing.#endif	printf (" done\n");	return 0;}/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt){	ulong cp, wp, data;	int i, l, rc;	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 */static int write_word (flash_info_t *info, ulong dest, ulong data){	ulong addr = (ulong)(info->start[0]);	ulong start,last;	int flag;	ulong i;	int  data_short[2];	/* Check if Flash is (sufficiently) erased */	if ( ((ulong)  *(ulong *)dest & data) != data ) {		return (2);	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();#if defined(CONFIG_BOOT_8B)#ifdef DEBUG	{	int in_mid,in_did;	my_out_8( (unsigned char * )  (addr+0x555) , 0xaa );	my_out_8( (unsigned char * )  (addr+0x2aa) , 0x55 );	my_out_8( (unsigned char * )  (addr+0x555) , 0x90 );	in_mid=my_in_8( (unsigned char * ) addr );	in_did=my_in_8( (unsigned char * ) (addr+1) );  	printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );	my_out_8( (unsigned char *)addr, 0xf0);	udelay(1);	}#endif      {	int  data_ch[4];	data_ch[0]=(int ) ((data>>24) & 0xff);	data_ch[1]=(int ) ((data>>16) &0xff ); 	data_ch[2]=(int ) ((data >>8) & 0xff);	data_ch[3]=(int ) (data & 0xff);	for (i=0;i<4;i++ ){	  my_out_8( (unsigned char *) (addr+0x555),0xaa);	  my_out_8((unsigned char *) (addr+0x2aa),0x55);	  my_out_8( (unsigned char *)  (addr+0x555),0xa0);	  my_out_8((unsigned char *)  (dest+i) ,data_ch[i]);	/* re-enable interrupts if necessary */	if (flag)		enable_interrupts();  	  start = get_timer (0);	last  = start;	  while(  ( my_in_8((unsigned char *) (dest+i)) ) != ( data_ch[i]  ) ) {		  if (get_timer(start) > CFG_FLASH_WRITE_TOUT ) {			  return 1;		  }	  }	}/* for */     }#elif defined( CONFIG_BOOT_16B)	data_short[0]=(int) (data>>16) & 0xffff;	data_short[1]=(int ) data & 0xffff ; 	for (i=0;i<2;i++ ){	my_out_be16(     (unsigned short *) ((ulong)addr+ 0xaaa),0xaa );	my_out_be16(     (unsigned short *) ((ulong)addr+ 0x554),0x55 );	my_out_be16(     (unsigned short *) ((ulong)addr+ 0xaaa),0xa0 );	my_out_be16(  (unsigned short *) (dest+(i*2)) ,data_short[i]);	/* re-enable interrupts if necessary */	if (flag)		enable_interrupts();  	  start = get_timer (0);	last  = start;	  while(  ( my_in_be16((unsigned short *) (dest+(i*2))) ) != ( data_short[i]  ) ) {		  if (get_timer(start) > CFG_FLASH_WRITE_TOUT ) {			  return 1;		  }	  }	}#elif defined( CONFIG_BOOT_32B)	addr[0x0555] = 0x00AA00AA;	addr[0x02AA] = 0x00550055;	addr[0x0555] = 0x00A000A0;	*((vu_long *)dest) = data;	/* 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);		}	}#endif			return (0);}#ifdef  CONFIG_BOOT_8Bstatic int my_in_8  ( unsigned char *addr){       int ret;       __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));       return ret;}static void my_out_8  ( unsigned char *addr, int val){       __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));}#endif#ifdef  CONFIG_BOOT_16Bstatic int my_in_be16( unsigned short *addr){       int ret;        __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));			        return ret;}static void my_out_be16( unsigned short *addr, int val){       __asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));}#endif#ifdef  CONFIG_BOOT_32Bstatic  unsigned my_in_be32( unsigned *addr){        unsigned ret;        __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));			        return ret;}static  void my_out_be32( unsigned *addr, int val){       __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));}#endif

⌨️ 快捷键说明

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