unsigned* target_atag_mem(unsigned* ptr) { struct smem_ram_ptable ram_ptable; unsigned i = 0; if (smem_ram_ptable_init(&ram_ptable)) { for (i = 0; i < ram_ptable.len; i++) { if ((ram_ptable.parts[i].attr == READWRITE) && (ram_ptable.parts[i].domain == APPS_DOMAIN) && (ram_ptable.parts[i].start != 0x0) && (!(ROUND_TO_MB(ram_ptable.parts[i].size) <= SIZE_1M))) { /* ATAG_MEM */ *ptr++ = 4; *ptr++ = 0x54410002; /* RAM parition are reported correctly by NON-HLOS Use the size passed directly */ if (target_is_emmc_boot()) *ptr++ = ROUND_TO_MB(ram_ptable.parts[i].size); else *ptr++ = ram_ptable.parts[i].size; *ptr++ = ram_ptable.parts[i].start; } } } else { dprintf(CRITICAL, "ERROR: Unable to read RAM partition\n"); ASSERT(0); } return ptr; }
int board_get_wifimac(char *wifimac) { int n,i; char temp[32]; #ifdef BOOTSD_INCLUDE if (target_is_emmc_boot()) n = get_emmc_serial(temp); else #endif #if defined(NAND_BOOT_INCLUDE) n = NAND_GetSerialNumber(temp, 32); #else return 0; #endif if (temp[1] == '1') { for (i=0; i<12; i++) { *wifimac++ = temp[4+i]; if (i==11) break; if (!((i+1)%2)) *wifimac++ = ':'; } } else if(temp[1] == '2') { for (i=0; i<12; i++) { *wifimac++ = temp[16+i]; if (i==11) break; if (!((i+1)%2)) *wifimac++ = ':'; } } *wifimac = '\0'; return strlen(wifimac); }
unsigned check_reboot_mode(void) { unsigned mode[2] = { 0, 0 }; unsigned int mode_len = sizeof(mode); unsigned smem_status; unsigned int cookie = 0; smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, &mode, mode_len); /* * SMEM value is relied upon on power shutdown. Check either of SMEM * or FOTA update cookie is set */ if (target_is_emmc_boot()) cookie = get_fota_cookie_mmc(); else cookie = get_fota_cookie_mtd(); if ((mode[0] == RECOVERY_MODE) || (cookie == FOTA_COOKIE)) return RECOVERY_MODE; if (smem_status) { dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); return 0; } return mode[0]; }
void target_serialno(unsigned char *buf) { uint32_t serialno; if (target_is_emmc_boot()) { serialno = mmc_get_psn(); snprintf((char *)buf, 13, "%x", serialno); } }
void target_serialno(unsigned char *buf) { unsigned int serialno; if(target_is_emmc_boot()) { serialno = mmc_get_psn(); sprintf(buf,"%x",serialno); } }
void target_serialno(unsigned char *buf) { uint32_t serialno; if (target_is_emmc_boot()) { if (platform_boot_dev_isemmc()) serialno = mmc_get_psn(); else serialno = board_chip_serial(); snprintf((char *)buf, 13, "%x", serialno); } }
static int read_misc(unsigned page_offset, void *buf, unsigned size) { const char *ptn_name = "misc"; uint32_t pagesize = get_page_size(); unsigned offset; if (size == 0 || buf == NULL) return -1; offset = page_offset * pagesize; if (target_is_emmc_boot()) { int index; unsigned long long ptn; unsigned long long ptn_size; index = partition_get_index(ptn_name); if (index == INVALID_PTN) { dprintf(CRITICAL, "No '%s' partition found\n", ptn_name); return -1; } ptn = partition_get_offset(index); ptn_size = partition_get_size(index); mmc_set_lun(partition_get_lun(index)); if (ptn_size < offset + size) { dprintf(CRITICAL, "Read request out of '%s' boundaries\n", ptn_name); return -1; } if (mmc_read(ptn + offset, (unsigned int *)buf, size)) { dprintf(CRITICAL, "Reading MMC failed\n"); return -1; } } else { dprintf(CRITICAL, "Misc partition not supported for NAND targets.\n"); return -1; } return 0; }
int board_get_btaddr(char *btaddr) { int n,i; char temp[32]; #ifdef BOOTSD_INCLUDE if (target_is_emmc_boot()) n = get_emmc_serial(temp); else #endif #if defined(NAND_BOOT_INCLUDE) n = NAND_GetSerialNumber(temp, 32); #else return 0; #endif for (i=4; i<16; i++) // 12 = bluetooth bd address field(12) *btaddr++ = temp[i]; *btaddr = '\0'; return strlen(btaddr); }
void cmd_boot(const char *arg, void *data, unsigned sz) { unsigned kernel_actual; unsigned ramdisk_actual; static struct boot_img_hdr hdr; char *ptr = ((char*) data); if (sz < sizeof(hdr)) { fastboot_fail("invalid bootimage header"); return; } memcpy(&hdr, data, sizeof(hdr)); /* ensure commandline is terminated */ hdr.cmdline[BOOT_ARGS_SIZE-1] = 0; if(target_is_emmc_boot() && hdr.page_size) { page_size = hdr.page_size; page_mask = page_size - 1; } kernel_actual = ROUND_TO_PAGE(hdr.kernel_size, page_mask); ramdisk_actual = ROUND_TO_PAGE(hdr.ramdisk_size, page_mask); if (page_size + kernel_actual + ramdisk_actual < sz) { fastboot_fail("incomplete bootimage"); return; } memmove((void*) KERNEL_ADDR, ptr + page_size, hdr.kernel_size); memmove((void*) RAMDISK_ADDR, ptr + page_size + kernel_actual, hdr.ramdisk_size); fastboot_okay(""); target_battery_charging_enable(0, 1); udc_stop(); boot_linux((void*) KERNEL_ADDR, (void*) TAGS_ADDR, (const char*) hdr.cmdline, board_machtype(), (void*) RAMDISK_ADDR, hdr.ramdisk_size); }
int board_get_serialno(char *serialno) { int n,i; char temp[32]; #ifdef BOOTSD_INCLUDE if (target_is_emmc_boot()) n = get_emmc_serial(temp); else #endif #if defined(NAND_BOOT_INCLUDE) n = NAND_GetSerialNumber(temp, 32); #else return 0; #endif for (i=0; i<4; i++) // 4 = custon field(2) + product number(2) *serialno++ = temp[i]; for (i=16; i<32; i++) // 16 = time(12) + serial count(4) *serialno++ = temp[i]; *serialno = '\0'; return strlen(serialno); }
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; 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 board_info(void) { struct smem_board_info_v4 board_info_v4; unsigned int board_info_len = 0; unsigned smem_status; unsigned format = 0; unsigned id = 0; if (hw_platform && target_msm_id) return; hw_platform = MSM7X27A_SURF; target_msm_id = MSM7225A; smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if (!smem_status) { if (format == 4) { board_info_len = sizeof(board_info_v4); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v4, board_info_len); if (!smem_status) { id = board_info_v4.board_info_v3.hw_platform; target_msm_id = board_info_v4.board_info_v3.msm_id; msm_version = board_info_v4.board_info_v3.msm_version; } } /* Detect SURF v/s FFA v/s QRD */ if (target_msm_id >= MSM8225 && target_msm_id <= MSM8625 || (target_msm_id == MSM8125A)) { switch (id) { case 0x1: hw_platform = MSM8X25_SURF; break; case 0x2: hw_platform = MSM8X25_FFA; break; case 0x10: hw_platform = MSM8X25_EVT; break; case 0xC: hw_platform = MSM8X25_EVB; break; case 0xF: hw_platform = MSM8X25_QRD7; break; default: hw_platform = MSM8X25_SURF; } } else { switch (id) { case 0x1: /* Set the machine type based on msm ID */ if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_SURF; else hw_platform = MSM7X27A_SURF; break; case 0x2: if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_FFA; else hw_platform = MSM7X27A_FFA; break; case 0xB: if(target_is_emmc_boot()) hw_platform = MSM7X27A_QRD1; else hw_platform = MSM7X27A_QRD3; break; case 0xC: hw_platform = MSM7X27A_EVB; break; case 0xF: hw_platform = MSM7X27A_QRD3; break; default: if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_SURF; else hw_platform = MSM7X27A_SURF; }; } /* Set msm ID for target variants based on values read from smem */ switch (target_msm_id) { case MSM7225A: case MSM7625A: case ESM7225A: case MSM7225AA: case MSM7625AA: case ESM7225AA: case MSM7225AB: case MSM7625AB: case ESM7225AB: case MSM7125A: target_msm_id = MSM7625A; break; case MSM8225: case MSM8625: case MSM8125A: target_msm_id = MSM8625; break; default: target_msm_id = MSM7627A; } } return; }
int boot_linux_from_flash(void) { struct boot_img_hdr *hdr = (void*) buf; unsigned n; struct ptentry *ptn; struct ptable *ptable; unsigned offset = 0; const char *cmdline; if (target_is_emmc_boot()) { hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR; if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { dprintf(CRITICAL, "ERROR: Invalid boot image header\n"); return -1; } goto continue_boot; } ptable = flash_get_ptable(); if (ptable == NULL) { dprintf(CRITICAL, "ERROR: Partition table not found\n"); return -1; } if(!boot_into_recovery) { ptn = ptable_find(ptable, "boot"); if (ptn == NULL) { dprintf(CRITICAL, "ERROR: No boot partition found\n"); return -1; } } else { ptn = ptable_find(ptable, "recovery"); if (ptn == NULL) { dprintf(CRITICAL, "ERROR: No recovery partition found\n"); return -1; } } if (flash_read(ptn, offset, buf, page_size)) { dprintf(CRITICAL, "ERROR: Cannot read boot image header\n"); return -1; } offset += page_size; if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { dprintf(CRITICAL, "ERROR: Invaled boot image heador\n"); return -1; } if (hdr->page_size != page_size) { dprintf(CRITICAL, "ERROR: Invaled boot image pagesize. Device pagesize: %d, Image pagesize: %d\n",page_size,hdr->page_size); return -1; } n = ROUND_TO_PAGE(hdr->kernel_size, page_mask); if (flash_read(ptn, offset, (void *)hdr->kernel_addr, n)) { dprintf(CRITICAL, "ERROR: Cannot read kernel image\n"); return -1; } offset += n; n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, n)) { dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n"); return -1; } offset += n; continue_boot: dprintf(INFO, "\nkernel @ %x (%d bytes)\n", hdr->kernel_addr, hdr->kernel_size); dprintf(INFO, "ramdisk @ %x (%d bytes)\n", hdr->ramdisk_addr, hdr->ramdisk_size); if(hdr->cmdline[0]) { cmdline = (char*) hdr->cmdline; } else { cmdline = DEFAULT_CMDLINE; } dprintf(INFO, "cmdline = '%s'\n", cmdline); /* TODO: create/pass atags to kernel */ dprintf(INFO, "\nBooting Linux\n"); boot_linux((void *)hdr->kernel_addr, (void *)TAGS_ADDR, (const char *)cmdline, board_machtype(), (void *)hdr->ramdisk_addr, hdr->ramdisk_size); return 0; }
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 }
int write_misc(unsigned page_offset, void *buf, unsigned size) { const char *ptn_name = "misc"; void *scratch_addr = target_get_scratch_address(); unsigned offset; unsigned aligned_size; if (size == 0 || buf == NULL || scratch_addr == NULL) return -1; if (target_is_emmc_boot()) { int index; unsigned long long ptn; unsigned long long ptn_size; index = partition_get_index(ptn_name); if (index == INVALID_PTN) { dprintf(CRITICAL, "No '%s' partition found\n", ptn_name); return -1; } ptn = partition_get_offset(index); ptn_size = partition_get_size(index); offset = page_offset * BLOCK_SIZE; aligned_size = ROUND_TO_PAGE(size, (unsigned)BLOCK_SIZE - 1); if (ptn_size < offset + aligned_size) { dprintf(CRITICAL, "Write request out of '%s' boundaries\n", ptn_name); return -1; } if (scratch_addr != buf) memcpy(scratch_addr, buf, size); if (mmc_write(ptn + offset, aligned_size, (unsigned int *)scratch_addr)) { dprintf(CRITICAL, "Writing MMC failed\n"); return -1; } } else { struct ptentry *ptn; struct ptable *ptable; unsigned pagesize = flash_page_size(); ptable = flash_get_ptable(); if (ptable == NULL) { dprintf(CRITICAL, "Partition table not found\n"); return -1; } ptn = ptable_find(ptable, ptn_name); if (ptn == NULL) { dprintf(CRITICAL, "No '%s' partition found\n", ptn_name); return -1; } offset = page_offset * pagesize; aligned_size = ROUND_TO_PAGE(size, pagesize - 1); if (ptn->length < offset + aligned_size) { dprintf(CRITICAL, "Write request out of '%s' boundaries\n", ptn_name); return -1; } if (scratch_addr != buf) memcpy(scratch_addr, buf, size); if (flash_write(ptn, offset, scratch_addr, aligned_size)) { dprintf(CRITICAL, "Writing flash failed\n"); return -1; } } return 0; }
void boot_linux(void *kernel, unsigned *tags, const char *cmdline, unsigned machtype, void *ramdisk, unsigned ramdisk_size) { unsigned *ptr = tags; unsigned pcount = 0; void (*entry)(unsigned,unsigned,unsigned*) = kernel; struct ptable *ptable; int cmdline_len = 0; int have_cmdline = 0; int pause_at_bootup = 0; /* CORE */ *ptr++ = 2; *ptr++ = 0x54410001; if (ramdisk_size) { *ptr++ = 4; *ptr++ = 0x54420005; *ptr++ = (unsigned)ramdisk; *ptr++ = ramdisk_size; } ptr = target_atag_mem(ptr); if (!target_is_emmc_boot()) { /* Skip NAND partition ATAGS for eMMC boot */ if ((ptable = flash_get_ptable()) && (ptable->count != 0)) { int i; for(i=0; i < ptable->count; i++) { struct ptentry *ptn; ptn = ptable_get(ptable, i); if (ptn->type == TYPE_APPS_PARTITION) pcount++; } *ptr++ = 2 + (pcount * (sizeof(struct atag_ptbl_entry) / sizeof(unsigned))); *ptr++ = 0x4d534d70; for (i = 0; i < ptable->count; ++i) ptentry_to_tag(&ptr, ptable_get(ptable, i)); } } if (cmdline && cmdline[0]) { cmdline_len = strlen(cmdline); have_cmdline = 1; } if (target_is_emmc_boot()) { cmdline_len += strlen(emmc_cmdline); } if (target_pause_for_battery_charge()) { pause_at_bootup = 1; cmdline_len += strlen(battchg_pause); } if (cmdline_len > 0) { const char *src; char *dst; unsigned n; /* include terminating 0 and round up to a word multiple */ n = (cmdline_len + 4) & (~3); *ptr++ = (n / 4) + 2; *ptr++ = 0x54410009; dst = (char *)ptr; if (have_cmdline) { src = cmdline; while ((*dst++ = *src++)); } if (target_is_emmc_boot()) { src = emmc_cmdline; if (have_cmdline) --dst; have_cmdline = 1; while ((*dst++ = *src++)); } if (pause_at_bootup) { src = battchg_pause; if (have_cmdline) --dst; while ((*dst++ = *src++)); } ptr += (n / 4); } /* END */ *ptr++ = 0; *ptr++ = 0; dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d)\n", kernel, ramdisk, ramdisk_size); if (cmdline) dprintf(INFO, "cmdline: %s\n", cmdline); enter_critical_section(); platform_uninit_timer(); arch_disable_cache(UCACHE); arch_disable_mmu(); #if DISPLAY_SPLASH_SCREEN display_shutdown(); #endif entry(0, machtype, tags); }
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 board_info(void) { struct smem_board_info_v4 board_info_v4; unsigned int board_info_len = 0; unsigned smem_status; unsigned format = 0; unsigned id = 0; if (hw_platform && target_msm_id) return; hw_platform = MSM7X27A_SURF; target_msm_id = MSM7225A; smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if (!smem_status) { if (format == 4) { board_info_len = sizeof(board_info_v4); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v4, board_info_len); if (!smem_status) { id = board_info_v4.board_info_v3.hw_platform; target_msm_id = board_info_v4.board_info_v3.msm_id; msm_version = board_info_v4.board_info_v3.msm_version; platform_version = board_info_v4.platform_version; } } /* Detect SURF v/s FFA v/s QRD */ if (target_msm_id >= MSM8225 && target_msm_id <= MSM8625 || (target_msm_id == MSM8125A) || (target_msm_id == MSM8125)) { switch (id) { case 0x1: hw_platform = MSM8X25_SURF; BOARD_NAME(target_msm_id, "SURF"); break; case 0x2: hw_platform = MSM8X25_FFA; BOARD_NAME(target_msm_id, "FFA"); break; case 0x10: case 0x60000000: /* Linux kernel use the id as the array index, change 0x60000000 to 0xA2 */ case 0xA2: hw_platform = MSM8X25_QRD5; BOARD_NAME(target_msm_id, "QRD5"); break; case 0xC: hw_platform = MSM8X25_EVB; BOARD_NAME(target_msm_id, "EVB"); break; case 0xA0: hw_platform = MSM8X25_SKUA; BOARD_NAME(target_msm_id, "SKUA"); break; case 0xA6: hw_platform = MSM8X25_SKUB; BOARD_NAME(target_msm_id, "SKUB"); break; case 0xA7: hw_platform = MSM8X25Q_SKUD; BOARD_NAME(target_msm_id, "SKUD"); break; case 0xA8: hw_platform = MSM8X25Q_SKUE; BOARD_NAME(target_msm_id, "SKUE"); break; case 0xF: hw_platform = MSM8X25_QRD7; BOARD_NAME(target_msm_id, "QRD7"); break; default: hw_platform = MSM8X25_SURF; BOARD_NAME(target_msm_id, "SURF"); } } else { switch (id) { case 0x1: /* Set the machine type based on msm ID */ if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_SURF; else hw_platform = MSM7X27A_SURF; BOARD_NAME(target_msm_id, "SURF"); break; case 0x2: if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_FFA; else hw_platform = MSM7X27A_FFA; BOARD_NAME(target_msm_id, "FFA"); break; case 0xB: if(target_is_emmc_boot()) hw_platform = MSM7X27A_QRD1; BOARD_NAME(target_msm_id, "QRD1"); hw_platform = MSM7X27A_QRD3; break; case 0xC: hw_platform = MSM7X27A_EVB; BOARD_NAME(target_msm_id, "EVB"); break; case 0xF: hw_platform = MSM7X27A_QRD3; BOARD_NAME(target_msm_id, "QRD3"); break; case 0xA2: hw_platform = MSM7X27A_QRD5A; BOARD_NAME(target_msm_id, "QRD5A"); break; default: if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_SURF; else hw_platform = MSM7X27A_SURF; BOARD_NAME(target_msm_id, "SURF"); }; } /* Set msm ID for target variants based on values read from smem */ switch (target_msm_id) { case MSM7225A: case MSM7625A: case ESM7225A: case MSM7225AA: case MSM7625AA: case ESM7225AA: case MSM7225AB: case MSM7625AB: case ESM7225AB: case MSM7125A: target_msm_id = MSM7625A; break; case MSM8225: case MSM8625: case MSM8125A: case MSM8125: target_msm_id = MSM8625; break; default: target_msm_id = MSM7627A; } } dprintf(INFO, "LK:hardware_id %d,hw_platform %d, target_msm_id %d\n", id, hw_platform, target_msm_id); return; }
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); } } }
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) { 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); }