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

📄 flash.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* This file contains all of the flash support code that does not need   to be relocated to RAM.  Two separate files (flash.c and flashpic.c)   are maintained because under certain compilers, they may need to be   compiled with different options to be made position independent.   NOTE: THESE FUNCTIONS ARE NOT RE-ENTRANT!!!  All of the FLASH routines   assume they can copy themselves into the array FlashFunc[]; hence, only   one operation can be active at any time.*/#include "config.h"#if INCLUDE_FLASH#include "cpu.h"#include "flash.h"typedef 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;extern int Flashtype29F040_8();extern int EndFlashtype29F040_8();extern int Flasherase29F040_8();extern int EndFlasherase29F040_8();extern int Flashwrite29F040_8();extern int EndFlashwrite29F040_8();extern int Flashewrite29F040_8();extern int EndFlashewrite29F040_8();extern int Flashtype29F800B_16();extern int EndFlashtype29F800B_16();extern int Flasherase29F800B_16();extern int EndFlasherase29F800B_16();extern int Flashwrite29F800B_16();extern int EndFlashwrite29F800B_16();extern int Flashewrite29F800B_16();extern int EndFlashewrite29F800B_16();struct flashinfo *addrtobank();int CurrentBank;/* FlashXXXFbufYYY[]:    Where XXX is the function to be stored in the buffer and YYY is the    device that the function is to operate on.    These arrays are loaded with the flash operation function (TYPE, ERASE,    WRITE & EWRITE) that must run in different memory space than the device    that is being operated on.  Recall that to operate on the flash, you    cannot be executing out of it.    The flash functions are copied here, then executed through a function    pointer flashfunc which is set (in FlashInit) to point to the buffer.*/long    FlashTypeFbuf040[FLASHFUNCSIZE];long    FlashWriteFbuf040[FLASHFUNCSIZE];long    FlashEraseFbuf040[FLASHFUNCSIZE];long    FlashEwriteFbuf040[FLASHFUNCSIZE];long    FlashTypeFbuf800[FLASHFUNCSIZE];long    FlashWriteFbuf800[FLASHFUNCSIZE];long    FlashEraseFbuf800[FLASHFUNCSIZE];long    FlashEwriteFbuf800[FLASHFUNCSIZE];/* FlashProtectWindow:   Must be set to allow any flash operation to be done on space assumed   to be boot code.*/int FlashProtectWindow;/* FlashNamId[]:   Used to correlate between the ID and a string representing the name   of the flash device.*/struct flashdesc FlashNamId[] = {    AMD29F800B, "AMD-29F800B",    AMD29F800T, "AMD-29F800T",    SGS29F040,  "SGS-29F040",    AMD29F040,  "AMD-29F040",    AMD29F010,  "AMD-29F010",    FLASHRAM,   "FLASH-RAM",};int SectorSizes29F040_8[] = {        0x10000, 0x10000, 0x10000, 0x10000,        0x10000, 0x10000, 0x10000, 0x10000,};int SectorSizes29F800B_16[] = {        0x4000,     0x2000,     0x2000,     0x8000,        0x10000,    0x10000,    0x10000,    0x10000,        0x10000,    0x10000,    0x10000,    0x10000,        0x10000,    0x10000,    0x10000,    0x10000,        0x10000,    0x10000,    0x10000};struct sectorinfo sinfo800[19], sinfo040[8];struct sectorinfo sinfoRAM[(FLASHRAM_SIZE/FLASHRAM_SSIZE)];/* FlashBank[]:    This table contains all of the information that is needed to keep the    flash code somewhat generic across multiple flash devices.*/struct  flashinfo FlashBank[FLASHBANKS];showflashtype(id)ulong id;{    int i;    for(i=0;i<sizeof FlashNamId/sizeof(struct flashdesc);i++) {        if (id == FlashNamId[i].id) {            printf("Device = %s\n",FlashNamId[i].desc);            return(0);        }    }    printf("Flash id 0x%x not recognized\n",id);    return(-1);}showflashinfo(fdev)struct flashinfo *fdev;{    int i;    if (showflashtype(fdev->id) < 0)        return(-1);    printf("  Base addr   : 0x%08x\n",fdev->base);    printf("  Sectors     : %d\n",fdev->sectorcnt);    printf("  Bank width  : %d\n",fdev->width);    printf("  Sector     Begin       End        Size     SW-Protected?\n");    for(i=0;i<fdev->sectorcnt;i++) {        printf("    %2d    0x%08x  0x%08x  0x%06x      %s\n",            fdev->sectors[i].snum,            fdev->sectors[i].begin,fdev->sectors[i].end,            fdev->sectors[i].size,            fdev->sectors[i].protected ? "yes" : " no");    }    return(0);}/* flashopload():    Copy flash operation to ram space.      Note that this function assumes that cache is disabled at this point.    This is important because we are copying text into bss space and if    cache was on, there could be a coherency problem.*/flashopload(ulong *begin,ulong *end,ulong *copy,int size){    volatile ulong  *bp;    int ret, mode;    /* Verify space availability: */    if (((int)end - (int)begin) >= size) {        printf("flashopload overflow ((0x%x-0x%x) > 0x%x)\n",end,begin,size);        return(-1);    }    ret = 0;    /* Copy function() to RAM, then verify: */    bp = begin;    while(bp <= end) {        *copy = *bp;        if (*copy++ != *bp++) {            printf("flashopload failed\n");            ret = -1;            break;        }    }    return(ret);}/* flashtype():    Use the device-specific function pointer to call the routine    relocated to RAM space.*/flashtype(fdev)struct flashinfo *fdev;{    return(fdev->fltype(fdev));}/* flasherase():    Use the device-specific function pointer to call the routine    relocated to RAM space.    Note that flasherase() is called with a sector number.  The sector    number is relative to the entire system, not just the particular device.    This means that if there is more than one flash device in the system that    the actual sector number (relative to the device) may not be the same    value.  This adjustment is made here so that the underlying code that is    pumped into ram for execution does not have to be aware of this.*/flasherase(fdev,snum)struct  flashinfo *fdev;int snum;{    int size;    char *base, *end;    if (fdev->id == FLASHRAM) {        if (snum == ALL_SECTORS) {            size = fdev->end - fdev->base;            base = fdev->base;        }        else {            sectortoaddr(snum,&size,&base);        }        end = base+size;        while(base < end) {            *base = 0xff;            if (*base++ != 0xff)                return(-1);        }        return(0);    }    if ((snum != ALL_SECTORS) && (fdev->sectors[0].snum != 0)) {/*      printf("Adjusting snum from %d to",snum); */        snum -= fdev->sectors[0].snum;/*      printf(" %d.\n",snum); */    }    return(fdev->flerase(fdev,snum));}/* flashwrite():    Use the device-specific function pointer to call the routine    relocated to RAM space.    First make a few checks on the request, then write to flash if all    checks succeed.*/flashwrite(fdev,dest,src,bytecnt)struct  flashinfo *fdev;uchar   *src, *dest;long    bytecnt;{    int i, j, lowsector, highsector;    register uchar  *dp, *sp, *edp;    if (fdev->id == FLASHRAM) {        uchar *sp, *dp, *end;        sp = src;        dp = dest;        end = dp+bytecnt;        while(dp < end) {            *dp = *sp;            if (*dp != *sp)                return(-1);            dp++; sp++;        }        return(0);    }    dp = dest;    sp = src;    edp = (dest + bytecnt) - 1;    /* If outside the devices space, return failed.. */    if ((edp < fdev->sectors[0].begin) ||        (dp > fdev->sectors[fdev->sectorcnt-1].end)) {        printf("flashwrite() failed: dest out of flash range\n");        return(-1);    }    /* Make sure the destination is not within a protected sector */    if (FlashProtectWindow == FLASH_PROTECT_WINDOW_CLOSED) {        /* First determine the sectors that overlap with the */        /* flash space to be written... */        lowsector = highsector = -1;        for(j=0;j<fdev->sectorcnt;j++) {            if ((dp >= fdev->sectors[j].begin) &&                (dp <= fdev->sectors[j].end))                lowsector = j;        }        for(j=0;j<fdev->sectorcnt;j++) {            if ((edp >= fdev->sectors[j].begin) &&                (edp <= fdev->sectors[j].end))                highsector = j;        }        if ((lowsector == -1) || (highsector == -1)) {            printf("flashwrite() failed: can't find sector\n");            return(-1);        }        /* Now that the range of affected sectors is known, */        /* verify that those sectors are not protected... */        for(j=lowsector;j<=highsector;j++) {            if (fdev->sectors[j].protected) {                printf("flashwrite() failed: sector protected\n");                return(-1);            }        }    }    /* Now make sure that there is no attempt to transition a bit */    /* in the affected range from 0 to 1...  A flash write can only */    /* bring bits low (erase brings them  high). */    while(dp < edp) {        if ((*dp & *sp) != *sp) {            printf("flashwrite() failed: bit 0->1 rqst denied.\n");            return(-1);        }        dp++;         sp++;    }    return(fdev->flwrite(fdev,dest,src,bytecnt));}/* flashewrite():    Use the device-specific function pointer to call the routine    relocated to RAM space.*/flashewrite(fdev,dest,src,bytecnt)struct  flashinfo *fdev;ulong   *src, *dest;long    bytecnt;{    int i;    /* Source and destination addresses must be long-aligned. */    if (((int)src & 3) || ((int)dest & 3))        return(-1);    /* If the protection window is closed, then verify that no protected */    /* sectors will be written over... */    if (FlashProtectWindow == FLASH_PROTECT_WINDOW_CLOSED) {        for (i=0;i<fdev->sectorcnt;i++) {            if((((uchar *)dest) > (fdev->sectors[i].end)) ||                (((uchar *)dest+bytecnt) < (fdev->sectors[i].begin)))                continue;            else                if (fdev->sectors[i].protected)                    return(-1);        }    }    return(fdev->flewrite(fdev,dest,src,bytecnt));}AppFlashWrite(dest,src,bytecnt)ulong   *src, *dest;long bytecnt;{    struct flashinfo *fbnk;    ulong   oints;    int ret;    fbnk = addrtobank(dest);    if (!fbnk)        return(-1);    oints = intsoff();    ret = flashwrite(fbnk,dest,src,bytecnt);    intsrestore(oints);

⌨️ 快捷键说明

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