/* * 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; }
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 */ }
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; }
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); }
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, §_first, §_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; }
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 */ }
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, §_first, §_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 }
/******************************************************************************* 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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, §_first, §_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; }