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

📄 flash.c

📁 U BOOT源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    int prot = 0;    /* Validate arguments */    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;    }    /* Check for KNOWN flash type */    if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {	printf ("Can erase only Intel flash types - aborted\n");	return 1;    }    /* Check for protected sectors */    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++) {	WATCHDOG_RESET();	if (info->protect[sect] == 0) {      /* not protected */	    vu_long *addr = (vu_long *)(info->start[sect]);	    unsigned long status;	    /* Disable interrupts which might cause a timeout here */	    flag = disable_interrupts();	    *addr = 0x00500050;              /* clear status register */	    *addr = 0x00200020;              /* erase setup */	    *addr = 0x00D000D0;              /* erase confirm */	    /* re-enable interrupts if necessary */	    if (flag)		enable_interrupts();	    /* Wait at least 80us - let's wait 1 ms */	    udelay (1000);	    while (((status = *addr) & 0x00800080) != 0x00800080) {		if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {		    printf ("Timeout\n");		    *addr = 0x00B000B0;      /* suspend erase      */		    *addr = 0x00FF00FF;      /* reset to read mode */		    return 1;		}		/* show that we're waiting */		if ((now - last) > 990) {   /* every second */		    putc ('.');		    last = now;		}	    }	    *addr = 0x00FF00FF;              /* reset to read mode */	}    }    printf (" done\n");    return 0;} /* end flash_erase32() */int flash_erase(flash_info_t *info, int s_first, int s_last){    if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)	return flash_erase8(info, s_first, s_last);    else	return flash_erase32(info, s_first, s_last);} /* end flash_erase() *//*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */static int write_buff8(flash_info_t *info, uchar *src, ulong addr, ulong cnt){    ulong cp, wp, data;    ulong start;    int i, l, rc;    start = get_timer (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_word8(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_word8(info, wp, data)) != 0) {	    return (rc);	}	wp  += 4;	cnt -= 4;	if (get_timer(start) > 1000) {   /* every second */	   WATCHDOG_RESET();	   putc ('.');	   start = get_timer(0);	}    }    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_word8(info, wp, data));} /* end write_buff8() */#define	FLASH_WIDTH	4	/* flash bus width in bytes */static int write_buff32 (flash_info_t *info, uchar *src, ulong addr, ulong cnt){	ulong cp, wp, data;	int i, l, rc;	ulong start;	start = get_timer (0);	if (info->flash_id == FLASH_UNKNOWN) {		return 4;	}	wp = (addr & ~(FLASH_WIDTH-1));	/* get lower FLASH_WIDTH 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<FLASH_WIDTH && cnt>0; ++i) {			data = (data << 8) | *src++;			--cnt;			++cp;		}		for (; cnt==0 && i<FLASH_WIDTH; ++i, ++cp) {			data = (data << 8) | (*(uchar *)cp);		}		if ((rc = write_word32(info, wp, data)) != 0) {			return (rc);		}		wp += FLASH_WIDTH;	}	/*	 * handle FLASH_WIDTH aligned part	 */	while (cnt >= FLASH_WIDTH) {		data = 0;		for (i=0; i<FLASH_WIDTH; ++i) {			data = (data << 8) | *src++;		}		if ((rc = write_word32(info, wp, data)) != 0) {			return (rc);		}		wp  += FLASH_WIDTH;		cnt -= FLASH_WIDTH;	  if (get_timer(start) > 990) {   /* every second */			putc ('.');			start = get_timer(0);		}	}	if (cnt == 0) {		return (0);	}	/*	 * handle unaligned tail bytes	 */	data = 0;	for (i=0, cp=wp; i<FLASH_WIDTH && cnt>0; ++i, ++cp) {		data = (data << 8) | *src++;		--cnt;	}	for (; i<FLASH_WIDTH; ++i, ++cp) {		data = (data << 8) | (*(uchar *)cp);	}	return (write_word32(info, wp, data));} /* write_buff32() */int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt){    int retval;    if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)	retval = write_buff8(info, src, addr, cnt);    else	retval = write_buff32(info, src, addr, cnt);    return retval;} /* end write_buff() *//*----------------------------------------------------------------------- * Write a word to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */static int write_word8(flash_info_t *info, ulong dest, ulong data){    volatile uchar *addr2 = (uchar *)(info->start[0]);    volatile uchar *dest2 = (uchar *)dest;    volatile uchar *data2 = (uchar *)&data;    int flag;    int i, tcode, rcode = 0;    /* Check if Flash is (sufficently) erased */    if ((*((volatile uchar *)dest) &	(uchar)data) != (uchar)data) {	return (2);    }    for (i=0; i < (4 / sizeof(uchar)); i++) {	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();	*(addr2 + 0x555) = (uchar)0xAA;	*(addr2 + 0x2aa) = (uchar)0x55;	*(addr2 + 0x555) = (uchar)0xA0;	dest2[i] = data2[i];	/* Wait for write to complete, up to 1ms */	tcode = wait_for_DQ7((ulong)&dest2[i], data2[i], 1);	/* re-enable interrupts if necessary */	if (flag)	    enable_interrupts();	/* Make sure we didn't timeout */	if (tcode) {	    rcode = 1;	}    }    return rcode;} /* end write_word8() */static int write_word32(flash_info_t *info, ulong dest, ulong data){    vu_long *addr = (vu_long *)dest;    ulong 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 = 0x00400040;                      /* write setup */    *addr = data;    /* re-enable interrupts if necessary */    if (flag)	enable_interrupts();    start = get_timer (0);    while (((status = *addr) & 0x00800080) != 0x00800080) {	WATCHDOG_RESET();	if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {	    *addr = 0x00FF00FF;              /* restore read mode */	    return (1);	}    }    *addr = 0x00FF00FF;                      /* restore read mode */    return (0);} /* end write_word32() */static int _flash_protect(flash_info_t *info, long sector){    int i;    int flag;    ulong status;    int rcode = 0;    volatile long *addr = (unsigned long *)sector;    switch(info->flash_id & FLASH_TYPEMASK) {	case FLASH_28F320J3A:	case FLASH_28F640J3A:	case FLASH_28F128J3A:	    /* Disable interrupts which might cause Flash to timeout */	    flag = disable_interrupts();	    /* Issue command */	    *addr = 0x00500050L;             /* Clear the status register */	    *addr = 0x00600060L;             /* Set lock bit setup */	    *addr = 0x00010001L;             /* Set lock bit confirm */	    /* Wait for command completion */	    for (i = 0; i < 10; i++) {       /* 75us timeout, wait 100us */		udelay(10);		if ((*addr & 0x00800080L) == 0x00800080L)		    break;	    }	    /* Not successful? */	    status = *addr;	    if (status != 0x00800080L) {		printf("Protect %x sector failed: %x\n",		       (uint)sector, (uint)status);		rcode = 1;	    }	    /* Restore read mode */	    *addr = 0x00ff00ffL;	    /* re-enable interrupts if necessary */	    if (flag)		enable_interrupts();	    break;	case FLASH_AM040:                    /* No soft sector protection */	    break;    }    /* Turn protection on for this sector */    for (i = 0; i < info->sector_count; i++) {	if (info->start[i] == sector) {	    info->protect[i] = 1;	    break;	}    }    return rcode;} /* end _flash_protect() */static int _flash_unprotect(flash_info_t *info, long sector){    int i;    int flag;    ulong status;    int rcode = 0;    volatile long *addr = (unsigned long *)sector;    switch(info->flash_id & FLASH_TYPEMASK) {	case FLASH_28F320J3A:	case FLASH_28F640J3A:	case FLASH_28F128J3A:	    /* Disable interrupts which might cause Flash to timeout */	    flag = disable_interrupts();	    *addr = 0x00500050L;             /* Clear the status register */	    *addr = 0x00600060L;             /* Clear lock bit setup */	    *addr = 0x00D000D0L;             /* Clear lock bit confirm */	    /* Wait for command completion */	    for (i = 0; i < 80 ; i++) {      /* 700ms timeout, wait 800 */		udelay(10000);               /* Delay 10ms */		if ((*addr & 0x00800080L) == 0x00800080L)		    break;	    }	    /* Not successful? */	    status = *addr;	    if (status != 0x00800080L) {		printf("Un-protect %x sector failed: %x\n",		       (uint)sector, (uint)status);		*addr = 0x00ff00ffL;		rcode = 1;	    }	    /* restore read mode */	    *addr = 0x00ff00ffL;	    /* re-enable interrupts if necessary */	    if (flag)		enable_interrupts();	    break;	case FLASH_AM040:                    /* No soft sector protection */	    break;    }    /*     * Fix Intel's little red wagon.  Reprotect     * sectors that were protected before we undid     * protection on a specific sector.     */    for (i = 0; i < info->sector_count; i++) {	if (info->start[i] != sector) {	    if (info->protect[i]) {		if (_flash_protect(info, info->start[i]))		    rcode = 1;	    }	}	else /* Turn protection off for this sector */	    info->protect[i] = 0;    }    return rcode;} /* end _flash_unprotect() */int flash_real_protect(flash_info_t *info, long sector, int prot){    int rcode;    if (prot)	rcode = _flash_protect(info, info->start[sector]);    else	rcode = _flash_unprotect(info, info->start[sector]);    return rcode;} /* end flash_real_protect() *//*----------------------------------------------------------------------- */

⌨️ 快捷键说明

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