void cmd_erase_emmc(const char *arg, void *data, unsigned sz)
{
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
    unsigned int part_id;
#endif
	unsigned long long ptn = 0;
	unsigned long long size = 0;
	int index = INVALID_PTN;
	int erase_ret = MMC_ERR_NONE;
	char msg[256];

	init_display_xy();
	dprintf (DBG_LV, "Enter cmd_erase()\n");

	index = partition_get_index(arg);
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
    part_id = partition_get_region(index);
#endif
	ptn = partition_get_offset(index);

	if(index == -1) {
		fastboot_fail_wrapper("Partition table doesn't exist");
		return;
	}
	if(!is_support_erase(index)){
		sprintf(msg,"partition '%s' not support erase\n",arg);
		fastboot_fail_wrapper(msg);
		return;
	}

	TIME_START;
	size = partition_get_size(index);
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
	erase_ret = emmc_erase(part_id, ptn, partition_get_size(index));
#else
	erase_ret = emmc_erase(ptn, partition_get_size(index));
#endif

	if(erase_ret  == MMC_ERR_NONE)
	{
		dprintf (DBG_LV, "emmc_erase() OK\n");
		fastboot_ok_wrapper("Erase EMMC", size);
	}
	else
	{
		dprintf (DBG_LV, "emmc_erase() Fail\n");
		snprintf(msg, sizeof(msg), "Erase error. code:%d", erase_ret);
		fastboot_fail_wrapper(msg);
	}


	return;
}
Esempio n. 2
0
File: grub.c Progetto: sndnvaps/lk-1
static int grub_load_from_tar(void) {
	// prepare block api
	priv.index = partition_get_index("aboot");
	priv.ptn = partition_get_offset(priv.index) + 1024*1024; // 1MB offset to aboot
	priv.is_ramdisk = 0;
	tio.blksz = BLOCK_SIZE;
	tio.lba = partition_get_size(priv.index) / tio.blksz - 1;

	// search file
	if(tar_get_fileinfo(&tio, "./boot/grub/core.img", &fi)) {
		dprintf(CRITICAL, "%s: couldn't find core.img!\n", __func__);
		return -1;
	}

	// load file into RAM
	if(tar_read_file(&tio, &fi, (void*)GRUB_LOADING_ADDRESS_VIRT)) {
		dprintf(CRITICAL, "%s: couldn't read core.img!\n", __func__);
		return -1;
	}

	grub_bootdev = strdup("hd1");
	grub_bootpath = strdup("/boot/grub");
	grub_found_tar = 1;

	dprintf(INFO, "Loaded GRUB from TAR\n");
	return 0;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
static int fastboot_data_part_wipe()
{
    int ret = B_OK;
    int err;

    int index;
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
    unsigned int part_id;
#endif
    unsigned long long ptn; 
    unsigned long long size; 

    index = partition_get_index("userdata");

    if (index == -1 || !is_support_erase(index))
    {
        ret = PART_GET_INDEX_FAIL;
        return ret;
    }    

#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
    part_id = partition_get_region(index);
#endif
    ptn = partition_get_offset(index);
    size = partition_get_size(index);

    set_env("unlock_erase", "start");

#ifdef MTK_EMMC_SUPPORT
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
    err = emmc_erase(part_id, ptn, size);
#else
    err = emmc_erase(ptn, size);
#endif
#else
    err = nand_erase(ptn,(u64)size);
#endif
    if (err)
    {    
        ret = PART_ERASE_FAIL;
        set_env("unlock_erase", "fail");
    } else
    {
        ret = B_OK;
        set_env("unlock_erase", "pass");
    }

    return ret;
}
void cmd_erase_nand(const char *arg, void *data, unsigned sz)
{

	int index;
	u64 offset,size;
	char msg[256];
	index = partition_get_index(arg);
	if(index == -1){
		fastboot_fail_wrapper("partition get index fail");
		return;
	}
	if(!is_support_erase(index)){
		sprintf(msg,"partition '%s' not support erase\n",arg);
		fastboot_fail_wrapper(msg);
		return;
	}

	offset = partition_get_offset(index);
	if(offset == (u64)(-1)){
		fastboot_fail_wrapper("partition get offset fail");
		return;
	}else{
		printf("get offset: 0x%llx\n",offset);
	}
	size = partition_get_size(index);
	if(size == (u64)(-1)){
		fastboot_fail_wrapper("partition get size fail");
		return;
	}else{
		printf("get size: 0x%llx\n",size);
	}

	TIME_START;
	display_info("erase flash ....");

	if(nand_erase(offset,size)!=0){
		fastboot_fail_wrapper("failed to erase partition");
		return;
	}

	fastboot_ok_wrapper("erase flash sucess",sz);

	return;
}
Esempio n. 6
0
static int mmcdev_open(struct ext4_blockdev *bdev)
{
	struct private_mmc_data* mmcdata = mmcdev_get_privatedata(bdev);
	unsigned long long index = INVALID_PTN;
	unsigned long long size;

	// get partition ptn
	index = partition_get_index(mmcdata->partname);
	mmcdata->ptn = partition_get_offset(index);
	if(mmcdata->ptn == 0) return EIO;

	// get size
	size = partition_get_size(index);
	bdev->ph_bsize = mmc_get_device_blocksize();
	bdev->ph_bcnt = size / bdev->ph_bsize;
	bdev->ph_bbuf = (uint8_t*)malloc(sizeof(uint8_t)*bdev->ph_bsize);

	return EOK;
}
Esempio n. 7
0
void target_load_ssd_keystore(void)
{
	uint64_t ptn;
	int      index;
	uint64_t size;
	uint32_t *buffer;

	if (!target_is_ssd_enabled())
		return;

	index = partition_get_index("ssd");

	ptn = partition_get_offset(index);
	if (ptn == 0){
		dprintf(CRITICAL, "Error: ssd partition not found\n");
		return;
	}

	size = partition_get_size(index);
	if (size == 0) {
		dprintf(CRITICAL, "Error: invalid ssd partition size\n");
		return;
	}

	buffer = memalign(CACHE_LINE, ROUNDUP(size, CACHE_LINE));
	if (!buffer) {
		dprintf(CRITICAL, "Error: allocating memory for ssd buffer\n");
		return;
	}

	if (mmc_read(ptn, buffer, size)) {
		dprintf(CRITICAL, "Error: cannot read data\n");
		free(buffer);
		return;
	}

	clock_ce_enable(SSD_CE_INSTANCE);
	scm_protect_keystore(buffer, size);
	clock_ce_disable(SSD_CE_INSTANCE);
	free(buffer);
}
Esempio n. 8
0
static void register_parition_var(void)
{
	int i;
	unsigned long long p_size;
	char *type_buf;
	char *value_buf;
	char *var_name_buf;
	char *p_name_buf;

	for(i=0;i<PART_MAX_COUNT;i++){
		p_size = partition_get_size(i);
		if(p_size == -1)
			break;
		partition_get_name(i,&p_name_buf);

		partition_get_type(i,&type_buf);
		var_name_buf = malloc(30);
		sprintf(var_name_buf,"partition-type:%s",p_name_buf);
		fastboot_publish(var_name_buf,type_buf);
		//printf("%d %s %s\n",i,var_name_buf,type_buf);

		/*reserved for MTK security*/
		if(!strcmp(type_buf,"ext4")){
			if(!strcmp(p_name_buf,"userdata")){
				p_size -= (u64)1*1024*1024;
				if (p_size > 800*1024*1024) {
				    p_size = 800*1024*1024;
				}
			}
		}
		value_buf = malloc(20);
		sprintf(value_buf,"%llx",p_size);
		var_name_buf = malloc(30);
		sprintf(var_name_buf,"partition-size:%s",p_name_buf);
		fastboot_publish(var_name_buf,value_buf);
		//printf("%d %s %s\n",i,var_name_buf,value_buf);
		
	}
}
BOOL write_to_nand(u8* data, u32 length, u32 img_total_len)
{
	static u64 partition_size = 0;
	int next_flip = 0;
	u32 index;
	static int img_type = UNKOWN_IMG;
	s8* p_type;
	u32 w_length =0;
	//u32 pre_chksum = 0;
	//u32 post_chksum = 0;
	int r;

	if(sto_info.first_run)
	{
		r = get_partition_name(data, length, sto_info.partition_name);
		if(r < 0)
		{
			display_info("\nGet_partition_name() Fail");
			return FALSE;
		}

		index = partition_get_index(sto_info.partition_name);  //
		if(index == -1)
		{
			display_info("\nBrick phone??");
			return FALSE;
		}

		if(!is_support_flash(index))
		{
			display_info("\nDont support partition.");
			return FALSE;
		}

		partition_size = partition_get_size(index);
		dprintf(DBG_LV, "[index:%d]-[partitionSize:%lld]-[downSize:%d]\n", index, partition_size, sto_info.to_write_data_len);

		if (ROUND_TO_PAGE(sto_info.to_write_data_len,511) > partition_size)
		{
			display_info("size too large, space small.");
			dprintf(DBG_LV, "size too large, space small.");
			return FALSE;
		}

		{
			char i_type[20] = {0};
			get_image_type(data,length,(char *)i_type);
					
			partition_get_type(index,&p_type);
			
			if(strcmp(i_type,p_type)){
					display_info("[warning]image type is not match with partition type\n");
					dprintf(DBG_LV, "[warning]image type'%s' is not match with partition type'%s'",i_type,p_type);
			}
			printf("image type %s\n",i_type);

			if(!strcmp(i_type,"raw data")){
				img_type = RAW_DATA_IMG;	
			}else if(!strcmp(i_type,"yaffs2")){
				img_type = YFFS2_IMG;	
			}else if(!strcmp(i_type,"ubifs")){
				img_type = UBIFS_IMG;	
			}else{
					dprintf(DBG_LV, "image type '%s' unkown\n",i_type);
					display_info("\nimage type unkown");
					return FALSE;
			}
		}		
		sto_info.image_base_addr = partition_get_offset(index);

		//NAND has no sparse image.
		//sto_info.unsparse_status.image_base_addr = sto_info.image_base_addr;
		//sto_info.is_sparse_image = is_sparse_image(data, length);
		sto_info.first_run = 0;
	}
#if defined(MTK_MLC_NAND_SUPPORT)
	if (0 != nand_write_img_ex((u64)(sto_info.image_base_addr+sto_info.bulk_image_offset), (void*)data, length,img_total_len?(u64)(img_total_len):(u64)(sto_info.to_write_data_len), &w_length, (u64)(sto_info.image_base_addr),(u64)partition_size, img_type))
#else
	if (0 != nand_write_img_ex((u32)(sto_info.image_base_addr+sto_info.bulk_image_offset), (void*)data, length,img_total_len?(u32)(img_total_len):(u32)(sto_info.to_write_data_len), &w_length, (u32)(sto_info.image_base_addr),(u32)partition_size, img_type))
#endif
	{
		dprintf(DBG_LV, "nand_write_img() Failed.\n");
		display_info("Error in write bulk in NAND.");
		return FALSE;
	}
	if(sto_info.checksum_enabled)
	{
		//NAND do not support read() now.
	}

	sto_info.bulk_image_offset += w_length;

	return TRUE;
}
BOOL write_to_emmc(u8* data, u32 length)
{
	u64 paritition_size = 0;
	u64 size_wrote = 0;
	int next_flip = 0;
	u32 index;
	u32 pre_chksum = 0;
	u32 post_chksum = 0;
	int r;

	while(sto_info.first_run)
	{
		r = get_partition_name(data, length, sto_info.partition_name);
		if(r < 0)
		{
			display_info("\nget_partition_name() Fail");
			return FALSE;
		}

		if((!strncmp((char*)sto_info.partition_name, (char*)"signatureFile", 16))
			|| (!strncmp((char*)sto_info.partition_name, (char*)"boot", 8)))
		{
			//this do not need subsequent codes for normal partition.
			ctx.boot_like_info.is_boot_like_image = TRUE;
			ctx.boot_like_info.offset = 0;
			sto_info.first_run = 0;
			break;
		}

		index = partition_get_index((char*)sto_info.partition_name);
		if(index == (u32)(-1))
		{
			display_info("\nBrick phone??");
			return FALSE;
		}

		if(!is_support_flash(index))
		{
			display_info((char*)sto_info.partition_name);
			display_info("\nDont support partition");
			return FALSE;
		}

		paritition_size = partition_get_size(index);
		dprintf(DBG_LV, "[index:%d]-[downSize:%d]\n", index,  sto_info.to_write_data_len);

		if (ROUND_TO_PAGE(sto_info.to_write_data_len,511) > paritition_size)
		{
			display_info("\nsize too large, space small.");
			dprintf(DBG_LV, "size too large, space small.");
			return FALSE;
		}

#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
		sto_info.part_id = partition_get_region(index);
		sto_info.unsparse_status.part_id = sto_info.part_id;
#endif
		sto_info.image_base_addr = partition_get_offset(index);
		sto_info.unsparse_status.image_base_addr = sto_info.image_base_addr;
		sto_info.is_sparse_image = is_sparse_image(data, length);
		sto_info.first_run = 0;
	}

	//boot like image do not need write to image at this function. it is in flash function.
	if(ctx.boot_like_info.is_boot_like_image)
	{
		dprintf(DBG_LV, "boot like img: len: %d\n", length);
		dprintf(DBG_LV, "data: %08X\n", (u32)data);
		//dprintf(DBG_LV, "ctx.boot_like_info.boot_like_image_address: %08X, ctx.boot_like_info.offset %u, \n", ctx.boot_like_info.boot_like_image_address , ctx.boot_like_info.offset);

		memcpy(ctx.boot_like_info.boot_like_image_address + ctx.boot_like_info.offset, data, length);
		ctx.boot_like_info.offset += length;
		return TRUE;
	}

	if(sto_info.is_sparse_image)
	{
		next_flip = cache_shift(ctx.flipIdxR);

		sto_info.unsparse_status.buf = data;
		sto_info.unsparse_status.size = length;
		mmc_write_sparse_data(&sto_info.unsparse_status);

		if(sto_info.unsparse_status.handle_status == S_DA_SDMMC_SPARSE_INCOMPLETE)
		{
			ctx.dual_cache[next_flip].padding_length = sto_info.unsparse_status.size;
			memcpy(ctx.dual_cache[next_flip].padding_buf +(CACHE_PADDING_SIZE-sto_info.unsparse_status.size)
				, sto_info.unsparse_status.buf
				, sto_info.unsparse_status.size);
		}
		else if (sto_info.unsparse_status.handle_status== S_DONE)
		{
			ctx.dual_cache[next_flip].padding_length = 0;
		}
		else
		{
			//some error
			dprintf(DBG_LV, "write_to_emmc() Failed. handle_status(%d)\n", sto_info.unsparse_status.handle_status);
			display_info("\nError in write sparse image in EMMC.");
			return FALSE;
		}
	}
	else
	{
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
		size_wrote = emmc_write(sto_info.part_id, sto_info.image_base_addr+sto_info.bulk_image_offset , (void*)data, length);
#else
		size_wrote = emmc_write(sto_info.image_base_addr+sto_info.bulk_image_offset , (void*)data, length);
#endif
		if (size_wrote  != length)
		{
			dprintf(DBG_LV, "write_to_emmc() Failed. act(%d) != want(%d)\n", (u32)size_wrote, length);
			display_info("\nError in write bulk in EMMC.");
			return FALSE;
		}
		if(sto_info.checksum_enabled)
		{
			pre_chksum = calc_checksum(data, (u32)length);
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
			if(length != emmc_read(sto_info.part_id, sto_info.image_base_addr+sto_info.bulk_image_offset, data,  length))
#else
			if(length != emmc_read(sto_info.image_base_addr+sto_info.bulk_image_offset, data,  length))
#endif
			{
				dprintf(DBG_LV, "emmc_read() Failed.\n");
				display_info("\nError in Read bulk EMMC.");
				return FALSE;
			}

			post_chksum = calc_checksum(data, (u32)length);

			if(post_chksum != pre_chksum)
			{
				dprintf(DBG_LV, "write_to_emmc() Failed. checksum error\n");
				display_info("\nWrite bulk in EMMC. Checksum Error");
				return FALSE;
			}
		}

		sto_info.bulk_image_offset += size_wrote;
	}
	return TRUE;
}
BOOL cmd_flash_nand_img(const char *arg, void *data, unsigned sz)
{
	int index;
	u64 offset,size;
	int img_type;
	char *p_type;
	char msg[256];

    index = partition_get_index(arg);
    if(index == -1){
        fastboot_fail_wrapper("partition get index fail");
        return FALSE;
    }
    if(!is_support_flash(index)){
        sprintf(msg,"partition '%s' not support flash\n",arg);
        fastboot_fail_wrapper(msg);
        return FALSE;
    }

    offset = partition_get_offset(index);
    if(offset == (u64)(-1)){
        fastboot_fail_wrapper("partition get offset fail");
        return FALSE;
    }else{
        printf("get offset: 0x%llx\n",offset);
    }
    size = partition_get_size(index);
    if(size == (u64)(-1)){
        fastboot_fail_wrapper("partition get size fail");
        return FALSE;
    }else{
        printf("get size: 0x%llx\n",size);
    }

    if (!strcmp(arg, "boot") || !strcmp(arg, "recovery"))
    {
        if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC)))
        {
            fastboot_fail_wrapper("image is not a boot image");
            return FALSE;
        }
    }
    {
			char i_type[20] = {0};
			
			get_image_type(data,sz,(char *)i_type);
					
			partition_get_type(index,&p_type);
			
			if(strcmp(i_type,p_type)){
					display_info("[warning]image type is not match with partition type\n");
					dprintf(DBG_LV, "[warning]image type'%s' is not match with partition type'%s'",i_type,p_type);
			}
			if(!strcmp(i_type,"raw data")){
				img_type = RAW_DATA_IMG;	
			}else if(!strcmp(i_type,"yaffs2")){
				img_type = YFFS2_IMG;	
			}else if(!strcmp(i_type,"ubifs")){
				img_type = UBIFS_IMG;	
			}else{
					dprintf(DBG_LV, "image type '%s' unkown\n",i_type);
					display_info("\nimage type unkown");
					return FALSE;
			}
		}
    TIME_START;
    display_info("write flash ....");
    printf("writing %d bytes to '%s' img_type %d\n", sz, arg,img_type);
#if defined(MTK_MLC_NAND_SUPPORT)
    if (nand_write_img((u64)offset, (char*)data, sz,(u64)size,img_type)) {
#else
    if (nand_write_img((u32)offset, (char*)data, sz,(u32)size,img_type)) {
#endif
        fastboot_fail_wrapper("nand  write image failure");
        return FALSE;
    }
    printf("partition '%s' updated\n", arg);
    fastboot_ok_wrapper("write flash sucess",sz);

    return TRUE;
}


void cmd_flash_nand(const char *arg, void *data, unsigned sz)
{
	char msg[128] = {0};

	if(sz  == 0)
	{
		fastboot_okay("");
		return;
	}
	
#ifdef MTK_SECURITY_SW_SUPPORT    
    //Please DO NOT get any data for reference if security check is not passed
    if(!security_check((u8**)&data, &sz, 0, arg))
    {
        sprintf(msg, "\nSecurity deny - Err:0x%x \n", sec_error());
    	dprintf(DBG_LV, msg);
    	fastboot_fail_wrapper(msg);
        return;
    }
#endif

	dprintf(DBG_LV, "cmd_flash_nand, data:0x%x\n",*(int*)data);

    if(cmd_flash_nand_img(arg,data,sz))
    {
        //[Security] Notify security check that is the end.
        sz = 0;
    #ifdef MTK_SECURITY_SW_SUPPORT    
        security_check((u8**)&data, &sz, IMAGE_TRUNK_SIZE, arg); 
    #endif
    }
}
Esempio n. 12
0
BOOL write_to_emmc(u8* data, u32 length)
{
	u64 paritition_size = 0;
	u64 size_wrote = 0;
	int next_flip = 0;
	u32 index;
	u32 pre_chksum = 0;
	u32 post_chksum = 0;
	int r;

	if(sto_info.first_run)
	{
		r = get_partition_name(data, length, sto_info.partition_name);
		if(r < 0)
		{
			display_info("\nASSERT!! get_partition_name() Fail");
			return FALSE;
		}
		if(!strncmp(sto_info.partition_name, "boot", 8))
		{
			ctx.boot_info.is_boot_image = TRUE;
			ctx.boot_info.offset = 0;
		}
		index = partition_get_index(sto_info.partition_name);
		if(index == -1)
		{
			display_info("\nASSERT!! Brick phone??");
			return FALSE;
		}

		if(!is_support_flash(index))
		{
			display_info(sto_info.partition_name);
			display_info("\nASSERT!! Dont support system??");
			return FALSE;
		}

		paritition_size = partition_get_size(index);
		dprintf(DBG_LV, "[index:%d]-[partitionSize:%lld]-[downSize:%lld]\n", index, paritition_size, sto_info.to_write_data_len);

		if (ROUND_TO_PAGE(sto_info.to_write_data_len,511) > paritition_size)
		{
			display_info("\nsize too large, space small.");
			dprintf(DBG_LV, "size too large, space small.");
			return FALSE;
		}

		sto_info.image_base_addr = partition_get_offset(index);
		sto_info.unsparse_status.image_base_addr = sto_info.image_base_addr;
		sto_info.is_sparse_image = is_sparse_image(data, length);
		sto_info.first_run = 0;
	}

	//boot image do not need write to image at this function. it is in flash function.
	if(ctx.boot_info.is_boot_image)
	{
		dprintf(DBG_LV, "boot img: len: %d\n", length);
		dprintf(DBG_LV, "data: %08X\n", data);
		dprintf(DBG_LV, "ctx.boot_info.boot_image_address: %08X, ctx.boot_info.offset %u, \n", ctx.boot_info.boot_image_address , ctx.boot_info.offset);

		memcpy(ctx.boot_info.boot_image_address + ctx.boot_info.offset, data, length);
		ctx.boot_info.offset += length;
		return TRUE;
	}

	if(sto_info.is_sparse_image)
	{
		next_flip = cache_shift(ctx.flipIdxR);

		sto_info.unsparse_status.buf = data;
		sto_info.unsparse_status.size = length;
		mmc_write_sparse_data(&sto_info.unsparse_status);

		if(sto_info.unsparse_status.handle_status == S_DA_SDMMC_SPARSE_INCOMPLETE)
		{
			ctx.dual_cache[next_flip].padding_length = sto_info.unsparse_status.size;
			memcpy(ctx.dual_cache[next_flip].padding_buf +(CACHE_PADDING_SIZE-sto_info.unsparse_status.size)
				, sto_info.unsparse_status.buf
				, sto_info.unsparse_status.size);
		}
		else if (sto_info.unsparse_status.handle_status== S_DONE)
		{
			ctx.dual_cache[next_flip].padding_length = 0;
		}
		else
		{
			//some error
			dprintf(DBG_LV, "write_to_emmc() Failed. handle_status(%d)\n", sto_info.unsparse_status.handle_status);
			display_info("\nError in write sparse image in EMMC.");
			return FALSE;
		}
	}
	else
	{
		size_wrote = emmc_write(sto_info.image_base_addr+sto_info.bulk_image_offset , (void*)data, length);
		if (size_wrote  != length)
		{
			dprintf(DBG_LV, "write_to_emmc() Failed. act(%lld) != want(%lld)\n", size_wrote, length);
			display_info("\nError in write bulk in EMMC.");
			return FALSE;
		}
		if(sto_info.checksum_enabled)
		{
			pre_chksum = calc_checksum(data, (u32)length);
			if(length != emmc_read(sto_info.image_base_addr+sto_info.bulk_image_offset, data,  length))
			{
				dprintf(DBG_LV, "emmc_read() Failed.\n");
				display_info("\nError in Read bulk EMMC.");
				return FALSE;
			}

			post_chksum = calc_checksum(data, (u32)length);

			if(post_chksum != pre_chksum)
			{
				dprintf(DBG_LV, "write_to_emmc() Failed. checksum error\n");
				display_info("\nWrite bulk in EMMC. Checksum Error");
				return FALSE;
			}
		}

		sto_info.bulk_image_offset += size_wrote;
	}
	return TRUE;
}
Esempio n. 13
0
BOOL cmd_flash_nand_img(const char *arg, void *data, unsigned sz)
{
	int index;
	u64 offset,size;
	int img_type;
	char *p_type;
	char msg[256];

    index = partition_get_index(arg);
    if(index == -1){
        fastboot_fail_wrapper("partition get index fail");
        return FALSE;
    }
    if(!is_support_flash(index)){
        sprintf(msg,"partition '%s' not support flash\n",arg);
        fastboot_fail_wrapper(msg);
        return FALSE;
    }

    offset = partition_get_offset(index);
    if(offset == -1){
        fastboot_fail_wrapper("partition get offset fail");
        return FALSE;
    }else{
        printf("get offset: 0x%llx\n",offset);
    }
    size = partition_get_size(index);
    if(size == -1){
        fastboot_fail_wrapper("partition get size fail");
        return FALSE;
    }else{
        printf("get size: 0x%llx\n",size);
    }

    if (!strcmp(arg, "boot") || !strcmp(arg, "recovery"))
    {
        if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC)))
        {
            fastboot_fail_wrapper("image is not a boot image");
            return FALSE;
        }
    }
    {
			char i_type[20] = {0};
			
			get_image_type(data,sz,(char *)i_type);
					
			partition_get_type(index,&p_type);
			
			if(strcmp(i_type,p_type)){
					display_info("[warning]image type is not match with partition type\n");
					dprintf(DBG_LV, "[warning]image type'%s' is not match with partition type'%s'",i_type,p_type);
			}
			if(!strcmp(i_type,"raw data")){
				img_type = RAW_DATA_IMG;	
			}else if(!strcmp(i_type,"yaffs2")){
				img_type = YFFS2_IMG;	
			}else if(!strcmp(i_type,"ubifs")){
				img_type = UBIFS_IMG;	
			}else{
					dprintf(DBG_LV, "image type '%s' unkown\n",i_type);
					display_info("\nimage type unkown");
					return FALSE;
			}
		}
    TIME_START;
    display_info("write flash ....");
    printf("writing %d bytes to '%s' img_type %d\n", sz, arg,img_type);
    if (nand_write_img((u32)offset, data, sz,(u32)size,img_type)) {
        fastboot_fail_wrapper("nand  write image failure");
        return FALSE;
    }
    printf("partition '%s' updated\n", arg);
    fastboot_ok_wrapper("write flash sucess",sz);

    return TRUE;
}
Esempio n. 14
0
uint32_t mmc_write_protect(const char *ptn_name, int set_clr)
{
	void *dev = NULL;
	struct mmc_card *card = NULL;
	uint32_t block_size;
	unsigned long long  ptn = 0;
	uint64_t size;
	int index = -1;
#ifdef UFS_SUPPORT
	int ret = 0;
#endif

	dev = target_mmc_device();
	block_size = mmc_get_device_blocksize();

	if (target_mmc_device())
	{
		card = &((struct mmc_device *)dev)->card;

		index = partition_get_index(ptn_name);

		ptn = partition_get_offset(index);
		if(!ptn)
		{
			return 1;
		}

		/* Convert the size to blocks */
		size = partition_get_size(index) / block_size;

		/*
		 * For read only partitions the minimum size allocated on the disk is
		 * 1 WP GRP size. If the size of partition is less than 1 WP GRP size
		 * protect atleast one WP group.
		 */
		if (partition_read_only(index) && size < card->wp_grp_size)
		{
			/* Write protect api takes the size in bytes, convert size to bytes */
			size = card->wp_grp_size * block_size;
		}
		else
		{
			size *= block_size;
		}

		/* Set the power on WP bit */
		return mmc_set_clr_power_on_wp_user((struct mmc_device *)dev, (ptn / block_size), size, set_clr);
	}
	else
	{
#ifdef UFS_SUPPORT
		/* Enable the power on WP fo all LUNs which have WP bit is enabled */
		ret = dme_set_fpoweronwpen((struct ufs_dev*) dev);
		if (ret < 0)
		{
			dprintf(CRITICAL, "Failure to WP UFS partition\n");
			return 1;
		}
#endif
	}

	return 0;
}
Esempio n. 15
0
BOOL write_to_nand(u8* data, u32 length)
{
	u64 paritition_size = 0;
	int next_flip = 0;
	u32 index;
	BOOL partition_type;
	s8* p_type;
	//u32 pre_chksum = 0;
	//u32 post_chksum = 0;
	int r;

	if(sto_info.first_run)
	{
		r = get_partition_name(data, length, sto_info.partition_name);
		if(r < 0)
		{
			display_info("ASSERT!! get_partition_name() Fail");
			return FALSE;
		}

		index = partition_get_index(sto_info.partition_name);  //
		if(index == -1)
		{
			display_info("ASSERT!! Brick phone??");
			return FALSE;
		}

		if(!is_support_flash(index))
		{
			display_info("ASSERT!! Dont support system??");
			return FALSE;
		}
		//verify boot partition.
		if (!strcmp(sto_info.partition_name, "boot") || !strcmp(sto_info.partition_name, "recovery"))
		{
			if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC)))
			{
				display_info("image is not a boot image");
				return FALSE;
			}
		}

		paritition_size = partition_get_size(index);
		dprintf(DBG_LV, "[index:%d]-[partitionSize:%lld]-[downSize:%d]\n", index, paritition_size, sto_info.to_write_data_len);

		if (ROUND_TO_PAGE(sto_info.to_write_data_len,511) > paritition_size)
		{
			display_info("size too large, space small.");
			dprintf(DBG_LV, "size too large, space small.");
			return FALSE;
		}

		partition_get_type(index,&p_type);
		partition_type = (!strcmp(p_type,"yaffs2")) ? TRUE : FALSE;

		sto_info.image_base_addr = partition_get_offset(index);
		//NAND has no sparse image.
		//sto_info.unsparse_status.image_base_addr = sto_info.image_base_addr;
		//sto_info.is_sparse_image = is_sparse_image(data, length);
		sto_info.first_run = 0;
	}

	if (0 != nand_write_img((u32)(sto_info.image_base_addr+sto_info.bulk_image_offset), (void*)data, length,(u32)paritition_size, partition_type))
	{
		dprintf(DBG_LV, "nand_write_img() Failed.\n");
		display_info("Error in write bulk in NAND.");
		return FALSE;
	}
	if(sto_info.checksum_enabled)
	{
		//NAND do not support read() now.
	}

	sto_info.bulk_image_offset += length;

	return TRUE;
}
Esempio n. 16
0
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;
}
BOOL cmd_flash_emmc_img(const char *arg, void *data, unsigned sz)
{
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
    unsigned int part_id;
#endif
	unsigned long long ptn = 0;
	unsigned long long size = 0;
	unsigned long long size_wrote = 0;
	int index = INVALID_PTN;
	u32 pre_chksum = 0;
	u32 post_chksum = 0;
	char msg[256];
	dprintf(DBG_LV, "Function cmd_flash_img()\n");
	//dprintf(DBG_LV, "EMMC Offset[0x%x], Length[0x%x], data In[0x%x]\n", arg, sz, data);
	TIME_START;

	if (!strcmp(arg, "partition"))
	{
		dprintf(DBG_LV, "Attempt to write partition image.(MBR, GPT?)\n");
		dprintf(DBG_LV, "Not supported, return.\n");
		fastboot_fail_wrapper("Not supported 'partition'.\n");
		return FALSE;
		/*if (write_partition(sz, (unsigned char *) data)) {
		fastboot_fail_wrapper("failed to write partition");
		return FALSE;
		}*/
	}
	else
	{
		index = partition_get_index(arg);
		if(index == -1)
		{
			fastboot_fail_wrapper("partition table doesn't exist");
			return FALSE;
		}
		if(!is_support_flash(index)){
			sprintf(msg,"\npartition '%s' not support flash",arg);
			fastboot_fail_wrapper(msg);
			return FALSE;
		}

#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
        part_id = partition_get_region(index);
#endif
		ptn = partition_get_offset(index);

		//dprintf(DBG_LV, "[arg:%s]-[index:%d]-[ptn(offset):0x%x]\n", arg, index, ptn);

		if (!strcmp(arg, "boot") || !strcmp(arg, "recovery"))
		{
			if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC)))
			{
				fastboot_fail_wrapper("\nimage is not a boot image");
				return FALSE;
			}
		}

		size = partition_get_size(index);
		//dprintf(DBG_LV, "[index:%d]-[partitionSize:%lld]-[downSize:%lld]\n", index, size, sz);

		if (ROUND_TO_PAGE(sz,511) > size)
		{
			fastboot_fail_wrapper("size too large");
			dprintf(DBG_LV, "size too large");
			return FALSE;
		}

		display_info("\nWriting Flash ... ");

		pre_chksum = calc_checksum(data,  (u32)sz);

#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
		size_wrote = emmc_write(part_id, ptn , data, sz);
#else
		size_wrote = emmc_write(ptn , data, sz);
#endif
		if (size_wrote  != sz)
		{
			//dprintf(DBG_LV, "emmc_write() Failed. act(%lld) != want(%lld)\n", size_wrote, sz);
			fastboot_fail_wrapper("\nFlash write failure");
			return FALSE;
		}

#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
		if(sz != emmc_read(part_id, ptn,  data,  sz))
#else
		if(sz != emmc_read(ptn,  data,  sz))
#endif
		{
			dprintf(DBG_LV, "emmc_read() Failed.\n");
			fastboot_fail_wrapper("\nRead EMMC error.");
			return FALSE;
		}

		post_chksum = calc_checksum(data, (u32)sz);
		if(post_chksum != pre_chksum)
		{
			dprintf(DBG_LV, "write_to_emmc() Failed. checksum error\n");
			fastboot_fail_wrapper("\nChecksum Error.");
			return FALSE;
		}

		fastboot_ok_wrapper("OK", sz);
	}
    
	return TRUE;
}
BOOL cmd_flash_emmc_sparse_img(const char *arg, void *data, unsigned sz)
{
	unsigned int chunk;
	unsigned int chunk_data_sz;
	sparse_header_t *sparse_header;
	chunk_header_t *chunk_header;
	u32 total_blocks = 0;
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
    unsigned int part_id;
#endif
	unsigned long long ptn = 0;
	unsigned long long size = 0;
	unsigned long long size_wrote = 0;
	int index = INVALID_PTN;
	char msg[256];
	dprintf(DBG_LV, "Enter cmd_flash_sparse_img()\n");
	//dprintf(DBG_LV, "EMMC Offset[0x%x], Length[%d], data In[0x%x]\n", arg, sz, data);

	index = partition_get_index(arg);
	if(index == -1)
	{
		fastboot_fail_wrapper("partition table doesn't exist");
		return FALSE;
	}

	if(!is_support_flash(index)){
		sprintf(msg,"partition '%s' not support flash\n",arg);
		fastboot_fail_wrapper(msg);
		return FALSE;
	}

#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
    part_id = partition_get_region(index);
#endif
	ptn = partition_get_offset(index);

	size = partition_get_size(index);
	if (ROUND_TO_PAGE(sz,511) > size)
	{
		fastboot_fail_wrapper("size too large");
		return FALSE;
	}

	/* Read and skip over sparse image header */
	sparse_header = (sparse_header_t *) data;
	data += sparse_header->file_hdr_sz;
	if(sparse_header->file_hdr_sz > sizeof(sparse_header_t))
	{
		/* Skip the remaining bytes in a header that is longer than
		* we expected.
		*/
		data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
	}

	dprintf (DBG_LV, "=== Sparse Image Header ===\n");
	dprintf (DBG_LV, "magic: 0x%x\n", sparse_header->magic);
	dprintf (DBG_LV, "major_version: 0x%x\n", sparse_header->major_version);
	dprintf (DBG_LV, "minor_version: 0x%x\n", sparse_header->minor_version);
	dprintf (DBG_LV, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
	dprintf (DBG_LV, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
	dprintf (DBG_LV, "blk_sz: %d\n", sparse_header->blk_sz);
	dprintf (DBG_LV, "total_blks: %d\n", sparse_header->total_blks);
	dprintf (DBG_LV, "total_chunks: %d\n", sparse_header->total_chunks);

	TIME_START;
	display_info("Writing Flash ... ");
	/* Start processing chunks */
	for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
	{
		/* Read and skip over chunk header */
		chunk_header = (chunk_header_t *) data;
		data += sizeof(chunk_header_t);

		dprintf (INFO, "=== Chunk Header ===\n");
		dprintf (INFO, "chunk_type: 0x%x\n", chunk_header->chunk_type);
		dprintf (INFO, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
		dprintf (INFO, "total_size: 0x%x\n", chunk_header->total_sz);

		if(sparse_header->chunk_hdr_sz > sizeof(chunk_header_t))
		{
			/* Skip the remaining bytes in a header that is longer than
			* we expected.
			*/
			data += (sparse_header->chunk_hdr_sz - sizeof(chunk_header_t));
		}

		chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
		switch (chunk_header->chunk_type)
		{
		case CHUNK_TYPE_RAW:
			if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
				chunk_data_sz))
			{
				fastboot_fail_wrapper("Bogus chunk size for chunk type Raw");
				return FALSE;
			}


			//dprintf(INFO, "[Flash Base Address:0x%llx offset:0x%llx]-[size:%d]-[DRAM Address:0x%x]\n",
			//	ptn , ((uint64_t)total_blocks*sparse_header->blk_sz), chunk_data_sz, data);

#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
			size_wrote = emmc_write(part_id, ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
				(unsigned int*)data, chunk_data_sz);
#else
			size_wrote = emmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
				(unsigned int*)data, chunk_data_sz);
#endif

			dprintf(INFO, "[wrote:%lld]-[size:%d]\n", size_wrote ,chunk_data_sz);

			if(size_wrote != chunk_data_sz)
			{
				fastboot_fail_wrapper("flash write failure");
				return FALSE;
			}
			total_blocks += chunk_header->chunk_sz;
			data += chunk_data_sz;
			break;

		case CHUNK_TYPE_DONT_CARE:
			total_blocks += chunk_header->chunk_sz;
			break;

		case CHUNK_TYPE_CRC:
			if(chunk_header->total_sz != sparse_header->chunk_hdr_sz)
			{
				fastboot_fail_wrapper("Bogus chunk size for chunk type Dont Care");
				return FALSE;
			}
			total_blocks += chunk_header->chunk_sz;
			data += chunk_data_sz;
			break;

		default:
			fastboot_fail_wrapper("Unknown chunk type");
			return FALSE;
		}
	}

	dprintf(DBG_LV, "Wrote %d blocks, expected to write %d blocks\n",
		total_blocks, sparse_header->total_blks);

	if(total_blocks != sparse_header->total_blks)
	{
		fastboot_fail_wrapper("sparse image write failure");
        return FALSE;
	}

    fastboot_ok_wrapper("Write Flash OK", sz);
	
	return TRUE;;
}
Esempio n. 19
0
void cmd_flash_nand(const char *arg, void *data, unsigned sz)
{
	int index;
	u64 offset,size;
	bool partition_type;
	char *p_type;
	char msg[256];

	if(sz  == 0)
	{
		fastboot_okay("");
		return;
	}

	index = partition_get_index(arg);
	if(index == -1){
		fastboot_fail_wrapper("partition get index fail");
		return;
	}
	if(!is_support_flash(index)){
		sprintf(msg,"partition '%s' not support flash\n",arg);
		fastboot_fail_wrapper(msg);
		return;
	}

	offset = partition_get_offset(index);
	if(offset == -1){
		fastboot_fail_wrapper("partition get offset fail");
		return;
	}else{
		printf("get offset: 0x%llx\n",offset);
	}
	size = partition_get_size(index);
	if(size == -1){
		fastboot_fail_wrapper("partition get size fail");
		return;
	}else{
		printf("get size: 0x%llx\n",size);
	}

	if (!strcmp(arg, "boot") || !strcmp(arg, "recovery"))
	{
		if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC)))
		{
			fastboot_fail_wrapper("image is not a boot image");
			return;
		}
	}
    partition_get_type(index,&p_type);
	partition_type = (!strcmp(p_type,"yaffs2"))?1:0;
	TIME_START;
	display_info("write flash ....");
	printf("writing %d bytes to '%s' '%s' partition_type %d\n", sz, arg,p_type,partition_type);
	if (nand_write_img((u32)offset, data, sz,(u32)size,partition_type)) {
		fastboot_fail_wrapper("nand  write image failure");
		return;
	}
	printf("partition '%s' updated\n", arg);
	fastboot_ok_wrapper("write flash sucess",sz);
	return;
}