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

📄 flash_toshiba.c

📁 Embeded bootloader (rrload by ridgerun) for TI linux based platform v5.36
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: flash_toshiba.c * * An implementation of a flash utility for most flash chips that support * the CFI command set 2 specification.  Also supports specific chips * including the 2 Mbyte Toshiba chip (TC58FB160FT-xx) or the very similar,  * but larger, 8 Mbyte Fujitsu MBM29DL323B chip. * * See Also *    flash.h * *  This program is free software; you can redistribute  it and/or modify it *  under  the terms of  the GNU General  Public License as published by the *  Free Software Foundation;  either version 2 of the  License, or (at your *  option) any later version. * *  THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT, *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *  You should have received a copy of the  GNU General Public License along *  with this program; if not, write  to the Free Software Foundation, Inc., *  675 Mass Ave, Cambridge, MA 02139, USA. * */#include "flash.h"#include "types.h"#include "util.h"#include "io.h"#include "memconfig.h"static int total_sectors = 0;  // set in flash_init()#define CMDMAX 10unsigned char cmd[CMDMAX];#if BSPCONF_FLASH_TYPE == CFI_CMDSET_2#define TOTAL_SECT 256                  // a number bigger than largest chipstatic int sect_sizes[TOTAL_SECT];      // filled in by flash_init()#elif BSPCONF_FLASH_TYPE == TOSHIBA_TC58FB160FT#define FLASH_ID 0x00980043#define NUM_CHIP_SECT 35#define NUM_CHIPS 1#define TOTAL_SECT (NUM_CHIPS*NUM_CHIP_SECT)static const int sect_sizes[NUM_CHIP_SECT] = {  0x4000,  0x2000,  0x2000,  0x8000,  0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000};#elif  BSPCONF_FLASH_TYPE == FUJITSU_MBM29DL323B#define FLASH_ID 0x00042253#define NUM_CHIP_SECT 71#define NUM_CHIPS 1#define TOTAL_SECT (NUM_CHIPS*NUM_CHIP_SECT)static const int sect_sizes[NUM_CHIP_SECT] = {  0x2000,  0x2000,  0x2000,  0x2000,  0x2000,  0x2000 , 0x2000 , 0x2000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000};#elif BSPCONF_FLASH_TYPE == AMD_AM29DL164DT#define FLASH_ID 0x00012233#define NUM_CHIP_SECT 39#define NUM_CHIPS 1#define TOTAL_SECT (NUM_CHIPS*NUM_CHIP_SECT)static const int sect_sizes[NUM_CHIP_SECT] = {  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000};#elif  BSPCONF_FLASH_TYPE == FUJITSU_29LV320T#define FLASH_ID 0x000422F6#define NUM_CHIP_SECT 71#define NUM_CHIPS 1#define TOTAL_SECT (NUM_CHIPS*NUM_CHIP_SECT)static const int sect_sizes[NUM_CHIP_SECT] = {  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x2000,  0x2000,  0x2000,  0x2000,  0x2000,  0x2000 , 0x2000 , 0x2000};//###########################################################////  This is OUR TYPE !!!! ////############################################################elif  BSPCONF_FLASH_TYPE == HYNIX_HY29LD320B#define SST	      0#define ST	      1#define M29W320DB     0x22CA#define SST39VF320    0x2783//***********************************************************// ST (M29W320DB) : //		VENDOR_ID     = 0x0020//		FLASH_ID      = 0x22CB//		NUM_CHIP_SECT = 67//		TOTAL_SECT    = 67 (NUM_CHIP_SECT * NUM_CHIPS)//***********************************************************// SST (SST39VF320) ://		VENDOR_ID     = 0x00BF//		FLASH_ID      = 0x2783//		NUM_CHIP_SECT = 64//		TOTAL_SECT    = 64 (NUM_CHIP_SECT * NUM_CHIPS)//***********************************************************#define NUM_CHIPS     1#define MAX_SECT_NUM  80#define SST39VF320_NUM_SECT   64#define M29W320DB_NUM_SECT    67static const int M29W320DB_SECT_SIZES[MAX_SECT_NUM] = {  0x4000,  0x2000,  0x2000,  0x8000,  0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000,};static const int SST39VF320_SECT_SIZES[MAX_SECT_NUM] = {  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,  0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000,};static int VENDOR_ID, FLASH_ID;static int NUM_CHIP_SECT, TOTAL_SECT;//############################################################else   #error Must specify a supported BSPCONF_FLASH part.#endiftypedef struct {    int   start_addr;    int   end_addr;} sect_info_t;sect_info_t sect_info[MAX_SECT_NUM*NUM_CHIPS];struct erase_region_info {    int   sectors;    int   size;};#define MAX_REGIONS_PER_FLASH 8//***************************************************************// Routine:// Description: Returns the starting address for flash block//              containing block_address//***************************************************************unsigned short *get_start_address(unsigned short *block_address){    int i;    for (i=0; i<total_sectors; i++)     {        if (((unsigned short *)sect_info[i].start_addr >= block_address) &&            ((unsigned short *)sect_info[i].start_addr <= block_address))         {            return((unsigned short *)sect_info[i].start_addr);        }    }     return(0);}//***************************************************************// Routine:// Description: Returns the ending address for flash block//              containing block_address//***************************************************************unsigned short *get_end_address(unsigned short *block_address){    int i;    for (i=0; i<total_sectors; i++)     {        if (((unsigned short *)sect_info[i].start_addr >= block_address) &&            ((unsigned short *)sect_info[i].start_addr <= block_address))         {            return((unsigned short *)sect_info[i].end_addr);        }    }    return(0);}//***************************************************************// Routine:// Description: returns true if the block has been erased//***************************************************************static int verify_block_erased(unsigned short *block_addr, int print_err){    volatile unsigned short *addr;    volatile unsigned short contents;    unsigned short          *start_addr;    unsigned short          *end_addr;    int                     err = false;    start_addr = get_start_address(block_addr);    end_addr   = get_end_address(block_addr);    for (addr=start_addr; addr<end_addr; addr++)     {        contents = *addr;        if (contents != 0xFFFF)         {             err = true;            break;        }    }    if (err && print_err)     {        util_printf("Error: address range %X - %X not erased: %X=%x\n", 	            start_addr, end_addr, addr, contents);    }    return(!err);}#if defined(BSPCONF_BTLDR_MEMMAP_DEBUG) || (BSPCONF_FLASH_TYPE == CFI_CMDSET_2)//***************************************************************// Routine:// Description://***************************************************************static void enable_read_mode(){  volatile unsigned short *addr;  addr = (unsigned short *) BSPCONF_FLASH_BASE;    if (FLASH_ID == M29W320DB)    {        *addr = 0xF0;    }    else if (FLASH_ID == SST39VF320)    {        addr[0x5555] = 0xAA;        addr[0x2AAA] = 0x55;        addr[0x5555] = 0xF0;    }    io_delay(100);}//***************************************************************// Routine:// Description: Returns true if flash//              part supports CFI//***************************************************************static int cfi_supported(void){    volatile unsigned short *addr;    int                     read_array[3];    addr = (unsigned short *) BSPCONF_FLASH_BASE;    //---------------------------------------------    // 1st try !!  (SST)    //---------------------------------------------    addr[0x5555] = 0xAA;    addr[0x2AAA] = 0x55;    addr[0x5555] = 0x98;    io_delay (100);    read_array[0] = addr[0x10];    read_array[1] = addr[0x11];    read_array[2] = addr[0x12];    if ((read_array[0]=='Q') && (read_array[1]=='R') && (read_array[2]=='Y'))        return SST39VF320; // FOUND !!! :-)    //---------------------------------------------    // 2nd try !! (ST)    //---------------------------------------------    addr[0x55] = 0x98; /* Enter read array mode */    read_array[0] = addr[0x10];    read_array[1] = addr[0x11];    read_array[2] = addr[0x12];     if ((read_array[0]=='Q') && (read_array[1]=='R') && (read_array[2]=='Y'))        return M29W320DB;  // FOUND !!! :-)    return 0; // NOT FOUND !!! :-(}//***************************************************************// Routine:// Description: returns true if device//              code read, false if chip doesn't support CFI//***************************************************************int read_device_codes(unsigned long *Code){    unsigned short           regval;    volatile unsigned short  *addr;    int                      ret_value;    addr = (unsigned short *) BSPCONF_FLASH_BASE;    ret_value = cfi_supported ();    if (ret_value == 0)    {        *Code = 0;        return 0;    }    //--------------------------------------    // set flash device info    //--------------------------------------    switch (ret_value)    {        case SST39VF320: // SST            VENDOR_ID = SST;            NUM_CHIP_SECT = SST39VF320_NUM_SECT;            break;        case M29W320DB:  // ST            VENDOR_ID = ST;            NUM_CHIP_SECT = M29W320DB_NUM_SECT;            break;    }    FLASH_ID   = ret_value;    TOTAL_SECT = NUM_CHIP_SECT * NUM_CHIPS;    enable_read_mode();    if (FLASH_ID == M29W320DB)    {        addr[0x555] = 0xAA;        addr[0x2AA] = 0x55;        addr[0x555] = 0x90;    }     else if (FLASH_ID == SST39VF320)    {        addr[0x5555] = 0xAA;        addr[0x2AAA] = 0x55;        addr[0x5555] = 0x90;    }     io_delay (100);    util_printf ("----------------------------------------------------\n");    /////////////////////////////////////////////////    // Manufacturer's Code    /////////////////////////////////////////////////    regval = addr[0];    util_printf ("  Manufacturer's ID = 0x%x \t", regval);    switch (regval)    {        case 0x20:    // ST            util_printf ("[ST]\n");            break;        case 0xBF:    // SST            util_printf ("[SST]\n");            break;    }    /////////////////////////////////////////////////    // Device's Code    /////////////////////////////////////////////////    *Code =  regval << 16;    regval = addr[1];    util_printf ("  Device         ID = 0x%x \t", regval);    switch (regval)    {        case 0x22CB:  // ST (M29W320DB)            util_printf ("[M29W320DB]\n");            break;        case 0x2783:  // SST (SST39VF320)            util_printf ("[SST39VF320]\n");            break;        case 0x235B:  // SST (SST39VF3201)            util_printf ("[SST39VF3201]\n");            break;        case 0x235A:  // SST (SST39VF3202)            util_printf ("[SST39VF3202]\n");            break;    }    util_printf ("----------------------------------------------------\n");    *Code = *Code | regval;    enable_read_mode();    return(1);}//***************************************************************// Routine:// Description: returns true if chip supports CFI.  array elements//      from CFI_START_ADDR to CFI_END_ADDR filled with CFI read array data.// Returns: false if chip doesn't support CFI.//***************************************************************int read_cfi_array(unsigned short array[], int array_size){    volatile unsigned short *addr;     int                     i;      addr = (unsigned short *) BSPCONF_FLASH_BASE;    if ( array_size < (CFI_END_ADDR +1))    {        util_printf("read_cfi_array: ERROR array too small\n");        return(0);    }    if ( ! cfi_supported() )    {        return(0);    }    enable_read_mode();        if (FLASH_ID == M29W320DB)    {        addr[0x55] = 0x98;     /* Enter read array mode */    }    else if (FLASH_ID == SST39VF320)

⌨️ 快捷键说明

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