Esempio n. 1
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
	u32 offset;

	if (init_mmc_for_env(mmc))
		return 1;

	if(mmc_get_env_addr(mmc, &offset))
		return 1;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc   = crc32(0, env_new.data, ENV_SIZE);
	printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV);
	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)&env_new)) {
		puts("failed\n");
		return 1;
	}

	puts("done\n");
	return 0;
}
Esempio n. 2
0
/*
 * Command interface: print one or all environment variables
 *
 * Returns 0 in case of error, or length of printed string
 */
static int env_print(char *name)
{
	char *res = NULL;
	size_t len;

	if (name) {		/* print a single name */
		ENTRY e, *ep;

		e.key = name;
		e.data = NULL;
		hsearch_r(e, FIND, &ep, &env_htab);
		if (ep == NULL)
			return 0;
		len = printf("%s=%s\n", ep->key, ep->data);
		return len;
	}

	/* print whole list */
	len = hexport_r(&env_htab, '\n', &res, 0);

	if (len > 0) {
		puts(res);
		free(res);
		return len;
	}

	/* should never happen */
	return 0;
}
Esempio n. 3
0
/* Export the environment and generate CRC for it. */
int env_export(env_t *env_out)
{
	char *res;
	ssize_t	len;
	int ret;

	res = (char *)env_out->data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}

	/* Encrypt the env if desired. */
	ret = env_aes_cbc_crypt(env_out, 1);
	if (ret)
		return ret;

	env_out->crc = crc32(0, env_out->data, ENV_SIZE);

#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
	env_out->flags = ++env_flags; /* increase the serial */
#endif

	return 0;
}
Esempio n. 4
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	int	ret = 0;
	nand_erase_options_t nand_erase_options;

	nand_erase_options.length = CONFIG_ENV_RANGE;
	nand_erase_options.quiet = 0;
	nand_erase_options.jffs2 = 0;
	nand_erase_options.scrub = 0;

	if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
		return 1;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc   = crc32(0, env_new.data, ENV_SIZE);
	env_new.flags = ++env_flags; /* increase the serial */

	if(gd->env_valid == 1) {
		puts("Erasing redundant NAND...\n");
		nand_erase_options.offset = CONFIG_ENV_OFFSET_REDUND;
		if (nand_erase_opts(&nand_info[0], &nand_erase_options))
			return 1;

		puts("Writing to redundant NAND... ");
		ret = writeenv(CONFIG_ENV_OFFSET_REDUND,
			(u_char *)&env_new);
	} else {
		puts("Erasing NAND...\n");
		nand_erase_options.offset = CONFIG_ENV_OFFSET;
		if (nand_erase_opts(&nand_info[0], &nand_erase_options))
			return 1;

		puts("Writing to NAND... ");
		ret = writeenv(CONFIG_ENV_OFFSET,
			(u_char *)&env_new);
	}
	if (ret) {
		puts("FAILED!\n");
		return 1;
	}

	puts("done\n");

	gd->env_valid = (gd->env_valid == 2 ? 1 : 2);

	return ret;
}
Esempio n. 5
0
static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
		       int argc, char * const argv[])
{
	char *res = NULL;
	int len, grep_how, grep_what;

	if (argc < 2)
		return CMD_RET_USAGE;

	grep_how  = H_MATCH_SUBSTR;	/* default: substring search	*/
	grep_what = H_MATCH_BOTH;	/* default: grep names and values */

	while (argc > 1 && **(argv + 1) == '-') {
		char *arg = *++argv;

		--argc;
		while (*++arg) {
			switch (*arg) {
#ifdef CONFIG_REGEX
			case 'e':		/* use regex matching */
				grep_how  = H_MATCH_REGEX;
				break;
#endif
			case 'n':		/* grep for name */
				grep_what = H_MATCH_KEY;
				break;
			case 'v':		/* grep for value */
				grep_what = H_MATCH_DATA;
				break;
			case 'b':		/* grep for both */
				grep_what = H_MATCH_BOTH;
				break;
			case '-':
				goto DONE;
			default:
				return CMD_RET_USAGE;
			}
		}
	}

DONE:
	len = hexport_r(&env_htab, '\n',
			flag | grep_what | grep_how,
			&res, 0, argc, argv);

	if (len > 0) {
		puts(res);
		free(res);
	}

	if (len < 2)
		return 1;

	return 0;
}
Esempio n. 6
0
int saveenv(void)
{
	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
	ssize_t	len;
	char	*res;
	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
	u32	offset;
	int	ret, copy = 0;

	if (init_mmc_for_env(mmc))
		return 1;

	res = (char *)&env_new->data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		ret = 1;
		goto fini;
	}

	env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);

#ifdef CONFIG_ENV_OFFSET_REDUND
	env_new->flags	= ++env_flags; /* increase the serial */

	if (gd->env_valid == 1)
		copy = 1;
#endif

	if (mmc_get_env_addr(mmc, copy, &offset)) {
		ret = 1;
		goto fini;
	}

	printf("Writing to %sMMC(%d)... ", copy ? "redundant " : "",
	       CONFIG_SYS_MMC_ENV_DEV);
	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {
		puts("failed\n");
		ret = 1;
		goto fini;
	}

	puts("done\n");
	ret = 0;

#ifdef CONFIG_ENV_OFFSET_REDUND
	gd->env_valid = gd->env_valid == 2 ? 1 : 2;
#endif

fini:
	fini_mmc_for_env(mmc);
	return ret;
}
Esempio n. 7
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	block_dev_desc_t *dev_desc = NULL;
	int dev = FAT_ENV_DEVICE;
	int part = FAT_ENV_PART;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}

#ifdef CONFIG_MMC
	if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) {
		struct mmc *mmc = find_mmc_device(dev);

		if (!mmc) {
			printf("no mmc device at slot %x\n", dev);
			return 1;
		}

		mmc->has_init = 0;
		mmc_init(mmc);
	}
#endif /* CONFIG_MMC */

	dev_desc = get_dev(FAT_ENV_INTERFACE, dev);
	if (dev_desc == NULL) {
		printf("Failed to find %s%d\n",
			FAT_ENV_INTERFACE, dev);
		return 1;
	}
	if (fat_register_device(dev_desc, part) != 0) {
		printf("Failed to register %s%d:%d\n",
			FAT_ENV_INTERFACE, dev, part);
		return 1;
	}

	env_new.crc = crc32(0, env_new.data, ENV_SIZE);
	if (file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)) == -1) {
		printf("\n** Unable to write \"%s\" from %s%d:%d **\n",
			FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part);
		return 1;
	}

	puts("done\n");
	return 0;
}
Esempio n. 8
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	int	rc;
	unsigned int off	= CONFIG_ENV_OFFSET;
#ifdef CONFIG_ENV_OFFSET_REDUND
	unsigned int off_red	= CONFIG_ENV_OFFSET_REDUND;
	char flag_obsolete	= OBSOLETE_FLAG;
#endif

	BUG_ON(env_ptr != NULL);

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc = crc32(0, env_new.data, ENV_SIZE);

#ifdef CONFIG_ENV_OFFSET_REDUND
	if (gd->env_valid == 1) {
		off	= CONFIG_ENV_OFFSET_REDUND;
		off_red	= CONFIG_ENV_OFFSET;
	}

	env_new.flags = ACTIVE_FLAG;
#endif

	rc = eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR,
			      off, (uchar *)&env_new, CONFIG_ENV_SIZE);

#ifdef CONFIG_ENV_OFFSET_REDUND
	if (rc == 0) {
		eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR,
				 off_red + offsetof(env_t, flags),
				 (uchar *)&flag_obsolete, 1);

		if (gd->env_valid == 1)
			gd->env_valid = 2;
		else
			gd->env_valid = 1;
	}
#endif
	return rc;
}
Esempio n. 9
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	struct mtd_info *mtd = &onenand_mtd;
#ifdef CONFIG_ENV_ADDR_FLEX
	struct onenand_chip *this = &onenand_chip;
#endif
	loff_t	env_addr = CONFIG_ENV_ADDR;
	size_t	retlen;
	struct erase_info instr = {
		.callback	= NULL,
	};

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc = crc32(0, env_new.data, ENV_SIZE);

	instr.len = CONFIG_ENV_SIZE;
#ifdef CONFIG_ENV_ADDR_FLEX
	if (FLEXONENAND(this)) {
		env_addr = CONFIG_ENV_ADDR_FLEX;
		instr.len = CONFIG_ENV_SIZE_FLEX;
		instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ?
				1 : 0;
	}
#endif
	instr.addr = env_addr;
	instr.mtd = mtd;
	if (mtd->erase(mtd, &instr)) {
		printf("OneNAND: erase failed at 0x%08llx\n", env_addr);
		return 1;
	}

	if (mtd->write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen,
	     (u_char *)&env_new)) {
		printf("OneNAND: write failed at 0x%llx\n", instr.addr);
		return 2;
	}

	return 0;
}
Esempio n. 10
0
int saveenv(void)
{
    struct mmc *mmc;
    int dev_num;
    unsigned cnt = CONFIG_ENV_SIZE;
    u64 blk = CONFIG_ENV_OFFSET;
    dev_num = CONFIG_SYS_MMC_ENV_DEV;
    env_t *env_new_p = NULL;
    ssize_t	len;
    char	*res;
    mmc = find_mmc_device(dev_num);
    if (!mmc)
    {
        puts("No MMC device! Environment MMC not initialized!\n");
        return -1;
    }
    if ((cnt % 512) || (blk % 512)) {
        printf("addr notalign 0x%llx or byte notalign 0x%llx",blk,cnt);
        return -1;
    }
    env_new_p = (env_t *)malloc (CONFIG_ENV_SIZE);
    // get env data from hash table
    memset(env_new_p->data, 0, ENV_SIZE);
    res = (char *)&(env_new_p->data);
    len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
    if (len < 0) {
        error("Cannot export environment: errno = %d\n", errno);
        free(env_new_p);
        return 1;
    }
    env_new_p->crc   = crc32(0, env_new_p->data, ENV_SIZE);
    mmc_init(mmc);
    blk >>= 9;
    cnt >>= 9;
    if(cnt == mmc->block_dev.block_write(dev_num, blk, cnt, (const void *)env_new_p))
    {
        printf("mmc save env ok\n");
    }
    else
    {
        printf("mmc save env fail\n");
        free(env_new_p);
        return -1;
    }
    free(env_new_p);
    return 0;
}
Esempio n. 11
0
/*
 * Command interface: print one or all environment variables
 *
 * Returns 0 in case of error, or length of printed string
 */
static int env_print(char *name)
{
	char *res = NULL;
	size_t len;

	if (name) {		/* print a single name */
		ENTRY e, *ep;

		e.key = name;
		e.data = NULL;
		hsearch_r(e, FIND, &ep, &env_htab);
		if (ep == NULL)
			return 0;
        if(!strncmp(name,"otp.sec.",8)){
            uchar *buf=NULL;   
            len = strlen(ep->data);
            buf = malloc(len);
            if(buf){
                memset(buf,0x00, len);
                otp_sec_decode(ep->data, buf);
                len = printf("%s=%s\n",ep->key, buf);
                free(buf);
                return len;
            }else{
                printf("Malloc mem failed!\n");
                return 0;
            }
                
            
        }
		len = printf("%s=%s\n", ep->key, ep->data);
		return len;
	}

	/* print whole list */
	len = hexport_r(&env_htab, '\n', &res, 0, 0, NULL);

	if (len > 0) {
		puts(res);
		free(res);
		return len;
	}

	/* should never happen */
	return 0;
}
Esempio n. 12
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc = crc32(0, env_new.data, ENV_SIZE);

	return write_dataflash(CONFIG_ENV_ADDR,
				(unsigned long)&env_new,
				CONFIG_ENV_SIZE);
}
Esempio n. 13
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	block_dev_desc_t *dev_desc = NULL;
	int dev = EXT4_ENV_DEVICE;
	int part = EXT4_ENV_PART;
	int err;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}

	dev_desc = get_dev(EXT4_ENV_INTERFACE, dev);
	if (dev_desc == NULL) {
		printf("Failed to find %s%d\n",
			EXT4_ENV_INTERFACE, dev);
		return 1;
	}

	err = ext4_register_device(dev_desc, part);
	if (err) {
		printf("Failed to register %s%d:%d\n",
			EXT4_ENV_INTERFACE, dev, part);
		return 1;
	}

	env_new.crc = crc32(0, env_new.data, ENV_SIZE);
	err = ext4fs_write(EXT4_ENV_FILE, (void *)&env_new, sizeof(env_t));
	ext4fs_close();
	if (err == -1) {
		printf("\n** Unable to write \"%s\" from %s%d:%d **\n",
			EXT4_ENV_FILE, EXT4_ENV_INTERFACE, dev, part);
		return 1;
	}

	puts("done\n");
	return 0;
}
Esempio n. 14
0
/* Export the environment and generate CRC for it. */
int env_export(env_t *env_out)
{
	char *res;
	ssize_t	len;

	res = (char *)env_out->data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		pr_err("Cannot export environment: errno = %d\n", errno);
		return 1;
	}

	env_out->crc = crc32(0, env_out->data, ENV_SIZE);

#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
	env_out->flags = ++env_flags; /* increase the serial */
#endif

	return 0;
}
Esempio n. 15
0
int saveenv(void)
{
	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
	int mmc_env_devno = mmc_get_env_devno();
	ssize_t	len;
	char	*res;
	struct mmc *mmc = find_mmc_device(mmc_env_devno);
	u32	offset;
	int	ret;

	if (init_mmc_for_env(mmc))
		return 1;

	if (mmc_get_env_addr(mmc, &offset)) {
		ret = 1;
		goto fini;
	}

	res = (char *)&env_new->data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		ret = 1;
		goto fini;
	}

	env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);
	printf("Writing to MMC(%d)... ", mmc_env_devno);
	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {
		puts("failed\n");
		ret = 1;
		goto fini;
	}

	puts("done\n");
	ret = 0;

fini:
	fini_mmc_for_env(mmc);
	return ret;
}
Esempio n. 16
0
/* Emport the environment and generate CRC for it. */
int env_export(env_t *env_out)
{
    char *res;
    ssize_t	len;
    int ret;

    res = (char *)env_out->data;
    len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
    if (len < 0) {
        error("Cannot export environment: errno = %d\n", errno);
        return 1;
    }

    /* Encrypt the env if desired. */
    ret = env_aes_cbc_crypt(env_out, 1);
    if (ret)
        return ret;

    env_out->crc = crc32(0, env_out->data, ENV_SIZE);

    return 0;
}
Esempio n. 17
0
/**
 * show_efi_boot_dump() - dump all UEFI load options
 *
 * @cmdtp:	Command table
 * @flag:	Command flag
 * @argc:	Number of arguments
 * @argv:	Argument array
 * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
 *
 * Implement efidebug "boot dump" sub-command.
 * Dump information of all UEFI load options defined.
 *   - boot dump
 */
static int do_efi_boot_dump(cmd_tbl_t *cmdtp, int flag,
			    int argc, char * const argv[])
{
	char regex[256];
	char * const regexlist[] = {regex};
	char *variables = NULL, *boot, *value;
	int len;
	int id;

	if (argc > 1)
		return CMD_RET_USAGE;

	snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_Boot[0-9A-F]+");

	/* TODO: use GetNextVariableName? */
	len = hexport_r(&env_htab, '\n', H_MATCH_REGEX | H_MATCH_KEY,
			&variables, 0, 1, regexlist);

	if (!len)
		return CMD_RET_SUCCESS;

	if (len < 0)
		return CMD_RET_FAILURE;

	boot = variables;
	while (*boot) {
		value = strstr(boot, "Boot") + 4;
		id = (int)simple_strtoul(value, NULL, 16);
		show_efi_boot_opt(id);
		boot = strchr(boot, '\n');
		if (!*boot)
			break;
		boot++;
	}
	free(variables);

	return CMD_RET_SUCCESS;
}
Esempio n. 18
0
int saveenv(void)
{
	block_dev_desc_t *sata = NULL;
	env_t	env_new;
	ssize_t	len;
	char *res;

	if (sata_curr_device == -1) {
		if (sata_initialize())
			return 1;
		sata_curr_device = CONFIG_SATA_ENV_DEV;
	}

	if (sata_curr_device >= CONFIG_SYS_SATA_MAX_DEVICE) {
		printf("Unknown SATA(%d) device for environment!\n",
			sata_curr_device);
		return 1;
	}

	sata = sata_get_dev(sata_curr_device);

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc = crc32(0, env_new.data, ENV_SIZE);

	printf("Writing to SATA(%d)...", sata_curr_device);
	if (write_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, &env_new)) {
		puts("failed\n");
		return 1;
	}

	puts("done\n");
	return 0;
}
Esempio n. 19
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.
 */
int writeenv(size_t offset, u_char *buf)
{
	size_t end = offset + CONFIG_ENV_RANGE;
	size_t amount_saved = 0;
	size_t blocksize, len;

	u_char *char_ptr;

	blocksize = nand_info[0].erasesize;
	len = min(blocksize, CONFIG_ENV_SIZE);

	while (amount_saved < CONFIG_ENV_SIZE && offset < end) {
		if (nand_block_isbad(&nand_info[0], offset)) {
			offset += blocksize;
		} else {
			char_ptr = &buf[amount_saved];
			if (nand_write(&nand_info[0], offset, &len,
					char_ptr))
				return 1;
			offset += blocksize;
			amount_saved += len;
		}
	}
	if (amount_saved != CONFIG_ENV_SIZE)
		return 1;

	return 0;
}

#ifdef CONFIG_ENV_OFFSET_REDUND
static unsigned char env_flags;

int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	int	ret = 0;
	nand_erase_options_t nand_erase_options;

	nand_erase_options.length = CONFIG_ENV_RANGE;
	nand_erase_options.quiet = 0;
	nand_erase_options.jffs2 = 0;
	nand_erase_options.scrub = 0;

	if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
		return 1;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc   = crc32(0, env_new.data, ENV_SIZE);
	env_new.flags = ++env_flags; /* increase the serial */

	if(gd->env_valid == 1) {
		puts("Erasing redundant NAND...\n");
		nand_erase_options.offset = CONFIG_ENV_OFFSET_REDUND;
		if (nand_erase_opts(&nand_info[0], &nand_erase_options))
			return 1;

		puts("Writing to redundant NAND... ");
		ret = writeenv(CONFIG_ENV_OFFSET_REDUND,
			(u_char *)&env_new);
	} else {
		puts("Erasing NAND...\n");
		nand_erase_options.offset = CONFIG_ENV_OFFSET;
		if (nand_erase_opts(&nand_info[0], &nand_erase_options))
			return 1;

		puts("Writing to NAND... ");
		ret = writeenv(CONFIG_ENV_OFFSET,
			(u_char *)&env_new);
	}
	if (ret) {
		puts("FAILED!\n");
		return 1;
	}

	puts("done\n");

	gd->env_valid = (gd->env_valid == 2 ? 1 : 2);

	return ret;
}
#else /* ! CONFIG_ENV_OFFSET_REDUND */
int saveenv(void)
{
	int ret = 0;
	env_t	env_new;
	ssize_t	len;
	char	*res;
	nand_erase_options_t nand_erase_options;

	nand_erase_options.length = CONFIG_ENV_RANGE;
	nand_erase_options.quiet = 0;
	nand_erase_options.jffs2 = 0;
	nand_erase_options.scrub = 0;
	nand_erase_options.offset = CONFIG_ENV_OFFSET;

	if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
		return 1;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc   = crc32(0, env_new.data, ENV_SIZE);

	puts("Erasing Nand...\n");
	if (nand_erase_opts(&nand_info[0], &nand_erase_options))
		return 1;

	puts("Writing to Nand... ");
	if (writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new)) {
		puts("FAILED!\n");
		return 1;
	}

	puts("done\n");
	return ret;
}
Esempio n. 20
0
static int flash_saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	u32     start;

	start = sunxi_partition_get_offset_byname(CONFIG_SUNXI_ENV_PARTITION);
	if(!start){
		printf("fail to find part named %s\n", CONFIG_SUNXI_ENV_PARTITION);
		return -1;
	}

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc   = crc32(0, env_new.data, ENV_SIZE);

	return sunxi_flash_write(start, env_size/512, &env_new);
}
Esempio n. 21
0
int saveenv(void)
{
	env_t *env_new = (env_t *)env_buf;
	ssize_t	len;
	char	*res;

	res = (char *)env_new->data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return -1;
	}

	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
	printf("Writing env to storage... \n");
	if (write_env(CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, (u_char *)env_new)) {
		puts("failed\n");
		return -1;
	}

	puts("done\n");
	return 0;
}
Esempio n. 22
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	int	rcode = 0;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc = crc32(0, env_new.data, ENV_SIZE);

#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
	nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE);
#else
	if (memcpy((char *)CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE) == NULL)
		rcode = 1;
#endif
	return rcode;
}
Esempio n. 23
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.
 */
int writeenv(size_t offset, u_char *buf)
{
	uint64_t end = offset + CONFIG_ENV_RANGE;
	uint64_t amount_saved = 0;
	uint64_t blocksize, len;

	u_char *char_ptr;

	blocksize = nand_info[0].erasesize;
	len = min(blocksize, CONFIG_ENV_SIZE);

	offset = CONFIG_ENV_OFFSET;
	
	while (amount_saved < CONFIG_ENV_SIZE && offset < end) {
		if (nand_block_isbad(&nand_info[0], offset)) {
			offset += blocksize;
		} else {
			char_ptr = &buf[amount_saved];
			if (nand_write(&nand_info[0], offset, (size_t *)&len, char_ptr))
				return 1;

			offset += blocksize;
			amount_saved += len;
		}
	}
	if (amount_saved != CONFIG_ENV_SIZE)
		return 1;

	return 0;
}

#ifdef CONFIG_ENV_OFFSET_REDUND
static unsigned char env_flags;

int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res;
	int	ret = 0;
	nand_erase_options_t nand_erase_options;

	memset(&nand_erase_options, 0, sizeof(nand_erase_options));
	nand_erase_options.length = CONFIG_ENV_RANGE;
	nand_erase_options.quiet = 1;


	if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
		return 1;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc	= crc32(0, env_new.data, ENV_SIZE);
	env_new.flags	= ++env_flags; /* increase the serial */

	if (gd->env_valid == 1) {
		puts("Erasing redundant NAND...\n");
		nand_erase_options.offset = CONFIG_ENV_OFFSET_REDUND;
		if (nand_erase_opts(&nand_info[0], &nand_erase_options))
			return 1;

		puts("Writing to redundant NAND... ");
		ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)&env_new);
	} else {
		puts("Erasing NAND...\n");
		nand_erase_options.offset = CONFIG_ENV_OFFSET;
		if (nand_erase_opts(&nand_info[0], &nand_erase_options))
			return 1;

		puts("Writing to NAND... ");
		ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new);
	}
	if (ret) {
		puts("FAILED!\n");
		return 1;
	}

	puts("done\n");

	gd->env_valid = gd->env_valid == 2 ? 1 : 2;

	return ret;
}
#else /* ! CONFIG_ENV_OFFSET_REDUND */
int saveenv(void)
{
	int	ret = 0;
	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
	ssize_t	len;
	char	*res;
	nand_erase_options_t nand_erase_options;

	memset(&nand_erase_options, 0, sizeof(nand_erase_options));
	nand_erase_options.length = CONFIG_ENV_RANGE;
	nand_erase_options.quiet = 1;
	nand_erase_options.offset = CONFIG_ENV_OFFSET;

	if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
		return 1;

	res = (char *)&env_new->data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new->crc = crc32(0, env_new->data, ENV_SIZE);

	puts("Erasing Nand...\n");
	if (nand_erase_opts(&nand_info[0], &nand_erase_options))
		return 1;

	puts("Writing to Nand... ");
	if (writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new)) {
		puts("FAILED!\n");
		return 1;
	}

	puts("done\n");
	return ret;
}
Esempio n. 24
0
int saveenv(void)
{
#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
	env_t	*env_new = (env_t *)env_buf;
#else
	env_t	*env_new = (env_t *)CONFIG_ENV_ADDR;
#endif
	ssize_t	len;
	char	*res;
	int	rcode = 0;

	res = (char *)env_new->data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new->crc = crc32(0, env_new->data, ENV_SIZE);

#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
	nvram_write(CONFIG_ENV_ADDR, env_new, CONFIG_ENV_SIZE);
#endif
	return rcode;
}
Esempio n. 25
0
int do_painit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	u32 pram, nextbase, base;
	char *v;
	u32 param;
	ulong *lptr;

	env_t *envp;
	char *res;
	int len;

	v = getenv("pram");
	if (v)
		pram = simple_strtoul(v, NULL, 10);
	else {
		printf("Error: pram undefined. Please define pram in KiB\n");
		return 1;
	}

	base = gd->bd->bi_memsize;
#if defined(CONFIG_LOGBUFFER)
	base -= LOGBUFF_LEN + LOGBUFF_OVERHEAD;
#endif
	/*
	 * gd->bd->bi_memsize == physical ram size - CONFIG_SYS_MEM_TOP_HIDE
	 */
	param = base - (pram << 10);
	printf("PARAM: @%08x\n", param);
	debug("memsize=0x%08x, base=0x%08x\n", (u32)gd->bd->bi_memsize, base);

	/* clear entire PA ram */
	memset((void*)param, 0, (pram << 10));

	/* reserve 4k for pointer field */
	nextbase = base - 4096;
	lptr = (ulong*)(base);

	/*
	 * *(--lptr) = item_size;
	 * *(--lptr) = base - item_base = distance from field top;
	 */

	/* env is first (4k aligned) */
	nextbase -= ((CONFIG_ENV_SIZE + 4096 - 1) & ~(4096 - 1));
	envp = (env_t *)nextbase;
	res = (char *)envp->data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	envp->crc = crc32(0, envp->data, ENV_SIZE);

	*(--lptr) = CONFIG_ENV_SIZE;     /* size */
	*(--lptr) = base - nextbase;  /* offset | type=0 */

	/* free section */
	*(--lptr) = nextbase - param; /* size */
	*(--lptr) = (base - param) | 126; /* offset | type=126 */

	/* terminate pointer field */
	*(--lptr) = crc32(0, (void*)(base - 0x10), 0x10);
	*(--lptr) = 0;                /* offset=0 -> terminator */
	return 0;
}
Esempio n. 26
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*res, *saved_buffer = NULL, flag = OBSOLETE_FLAG;
	u32	saved_size, saved_offset, sector = 1;
	int	ret;

	if (!env_flash) {
		env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
			CONFIG_ENV_SPI_CS,
			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
		if (!env_flash) {
			set_default_env("!spi_flash_probe() failed");
			return 1;
		}
	}

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		return 1;
	}
	env_new.crc	= crc32(0, env_new.data, ENV_SIZE);
	env_new.flags	= ACTIVE_FLAG;

	if (gd->env_valid == 1) {
		env_new_offset = CONFIG_ENV_OFFSET_REDUND;
		env_offset = CONFIG_ENV_OFFSET;
	} else {
		env_new_offset = CONFIG_ENV_OFFSET;
		env_offset = CONFIG_ENV_OFFSET_REDUND;
	}

	/* Is the sector larger than the env (i.e. embedded) */
	if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
		saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
		saved_offset = env_new_offset + CONFIG_ENV_SIZE;
		saved_buffer = malloc(saved_size);
		if (!saved_buffer) {
			ret = 1;
			goto done;
		}
		ret = spi_flash_read(env_flash, saved_offset,
					saved_size, saved_buffer);
		if (ret)
			goto done;
	}

	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++;
	}

	puts("Erasing SPI flash...");
	ret = spi_flash_erase(env_flash, env_new_offset,
				sector * CONFIG_ENV_SECT_SIZE);
	if (ret)
		goto done;

	puts("Writing to SPI flash...");

	ret = spi_flash_write(env_flash, env_new_offset,
		CONFIG_ENV_SIZE, &env_new);
	if (ret)
		goto done;

	if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
		ret = spi_flash_write(env_flash, saved_offset,
					saved_size, saved_buffer);
		if (ret)
			goto done;
	}

	ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags),
				sizeof(env_new.flags), &flag);
	if (ret)
		goto done;

	puts("done\n");

	gd->env_valid = gd->env_valid == 2 ? 1 : 2;

	printf("Valid environment: %d\n", (int)gd->env_valid);

 done:
	if (saved_buffer)
		free(saved_buffer);

	return ret;
}
Esempio n. 27
0
int saveenv(void)
{
	u32	saved_size, saved_offset, sector = 1;
	char	*res, *saved_buffer = NULL;
	int	ret = 1;
	env_t	env_new;
	ssize_t	len;

	if (!env_flash) {
		env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
			CONFIG_ENV_SPI_CS,
			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
		if (!env_flash) {
			set_default_env("!spi_flash_probe() failed");
			return 1;
		}
	}

	/* Is the sector larger than the env (i.e. embedded) */
	if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
		saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
		saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE;
		saved_buffer = malloc(saved_size);
		if (!saved_buffer)
			goto done;

		ret = spi_flash_read(env_flash, saved_offset,
			saved_size, saved_buffer);
		if (ret)
			goto done;
	}

	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++;
	}

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		goto done;
	}
	env_new.crc = crc32(0, env_new.data, ENV_SIZE);

	puts("Erasing SPI flash...");
	ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET,
		sector * CONFIG_ENV_SECT_SIZE);
	if (ret)
		goto done;

	puts("Writing to SPI flash...");
	ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET,
		CONFIG_ENV_SIZE, &env_new);
	if (ret)
		goto done;

	if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
		ret = spi_flash_write(env_flash, saved_offset,
			saved_size, saved_buffer);
		if (ret)
			goto done;
	}

	ret = 0;
	puts("done\n");

 done:
	if (saved_buffer)
		free(saved_buffer);

	return ret;
}
Esempio n. 28
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	int	rc = 1;
	char	*res;
	char	*saved_data = NULL;
#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
	ulong	up_data = 0;

	up_data = (end_addr + 1 - ((long)flash_addr + CONFIG_ENV_SIZE));
	debug("Data to save 0x%lx\n", up_data);
	if (up_data) {
		if ((saved_data = malloc(up_data)) == NULL) {
			printf("Unable to save the rest of sector (%ld)\n",
				up_data);
			goto done;
		}
		memcpy(saved_data,
			(void *)((long)flash_addr + CONFIG_ENV_SIZE), up_data);
		debug("Data (start 0x%lx, len 0x%lx) saved at 0x%lx\n",
			(ulong)flash_addr + CONFIG_ENV_SIZE,
			up_data,
			(ulong)saved_data);
	}
#endif	/* CONFIG_ENV_SECT_SIZE */

	debug("Protect off %08lX ... %08lX\n",
		(ulong)flash_addr, end_addr);

	if (flash_sect_protect(0, (long)flash_addr, end_addr))
		goto done;

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		goto done;
	}
	env_new.crc = crc32(0, env_new.data, ENV_SIZE);

	puts("Erasing Flash...");
	if (flash_sect_erase((long)flash_addr, end_addr))
		goto done;

	puts("Writing to Flash... ");
	rc = flash_write((char *)&env_new, (long)flash_addr, CONFIG_ENV_SIZE);
	if (rc != 0) {
		flash_perror(rc);
		goto done;
	}
#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
	if (up_data) {	/* restore the rest of sector */
		debug("Restoring the rest of data to 0x%lx len 0x%lx\n",
			(ulong)flash_addr + CONFIG_ENV_SIZE, up_data);
		if (flash_write(saved_data,
				(long)flash_addr + CONFIG_ENV_SIZE,
				up_data)) {
			flash_perror(rc);
			goto done;
		}
	}
#endif
	puts("done\n");
	rc = 0;
done:
	if (saved_data)
		free(saved_data);
	/* try to re-protect */
	(void) flash_sect_protect(1, (long)flash_addr, end_addr);
	return rc;
}
Esempio n. 29
0
/*
 * env export [-t | -b | -c] addr [size]
 *	-t:	export as text format; if size is given, data will be
 *		padded with '\0' bytes; if not, one terminating '\0'
 *		will be added (which is included in the "filesize"
 *		setting so you can for exmple copy this to flash and
 *		keep the termination).
 *	-b:	export as binary format (name=value pairs separated by
 *		'\0', list end marked by double "\0\0")
 *	-c:	export as checksum protected environment format as
 *		used for example by "saveenv" command
 *	addr:	memory address where environment gets stored
 *	size:	size of output buffer
 *
 * With "-c" and size is NOT given, then the export command will
 * format the data as currently used for the persistent storage,
 * i. e. it will use CONFIG_ENV_SECT_SIZE as output block size and
 * prepend a valid CRC32 checksum and, in case of resundant
 * environment, a "current" redundancy flag. If size is given, this
 * value will be used instead of CONFIG_ENV_SECT_SIZE; again, CRC32
 * checksum and redundancy flag will be inserted.
 *
 * With "-b" and "-t", always only the real data (including a
 * terminating '\0' byte) will be written; here the optional size
 * argument will be used to make sure not to overflow the user
 * provided buffer; the command will abort if the size is not
 * sufficient. Any remainign space will be '\0' padded.
 *
 * On successful return, the variable "filesize" will be set.
 * Note that filesize includes the trailing/terminating '\0' byte(s).
 *
 * Usage szenario:  create a text snapshot/backup of the current settings:
 *
 *	=> env export -t 100000
 *	=> era ${backup_addr} +${filesize}
 *	=> cp.b 100000 ${backup_addr} ${filesize}
 *
 * Re-import this snapshot, deleting all other settings:
 *
 *	=> env import -d -t ${backup_addr}
 */
static int do_env_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char	buf[32];
	char	*addr, *cmd, *res;
	size_t	size;
	ssize_t	len;
	env_t	*envp;
	char	sep = '\n';
	int	chk = 0;
	int	fmt = 0;

	cmd = *argv;

	while (--argc > 0 && **++argv == '-') {
		char *arg = *argv;
		while (*++arg) {
			switch (*arg) {
			case 'b':		/* raw binary format */
				if (fmt++)
					goto sep_err;
				sep = '\0';
				break;
			case 'c':		/* external checksum format */
				if (fmt++)
					goto sep_err;
				sep = '\0';
				chk = 1;
				break;
			case 't':		/* text format */
				if (fmt++)
					goto sep_err;
				sep = '\n';
				break;
			default:
				return cmd_usage(cmdtp);
			}
		}
	}

	if (argc < 1)
		return cmd_usage(cmdtp);

	addr = (char *)simple_strtoul(argv[0], NULL, 16);

	if (argc == 2) {
		size = simple_strtoul(argv[1], NULL, 16);
		memset(addr, '\0', size);
	} else {
		size = 0;
	}

	if (sep) {		/* export as text file */
		len = hexport_r(&env_htab, sep, &addr, size);
		if (len < 0) {
			error("Cannot export environment: errno = %d\n",
				errno);
			return 1;
		}
		sprintf(buf, "%zX", (size_t)len);
		setenv("filesize", buf);

		return 0;
	}

	envp = (env_t *)addr;

	if (chk)		/* export as checksum protected block */
		res = (char *)envp->data;
	else			/* export as raw binary data */
		res = addr;

	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n",
			errno);
		return 1;
	}

	if (chk) {
		envp->crc   = crc32(0, envp->data, ENV_SIZE);
#ifdef CONFIG_ENV_ADDR_REDUND
		envp->flags = ACTIVE_FLAG;
#endif
	}
	sprintf(buf, "%zX", (size_t)(len + offsetof(env_t, data)));
	setenv("filesize", buf);

	return 0;

sep_err:
	printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n",
		cmd);
	return 1;
}
Esempio n. 30
0
int saveenv(void)
{
	env_t	env_new;
	ssize_t	len;
	char	*saved_data = NULL;
	char	*res;
	int	rc = 1;
	char	flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG;
#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
	ulong	up_data = 0;
#endif

	debug("Protect off %08lX ... %08lX\n",
		(ulong)flash_addr, end_addr);

	if (flash_sect_protect(0, (ulong)flash_addr, end_addr)) {
		goto done;
	}

	debug("Protect off %08lX ... %08lX\n",
		(ulong)flash_addr_new, end_addr_new);

	if (flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new)) {
		goto done;
	}

	res = (char *)&env_new.data;
	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE);
	if (len < 0) {
		error("Cannot export environment: errno = %d\n", errno);
		goto done;
	}
	env_new.crc   = crc32(0, env_new.data, ENV_SIZE);
	env_new.flags = new_flag;

#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
	up_data = (end_addr_new + 1 - ((long)flash_addr_new + CONFIG_ENV_SIZE));
	debug("Data to save 0x%lX\n", up_data);
	if (up_data) {
		if ((saved_data = malloc(up_data)) == NULL) {
			printf("Unable to save the rest of sector (%ld)\n",
				up_data);
			goto done;
		}
		memcpy(saved_data,
			(void *)((long)flash_addr_new + CONFIG_ENV_SIZE), up_data);
		debug("Data (start 0x%lX, len 0x%lX) saved at 0x%p\n",
			(long)flash_addr_new + CONFIG_ENV_SIZE,
			up_data, saved_data);
	}
#endif
	puts("Erasing Flash...");
	debug(" %08lX ... %08lX ...",
		(ulong)flash_addr_new, end_addr_new);

	if (flash_sect_erase((ulong)flash_addr_new, end_addr_new)) {
		goto done;
	}

	puts("Writing to Flash... ");
	debug(" %08lX ... %08lX ...",
		(ulong)&(flash_addr_new->data),
		sizeof(env_ptr->data)+(ulong)&(flash_addr_new->data));
	if ((rc = flash_write((char *)&env_new,
			(ulong)flash_addr_new,
			sizeof(env_new))) ||
	    (rc = flash_write(&flag,
			(ulong)&(flash_addr->flags),
			sizeof(flash_addr->flags))) ) {
		flash_perror(rc);
		goto done;
	}

#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
	if (up_data) { /* restore the rest of sector */
		debug("Restoring the rest of data to 0x%lX len 0x%lX\n",
			(long)flash_addr_new + CONFIG_ENV_SIZE, up_data);
		if (flash_write(saved_data,
				(long)flash_addr_new + CONFIG_ENV_SIZE,
				up_data)) {
			flash_perror(rc);
			goto done;
		}
	}
#endif
	puts("done\n");

	{
		env_t * etmp = flash_addr;
		ulong ltmp = end_addr;

		flash_addr = flash_addr_new;
		flash_addr_new = etmp;

		end_addr = end_addr_new;
		end_addr_new = ltmp;
	}

	rc = 0;
done:
	if (saved_data)
		free(saved_data);
	/* try to re-protect */
	(void) flash_sect_protect(1, (ulong)flash_addr, end_addr);
	(void) flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new);

	return rc;
}