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

📄 flash.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************** Copyright (c) 2003-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* * flash.c * * by Ho Lee 02/05/2003 */#include "config.h"#include "uart.h"#include "hardware.h"#include "io.h"#include "em86xxapi.h"#include "flash.h"#define FLASH_VERBOSE           0#define FLASH_ERR_CNT		(1<<8)	/* Error limit before reporting */#define FLASH_WAIT_DIV		1	/* 1 for the board without 					   IORDY lifted, it'll try the full 					   cycle, or more than 1 for others */#define FLASH_USE_DQX	/* Use DQx toggling bit to detect programming status */#ifdef CONFIG_ENABLE_FULLFUNCTIONstatic const char *finfo_msg = "Flash %d : base addr = %08x, size = %08x\n";#endifstatic unsigned flash_wait_div = FLASH_WAIT_DIV;/* * FlexROM / Parallel flash is connected to Peripheral Bus CS#2 * 8/24 nonmultiplexed mode */int flash_init(void){#if 0    // Peripheral Bus interface    // use timing 0    __raw_writel(DEFAULT_PB_TIMING0, REG_BASE_HOST + PB_timing0);    __raw_writel(DEFAULT_PB_USE_TIMING0, REG_BASE_HOST + PB_use_timing0);#endif    return 0;}#ifdef CONFIG_ENABLE_FLASH/* * flash-cfi.c * * flash driver from scratch * based on CFI (Common Flash Memory Interface) Specification 2.0 * supports multiple flashes * supports command set 2 (AMD standard) * * first revision by Ho Lee 10/31/2002 * code cleanup by Ho Lee 11/08/2002 * code cleanup by Ho Lee 12/01/2003 */#include "config.h"#include "uart.h"#include "util.h"#include "io.h"#include "flash.h"//// for matching endian between CPU and CFI interface// CFI and HOST use same endian//#define cpu_to_cfi8(x)                  (x)#define cfi8_to_cpu(x)                  (x)#define cpu_to_cfi16(x)                 (x)#define cfi16_to_cpu(x)                 (x)#define cpu_to_cfi32(x)                 (x)#define cfi32_to_cpu(x)                 (x)//// CFI Query Identification//// Vendor command set & control interface ID code assignment // CFI Publication 100#define CFI_PRIMARY_ID_NULL             0   // none is specified#define CFI_PRIMARY_ID_INTEL_EXT        1   // Intel/Sharp Extended command set#define CFI_PRIMARY_ID_AMD_STD          2   // AMD/Fujitsu Standard command set#define CFI_PRIMARY_ID_INTEL_STD        3   // Intel Standard command set#define CFI_PRIMARY_ID_AMD_EXT          4   // AMD/Fujitsu Extended command set#define CFI_PRIMARY_ID_MITSUBISHI_STD   256 // Mitsubishi Standard command set#define CFI_PRIMARY_ID_MITSUBISHI_EXT   257 // Mitsubishi Extended command set#define CFI_PRIMARY_ID_SST              258 // Page Write command set#define CFI_PRIMARY_ID_RESERVED         65535// Device interface code assignment// CFI Publication 100#define CFI_INTERFACE_X8                0   // x8-only asynchronous interface#define CFI_INTERFACE_X16               1   // x16-only asynchronous inteface#define CFI_INTERFACE_X8_16             2   // x8 and x16 via BYTE# with asynchronous interface#define CFI_INTERFACE_X32               3   // x32-only asynchronous interface#define CFI_INTERFACE_X16_32            5   // x16 and x32 via WORD# with asynchronous interface#define CFI_INTERFACE_RESERVED          65535#define CFI_MAX_ERASE_REGIONS           8// Query ID structurestruct cfi_query_id {    unsigned char query[3];                 // 0x10 - 0x12 : query-unique ACSII string "QRY"    unsigned short primary_id;              // 0x13 - 0x14 : primary vendor command set and control interface ID code    unsigned short primary_table_addr;      // 0x15 - 0x16 : address for primary algorithm extended query table    unsigned short alternate_id;            // 0x17 - 0x18 : alternate vendor command set and control interface ID code    unsigned short alternate_table_addr;    // 0x19 - 0x1a : address for alternate algorithm extended query table    unsigned char vcc_min;                  // 0x1b : Vcc logic supply minimum voltage    unsigned char vcc_max;                  // 0x1c : Vcc logic supply maximum voltage    unsigned char vpp_min;                  // 0x1d : Vpp logic supply minimum voltage    unsigned char vpp_max;                  // 0x1e : Vpp logic supply maximum voltage    unsigned char timeout_single_write;     // 0x1f : typical timeout per single byte/word write    unsigned char timeout_buffer_write;     // 0x20 : typical timeout for minimum-size buffer write    unsigned char timeout_block_erase;      // 0x21 : typical timeout for individual block erase    unsigned char timeout_chip_erase;       // 0x22 : typical timeout for full chip erase    unsigned char max_timeout_single_write; // 0x23 : maximum timeout per single byte/word write    unsigned char max_timeout_buffer_write; // 0x24 : maximum timeout for minimum-size buffer write    unsigned char max_timeout_block_erase;  // 0x25 : maximum timeout for individual block erase    unsigned char max_timeout_chip_erase;   // 0x26 : maximum timeout for full chip erase    unsigned char device_size;              // 0x27 : device size = 2^n in number of bytes    unsigned short interface_desc;          // 0x28 - 0x29 : flash device interface description    unsigned short max_multibyte_write;     // 0x2a - 0x2b : maximum number of bytes in multi-byte write = 2^n    unsigned char num_erase_regions;        // 0x2c : number of erase block regions within device    unsigned int erase_region_info[CFI_MAX_ERASE_REGIONS];  // erase block region information                                            // bits 31-16 :                                             // bits 15-0 : } __attribute__((packed));struct cfi_eraseregions {    unsigned int start;    unsigned int size;    unsigned int blocks;};enum {     FLSTATE_READY,    FLSTATE_ERASING,    FLSTATE_WRITING,};// CFI information block used by this drivertypedef struct {    int exist;    int chip_state;    unsigned int base, size;    struct cfi_query_id ident;    struct cfi_eraseregions erase_regions[CFI_MAX_ERASE_REGIONS];    unsigned long addr_unlock1, addr_unlock2;} cfi_info_t;//// global variables//static int g_flash_inited = 0;static int g_flash_chips = 0;static cfi_info_t g_cfi[FLASH_MAX_CHIPSET];//// function prototypes//// data structure managementstatic cfi_info_t *get_free_cfi(void);static cfi_info_t *find_cfi(unsigned long addr);// CFI basic I/Ostatic __inline__ unsigned char cfi_readb(unsigned long addr) { return __raw_readb(addr); }static __inline__ unsigned short cfi_readw(unsigned long addr) { return __raw_readw(addr); }static __inline__ unsigned long cfi_readl(unsigned long addr) { return __raw_readl(addr); }static __inline__ void cfi_writeb(unsigned int val, unsigned long addr) { __raw_writeb(val, addr); mb(); }static __inline__ void cfi_writew(unsigned int val, unsigned long addr) { __raw_writew(val, addr); mb(); }static __inline__ void cfi_writel(unsigned int val, unsigned long addr) { __raw_writel(val, addr); mb(); }static __inline__ unsigned int cfi_read(unsigned long addr);static __inline__ void cfi_write(unsigned val, unsigned long addr);// CFI advanced I/Ostatic __inline__ unsigned int cfi_build_cmd_addr(unsigned long addr);static __inline__ unsigned int cfi_build_cmd(unsigned int cmd);static __inline__ void cfi_send_gen_cmd(unsigned int cmd, unsigned int cmd_addr, unsigned int base);// probing & setupstatic int cfi_probe_chip(cfi_info_t *pcfi);static int cfi_query_present(unsigned int base);static int cfi_chip_setup(cfi_info_t *pcfi);static void cfi_cmdset_0002(cfi_info_t *pcfi);// init & basicint flash_found(void);int flash_probe(unsigned int base, int force, int verbose);// eraseint flash_erase_all(void);int flash_erase_oneblock(unsigned long addr);int flash_erase_region(unsigned long addr, unsigned int len);// writeint flash_write_onebyte(unsigned long addr, unsigned int data);int flash_write_oneword(unsigned long addr, unsigned int data);static int flash_write_data_internal(unsigned long addr, unsigned short *data, int nwords, cfi_info_t *pcfi);int flash_write_data(unsigned long addr, unsigned char *data, int len);// miscellaneousstatic char *cfi_get_idname(unsigned int vendor);void flash_list(void *vpcfi);int flash_calcblock(unsigned long addr, unsigned int *pstart, unsigned int *plen);//// data structure management// cfi_info_t *get_free_cfi(void){    int i;    for (i = 0; i < FLASH_MAX_CHIPSET; ++i)        if (!g_cfi[i].exist)            return &g_cfi[i];    return NULL;}cfi_info_t *find_cfi(unsigned long addr){    int i;	     for (i = 0; i < FLASH_MAX_CHIPSET; ++i)        if (g_cfi[i].exist)             if (addr >= g_cfi[i].base && addr < g_cfi[i].base + g_cfi[i].size)                return &g_cfi[i];    return NULL;}//// CFI basic I/O//__inline__ unsigned int cfi_read(unsigned long addr){    unsigned int data;    switch (CFIDEV_BUSWIDTH) {    case 1 :         data = cfi_readb(addr);        break;    case 2 :         data = cfi_readw(addr);        break;    case 4 :        data = cfi_readl(addr);        break;    default :        return 0;    }#if FLASH_VERBOSE    uart_printf("FLASH Read addr = %08lx, data = %*x\n", addr, CFIDEV_BUSWIDTH * 2, data);#endif    return data;}__inline__ void cfi_write(unsigned val, unsigned long addr){#if FLASH_VERBOSE   // uart_printf("FLASH Write addr = %08lx, data = %*x\n", addr, CFIDEV_BUSWIDTH * 2, val);uart_printf("FLASH Write addr = %x, data = %x\n", addr, val);#endif    switch (CFIDEV_BUSWIDTH) {    case 1 :         cfi_writeb(val, addr);        break;    case 2 :         cfi_writew(val, addr);        break;    case 4 :        cfi_writel(val, addr);        break;    default :        return;    }}// // CFI advanced I/O//// bus width address => byte address__inline__ unsigned int cfi_build_cmd_addr(unsigned long addr){    return addr * CFIDEV_DEVTYPE * CFIDEV_INTERLEAVE;}__inline__ unsigned int cfi_build_cmd(unsigned int cmd){    unsigned int val = 0;    switch (CFIDEV_BUSWIDTH) {    case 1 :         val = cmd;        break;    case 2 :         if (CFIDEV_INTERLEAVE == 1)            val = cpu_to_cfi16(cmd);        else if (CFIDEV_INTERLEAVE == 2)            val = cpu_to_cfi16((cmd << 8) | cmd);        break;    case 4 :         if (CFIDEV_INTERLEAVE == 1)            val = cpu_to_cfi32(cmd);        else if (CFIDEV_INTERLEAVE == 2)            val = cpu_to_cfi32((cmd << 16) | cmd);        else if (CFIDEV_INTERLEAVE == 4) {            val = (cmd << 16) | cmd;            val = cpu_to_cfi32((val << 8) | val);        }        break;    default :        break;    }    return val;}__inline__ void cfi_send_gen_cmd(unsigned int cmd, unsigned int cmd_addr, unsigned int base){    cfi_write(cfi_build_cmd(cmd), base + cfi_build_cmd_addr(cmd_addr));}__inline__ void cfi_send_cmd(unsigned int cmd, unsigned int cmd_addr, unsigned int base){    cfi_write(cfi_build_cmd(cmd), base + cmd_addr);}//// probing & setup// int cfi_probe_chip(cfi_info_t *pcfi){    int ret;    unsigned long addr_probe1, addr_probe2;    unsigned int data_probe1, data_probe2;    if (pcfi->exist)        --g_flash_chips;    pcfi->exist = 0;    addr_probe1 = pcfi->base + cfi_build_cmd_addr(0);    addr_probe2 = pcfi->base + cfi_build_cmd_addr(0x55);    data_probe1 = cfi_read(addr_probe1);    data_probe2 = cfi_read(addr_probe2);    // Reset    cfi_send_gen_cmd(0xf0, 0, pcfi->base);    // Enter CFI Query mode    cfi_send_gen_cmd(0x98, 0x55, pcfi->base);    if ((ret = cfi_query_present(pcfi->base)) != 0) {        cfi_write(data_probe1, addr_probe1);        cfi_write(data_probe2, addr_probe2);        return ret;    }    pcfi->exist = 1;    ++g_flash_chips;    if ((ret = cfi_chip_setup(pcfi)) != 0)        return ret;    // Reset    cfi_send_gen_cmd(0xf0, 0, pcfi->base);    // internal settings    cfi_cmdset_0002(pcfi);    return FLASH_OK;}int cfi_query_present(unsigned int base){    return (cfi_read(base + cfi_build_cmd_addr(0x10)) == cfi_build_cmd('Q') &&        cfi_read(base + cfi_build_cmd_addr(0x11)) == cfi_build_cmd('R') &&        cfi_read(base + cfi_build_cmd_addr(0x12)) == cfi_build_cmd('Y')) ? FLASH_OK : FLASH_NOTEXIST;

⌨️ 快捷键说明

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