Mercurial > ecos
diff packages/redboot/current/src/flash.c @ 184:022f1e506033
Merge from eCos master repository on 2001-10-02-17:59:22-BST
| author | jlarmour |
|---|---|
| date | Tue, 02 Oct 2001 18:28:24 +0000 |
| parents | 9160a8005d76 |
| children | 678094f34118 |
line wrap: on
line diff
--- a/packages/redboot/current/src/flash.c +++ b/packages/redboot/current/src/flash.c @@ -145,8 +145,11 @@ extern struct cmd __FIS_cmds_TAB__[], __ // Local data used by these routines static void *flash_start, *flash_end; static int block_size, blocks; +#ifdef CYGOPT_REDBOOT_FIS static void *fis_work_block; -static int fisdir_size; // Size of FIS directory. Note: zero if FIS not enabled +static void *fis_addr; +static int fisdir_size; // Size of FIS directory. +#endif #ifdef CYGSEM_REDBOOT_FLASH_CONFIG static void *cfg_base; // Location in Flash of config data static int cfg_size; // Length of config data - rounded to Flash block size @@ -161,22 +164,20 @@ fis_usage(char *why) cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); } +static void +_show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat) +{ + diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); + diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); +} + #ifdef CYGOPT_REDBOOT_FIS struct fis_image_desc * fis_lookup(char *name) { int i; - void *fis_addr; struct fis_image_desc *img; - if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { - fis_addr = (void *)((unsigned long)flash_end + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } else { - fis_addr = (void *)((unsigned long)flash_start + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } - memcpy(fis_work_block, fis_addr, block_size); img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { @@ -191,10 +192,11 @@ fis_init(int argc, char *argv[]) { int stat; struct fis_image_desc *img; - void *fis_base, *err_addr; + void *err_addr; bool full_init = false; struct option_info opts[1]; - unsigned long redboot_image_size, redboot_flash_start; + CYG_ADDRESS redboot_flash_start; + unsigned long redboot_image_size; init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG, (void **)&full_init, (bool *)0, "full initialization, erases all of flash"); @@ -217,12 +219,12 @@ fis_init(int argc, char *argv[]) #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE memset(img, 0, sizeof(*img)); strcpy(img->name, "(reserved)"); - img->flash_base = (unsigned long)flash_start; - img->mem_base = (unsigned long)flash_start; + img->flash_base = (CYG_ADDRESS)flash_start; + img->mem_base = (CYG_ADDRESS)flash_start; img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE; img++; #endif - redboot_flash_start = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; + redboot_flash_start = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; #ifdef CYGOPT_REDBOOT_FIS_REDBOOT memset(img, 0, sizeof(*img)); strcpy(img->name, "RedBoot"); @@ -235,7 +237,7 @@ fis_init(int argc, char *argv[]) #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST #ifdef CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET // Take care to place the POST entry at the right offset: - redboot_flash_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET; + redboot_flash_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET; #endif memset(img, 0, sizeof(*img)); strcpy(img->name, "RedBoot[post]"); @@ -259,30 +261,16 @@ fis_init(int argc, char *argv[]) // And a descriptor for the configuration data memset(img, 0, sizeof(*img)); strcpy(img->name, "RedBoot config"); - if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { - cfg_base = (void *)((unsigned long)flash_end + - (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); - } else { - cfg_base = (void *)((unsigned long)flash_start + - (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); - } - img->flash_base = (unsigned long)cfg_base; - img->mem_base = (unsigned long)cfg_base; + img->flash_base = (CYG_ADDRESS)cfg_base; + img->mem_base = (CYG_ADDRESS)cfg_base; img->size = cfg_size; img++; #endif // And a descriptor for the descriptor table itself memset(img, 0, sizeof(*img)); strcpy(img->name, "FIS directory"); - if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { - fis_base = (void *)((unsigned long)flash_end + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } else { - fis_base = (void *)((unsigned long)flash_start + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } - img->flash_base = (unsigned long)fis_base; - img->mem_base = (unsigned long)fis_base; + img->flash_base = (CYG_ADDRESS)fis_addr; + img->mem_base = (CYG_ADDRESS)fis_addr; img->size = block_size; img++; @@ -290,12 +278,14 @@ fis_init(int argc, char *argv[]) // calculates where the high water mark of default RedBoot images is. if (full_init) { - unsigned long erase_start, erase_size; + unsigned long erase_size; + CYG_ADDRESS erase_start; // Erase everything except default RedBoot images, fis block, // and config block. // First deal with the possible first part, before RedBoot images: - erase_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; - erase_size = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; +#if (CYGBLD_REDBOOT_FLASH_BOOT_OFFSET > CYGNUM_REDBOOT_FLASH_RESERVED_BASE) + erase_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; + erase_size = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; if ( erase_size > erase_start ) { erase_size -= erase_start; if ((stat = flash_erase((void *)erase_start, erase_size, @@ -304,15 +294,16 @@ fis_init(int argc, char *argv[]) err_addr, flash_errmsg(stat)); } } +#endif // second deal with the larger part in the main: erase_start = redboot_flash_start; // high water of created images // Now the empty bits between the end of Redboot and the cfg and dir // blocks. #ifdef CYGSEM_REDBOOT_FLASH_CONFIG - if (fis_base > cfg_base) { - erase_size = (unsigned long)cfg_base - erase_start; // the gap between HWM and config data + if (fis_addr > cfg_base) { + erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between HWM and config data } else { - erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data + erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data } if ((stat = flash_erase((void *)erase_start, erase_size, (void **)&err_addr)) != 0) { @@ -320,10 +311,10 @@ fis_init(int argc, char *argv[]) err_addr, flash_errmsg(stat)); } erase_start += (erase_size + block_size); - if (fis_base > cfg_base) { - erase_size = (unsigned long)fis_base - erase_start; // the gap between config and fis data + if (fis_addr > cfg_base) { + erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between config and fis data } else { - erase_size = (unsigned long)cfg_base - erase_start; // the gap between fis and config data + erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between fis and config data } if ((stat = flash_erase((void *)erase_start, erase_size, (void **)&err_addr)) != 0) { @@ -332,7 +323,7 @@ fis_init(int argc, char *argv[]) } erase_start += (erase_size + block_size); #else // !CYGSEM_REDBOOT_FLASH_CONFIG - erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data + erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data if ((stat = flash_erase((void *)erase_start, erase_size, (void **)&err_addr)) != 0) { diag_printf(" initialization failed %p: %s\n", @@ -341,7 +332,7 @@ fis_init(int argc, char *argv[]) erase_start += (erase_size + block_size); #endif // Lastly, anything at the end - erase_size = (unsigned long)flash_end - erase_start; + erase_size = ((CYG_ADDRESS)flash_end - erase_start) + 1; if ((stat = flash_erase((void *)erase_start, erase_size, (void **)&err_addr)) != 0) { diag_printf(" initialization failed at %p: %s\n", @@ -353,13 +344,13 @@ fis_init(int argc, char *argv[]) #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Ensure [quietly] that the directory is unlocked before trying to update - flash_unlock((void *)fis_base, block_size, (void **)&err_addr); + flash_unlock((void *)fis_addr, block_size, (void **)&err_addr); #endif - if ((stat = flash_erase(fis_base, block_size, (void **)&err_addr)) != 0) { + if ((stat = flash_erase(fis_addr, block_size, (void **)&err_addr)) != 0) { diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); } else { - if ((stat = flash_program(fis_base, fis_work_block, - (unsigned long)img - (unsigned long)fis_work_block, + if ((stat = flash_program(fis_addr, fis_work_block, + (CYG_ADDRESS)img - (CYG_ADDRESS)fis_work_block, (void **)&err_addr)) != 0) { diag_printf("Error writing image descriptors at %p: %s\n", err_addr, flash_errmsg(stat)); @@ -367,7 +358,7 @@ fis_init(int argc, char *argv[]) } #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Ensure [quietly] that the directory is locked after the update - flash_lock((void *)fis_base, block_size, (void **)&err_addr); + flash_lock((void *)fis_addr, block_size, (void **)&err_addr); #endif } @@ -393,13 +384,7 @@ fis_list(int argc, char *argv[]) { return; } - if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { - img = (void *)((unsigned long)flash_end + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } else { - img = (void *)((unsigned long)flash_start + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } + img = (struct fis_image_desc *)fis_work_block; // Let diag_printf do the formatting in both cases, rather than counting // cols by hand.... diag_printf("%-16s %-10s %-10s %-10s %-s\n", @@ -430,15 +415,15 @@ fis_free(int argc, char *argv[]) unsigned long *area_start; // Do not search the area reserved for pre-RedBoot systems: - fis_ptr = (unsigned long *)((unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); - fis_end = (unsigned long *)(unsigned long)flash_end; + fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); + fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; area_start = fis_ptr; while (fis_ptr < fis_end) { if (*fis_ptr != (unsigned long)0xFFFFFFFF) { if (area_start != fis_ptr) { // Assume that this is something diag_printf(" 0x%08lX .. 0x%08lX\n", - (unsigned long)area_start, (unsigned long)fis_ptr); + (CYG_ADDRESS)area_start, (CYG_ADDRESS)fis_ptr); } // Find next blank block area_start = fis_ptr; @@ -446,36 +431,36 @@ fis_free(int argc, char *argv[]) if (*area_start == (unsigned long)0xFFFFFFFF) { break; } - area_start += block_size / sizeof(unsigned long); + area_start += block_size / sizeof(CYG_ADDRESS); } fis_ptr = area_start; } else { - fis_ptr += block_size / sizeof(unsigned long); + fis_ptr += block_size / sizeof(CYG_ADDRESS); } } if (area_start != fis_ptr) { diag_printf(" 0x%08lX .. 0x%08lX\n", - (unsigned long)area_start, (unsigned long)fis_ptr); + (CYG_ADDRESS)area_start, (CYG_ADDRESS)fis_ptr); } } // Find the first unused area of flash which is long enough static bool -fis_find_free(unsigned long *addr, unsigned long length) +fis_find_free(CYG_ADDRESS *addr, unsigned long length) { unsigned long *fis_ptr, *fis_end; unsigned long *area_start; // Do not search the area reserved for pre-RedBoot systems: - fis_ptr = (unsigned long *)((unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); - fis_end = (unsigned long *)(unsigned long)flash_end; + fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); + fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; area_start = fis_ptr; while (fis_ptr < fis_end) { if (*fis_ptr != (unsigned long)0xFFFFFFFF) { if (area_start != fis_ptr) { // Assume that this is something if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { - *addr = (unsigned long)area_start; + *addr = (CYG_ADDRESS)area_start; return true; } } @@ -485,16 +470,16 @@ fis_find_free(unsigned long *addr, unsig if (*area_start == (unsigned long)0xFFFFFFFF) { break; } - area_start += block_size / sizeof(unsigned long); + area_start += block_size / sizeof(CYG_ADDRESS); } fis_ptr = area_start; } else { - fis_ptr += block_size / sizeof(unsigned long); + fis_ptr += block_size / sizeof(CYG_ADDRESS); } } if (area_start != fis_ptr) { if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { - *addr = (unsigned long)area_start; + *addr = (CYG_ADDRESS)area_start; return true; } } @@ -505,7 +490,8 @@ static void fis_create(int argc, char *argv[]) { int i, stat; - unsigned long mem_addr, exec_addr, flash_addr, entry_addr, length, img_size; + unsigned long length, img_size; + CYG_ADDRESS mem_addr, exec_addr, flash_addr, entry_addr; char *name; bool mem_addr_set = false; bool exec_addr_set = false; @@ -514,11 +500,11 @@ fis_create(int argc, char *argv[]) bool length_set = false; bool img_size_set = false; bool no_copy = false; - void *fis_addr, *err_addr; + void *err_addr; struct fis_image_desc *img; bool slot_found, defaults_assumed; struct option_info opts[7]; - bool prog_ok = false; + bool prog_ok = true; init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, (void **)&mem_addr, (bool *)&mem_addr_set, "memory base address"); @@ -543,14 +529,6 @@ fis_create(int argc, char *argv[]) defaults_assumed = false; if (name) { // Search existing files to acquire defaults for params not specified: - if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { - fis_addr = (void *)((unsigned long)flash_end + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } else { - fis_addr = (void *)((unsigned long)flash_start + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } - memcpy(fis_work_block, fis_addr, block_size); img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { @@ -595,8 +573,7 @@ fis_create(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) { - diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + _show_invalid_flash_address(flash_addr, stat); return; } if (flash_addr_set && flash_addr & (block_size-1)) { @@ -609,8 +586,8 @@ fis_create(int argc, char *argv[]) return; } if (!no_copy) { - if ((mem_addr < (unsigned long)ram_start) || - ((mem_addr+img_size) >= (unsigned long)ram_end)) { + if ((mem_addr < (CYG_ADDRESS)ram_start) || + ((mem_addr+img_size) >= (CYG_ADDRESS)ram_end)) { diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } @@ -622,14 +599,6 @@ fis_create(int argc, char *argv[]) // Find a slot in the directory for this entry // First, see if an image by this name is already present slot_found = false; - if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { - fis_addr = (void *)((unsigned long)flash_end + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } else { - fis_addr = (void *)((unsigned long)flash_start + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } - memcpy(fis_work_block, fis_addr, block_size); img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { @@ -672,7 +641,6 @@ fis_create(int argc, char *argv[]) diag_printf("Can't program this region - contains code in use!\n"); return; } - prog_ok = true; if (prog_ok) { // Erase area to be programmed if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { @@ -694,7 +662,7 @@ fis_create(int argc, char *argv[]) strcpy(img->name, name); img->flash_base = flash_addr; img->mem_base = exec_addr_set ? exec_addr : (flash_addr_set ? flash_addr : mem_addr); - img->entry_point = entry_addr_set ? entry_addr : (unsigned long)entry_address; // Hope it's been set + img->entry_point = entry_addr_set ? entry_addr : (CYG_ADDRESS)entry_address; // Hope it's been set img->size = length; img->data_length = img_size; #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK @@ -725,7 +693,7 @@ fis_delete(int argc, char *argv[]) { char *name; int num_reserved, i, stat; - void *fis_addr, *err_addr; + void *err_addr; struct fis_image_desc *img; bool slot_found; @@ -735,14 +703,6 @@ fis_delete(int argc, char *argv[]) return; } slot_found = false; - if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { - fis_addr = (void *)((unsigned long)flash_end + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } else { - fis_addr = (void *)((unsigned long)flash_start + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); - } - memcpy(fis_work_block, fis_addr, block_size); img = (struct fis_image_desc *)fis_work_block; num_reserved = 0; #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE @@ -813,7 +773,7 @@ fis_load(int argc, char *argv[]) { char *name; struct fis_image_desc *img; - unsigned long mem_addr; + CYG_ADDRESS mem_addr; bool mem_addr_set = false; bool show_cksum = false; struct option_info opts[3]; @@ -849,8 +809,8 @@ fis_load(int argc, char *argv[]) mem_addr = img->mem_base; } // Load image from FLASH into RAM - if ((mem_addr < (unsigned long)user_ram_start) || - ((mem_addr+img->size) >= (unsigned long)user_ram_end)) { + if ((mem_addr < (CYG_ADDRESS)user_ram_start) || + ((mem_addr+img->size) >= (CYG_ADDRESS)user_ram_end)) { diag_printf("Not a loadable image\n"); return; } @@ -905,7 +865,8 @@ static void fis_write(int argc, char *argv[]) { int stat; - unsigned long mem_addr, flash_addr, length; + unsigned long length; + CYG_ADDRESS mem_addr, flash_addr; bool mem_addr_set = false; bool flash_addr_set = false; bool length_set = false; @@ -937,8 +898,7 @@ fis_write(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - diag_printf("Invalid FLASH address %p: (%s)\n", (void *)flash_addr, flash_errmsg(stat)); - diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + _show_invalid_flash_address(flash_addr, stat); return; } if (flash_addr_set && flash_addr & (block_size-1)) { @@ -946,8 +906,8 @@ fis_write(int argc, char *argv[]) diag_printf(" must be 0x%x aligned\n", block_size); return; } - if ((mem_addr < (unsigned long)ram_start) || - ((mem_addr+length) >= (unsigned long)ram_end)) { + if ((mem_addr < (CYG_ADDRESS)ram_start) || + ((mem_addr+length) >= (CYG_ADDRESS)ram_end)) { diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } @@ -982,7 +942,8 @@ static void fis_erase(int argc, char *argv[]) { int stat; - unsigned long flash_addr, length; + unsigned long length; + CYG_ADDRESS flash_addr; bool flash_addr_set = false; bool length_set = false; void *err_addr; @@ -1005,8 +966,7 @@ fis_erase(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + _show_invalid_flash_address(flash_addr, stat); return; } if (flash_addr_set && flash_addr & (block_size-1)) { @@ -1030,7 +990,8 @@ static void fis_lock(int argc, char *argv[]) { int stat; - unsigned long flash_addr, length; + unsigned long length; + CYG_ADDRESS flash_addr; bool flash_addr_set = false; bool length_set = false; void *err_addr; @@ -1053,8 +1014,7 @@ fis_lock(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + _show_invalid_flash_address(flash_addr, stat); return; } if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) { @@ -1066,7 +1026,8 @@ static void fis_unlock(int argc, char *argv[]) { int stat; - unsigned long flash_addr, length; + unsigned long length; + CYG_ADDRESS flash_addr; bool flash_addr_set = false; bool length_set = false; void *err_addr; @@ -1089,8 +1050,7 @@ fis_unlock(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + _show_invalid_flash_address(flash_addr, stat); return; } if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) { @@ -1099,6 +1059,7 @@ fis_unlock(int argc, char *argv[]) } #endif +// This is set non-zero if the FLASH subsystem has successfully been initialized static int __flash_init = 0; void @@ -1106,7 +1067,7 @@ void { if (!__flash_init) return; diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", - flash_start, flash_end, blocks, (void *)block_size); + flash_start, (CYG_ADDRWORD)flash_end + 1, blocks, (void *)block_size); } static bool @@ -1122,10 +1083,15 @@ do_flash_init(void) return false; } flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); + // Keep 'end' address as last valid location, to avoid wrap around problems + flash_end = (void *)((CYG_ADDRESS)flash_end - 1); flash_get_block_info(&block_size, &blocks); - fis_work_block = (unsigned char *)(workspace_end-FLASH_MIN_WORKSPACE-block_size); - workspace_end = fis_work_block; + workspace_end = (unsigned char *)(workspace_end-FLASH_MIN_WORKSPACE); +#ifdef CYGOPT_REDBOOT_FIS + workspace_end = (unsigned char *)(workspace_end-block_size); + fis_work_block = workspace_end; fisdir_size = block_size; +#endif } return true; } @@ -1143,7 +1109,20 @@ do_fis(int argc, char *argv[]) fis_usage("too few arguments"); return; } - if (!do_flash_init()) return; + if (!do_flash_init()) { + diag_printf("Sorry, no FLASH memory is available\n"); + return; + } +#ifdef CYGOPT_REDBOOT_FIS + if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { + fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 + + (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); + } else { + fis_addr = (void *)((CYG_ADDRESS)flash_start + + (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); + } + memcpy(fis_work_block, fis_addr, block_size); +#endif if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, argv[1])) != (struct cmd *)0) { (cmd->fun)(argc, argv); @@ -1163,7 +1142,7 @@ static struct _config { unsigned char config_data[MAX_CONFIG_DATA-(4*4)]; unsigned long key2; unsigned long cksum; -} config; +} *config, *backup_config; static bool config_ok; #define CONFIG_KEY1 0x0BADFACE @@ -1365,7 +1344,7 @@ get_config(unsigned char *dp, char *titl #ifdef CYGPKG_REDBOOT_NETWORKING case CONFIG_IP: memcpy(&hold_ip_val.s_addr, &((in_addr_t *)val_ptr)->s_addr, sizeof(in_addr_t)); - if (!inet_aton(line, &new_ip_val)) { + if (!_gethostbyname(line, &new_ip_val)) { return CONFIG_BAD; } if (hold_ip_val.s_addr != new_ip_val.s_addr) { @@ -1459,7 +1438,6 @@ do_flash_config(int argc, char *argv[]) bool need_update = false; struct config_option *optend = __CONFIG_options_TAB_END__; struct config_option *opt = __CONFIG_options_TAB__; - struct _config hold_config; struct option_info opts[4]; bool list_only; bool nicknames; @@ -1473,8 +1451,11 @@ do_flash_config(int argc, char *argv[]) bool doneone = false; bool init = false; - if (!do_flash_init()) return; - memcpy(&hold_config, &config, sizeof(config)); + if (!__flash_init) { + diag_printf("Sorry, no FLASH memory is available\n"); + return; + } + memcpy(backup_config, config, sizeof(struct _config)); script = (unsigned char *)0; init_opts(&opts[0], 'l', false, OPTION_ARG_TYPE_FLG, @@ -1507,8 +1488,8 @@ do_flash_config(int argc, char *argv[]) config_init(); } - dp = &config.config_data[0]; - while (dp < &config.config_data[sizeof(config.config_data)]) { + dp = &config->config_data[0]; + while (dp < &config->config_data[sizeof(config->config_data)]) { if (CONFIG_OBJECT_TYPE(dp) == CONFIG_EMPTY) { break; } @@ -1534,7 +1515,7 @@ do_flash_config(int argc, char *argv[]) case CONFIG_DONE: goto done; case CONFIG_ABORT: - memcpy(&config, &hold_config, sizeof(config)); + memcpy(config, backup_config, sizeof(struct _config)); return; case CONFIG_CHANGED: need_update = true; @@ -1542,7 +1523,7 @@ do_flash_config(int argc, char *argv[]) dp += len; break; case CONFIG_BACK: - dp = &config.config_data[0]; + dp = &config->config_data[0]; continue; case CONFIG_BAD: // Nothing - make him do it again @@ -1607,7 +1588,7 @@ do_alias(int argc, char *argv[]) opt.enable = (char *)0; opt.enable_sense = 1; opt.key = name; - opt.dflt = (unsigned long)argv[2]; + opt.dflt = (CYG_ADDRESS)argv[2]; flash_add_config(&opt, true); break; default: @@ -1615,20 +1596,64 @@ do_alias(int argc, char *argv[]) } } +// Lookup an alias. First try plain string aliases. If that fails try +// other types so allowing access to all configured values. This allows +// for alias (macro) expansion of normal 'fconfig' data, such as the +// board IP address. static char * -lookup_alias(char *alias) +lookup_alias(char *alias, char *alias_buf) { char name[80]; char *val; + unsigned char * dp; + void *val_ptr; + int type; + bool hold_bool_val; + long hold_long_val; + int esa_ptr; make_alias(name, alias); if (flash_get_config(name, &val, CONFIG_STRING)) { return val; } else { + dp = flash_lookup_config(alias); + if (dp) { + val_ptr = (void *)CONFIG_OBJECT_VALUE(dp); + switch (type = CONFIG_OBJECT_TYPE(dp)) { + case CONFIG_BOOL: + memcpy(&hold_bool_val, val_ptr, sizeof(bool)); + diag_sprintf(alias_buf, "%s", hold_bool_val ? "true" : "false"); + break; + case CONFIG_INT: + memcpy(&hold_long_val, val_ptr, sizeof(unsigned long)); + diag_sprintf(alias_buf,"%ld", hold_long_val); + break; +#ifdef CYGPKG_REDBOOT_NETWORKING + case CONFIG_IP: + diag_sprintf(alias_buf,"%s", inet_ntoa((in_addr_t *)val_ptr)); + break; + case CONFIG_ESA: + for (esa_ptr = 0; esa_ptr < sizeof(enet_addr_t); esa_ptr++) { + diag_sprintf(alias_buf+(3*esa_ptr), "0x%02X", ((unsigned char *)val_ptr)[esa_ptr]); + if (esa_ptr < (sizeof(enet_addr_t)-1)) diag_printf(":"); + } + break; +#endif + case CONFIG_SCRIPT: + return (char *) val_ptr; + break; + default: + return (char *)NULL; + } + return alias_buf; + } return (char *)NULL; } } +// Expand aliases, this is recursive. ie if one alias contains other +// aliases, these will also be expanded from the insertion point +// onwards. bool _expand_aliases(char *line, int len) { @@ -1637,6 +1662,7 @@ bool char *alias; char c; int offset, line_len, alias_len; + char alias_buf[MAX_STRING_LENGTH]; bool macro_found = false; if ((line_len = strlen(line)) != 0) { @@ -1655,18 +1681,26 @@ bool me = lp; *me = '\0'; lp++; - if ((alias = lookup_alias(ms)) != (char *)NULL) { + if ((alias = lookup_alias(ms,alias_buf)) != (char *)NULL) { alias_len = strlen(alias); // See if there is room in the line to expand this macro/alias if ((line_len+alias_len) < len) { // Make a hole by moving data within the line offset = alias_len-strlen(ms)-2; // Number of bytes being inserted - ep = &lp[strlen(lp)-1]; - me = &ep[offset]; - while (ep != (lp-1)) { - ep[offset-1] = *ep--; - } - *me = '\0'; + ep = &lp[strlen(lp)-1]; + if (offset > 1) { + ep[offset] = '\0'; + while (ep != (lp-1)) { + ep[offset-1] = *ep--; + } + } else { + if (offset <=0) { + while ((lp-1) != ep) { + lp[offset-1] = *lp++; + } + lp[offset-1]='\0'; + } + } // Insert the macro/alias data lp = ms-2; while (*alias) { @@ -1674,6 +1708,7 @@ bool *lp++ = *alias++; } line_len = strlen(line); + lp = lp - alias_len; } else { diag_printf("No room to expand '%s'\n", ms); line[0] = '\0'; // Destroy line @@ -1708,17 +1743,10 @@ flash_write_config(void) int stat; void *err_addr; - config.len = sizeof(config); - config.key1 = CONFIG_KEY1; - config.key2 = CONFIG_KEY2; - config.cksum = crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)); - if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { - cfg_base = (void *)((unsigned long)flash_end + - (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); - } else { - cfg_base = (void *)((unsigned long)flash_start + - (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); - } + config->len = sizeof(struct _config); + config->key1 = CONFIG_KEY1; + config->key2 = CONFIG_KEY2; + config->cksum = crc32((unsigned char *)config, sizeof(struct _config)-sizeof(config->cksum)); if (verify_action("Update RedBoot non-volatile configuration")) { #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the config page is unlocked before trying to update @@ -1727,8 +1755,8 @@ flash_write_config(void) if ((stat = flash_erase(cfg_base, cfg_size, (void **)&err_addr)) != 0) { diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); } else { - if ((stat = flash_program(cfg_base, (void *)&config, - sizeof(config), (void **)&err_addr)) != 0) { + if ((stat = flash_program(cfg_base, (void *)config, sizeof(struct _config), + (void **)&err_addr)) != 0) { diag_printf("Error writing config data at %p: %s\n", err_addr, flash_errmsg(stat)); } @@ -1751,8 +1779,8 @@ flash_lookup_config(char *key) if (!config_ok) return (unsigned char *)NULL; - dp = &config.config_data[0]; - while (dp < &config.config_data[sizeof(config.config_data)]) { + dp = &config->config_data[0]; + while (dp < &config->config_data[sizeof(config->config_data)]) { len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) + config_length(CONFIG_OBJECT_TYPE(dp)); if (strcmp(key, CONFIG_OBJECT_KEY(dp)) == 0) { @@ -1857,9 +1885,9 @@ flash_add_config(struct config_option *o return true; } // Add the data item - dp = &config.config_data[0]; + dp = &config->config_data[0]; size = 0; - while (size < sizeof(config.config_data)) { + while (size < sizeof(config->config_data)) { if (CONFIG_OBJECT_TYPE(dp) == CONFIG_EMPTY) { kp = opt->key; len = strlen(kp) + 1; @@ -1870,7 +1898,7 @@ flash_add_config(struct config_option *o } else { elen = 0; } - if (size > sizeof(config.config_data)) { + if (size > sizeof(config->config_data)) { break; } CONFIG_OBJECT_TYPE(dp) = opt->type; @@ -1911,7 +1939,7 @@ config_init(void) struct config_option *optend = __CONFIG_options_TAB_END__; struct config_option *opt = __CONFIG_options_TAB__; - memset(&config, 0, sizeof(config)); + memset(config, 0, sizeof(struct _config)); while (opt != optend) { if (!flash_add_config(opt, false)) { return; @@ -1934,19 +1962,24 @@ load_flash_config(void) config_ok = false; script = (unsigned char *)0; if (!do_flash_init()) return; + config = (struct _config *)(workspace_end-sizeof(struct _config)); + backup_config = (struct _config *)((CYG_ADDRESS)config-sizeof(struct _config)); + workspace_end = (unsigned char *)backup_config; #define _roundup(n,s) ((((n)+(s-1))/s)*s) - cfg_size = (block_size > sizeof(config)) ? sizeof(config) : - _roundup(sizeof(config), block_size); + cfg_size = (block_size > sizeof(struct _config)) ? + sizeof(struct _config) : + _roundup(sizeof(struct _config), block_size); if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { - cfg_base = (void *)((unsigned long)flash_end + + cfg_base = (void *)((CYG_ADDRESS)flash_end + 1 + (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); } else { - cfg_base = (void *)((unsigned long)flash_start + + cfg_base = (void *)((CYG_ADDRESS)flash_start + (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); } - memcpy(&config, cfg_base, sizeof(config)); - if ((crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)) != config.cksum) || - (config.key1 != CONFIG_KEY1)|| (config.key2 != CONFIG_KEY2)) { + memcpy(config, cfg_base, sizeof(struct _config)); + if ((crc32((unsigned char *)config, + sizeof(struct _config)-sizeof(config->cksum)) != config->cksum) || + (config->key1 != CONFIG_KEY1)|| (config->key2 != CONFIG_KEY2)) { diag_printf("FLASH configuration checksum error or invalid key\n"); config_init(); return;
