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

📄 flashpic.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
字号:
/*  * flashpic.c: * * by Thomas E. Arvanitis (tharvan@inaccessnetworks.com) *  * This file contains the flash-support code that is relocated to * RAM prior to execution.  * * TODO: Need some cleanup, and perhaps rewrite to use buffer write  *       to speed up operations. * * Here we only do WIDTH32 specifically. */#include "config.h"#if INCLUDE_FLASHtypedef unsigned char uchar;typedef unsigned short ushort;typedef unsigned long ulong;typedef volatile unsigned char vuchar;typedef volatile unsigned short vushort;typedef volatile unsigned long vulong;typedef volatile unsigned int vuint;typedef volatile int vint;#include "cpu.h"#include "flashdev.h"#include "flash.h"#define SR_WAIT 100000#define WR_WAIT 50#define DEV_WIDTH   4#define WSMS    0x00800080#define WSMS_L  0x00000080#define WSMS_H  0x00800000#define ESS 0x00400040#define ES  0x00200020#define PSS 0x00040004#define PS  0x00100010extern struct flashinfo Fdev;extern int FlashProtectWindow;intFlashlock32(struct flashinfo *fdev,int snum,int operation){    ulong   add;    int sector;    add = (ulong)(fdev->base);    /* Lock the requested sector(s): */    for (sector=0;sector<fdev->sectorcnt;sector++) {        if ((snum == ALL_SECTORS) || (snum == sector)) {            /* Issue the appropriate command sequence: */            Write_60_to_base();             switch(operation) {            case FLASH_UNLOCK:                Write_d0_to(add);                break;            case FLASH_LOCK:                Write_01_to(add);                break;            case FLASH_LOCKDWN:                return(-1);                break;            }        }        add += fdev->sectors[sector].size;    }    Write_ff_to_base();     /* Go to read-array mode */    return(0);}voidEndFlashlock32(){}/* Flasherase():   Based on the 'snum' value, erase the appropriate sector(s).   Write the "Erase Setup" and "Erase Confirm" commands...   Return 0 if success, else -1.*/intFlasherase32(struct flashinfo *fdev,int snum){    int ret, sector;    volatile int i;    ret = 0;    FDEBUG('E');    /* Erase the request sector(s): */    for (sector=0; sector < fdev->sectorcnt; sector++) {        FDEBUG('2');        if ((!FlashProtectWindow) && (fdev->sectors[sector].protected)) {            FDEBUG('3');            continue;        }        if ((snum == ALL_SECTORS) || (snum == sector)) {            register ulong *lp, *lp1;            int noterased;            FDEBUG('4');            /* See if the sector is already erased: */            noterased = 0;            lp = (ulong *)fdev->sectors[sector].begin;             lp1 = (ulong *)((char *)lp + fdev->sectors[sector].size);             while(lp < lp1) {                if (*lp++ != 0xffffffff) {                    FDEBUG('a');                    noterased = 1;                    break;                }            }            FDEBUG('5');            if (noterased) {                FDEBUG('6');                /* Issue the setup/confirm sequence: */                Write_20_to(fdev->sectors[sector].begin);/* setup */                Write_d0_to(fdev->sectors[sector].begin);/* confirm */                /* Wait for sector erase to complete by polling RSR... */                while(1) {                    ulong rsr;                    Write_70_to_base();                    rsr = Read_0000_from_base();                    if (! (rsr & WSMS_H && rsr & WSMS_L)) { /* Wait till ready */                        FDEBUG('a');                        for (i=0; i<SR_WAIT; i++);                        continue;                    }                    if (rsr & ESS) { /* Should not be suspended */                        FDEBUG('b');                        ret = -1;                    }                    if (rsr & ES) { /* Should not have error */                        FDEBUG('c');                        ret = -1;                    }                    break;                }                FDEBUG('7');                Write_50_to_base(); /* Clear status register */                Write_ff_to_base(); /* Go to read-array mode */            }            FDEBUG('8');            if (ret == -1)                break;        }        FDEBUG('9');    }    FDEBUG('\n');    FDEBUG('\r');    for (i=0; i<SR_WAIT; i++);    return(ret);}/* EndFlasherase():   Function place holder to determine the "end" of the   sectorerase() function.*/voidEndFlasherase32(){}/* Flashwrite():   Return 0 if successful, else -1.*/intFlashwrite32(struct flashinfo *fdev, uchar *dest, uchar *src, long bytecnt){    int rval;    ulong sr, obuff, addrC, addrE, addrL;    rval = 0;    addrC = (ulong)dest;    addrE = (ulong)dest + bytecnt;    addrL = (ulong)dest & ~0x03UL;    while (addrC < addrE) {        obuff = *(ftype *)addrL;        switch (addrC & 0x03UL) {        case 0x0:            obuff &= (ulong)(*src++ << 0x00) | 0xffffff00;            if ( ++addrC == addrE )                break;            /* fall through */        case 0x1:            obuff &= (ulong)(*src++ << 0x08) | 0xffff00ff;            if ( ++addrC == addrE )                break;            /* fall through */        case 0x2:            obuff &= (ulong)(*src++ << 0x10) | 0xff00ffff;            if ( ++addrC == addrE )                break;            /* fall through */        case 0x3:            obuff &= (ulong)(*src++ << 0x18) | 0x00ffffff;            if ( ++addrC == addrE )                break;        }        Write_40_to(addrL); /* flash program setup */        FWrite(addrL, &obuff); /* write value */        do {            Write_70_to_base();            sr = Read_0000_from_base();        } while ( ! (sr & WSMS_H && sr & WSMS_L) );        Write_50_to_base(); /* Clear status register */        Write_ff_to_base(); /* Go to read-array mode */        if ( Is_Not_Equal(addrL, &obuff) ) {            rval = -1;            break;        }                addrL = addrC;    }    return rval;}/* EndFlashwrite():    Function place holder to determine the "end" of the    Flashwrite() function.*/voidEndFlashwrite32(){}/* Ewrite():   Erase all sectors that are part of the address space to be written,   then write the data to that address space.  This is basically a   concatenation of flasherase and flashwrite done in one step.  This is   necessary primarily for re-writing the bootcode; because after the boot   code is erased, there is nowhere to return so the re-write must be done   while executing out of ram also.*/intFlashewrite32(struct flashinfo *fdev,uchar *destA,uchar *srcA,int bytecnt){    int     sector, i;    void    (*reset)();    uchar   *src1;    ftype   val;    uchar   *src, *dest;    ulong   rsr;ewrite_again:    src = srcA;    dest = destA;    Write_50_to_base(); /* clear status register */    Write_ff_to_base(); /* set device in read-array mode */    FDEBUG('A');    /* For each sector, if it overlaps any of the destination space */    /* then erase that sector. */    for (sector = 0; sector < fdev->sectorcnt; sector++) {        FDEBUG('1');        if ((((uchar *)dest) > (fdev->sectors[sector].end)) ||            (((uchar *)dest+bytecnt) < (fdev->sectors[sector].begin))) {            FDEBUG('2');            continue;        }        FDEBUG('3');        /* Issue the ERASE setup/confirm sequence: */        Write_20_to(fdev->sectors[sector].begin);/* setup */        Write_d0_to(fdev->sectors[sector].begin);/* confirm */        FDEBUG('4');        /* Wait for sector erase to complete by polling RSR... */        do {            Write_70_to_base();            rsr = Read_0000_from_base();        } while (! (rsr & WSMS_H && rsr & WSMS_L));        FDEBUG('5');        Write_50_to_base();     /* Clear status register */        Write_ff_to_base();     /* Go to read-array mode */        FDEBUG(':');    }    FDEBUG('\n');    FDEBUG('\r');    FDEBUG('6');    src1 = (uchar *)&val;    for(i = 0; i < bytecnt; i += DEV_WIDTH) {        /* Just in case src is not aligned... */        src1[0] = src[0];        src1[1] = src[1];        src1[2] = src[2];        src1[3] = src[3];        /* Flash program setup command */        Write_40_to(dest);                /* Write the value */        FWrite(dest,src1);        /* Wait for write to complete by polling RSR... */        do {            Write_70_to_base();            rsr = Read_0000_from_base();        } while (! (rsr & WSMS_H && rsr & WSMS_L));        Write_50_to_base();     /* Clear status register */        Write_ff_to_base();     /* Go to read-array mode */        if (Is_Not_Equal(dest, src1)) {            FPRINT('E'); FPRINT('1');            goto ewrite_again;        }        dest+=DEV_WIDTH;        src+=DEV_WIDTH;    }        FDEBUG('7');    FDEBUG('\n');    FDEBUG('\r');    /* Now that the re-programming of flash is complete, reset: */    reset = RESETFUNC();    reset();    return(0);  /* won't get here */}/* EndFlashewrite():    Function place holder to determine the "end" of the    FlashEraseAndWrite() function.*/voidEndFlashewrite32(){}/* Flashtype():   Use the ReadCOnfiguration command (90H) to read manufacturer code (0000)   and device id code (0001).*/intFlashtype32(struct flashinfo *fdev){    ushort  man, dev;    ulong   id;    /* Issue the read configuration command: */    Write_90_to_base();    man = (ushort)Read_0000_from_base();    /* manufacturer ID */    dev = (ushort)Read_0001_from_base();    /* device ID */    id = man;    id <<= 16;    id |= dev;    fdev->id = id;    /* Issue the read array command: */    Write_ff_to_base();        return((int)(fdev->id));}/* EndFlashtype():    Function place holder to determine the "end" of the    Flashtype() function.*/voidEndFlashtype32(){}#endif

⌨️ 快捷键说明

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