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;
}
Example #2
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;
}
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_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;;
}
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;
}