コード例 #1
0
ファイル: cmd_movi.c プロジェクト: minime/x210ii
int do_insnand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	size_t total = CFG_ENV_OFFSET;
	ulong addr = PHYS_SDRAM_1;

	movi_read((uint) addr, ofsinfo.bl2, MOVI_BL2_BLKCNT);
	nand_erase(&nand_info[0], 0x0, CFG_ENV_OFFSET + CFG_ENV_SIZE);
	nand_write(&nand_info[0], 0x0, &total, (u_char *) addr);

	printf("done\n");

	return 1;
}
コード例 #2
0
ファイル: env_auto.c プロジェクト: gexueyuan/WAT-10-uboot
int saveenv_nand_adv(void)
{
	size_t total;
	int ret = 0;
	
	u_char *tmp;
	total = CFG_ENV_OFFSET;

	tmp = (u_char *) malloc(total);
	nand_read(&nand_info[0], 0x0, &total, (u_char *) tmp);

	puts("Erasing Nand...");
	nand_erase(&nand_info[0], 0x0, CFG_ENV_OFFSET + CFG_ENV_SIZE);

//#ifndef CONFIG_S5PC100_EVT1
	if (nand_erase(&nand_info[0], 0x0, CFG_ENV_OFFSET + CFG_ENV_SIZE)) {
		free(tmp);
		return 1;
	}
//#endif

	puts("Writing to Nand... ");
	ret = nand_write(&nand_info[0], 0x0, &total, (u_char *) tmp);
	total = CFG_ENV_SIZE;

	ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char *) env_ptr);

//#ifndef CONFIG_S5PC100_EVT1
	if (ret || total != CFG_ENV_SIZE) {
		free(tmp);
		return 1;
	}
//#endif
	puts("done\n");
	free(tmp);

	return ret;
}
コード例 #3
0
int saveenv_nand_adv(void)
{
#if defined(CONFIG_CMD_NAND)
	size_t total;
	int ret = 0;
	
	u_char *tmp;
	total = CONFIG_ENV_OFFSET;

	tmp = (u_char *) malloc(total);
	nand_read(&nand_info[0], 0x0, &total, (u_char *) tmp);

	puts("Erasing Nand...");
	nand_erase(&nand_info[0], 0x0, CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE);

	if (nand_erase(&nand_info[0], 0x0, CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)) {
		free(tmp);
		return 1;
	}

	puts("Writing to Nand... ");
	ret = nand_write(&nand_info[0], 0x0, &total, (u_char *) tmp);
	total = CONFIG_ENV_SIZE;

	ret = nand_write(&nand_info[0], CONFIG_ENV_OFFSET, &total, (u_char *) env_ptr);

	if (ret || total != CONFIG_ENV_SIZE) {
		free(tmp);
		return 1;
	}
	puts("done\n");
	free(tmp);

	return ret;
#else
	return 0;
#endif	/* CONFIG_CMD_NAND	*/
}
コード例 #4
0
ファイル: main.c プロジェクト: kcoewoys/work
int main()
{
	nand_init();
	
	nand_erase(0x600000, 0x100000);
	
	char *str = "jiangshen 123456789 haha";

	nand_write((unsigned int)str, 0x600000, 2048);

	nand_read((unsigned int)0x41000000, 0x600000, 2048);

	return 0;
}
コード例 #5
0
ファイル: main.c プロジェクト: bourne015/myCODES
void update_program(void)
{
	unsigned char *buf = (unsigned char *)0x52000000;
	unsigned long len = 0;
	int have_begin = 0;
	int nodata_time = 0;
	char c;

	/* 读串口获得数据 */
	printf("\n\ruse gtkterm to send file\n\r", len);
	while (1)
	{
		if (getc_nowait(&buf[len]) == 0)
		{
			have_begin = 1;
			nodata_time = 0;
			len++;
		}
		else
		{
			if (have_begin)
			{
				nodata_time++;
			}			
		}

		if (nodata_time == 1000)
		{
			break;
		}
	}
	printf("have get %d bytes data\n\r", len);

	printf("Press Y to program the flash: \n\r");

	c = getc();
	
	if (c == 'y' || c == 'Y')
	{	
		/* 烧写到nand flash block 0 */
		nand_erase_block(0);
		nand_write(0, buf, len);
		
		printf("update program successful\n\r");
	}
	else
	{
		printf("Cancel program!\n\r");
	}
}
コード例 #6
0
ファイル: vfl.c プロジェクト: fergy/iPhone_kernel_26
int VFL_Write(u32 virtualPageNumber, u8* buffer, u8* spare)
{
	u16 virtualBank;
	u16 virtualBlock;
	u16 virtualPage;
	u16 physicalBlock;

	u32 dwVpn;

	int page;
	int ret;

	dwVpn = virtualPageNumber + (NANDGeometry->pagesPerSuBlk * FTLData->field_4);
	if(dwVpn >= NANDGeometry->pagesTotal) {
		LOG("ftl: dwVpn overflow: %d\n", dwVpn);
		return -EINVAL;
	}

	if(dwVpn < NANDGeometry->pagesPerSuBlk) {
		LOG("ftl: dwVpn underflow: %d\n", dwVpn);
	}

	virtual_page_number_to_virtual_address(dwVpn, &virtualBank, &virtualBlock, &virtualPage);
	physicalBlock = virtual_block_to_physical_block(virtualBank, virtualBlock);

	page = physicalBlock * NANDGeometry->pagesPerBlock + virtualPage;

#ifdef IPHONE_DEBUG
	LOG("ftl: vfl_write: vpn: %u, bank %d, page %u\n", virtualPageNumber, virtualBank, page);
#endif

		ret = nand_read(virtualBank, page, PageBuffer, SpareBuffer, true, true);
	if(ret != ERROR_EMPTYBLOCK)
	{
		LOG("ftl: WTF trying to write to a non-blank page! vpn = %u bank = %d page = %u\r\n", virtualPageNumber, virtualBank, page);
		return -1;
	}

	ret = nand_write(virtualBank, page, buffer, spare, true);
	if(ret == 0)
		return 0;

	++pstVFLCxt[virtualBank].field_16;
	vfl_gen_checksum(virtualBank);
	vfl_schedule_block_for_remap(virtualBank, virtualBlock);

	return -1;
}
コード例 #7
0
ファイル: main.c プロジェクト: elliotxu/tiny6410
void nand_write_test(void)
{
	char buf[100];
	unsigned long addr;
	unsigned long size;
	
	printf("enter the start address: ");
	scanf("%s", buf);
	addr = strtoul(buf, NULL, 0);

	printf("enter the string: ");
	scanf("%s", buf);

	size = strlen(buf) + 1;

	nand_write(addr, (unsigned char *)buf, size);
}
コード例 #8
0
ファイル: vfl.c プロジェクト: fergy/iPhone_kernel_26
static int vfl_store_cxt(int bank)
{
	int i;
	int good;
	SpareData* spareData = (SpareData*) SpareBuffer;

	--pstVFLCxt[bank].usnDec;
	pstVFLCxt[bank].usnInc = ++curVFLusnInc;
	pstVFLCxt[bank].nextcxtpage += 8;
	vfl_gen_checksum(bank);

	memset(spareData, 0xFF, NANDGeometry->bytesPerSpare);
	spareData->meta.usnDec = pstVFLCxt[bank].usnDec;
	spareData->type2 = 0;
	spareData->type1 = 0x80;

	for(i = 0; i < 8; ++i)
	{
		u32 index = pstVFLCxt[bank].activecxtblock;
		u32 block = pstVFLCxt[bank].VFLCxtBlock[index];
		u32 page = block * NANDGeometry->pagesPerBlock;
		page += pstVFLCxt[bank].nextcxtpage - 8 + i;
		nand_write(bank, page, (u8*) &pstVFLCxt[bank], (u8*) spareData, true);
	}

	good = 0;
	for(i = 0; i < 8; ++i)
	{
		u32 index = pstVFLCxt[bank].activecxtblock;
		u32 block = pstVFLCxt[bank].VFLCxtBlock[index];
		u32 page = block * NANDGeometry->pagesPerBlock;
		page += pstVFLCxt[bank].nextcxtpage - 8 + i;
		if(nand_read(bank, page, PageBuffer, (u8*) spareData, true, true) != 0)
			continue;

		if(memcmp(PageBuffer, &pstVFLCxt[bank], sizeof(VFLCxt)) != 0)
			continue;

		if(spareData->type2 == 0 && spareData->type1 == 0x80)
			++good;

	}

	return (good > 3) ? 0 : -1;
}
コード例 #9
0
/*
 * The legacy NAND code saved the environment in the first NAND device i.e.,
 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
 */
#ifdef CFG_ENV_OFFSET_REDUND
int saveenv(void)
{
	ulong total;
	int ret = 0;

	env_ptr->flags++;
	total = CFG_ENV_SIZE;

	if(gd->env_valid == 1) {
		puts ("Erasing redundant Nand...");
		if (nand_erase(&nand_info[0],
			       CFG_ENV_OFFSET_REDUND, CFG_ENV_SIZE))
			return 1;
		puts ("Writing to redundant Nand... ");
		ret = nand_write(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total,
				 (u_char*) env_ptr);
	} else {
		puts ("Erasing Nand...");
		if (nand_erase(&nand_info[0],
			       CFG_ENV_OFFSET, CFG_ENV_SIZE))
			return 1;

		puts ("Writing to Nand... ");
		ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total,
				 (u_char*) env_ptr);
	}
	if (ret || total != CFG_ENV_SIZE)
		return 1;

	puts ("done\n");
	gd->env_valid = (gd->env_valid == 2 ? 1 : 2);
	return ret;
}
#else /* ! CFG_ENV_OFFSET_REDUND */
int saveenv(void)
{
	ulong total;
	int ret = 0;

	puts ("Erasing Nand...");
	if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))
		return 1;

	puts ("Writing to Nand... ");
	total = CFG_ENV_SIZE;
	ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
	if (ret || total != CFG_ENV_SIZE)
		return 1;

	puts ("done\n");
	return ret;
}
コード例 #10
0
/**
* 作用:nandc模块按分区名和分区相对偏移来使能ECC功能的写数据操作,注意此函数的写操作带OOB数据且在写的过程中会擦除nandflash
*
* 参数:
* @partition_name          		---要写数据的分区名
* @partition_offset      	    ---要写数据的分区相对偏移地址
* @ptr_ram_addr          		---要写数据的地址
* @length      	    			---要写数据的长度
*
* 描述:根据分区名和分区的偏移地址来确定Flash的地址,再来写Flash操作
*/
s32 bsp_nand_write(const char *partition_name, u32 partition_offset, void* ptr_ram_addr, u32 length)
{
    u32 flash_addr, ret = NANDC_ERROR;
    struct ST_PART_TBL * ptable = find_partition_by_name(partition_name);

    if(!ptable)
    {
        goto ERRO;
    }

    /*得到要写Flash的地址*/
    flash_addr = ptable->offset + partition_offset;
	/*在写的过程中会擦除nandflash,因此不需要调用者再来擦除一次*/
	return nand_write(flash_addr, (u32)ptr_ram_addr, length, NULL);

 ERRO:
    return ret;
}
コード例 #11
0
ファイル: main.c プロジェクト: hemiao3000/code
int main(int argc, char *argv[])
{
	int i = 0;
	char *p=(void *)0x52000000;
	char *buf=(void *)0x51000000;
	WTCON=0;
	clock_init();
	uart_init();
	ddr_init();
	nand_init();

	memcpy(buf,"helloworld\n",12);
	memset(p,0,12);
	nand_erase(0x200000,12);
	nand_write(buf,0x200000,12);
	nand_read(p,0x200000,12);
	uprintf(p);
	uprintf("\n");
	return 0;
}
コード例 #12
0
ファイル: k9f2g08.c プロジェクト: wuliaodew/RTT
int K9F2G08_WriteTags(u32 block, u32 page, const u8 *spare, int ofs, int len)
{
    int i,stat;
	u32 _page = block*PAGES_PER_BLOCK + page;

    /* nand_Init_ECC(); */  /* Initialize ECC */
    
    nand_cs_en(); 

    nand_write_cmd(NAND_CMD_SEQIN);
	for(i=0;i<10;i++); 
    nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
	nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
    nand_write_addr(_page&0xff);
    nand_write_addr((_page>>8)&0xff);
    nand_write_addr((_page>>16)&0xff);

    for(i=0;i<len;i++)
    {
		nand_write(*spare++);
    }   

    nand_write_cmd(NAND_CMD_PAGEPROG);

    nand_wait();    /* wait tPROG 200~500us; */
 
	stat = read_nand_stats();
    if(!stat) /* Page write error */
    {	
    	nand_cs_ds();
		return 0;
    }
    else 
    {
    	nand_cs_ds();
		return 1;
    }
}
コード例 #13
0
ファイル: bubt.c プロジェクト: Philippe12/u-boot-sunxi
static int nand_burn_image(size_t image_size)
{
	int ret, block_size;
	nand_info_t *nand;
	int dev = nand_curr_device;

	if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) ||
	    (!nand_info[dev].name)) {
		puts("\nno devices available\n");
		return -ENOMEDIUM;
	}
	nand = &nand_info[dev];
	block_size = nand->erasesize;

	/* Align U-Boot size to currently used blocksize */
	image_size = ((image_size + (block_size - 1)) & (~(block_size - 1)));

	/* Erase the U-BOOT image space */
	printf("Erasing 0x%x - 0x%x:...", 0, (int)image_size);
	ret = nand_erase(nand, 0, image_size);
	if (ret) {
		printf("Error!\n");
		goto error;
	}
	printf("Done!\n");

	/* Write the image to flash */
	printf("Writing image:...");
	printf("&image_size = 0x%p\n", (void *)&image_size);
	ret = nand_write(nand, 0, &image_size, (void *)get_load_addr());
	if (ret)
		printf("Error!\n");
	else
		printf("Done!\n");

error:
	return ret;
}
コード例 #14
0
ファイル: command.c プロジェクト: 20400992/ARM-Codes
/* load from nand_flash */
int nand(int argc, char *argv[])
{
	int nand_addr, sdram_addr;
	unsigned int size;
	
	if (argc < 5)
		return 0;
		
	sdram_addr = atoi(argv[2]);
	nand_addr = atoi(argv[3]);
	size = atoi(argv[4]);

	printf("sdram 0x%x, nand 0x%x, size 0x%x\n", sdram_addr, nand_addr, size);

	if (strcmp(argv[1], "read") == 0)
		nand_read(sdram_addr, nand_addr, size);

	if (strcmp(argv[1], "write") == 0)
		nand_write(sdram_addr, nand_addr, size);

	printf("nand %s finished!\n", argv[1]);
	return 0;
}
コード例 #15
0
static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,
			int read)
{
	int ret = 0;

	while (count--) {
		/* Raw access */
		mtd_oob_ops_t ops = {
			.datbuf = (u8 *)addr,
			.oobbuf = ((u8 *)addr) + nand->writesize,
			.len = nand->writesize,
			.ooblen = nand->oobsize,
			.mode = MTD_OOB_RAW
		};

		if (read)
			ret = nand->read_oob(nand, off, &ops);
		else
			ret = nand->write_oob(nand, off, &ops);

		if (ret) {
			printf("%s: error at offset %llx, ret %d\n",
				__func__, (long long)off, ret);
			break;
		}

		addr += nand->writesize + nand->oobsize;
		off += nand->writesize;
	}

	return ret;
}

static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int i, ret = 0;
	ulong addr;
	loff_t off, size;
	char *cmd, *s;
	nand_info_t *nand;
#ifdef CONFIG_SYS_NAND_QUIET
	int quiet = CONFIG_SYS_NAND_QUIET;
#else
	int quiet = 0;
#endif
	const char *quiet_str = getenv("quiet");
	int dev = nand_curr_device;
	int repeat = flag & CMD_FLAG_REPEAT;

	/* at least two arguments please */
	if (argc < 2)
		goto usage;

	if (quiet_str)
		quiet = simple_strtoul(quiet_str, NULL, 0) != 0;

	cmd = argv[1];

	/* Only "dump" is repeatable. */
	if (repeat && strcmp(cmd, "dump"))
		return 0;

	if (strcmp(cmd, "info") == 0) {

		putc('\n');
		for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
			if (nand_info[i].name)
				nand_print_and_set_info(i);
		}
		return 0;
	}

	if (strcmp(cmd, "device") == 0) {
		if (argc < 3) {
			putc('\n');
			if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE)
				puts("no devices available\n");
			else
				nand_print_and_set_info(dev);
			return 0;
		}

		dev = (int)simple_strtoul(argv[2], NULL, 10);
		set_dev(dev);

		return 0;
	}

#ifdef CONFIG_ENV_OFFSET_OOB
	/* this command operates only on the first nand device */
	if (strcmp(cmd, "env.oob") == 0)
		return do_nand_env_oob(cmdtp, argc - 1, argv + 1);
#endif

	/* The following commands operate on the current device, unless
	 * overridden by a partition specifier.  Note that if somehow the
	 * current device is invalid, it will have to be changed to a valid
	 * one before these commands can run, even if a partition specifier
	 * for another device is to be used.
	 */
	if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
	    !nand_info[dev].name) {
		puts("\nno devices available\n");
		return 1;
	}
	nand = &nand_info[dev];

	if (strcmp(cmd, "bad") == 0) {
		printf("\nDevice %d bad blocks:\n", dev);
		for (off = 0; off < nand->size; off += nand->erasesize)
			if (nand_block_isbad(nand, off))
				printf("  %08llx\n", (unsigned long long)off);
		return 0;
	}

	/*
	 * Syntax is:
	 *   0    1     2       3    4
	 *   nand erase [clean] [off size]
	 */
	if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) {
		nand_erase_options_t opts;
		/* "clean" at index 2 means request to write cleanmarker */
		int clean = argc > 2 && !strcmp("clean", argv[2]);
		int scrub_yes = argc > 2 && !strcmp("-y", argv[2]);
		int o = (clean || scrub_yes) ? 3 : 2;
		int scrub = !strncmp(cmd, "scrub", 5);
		int spread = 0;
		int args = 2;
		const char *scrub_warn =
			"Warning: "
			"scrub option will erase all factory set bad blocks!\n"
			"         "
			"There is no reliable way to recover them.\n"
			"         "
			"Use this command only for testing purposes if you\n"
			"         "
			"are sure of what you are doing!\n"
			"\nReally scrub this NAND flash? <y/N>\n";

		if (cmd[5] != 0) {
			if (!strcmp(&cmd[5], ".spread")) {
				spread = 1;
			} else if (!strcmp(&cmd[5], ".part")) {
				args = 1;
			} else if (!strcmp(&cmd[5], ".chip")) {
				args = 0;
			} else {
				goto usage;
			}
		}

		/*
		 * Don't allow missing arguments to cause full chip/partition
		 * erases -- easy to do accidentally, e.g. with a misspelled
		 * variable name.
		 */
		if (argc != o + args)
			goto usage;

		printf("\nNAND %s: ", cmd);
		/* skip first two or three arguments, look for offset and size */
		if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0)
			return 1;

		nand = &nand_info[dev];

		memset(&opts, 0, sizeof(opts));
		opts.offset = off;
		opts.length = size;
		opts.jffs2  = clean;
		opts.quiet  = quiet;
		opts.spread = spread;

		if (scrub) {
			if (!scrub_yes)
				puts(scrub_warn);

			if (scrub_yes)
				opts.scrub = 1;
			else if (getc() == 'y') {
				puts("y");
				if (getc() == '\r')
					opts.scrub = 1;
				else {
					puts("scrub aborted\n");
					return -1;
				}
			} else {
				puts("scrub aborted\n");
				return -1;
			}
		}
		ret = nand_erase_opts(nand, &opts);
		printf("%s\n", ret ? "ERROR" : "OK");

		return ret == 0 ? 0 : 1;
	}

	if (strncmp(cmd, "dump", 4) == 0) {
		if (argc < 3)
			goto usage;

		off = (int)simple_strtoul(argv[2], NULL, 16);
		ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat);

		return ret == 0 ? 1 : 0;
	}

	if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
		size_t rwsize;
		ulong pagecount = 1;
		int read;
		int raw = 0;

		if (argc < 4)
			goto usage;

		addr = (ulong)simple_strtoul(argv[2], NULL, 16);

		read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
		printf("\nNAND %s: ", read ? "read" : "write");

		nand = &nand_info[dev];

		s = strchr(cmd, '.');

		if (s && !strcmp(s, ".raw")) {
			raw = 1;

			if (arg_off(argv[3], &dev, &off, &size))
				return 1;

			if (argc > 4 && !str2long(argv[4], &pagecount)) {
				printf("'%s' is not a number\n", argv[4]);
				return 1;
			}

			if (pagecount * nand->writesize > size) {
				puts("Size exceeds partition or device limit\n");
				return -1;
			}

			rwsize = pagecount * (nand->writesize + nand->oobsize);
		} else {
			if (arg_off_size(argc - 3, argv + 3, &dev,
						&off, &size) != 0)
				return 1;

			rwsize = size;
		}

		if (!s || !strcmp(s, ".jffs2") ||
		    !strcmp(s, ".e") || !strcmp(s, ".i")) {
			if (read)
				ret = nand_read_skip_bad(nand, off, &rwsize,
							 (u_char *)addr);
			else
				ret = nand_write_skip_bad(nand, off, &rwsize,
							  (u_char *)addr, 0);
#ifdef CONFIG_CMD_NAND_TRIMFFS
		} else if (!strcmp(s, ".trimffs")) {
			if (read) {
				printf("Unknown nand command suffix '%s'\n", s);
				return 1;
			}
			ret = nand_write_skip_bad(nand, off, &rwsize,
						(u_char *)addr,
						WITH_DROP_FFS);
#endif
		}else if((!read) && (s != NULL) && (!strcmp(s, ".uboot")) && nand->writesize == 4096){
			rwsize = 4096;
			nand_write(nand, off, &rwsize, (u_char *)addr);
			off+=  4096;
			addr+= 2048;
			nand_write(nand, off, &rwsize, (u_char *)addr);
                        off+=  4096;
                        addr+= 2048;
			nand_write(nand, off, &rwsize, (u_char *)addr);
                        off+=  4096;
                        addr+= 2048;
			nand_write(nand, off, &rwsize, (u_char *)addr);
                        off+=  4096;
                        addr+= 2048;
			rwsize = CONFIG_SYS_NAND_U_BOOT_SIZE - 8*1024;
			ret = nand_write(nand, off, &rwsize, (u_char *)addr);
#ifdef CONFIG_CMD_NAND_YAFFS
		} else if (!strcmp(s, ".yaffs")) {
			if (read) {
				printf("Unknown nand command suffix '%s'.\n", s);
				return 1;
			}
			ret = nand_write_skip_bad(nand, off, &rwsize,

q
						(u_char *)addr,
						WITH_INLINE_OOB);
#endif
		} else if (!strcmp(s, ".oob")) {
			/* out-of-band data */
			mtd_oob_ops_t ops = {
				.oobbuf = (u8 *)addr,
				.ooblen = rwsize,
				.mode = MTD_OOB_RAW
			};

			if (read)
				ret = nand->read_oob(nand, off, &ops);
			else
				ret = nand->write_oob(nand, off, &ops);
		} else if (raw) {
コード例 #16
0
int flash_test(void)
{
	struct nand_chip *nand_chip = nand_info[0].priv;
	nand_info_t *nand;
	int count;

	int ret = 0;
/*********************** ERASE - start ***************************************/
	struct erase_info instr;
	ulong start;
	ulong end = 0x8000000;
	ulong ofs = 0;
	ulong block;
	ulong off;
	size_t size;
	int i = 0;
	int test_passed = 1;
	int p_test_passed = 1;
	u_char *read_buff = (u_char *) FLASH_READ_BUF_ADDR;
	u_char *write_buff = (u_char *) FLASH_WRITE_BUF_ADDR;

	nand = &nand_info[nand_curr_device];

	/* Added to check nand bad block */
	ret = check_nand_bad_block(nand);
	if (ret != 0) {
		printf("FAILED\n");
		return -1;
	}

	for (count = 0; count < 3; count++) {
		start = 283;
		end = 345;
		if (count == 1) {
			start = 1103;
			end = 1165;
		} else if (count == 2) {
			start = 1922;
			end = 1984;
		}

		if (!end || end < 0)
			end = start;

		printf("Running Erase Test...Please wait...");
		printf("Start Block : %d, End Block : %d\n", (int)start, (int)end);

		for (i = 0; i < 0x20000; i++) {
			write_buff[i] = (unsigned char)i;
		}

		for (block = start; block <= end; ofs++, block++) {
			instr.addr = block << nand_chip->phys_erase_shift;
			instr.len = 1 << nand_chip->phys_erase_shift;
			off = instr.addr;
			size = instr.len;
			ret = nand_erase(nand, off, size);
			if (ret) {
				if (!nand_block_isbad(nand, off)) {
					printf("erase failed at block %d\n", (int)block);
					p_test_passed = test_passed = 0;
				}
				continue;
			}
		}
/*********************** ERASE - end ***************************************/
		if (p_test_passed) {
			printf("PASSED\n");
		} else
			printf("FAILED\n");

		p_test_passed = 1;
		printf("Running Write test...Please wait...");
		printf("Start Block : %d, End Block : %d\n", (int)start, (int)end);
		for (block = start; block <= end; ofs++, block++) {

			instr.addr = block << nand_chip->phys_erase_shift;
			instr.len = 1 << nand_chip->phys_erase_shift;
			off = instr.addr;
			size = instr.len;
			ret = nand_write(nand, off, &size, (u_char *) write_buff);

			if (ret) {
				printf("Error writing to NAND: ret = %d\n", ret);
				p_test_passed = test_passed = 0;
				continue;
			}
		}

		if (p_test_passed) {
			printf("PASSED\n");
		} else
			printf("FAILED\n");

		p_test_passed = 1;
		printf("Running Read test...Please wait...");
		printf("Start Block : %d, End Block : %d\n", (int)start, (int)end);

		for (block = start; block <= end; ofs++, block++) {

			instr.addr = block << nand_chip->phys_erase_shift;
			instr.len = 1 << nand_chip->phys_erase_shift;
			off = instr.addr;
			size = instr.len;
			nand_read(nand, off, &size, (u_char *) read_buff);

			for (i = 0; i < 0x20000; i++) {
				if (read_buff[i] != (unsigned char)i) {
					if (!nand_block_isbad(nand, off)) {
						printf("write-read failed at offset 0x%x (0x%x)\n", (unsigned int)(block * 0x20000 + i), read_buff[i]);
						p_test_passed = test_passed = 0;
					}
					break;
				}
			}
		}

		if (p_test_passed) {
			printf("PASSED\n");
		} else {
			printf("FAILED\n");
		}
	}

/*********************** ERASE - start ***************************************/
	printf("Erase nand after completing the Nand write read test... \n");
	{
		struct erase_info instr;
		ulong start;
		ulong end = 0x8000000;
		ulong ofs = 0;
		ulong block;
		ulong off, size;
		int i = 0;
		u_char *write_buff = (u_char *) FLASH_WRITE_BUF_ADDR;

		nand = &nand_info[nand_curr_device];

		for (count = 0; count < 3; count++) {
			start = 283;
			end = 345;
			if (count == 1) {
				start = 1103;
				end = 1165;
			} else if (count == 2) {
				start = 1922;
				end = 1984;
			}

			if (!end || end < 0)
				end = start;

			printf("Running Erase Test...Please wait...");
			printf("Start Block : %d, End Block : %d\n", (int)start, (int)end);

			for (i = 0; i < 0x20000; i++) {
				write_buff[i] = (unsigned char)i;
			}
			for (block = start; block <= end; ofs++, block++) {
				instr.addr = block << nand_chip->phys_erase_shift;
				instr.len = 1 << nand_chip->phys_erase_shift;
				off = instr.addr;
				size = instr.len;
				ret = nand_erase(nand, off, size);
				if (ret) {
					if (!nand_block_isbad(nand, off)) {
						printf("erase failed at block %d\n", (int)block);
						p_test_passed = test_passed = 0;
					}
					continue;
				}
			}
		}
	}
/*********************** ERASE - end ***************************************/
	printf("Nand Test Completed... %s\n", ((test_passed) ? "PASS" : "FAIL"));
	return 0;
}
コード例 #17
0
ファイル: commands.c プロジェクト: baliking/iphonelinux
void cmd_nand_write(int argc, char** argv) {
	if(argc < 6) {
		bufferPrintf("Usage: %s <data> <spare> <bank> <page> <ecc>\r\n", argv[0]);
		return;
	}

	uint32_t address = parseNumber(argv[1]);
	uint32_t spare = parseNumber(argv[2]);
	uint32_t bank = parseNumber(argv[3]);
	uint32_t page = parseNumber(argv[4]);
	uint32_t ecc = parseNumber(argv[5]);

	bufferPrintf("nand_write(%d, %d, %x, %x, %d) = %d\r\n", bank, page, address, spare, ecc, nand_write(bank, page, (uint8_t*) address, (uint8_t*) spare, ecc));
}
コード例 #18
0
ファイル: main.c プロジェクト: elliotxu/tiny6410
void update_program(void)
{
	unsigned char *buf = (unsigned char *)0x52000000;
	unsigned long len = 0;
	int have_begin = 0;
	int nodata_time = 0;
	unsigned long erase_addr;
	char c;
	int i;

	/* 读串口获得数据 */
	printf("\n\ruse V2.2.exe/gtkterm to send file\n\r", len);
	while (1)
	{
		if (getc_nowait(&buf[len]) == 0)
		{
			have_begin = 1;
			nodata_time = 0;
			len++;
		}
		else
		{
			if (have_begin)
			{
				nodata_time++;
			}			
		}

		if (nodata_time == 1000)
		{
			break;
		}
	}
	printf("have get %d bytes data\n\r", len);
	printf("the first 16 bytes data: \n\r");
	for (i = 0; i < 16; i++)
	{
		printf("%02x ", buf[i]);
	}
	printf("\n\r");

	printf("Press Y to program the flash: \n\r");

	c = getc();
	
	if (c == 'y' || c == 'Y')
	{	
		/* 烧写到nand flash block 0 */
		for (erase_addr = 0; erase_addr < ((len + 0x1FFFF) & ~0x1FFFF); erase_addr += 0x20000)
		{
			nand_erase_block(erase_addr);
		}
		nand_write(0, buf, len);
		
		printf("update program successful\n\r");
	}
	else
	{
		printf("Cancel program!\n\r");
	}
}
コード例 #19
0
ファイル: cmd_nand.c プロジェクト: Astralix/hardware_drivers
static int nand_biterr(nand_info_t *nand, loff_t addr, int bit)
{
	nand_erase_options_t opts;
	struct mtd_oob_ops ops;
	uint8_t *datbuf, *pagebuf, *write_buf;
	size_t size;
	loff_t write_addr;
	int ret, pages;

	datbuf = malloc(nand->erasesize);
	if (!datbuf) {
		printf("biterr: out of memory\n");
		return 1;
	}
	pagebuf = malloc(nand->writesize + nand->oobsize);
	if (!pagebuf) {
		printf("biterr: out of memory\n");
		free(datbuf);
		return 1;
	}

	/* first read the whole erase block */
	size = nand->erasesize;
	ret = nand_read(nand, addr & ~(nand->erasesize - 1), &size, datbuf);
	if (ret < 0 && ret != -EUCLEAN) {
		printf("biterr: nand_read failed\n");
		goto err;
	}

	nand_use_ecc(nand, 0);

	/* read the affected page with oob */
	memset(&ops, 0, sizeof(ops));
	ops.datbuf = pagebuf;
	ops.oobbuf = pagebuf + nand->writesize;
	ops.len = nand->writesize;
	ops.ooblen = nand->oobsize;
	ops.mode = MTD_OOB_RAW;
	ret = nand->read_oob(nand, addr & ~(nand->writesize - 1), &ops);
	if (ret < 0) {
		printf("biterr: read_oob failed\n");
		nand_use_ecc(nand, 1);
		goto err;
	}

	/* flip the bit(s) */
	pagebuf[(addr & (nand->writesize - 1)) + (bit & ~7)] ^= 1 << (bit & 7);

	/* erase */
	memset(&opts, 0, sizeof(opts));
	opts.quiet  = 1;
	opts.offset = addr & ~(nand->erasesize - 1);
	opts.length = nand->erasesize;
	ret = nand_erase_opts(nand, &opts);
	if (ret < 0) {
		printf("biterr: erase failed\n");
		nand_use_ecc(nand, 1);
		goto err;
	}

	/* write the affected page back with oob in raw mode */
	memset(&ops, 0, sizeof(ops));
	ops.datbuf = pagebuf;
	ops.oobbuf = pagebuf + nand->writesize;
	ops.len = nand->writesize;
	ops.ooblen = nand->oobsize;
	ops.mode = MTD_OOB_RAW;
	ret = nand->write_oob(nand, addr & ~(nand->writesize - 1), &ops);
	if (ret < 0) {
		printf("biterr: write_oob failed\n");
		nand_use_ecc(nand, 1);
		goto err;
	}

	nand_use_ecc(nand, 1);

	/* write back the other pages as normal */
	write_addr = addr & ~(nand->erasesize - 1);
	write_buf = datbuf;
	for (pages = nand->erasesize / nand->writesize;
	     pages > 0;
	     pages--, write_addr += nand->writesize, write_buf += nand->writesize) {
		/* skip the block that was written back raw */
		if (write_addr == (addr & ~(nand->writesize - 1)))
			continue;

		size = nand->writesize;
		ret = nand_write(nand, write_addr, &size, write_buf);
		if (ret < 0)
			printf("biterr: error writing back page 0x%llx\n", write_addr);
	}

	free(datbuf);
	free(pagebuf);
	return 0;

err:
	free(datbuf);
	free(pagebuf);
	return 1;
}
コード例 #20
0
ファイル: env_auto.c プロジェクト: gexueyuan/WAT-10-uboot
/*
 * The legacy NAND code saved the environment in the first NAND device i.e.,
 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
 */
int saveenv_nand(void)
{
        size_t total;
        int ret = 0, i;
        u32 erasebase;
        u32 eraselength;
        u32 eraseblock;
        u32 erasesize = nand_info[0].erasesize;
        uint8_t *data;

        puts("Erasing Nand...\n");

        /* If the value of CFG_ENV_OFFSET is not a NAND block boundary, the
         * NAND erase operation will fail. So first check if the CFG_ENV_OFFSET
         * is equal to a NAND block boundary
         */
        if ((CFG_ENV_OFFSET % (erasesize - 1)) != 0 ) {
                /* CFG_ENV_OFFSET is not equal to block boundary address. So, read
                 * the read the NAND block (in which ENV has to be stored), and
                 * copy the ENV data into the copied block data.
                 */

                /* Step 1: Find out the starting address of the NAND block to
                 * be erased. Also allocate memory whose size is equal to tbe
                 * NAND block size (NAND erasesize).
                 */
                eraseblock = CFG_ENV_OFFSET / erasesize;
                erasebase = eraseblock * erasesize;
                data = (uint8_t*)malloc(erasesize);
                if (data == NULL) {
                        printf("Could not save enviroment variables\n");
                        return 1;
                }

                /* Step 2: Read the NAND block into which the ENV data has
                 * to be copied
                 */
                total = erasesize;
		for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
			if (nand_scan(&nand_info[i], 1) == 0) {
				ret = nand_read(&nand_info[0], erasebase, &total, data);
			} else {
				printf("no devices available\n");
				return 1;
			}
		}
                if (ret || total != erasesize) {
                        printf("Could not save enviroment variables %d\n",ret);
                        return 1;
                }

                /* Step 3: Copy the ENV data into the local copy of the block
                 * contents.
                 */
                memcpy((data + (CFG_ENV_OFFSET - erasebase)), (void*)env_ptr, CFG_ENV_SIZE);
        } else {
                /* CFG_ENV_OFFSET is equal to a NAND block boundary. So
                 * no special care is required when erasing and writing NAND
                 * block
                 */
                data = env_ptr;
                erasebase = CFG_ENV_OFFSET;
                erasesize = CFG_ENV_SIZE;
        }

        /* Erase the NAND block which will hold the ENV data */
        if (nand_erase(&nand_info[0], erasebase, erasesize))
                return 1;

        puts("Writing to Nand... \n");
        total = erasesize;

        /* Write the ENV data to the NAND block */
        ret = nand_write(&nand_info[0], erasebase, &total, (u_char*)data);
        if (ret || total != erasesize) {
                printf("Could not save enviroment variables\n");
                return 1;
        }

         if ((CFG_ENV_OFFSET % (erasesize - 1)) != 0 )
                free(data);

        puts("Saved enviroment variables\n");
        return ret;
}
コード例 #21
0
/*
 * The legacy NAND code saved the environment in the first NAND device i.e.,
 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
 */
#ifdef CFG_ENV_OFFSET_REDUND
int saveenv(void)
{
	ulong total;
	int ret = 0;

	env_ptr->flags++;
	total = CFG_ENV_SIZE;

	if(gd->env_valid == 1) {
		puts ("Erasing redundant Nand...");
		if (nand_erase(&nand_info[0],
			       CFG_ENV_OFFSET_REDUND, CFG_ENV_SIZE))
			return 1;
		puts ("Writing to redundant Nand... ");
		ret = nand_write(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total,
				 (u_char*) env_ptr);
	} else {
		puts ("Erasing Nand...");
		if (nand_erase(&nand_info[0],
			       CFG_ENV_OFFSET, CFG_ENV_SIZE))
			return 1;

		puts ("Writing to Nand... ");
		ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total,
				 (u_char*) env_ptr);
	}
	if (ret || total != CFG_ENV_SIZE)
		return 1;

	puts ("done\n");
	gd->env_valid = (gd->env_valid == 2 ? 1 : 2);
	return ret;
}
#else /* ! CFG_ENV_OFFSET_REDUND */
int saveenv(void)  //YWDRIVER_MODI lwj :这里需要注意,还需要加一些代码,否则如果要保存环境变量的地方是坏块的话,就会出问题的。
{
	//YWDRIVER_MODI 2010/3/5 d48zm modify
	#if 0
	int ret = 0;
	int blockstart = -1;
	ulong erasesize_blockalign = nand_info[0].erasesize;
	u_char* data_ptr = (u_char*)env_ptr;
	ssize_t offset = CFG_ENV_OFFSET;
	ssize_t envlen = CFG_ENV_SIZE;
	ulong writelen = erasesize_blockalign;
	ulong checklen = erasesize_blockalign;
	ssize_t boundbegin = CFG_ENV_OFFSET + YW_CFG_NAND_ENV_BOUND - erasesize_blockalign;

	while ((envlen > 0) && (offset <= boundbegin)){

		if (envlen < erasesize_blockalign){
			checklen = envlen;
			writelen = envlen;
		}

		/*
		 * new eraseblock, check for bad block(s). Stay in the
		 * loop to be sure if the offset changes because of
		 * a bad block, that the next block that will be
		 * written to is also checked. Thus avoiding errors if
		 * the block(s) after the skipped block(s) is also bad
		 * (number of blocks depending on the blockalign
		 */
		while (blockstart != (offset & (~erasesize_blockalign+1))) {
			blockstart = offset & (~erasesize_blockalign+1);

			int ret = nand_block_isbad(&nand_info[0], offset);

			if (ret < 0) {
				printf("Bad block check failed\n");
				return 1;
			}
			if (ret == 1) {
				offset = blockstart
					+ erasesize_blockalign;
				printf("\rBad block at 0x%lx "
					   "in erase block from "
					   "0x%x will be skipped\n",
					   (long) offset,
					   blockstart);
			}
		}
		printf ("Erasing Nand block at 0x%lx...", offset);
		if (nand_erase(&nand_info[0], offset, erasesize_blockalign))
			return 1;

		puts ("Writing to Nand block... ");
		ret = nand_write(&nand_info[0], offset, &writelen, data_ptr);
		if (ret || writelen != checklen)
			return 1;

		envlen -= writelen;
		data_ptr += writelen;
		offset += writelen;
	}
	#else
	ulong total;
	int ret = 0;

	puts ("Erasing Nand...");
	if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))
		return 1;

	puts ("Writing to Nand... ");
	total = CFG_ENV_SIZE;
	ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
	if (ret || total != CFG_ENV_SIZE)
		return 1;
	#endif
	//YWDRIVER_MODI end

	puts ("done\n");
	return ret;
}