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

📄 flash_toshiba.c

📁 Embeded bootloader (rrload by ridgerun) for TI linux based platform v5.36
💻 C
📖 第 1 页 / 共 2 页
字号:
    {        addr[0x5555] = 0xAA;   /* Enter read array mode */        addr[0x2AAA] = 0x55;   /* Enter read array mode */        addr[0x5555] = 0x98;   /* Enter read array mode */    }    for ( i=CFI_START_ADDR; i <= CFI_END_ADDR; i++)    {        array[i] = addr[i];    }    enable_read_mode();    return(1);}//***************************************************************// Routine:// Description: returns number of sectors if chip supports CFI.  //              sector_map contains size of each sector.// Returns: false if chip doesn't support CFI.//// WARNING: this only works with flash chips supporting//          CFI extended query table 1.1 or greater//***************************************************************int build_sector_map(unsigned int sector_map[], int sector_map_size){    unsigned short array[CFI_END_ADDR];    int            ret, i, j;    int            region_count;    int            sector_count = 0;    int            region_sector_count;    long           region_size;    int            sector_index = 0;    long           calculated_flash_size = 0;    struct erase_region_info     erase_regions[MAX_REGIONS_PER_FLASH];    char           major, minor;    int            ext_table;    int            bootloc;    long           flash_id;    if ( ! cfi_supported() )    {        return 0;    }    ret = read_cfi_array (array, CFI_END_ADDR + 1);    if ( ! ret )    {        util_printf("build_sector_map: ERROR unable to read CFI array\n");        return 0;    }    region_count = array[0x2C];    /* read in the erase region information */    for ( i=0; i<region_count; i++)    {         erase_regions[i].sectors = (array[0x2E + (i * 4)] << 8) +                                     array[0x2D + (i * 4)] + 1;        erase_regions[i].size = ((array[0x30 + (i * 4)] << 8) +                                  array[0x2F + (i * 4)]) * 256;    }    //    // Some chips contain a defect in describing the sector map    // The following logic was taked from     // linux/drivers/mtd/chips/cfi_cmdset_0002.c start at the line with the    // text "Bring me the head of someone at AMD"    //    ret = read_device_codes(&flash_id);    if (!ret)     {         util_printf("   ERROR: flash chip did not respond to CFI query\n");         return(0);    }    ext_table = (array[0x16] << 8) + array[0x15];    major = (char) array[ext_table+0x03];    minor = (char) array[ext_table+0x04];    bootloc = array[ext_table+0x0F];    if (((major << 8) | minor) < 0x3131)     {        /* CFI version 1.0 top / bottom boot not specified, thus            building erase sector table not supported  */        return(0);    }    if (bootloc == 3 && region_count  > 1)     {        for (i=0; i<region_count / 2; i++)         {            j = (region_count-1)-i;				            region_sector_count = erase_regions[i].sectors;            region_size = erase_regions[i].size;            erase_regions[i].sectors = erase_regions[j].sectors;            erase_regions[i].size = erase_regions[j].size;            erase_regions[j].sectors = region_sector_count;            erase_regions[j].size = region_size;        }    }    /* process each region in the chip */    for ( i=0; i<region_count; i++)    {         region_sector_count = erase_regions[i].sectors;        sector_count += region_sector_count;        region_size = erase_regions[i].size;//        util_printf("   Region %d contains %d sectors of size 0x%X\n", //                     i, region_sector_count, region_size);        /*process each sector in the current region */        for (j=0; j<region_sector_count; j++)        {            if ( sector_index >= sector_map_size)            {                util_printf( "build_sector_map: ERROR sector map array "                             "too small %d\n", sector_map_size);                return 0;            }            sector_map[sector_index++] = region_size;            calculated_flash_size += region_size;        }    }    if ( (calculated_flash_size >> 20) != (1 << (array[0x27]-20)) )    {        util_printf("Warning: calculated flash size doesn't match CFI query "                    "flash size\n");        util_printf("Calculated flash size: %d Mbytes",                      calculated_flash_size >> 20);        util_printf("CFI stated flash size: %d Mbytes", 1 << (array[0x27]-20));    }    return(sector_count);}#endif//***************************************************************// Routine:// Description: returns true if block erased successfully//***************************************************************static int block_erase(volatile unsigned short *block_addr){    volatile unsigned short *addr;    int                     i;     //only erase block if it is not already erased    if (verify_block_erased((unsigned short *)block_addr, false))     {        return(true);    }    addr = (unsigned short *)BSPCONF_FLASH_BASE;    if (FLASH_ID == M29W320DB)    {        addr[0x555] = 0xAA;        addr[0x2AA] = 0x55;        addr[0x555] = 0x80;        addr[0x555] = 0xAA;        addr[0x2AA] = 0x55;        *block_addr = 0x30;    }    else if (FLASH_ID == SST39VF320)    {        addr[0x5555] = 0xAA;        addr[0x2AAA] = 0x55;        addr[0x5555] = 0x80;        addr[0x5555] = 0xAA;        addr[0x2AAA] = 0x55;        *block_addr = 0x50;    }    i = 7;    while (*block_addr != 0xFFFF)     {        io_delay(1000);        if (! i--)         {             return(verify_block_erased((unsigned short *)block_addr, true));            break;         }    }    return(true);}//***************************************************************// Routine:// Description://***************************************************************static int prog_data(volatile unsigned short *block_addr, unsigned short data){    volatile unsigned short *addr;    int                     i, j;    if ((*block_addr & data) != data)     {        // we can only change bits from a "1" to "0".        util_printf ("\nProgramming error; flash not erased;");        util_printf (" 0x%X = %x (programming %x)\n",                      block_addr, *block_addr, data);        return -1;    }    addr = (unsigned short *)BSPCONF_FLASH_BASE;    if (FLASH_ID == M29W320DB)    {        addr[0x555] = 0xAA;        addr[0x2AA] = 0x55;        addr[0x555] = 0xA0;    }    else if (FLASH_ID == SST39VF320)    {        addr[0x5555] = 0xAA;        addr[0x2AAA] = 0x55;        addr[0x5555] = 0xA0;    }    *block_addr = data;  /* wait a good long time, but not forever */    for (j=0; j < 100 ; j++)     {        i = 100000;        while ( i-- > 0 )         {            if (*block_addr == data)             {                return 0;            }        }        io_delay(100);    }    return -1;}//***************************************************************// Routine:// Description://   Note: See flash.h for description.//***************************************************************void flash_read(unsigned int offset,  // Of flash.                unsigned short *dest, // Destination buffer.                unsigned int num_bytes,                PutValAtAddrCallBack_t CBack){    unsigned int i, num_words;    unsigned short fval, *s_addr, *d_addr;    s_addr = (unsigned short *)(BSPCONF_FLASH_BASE+offset);    d_addr = dest;    num_words = ((num_bytes+1)>>1); // round up.    for (i=0; i<num_words; i++)     {        // Flash, for this board, requires that we read words, not bytes.        fval = *s_addr;        if (CBack)         {            (*CBack)(d_addr,fval); // write out the the 16bit value.        }        else         {            *d_addr=fval; // write out the the 16bit value.        }        s_addr++;        d_addr++;    }}//***************************************************************// Routine:// Description:// Note: See flash.h for description.//***************************************************************int flash_write(unsigned int offset,  // Of flash.                 unsigned short *src,  // Source buffer.                 unsigned int num_bytes,                 GetValAtAddrCallBack_t CBack){    unsigned int    i, num_words;    unsigned short  fval, *d_addr, *s_addr;    int             ret;    s_addr = src;    d_addr = (unsigned short *)(BSPCONF_FLASH_BASE+offset);    num_words = ((num_bytes+1)>>1); // round up.    for (i=0; i<num_words; i++)     {        if (CBack)         {            (*CBack)(s_addr,&fval);        }        else         {            fval = *s_addr;        }        ret = prog_data(d_addr,fval);        if (ret != 0 )         {            return ret;        }                    s_addr++;        d_addr++;    }    return 0;}//***************************************************************// Routine:// Description:// Note: See flash.h for description.//***************************************************************int flash_flush(void){  // Return a -1 if all went well, otherwise  // return the flash offset which presented  // a problem.  return -1;}//***************************************************************// Routine:// Description:// Note: See flash.h for description.//***************************************************************void flash_erase(void){    // Erase the entire flash chip.    int i;    int err = false;    char cmd[10];    for (i=0; i<total_sectors; i++)     {        util_printf ("Erasing %X to %X\n",                     sect_info[i].start_addr, sect_info[i].end_addr);        err |= !block_erase((unsigned short *)(sect_info[i].start_addr));    }    if (err)     {        util_printf("Press return to continue");        util_gets(cmd, 10);    }}//***************************************************************// Routine:// Description:// Note: See flash.h for description.//***************************************************************void flash_erase_range(int start_addr, int end_addr){    int   i;    int   start_erase=-1;    int   end_erase=-1;    util_printf("Erasing blocks containing addresses 0x%X to 0x%X\n",                start_addr,end_addr);    for (i=0; i<total_sectors; i++)     {        if ((sect_info[i].start_addr <= start_addr) &&            (sect_info[i].end_addr >= start_addr))         {            start_erase = i;        }        if ((sect_info[i].start_addr <= end_addr) &&            (sect_info[i].end_addr >= end_addr))         {            end_erase = i;        }    }    if (( start_erase < 0 ) || ( end_erase < 0 ))     {        util_printf("Erase flash bad address range\n");    }    for (i=start_erase; i<=end_erase; i++)     {        util_printf("Erasing block %i of %i\n",i,total_sectors);        block_erase((unsigned short *)(sect_info[i].start_addr));    }}//***************************************************************// Routine:// Description:// Note: See flash.h for description.//***************************************************************int flash_init(){    int      i, addr_tally;    long     flash_id;    addr_tally = BSPCONF_FLASH_BASE;    i = read_device_codes (&flash_id);/*    util_printf ("\n----------------------------------------------------\n");    util_printf (" Flash Device is ... ");    if ((i == 1) && (FLASH_ID == M29W320DB))            util_printf ("  M29W320DB [ST]\n");    else if ((i == 1) && (FLASH_ID == SST39VF320))            util_printf ("  SST39VF320 [SST]\n");    else            util_printf ("\n ERROR !!! Unrecognized Flash Device !!! \n");    util_printf ("----------------------------------------------------\n");*/        /*    if (i == 1)  util_printf ("[Gagamel] Checking ... TRUE [%x]\n", flash_id);    else if (i == 0)  util_printf ("[Gagamel] Checking ... FALSE\n");    else              util_printf ("[Gagamel] Checking ... NOTHING \n");*/#if BSPCONF_FLASH_TYPE == CFI_CMDSET_2  total_sectors = build_sector_map(sect_sizes, TOTAL_SECT);    if ( total_sectors == 0 )     {        util_printf("\nError: flash chip does not support CFI version 1.1 "                    "or greater\n");        util_printf("You can not use the CFI CMDSET 2 flash chip driver\n");        util_printf("Select a different flash chip using the BSP configuration "                    "tool (make bspconfig)\n");        util_printf("Press <Enter>....\n");        util_gets(cmd,CMDMAX);    }#else    total_sectors = TOTAL_SECT;#endif    for ( i = 0 ; i < total_sectors ; i++)     {        sect_info[i].start_addr = addr_tally;        if (FLASH_ID == M29W320DB)            addr_tally += M29W320DB_SECT_SIZES[i];        else if (FLASH_ID == SST39VF320)            addr_tally += SST39VF320_SECT_SIZES[i];        sect_info[i].end_addr = addr_tally-1;    }    return 160;}

⌨️ 快捷键说明

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