Example #1
0
File: env.c Project: qgp/armboot
/*
 * save environment buffer back to flash
 * returns -1 on error, 0 if ok
 */
int board_env_save(bd_t *bd, env_t *env, int size)
{
    int rc;
    ulong start_addr, end_addr;

#if CFG_ENV_SIZE <= CFG_ENV_SECT_SIZE
#error Make sure that CFG_ENV_SIZE <= CFG_ENV_SECT_SIZE
#endif    

    start_addr = CFG_ENV_ADDR;
    end_addr   = start_addr + CFG_ENV_SIZE - 1;

    rc = flash_sect_protect(0, CFG_ENV_ADDR, end_addr);
    if (rc < 0)
      return rc;

    rc = flash_sect_erase(start_addr, end_addr);
    if (rc < 0)
    {
	flash_sect_protect(1, start_addr, end_addr);
	flash_perror(rc);
	return rc;
    }
    
    printf("Saving Environment to Flash...");
    rc = flash_write((uchar*)env, start_addr, size);
    if (rc < 0)
      flash_perror(rc);
    else 
      printf("done.\n");

    (void)flash_sect_protect(1, start_addr, end_addr);

    return 0;
}
Example #2
0
void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED) || defined(CFG_ENV_ADDR_REDUND)
#ifdef CFG_ENV_ADDR_REDUND
	DECLARE_GLOBAL_DATA_PTR;

	if (gd->env_addr != (ulong)&(flash_addr->data)) {
		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;
	}

	if (flash_addr_new->flags != OBSOLETE_FLAG &&
	    crc32(0, flash_addr_new->data, ENV_SIZE) ==
	    flash_addr_new->crc) {
		char flag = OBSOLETE_FLAG;

		gd->env_valid = 2;
		flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new);
		flash_write(&flag,
			    (ulong)&(flash_addr_new->flags),
			    sizeof(flash_addr_new->flags));
		flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new);
	}

	if (flash_addr->flags != ACTIVE_FLAG &&
	    (flash_addr->flags & ACTIVE_FLAG) == ACTIVE_FLAG) {
		char flag = ACTIVE_FLAG;

		gd->env_valid = 2;
		flash_sect_protect (0, (ulong)flash_addr, end_addr);
		flash_write(&flag,
			    (ulong)&(flash_addr->flags),
			    sizeof(flash_addr->flags));
		flash_sect_protect (1, (ulong)flash_addr, end_addr);
	}

	if (gd->env_valid == 2)
		puts ("*** Warning - some problems detected "
		      "reading environment; recovered successfully\n\n");
#endif /* CFG_ENV_ADDR_REDUND */
#if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH))
	memcpy (env_ptr, (void*)flash_addr, CFG_ENV_SIZE);
#endif
#endif /* ! ENV_IS_EMBEDDED || CFG_ENV_ADDR_REDUND */
}
Example #3
0
int do_install ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int rc;
	size_t sect_top;

	if (argc != 1) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	for(sect_top=0; sect_top<sizeof(u_boot_bin_data); sect_top+=PHYS_FLASH_SECT_SIZE) continue;
	sect_top--;
	flash_sect_protect(0, CFG_FLASH_BASE, sect_top);
	flash_sect_erase(CFG_FLASH_BASE, sect_top);

	puts ("Copying to Flash... ");

	rc = flash_write ((uchar *)u_boot_bin_data, CFG_FLASH_BASE, sizeof(u_boot_bin_data));
	if (rc != 0) {
		flash_perror (rc);
		return (1);
	}
	puts ("done\n");
	return 0;
}
Example #4
0
void env_relocate_spec(void)
{
#ifdef CONFIG_ENV_ADDR_REDUND
	if (gd->env_addr != (ulong)&(flash_addr->data)) {
		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;
	}

	if (flash_addr_new->flags != OBSOLETE_FLAG &&
	    crc32(0, flash_addr_new->data, ENV_SIZE) ==
	    flash_addr_new->crc) {
		char flag = OBSOLETE_FLAG;

		gd->env_valid = 2;
		flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new);
		flash_write(&flag,
			    (ulong)&(flash_addr_new->flags),
			    sizeof(flash_addr_new->flags));
		flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new);
	}

	if (flash_addr->flags != ACTIVE_FLAG &&
	    (flash_addr->flags & ACTIVE_FLAG) == ACTIVE_FLAG) {
		char flag = ACTIVE_FLAG;

		gd->env_valid = 2;
		flash_sect_protect(0, (ulong)flash_addr, end_addr);
		flash_write(&flag,
			    (ulong)&(flash_addr->flags),
			    sizeof(flash_addr->flags));
		flash_sect_protect(1, (ulong)flash_addr, end_addr);
	}

	if (gd->env_valid == 2)
		puts ("*** Warning - some problems detected "
		      "reading environment; recovered successfully\n\n");
#endif /* CONFIG_ENV_ADDR_REDUND */

	env_import((char *)flash_addr, 1);
}
Example #5
0
int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#ifndef CONFIG_SYS_NO_FLASH
	flash_info_t *info;
	ulong bank;
	int i, n, sect_first, sect_last;
#endif /* CONFIG_SYS_NO_FLASH */
#if !defined(CONFIG_SYS_NO_FLASH) || defined(CONFIG_HAS_DATAFLASH)
	ulong addr_first, addr_last;
#endif
#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS)
	struct mtd_device *dev;
	struct part_info *part;
	u8 dev_type, dev_num, pnum;
#endif
#ifdef CONFIG_HAS_DATAFLASH
	int status;
#endif
	int p;
	int rcode = 0;

	if (argc < 3) {
		cmd_usage(cmdtp);
		return 1;
	}

	if (strcmp(argv[1], "off") == 0) {
		p = 0;
	} else if (strcmp(argv[1], "on") == 0) {
		p = 1;
	} else {
		cmd_usage(cmdtp);
		return 1;
	}

#ifdef CONFIG_HAS_DATAFLASH
	if ((strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0)) {
		addr_first = simple_strtoul(argv[2], NULL, 16);
		addr_last  = simple_strtoul(argv[3], NULL, 16);

		if (addr_dataflash(addr_first) && addr_dataflash(addr_last)) {
			status = dataflash_real_protect(p,addr_first,addr_last);
			if (status < 0){
				puts ("Bad DataFlash sector specification\n");
				return 1;
			}
			printf("%sProtect %d DataFlash Sectors\n",
				p ? "" : "Un-", status);
			return 0;
		}
	}
#endif

#ifndef CONFIG_SYS_NO_FLASH
	if (strcmp(argv[2], "all") == 0) {
		for (bank=1; bank<=CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
			info = &flash_info[bank-1];
			if (info->flash_id == FLASH_UNKNOWN) {
				continue;
			}
			printf ("%sProtect Flash Bank # %ld\n",
				p ? "" : "Un-", bank);

			for (i=0; i<info->sector_count; ++i) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
				if (flash_real_protect(info, i, p))
					rcode = 1;
				putc ('.');
#else
				info->protect[i] = p;
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
			}
#if defined(CONFIG_SYS_FLASH_PROTECTION)
			if (!rcode) puts (" done\n");
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
		}
		return rcode;
	}

	if ((n = abbrev_spec(argv[2], &info, &sect_first, &sect_last)) != 0) {
		if (n < 0) {
			puts ("Bad sector specification\n");
			return 1;
		}
		printf("%sProtect Flash Sectors %d-%d in Bank # %zu\n",
			p ? "" : "Un-", sect_first, sect_last,
			(info-flash_info)+1);
		for (i = sect_first; i <= sect_last; i++) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
			if (flash_real_protect(info, i, p))
				rcode =  1;
			putc ('.');
#else
			info->protect[i] = p;
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
		}

#if defined(CONFIG_SYS_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CONFIG_SYS_FLASH_PROTECTION */

		return rcode;
	}

#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS)
	/* protect on/off <part-id> */
	if ((argc == 3) && (mtd_id_parse(argv[2], NULL, &dev_type, &dev_num) == 0)) {
		mtdparts_init();
		if (find_dev_and_part(argv[2], &dev, &pnum, &part) == 0) {
			if (dev->id->type == MTD_DEV_TYPE_NOR) {
				bank = dev->id->num;
				info = &flash_info[bank];
				addr_first = part->offset + info->start[0];
				addr_last = addr_first + part->size - 1;

				printf ("%sProtect Flash Partition %s, "
						"bank %ld, 0x%08lx - 0x%08lx\n",
						p ? "" : "Un", argv[1],
						bank, addr_first, addr_last);

				rcode = flash_sect_protect (p, addr_first, addr_last);
				return rcode;
			}

			printf("cannot %sprotect, not a NOR device\n",
					p ? "" : "un");
			return 1;
		}
	}
#endif

	if (argc != 4) {
		cmd_usage(cmdtp);
		return 1;
	}

	if (strcmp(argv[2], "bank") == 0) {
		bank = simple_strtoul(argv[3], NULL, 16);
		if ((bank < 1) || (bank > CONFIG_SYS_MAX_FLASH_BANKS)) {
			printf ("Only FLASH Banks # 1 ... # %d supported\n",
				CONFIG_SYS_MAX_FLASH_BANKS);
			return 1;
		}
		printf ("%sProtect Flash Bank # %ld\n",
			p ? "" : "Un-", bank);
		info = &flash_info[bank-1];

		if (info->flash_id == FLASH_UNKNOWN) {
			puts ("missing or unknown FLASH type\n");
			return 1;
		}
		for (i=0; i<info->sector_count; ++i) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
			if (flash_real_protect(info, i, p))
				rcode =  1;
			putc ('.');
#else
			info->protect[i] = p;
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
		}

#if defined(CONFIG_SYS_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CONFIG_SYS_FLASH_PROTECTION */

		return rcode;
	}

	if (addr_spec(argv[2], argv[3], &addr_first, &addr_last) < 0){
		printf("Bad address format\n");
		return 1;
	}

	if (addr_first >= addr_last) {
		cmd_usage(cmdtp);
		return 1;
	}
	rcode = flash_sect_protect (p, addr_first, addr_last);
#endif /* CONFIG_SYS_NO_FLASH */
	return rcode;
}
Example #6
0
void do_saveenv  (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
	int rc;
	extern void flash_sect_protect (int p, ulong addr_first, ulong addr_last);
	extern void flash_sect_erase (ulong addr_first, ulong addr_last);
#if defined(CFG_FLASH_ENV_BUF)
	uchar *sector_buffer;
#endif	/* CFG_FLASH_ENV_BUF */

#if defined(CFG_FLASH_ENV_ADDR)
	 uchar *environment = env_init();
#endif	/* CFG_FLASH_ENV_BUF */

#ifdef CONFIG_4xx
	uchar *ed_buf;

	/*
	 * On ppc4xx still saved somewhere within a flash sector (no sector
	 * reserved for the environment variables). This will be changed in a
	 * future release.
	 */
        ulong sector_flash_addr;
        ulong sector_flash_size;
        ulong sector_flash_offs;
        int i;
        flash_info_t *info;

# ifndef CFG_FLASH_ENV_ADDR
	env_init();
# endif

        /*
         * Calculate environment variables sector address and size
         */
        info = addr2info((ulong)flash_addr);
        for (i=0; i<info->sector_count; i++)
          {
            if (info->start[i] >= (ulong)flash_addr)
              break;
          }
        sector_flash_addr = info->start[i-1];
        sector_flash_size = info->start[i] - info->start[i-1];
        sector_flash_offs = (ulong)flash_addr - info->start[i-1];

	/*
	 * Allocate temp buffer to edit environment
	 */
	if ((ed_buf = malloc(sector_flash_size)) == NULL) {
		printf ("## malloc(%lu) failed\n", sector_flash_size);
		return;
	}

        /*
         * Copy sector down to ram
         */
	memcpy(ed_buf, (uchar *)sector_flash_addr, sector_flash_size);

        /*
         * Copy new environment variables to ram image of flash sector
         */
	memcpy(ed_buf+sector_flash_offs, (uchar *)environment, env_size);

	flash_sect_protect (0, sector_flash_addr, sector_flash_addr+sector_flash_size-1);

	printf ("Erasing Flash...");
	flash_sect_erase (sector_flash_addr, sector_flash_addr+sector_flash_size-1);

	printf ("Saving Environment to Flash...\n");
	switch (rc = flash_write (ed_buf, sector_flash_addr, sector_flash_size)) {
	case 0: break;
	case 1: printf ("Timeout writing to Flash\n");
		break;
	case 2: printf ("Flash not Erased\n");
		break;
	case 4: printf ("Can't write to protected Flash sectors\n");
		break;
	default:
		printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);
	}

	free (ed_buf);

	flash_sect_protect (1, sector_flash_addr, sector_flash_addr+sector_flash_size-1);
#else	/* ! CONFIG_4xx */

# ifndef CFG_FLASH_ENV_ADDR
	env_init();
# endif

# if defined(CFG_FLASH_ENV_BUF)
	/* this buffer area was reserved in board_init_f() */
	sector_buffer = (uchar *)((ulong)bd - CFG_FLASH_ENV_BUF);
	/* copy the environment into the sector buffer */
	memcpy(sector_buffer, environment, env_size);
	/* override the old names */
# define environment sector_buffer
# define env_size CFG_FLASH_ENV_BUF
# endif	/* CFG_FLASH_ENV_BUF */

	flash_sect_protect (0, (ulong)flash_addr, (ulong)flash_addr+env_size-1);

	printf ("Erasing Flash...");
	flash_sect_erase ((ulong)flash_addr, (ulong)flash_addr+env_size-1);

	printf ("Saving Environment to Flash...\n");
	switch (rc = flash_write (environment, (ulong)flash_addr, env_size)) {
	case 0: break;
	case 1: printf ("Timeout writing to Flash\n");
		break;
	case 2: printf ("Flash not Erased\n");
		break;
	case 4: printf ("Can't write to protected Flash sectors\n");
		break;
	case 8: printf ("Outside available Flash\n");
		return;
	default:
		printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);
	}

	flash_sect_protect (1, (ulong)flash_addr, (ulong)flash_addr+env_size-1);

# if defined(CFG_FLASH_ENV_BUF)
# undef environment
# undef env_size
# endif	/* CFG_FLASH_ENV_BUF */

#endif	/* CONFIG_4xx */
}
Example #7
0
void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
	flash_info_t *info;
	ulong bank, addr_first, addr_last;
	int i, p, n, sect_first, sect_last;

	if (argc < 3) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return;
	}

	if (strcmp(argv[1], "off") == 0)
		p = 0;
	else if (strcmp(argv[1], "on") == 0)
		p = 1;
	else {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return;
	}

	if (strcmp(argv[2], "all") == 0) {
		for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) {
			info = &flash_info[bank-1];
			if (info->flash_id == FLASH_UNKNOWN) {
				continue;
			}
			printf ("%sProtect Flash Bank # %ld\n",
				p ? "" : "Un-", bank);

			for (i=0; i<info->sector_count; ++i) {
                          if ((info->flash_id & FLASH_TYPEMASK)==FLASH_INT640B) { flash_protect_sector(info, i, p); }
                          else { protect_sector(info, i, p); }
			}
		}
		return;
	}

	if ((n = abbrev_spec(argv[2], &info, &sect_first, &sect_last)) != 0) {
		if (n < 0) {
			printf("Bad sector specification\n");
			return;
		}
		printf("%sProtect Flash Sectors %d-%d in Bank # %d\n",
			p ? "" : "Un-", sect_first, sect_last,
			(info-flash_info)+1);
		for (i = sect_first; i <= sect_last; i++) {
			   if ((info->flash_id & FLASH_TYPEMASK)==FLASH_INT640B) { flash_protect_sector(info, i, p); }
                           else { protect_sector(info, i, p); }
		}
		return;
	}

	if (argc != 4) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return;
	}

	if (strcmp(argv[2], "bank") == 0) {
		bank = simple_strtoul(argv[3], NULL, 16);
		if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
			printf ("Only FLASH Banks # 1 ... # %d supported\n",
				CFG_MAX_FLASH_BANKS);
			return;
		}
		printf ("%sProtect Flash Bank # %ld\n",
			p ? "" : "Un-", bank);
		info = &flash_info[bank-1];

		if (info->flash_id == FLASH_UNKNOWN) {
			printf ("missing or unknown FLASH type\n");
			return;
		}
		for (i=0; i<info->sector_count; ++i) {
	                   if ((info->flash_id & FLASH_TYPEMASK)==FLASH_INT640B) { flash_protect_sector(info, i, p); }
                           else { protect_sector(info, i, p); }
		}
		return;
	}

	addr_first = simple_strtoul(argv[2], NULL, 16);
	addr_last  = simple_strtoul(argv[3], NULL, 16);

	if (addr_first >= addr_last) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return;
	}

	flash_sect_protect (p, addr_first, addr_last);
}
int
au_do_update(int idx, long sz)
{
	image_header_t *hdr;
	char *addr;
	long start, end;
	int off, rc;
	uint nbytes;

	hdr = (image_header_t *)LOAD_ADDR;
#if defined(CONFIG_FIT)
	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
		puts ("Non legacy image format not supported\n");
		return -1;
	}
#endif

	/* disable the power switch */
	*CPLD_VFD_BK |= POWER_OFF;

	/* execute a script */
	if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
		addr = (char *)((char *)hdr + image_get_header_size ());
		/* stick a NULL at the end of the script, otherwise */
		/* parse_string_outer() runs off the end. */
		addr[image_get_data_size (hdr)] = 0;
		addr += 8;
		parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
		return 0;
	}

	start = aufl_layout[FIDX_TO_LIDX(idx)].start;
	end = aufl_layout[FIDX_TO_LIDX(idx)].end;

	/* unprotect the address range */
	/* this assumes that ONLY the firmware is protected! */
	if (idx == IDX_FIRMWARE) {
#undef AU_UPDATE_TEST
#ifdef AU_UPDATE_TEST
		/* erase it where Linux goes */
		start = aufl_layout[1].start;
		end = aufl_layout[1].end;
#endif
		flash_sect_protect(0, start, end);
	}

	/*
	 * erase the address range.
	 */
	debug ("flash_sect_erase(%lx, %lx);\n", start, end);
	flash_sect_erase(start, end);
	wait_ms(100);
	/* strip the header - except for the kernel and ramdisk */
	if (image_check_type (hdr, IH_TYPE_KERNEL) ||
			image_check_type (hdr, IH_TYPE_RAMDISK)) {
		addr = (char *)hdr;
		off = image_get_header_size ();
		nbytes = image_get_image_size (hdr);
	} else {
		addr = (char *)((char *)hdr + image_get_header_size ());
#ifdef AU_UPDATE_TEST
		/* copy it to where Linux goes */
		if (idx == IDX_FIRMWARE)
			start = aufl_layout[1].start;
#endif
		off = 0;
		nbytes = image_get_data_size (hdr);
	}

	/* copy the data from RAM to FLASH */
	debug ("flash_write(%p, %lx %x)\n", addr, start, nbytes);
	rc = flash_write(addr, start, nbytes);
	if (rc != 0) {
		printf("Flashing failed due to error %d\n", rc);
		return -1;
	}

	/* check the dcrc of the copy */
	if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) !=
	    image_get_dcrc (hdr)) {
		printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]);
		return -1;
	}

	/* protect the address range */
	/* this assumes that ONLY the firmware is protected! */
	if (idx == IDX_FIRMWARE)
		flash_sect_protect(1, start, end);
	return 0;
}
int do_bootloader_update_nor(uint32_t image_addr, int length,
			     uint32_t burn_addr, int failsafe)
{
#if defined(CONFIG_SYS_NO_FLASH)
	printf("ERROR: Bootloader not compiled with NOR flash support\n");
	return 1;
#else
	uint32_t failsafe_size, failsafe_top_remapped;
	uint32_t burn_addr_remapped, image_size, normal_top_remapped;
	flash_info_t *info;
	char tmp[16] __attribute__ ((unused));	/* to hold 32 bit numbers in hex */
	int sector = 0;
	bootloader_header_t *header;
	int rc;

	header = cvmx_phys_to_ptr(image_addr);

	DBGUPD("%s(0x%x, 0x%x, 0x%x, %s)\n", __func__, image_addr, length,
	       burn_addr, failsafe ? "failsafe" : "normal");
	DBGUPD("LOOKUP_STEP                0x%x\n", LOOKUP_STEP);
	DBGUPD("CFG_FLASH_BASE             0x%x\n", CONFIG_SYS_FLASH_BASE);

	/* File with rev 1.1 headers are not relocatable, so _must_ be burned
	 * at the address that they are linked at.
	 */
	if (header->maj_rev == 1 && header->min_rev == 1) {
		if (burn_addr && burn_addr != header->address) {
			printf("ERROR: specified address (0x%x) does not match "
			       "required burn address (0x%llx\n)\n",
			       burn_addr, header->address);
			return 1;
		}
		burn_addr = header->address;
	}

	/* If we have at least one bank of non-zero size, we have some NOR */
	if (!flash_info[0].size) {
		puts("ERROR: No NOR Flash detected on board, can't burn NOR "
		     "bootloader image\n");
		return 1;
	}

	/* check the burn address allignement */
	if ((burn_addr & (LOOKUP_STEP - 1)) != 0) {
		printf("Cannot programm normal image at 0x%x: address must be\n"
		       " 0x%x bytes alligned for normal boot lookup\n",
		       burn_addr, LOOKUP_STEP);
		return 1;
	}

	/* for failsage checks are easy */
	if ((failsafe) && (burn_addr != FAILSAFE_BASE)) {
		printf("ERROR: Failsafe image must be burned to address 0x%x\n",
		       FAILSAFE_BASE);
		return 1;
	}

	if (burn_addr && (burn_addr < FAILSAFE_BASE)) {
		printf("ERROR: burn address 0x%x out of boot range\n",
		       burn_addr);
		return 1;
	}

	if (!failsafe) {
#ifndef CONFIG_OCTEON_NO_FAILSAFE
		/* find out where failsafe ends */
		failsafe_size = get_image_size((bootloader_header_t *)
					       CONFIG_SYS_FLASH_BASE);
		if (failsafe_size == 0) {
			/* failsafe does not have header - assume fixed size
			 * old image
			 */
			puts("Failsafe has no valid header, assuming old image. "
			     "Using default failsafe size\n");
			failsafe_size =
			    CONFIG_SYS_NORMAL_BOOTLOADER_BASE - FAILSAFE_BASE;

			/* must default to CONFIG_SYS_NORMAL_BOOTLOADER_BASE */
			if (!burn_addr)
				burn_addr = CONFIG_SYS_NORMAL_BOOTLOADER_BASE;
			else if (CONFIG_SYS_NORMAL_BOOTLOADER_BASE != burn_addr) {
				printf("WARNING: old failsafe image will not be able to start\n"
				       "image at any address but 0x%x\n",
				       CONFIG_SYS_NORMAL_BOOTLOADER_BASE);
#ifdef ERR_ON_OLD_BASE
				return 1;
#endif
			}
		}		/* old failsafe */
#else
		failsafe_size = 0;
#endif		/* CONFIG_OCTEON_NO_FAILSAFE */

		DBGUPD("failsafe size is 0x%x\n", failsafe_size);
		DBGUPD("%s: burn address: 0x%x\n", __func__, burn_addr);
		/* Locate the next flash sector */
		failsafe_top_remapped = CONFIG_SYS_FLASH_BASE + failsafe_size;
		DBGUPD("failsafe_top_remapped 0x%x\n", failsafe_top_remapped);
		info = &flash_info[0];	/* no need to look into any other banks */
		/* scan flash bank sectors */
		for (sector = 0; sector < info->sector_count; ++sector) {
			DBGUPD("%d: 0x%lx\n", sector, info->start[sector]);
			if (failsafe_top_remapped <= info->start[sector])
				break;
		}

		if (sector == info->sector_count) {
			puts("Failsafe takes all the flash??  Can not burn normal image\n");
			return 1;
		}

		/* Move failsafe top up to the sector boundary */
		failsafe_top_remapped = info->start[sector];

		DBGUPD("Found next sector after failsafe is at remapped addr 0x%x\n",
		       failsafe_top_remapped);
		failsafe_size = failsafe_top_remapped - CONFIG_SYS_FLASH_BASE;
		DBGUPD("Alligned up failsafe size is 0x%x\n", failsafe_size);

		/* default to the first sector after the failsafe */
		if (!burn_addr) {
			burn_addr = FAILSAFE_BASE + failsafe_size;
			DBGUPD("Setting burn address to 0x%x, failsafe size: 0x%x\n",
			       burn_addr, failsafe_size);
		/* check for overlap */
		} else if (FAILSAFE_BASE + failsafe_size > burn_addr) {
			puts("ERROR: can not burn: image overlaps with failsafe\n");
			printf("burn address is 0x%x, in-flash failsafe top is 0x%x\n",
			       burn_addr, FAILSAFE_BASE + failsafe_size);
			return 1;
		}
		/* done with failsafe checks */
	}

	if (length)
		image_size = length;
	else
		image_size = get_image_size((bootloader_header_t *)image_addr);
	if (!image_size) {
		/* this is wierd case. Should never happen with good image */
		printf("ERROR: image has size field set to 0??\n");
		return 1;
	}

	/* finally check the burn address' CKSSEG limit */
	if ((burn_addr + image_size) >= (uint64_t) CKSSEG) {
		puts("ERROR: can not burn: image exceeds KSEG1 area\n");
		printf("burnadr is 0x%x, top is 0x%x\n", burn_addr,
		       burn_addr + image_size);
		return 1;
	}
	DBGUPD("burn_addr: 0x%x, image_size: 0x%x\n", burn_addr, image_size);
	/* Look up the last sector to use by the new image */
	burn_addr_remapped = burn_addr - FAILSAFE_BASE + CONFIG_SYS_FLASH_BASE;
	DBGUPD("burn_addr_remapped 0x%x\n", burn_addr_remapped);
	normal_top_remapped = burn_addr_remapped + image_size;
	/* continue flash scan - now for normal image top */
	if (failsafe)
		sector = 0;	/* is failsafe, we start from first sector here */
	for (; sector < info->sector_count; ++sector) {
		DBGUPD("%d: 0x%lx\n", sector, info->start[sector]);
		if (normal_top_remapped <= info->start[sector])
			break;
	}
	if (sector == info->sector_count) {
		puts("ERROR: not enough room in flash bank for the image??\n");
		return 1;
	}
	/* align up for environment variable set up */
	normal_top_remapped = info->start[sector];

	DBGUPD("normal_top_remapped 0x%x\n", normal_top_remapped);
	/* if there is no header (length != 0) - check burn address and
	 * give warning
	 */
	if (length && CONFIG_SYS_NORMAL_BOOTLOADER_BASE != burn_addr) {
#ifdef ERR_ON_OLD_BASE
		puts("ERROR: burning headerless image at other that defailt address\n"
		     "Image look up will not work.\n");
		printf("Default burn address: 0x%x requested burn address: 0x%x\n",
		       CONFIG_SYS_NORMAL_BOOTLOADER_BASE, burn_addr);
		return 1;
#else
		puts("WARNING: burning headerless image at other that defailt address\n"
		     "Image look up will not work.\n");
		printf("Default burn address: 0x%x requested burn address: 0x%x\n",
		       CONFIG_SYS_NORMAL_BOOTLOADER_BASE, burn_addr);
#endif
	}

	printf("Image at 0x%x is ready for burning\n", image_addr);
	printf("           Header version: %d.%d\n", header->maj_rev,
	       header->min_rev);
	printf("           Header size %d, data size %d\n", header->hlen,
	       header->dlen);
	printf("           Header crc 0x%x, data crc 0x%x\n", header->hcrc,
	       header->dcrc);
	printf("           Image link address is 0x%llx\n", header->address);
	printf("           Image burn address on flash is 0x%x\n", burn_addr);
	printf("           Image size on flash 0x%x\n",
	       normal_top_remapped - burn_addr_remapped);

	DBGUPD("burn_addr_remapped 0x%x normal_top_remapped 0x%x\n",
	       burn_addr_remapped, normal_top_remapped);
	if (flash_sect_protect(0, burn_addr_remapped, normal_top_remapped - 1)) {
		puts("Flash unprotect failed\n");
		return 1;
	}
	if (flash_sect_erase(burn_addr_remapped, normal_top_remapped - 1)) {
		puts("Flash erase failed\n");
		return 1;
	}

	puts("Copy to Flash... ");
	/* Note: Here we copy more than we should - whatever is after the image
	 * in memory gets copied to flash.
	 */
	rc = flash_write((char *)image_addr, burn_addr_remapped,
			 normal_top_remapped - burn_addr_remapped);
	if (rc != 0) {
		flash_perror(rc);
		return 1;
	}
	puts("done\n");

#ifndef CONFIG_ENV_IS_IN_NAND
	/* Erase the environment so that older bootloader will use its default
	 * environment.  This will ensure that the default
	 * 'bootloader_flash_update' macro is there.  HOWEVER, this is only
	 * useful if a legacy sized failsafe u-boot image is present.
	 * If a new larger failsafe is present, then that macro will be incorrect
	 * and will erase part of the failsafe.
	 * The 1.9.0 u-boot needs to have its link address and
	 * normal_bootloader_size/base modified to work with this...
	 */
	if (header->maj_rev == 1 && header->min_rev == 1) {
		puts("Erasing environment due to u-boot downgrade.\n");
		flash_sect_protect(0, CONFIG_ENV_ADDR,
				   CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1);
		if (flash_sect_erase
		    (CONFIG_ENV_ADDR, CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1)) {
			puts("Environment erase failed\n");
			return 1;
		}

	}
#endif
	return 0;
#endif
}
Example #10
0
/*******************************************************************************
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;

#endif

#if defined(CONFIG_ENV_IS_IN_NAND)
	size_t offset = 0;
	nand_info_t *nand = &nand_info[0];
	int sum = 0;

#if defined(CONFIG_SKIP_BAD_BLOCK)
	int i = 0;
	size_t blocksize;
	blocksize = nand_info[0].erasesize;
	while(i * blocksize < nand_info[0].size) {
		if (!nand_block_isbad(&nand_info[0], (i * blocksize)))
			sum += blocksize;
		else {
			sum = 0;
			offset = (i + 1) * blocksize;
		}
		if (sum >= CONFIG_UBOOT_SIZE)
			break;
		i++;
	}
#else
	offset = CONFIG_ENV_OFFSET;
#endif
	printf("Erasing 0x%x - 0x%x:",CONFIG_UBOOT_SIZE + offset, CONFIG_ENV_RANGE_NAND);
	nand_erase(nand, CONFIG_UBOOT_SIZE + offset, CONFIG_ENV_RANGE_NAND);
	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(0, 0, 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");

#endif
	printf("Warning: Default Environment Variables will take effect Only after RESET\n");
	return 0;
}
Example #11
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;
}
Example #12
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;
}
/*******************************************************************************
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;
}
Example #14
0
int saveenv(void)
{
	int	len, rc;
	ulong	end_addr;
	ulong	flash_sect_addr;
#if defined(CONFIG_ENV_SECT_SIZE) && (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE)
	ulong	flash_offset;
	uchar	env_buffer[CONFIG_ENV_SECT_SIZE];
#else
	uchar *env_buffer = (uchar *)env_ptr;
#endif	/* CONFIG_ENV_SECT_SIZE */
	int rcode = 0;

#if defined(CONFIG_ENV_SECT_SIZE) && (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE)

	flash_offset    = ((ulong)flash_addr) & (CONFIG_ENV_SECT_SIZE-1);
	flash_sect_addr = ((ulong)flash_addr) & ~(CONFIG_ENV_SECT_SIZE-1);

	debug ( "copy old content: "
		"sect_addr: %08lX  env_addr: %08lX  offset: %08lX\n",
		flash_sect_addr, (ulong)flash_addr, flash_offset);

	/* copy old contents to temporary buffer */
	memcpy (env_buffer, (void *)flash_sect_addr, CONFIG_ENV_SECT_SIZE);

	/* copy current environment to temporary buffer */
	memcpy ((uchar *)((unsigned long)env_buffer + flash_offset),
		env_ptr,
		CONFIG_ENV_SIZE);

	len	 = CONFIG_ENV_SECT_SIZE;
#else
	flash_sect_addr = (ulong)flash_addr;
	len	 = CONFIG_ENV_SIZE;
#endif	/* CONFIG_ENV_SECT_SIZE */

#ifndef CONFIG_INFERNO
	end_addr = flash_sect_addr + len - 1;
#else
	/* this is the last sector, and the size is hardcoded here */
	/* otherwise we will get stack problems on loading 128 KB environment */
	end_addr = flash_sect_addr + CONFIG_INFERNO - 1;
#endif

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

	if (flash_sect_protect (0, flash_sect_addr, end_addr))
		return 1;

	puts ("Erasing Flash...");
	if (flash_sect_erase (flash_sect_addr, end_addr))
		return 1;

	puts ("Writing to Flash... ");
	rc = flash_write((char *)env_buffer, flash_sect_addr, len);
	if (rc != 0) {
		flash_perror (rc);
		rcode = 1;
	} else {
		puts ("done\n");
	}

	/* try to re-protect */
	(void) flash_sect_protect (1, flash_sect_addr, end_addr);
	return rcode;
}
Example #15
0
int saveenv(void)
{
	char *saved_data = NULL;
	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;
	}

#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%x\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%x, len 0x%x) saved at 0x%x\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_ptr->data,
			(ulong)&(flash_addr_new->data),
			sizeof(env_ptr->data))) ||
	    (rc = flash_write((char *)&(env_ptr->crc),
			(ulong)&(flash_addr_new->crc),
			sizeof(env_ptr->crc))) ||
	    (rc = flash_write(&flag,
			(ulong)&(flash_addr->flags),
			sizeof(flash_addr->flags))) ||
	    (rc = flash_write(&new_flag,
			(ulong)&(flash_addr_new->flags),
			sizeof(flash_addr_new->flags))))
	{
		flash_perror (rc);
		goto Done;
	}
	puts ("done\n");

#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
	if (up_data) { /* restore the rest of sector */
		debug ("Restoring the rest of data to 0x%x len 0x%x\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
	{
		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;
}
Example #16
0
int saveenv(void)
{
	env_t	env_new;
	char	*saved_data = NULL;
	char	flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG;
	int	rc = 1;
#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;

	rc = env_export(&env_new);
	if (rc)
		return rc;
	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) {
		saved_data = malloc(up_data);
		if (saved_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));
	rc = flash_write((char *)&env_new, (ulong)flash_addr_new,
			 sizeof(env_new));
	if (rc)
		goto perror;

	rc = flash_write(&flag, (ulong)&(flash_addr->flags),
			 sizeof(flash_addr->flags));
	if (rc)
		goto perror;

#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))
			goto perror;
	}
#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;
	goto done;
perror:
	flash_perror(rc);
done:
	if (saved_data)
		free(saved_data);
	/* try to re-protect */
	flash_sect_protect(1, (ulong)flash_addr, end_addr);
	flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new);

	return rc;
}
Example #17
0
int saveenv(void)
{
	env_t	env_new;
	int	rc = 1;
	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) {
		saved_data = malloc(up_data);
		if (saved_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;

	rc = env_export(&env_new);
	if (rc)
		goto done;

	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)
		goto perror;

#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))
			goto perror;
	}
#endif
	puts("done\n");
	rc = 0;
	goto done;
perror:
	flash_perror(rc);
done:
	if (saved_data)
		free(saved_data);
	/* try to re-protect */
	flash_sect_protect(1, (long)flash_addr, end_addr);
	return rc;
}
Example #18
0
int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	flash_info_t *info;
	ulong bank, addr_first, addr_last;
	int i, p, n, sect_first, sect_last;
	int rcode = 0;
#ifdef CONFIG_HAS_DATAFLASH
	int status;
#endif
	if (argc < 3) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (strcmp(argv[1], "off") == 0) {
		p = 0;
	} else if (strcmp(argv[1], "on") == 0) {
		p = 1;
	} else {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

#ifdef CONFIG_HAS_DATAFLASH
	if ((strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0)) {
		addr_first = simple_strtoul(argv[2], NULL, 16);
		addr_last  = simple_strtoul(argv[3], NULL, 16);

		if (addr_dataflash(addr_first) && addr_dataflash(addr_last)) {
			status = dataflash_real_protect(p,addr_first,addr_last);
			if (status < 0){
				puts ("Bad DataFlash sector specification\n");
				return 1;
			}
			printf("%sProtect %d DataFlash Sectors\n",
				p ? "" : "Un-", status);
			return 0;
		}
	}
#endif

	if (strcmp(argv[2], "all") == 0) {
		for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) {
			info = &flash_info[bank-1];
			if (info->flash_id == FLASH_UNKNOWN) {
				continue;
			}
			printf ("%sProtect Flash Bank # %ld\n",
				p ? "" : "Un-", bank);

			for (i=0; i<info->sector_count; ++i) {
#if defined(CFG_FLASH_PROTECTION)
				if (flash_real_protect(info, i, p))
					rcode = 1;
				putc ('.');
#else
				info->protect[i] = p;
#endif	/* CFG_FLASH_PROTECTION */
			}
		}

#if defined(CFG_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CFG_FLASH_PROTECTION */

		return rcode;
	}

	if ((n = abbrev_spec(argv[2], &info, &sect_first, &sect_last)) != 0) {
		if (n < 0) {
			puts ("Bad sector specification\n");
			return 1;
		}
		printf("%sProtect Flash Sectors %d-%d in Bank # %d\n",
			p ? "" : "Un-", sect_first, sect_last,
			(info-flash_info)+1);
		for (i = sect_first; i <= sect_last; i++) {
#if defined(CFG_FLASH_PROTECTION)
			if (flash_real_protect(info, i, p))
				rcode =  1;
			putc ('.');
#else
			info->protect[i] = p;
#endif	/* CFG_FLASH_PROTECTION */
		}

#if defined(CFG_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CFG_FLASH_PROTECTION */

		return rcode;
	}

	if (argc != 4) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (strcmp(argv[2], "bank") == 0) {
		bank = simple_strtoul(argv[3], NULL, 16);
		if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
			printf ("Only FLASH Banks # 1 ... # %d supported\n",
				CFG_MAX_FLASH_BANKS);
			return 1;
		}
		printf ("%sProtect Flash Bank # %ld\n",
			p ? "" : "Un-", bank);
		info = &flash_info[bank-1];

		if (info->flash_id == FLASH_UNKNOWN) {
			puts ("missing or unknown FLASH type\n");
			return 1;
		}
		for (i=0; i<info->sector_count; ++i) {
#if defined(CFG_FLASH_PROTECTION)
			if (flash_real_protect(info, i, p))
				rcode =  1;
			putc ('.');
#else
			info->protect[i] = p;
#endif	/* CFG_FLASH_PROTECTION */
		}

#if defined(CFG_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CFG_FLASH_PROTECTION */

		return rcode;
	}

	addr_first = simple_strtoul(argv[2], NULL, 16);
	addr_last  = simple_strtoul(argv[3], NULL, 16);

	if (addr_first >= addr_last) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}
	rcode = flash_sect_protect (p, addr_first, addr_last);
	return rcode;
}