?? btldr_pi.c127
字號:
// 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 *) ¤t_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; } switch (comp) {#ifdef REPLACE_VECTOR_TABLE case c_VECTORS: if (TRUE == comp_info[comp].is_SDRAM_resident) { ret |= flash_write(comp_flash_info[comp].START_OFFSET, (unsigned short *) (comp_info[comp].fheader.load_addr), comp_info[comp].fheader.num_bytes, NULL); if (ret == 0) { comp_info[comp].is_FLASH_resident = TRUE; } } break;#endif case c_BOOTLDR: if (TRUE == comp_info[comp].is_SRAM_resident) {// if (TRUE == comp_info[comp].is_SDRAM_resident) { ret |= flash_write(comp_flash_info[comp].START_OFFSET, (unsigned short *) (comp_info[comp].fheader.load_addr), comp_info[comp].fheader.num_bytes, get_val_from_addr); if (ret == 0) { comp_info[comp].is_FLASH_resident = TRUE; } } break; case c_PARAMS: if (TRUE == comp_info[comp].is_SRAM_resident) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -