Beispiel #1
0
// for ext4
int ext4_dump_read(part_t *part, unsigned char* buf, uint64_t offset, uint32_t len)
{
#ifdef MTK_GPT_SCHEME_SUPPORT
    if ((offset / BLK_SIZE + len / BLK_SIZE) >= part->nr_sects) {
      voprintf_error("GPT: Read %s partition overflow, size%lu, block %lu\n", part->info->name, offset / BLK_SIZE, part->nr_sects);
        return 0;
    }
#else
    if ((offset / BLK_SIZE + len / BLK_SIZE) >= part->blknum) {
      voprintf_error("Read %s partition overflow, size%lu, block %lu\n", part->name, offset / BLK_SIZE, part->blknum);
        return 0;
    }
#endif

#ifdef MTK_NEW_COMBO_EMMC_SUPPORT
#ifdef MTK_GPT_SCHEME_SUPPORT
    return emmc_read(part->part_id, (part->start_sect * BLK_SIZE) + offset, buf, len) == len;
#else
    return emmc_read(part->part_id, (part->startblk * BLK_SIZE) + offset, buf, len) == len;
#endif
#else
#ifdef MTK_GPT_SCHEME_SUPPORT
    return emmc_read((part->start_sect * BLK_SIZE) + offset, buf, len) == len;
#else
    return emmc_read((part->startblk * BLK_SIZE) + offset, buf, len) == len;
#endif
#endif
}
Beispiel #2
0
int update_firmware_emmc_image (struct update_header *header, char *name)
{
	unsigned offset = 0;
	unsigned pagesize = flash_page_size();
	unsigned pagemask = pagesize -1;
	unsigned n = 0;
	unsigned long long ptn = 0;
	unsigned ret;

	ptn = emmc_ptn_offset("cache");

	if (ptn == 0) {
		dprintf(CRITICAL, "ERROR: No cache partition found\n");
		return -1;
	}

	offset += header->image_offset;
	n = (header->image_length + pagemask) & (~pagemask);


	if (emmc_read(ptn, n+60, SCRATCH_ADDR))
	{
		dprintf(CRITICAL, "ERROR: Cannot read bootloader image\n");
		return -1;
	}

	memcpy(SCRATCH_ADDR,SCRATCH_ADDR+0x03c, n); 

	if (!strcmp(name, "bootloader")) 
		FwdnUpdateBootSDFirmware(n);

	dprintf(INFO, "Partition writen successfully!");
	return 0;
}
Beispiel #3
0
DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber (0..) */
                  BYTE *buff, /* Data buffer to store read data */
                  DWORD sector, /* Sector address (LBA) */
                  BYTE count /* Number of sectors to read (1..128) */
                 ) {
    int32_t res = emmc_read(buff, count * 512, sector);

    if (res != -1)
        return RES_OK;
    else
        return RES_ERROR;
}
Beispiel #4
0
static int emmc_get_recovery_msg(struct recovery_message *in)
{
	char *ptn_name = "misc";
	unsigned long long ptn = 0;
	unsigned int size = ROUND_TO_PAGE(sizeof(*in),511);
	unsigned char data[size];

	ptn = emmc_ptn_offset(ptn_name);
	if(ptn == 0) {
		dprintf(CRITICAL,"partition %s doesn't exist\n",ptn_name);
		return -1;
	}
	
	if (emmc_read(ptn , size ,(unsigned int*)data))
	{
		dprintf(CRITICAL,"read failure %s %d\n",ptn_name, size);
		return -1;
	}
	memcpy(in, data, sizeof(*in));
	return 0;
}
Beispiel #5
0
int main(int argc,char **argv)
{
	char op;

	if (argc < 3)
		goto CmdFail;

	op = *(argv[1]);
	switch (op) {
	case 'r':
#if ! defined (CONFIG_MTK_EMMC_SUPPORT)
		if (mtd_read(argv[2]) < 0)
#else
		if (emmc_read(argv[2]) < 0)
#endif
			goto Fail;
		break;
	case 'w':
		if (argc < 4)
			goto CmdFail;
#if ! defined (CONFIG_MTK_EMMC_SUPPORT)
		if (mtd_write(argv[2], argv+3) < 0)
#else
		if (emmc_write(argv[2], argv+3) < 0)
#endif
			goto Fail;
		break;
	default:
		goto CmdFail;
	}

	return 0;
CmdFail:
	usage(argv);
Fail:
	return -1;
}
Beispiel #6
0
int read_update_header_for_emmc_bootloader(struct update_header *header)
{
	char *ptn_name = "cache";
	unsigned long long ptn = 0;
	unsigned pagesize = 512;

	ptn = emmc_ptn_offset("cache");

	if (ptn == 0) {
		dprintf(CRITICAL, "ERROR: No cache partition found\n");
		return -1;
	}

	if (emmc_read(ptn, pagesize , buf))
	{
		dprintf(CRITICAL, "ERROR: Cannot read recovery_header\n");
		return -1;
	}
	memcpy(header, buf, sizeof(*header));

	if(strncmp(header->MAGIC, UPDATE_MAGIC, UPDATE_MAGIC_SIZE))
		return -1;
	return 0;
}
Beispiel #7
0
int do_movi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	char *cmd;
	unsigned int addr, blk, blocks;
	uint last_blkpos, bytes;

	cmd = argv[1];

	if (strcmp(cmd, "init") == 0) {
		if (argc < 4)
			goto usage;
		
		last_blkpos = (uint) simple_strtoul(argv[2], NULL, 10);
		movi_hc = (uint) simple_strtoul(argv[3], NULL, 10);

		if (movi_set_ofs(last_blkpos))
			movi_init();
	} else {
		if (argc == 4 || (strcmp(argv[2], "rootfs") == 0))
			addr = (ulong) simple_strtoul(argv[3], NULL, 16);
		else if (argc == 5)
			addr = (ulong) simple_strtoul(argv[4], NULL, 16);
		else
			goto usage;

		if (addr >= 0xc0000000)
			addr = virt_to_phys(addr);

		if ((ofsinfo.last == 0) && (movi_emmc ==0)) {
			printf("### Execute 'movi init' command first!\n");
			return -1;
		}
		
		if (strcmp(cmd, "read") == 0) {
			if (argc == 4 || (strcmp(argv[2], "rootfs") == 0)) {
				if (strcmp(argv[2], "u-boot") == 0) {
					if (movi_emmc == 1) {	/* eMMC_4.3 */
						printf("eMMC Reading bootloader.. from sector %d (%d sectors)..", ofsinfo.bl2, EMMC_BL_BLKCNT);
						emmc_read((uint) addr, ofsinfo.bl2, EMMC_BL_BLKCNT);
					} else {
						printf("Reading bootloader.. ");
						movi_read((uint) addr, ofsinfo.bl2, MOVI_BL2_BLKCNT);
					}
					printf("completed\n");

				} else if (strcmp(argv[2], "kernel") == 0) {
					if (movi_emmc == 1) {	/* eMMC_4.3 */
						printf("eMMC Reading kernel from sector %d (%d sectors).. ", ofsinfo.kernel, EMMC_KERNEL_BLKCNT);
						emmc_read((uint) addr, ofsinfo.kernel, EMMC_KERNEL_BLKCNT);
					} else {
						printf("Reading kernel from sector %d (%d sectors).. ", ofsinfo.kernel, MOVI_ZIMAGE_BLKCNT);
						movi_read((uint) addr, ofsinfo.kernel, MOVI_ZIMAGE_BLKCNT);
					}
					printf("completed\n");

				} else if (strcmp(argv[2], "rootfs") == 0) {
					bytes = simple_strtoul(argv[4], NULL, 16);
					
					if (argc == 5)
						blocks = (ulong) (bytes / MOVI_BLKSIZE);
					else
						blocks = MOVI_ROOTFS_BLKCNT;

					if (bytes % MOVI_BLKSIZE > 0)
						blocks++;

					blk = ofsinfo.rootfs;

					if (movi_emmc == 1) {	/* eMMC_4.3 */
						printf("eMMC Reading rootfs from sector %d (%d sectors).. ", ofsinfo.rootfs, EMMC_ROOTFS_BLKCNT);
						emmc_read((uint) addr, ofsinfo.rootfs, EMMC_ROOTFS_BLKCNT);
					} else {
						printf("Reading rootfs from sector %d (%d sectors).. ", blk, blocks);

						while (blocks > 0) {
							if (blocks < MOVI_RW_MAXBLKS) {
								movi_read((uint) addr, blk, blocks);
								blocks = 0;
							} else {
								movi_read((uint) addr, blk, MOVI_RW_MAXBLKS);
								addr += (MOVI_RW_MAXBLKS * MOVI_BLKSIZE);
								blk += MOVI_RW_MAXBLKS;
								blocks -= MOVI_RW_MAXBLKS;
							}
						}
					}
					printf("completed\n");
				} else
					goto usage;
			} else {
				blk = (uint) simple_strtoul(argv[2], NULL, 10);
				bytes = (uint) simple_strtoul(argv[3], NULL, 16);

				if (blk >= 0 && blk <= ofsinfo.last) {
					blocks = (int) (bytes / MOVI_BLKSIZE);

					if (bytes % MOVI_BLKSIZE > 0)
						blocks++;

					if (movi_emmc == 1) {	/* eMMC_4.3 */
						if ((blk + blocks) <= ofsinfo.last ) {
							printf("eMMC Reading data from sector %d (%d sectors).. ", blk, blocks);
							emmc_read((uint) addr, blk, blocks);
						}
					} else {
						printf("Reading data from sector %d (%d sectors).. ", blk, blocks);

						while (blocks > 0) {
							if (blocks < MOVI_RW_MAXBLKS) {
								movi_read((uint) addr, blk, blocks);
								blocks = 0;
							} else {
								movi_read((uint) addr, blk, MOVI_RW_MAXBLKS);
								addr += (MOVI_RW_MAXBLKS * MOVI_BLKSIZE);
								blk += MOVI_RW_MAXBLKS;
								blocks -= MOVI_RW_MAXBLKS;
							}
						}
					}
					printf("completed\n");
				} else
					goto usage;
			}
		} else if (strcmp(cmd, "write") == 0) {
			if (argc == 4 || (strcmp(argv[2], "rootfs") == 0)) {
				if (strcmp(argv[2], "u-boot") == 0) {
					if (movi_emmc == 1) {	/* eMMC_4.3 */
						printf("eMMC Writing bootloader to sector %d (%d sectors).. ", ofsinfo.bl2, EMMC_BL_BLKCNT);
						emmc_write((uint) addr, ofsinfo.bl2, EMMC_BL_BLKCNT);
					} else {		/* SD/MMC */
						printf("Writing 1st bootloader to sector %d (%d sectors).. ", ofsinfo.bl1, MOVI_BL1_BLKCNT);
						movi_write((uint) addr, ofsinfo.bl1, MOVI_BL1_BLKCNT);
						printf("completed\nWriting 2nd bootloader to sector %d (%d sectors).. ", ofsinfo.bl2, MOVI_BL2_BLKCNT);
						movi_write((uint) addr, ofsinfo.bl2, MOVI_BL2_BLKCNT);
					}
					printf("completed\n");

				} else if (strcmp(argv[2], "kernel") == 0) {
					if (movi_emmc == 1) {	/* eMMC_4.3 */
						printf("eMMC Writing kernel to sector %d (%d sectors).. ", ofsinfo.kernel, EMMC_KERNEL_BLKCNT);
						emmc_write((uint) addr, ofsinfo.kernel, EMMC_KERNEL_BLKCNT);
					} else {		/* SD/MMC */
						printf("Writing kernel to sector %d (%d sectors).. ", ofsinfo.kernel, MOVI_ZIMAGE_BLKCNT);
						movi_write((uint) addr, ofsinfo.kernel, MOVI_ZIMAGE_BLKCNT);
					}
					printf("completed\n");

				} else if (strcmp(argv[2], "env") == 0) {
					if (movi_emmc == 1) {	/* eMMC_4.3 */
						printf("eMMC Writing env to sector %d (%d sectors).. ", ofsinfo.env, EMMC_ENV_BLKCNT);
						emmc_write((uint) addr, ofsinfo.env, EMMC_ENV_BLKCNT);
					} else {		/* SD/MMC */
						printf("Writing env to sector %d (%d sectors).. ", ofsinfo.env, MOVI_ENV_BLKCNT);
						movi_write((uint) addr, ofsinfo.env, MOVI_ENV_BLKCNT);
					}
					printf("completed\n");

				} else if (strcmp(argv[2], "rootfs") == 0) {
					if (movi_emmc == 1) {	/* eMMC_4.3 */
						printf("eMMC Writing rootfs to sector %d (%d sectors).. ", ofsinfo.rootfs, EMMC_ROOTFS_BLKCNT);
						emmc_write((uint) addr, ofsinfo.rootfs, EMMC_ROOTFS_BLKCNT);
					} else {		/* SD/MMC */
						blk = ofsinfo.rootfs;
						bytes = simple_strtoul(argv[4], NULL, 16);
						
						if (argc == 5)
							blocks = (ulong) (bytes / MOVI_BLKSIZE);
						else
							blocks = MOVI_ROOTFS_BLKCNT;

						if (bytes % MOVI_BLKSIZE > 0)
							blocks++;

						printf("Writing rootfs to sector %d (%d sectors).. ", blk, blocks);

						while (blocks > 0) {
							if (blocks < MOVI_RW_MAXBLKS) {
								movi_write((uint) addr, blk, blocks);
								blocks = 0;
							} else {
								movi_write((uint) addr, blk, MOVI_RW_MAXBLKS);
								addr += (MOVI_RW_MAXBLKS * MOVI_BLKSIZE);
								blk += MOVI_RW_MAXBLKS;
								blocks -= MOVI_RW_MAXBLKS;
							}
						}
					}
					printf("completed\n");
				} else
					goto usage;
			} else {
				blk = (uint) simple_strtoul(argv[2], NULL, 10);
				bytes = (uint) simple_strtoul(argv[3], NULL, 16);

				if (blk >= 0 && blk <= ofsinfo.last) {
					blocks = (int) (bytes / MOVI_BLKSIZE);

					if (bytes % MOVI_BLKSIZE > 0)
						blocks++;

					if (movi_emmc == 1) {	/* eMMC_4.3 */
						if ((blk + blocks) <= ofsinfo.last ) {
							printf("eMMC Writing data to sector %d (%d sectors).. ", blk, blocks);
							emmc_write((uint) addr, blk, blocks);
						}
					} else {		/* SD/MMC */
						printf("Writing data to sector %d (%d sectors).. ", blk, blocks);

						while (blocks > 0) {
							if (blocks < MOVI_RW_MAXBLKS) {
								movi_write((uint) addr, blk, blocks);
								blocks = 0;
							} else {
								movi_write((uint) addr, blk, MOVI_RW_MAXBLKS);
								addr += (MOVI_RW_MAXBLKS * MOVI_BLKSIZE);
								blk += MOVI_RW_MAXBLKS;
								blocks -= MOVI_RW_MAXBLKS;
							}
						}
					}
					printf("completed\n");
				} else
					goto usage;
			}
		} else {
			goto usage;
		}
	}

	return 1;

usage:
	printf("Usage:\n%s\n", cmdtp->usage);
	return -1;
}
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_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;
}
static ssize_t emmc_ipanic_gbuffer_proc_read(struct file *file, char __user *buffer,
			     size_t count, loff_t *ppos)
{
	struct emmc_ipanic_data *ctx = &drv_ctx;
	size_t log_len, log_head;
	off_t log_off;
	int rc;

	if (!ctx) {
		pr_err("%s:invalid panic handler\n", __func__);
		return 0;
	}

	if (!count)
		return 0;

	mutex_lock(&drv_mutex);

	log_off = ctx->curr.log_offset[IPANIC_LOG_GBUFFER];
	log_len = ctx->curr.log_length[IPANIC_LOG_GBUFFER];
	log_head = ctx->curr.log_head[IPANIC_LOG_GBUFFER];

	if (*ppos >= log_len) {
		mutex_unlock(&drv_mutex);
		return 0;
	}

	if (*ppos < log_len - log_head) {
		/* No overflow (log_head == 0)
		 * or
		 * overflow 2nd part buf (log_head = log_woff)
		 * |-------w--------|
		 *           off^
		 *         |--------|
		 */
		log_off += log_head;
		log_len -= log_head;
	} else {
		/* 1st part buf
		 * |-------w--------|
		 *   off^
		 * |-------|
		 */
		*ppos -= (log_len - log_head);
		log_len = log_head;
	}

	if ((*ppos + count) > log_len)
		count = log_len - *ppos;

	rc = emmc_read(ctx->emmc, emmc_ipanic_gbuffer_proc_read,
			  buffer, log_off + *ppos, count, true);
	if (rc <= 0) {
		mutex_unlock(&drv_mutex);
		pr_err("%s: emmc_read: invalid args: offset:0x%08llx, count:%zd",
		       __func__, (u64)(log_off + *ppos), count);
		return rc;
	}

	*ppos += rc;

	mutex_unlock(&drv_mutex);

	return rc;
}
Beispiel #11
0
static int read_sdcard(s_device *dev, uint32_t *offset, void *buff, uint32_t len)
{
    DO_NOTHING_WITH(dev);
    return emmc_read(bd, buff, len, *offset);
}
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;
}