int
mmc_berase(int dev_num, unsigned long start, unsigned blkcnt)
{
	int err = 0;
	struct mmc *mmc = find_mmc_device(dev_num);
//	unsigned blk = 0, blk_r = 0;
	void* src = (void*)0x41000000;

	if (!mmc)
		return -1;

	memset(src, 0, 512*blkcnt);
	mmcinfo("erase blk %d ~ %d\n", start, start + blkcnt - 1);
	err = mmc_bwrite(dev_num, start, blkcnt, src);
	return err;
	/*
	if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
		mmcdbg("\n\nCaution! Your devices Erase group is 0x%x\n"
			"The erase range would be change to 0x%x~0x%x\n\n",
		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
		       ((start + blkcnt + mmc->erase_grp_size)
		       & ~(mmc->erase_grp_size - 1)) - 1);

	while (blk < blkcnt) {
		blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
			mmc->erase_grp_size : (blkcnt - blk);
		err = mmc_erase_t(mmc, start + blk, blk_r);
		if (err)
			break;

		blk += blk_r;
	}
	return blk;
	*/
}
예제 #2
0
파일: cmd_mmc.c 프로젝트: josh64x2/apc-rock
int do_mmc_write (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int device_num = 1;
	ulong dev_id = 0;
	ulong addr,block_num,bytes,blk_cnt;
	ulong ret;
		
	if (argc < 4) {
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}
	
	/*get device id*/
	dev_id = simple_strtoul(argv[1], NULL, 16);
	if (dev_id == 0 || dev_id == 1 || dev_id == 2 || dev_id == 3)//add dev_id == 3 by eason 2012/3/27
		device_num = dev_id;
	else {
		printf("dev_id Invalid\n");
		return 1;
	}

	/*get memory address*/
	addr = simple_strtoul (argv[2], NULL, 16);
	if (addr < 0) {
		printf("addr Invalid\n");
		return 1;
	}

	/*get card block address*/
	block_num = simple_strtoul (argv[3], NULL, 16);
	if (block_num < 0) {
		printf("block_num Invalid\n");
		return 1;
	}

	/*get transfer size is bytes*/
	bytes = simple_strtoul (argv[4], NULL, 16);
	if (bytes < 0) {
		printf("bytes Invalid\n");
		return 1;
	}
	
	if (bytes == 0)
		return 0;

	/*calculate transfer block count*/
	blk_cnt = (bytes / 512);
	if (bytes % 512)
		blk_cnt++;
	
	//printf("device_num = %x block_num = %x addr =  %x bytes = %x blk_cnt =%x\n",device_num,block_num,addr,bytes,blk_cnt);
	ret = mmc_bwrite(device_num,block_num,blk_cnt,(ulong *)addr);

	if (ret != blk_cnt) {
		printf("Write Data Fail\n");
		return 1;
	} else {
		printf("Write Data Success\n");
	}
		

	return 0;
}
예제 #3
0
/* update_mmc [dev no] <type> 'mem' 'addr' 'length' [load addr] */
int do_update_mmc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	block_dev_desc_t *desc;
	uint64_t dst_addr = 0, mem_len = 0;
	unsigned int mem_addr = 0;
	unsigned char *p;
	char cmd[32];
	lbaint_t blk, cnt;
	int ret, dev;

	if (6 > argc)
		goto usage;

	ret = get_device("mmc", argv[1], &desc);
	if (0 > ret) {
		printf ("** Not find device mmc.%s **\n", argv[1]);
		return 1;
	}

	dev = simple_strtoul (argv[1], NULL, 10);
	sprintf(cmd, "mmc dev %d", dev);
	if (0 > run_command(cmd, 0))	/* mmc device */
		return -1;

	if (0 != strcmp(argv[2], "2ndboot")  &&
		0 != strcmp(argv[2], "boot") &&
		0 != strcmp(argv[2], "raw")  &&
		0 != strcmp(argv[2], "part"))
		goto usage;

	mem_addr = simple_strtoul (argv[3], NULL, 16);
	dst_addr = simple_strtoull(argv[4], NULL, 16);
	mem_len  = simple_strtoull(argv[5], NULL, 16);

	p   = (unsigned char *)mem_addr;
	blk = (dst_addr/MMC_BLOCK_SIZE);
	cnt = (mem_len/MMC_BLOCK_SIZE) + ((mem_len & (MMC_BLOCK_SIZE-1)) ? 1 : 0);

	flush_dcache_all();

	if (! strcmp(argv[2], "2ndboot")) {
		struct boot_dev_head *bh = (struct boot_dev_head *)mem_addr;
		struct boot_dev_mmc  *bd = (struct boot_dev_mmc *)&bh->bdi;

		bd->port_no = dev; /* set u-boot device port num */
		printf("head boot dev  = %d\n", bd->port_no);

		goto do_write;
	}

	if (! strcmp(argv[2], "boot")) {
		struct boot_dev_head head;
		struct boot_dev_head *bh = &head;
		struct boot_dev_mmc *bd = (struct boot_dev_mmc *)&bh->bdi;
		int len = sizeof(head);
		unsigned int load = CONFIG_SYS_TEXT_BASE;

		if (argc == 7)
			load = simple_strtoul (argv[6], NULL, 16);

		memset((void*)&head, 0x00, len);

		bh->load_addr = (unsigned int)load;
		bh->jump_addr = bh->load_addr;
		bh->load_size = (unsigned int)mem_len;
		bh->signature = SIGNATURE_ID;
		bd->port_no	  = dev;

		printf("head boot dev  = %d\n", bd->port_no);
		printf("head load addr = 0x%08x\n", bh->load_addr);
		printf("head load size = 0x%08x\n", bh->load_size);
		printf("head gignature = 0x%08x\n", bh->signature);

		p -= len;
		memcpy(p, bh, len);

		mem_len += MMC_BLOCK_SIZE;
		cnt = (mem_len/MMC_BLOCK_SIZE) + ((mem_len & (MMC_BLOCK_SIZE-1)) ? 1 : 0);

		goto do_write;
	}

	if (strcmp(argv[2], "part") == 0) {
		uint64_t parts[4][2] = { {0,0}, };
		uint64_t part_len = 0;
		int partno = (int)dst_addr;
		int num = 0;

		if (0 > mmc_get_part_table(desc, parts, &num))
			return 1;

		if (partno > num || 1 > partno)  {
			printf ("** Invalid mmc.%d partition number %d (1 ~ %d) **\n",
				dev, partno, num);
			return 1;
		}

		dst_addr = parts[partno-1][0];	/* set write addr from part table */
		part_len = parts[partno-1][1];
		blk = (dst_addr/MMC_BLOCK_SIZE);

 		if (0 == check_compress_ext4((char*)p, part_len)) {
			printf("update mmc.%d compressed ext4 = 0x%llx(%d) ~ 0x%llx(%d): ",
				dev, dst_addr, (unsigned int)blk, mem_len, (unsigned int)cnt);

			ret = write_compressed_ext4((char*)p, blk);
			printf("%s\n", ret?"Fail":"Done");
			return 1;
		}
		goto do_write;
	}

do_write:
	if (! blk) {
		printf("-- Fail: start %d block(0x%llx) is in MBR zone (0x200) --\n", (int)blk, dst_addr);
		return -1;
	}

	printf("update mmc.%d type %s = 0x%llx(0x%x) ~ 0x%llx(0x%x): ",
		dev, argv[2], dst_addr, (unsigned int)blk, mem_len, (unsigned int)cnt);

	ret = mmc_bwrite(dev, blk, cnt, (void const*)p);

	printf("%s\n", ret?"Done":"Fail");
	return ret;

usage:
	cmd_usage(cmdtp);
	return 1;
}
/*******************************************************************************
Reset environment variables.
********************************************************************************/
int resetenv_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#if defined(CONFIG_ENV_IS_IN_FLASH )
	ulong	stop_addr;
	ulong	start_addr;
#elif defined(CONFIG_ENV_IS_IN_MMC)
	lbaint_t	start_lba;
	lbaint_t	blk_count;
	ulong		blk_erased;
	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
	struct mmc	*mmc;
	int			err;
#endif

#if defined(CONFIG_ENV_IS_IN_NAND)
	size_t env_offset = CONFIG_ENV_OFFSET;
	nand_info_t *nand = &nand_info[0];

	printf("Erasing 0x%x - 0x%x:",env_offset, env_offset + CONFIG_ENV_RANGE);
	nand_erase(nand, env_offset, CONFIG_ENV_RANGE);
	puts ("[Done]\n");

#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
	u32 sector = 1;

	if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) {
		sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE;
		if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE)
			sector++;
	}

#ifdef CONFIG_SPI_FLASH_PROTECTION
	printf("Unprotecting flash:");
	spi_flash_protect(flash, 0);
	printf("\t\t[Done]\n");
#endif

	printf("Erasing 0x%x - 0x%x:",CONFIG_ENV_OFFSET, CONFIG_ENV_OFFSET + sector * CONFIG_ENV_SECT_SIZE);
	if(!flash) {
		flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
								CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
		if (!flash) {
			printf("Failed to probe SPI Flash\n");
			set_default_env("!spi_flash_probe() failed");
			return 0;
		}
	}
	if (spi_flash_erase(flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE))
		return 1;
	puts("\t[Done]\n");

#ifdef CONFIG_SPI_FLASH_PROTECTION
	printf("Protecting flash:");
	spi_flash_protect(flash, 1);
	printf("\t\t[Done]\n");
#endif

#elif defined(CONFIG_ENV_IS_IN_FLASH )
	start_addr = CONFIG_ENV_ADDR;
	stop_addr = start_addr + CONFIG_ENV_SIZE - 1;

	printf("Erasing sector 0x%x:",CONFIG_ENV_OFFSET);
	flash_sect_protect (0, start_addr, stop_addr);

	flash_sect_erase (start_addr, stop_addr);

	flash_sect_protect (1, start_addr, stop_addr);
	printf("\t[Done]\n");

#elif defined(CONFIG_ENV_IS_IN_MMC)

	start_lba = CONFIG_ENV_ADDR / CONFIG_ENV_SECT_SIZE;
	blk_count = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE;

	mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
	if (!mmc) {
		printf("No MMC card found\n");
		return 1;
	}

	if (mmc_init(mmc)) {
		printf("MMC(%d) init failed\n", CONFIG_SYS_MMC_ENV_DEV);
		return 1;
	}

#ifdef CONFIG_SYS_MMC_ENV_PART /* Valid for MMC/eMMC only - switch to ENV partition */
	if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) {
		if (mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, CONFIG_SYS_MMC_ENV_PART)) {
			printf("MMC partition switch failed\n");
			return 1;
		}
	}
#endif

	printf("Erasing 0x"LBAF" blocks starting at sector 0x"LBAF" :", blk_count, start_lba);
	/* For some unknown reason the mmc_berase() fails with timeout if called
	   before any futher write to MMC/SD (for instance, right after u-boot bring up).
	   However the mmc_bwrite() always succeds.
	   Writing zeroes into SD/MMC blocks is similar operation as doing so to IDE/SATA
	   disk and therefore can be used for erasing the imformation stored on the media.
	   blk_erased = mmc_berase(CONFIG_SYS_MMC_ENV_DEV, start_lba, blk_count);
	*/
	memset(buf, 0, CONFIG_ENV_SIZE);
	blk_erased = mmc_bwrite(CONFIG_SYS_MMC_ENV_DEV, start_lba, blk_count, buf);
	if (blk_erased != blk_count) {
		printf("\t[FAIL] - erased %#lx blocks\n", blk_erased);
		err = 1;
	} else {
		printf("\t[Done]\n");
		err = 0;
	}

#ifdef CONFIG_SYS_MMC_ENV_PART /* Valid for MMC/eMMC only - restore current partition */
	if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num)
		mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, mmc->part_num);
#endif

	if (err)
		return err;

#endif
	printf("Warning: Default Environment Variables will take effect Only after RESET\n");
	return 0;
}