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

📄 flash_intel.c

📁 Embeded bootloader (rrload by ridgerun) for TI linux based platform v5.36
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (retry_tally++ < 3) {      goto retry;    }    else {      util_printf("Giving up!\n");      enable_read_mode(block_addr);      return 1; // failed    }  }#if 0 /* stuff that was helpful for a while on C547X but now doesn't seem necessary. */  {    unsigned long val;    enable_read_mode(block_addr);    val = *l_addr;    if (0xffffffff != val) { // basic sanity check.      util_printf("Erase error. block addr = 0x%X, l_addr = 0x%X, val = 0x%X\n",block_addr,l_addr,val);      status = read_status(block_addr);      util_printf("[status = 0x%x]\n",status);      util_printf("[retrying]\n");      if (retry_tally++ < 3) {        goto retry;      }      else {        util_printf("Giving up!\n");        enable_read_mode(block_addr);        return 1; // failed      }    }  }#endif    enable_read_mode(block_addr);  return 0; // success}#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS   /******************************    Routine:    Description:   ******************************/   static int prog_data_32(unsigned long *block_addr, unsigned long data)   {     #define PROG_CODE_32 0x00400040;     unsigned short status;     // util_printf("0x%X = 0x%X\n", block_addr, data); // *debug* tmp     if ((*block_addr & data) != data) {       // we can only change bits from a "1" to "0".       util_printf("Error, not previously erased; addr = 0x%X, data = 0x%X\n",block_addr,*block_addr);       return 1; // failed     }     clear_status((unsigned short *)block_addr);     if (0xBEEFFEED != FlashLockMode) {       util_printf("Error: Please Unlock Flash before trying to modify it.\n");       util_printf("       Giving up.\n");       return 1; // failed     }     *block_addr = PROG_CODE_32; // Put each chip in program mode, and then...     *block_addr = data;         // 16bits+16bits=32bits; Give each chip a 16bit data value.     while (is_busy((unsigned short *)block_addr)) {}     if (was_error((unsigned short *)block_addr)) {       status = read_status((unsigned short *)block_addr);       util_printf("Prog error. addr = %X, status = %x\n",block_addr,status);       clear_status((unsigned short *)block_addr);  // *debug* temp       util_printf("Prog error. addr = %X, status = %x\n",block_addr,status);       SYSTEM_FATAL("Terminating.");     }     enable_read_mode((unsigned short *)block_addr);     return 0; // success   }    #else   /******************************    Routine:    Description:   ******************************/   static int prog_data_16(unsigned short *block_addr, unsigned short data)   {     #define PROG_CODE_16 0x40;     unsigned short status;     // util_printf("0x%X = 0x%x\n", block_addr, data); // *debug* tmp     if ((*block_addr & data) != data) {       // we can only change bits from a "1" to "0".       util_printf("Error, not previously erased; addr = 0x%X, data = 0x%X\n",block_addr,*block_addr);       return 1; // failed     }     clear_status(block_addr);     if (0xBEEFFEED != FlashLockMode) {       util_printf("Error: Please Unlock Flash before trying to modify it.\n");       util_printf("       Giving up.\n");       return 1; // failed     }     *block_addr = PROG_CODE_16;     *block_addr = data;     while (is_busy(block_addr)) {}     if (was_error(block_addr)) {       status = read_status(block_addr);       util_printf("Prog error. addr = %X, status = %x\n",block_addr,status);       clear_status(block_addr);  // *debug* temp       util_printf("Prog error. addr = %X, status = %x\n",block_addr,status);       SYSTEM_FATAL("Terminating.");     }     enable_read_mode(block_addr);     return 0; // success   }#endif/****************************** 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;  // Flash; read word at a time, not byte at a time.  num_words = ((num_bytes+1)>>1); // round up.  for (i=0; i<num_words; i++) {    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){#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS  unsigned int i, failed, num_32bit_words;  unsigned long fval, *d_addr;  unsigned short fval_lo, fval_hi, *s_addr;  s_addr = src;  failed = 0;  d_addr = (unsigned long *)(BSPCONF_FLASH_BASE+offset);  if (2 == num_bytes) {    // -- Special Case--  The only time that    // we expect to see 2 bytes at a time coming in is    // during an XIP download directly to flash. In    // this case we'll have to except the two bytes (16bits)    // and cache it temporarily until the next call    // which gives us a second 16bit value which can    // be finally combined with the first to give us    // the 32bit unit we need for each flash operation.    // Summary, For c547x the minimum we can flash in    // one operation is 4 bytes (32bits), yet the XIP    // parser is feeding us 16bits at a time.    if (Cached_Short_valid) {      if (CBack) {        (*CBack)(s_addr,&fval_hi);      }      else {        fval_hi = *s_addr;      }      // Okay this is short number two, we've got 32bits      // worth of data and can send it to flash now.      fval = (fval_hi << 16) | Cached_Short;      failed = prog_data_32(Cached_flash_addr,fval);      if (failed) goto done;      Cached_Short_valid = 0;    }    else {      if (CBack) {        (*CBack)(s_addr,&Cached_Short);      }      else {        Cached_Short = *s_addr;      }      // Okay, cache it and wait for next call to give      // us another 16bits -- then we'll have the 32bits      // we need for the flash operation.      Cached_flash_addr = d_addr;      Cached_Short_valid = 1;    }  }  else {    // --Normal Case--    // Flash; write 32bits at a time.    num_32bit_words = ((num_bytes+3)>>2); // round up.    for (i=0; i<num_32bit_words; i++) {      if (CBack) {        (*CBack)(s_addr,  &fval_lo);        (*CBack)(s_addr+1,&fval_hi);      }      else {        fval_lo = *s_addr;        fval_hi = *(s_addr+1);      }      fval = (fval_hi << 16) | fval_lo;      failed = prog_data_32(d_addr,fval);      if (failed) break;      s_addr+=2;      d_addr++;    }  }#else  unsigned int i, failed, num_16bit_words;  unsigned short fval, *d_addr, *s_addr;  failed = 0;  s_addr = src;  d_addr = (unsigned short *)(BSPCONF_FLASH_BASE+offset);  // Flash; write 16bits at a time.  num_16bit_words = ((num_bytes+1)>>1); // round up.  for (i=0; i<num_16bit_words; i++) {    if (CBack) {      (*CBack)(s_addr,&fval);    }    else {      fval = *s_addr;    }    failed = prog_data_16(d_addr,fval);    if (failed) break;    s_addr++;    d_addr++;  }#endifdone:    if (failed) {    io_delay(6000);  }  return 0;}/****************************** Routine: Description:   Note: See flash.h for description. ******************************/int flash_flush(void){#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS  // This block became necessary for supporting XIP downloads  // on these style boards.  if (Cached_Short_valid) {    {      unsigned long final_val;      // We hadn't finished that last 32 bit flash write      // operation since we were waiting for a full 32 bit      // value. It looks like we are not going to get any      // more data so we'll fill out the remainder of that      // 32bit value with zeros and finish up the flash      // operation.      final_val = 0x0000 | Cached_Short;      prog_data_32(Cached_flash_addr,final_val);      Cached_Short_valid = 0;    }  }#endif  return -1; // *debug* finish later.}/****************************** Routine: Description:   Note: See flash.h for description. ******************************/void flash_erase(void){  // Erase the entire flash chip(s).  int i, failed;  unsigned short *ChipAddr;  for (i=0; i<TotalSectors; i++) {    util_printf("Erasing block %i of %i\n",i,TotalSectors);    ChipAddr = (unsigned short *)(SectInfoTable[i].start_addr);    failed = block_erase(ChipAddr);    if (failed) break;  }  if (failed) {    io_delay(6000);  }}/****************************** Routine: Description:   Note: See flash.h for description. ******************************/void flash_erase_range(int start_addr, int end_addr){  // Erases the indicated portion of the flash.  // Note: the whole block containing the start_addr as well as  // the whole block containing the end_addr, and all blocks  // in-between, are erased. Keep this in mind when forming  // your range request -- if not careful you will get more  // erased than your range defines due to the erase constraints  // of flash chips. They can only erase whole blocks.  int i, failed;  unsigned short *ChipAddr;  util_printf("Erasing blocks containing addresses 0x%X to 0x%X\n",start_addr,end_addr);  for (i=0; i<TotalSectors; i++) {    if ((SectInfoTable[i].start_addr >= start_addr) &&        (SectInfoTable[i].start_addr <= end_addr)) {      util_printf("Erasing block %i of %i\n",i,TotalSectors);      ChipAddr = (unsigned short *)(SectInfoTable[i].start_addr);      failed = block_erase(ChipAddr);      if (failed) break;    }  }  if (failed) {    io_delay(6000);  }}/****************************** Routine: Description:   Note: See flash.h for description. ******************************/int flash_init(void){  #define Intel_28F160F3_alt 0x008988F4 // examples, ti925 and ...  #define Intel_28F160F3     0x008988F3 // examples, omap1510-Helen/P1 and ...  #define Intel_28F128J3A    0x00890018 // examples, omap1510-Helen/P1, ti925 and ...  #define Intel_28F320_TB    0x00898896 // examples, C547X TopBoot devices and ...  #define Intel_28F320_BB    0x00898897 // examples, C547X BottomBoot devices and ...  int i, j, index, addr_tally;  unsigned long code;  short NumChipSectors;#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS  // This block became necessary for supporting XIP downloads  // on these style boards.  Cached_Short_valid = 0;  Cached_Short = 0;#endif    index = 0;  addr_tally = BSPCONF_FLASH_BASE;  (void)read_device_codes(&code);  // util_printf("device ID = 0x%X\n",code);  switch(code) {  case Intel_28F160F3:    NumChipSectors = NUM_CHIP_SECT;    TotalSectors   = TOTAL_SECT;    SectInfoTable  = sect_info;    for (j=0; j<NUM_SEQUENTIAL_CHIPS; j++) {      for (i=0; i<NumChipSectors; i++) {        SectInfoTable[index].start_addr = addr_tally;        addr_tally += sect_sizes[i];        SectInfoTable[index].end_addr = addr_tally-1;        index++;      }    }    return 160;    break;  case Intel_28F160F3_alt:    NumChipSectors = NUM_CHIP_SECT;    TotalSectors   = TOTAL_SECT;    SectInfoTable  = sect_info;    for (j=0; j<NUM_SEQUENTIAL_CHIPS; j++) {      for (i=0; i<NumChipSectors; i++) {        SectInfoTable[index].start_addr = addr_tally;        addr_tally += sect_sizes[i];        SectInfoTable[index].end_addr = addr_tally-1;        index++;      }    }    return 160;    break;  case Intel_28F320_TB:    NumChipSectors = NUM_CHIP_SECT_A;    TotalSectors   = TOTAL_SECT_A;    SectInfoTable  = sect_info_A;    for (j=0; j<NUM_SEQUENTIAL_CHIPS; j++) {      for (i=0; i<NumChipSectors; i++) {        SectInfoTable[index].start_addr = addr_tally;        addr_tally += sect_sizes_A[i];        SectInfoTable[index].end_addr = addr_tally-1;        index++;      }    }    return 320;    break;  case Intel_28F128J3A:    NumChipSectors = NUM_CHIP_SECT_B;    TotalSectors   = TOTAL_SECT_B;    SectInfoTable  = sect_info_B;    for (j=0; j<NUM_SEQUENTIAL_CHIPS; j++) {      for (i=0; i<NumChipSectors; i++) {        SectInfoTable[index].start_addr = addr_tally;        addr_tally += sect_sizes_B[i];        SectInfoTable[index].end_addr = addr_tally-1;        index++;      }    }    return 128;    break;  default:    util_printf("***************************************\n");    util_printf("Warning: Unknown flash device detected!\n");    util_printf("       : Detected device code = 0x%X   \n",code);    util_printf("***************************************\n");    util_printf("\n");#if 1        SYSTEM_FATAL("Terminating.");#else        io_delay(6000); // To prevent ui frontend from clearing the                     // screen before the user can read it.    return 160; // Hmmm? just return some default value.#endif        break;  }}

⌨️ 快捷键说明

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