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

📄 btldr_pi.c

📁 Embeded bootloader (rrload by ridgerun) for TI linux based platform v5.36
💻 C
📖 第 1 页 / 共 4 页
字号:
#define DFIFO_FLUSH (1 << 10)#define DEND_PROG   (1 << 11)#define DSYNC_SET   (1 << 6)#define DREPEAT     (1 << 9)#define DFRAME      (1 << 3)static void dma_flash_read(unsigned int offset_orig,  // Of flash.                           unsigned int dest_orig, // Destination buffer                           unsigned int num_bytes){        volatile dma_regs_t *regs = (dma_regs_t *)0xfffed800;    // channel 0        unsigned int remaining = num_bytes;        unsigned int offset = offset_orig;        unsigned int dest = dest_orig;        int error_count = 0;        // one-time setup:        regs->cicr = 0x2b;              // Show status on Block or Frame done, or on errors (timeout, drop)        regs->ccr = ((1 << 14) |        // source,destn auto increment, high priority, flush                     (1 << 12) |                     (1 << 10) |                     (1 << 6));        regs->csdp = ((3 << 14) |       // source EMIFS, destn EMIFF, burst 8 if possible, s32 bit transfers                      (3 << 7) |                      (1 << 2) |                      2);        regs->cfn = 1;        regs->cfi = 0;        regs->cei = 0;                        // Per-transfer setup:        while (remaining) {                int num_transferred;                int status;                // Arbitrary transfer size of 4000 elements (= 16K bytes)                if (error_count == 0) {                        if (remaining > 0x4000) {                                remaining -= 0x4000;                                num_transferred = 0x1000;                        }                        else {                                num_transferred = remaining;                                remaining = 0;                                regs->csdp &= ~0x3;    // switch to byte transfers for last packet                        }                }                               // Setup transfer                regs->cssa_l = offset;                regs->cssa_u = offset >> 16;                regs->cdsa_l = dest;                regs->cdsa_u = dest >> 16;                regs->cen = num_transferred;                // Clear status                status = regs->csr;                // Start transfer                regs->ccr |= DCCR_EN;                        // Check transfer status                status = regs->csr;                while ((regs->ccr & DCCR_EN) &&                       ((status & 0xb) == 0)) {                        status = regs->csr;                }#if 0                          if (regs->ccr & DCCR_EN) {                        util_printf("ccr is %X\n", regs->ccr);                        util_printf("status is %X\n", status);                }#endif                if (status & DCSR_ERROR) {                        util_printf("DMA error, status is %X\n", status);                        error_count++;                        util_printf("Retrying DMA count : %d\n", error_count);                }                else {                        error_count = 0;                }                                // Too many errors, go to normal copy.                if (error_count == 10) break;                // Go to next buffer                if (error_count == 0) {                        offset += num_transferred * 4;                        dest += num_transferred * 4;                }        }#if 0        // Data check.  Very slow.        {                unsigned char *source = offset_orig;                unsigned char *destn = dest_orig;                unsigned int count = 0;                for (remaining = 0; remaining < num_bytes; remaining++) {                        if (*source != *destn) {                                util_printf("source : 0x%x, source value : 0x%x\n", source, *source);                                util_printf("destn : 0x%x, destn value : 0x%x\n", destn, *destn);                                count++;                        }                        source++;                        destn++;                        while (count == 10);                }        }#endif        // DMA didn't work, try slow copy        if (error_count) {                util_printf("DMA copy had errors, trying slow copy\n");                flash_read(offset_orig,                           (unsigned short *)dest_orig,                           num_bytes,                           put_val_at_addr_2);                        }}// endif   OMAP1510// Any other platforms can use this Psuedo dma (it's faster than a byte copy).#elsestatic void dma_flash_read(unsigned int offset, // Of flash.                           unsigned int dest,   // Destination buffer                           unsigned int num_bytes){    //util_printf("\nin psuedo dma copy\n");    //util_printf("%X %X %X\n", offset, dest, num_bytes);    offset += BSPCONF_FLASH_BASE;    if ((offset & 3) || (dest & 3))    {        flash_read(offset, (unsigned short *)dest, num_bytes, NULL);                        return;    }    if (num_bytes >= 24)    {        // Note:        // Our objective below is to copy a chunk of bytes from a source        // memory address to a new destination location. We'll be moving        // 24 bytes at at time.        // first set reg r1 == destination memory address,        // next  set reg r2 == source memory address,        // then  set reg r12 == num bytes to move,        // lastly drop into a loop which copies 24 bytes at a time until        // all bytes are copied. This will take advantage of the        // "ldmia r2!,{r3-r8)" style assembly instruction which loads        // in one fell swoop the six registers (r3-r8) with a total of        // 24 continguous bytes read from the memory address reflected        // by register r2 (and r2 is then automatically incremented by 24).        // Now that the data registers are loaded, we can perform a        // "stmia r1!,{r3-r8}" style instruction to move all 24        // continuous bytes to the destination memory location reflected        // by register r1 (and r1 is then automatically incremented by 24).        // Finally, subtract our byte count by 24 and see if another pass        // through the loop is needed. (I stepped through the code with        // a debugger and that is how I know *all* the participating        // registers used by the compiler for the algorithm below).        num_bytes -= 24;        asm volatile ("loop: \                    \n ldmia   %0!,{r3 - r8} \                    \n stmia   %1!,{r3 - r8} \                    \n subs    %2, %2, #24 \                    \n bge     loop"                     : "+r" (offset), "+r" (dest), "+r" (num_bytes)                     : "r" (offset), "r" (dest), "r" (num_bytes)                     : "cc","r3","r4","r5","r6","r7","r8");    }    num_bytes +=24;    if (num_bytes)    {        unsigned char *p1,*p2;        p1 = (unsigned char *) offset;        p2 = (unsigned char *) dest;        while (num_bytes)        {            *p2++ = *p1++;            num_bytes--;        }    }}#endif/****************************** Routine: Description: ******************************/static void pull_from_flash(comp_t comp){  MAGIC_t magicn;  char *image_start_in_flash;  switch (comp) {    case c_PARAMS:      flash_read(comp_flash_info[comp].START_OFFSET,                 (unsigned short *) &magicn,                 sizeof(MAGIC_t),                 NULL);      if (comp_flash_info[comp].MAGIC_NUM == magicn) {        flash_read(comp_flash_info[comp].START_OFFSET + sizeof(MAGIC_t),                   (unsigned short *) &current_params,                   sizeof(current_params),                   NULL);#if defined(DSC24_OSD)        if (0 == util_strncmp("yes",current_params.OSD_enable,util_strlen("yes")))        {            unsigned char *optr;            flash_read(comp_flash_info[comp].START_OFFSET + sizeof(MAGIC_t) + sizeof(current_params),                       (unsigned short *) &(comp_info[comp].fheader),                       sizeof(FHEADER_t),                       NULL);            if (io_AddressIsInFlashSpace(comp_info[comp].fheader.load_addr)) {              // This component is intended to be used in-place. It              // has a load_addr that is in flash space which means              // that when the user originally "loaded" this component              // the srec or rrbin or ?? image indicated that it was to              // load into flash space. In this case there is no need              // to move it to SDRAM before using it.               return;            }            optr = (unsigned char *) comp_info[comp].fheader.load_addr;            osd_init();#if 1 //defined(DSC21) || defined(DSC24) || defined(DSC25) || defined(DM270) || defined(DM310) || defined(OMAP1510)            dma_flash_read(comp_flash_info[comp].START_OFFSET +			     sizeof(MAGIC_t) + sizeof(current_params) +			     sizeof(FHEADER_t),			   comp_info[comp].fheader.load_addr,			   comp_info[comp].fheader.num_bytes);        #else            flash_read(comp_flash_info[comp].START_OFFSET +		         sizeof(MAGIC_t) + sizeof(current_params) +		         sizeof(FHEADER_t),		       (unsigned short *) (comp_info[comp].fheader.load_addr),		       comp_info[comp].fheader.num_bytes,		       put_val_at_addr_2);#endif            osd_init_mem(*(optr + 8));            osd_load_logo((unsigned char *)(optr + 8),  // Start of data                           *((int *)(optr + 4)),        // Vertical size of logo                           *((int *) optr));            // Horizontal size            osd_display();        }#endif        comp_info[comp].is_SDRAM_resident = TRUE;      }      break;    case c_KERNEL:    case c_FILESYS:      flash_read(comp_flash_info[comp].START_OFFSET,                 (unsigned short *) &magicn,                 sizeof(MAGIC_t),                 NULL);      if (comp_flash_info[comp].MAGIC_NUM == magicn) {        flash_read(comp_flash_info[comp].START_OFFSET + sizeof(MAGIC_t),                   (unsigned short *) &(comp_info[comp].fheader),                   sizeof(FHEADER_t),                   NULL);        if (io_AddressIsInFlashSpace(comp_info[comp].fheader.load_addr)) {          // This component is intended to be used in-place. It          // has a load_addr that is in flash space which means          // that when the user originally "loaded" this component          // the srec or rrbin or ?? image indicated that it was to          // load into flash space. In this case there is no need          // to move it to SDRAM before using it.           return;        }	// Either a straight copy of a decompress and copy is required.	image_start_in_flash = (char *)comp_flash_info[comp].START_OFFSET +	                       BSPCONF_FLASH_BASE +	                       sizeof(MAGIC_t) + sizeof(FHEADER_t);#if ( BSPCONF_KERNEL_COMPRESSED == 1 ) ||  ( BSPCONF_FS_COMPRESSED == 1 )	if (image_is_compressed(image_start_in_flash)) {	  (void)decompress_comp((char *)comp_info[comp].fheader.load_addr,				free_memory_start,				free_memory_size,				image_start_in_flash,				comp_info[comp].fheader.num_bytes);	}	else#endif	  {        // Next, move the image to SDRAM as per the        // value of load_addr recorded with the image.#if 1 //defined(DSC21) || defined(DSC24) || defined(DSC25) || defined(DM270) || defined(DM310) || defined(OMAP1510)	  dma_flash_read(comp_flash_info[comp].START_OFFSET + 			 sizeof(MAGIC_t) + sizeof(FHEADER_t),			 comp_info[comp].fheader.load_addr,			 comp_info[comp].fheader.num_bytes);        #else	  flash_read(comp_flash_info[comp].START_OFFSET + 		     sizeof(MAGIC_t) + sizeof(FHEADER_t),		     (unsigned short *) (comp_info[comp].fheader.load_addr),		     comp_info[comp].fheader.num_bytes,		     put_val_at_addr_2);#endif	  comp_info[comp].is_SDRAM_resident = TRUE;        // util_printf("retrieved -- load_addr 0x%X, entry_addr 0x%X, num_bytes 0x%X\n",        //             comp_info[comp].fheader.load_addr,        //             comp_info[comp].fheader.entry_addr,        //             comp_info[comp].fheader.num_bytes); // *debug* temp.	}      }      break;    case c_BOOTLDR:      // Pull this to SDRAM, why? Ignore this request since      // for the bootldr the very act of doing so would pull      // bytes down on top of the very program running now,      // presumably at that same SDRAM location. So, for this      // particular implementation of the btldr_pi.h      // programmer's interface, we will not support this type      // of flash -> SDRAM copy request.#ifdef REPLACE_VECTOR_TABLE    case c_VECTORS:#endif      break;    default:      SYSTEM_FATAL("Logic Error");      break;  }}/****************************** Routine: Description: ******************************/static int flash_area_has_content(comp_t comp){  unsigned short test_word;    return FALSE; // *debug* temp  // A Quick-and-Dirty test to see if the area of flash  // that normally holds component "comp" is already occupied  // with content.  switch (comp) {    case c_BOOTLDR:    case c_PARAMS:    case c_KERNEL:    case c_FILESYS:#ifdef REPLACE_VECTOR_TABLE    case c_VECTORS:#endif      // good it's one we recognize.      break;    default:      // what?, just return.     return TRUE;     break;  }  flash_read(comp_flash_info[comp].START_OFFSET,             (unsigned short *)&test_word,             sizeof(unsigned short),             NULL);  if (0xFFFF == test_word) {    // no content, this area of flash appears to be empty (erased).    return FALSE;  }  else {    // content found.     return TRUE;  }}/****************************** Routine: Description: returns non-zero if flash write error occurred ******************************/static int push_to_flash(comp_t comp){  int status;  int ret = 0;    if (TRUE == flash_area_has_content(comp)) {    util_printf("Warning: Can't overwrite existing one; Aborting\n");    util_printf("Press <Enter>....\n");    util_gets(cmd,CMDMAX);    return 0;

⌨️ 快捷键说明

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