void target_init(void) { unsigned offset; struct flash_info *flash_info; 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); for (i = 0; i < num_parts; i++) { struct ptentry *ptn = &board_part_list[i]; unsigned len = ptn->length; if ((len == 0) && (i == num_parts - 1)) len = flash_info->num_blocks - offset - ptn->start; 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; struct ptentry *board_part_list; 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"); display_image_on_screen(); #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); if (flash_ecc_bch_enabled()) board_part_list = board_part_list_bchecc; else board_part_list = board_part_list_default; 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) { #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*/ 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); }
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); }
static void zybo_common_target_init(uint level) { status_t err; /* zybo has a spiflash on qspi */ spiflash_detect(); bdev_t *spi = bio_open("spi0"); if (spi) { /* find or create a partition table at the start of flash */ if (ptable_scan(spi, 0) < 0) { ptable_create_default(spi, 0); } struct ptable_entry entry = { 0 }; /* find and recover sysparams */ if (ptable_find("sysparam", &entry) < 0) { /* didn't find sysparam partition, create it */ ptable_add("sysparam", 0x1000, 0x1000, 0); ptable_find("sysparam", &entry); } if (entry.length > 0) { sysparam_scan(spi, entry.offset, entry.length); #if SYSPARAM_ALLOW_WRITE /* for testing purposes, put at least one sysparam value in */ if (sysparam_add("dummy", "value", sizeof("value")) >= 0) { sysparam_write(); } #endif sysparam_dump(true); } /* create bootloader partition if it does not exist */ ptable_add("bootloader", 0x20000, 0x40000, 0); printf("flash partition table:\n"); ptable_dump(); } /* recover boot arguments */ const char *cmdline = bootargs_get_command_line(); if (cmdline) { printf("command line: '%s'\n", cmdline); } /* see if we came from a bootimage */ uintptr_t bootimage_phys; size_t bootimage_size; if (bootargs_get_bootimage_pointer(&bootimage_phys, &bootimage_size) >= 0) { printf("our bootimage is at phys 0x%lx, size %zx\n", bootimage_phys, bootimage_size); void *ptr = paddr_to_kvaddr(bootimage_phys); if (ptr) { bootimage_t *bi; if (bootimage_open(ptr, bootimage_size, &bi) >= 0) { /* we have a valid bootimage, find the fpga section */ const void *fpga_ptr; size_t fpga_len; if (bootimage_get_file_section(bi, TYPE_FPGA_IMAGE, &fpga_ptr, &fpga_len) >= 0) { /* we have a fpga image */ /* lookup the physical address of the bitfile */ paddr_t pa = kvaddr_to_paddr((void *)fpga_ptr); if (pa != 0) { /* program the fpga with it*/ printf("loading fpga image at %p (phys 0x%lx), len %zx\n", fpga_ptr, pa, fpga_len); zynq_reset_fpga(); err = zynq_program_fpga(pa, fpga_len); if (err < 0) { printf("error %d loading fpga\n", err); } printf("fpga image loaded\n"); } } } } } #if WITH_LIB_MINIP /* pull some network stack related params out of the sysparam block */ uint8_t mac_addr[6]; uint32_t ip_addr = IPV4_NONE; uint32_t ip_mask = IPV4_NONE; uint32_t ip_gateway = IPV4_NONE; if (sysparam_read("net0.mac_addr", mac_addr, sizeof(mac_addr)) < (ssize_t)sizeof(mac_addr)) { /* couldn't find eth address, make up a random one */ for (size_t i = 0; i < sizeof(mac_addr); i++) { mac_addr[i] = rand() & 0xff; } /* unicast and locally administered */ mac_addr[0] &= ~(1<<0); mac_addr[0] |= (1<<1); } uint8_t use_dhcp = 0; sysparam_read("net0.use_dhcp", &use_dhcp, sizeof(use_dhcp)); sysparam_read("net0.ip_addr", &ip_addr, sizeof(ip_addr)); sysparam_read("net0.ip_mask", &ip_mask, sizeof(ip_mask)); sysparam_read("net0.ip_gateway", &ip_gateway, sizeof(ip_gateway)); minip_set_macaddr(mac_addr); gem_set_macaddr(mac_addr); if (!use_dhcp && ip_addr != IPV4_NONE) { minip_init(gem_send_raw_pkt, NULL, ip_addr, ip_mask, ip_gateway); } else { /* Configure IP stack and hook to the driver */ minip_init_dhcp(gem_send_raw_pkt, NULL); } gem_set_callback(minip_rx_driver_callback); #endif }
// return NULL for success, error string for failure int lkb_handle_command(lkb_t *lkb, const char *cmd, const char *arg, size_t len, const char **result) { *result = NULL; struct lkb_command *lcmd; for (lcmd = lkb_cmd_list; lcmd; lcmd = lcmd->next) { if (!strcmp(lcmd->name, cmd)) { *result = lcmd->handler(lkb, arg, len, lcmd->cookie); return 0; } } if (!strcmp(cmd, "flash") || !strcmp(cmd, "erase")) { struct ptable_entry entry; bdev_t *bdev; if (ptable_find(arg, &entry) < 0) { size_t plen = len; /* doesn't exist, make one */ if (ptable_add(arg, plen, 0) < 0) { *result = "error creating partition"; return -1; } if (ptable_find(arg, &entry) < 0) { *result = "couldn't find partition after creating it"; return -1; } } if (len > entry.length) { *result = "partition too small"; return -1; } if (!(bdev = ptable_get_device())) { *result = "ptable_get_device failed"; return -1; } printf("lkboot: erasing partition of size %llu\n", entry.length); if (bio_erase(bdev, entry.offset, entry.length) != (ssize_t)entry.length) { *result = "bio_erase failed"; return -1; } if (!strcmp(cmd, "flash")) { printf("lkboot: writing to partition\n"); void *buf = malloc(bdev->block_size); if (!buf) { *result = "memory allocation failed"; return -1; } size_t pos = 0; while (pos < len) { size_t toread = MIN(len - pos, bdev->block_size); LTRACEF("offset %zu, toread %zu\n", pos, toread); if (lkb_read(lkb, buf, toread)) { *result = "io error"; free(buf); return -1; } if (bio_write(bdev, buf, entry.offset + pos, toread) != (ssize_t)toread) { *result = "bio_write failed"; free(buf); return -1; } pos += toread; } free(buf); } } else if (!strcmp(cmd, "remove")) { if (ptable_remove(arg) < 0) { *result = "remove failed"; return -1; } } else if (!strcmp(cmd, "fpga")) { #if PLATFORM_ZYNQ void *buf = malloc(len); if (!buf) { *result = "error allocating buffer"; return -1; } /* translate to physical address */ paddr_t pa = vaddr_to_paddr(buf); if (pa == 0) { *result = "error allocating buffer"; free(buf); return -1; } if (lkb_read(lkb, buf, len)) { *result = "io error"; free(buf); return -1; } /* make sure the cache is flushed for this buffer for DMA coherency purposes */ arch_clean_cache_range((vaddr_t)buf, len); /* program the fpga */ zynq_reset_fpga(); zynq_program_fpga(pa, len); free(buf); #else *result = "no fpga"; return -1; #endif } else if (!strcmp(cmd, "boot")) { return do_boot(lkb, len, result); } else if (!strcmp(cmd, "getsysparam")) { const void *ptr; size_t len; if (sysparam_get_ptr(arg, &ptr, &len) == 0) { lkb_write(lkb, ptr, len); } } else if (!strcmp(cmd, "reboot")) { thread_resume(thread_create("reboot", &do_reboot, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); } else { *result = "unknown command"; return -1; } return 0; }
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); } } }
// return NULL for success, error string for failure const char *lkb_handle_command(lkb_t *lkb, const char *cmd, const char *arg, unsigned len) { struct lkb_command *lcmd; for (lcmd = lkb_cmd_list; lcmd; lcmd = lcmd->next) { if (!strcmp(lcmd->name, cmd)) { return lcmd->handler(lkb, arg, len, lcmd->cookie); } } if (len > lkb_iobuffer_size) { return "buffer too small"; } if (!strcmp(cmd, "flash") || !strcmp(cmd, "erase")) { struct ptable_entry entry; bdev_t *bdev; if (ptable_find(arg, &entry) < 0) { size_t plen = len; /* doesn't exist, make one */ #if PLATFORM_ZYNQ /* XXX not really the right place, should be in the ptable/bio layer */ plen = ROUNDUP(plen, 256*1024); #endif off_t off = ptable_allocate(plen, 0); if (off < 0) { return "no space to allocate partition"; } if (ptable_add(arg, off, plen, 0) < 0) { return "error creating partition"; } if (ptable_find(arg, &entry) < 0) { return "couldn't find partition after creating it"; } } if (len > entry.length) { return "partition too small"; } if (lkb_read(lkb, lkb_iobuffer, len)) { return "io error"; } if (!(bdev = bio_open(bootdevice))) { return "bio_open failed"; } if (bio_erase(bdev, entry.offset, entry.length) != (ssize_t)entry.length) { bio_close(bdev); return "bio_erase failed"; } if (!strcmp(cmd, "flash")) { if (bio_write(bdev, lkb_iobuffer, entry.offset, len) != (ssize_t)len) { bio_close(bdev); return "bio_write failed"; } } bio_close(bdev); return NULL; } else if (!strcmp(cmd, "remove")) { if (ptable_remove(arg) < 0) { return "remove failed"; } return NULL; } else if (!strcmp(cmd, "fpga")) { #if PLATFORM_ZYNQ unsigned *x = lkb_iobuffer; if (lkb_read(lkb, lkb_iobuffer, len)) { return "io error"; } for (unsigned n = 0; n < len; n+= 4) { *x = SWAP_32(*x); x++; } zynq_reset_fpga(); zynq_program_fpga(lkb_iobuffer_phys, len); return NULL; #else return "no fpga"; #endif } else if (!strcmp(cmd, "boot")) { if (lkb_read(lkb, lkb_iobuffer, len)) { return "io error"; } thread_resume(thread_create("boot", &do_boot, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); return NULL; } else if (!strcmp(cmd, "getsysparam")) { const void *ptr; size_t len; if (sysparam_get_ptr(arg, &ptr, &len) == 0) { lkb_write(lkb, ptr, len); } return NULL; } else if (!strcmp(cmd, "reboot")) { thread_resume(thread_create("reboot", &do_reboot, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); return NULL; } else { return "unknown command"; } }