void target_init(void) { #if defined(NAND_BOOT_INCLUDE) ASSERT(NAND_MTD_PARTITION_NUM == num_parts); unsigned offset; unsigned total_num_of_blocks; unsigned blocks_per_megabytes; unsigned next_ptr_start_adr = 0; int ret, i; struct flash_info *flash_info; bool start_addr_changed = false; unsigned long long nMTDReserved_Num=0; // total number of MTD Reserved Area TNFTL_MTDBadBlkInfo MTDBadBlkInfo[num_parts]; ///////////////////////////////////////////////////////////////////////////////////////////// unsigned long long nROAreaSize, nPartitionSize = 0; unsigned long int nBlockSize, nBlockSize_MB; unsigned int nDevPBpV, nDevBBpZ, nDevBBpV, nRervRate; unsigned int j, nUserDataArea = 0; struct ptable sPartition_List; memset( MTDBadBlkInfo, 0, sizeof(TNFTL_MTDBadBlkInfo) * num_parts ); edi_init(); #endif dprintf(ALWAYS, "target_init()\n"); keys_init(); keypad_init(); #if defined(BOOTSD_INCLUDE) if (target_is_emmc_boot()) { emmc_boot_main(); return ; } #endif #if defined(NAND_BOOT_INCLUDE) #if defined(TNFTL_V8_INCLUDE) if (check_fwdn_mode()) { fwdn_start(); return; } flash_boot_main(); #else if ( ( flash_get_ptable() == NULL ) ) { ptable_init(&flash_ptable); flash_set_partnum( num_parts ); flash_init(); flash_info = flash_get_info(); ASSERT(flash_info); if ( (flash_info->num_blocks) && (!flash_check_table()) ) { memcpy( sPartition_List.parts, board_part_list, sizeof( struct ptentry ) * num_parts ); flash_get_DevPBpV( &nDevPBpV, &nDevBBpZ, &nMTDReserved_Num ); nROAreaSize = (unsigned long long)( nMTDReserved_Num << 20 ); nBlockSize = flash_info->page_size << flash_info->ShiftPpB; // Set Block Size ( Byte Size ) //nROAreaSize = flash_info->num_blocks * nBlockSize; // Set Total ROArea Size ( Byte Size ) nBlockSize_MB = nBlockSize / ( 1 << 20 ); if( nBlockSize_MB > 1 ) // If Block is over the 1MB. Block must aligned. { // ex) Block Size 2MB, If Partition Size is 3MB. Partition Block Number must be 2. not 1. if( nBlockSize_MB == 2 ) // If Block Size 2MB. { for( i = 0; i < num_parts; i++ ) { if( sPartition_List.parts[i].length & 0x01 ) sPartition_List.parts[i].length++; } } else if ( nBlockSize_MB == 4 ) // If Block Size 4MB { unsigned int nDiff_Val; for( i = 0; i < num_parts; i++ ) { nDiff_Val = sPartition_List.parts[i].length & 0x03; if( nDiff_Val ) sPartition_List.parts[i].length += ( 4 - nDiff_Val ); } } } nMTDReserved_Num = ( nMTDReserved_Num << 20 ) / nBlockSize; nDevBBpV = ( nDevPBpV / 1024 ) * nDevBBpZ; nRervRate = ( nMTDReserved_Num * 100 ) / nDevPBpV; nDevBBpV = ( nDevBBpV * nRervRate ) / 100; if( nRervRate != 0 ) nRervRate = ( 100 / nRervRate ); nMTDReserved_Num = nRervRate + nDevBBpV; // Setup ROArea Reserved Block if(nMTDReserved_Num == 0) nMTDReserved_Num = 2; else if ( nMTDReserved_Num & 0x01 ) nMTDReserved_Num++; if( flash_info->ExtInterrupt == TRUE ) nMTDReserved_Num = nMTDReserved_Num << 1; for( i = 0; i < num_parts; i++ ) { if( sPartition_List.parts[i].length != VARIABLE_LENGTH ) { sPartition_List.parts[i].length = (unsigned long long)(sPartition_List.parts[i].length << 20); // Convert Length Unit. MByte -> Byte nPartitionSize += sPartition_List.parts[i].length; //ND_TRACE("sPartition_List.parts[%d].length:%lld [nPartitionSize:%d]\n", i, sPartition_List.parts[i].length, nPartitionSize); } else { nUserDataArea = i; } } if( nUserDataArea != 0 ) { sPartition_List.parts[nUserDataArea].length = nROAreaSize - nPartitionSize; // Calculate UserDataArea Size ( include Rerv Block ) //ND_TRACE("sPartition_List.parts[5].length:%lld [nPartitionSize:%d]\n", i, sPartition_List.parts[5].length, nPartitionSize); //sPartition_List.parts[nUserDataArea].length -= (nMTDReserved_Num * nBlockSize ); // UserDataArea Size. Reverved Block Removed } i = 1; sPartition_List.parts[0].length /= nBlockSize; // Partition 0 Length ( Block Unit ) MTDBadBlkInfo[0].PartBlkNum = sPartition_List.parts[0].length; // Set Block Number Each Partition do { sPartition_List.parts[i].length /= nBlockSize; // Partition i Length ( Block Unit ) sPartition_List.parts[i].start = sPartition_List.parts[i-1].start + sPartition_List.parts[i-1].length; MTDBadBlkInfo[i].PartBlkNum = sPartition_List.parts[i].length; // Set Block Number Each Partition ++i; } while( i < num_parts ); flash_set_rervnum( nMTDReserved_Num ); // Set Reserved Block Number flash_set_badblkinfo( MTDBadBlkInfo ); // Set Bad Block Table Info. About Block Number Each Partition for( i = 0; i < num_parts; i++ ) { ptable_add(&flash_ptable, sPartition_List.parts[i].name, flash_info->offset + sPartition_List.parts[i].start, sPartition_List.parts[i].length, sPartition_List.parts[i].flags); } ND_TRACE("\n-------------- [ Partition Table ] --------------\n"); for( i = 0; i < num_parts; i++ ) { ND_TRACE(" [Part %2d.%9s] [Start:%4d] [Length:%4d]\n", i, sPartition_List.parts[i].name ,sPartition_List.parts[i].start + flash_info->offset, sPartition_List.parts[i].length ); } ND_TRACE("-------------------------------------------------\n"); dprintf(INFO, "[NAND ] [Maker:0x%02x ][Device:0x%02x][Page_size:%d]\n", flash_info->vendor, flash_info->device, flash_info->page_size); dprintf(INFO, " [Spare_Size:%d][Block_Size:%d][MTD_TotalBlock:%d]\n", flash_info->spare_size, flash_info->block_size, flash_info->num_blocks); //dprintf(INFO, " [Spare_Size:%d][Block_Size:%d][MTD_Block:%d][Rerv_Block:%d]\n", // flash_info->spare_size, flash_info->block_size, flash_info->num_blocks - (U32)nMTDReserved_Num, (U32)nMTDReserved_Num); //ptable_dump(&flash_ptable); flash_set_ptable(&flash_ptable); ret = flash_set_badblktable(); if( ret != SUCCESS ) { dprintf(INFO, " !!! Fail Create Bad Block Table. [func:%s] [line:%d] !!! \n", __func__, __LINE__ ); ASSERT(-1); } flash_set_tablestatus(TRUE); } } #endif #endif }
void target_init(void) { unsigned offset; struct flash_info *flash_info; unsigned total_num_of_blocks; unsigned next_ptr_start_adr = 0; unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive */ int i; dprintf(INFO, "target_init()\n"); #if (!ENABLE_NANDWRITE) keys_init(); keypad_init(); #endif /* Display splash screen if enabled */ #if DISPLAY_SPLASH_SCREEN display_init(); dprintf(SPEW, "Diplay initialized\n"); #endif if (target_is_emmc_boot()) { /* Must wait for modem-up before we can intialize MMC. */ while (readl(MSM_SHARED_BASE + 0x14) != 1) ; if (mmc_boot_main(MMC_SLOT, MSM_SDC3_BASE)) { dprintf(CRITICAL, "mmc init failed!"); ASSERT(0); } return; } ptable_init(&flash_ptable); smem_ptable_init(); flash_init(); flash_info = flash_get_info(); ASSERT(flash_info); offset = smem_get_apps_flash_start(); if (offset == 0xffffffff) while (1) ; total_num_of_blocks = flash_info->num_blocks; blocks_per_1MB = (1 << 20) / (flash_info->block_size); for (i = 0; i < num_parts; i++) { struct ptentry *ptn = &board_part_list[i]; unsigned len = ((ptn->length) * blocks_per_1MB); if (ptn->start != 0) ASSERT(ptn->start == DIFF_START_ADDR); ptn->start = next_ptr_start_adr; if (ptn->length == VARIABLE_LENGTH) { unsigned length_for_prt = 0; unsigned j; for (j = i + 1; j < num_parts; j++) { struct ptentry *temp_ptn = &board_part_list[j]; ASSERT(temp_ptn->length != VARIABLE_LENGTH); length_for_prt += ((temp_ptn->length) * blocks_per_1MB); } len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); ASSERT(len >= 0); } next_ptr_start_adr = ptn->start + len; ptable_add(&flash_ptable, ptn->name, offset + ptn->start, len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); } smem_add_modem_partitions(&flash_ptable); ptable_dump(&flash_ptable); flash_set_ptable(&flash_ptable); }
void target_init(void) { unsigned offset; struct flash_info *flash_info; unsigned total_num_of_blocks; unsigned next_ptr_start_adr = 0; unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ unsigned base_addr; unsigned char slot; int i; dprintf(INFO, "target_init()\n"); #if (!ENABLE_NANDWRITE) keys_init(); keypad_init(); #endif if (target_is_emmc_boot()) { /* Trying Slot 2 first */ slot = 2; base_addr = mmc_sdc_base[slot-1]; if(mmc_boot_main(slot, base_addr)) { /* Trying Slot 4 next */ slot = 4; base_addr = mmc_sdc_base[slot-1]; if(mmc_boot_main(slot, base_addr)) { dprintf(CRITICAL, "mmc init failed!"); ASSERT(0); } } return; } ptable_init(&flash_ptable); smem_ptable_init(); flash_init(); flash_info = flash_get_info(); ASSERT(flash_info); enable_interleave_mode(target_is_interleaved_mode()); offset = smem_get_apps_flash_start(); if (offset == 0xffffffff) while(1); total_num_of_blocks = flash_info->num_blocks; blocks_per_1MB = (1 << 20) / (flash_info->block_size); for (i = 0; i < num_parts; i++) { struct ptentry *ptn = &board_part_list[i]; unsigned len = ((ptn->length) * blocks_per_1MB); if(ptn->start != 0) ASSERT(ptn->start == DIFF_START_ADDR); ptn->start = next_ptr_start_adr; if(ptn->length == VARIABLE_LENGTH) { unsigned length_for_prt = 0; unsigned j; for (j = i+1; j < num_parts; j++) { struct ptentry *temp_ptn = &board_part_list[j]; ASSERT(temp_ptn->length != VARIABLE_LENGTH); length_for_prt += ((temp_ptn->length) * blocks_per_1MB); } len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); ASSERT(len >= 0); } next_ptr_start_adr = ptn->start + len; if(target_is_interleaved_mode()) { ptable_add(&flash_ptable, ptn->name, offset + (ptn->start / 2), (len / 2), ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); } else { ptable_add(&flash_ptable, ptn->name, offset + ptn->start, len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); } } smem_add_modem_partitions(&flash_ptable); ptable_dump(&flash_ptable); flash_set_ptable(&flash_ptable); }
/*----------------------------------------------------------------------- * flash_init() * * sets up flash_info and returns size of FLASH (bytes) */ unsigned long flash_init (void) { unsigned long size = 0; int i; u32 regvalue,kk0 = 0xF,kk1 = 0xF ; char *s; #if 1 s = getenv("twe0"); //printf("twe0 set to %s\n",s); if(s) kk0 = simple_strtoul (s, NULL, 16); s = getenv("toe0"); //printf("toe0 set to %s\n",s); if(s) kk1 = simple_strtoul (s, NULL, 16); #if defined(RT3883_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) regvalue = *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0700); #else regvalue = *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0308); #endif #ifdef DEBUG printf("\n Default FLASH_CFG0 = %08X \n",regvalue); #endif regvalue &= ~(0x3 << 26); regvalue |= (0x1 << 26); regvalue |= (0x1 << 24); regvalue &= ~(0x3 << 20); regvalue |= (0x1 << 20); regvalue &= ~(0x3 << 16); regvalue |= (0x1 << 16); regvalue &= ~(0xF << 12); regvalue |= (kk0 << 12); regvalue &= ~(0xF << 8); regvalue |= (kk1 << 8); #ifdef DEBUG printf("\n Ready Set Value = 0x%08X\n",regvalue); #endif #if defined(RT3883_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0700) = regvalue; #else *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0308) = regvalue; #endif #if defined(RT3883_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) regvalue = *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0700); #else regvalue = *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0308); #endif #ifdef DEBUG printf("\n Setup FLASH_CFG0 = %08X \n",regvalue); #endif #endif /* Init: no FLASHes known */ for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) { ulong flashbase = PHYS_FLASH_START; #if defined (RT3052_MP2) && defined (ON_BOARD_32M_FLASH_COMPONENT) if (i == 1) ulong flashbase = PHYS_FLASH2_START; #endif #if 1 memset(&flash_info[i], 0, sizeof(flash_info_t)); #endif flash_info[i].size = flash_get_size((FPW *)flashbase, &flash_info[i]); if (flash_info[i].flash_id == FLASH_UNKNOWN) { printf("## Unknown FLASH on Bank %d - Size = 0x%08lx\n", i, flash_info[i].size); } size += flash_info[i].size; } #if 1 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE /* monitor protection ON by default */ flash_protect(FLAG_PROTECT_SET, PHYS_FLASH_1, PHYS_FLASH_1+monitor_flash_len-1, flash_get_info(PHYS_FLASH_1)); #ifdef DEBUG printf("\n monitor protection ON by default,monitor_flash_len = %d \n",monitor_flash_len); #endif #endif #endif #ifndef CFG_RUN_CODE_IN_RAM //CFG_ENV_IS_IN_FLASH /* ENV protection ON by default */ #ifdef DEBUG printf("\n ENV protection ON by default !! \n"); #endif flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR, CFG_ENV_ADDR+CFG_ENV_SIZE-1, flash_get_info(CFG_ENV_ADDR)); #endif return size; }
unsigned long flash_init (void) { unsigned int i; unsigned long size_b0 = 0, size_b1 = 0; unsigned long base, flash_size; /* Init: no FLASHes known */ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { flash_info[i].flash_id = FLASH_UNKNOWN; } /* the boot flash */ base = CFG_FLASH_BASE; #ifndef CFG_BOOT_FLASH_WIDTH #define CFG_BOOT_FLASH_WIDTH 1 #endif size_b0 = flash_get_size(CFG_BOOT_FLASH_WIDTH, (vu_long *)base, &flash_info[0]); #ifndef CONFIG_P3G4 printf("["); print_size (size_b0, ""); printf("@%08lX] ", base); #endif if (flash_info[0].flash_id == FLASH_UNKNOWN) { printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n", base, size_b0, size_b0<<20); } base = memoryGetDeviceBaseAddress(CFG_EXTRA_FLASH_DEVICE); for(i=1;i<CFG_MAX_FLASH_BANKS;i++) { unsigned long size = flash_get_size(CFG_EXTRA_FLASH_WIDTH, (vu_long *)base, &flash_info[i]); #ifndef CONFIG_P3G4 printf("["); print_size (size, ""); printf("@%08lX] ", base); #endif if (flash_info[i].flash_id == FLASH_UNKNOWN) { if(i==1) { printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n", base, size_b1, size_b1<<20); } break; } size_b1+=size; base+=size; } #if CFG_MONITOR_BASE >= CFG_FLASH_BASE /* monitor protection ON by default */ flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE, CFG_MONITOR_BASE + monitor_flash_len - 1, flash_get_info(CFG_MONITOR_BASE)); #endif #ifdef CFG_ENV_IS_IN_FLASH /* ENV protection ON by default */ flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR, CFG_ENV_ADDR + CFG_ENV_SIZE - 1, flash_get_info(CFG_ENV_ADDR)); #endif flash_size = size_b0 + size_b1; return flash_size; }
void update_ptable_apps_partitions(void) { uint32_t ptn_index, name_index = 0; uint32_t end = 0xffffffff; uint32_t name_size = strlen(ptable_ptn_names[name_index]); struct ptentry *ptentry_ptr = flash_ptable.parts; struct ptentry *fota_ptn; unsigned int size; fota_ptn = ptable_find(&flash_ptable, "FOTA"); /* Check for FOTA partitions and their size */ if (fota_ptn != NULL) { if (fota_ptn->length > 0) { /* FOTA partitions are present */ apps_ptn_flag[2] = 1; apps_ptn_flag[3] = 1; apps_ptn_flag[4] = 1; apps_ptn_flag[5] = 1; apps_ptn_flag[6] = 1; } } for (ptn_index = 0; ptentry_ptr[ptn_index].start != end; ptn_index++) { if (!(strncmp(ptentry_ptr[ptn_index].name, ptable_ptn_names[name_index], name_size))) { name_size = strlen(apps_ptn_names[name_index]); name_size++; /* For null termination */ /* Update the partition names to something familiar */ if (name_size <= MAX_PTENTRY_NAME) strncpy(ptentry_ptr[ptn_index].name, apps_ptn_names[name_index], name_size); /* Aboot uses modem page layout, leave aboot ptn */ if (name_index != 0) ptentry_ptr[ptn_index].type = TYPE_APPS_PARTITION; /* Check for valid partitions * according to the apps_ptn_flag */ do { /* Don't go out of bounds */ name_index++; if (name_index >= ptn_name_count) goto ptn_name_update_done; name_size = strlen(ptable_ptn_names[name_index]); } while (!apps_ptn_flag[name_index]); } } ptn_name_update_done: /* Update the end to be actual end for grow partition */ ptn_index--; for (; ptentry_ptr[ptn_index].length != end; ptn_index++) { }; /* If SMEM ptable is updated already then don't manually update this */ if (ptentry_ptr[ptn_index].start != end) ptentry_ptr[ptn_index].length = ((struct flash_info *)flash_get_info())->num_blocks - ptentry_ptr[ptn_index].start; }
void target_init(void) { unsigned offset; struct flash_info *flash_info; unsigned total_num_of_blocks; bool start_addr_changed = false; unsigned next_ptr_start_adr = 0; int i; dprintf(INFO, "target_init()\n"); #if (!ENABLE_NANDWRITE) keys_init(); keypad_init(); #endif if (target_is_emmc_boot()) return; ptable_init(&flash_ptable); smem_ptable_init(); flash_init(); flash_info = flash_get_info(); ASSERT(flash_info); offset = smem_get_apps_flash_start(); if (offset == 0xffffffff) while(1); total_num_of_blocks = (flash_info->block_size)/NUM_PAGES_PER_BLOCK; for (i = 0; i < num_parts; i++) { struct ptentry *ptn = &board_part_list[i]; unsigned len = ptn->length; if(len == VARIABLE_LENGTH) { start_addr_changed = true; unsigned length_for_prt = 0; unsigned j; for (j = i+1; j < num_parts; j++) { struct ptentry *temp_ptn = &board_part_list[j]; ASSERT(temp_ptn->length != VARIABLE_LENGTH); length_for_prt += temp_ptn->length; } len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); ASSERT(len >= 0); next_ptr_start_adr = ptn->start + len; } if((ptn->start == DIFF_START_ADDR) && (start_addr_changed)) { ASSERT(next_ptr_start_adr); ptn->start = next_ptr_start_adr; next_ptr_start_adr = ptn->start + ptn->length; } ptable_add(&flash_ptable, ptn->name, offset + ptn->start, len, ptn->flags); } ptable_dump(&flash_ptable); flash_set_ptable(&flash_ptable); }
void target_init(void) { unsigned offset; struct flash_info *flash_info; unsigned total_num_of_blocks; unsigned next_ptr_start_adr = 0; unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ int i; dprintf(INFO, "target_init()\n"); #if (!ENABLE_NANDWRITE) keys_init(); keypad_init(); #endif if (target_is_emmc_boot()) return; ptable_init(&flash_ptable); smem_ptable_init(); flash_init(); flash_info = flash_get_info(); ASSERT(flash_info); offset = smem_get_apps_flash_start(); if (offset == 0xffffffff) while(1); total_num_of_blocks = flash_info->num_blocks; blocks_per_1MB = (1 << 20) / (flash_info->block_size); for (i = 0; i < num_parts; i++) { struct ptentry *ptn = &board_part_list[i]; unsigned len = ((ptn->length) * blocks_per_1MB); if(ptn->start != 0) ASSERT(ptn->start == DIFF_START_ADDR); ptn->start = next_ptr_start_adr; if(ptn->length == VARIABLE_LENGTH) { unsigned length_for_prt = 0; unsigned j; for (j = i+1; j < num_parts; j++) { struct ptentry *temp_ptn = &board_part_list[j]; ASSERT(temp_ptn->length != VARIABLE_LENGTH); length_for_prt += ((temp_ptn->length) * blocks_per_1MB); } len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); ASSERT(len >= 0); } next_ptr_start_adr = ptn->start + len; ptable_add(&flash_ptable, ptn->name, offset + ptn->start, len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); } smem_add_modem_partitions(&flash_ptable); ptable_dump(&flash_ptable); flash_set_ptable(&flash_ptable); }
void target_init(void) { struct flash_info *flash_info; unsigned start_block; unsigned blocks_per_plen = 1; //blocks per partition length unsigned nand_num_blocks; keys_init(); keypad_init(); uint16_t keys[] = {KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_SOFT1, KEY_SEND, KEY_CLEAR, KEY_BACK, KEY_HOME}; for(unsigned i=0; i< sizeof(keys)/sizeof(uint16_t); i++) if (keys_get_state(keys[i]) != 0) { display_init(); display_lk_version(); //dprintf(ALWAYS,"key %d pressed\n", i); break; } dprintf(INFO, "htcleo_init\n"); if(get_boot_reason()==2) // booting for offmode charging, start recovery so kernel will charge phone { boot_into_recovery = 1; //dprintf(INFO, "reboot needed... \n"); //reboot(0); } dprintf(ALWAYS, "load address %x\n", load_address); dprintf(INFO, "flash init\n"); flash_init(); flash_info = flash_get_info(); ASSERT(flash_info); ASSERT(flash_info->num_blocks); nand_num_blocks = flash_info->num_blocks; ptable_init(&flash_ptable); if( strcmp(board_part_list[0].name,"PTABLE-BLK")==0 ) blocks_per_plen =1 ; else if( strcmp(board_part_list[0].name,"PTABLE-MB")==0 ) blocks_per_plen = (1024*1024)/flash_info->block_size; else panic("Invalid partition table\n"); start_block = HTCLEO_FLASH_OFFSET; for (unsigned i = 1; i < num_parts; i++) { struct ptentry *ptn = &board_part_list[i]; if( IS_PART_EMPTY(ptn) ) break; int len = ((ptn->length) * blocks_per_plen); if( ptn->start == 0 ) ptn->start = start_block; else if( ptn->start < start_block) panic("Partition %s start %x < %x\n", ptn->name, ptn->start, start_block); if(ptn->length == 0) { unsigned length_for_prt = 0; if( i<num_parts && !IS_PART_EMPTY((&board_part_list[i+1])) && board_part_list[i+1].start!=0) { length_for_prt = board_part_list[i+1].start - ptn->start; } else { for (unsigned j = i+1; j < num_parts; j++) { struct ptentry *temp_ptn = &board_part_list[j]; if( IS_PART_EMPTY(temp_ptn) ) break; if( temp_ptn->length==0 ) panic("partition %s and %s have variable length\n", ptn->name, temp_ptn->name); length_for_prt += ((temp_ptn->length) * blocks_per_plen); } } len = (nand_num_blocks - 1 - 186 - 4) - (ptn->start + length_for_prt); ASSERT(len >= 0); } start_block = ptn->start + len; ptable_add(&flash_ptable, ptn->name, ptn->start, len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); } htcleo_ptable_dump(&flash_ptable); flash_set_ptable(&flash_ptable); }
void target_init(void) { ASSERT(NAND_MTD_PARTITION_NUM == num_parts); unsigned offset; unsigned total_num_of_blocks; unsigned blocks_per_megabytes; unsigned next_ptr_start_adr = 0; int ret, i; struct flash_info *flash_info; bool start_addr_changed = false; unsigned int nMTDReserved_Num=0; // total number of MTD Reserved Area TNFTL_MTDBadBlkInfo MTDBadBlkInfo[num_parts]; ///////////////////////////////////////////////////////////////////////////////////////////// unsigned int nROAreaSize, nPartitionSize = 0; unsigned int nBlockSize, nBlockSize_MB; unsigned int nDevPBpV, nDevBBpZ, nDevBBpV, nRervRate; unsigned int j, nUserDataArea = 0; struct ptable sPartition_List; memset( MTDBadBlkInfo, 0, sizeof(TNFTL_MTDBadBlkInfo) * num_parts ); dprintf(ALWAYS, "target_init()\n"); #if _EMMC_BOOT_TCC PARTITION PartitionArr[50]; unsigned int nPartitionCnt = 0; #endif #ifdef TRIFLASH_INCLUDE ioctl_diskinfo_t disk_info; #endif #if (!ENABLE_NANDWRITE) #ifdef BOARD_TCC930X_STB_DEMO #else keys_init(); keypad_init(); #endif #endif if (target_is_emmc_boot()) { #if _EMMC_BOOT_TCC dprintf(INFO, "target_init() emmc_boot\n"); ptable_init(&flash_ptable); //SDMMC init //MCC DISK_Ioctl(DISK_DEVICE_TRIFLASH, DEV_INITIALIZE, NULL ); //get flash info? //MCC DISK_Ioctl(DISK_DEVICE_TRIFLASH, DEV_GET_DISKINFO, (void *)&disk_info); dprintf(INFO, "disk info: head: %d cylinder: %d sector : %d sector size: %d Total_sectors: %d \n",disk_info.head,disk_info.cylinder,disk_info.sector,disk_info.sector_size,disk_info.Total_sectors); //ptabel init //MCC // offset = flash_info->offset; offset = 0; //fixme // total_num_of_blocks = flash_info->num_blocks; total_num_of_blocks=10000000; // fixme memset(&PartitionArr, 0, sizeof(PARTITION) * 50); nPartitionCnt = GetLocalPartition(0, PartitionArr); for(i=0; i<nPartitionCnt; i++) PrintPartitionInfo(&PartitionArr[i], i); /* convert partition size to block unit */ //512byte ? blocks_per_megabytes = 1024*1024 / (disk_info.sector_size); ASSERT(blocks_per_megabytes); for (i = 0; i < num_parts; i++) { struct ptentry *ptn = &board_part_list[i]; if (ptn->length != VARIABLE_LENGTH) ptn->length *= blocks_per_megabytes; } for (i = 0; i < num_parts; i++) { struct ptentry *ptn = &board_part_list[i]; unsigned len = ptn->length; if (ptn->start != DIFF_START_ADDR) { if(i==2) { ptn->start = PartitionArr[1].start; } else { ptn->start *= blocks_per_megabytes; } } if (len == VARIABLE_LENGTH) { start_addr_changed = true; unsigned length_for_prt = ptn->start; unsigned j; for (j = i+1; j < num_parts; j++) { struct ptentry *temp_ptn = &board_part_list[j]; ASSERT(temp_ptn->length != VARIABLE_LENGTH); length_for_prt += temp_ptn->length; } len = total_num_of_blocks - length_for_prt; ASSERT(len >= 0); next_ptr_start_adr = ptn->start + len; } if((ptn->start == DIFF_START_ADDR) && (start_addr_changed)) { ASSERT(next_ptr_start_adr); ptn->start = next_ptr_start_adr; next_ptr_start_adr = ptn->start + ptn->length; } ptable_add(&flash_ptable, ptn->name, offset + ptn->start, len, ptn->flags); } ptable_dump(&flash_ptable); flash_set_ptable(&flash_ptable); #endif return; } if (flash_get_ptable() == NULL) { ptable_init(&flash_ptable); flash_set_partnum( num_parts ); flash_init(); flash_info = flash_get_info(); ASSERT(flash_info); if ( (flash_info->num_blocks) && (!flash_check_table()) ) { memcpy( sPartition_List.parts, board_part_list, sizeof( struct ptentry ) * num_parts ); nBlockSize = flash_info->page_size << flash_info->ShiftPpB; // Set Block Size ( Byte Size ) nROAreaSize = flash_info->num_blocks * nBlockSize; // Set Total ROArea Size ( Byte Size ) nBlockSize_MB = nBlockSize / ( 1 << 20 ); if( nBlockSize_MB > 1 ) // If Block is over the 1MB. Block must aligned. { // ex) Block Size 2MB, If Partition Size is 3MB. Partition Block Number must be 2. not 1. if( nBlockSize_MB == 2 ) // If Block Size 2MB. { for( i = 0; i < num_parts; i++ ) { if( sPartition_List.parts[i].length & 0x01 ) sPartition_List.parts[i].length++; } } else if ( nBlockSize_MB == 4 ) // If Block Size 4MB { unsigned int nDiff_Val; for( i = 0; i < num_parts; i++ ) { nDiff_Val = sPartition_List.parts[i].length & 0x03; if( nDiff_Val ) sPartition_List.parts[i].length += ( 4 - nDiff_Val ); } } } flash_get_DevPBpV( &nDevPBpV, &nDevBBpZ, &nMTDReserved_Num ); nMTDReserved_Num = ( nMTDReserved_Num << 20 ) / nBlockSize; nDevBBpV = ( nDevPBpV / 1024 ) * nDevBBpZ; nRervRate = ( nMTDReserved_Num * 100 ) / nDevPBpV; nDevBBpV = ( nDevBBpV * nRervRate ) / 100; nRervRate = ( 100 / nRervRate ); nMTDReserved_Num = nRervRate + nDevBBpV; // Setup ROArea Reserved Block if( nMTDReserved_Num & 0x01 ) nMTDReserved_Num++; if( flash_info->ExtInterrupt == TRUE ) nMTDReserved_Num = nMTDReserved_Num << 1; for( i = 0; i < num_parts; i++ ) { if( sPartition_List.parts[i].length != VARIABLE_LENGTH ) { sPartition_List.parts[i].length = sPartition_List.parts[i].length << 20; // Convert Length Unit. MByte -> Byte nPartitionSize += sPartition_List.parts[i].length; } else { nUserDataArea = i; } } sPartition_List.parts[nUserDataArea].length = nROAreaSize - nPartitionSize; // Calculate UserDataArea Size ( include Rerv Block ) sPartition_List.parts[nUserDataArea].length -= (nMTDReserved_Num * nBlockSize ); // UserDataArea Size. Reverved Block Removed i = 1; sPartition_List.parts[0].length /= nBlockSize; // Partition 0 Length ( Block Unit ) MTDBadBlkInfo[0].PartBlkNum = sPartition_List.parts[0].length; // Set Block Number Each Partition do { sPartition_List.parts[i].length /= nBlockSize; // Partition i Length ( Block Unit ) sPartition_List.parts[i].start = sPartition_List.parts[i-1].start + sPartition_List.parts[i-1].length; MTDBadBlkInfo[i].PartBlkNum = sPartition_List.parts[i].length; // Set Block Number Each Partition ++i; } while( i < num_parts ); flash_set_rervnum( nMTDReserved_Num ); // Set Reserved Block Number flash_set_badblkinfo( MTDBadBlkInfo ); // Set Bad Block Table Info. About Block Number Each Partition for( i = 0; i < num_parts; i++ ) { ptable_add(&flash_ptable, sPartition_List.parts[i].name, flash_info->offset + sPartition_List.parts[i].start, sPartition_List.parts[i].length, sPartition_List.parts[i].flags); } ND_TRACE("\n-------------- [ Partition Table ] --------------\n"); for( i = 0; i < num_parts; i++ ) { ND_TRACE(" [Part %2d.%9s] [Start:%4d] [Length:%4d]\n", i, sPartition_List.parts[i].name ,sPartition_List.parts[i].start + flash_info->offset, sPartition_List.parts[i].length ); } ND_TRACE("-------------------------------------------------\n"); dprintf(INFO, "[NAND ] [Maker:0x%02x ][Device:0x%02x][Page_size:%d]\n", flash_info->vendor, flash_info->device, flash_info->page_size); dprintf(INFO, " [Spare_Size:%d][Block_Size:%d][MTD_Block:%d][Rerv_Block:%d]\n", flash_info->spare_size, flash_info->block_size, flash_info->num_blocks - (U32)nMTDReserved_Num, (U32)nMTDReserved_Num); //ptable_dump(&flash_ptable); flash_set_ptable(&flash_ptable); ret = flash_set_badblktable(); if( ret != SUCCESS ) { dprintf(INFO, " !!! Fail Create Bad Block Table. [func:%s] [line:%d] !!! \n", __func__, __LINE__ ); ASSERT(-1); } flash_set_tablestatus(TRUE); } } }
uint8_t flash_get_size(void) { return flash_get_info().size; }
uint8_t flash(FlashControl* flash_control,bool bmc_flash, uint32_t address, char* write_file, char* obj_path) { bool has_sfc = false, has_ast = false, use_lpc = true; bool erase = true, program = true; int rc; printf("flasher: %s, BMC = %d, address = 0x%x\n",write_file,bmc_flash,address); #ifdef __arm__ /* Check platform */ check_platform(&has_sfc, &has_ast); /* Prepare for access */ if(bmc_flash) { if(!has_ast) { fprintf(stderr, "No BMC on this platform\n"); return FLASH_SETUP_ERROR; } rc = flash_access_setup_bmc(use_lpc, erase || program); if(rc) { return FLASH_SETUP_ERROR; } } else { if(!has_ast && !has_sfc) { fprintf(stderr, "No BMC nor SFC on this platform\n"); return FLASH_SETUP_ERROR; } rc = flash_access_setup_pnor(use_lpc, has_sfc, erase || program); if(rc) { return FLASH_SETUP_ERROR; } } rc = flash_get_info(fl_chip, &fl_name, &fl_total_size, &fl_erase_granule); if(rc) { fprintf(stderr, "Error %d getting flash info\n", rc); return FLASH_SETUP_ERROR; } #endif if(strcmp(write_file,"")!=0) { // If file specified but not size, get size from file struct stat stbuf; if(stat(write_file, &stbuf)) { perror("Failed to get file size"); return FLASH_ERROR; } uint32_t write_size = stbuf.st_size; #ifdef __arm__ rc = erase_chip(); if(rc) { return FLASH_ERROR; } rc = program_file(flash_control, write_file, address, write_size); if(rc) { return FLASH_ERROR; } #endif printf("Flash done\n"); } else { printf("Flash tuned\n"); } return FLASH_OK; }