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

📄 flash.c

📁 AT91RM9200的完整启动代码:包括loader, boot及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 + -