Index: /ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/tftp_server.c =================================================================== --- /ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/tftp_server.c (revision 12407) +++ /ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/tftp_server.c (revision 12429) @@ -111,6 +111,5 @@ #if defined(CYGPKG_HAL_MIPS_AR2316) #if FISTYPE == 1 - *(volatile unsigned *)0xB1000090 |= 1; /*set GPIO0 to 1 to spi flash CS normal state */ - *(volatile unsigned *)0xB1000098 |= 1; /*set GPIO0 to be output */ + set_gpio(0,1); page_programming_supported = 1; page_gpio = 0; @@ -118,6 +117,5 @@ #if FISTYPE == 2 - *(volatile unsigned *)0xB1000090 |= 1 << 3; /*set GPIO0 to 1 to spi flash CS normal state */ - *(volatile unsigned *)0xB1000098 |= 1 << 3; /*set GPIO0 to be output */ + set_gpio(3,1); page_programming_supported = 1; page_gpio = 3; Index: /ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/main.c =================================================================== --- /ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/main.c (revision 12409) +++ /ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/main.c (revision 12429) @@ -159,4 +159,22 @@ int in_rescue_mode = 0; + +void set_gpio(int gpio,int state) +{ +#if defined(CYGPKG_HAL_MIPS_AR2316) + *(volatile unsigned *)AR2316_GPIO_CR |= 1< #include -#include // assertion macros - +#include // assertion macros +#include "ramconfig.h" //#define CYGPRI_REDBOOT_7ZIP_FLASH 1; @@ -89,9 +89,6 @@ // Image management functions local_cmd_entry("init", - "Initialize FLASH Image System [FIS]", - "[-f]", - fis_init_comp, - FIS_cmds - ); + "Initialize FLASH Image System [FIS]", + "[-f]", fis_init_comp, FIS_cmds); #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK # define FIS_LIST_OPTS "[-c] [-d]" @@ -100,9 +97,6 @@ #endif local_cmd_entry("list", - "Display contents of FLASH Image System [FIS]", - FIS_LIST_OPTS, - fis_list, - FIS_cmds - ); + "Display contents of FLASH Image System [FIS]", + FIS_LIST_OPTS, fis_list, FIS_cmds); /*local_cmd_entry("free", "Display free [available] locations within FLASH Image System [FIS]", @@ -120,42 +114,32 @@ int page_gpio = 0; -static char fis_load_usage[] = +static char fis_load_usage[] = #ifdef CYGPRI_REDBOOT_ZLIB_FLASH - "[-d] " + "[-d] " #endif #ifdef CYGPRI_REDBOOT_7ZIP_FLASH - "[-l] " -#endif - - "[-b ] [-c] name"; + "[-l] " +#endif + "[-b ] [-c] name"; local_cmd_entry("load", - "Load image from FLASH Image System [FIS] into RAM", - fis_load_usage, - fis_load, - FIS_cmds - ); + "Load image from FLASH Image System [FIS] into RAM", + fis_load_usage, fis_load, FIS_cmds); local_cmd_entry("create", - "Create an image", - "-b -l [-s ]\n" - " [-f ] [-e ] [-r ] [-n] ", - fis_create, - FIS_cmds - ); + "Create an image", + "-b -l [-s ]\n" + " [-f ] [-e ] [-r ] [-n] ", + fis_create, FIS_cmds); #if defined(CYGPKG_HAL_MIPS_AR2316) local_cmd_entry("create256", - "Create an image", - "-b -l [-s ]\n" - " [-f ] [-e ] [-r ] [-n] ", - fis_create_256, - FIS_cmds - ); + "Create an image", + "-b -l [-s ]\n" + " [-f ] [-e ] [-r ] [-n] ", + fis_create_256, FIS_cmds); local_cmd_entry("createaccton", - "Create an image", - "-b -l [-s ]\n" - " [-f ] [-e ] [-r ] [-n] ", - fis_create_accton, - FIS_cmds - ); + "Create an image", + "-b -l [-s ]\n" + " [-f ] [-e ] [-r ] [-n] ", + fis_create_accton, FIS_cmds); #endif #endif @@ -170,15 +154,9 @@ #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING local_cmd_entry("lock", - "LOCK FLASH contents", - "[-f -l ] [name]", - fis_lock, - FIS_cmds - ); + "LOCK FLASH contents", + "[-f -l ] [name]", fis_lock, FIS_cmds); local_cmd_entry("unlock", - "UNLOCK FLASH contents", - "[-f -l ] [name]", - fis_unlock, - FIS_cmds - ); + "UNLOCK FLASH contents", + "[-f -l ] [name]", fis_unlock, FIS_cmds); #endif /*local_cmd_entry("write", @@ -190,6 +168,6 @@ // Define table boundaries -CYG_HAL_TABLE_BEGIN( __FIS_cmds_TAB__, FIS_cmds); -CYG_HAL_TABLE_END( __FIS_cmds_TAB_END__, FIS_cmds); +CYG_HAL_TABLE_BEGIN(__FIS_cmds_TAB__, FIS_cmds); +CYG_HAL_TABLE_END(__FIS_cmds_TAB_END__, FIS_cmds); extern struct cmd __FIS_cmds_TAB__[], __FIS_cmds_TAB_END__; @@ -197,10 +175,7 @@ // CLI function static cmd_fun do_fis; -RedBoot_nested_cmd("fis", - "Manage FLASH images", - "{cmds}", - do_fis, - __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__ - ); +RedBoot_nested_cmd("fis", + "Manage FLASH images", + "{cmds}", do_fis, __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__); // Local data used by these routines @@ -210,9 +185,9 @@ void *fis_work_block; void *fis_addr; -int fisdir_size; // Size of FIS directory. +int fisdir_size; // Size of FIS directory. #endif #ifdef CYGSEM_REDBOOT_FLASH_CONFIG -extern void *cfg_base; // Location in Flash of config data -extern int cfg_size; // Length of config data - rounded to Flash block size +extern void *cfg_base; // Location in Flash of config data +extern int cfg_size; // Length of config data - rounded to Flash block size extern struct _config *config; #endif @@ -221,36 +196,35 @@ #define VXWORKS_BOARD_CFG_DATA 0xbfde0000 #define VXWORKS_RADIO_CFG_DATA 0xbfdf0000 -#define CONSOLIDATED_DATA 0xbfdf0000 +#define CONSOLIDATED_DATA 0xbfdf0000 #define END_OF_FLASH 0xbffff000 #elif CYGNUM_FLASH_SIZE == 0x400000 #define VXWORKS_BOARD_CFG_DATA 0xbffe0000 #define VXWORKS_RADIO_CFG_DATA 0xbfff0000 -#define CONSOLIDATED_DATA 0xbfff0000 +#define CONSOLIDATED_DATA 0xbfff0000 #define END_OF_FLASH 0xbffff000 #elif CYGNUM_FLASH_SIZE == 0x800000 #define VXWORKS_BOARD_CFG_DATA 0xbffe0000 #define VXWORKS_RADIO_CFG_DATA 0xbfff0000 -#define CONSOLIDATED_DATA 0xbfff0000 +#define CONSOLIDATED_DATA 0xbfff0000 #define END_OF_FLASH 0xbffff000 #else #Warning! Currently works for only 2MB and 4MB -#endif // CYGNUM_FLASH_SIZE +#endif // CYGNUM_FLASH_SIZE #define HEURISTIC_SEARCH_LEN 0x60000 #define MAGIC_DATA 0x35333131 - -static void -fis_usage(char *why) -{ - diag_printf("*** invalid 'fis' command: %s\n", 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); +static void fis_usage(char *why) +{ + diag_printf("*** invalid 'fis' command: %s\n", 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); } @@ -262,973 +236,1079 @@ { #ifdef REDBOOT_FLASH_REVERSE_BYTEORDER - struct fis_image_desc *p = addr; - int cnt = fisdir_size / sizeof(struct fis_image_desc); - - while (cnt-- > 0) { - p->flash_base = CYG_SWAP32(p->flash_base); - p->mem_base = CYG_SWAP32(p->mem_base); - p->size = CYG_SWAP32(p->size); - p->entry_point = CYG_SWAP32(p->entry_point); - p->data_length = CYG_SWAP32(p->data_length); - p->desc_cksum = CYG_SWAP32(p->desc_cksum); - p->file_cksum = CYG_SWAP32(p->file_cksum); - p++; - } -#endif -} - -void -fis_read_directory(void) -{ - void *err_addr; - - FLASH_READ(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); - fis_endian_fixup(fis_work_block); -} - -struct fis_image_desc * -fis_lookup(char *name, int *num) -{ - int i; - struct fis_image_desc *img; - - fis_read_directory(); - - img = (struct fis_image_desc *)fis_work_block; - for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { - if ((img->name[0] != (unsigned char)0xFF) && - (strcasecmp(name, img->name) == 0)) { - if (num) *num = i; - return img; - } - } - return (struct fis_image_desc *)0; -} - -void -fis_update_directory(void) -{ - int stat; - void *err_addr; - - fis_endian_fixup(fis_work_block); + struct fis_image_desc *p = addr; + int cnt = fisdir_size / sizeof(struct fis_image_desc); + + while (cnt-- > 0) { + p->flash_base = CYG_SWAP32(p->flash_base); + p->mem_base = CYG_SWAP32(p->mem_base); + p->size = CYG_SWAP32(p->size); + p->entry_point = CYG_SWAP32(p->entry_point); + p->data_length = CYG_SWAP32(p->data_length); + p->desc_cksum = CYG_SWAP32(p->desc_cksum); + p->file_cksum = CYG_SWAP32(p->file_cksum); + p++; + } +#endif +} + +void fis_read_directory(void) +{ + void *err_addr; + + FLASH_READ(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + fis_endian_fixup(fis_work_block); +} + +struct fis_image_desc *fis_lookup(char *name, int *num) +{ + int i; + struct fis_image_desc *img; + + fis_read_directory(); + + img = (struct fis_image_desc *)fis_work_block; + for (i = 0; i < fisdir_size / sizeof(*img); i++, img++) { + if ((img->name[0] != (unsigned char)0xFF) && + (strcasecmp(name, img->name) == 0)) { + if (num) + *num = i; + return img; + } + } + return (struct fis_image_desc *)0; +} + +void fis_update_directory(void) +{ + int stat; + void *err_addr; + + fis_endian_fixup(fis_work_block); #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG - memcpy((char *)fis_work_block+fisdir_size, config, cfg_size); - conf_endian_fixup((char *)fis_work_block+fisdir_size); + memcpy((char *)fis_work_block + fisdir_size, config, cfg_size); + conf_endian_fixup((char *)fis_work_block + fisdir_size); #endif #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL - // Ensure [quietly] that the directory is unlocked before trying to update - flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr); -#endif - if ((stat = flash_erase(fis_addr, flash_block_size, (void **)&err_addr)) != 0) { - diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat)); - } else { - if ((stat = FLASH_PROGRAM(fis_addr, fis_work_block, - flash_block_size, (void **)&err_addr)) != 0) { - diag_printf("Error writing FIS directory at %p: %s\n", - err_addr, flash_errmsg(stat)); - } - } + // Ensure [quietly] that the directory is unlocked before trying to update + flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr); +#endif + if ((stat = + flash_erase(fis_addr, flash_block_size, + (void **)&err_addr)) != 0) { + diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, + flash_errmsg(stat)); + } else { + if ((stat = FLASH_PROGRAM(fis_addr, fis_work_block, + flash_block_size, + (void **)&err_addr)) != 0) { + diag_printf("Error writing FIS directory at %p: %s\n", + err_addr, flash_errmsg(stat)); + } + } #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL - // Ensure [quietly] that the directory is locked after the update - flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr); -#endif - fis_endian_fixup(fis_work_block); -} -void fis_init(int argc, char *argv[],int force); + // Ensure [quietly] that the directory is locked after the update + flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr); +#endif + fis_endian_fixup(fis_work_block); +} + +void fis_init(int argc, char *argv[], int force); static void fis_init_comp(int argc, char *argv[]) { -fis_init(argc, argv,0); -} -void fis_init(int argc, char *argv[],int force) -{ - int stat; - struct fis_image_desc *img; - void *err_addr; - bool full_init = false; - struct option_info opts[1]; - 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"); - if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) - { - return; - } - - if (!force && !verify_action("About to initialize [format] FLASH image system")) { - diag_printf("** Aborted\n"); - return; - } - diag_printf("*** Initialize FLASH Image System\n"); - + fis_init(argc, argv, 0); +} + +void fis_init(int argc, char *argv[], int force) +{ + int stat; + struct fis_image_desc *img; + void *err_addr; + bool full_init = false; + struct option_info opts[1]; + 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"); + if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) { + return; + } + + if (!force + && + !verify_action("About to initialize [format] FLASH image system")) { + diag_printf("** Aborted\n"); + return; + } + diag_printf("*** Initialize FLASH Image System\n"); #define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE - redboot_image_size = flash_block_size > MIN_REDBOOT_IMAGE_SIZE ? - flash_block_size : MIN_REDBOOT_IMAGE_SIZE; - - // Create a pseudo image for RedBoot - img = (struct fis_image_desc *)fis_work_block; - memset(img, 0xFF, fisdir_size); // Start with erased data + redboot_image_size = flash_block_size > MIN_REDBOOT_IMAGE_SIZE ? + flash_block_size : MIN_REDBOOT_IMAGE_SIZE; + + // Create a pseudo image for RedBoot + img = (struct fis_image_desc *)fis_work_block; + memset(img, 0xFF, fisdir_size); // Start with erased data #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE - memset(img, 0, sizeof(*img)); - strcpy(img->name, "(reserved)"); - 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 = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; + memset(img, 0, sizeof(*img)); + strcpy(img->name, "(reserved)"); + 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 = + (CYG_ADDRESS) flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; #ifdef CYGOPT_REDBOOT_FIS_REDBOOT - memset(img, 0, sizeof(*img)); - strcpy(img->name, "RedBoot"); - img->flash_base = redboot_flash_start; - img->mem_base = redboot_flash_start; - img->size = redboot_image_size; - img++; - redboot_flash_start += redboot_image_size; + memset(img, 0, sizeof(*img)); + strcpy(img->name, "RedBoot"); + img->flash_base = redboot_flash_start; + img->mem_base = redboot_flash_start; + img->size = redboot_image_size; + img++; + redboot_flash_start += redboot_image_size; #endif #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 = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET; -#endif - memset(img, 0, sizeof(*img)); - strcpy(img->name, "RedBoot[post]"); - img->flash_base = redboot_flash_start; - img->mem_base = redboot_flash_start; - img->size = redboot_image_size; - img++; - redboot_flash_start += redboot_image_size; + // Take care to place the POST entry at the right 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]"); + img->flash_base = redboot_flash_start; + img->mem_base = redboot_flash_start; + img->size = redboot_image_size; + img++; + redboot_flash_start += redboot_image_size; #endif #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP - // And a backup image - memset(img, 0, sizeof(*img)); - strcpy(img->name, "RedBoot[backup]"); - img->flash_base = redboot_flash_start; - img->mem_base = redboot_flash_start; - img->size = redboot_image_size; - img++; - redboot_flash_start += redboot_image_size; + // And a backup image + memset(img, 0, sizeof(*img)); + strcpy(img->name, "RedBoot[backup]"); + img->flash_base = redboot_flash_start; + img->mem_base = redboot_flash_start; + img->size = redboot_image_size; + img++; + redboot_flash_start += redboot_image_size; #endif #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH) - // And a descriptor for the configuration data - memset(img, 0, sizeof(*img)); - strcpy(img->name, "RedBoot config"); - 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"); - img->flash_base = (CYG_ADDRESS)fis_addr; - img->mem_base = (CYG_ADDRESS)fis_addr; - img->size = fisdir_size; - img++; + // And a descriptor for the configuration data + memset(img, 0, sizeof(*img)); + strcpy(img->name, "RedBoot config"); + 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"); + img->flash_base = (CYG_ADDRESS) fis_addr; + img->mem_base = (CYG_ADDRESS) fis_addr; + img->size = fisdir_size; + img++; #ifdef CYGOPT_REDBOOT_FIS_DIRECTORY_ARM_SIB_ID - // FIS gets the size of a full block - note, this should be changed - // if support is added for multi-block FIS structures. - img = (struct fis_image_desc *)((CYG_ADDRESS)fis_work_block + fisdir_size); - // Add a footer so the FIS will be recognized by the ARM Boot - // Monitor as a reserved area. - { - tFooter* footer_p = (tFooter*)((CYG_ADDRESS)img - sizeof(tFooter)); - cyg_uint32 check = 0; - cyg_uint32 *check_ptr = (cyg_uint32 *)footer_p; - cyg_int32 count = (sizeof(tFooter) - 4) >> 2; - - // Prepare footer. Try to protect all but the reserved space - // and the first RedBoot image (which is expected to be - // bootable), but fall back to just protecting the FIS if it's - // not at the default position in the flash. + // FIS gets the size of a full block - note, this should be changed + // if support is added for multi-block FIS structures. + img = + (struct fis_image_desc *)((CYG_ADDRESS) fis_work_block + + fisdir_size); + // Add a footer so the FIS will be recognized by the ARM Boot + // Monitor as a reserved area. + { + tFooter *footer_p = + (tFooter *) ((CYG_ADDRESS) img - sizeof(tFooter)); + cyg_uint32 check = 0; + cyg_uint32 *check_ptr = (cyg_uint32 *) footer_p; + cyg_int32 count = (sizeof(tFooter) - 4) >> 2; + + // Prepare footer. Try to protect all but the reserved space + // and the first RedBoot image (which is expected to be + // bootable), but fall back to just protecting the FIS if it's + // not at the default position in the flash. #if defined(CYGOPT_REDBOOT_FIS_RESERVED_BASE) && (-1 == CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK) - footer_p->blockBase = (char*)_ADDR_REDBOOT_TO_ARM(flash_start); - footer_p->blockBase += CYGNUM_REDBOOT_FLASH_RESERVED_BASE + redboot_image_size; + footer_p->blockBase = (char *)_ADDR_REDBOOT_TO_ARM(flash_start); + footer_p->blockBase += + CYGNUM_REDBOOT_FLASH_RESERVED_BASE + redboot_image_size; #else - footer_p->blockBase = (char*)_ADDR_REDBOOT_TO_ARM(fis_work_block); -#endif - footer_p->infoBase = NULL; - footer_p->signature = FLASH_FOOTER_SIGNATURE; - footer_p->type = TYPE_REDHAT_REDBOOT; - - // and compute its checksum - for ( ; count > 0; count--) { - if (*check_ptr > ~check) - check++; - check += *check_ptr++; - } - footer_p->checksum = ~check; - } -#endif - - // Do this after creating the initialized table because that inherently - // calculates where the high water mark of default RedBoot images is. - - if (full_init) { - 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: + footer_p->blockBase = + (char *)_ADDR_REDBOOT_TO_ARM(fis_work_block); +#endif + footer_p->infoBase = NULL; + footer_p->signature = FLASH_FOOTER_SIGNATURE; + footer_p->type = TYPE_REDHAT_REDBOOT; + + // and compute its checksum + for (; count > 0; count--) { + if (*check_ptr > ~check) + check++; + check += *check_ptr++; + } + footer_p->checksum = ~check; + } +#endif + + // Do this after creating the initialized table because that inherently + // calculates where the high water mark of default RedBoot images is. + + if (full_init) { + 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: #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, - (void **)&err_addr)) != 0) { - diag_printf(" initialization failed at %p: %s\n", - 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. + 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, + (void **)&err_addr)) != 0) { + diag_printf + (" initialization failed at %p: %s\n", + 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. #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && \ defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH) && \ !defined(CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG) - if (fis_addr > cfg_base) { - erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between HWM and config data - } else { - 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", - err_addr, flash_errmsg(stat)); - } - erase_start += (erase_size + flash_block_size); - if (fis_addr > cfg_base) { - erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between config and fis data - } else { - 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) { - diag_printf(" initialization failed %p: %s\n", - err_addr, flash_errmsg(stat)); - } - erase_start += (erase_size + flash_block_size); -#else // !CYGSEM_REDBOOT_FLASH_CONFIG - 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", - err_addr, flash_errmsg(stat)); - } - erase_start += (erase_size + flash_block_size); -#endif - // Lastly, anything at the end, if there is any - if ( erase_start < (((CYG_ADDRESS)flash_end)+1) ) { - 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", - err_addr, flash_errmsg(stat)); - } - } + if (fis_addr > cfg_base) { + erase_size = (CYG_ADDRESS) cfg_base - erase_start; // the gap between HWM and config data + } else { + 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", + err_addr, flash_errmsg(stat)); + } + erase_start += (erase_size + flash_block_size); + if (fis_addr > cfg_base) { + erase_size = (CYG_ADDRESS) fis_addr - erase_start; // the gap between config and fis data + } else { + 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) { + diag_printf(" initialization failed %p: %s\n", + err_addr, flash_errmsg(stat)); + } + erase_start += (erase_size + flash_block_size); +#else // !CYGSEM_REDBOOT_FLASH_CONFIG + 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", + err_addr, flash_errmsg(stat)); + } + erase_start += (erase_size + flash_block_size); +#endif + // Lastly, anything at the end, if there is any + if (erase_start < (((CYG_ADDRESS) flash_end) + 1)) { + 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", + err_addr, flash_errmsg(stat)); + } + } #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS - // In this case, 'fis free' works by scanning for erased blocks. Since the - // "-f" option was not supplied, there may be areas which are not used but - // don't appear to be free since they are not erased - thus the warning - } else { - diag_printf(" Warning: device contents not erased, some blocks may not be usable\n"); -#endif - } - fis_update_directory(); -} - -static void -fis_list(int argc, char *argv[]) -{ - struct fis_image_desc *img; - int i, image_indx; - bool show_cksums = false; - bool show_datalen = false; - struct option_info opts[2]; - unsigned long last_addr, lowest_addr; - bool image_found; + // In this case, 'fis free' works by scanning for erased blocks. Since the + // "-f" option was not supplied, there may be areas which are not used but + // don't appear to be free since they are not erased - thus the warning + } else { + diag_printf + (" Warning: device contents not erased, some blocks may not be usable\n"); +#endif + } + fis_update_directory(); +} + +static void fis_list(int argc, char *argv[]) +{ + struct fis_image_desc *img; + int i, image_indx; + bool show_cksums = false; + bool show_datalen = false; + struct option_info opts[2]; + unsigned long last_addr, lowest_addr; + bool image_found; #ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB - // FIXME: this is somewhat half-baked - extern void arm_fis_list(void); - arm_fis_list(); - return; -#endif - - init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG, - (void *)&show_datalen, (bool *)0, "display data length"); + // FIXME: this is somewhat half-baked + extern void arm_fis_list(void); + arm_fis_list(); + return; +#endif + + init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG, + (void *)&show_datalen, (bool *) 0, "display data length"); #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK - init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, - (void *)&show_cksums, (bool *)0, "display checksums"); - i = 2; + init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, + (void *)&show_cksums, (bool *) 0, "display checksums"); + i = 2; #else - i = 1; -#endif - if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { - return; - } - fis_read_directory(); - - // Let diag_printf do the formatting in both cases, rather than counting - // cols by hand.... - diag_printf("%-16s %-10s %-10s %-10s %-s\n", - "Name","FLASH addr", - show_cksums ? "Checksum" : "Mem addr", - show_datalen ? "Datalen" : "Length", - "Entry point" ); - last_addr = 0; - image_indx = 0; - do { - image_found = false; - lowest_addr = 0xFFFFFFFF; - img = (struct fis_image_desc *) fis_work_block; - for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { - if (img->name[0] != (unsigned char)0xFF) { - if ((img->flash_base > last_addr) && (img->flash_base < lowest_addr)) { - lowest_addr = img->flash_base; - image_found = true; - image_indx = i; - } - } - } - if (image_found) { - img = (struct fis_image_desc *) fis_work_block; - img += image_indx; - diag_printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img->name, - img->flash_base, + i = 1; +#endif + if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { + return; + } + fis_read_directory(); + + // Let diag_printf do the formatting in both cases, rather than counting + // cols by hand.... + diag_printf("%-16s %-10s %-10s %-10s %-s\n", + "Name", "FLASH addr", + show_cksums ? "Checksum" : "Mem addr", + show_datalen ? "Datalen" : "Length", "Entry point"); + last_addr = 0; + image_indx = 0; + do { + image_found = false; + lowest_addr = 0xFFFFFFFF; + img = (struct fis_image_desc *)fis_work_block; + for (i = 0; i < fisdir_size / sizeof(*img); i++, img++) { + if (img->name[0] != (unsigned char)0xFF) { + if ((img->flash_base > last_addr) + && (img->flash_base < lowest_addr)) { + lowest_addr = img->flash_base; + image_found = true; + image_indx = i; + } + } + } + if (image_found) { + img = (struct fis_image_desc *)fis_work_block; + img += image_indx; + diag_printf + ("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", + img->name, img->flash_base, #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK - show_cksums ? img->file_cksum : img->mem_base, - show_datalen ? img->data_length : img->size, + show_cksums ? img->file_cksum : img->mem_base, + show_datalen ? img->data_length : img->size, #else - img->mem_base, - img->size, -#endif - img->entry_point); - } - last_addr = lowest_addr; - } while (image_found == true); + img->mem_base, img->size, +#endif + img->entry_point); + } + last_addr = lowest_addr; + } while (image_found == true); } #ifdef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS struct free_chunk { - CYG_ADDRESS start, end; + CYG_ADDRESS start, end; }; -static int -find_free(struct free_chunk *chunks) -{ - CYG_ADDRESS *fis_ptr, *fis_end; - struct fis_image_desc *img; - int i, idx; - int num_chunks = 1; - - // Do not search the area reserved for pre-RedBoot systems: - fis_ptr = (CYG_ADDRESS *)((CYG_ADDRESS)flash_start + - CYGNUM_REDBOOT_FLASH_RESERVED_BASE + - CYGBLD_REDBOOT_MIN_IMAGE_SIZE); - fis_end = (CYG_ADDRESS *)flash_end; - chunks[num_chunks-1].start = (CYG_ADDRESS)fis_ptr; - chunks[num_chunks-1].end = (CYG_ADDRESS)fis_end; - fis_read_directory(); - img = (struct fis_image_desc *) fis_work_block; - for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { - if (img->name[0] != (unsigned char)0xFF) { - // Figure out which chunk this is in and split it - for (idx = 0; idx < num_chunks; idx++) { - if ((img->flash_base >= chunks[idx].start) && - (img->flash_base <= chunks[idx].end)) { - if (img->flash_base == chunks[idx].start) { - chunks[idx].start += img->size; - if (chunks[idx].start >= chunks[idx].end) { - // This free chunk has collapsed - while (idx < (num_chunks-1)) { - chunks[idx] = chunks[idx+1]; - idx++; - } - num_chunks--; - } - } else if ((img->flash_base+img->size) == chunks[idx].end) { - chunks[idx].end = img->flash_base; - } else { - // Split chunk into two parts - if ((img->flash_base+img->size) < (CYG_ADDRESS)fis_end) { - chunks[idx+1].start = img->flash_base + img->size; - chunks[idx+1].end = chunks[idx].end; - if (++num_chunks == CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) { - diag_printf("Warning: too many free chunks\n"); - return num_chunks; - } - } - chunks[idx].end = img->flash_base; - } - break; - } - } - } - } - return num_chunks; -} -#endif // CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS - +static int find_free(struct free_chunk *chunks) +{ + CYG_ADDRESS *fis_ptr, *fis_end; + struct fis_image_desc *img; + int i, idx; + int num_chunks = 1; + + // Do not search the area reserved for pre-RedBoot systems: + fis_ptr = (CYG_ADDRESS *) ((CYG_ADDRESS) flash_start + + CYGNUM_REDBOOT_FLASH_RESERVED_BASE + + CYGBLD_REDBOOT_MIN_IMAGE_SIZE); + fis_end = (CYG_ADDRESS *) flash_end; + chunks[num_chunks - 1].start = (CYG_ADDRESS) fis_ptr; + chunks[num_chunks - 1].end = (CYG_ADDRESS) fis_end; + fis_read_directory(); + img = (struct fis_image_desc *)fis_work_block; + for (i = 0; i < fisdir_size / sizeof(*img); i++, img++) { + if (img->name[0] != (unsigned char)0xFF) { + // Figure out which chunk this is in and split it + for (idx = 0; idx < num_chunks; idx++) { + if ((img->flash_base >= chunks[idx].start) && + (img->flash_base <= chunks[idx].end)) { + if (img->flash_base == + chunks[idx].start) { + chunks[idx].start += img->size; + if (chunks[idx].start >= + chunks[idx].end) { + // This free chunk has collapsed + while (idx < + (num_chunks - + 1)) { + chunks[idx] = + chunks[idx + + 1]; + idx++; + } + num_chunks--; + } + } else if ((img->flash_base + img->size) + == chunks[idx].end) { + chunks[idx].end = + img->flash_base; + } else { + // Split chunk into two parts + if ((img->flash_base + + img->size) < + (CYG_ADDRESS) fis_end) { + chunks[idx + 1].start = + img->flash_base + + img->size; + chunks[idx + 1].end = + chunks[idx].end; + if (++num_chunks == + CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) + { + diag_printf + ("Warning: too many free chunks\n"); + return + num_chunks; + } + } + chunks[idx].end = + img->flash_base; + } + break; + } + } + } + } + return num_chunks; +} +#endif // CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS // Find the first unused area of flash which is long enough -static bool -fis_find_free(CYG_ADDRESS *addr, unsigned long length) +static bool fis_find_free(CYG_ADDRESS * addr, unsigned long length) { #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS - unsigned long *fis_ptr, *fis_end, flash_data; - unsigned long *area_start; - void *err_addr; - - // Do not search the area reserved for pre-RedBoot systems: - fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + - CYGNUM_REDBOOT_FLASH_RESERVED_BASE + - CYGBLD_REDBOOT_MIN_IMAGE_SIZE); - fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; - area_start = fis_ptr; - while (fis_ptr < fis_end) { - flash_read(fis_ptr, &flash_data, sizeof(unsigned long), (void **)&err_addr); - if (flash_data != (unsigned long)0xFFFFFFFF) { - if (area_start != fis_ptr) { - // Assume that this is something - if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { - *addr = (CYG_ADDRESS)area_start; - return true; - } - } - // Find next blank block - area_start = fis_ptr; - while (area_start < fis_end) { - flash_read(area_start, &flash_data, sizeof(unsigned long), (void **)&err_addr); - if (flash_data == (unsigned long)0xFFFFFFFF) { - break; - } - area_start += flash_block_size / sizeof(CYG_ADDRESS); - } - fis_ptr = area_start; - } else { - fis_ptr += flash_block_size / sizeof(CYG_ADDRESS); - } - } - if (area_start != fis_ptr) { - if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { - *addr = (CYG_ADDRESS)area_start; - return true; - } - } - return false; + unsigned long *fis_ptr, *fis_end, flash_data; + unsigned long *area_start; + void *err_addr; + + // Do not search the area reserved for pre-RedBoot systems: + fis_ptr = (unsigned long *)((CYG_ADDRESS) flash_start + + CYGNUM_REDBOOT_FLASH_RESERVED_BASE + + CYGBLD_REDBOOT_MIN_IMAGE_SIZE); + fis_end = (unsigned long *)(CYG_ADDRESS) flash_end; + area_start = fis_ptr; + while (fis_ptr < fis_end) { + flash_read(fis_ptr, &flash_data, sizeof(unsigned long), + (void **)&err_addr); + if (flash_data != (unsigned long)0xFFFFFFFF) { + if (area_start != fis_ptr) { + // Assume that this is something + if ((fis_ptr - area_start) >= + (length / sizeof(unsigned))) { + *addr = (CYG_ADDRESS) area_start; + return true; + } + } + // Find next blank block + area_start = fis_ptr; + while (area_start < fis_end) { + flash_read(area_start, &flash_data, + sizeof(unsigned long), + (void **)&err_addr); + if (flash_data == (unsigned long)0xFFFFFFFF) { + break; + } + area_start += + flash_block_size / sizeof(CYG_ADDRESS); + } + fis_ptr = area_start; + } else { + fis_ptr += flash_block_size / sizeof(CYG_ADDRESS); + } + } + if (area_start != fis_ptr) { + if ((fis_ptr - area_start) >= (length / sizeof(unsigned))) { + *addr = (CYG_ADDRESS) area_start; + return true; + } + } + return false; #else - struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; - int idx, num_chunks; - - num_chunks = find_free(chunks); - for (idx = 0; idx < num_chunks; idx++) { - if ((chunks[idx].end - chunks[idx].start) >= length) { - *addr = (CYG_ADDRESS)chunks[idx].start; - return true; - } - } - return false; -#endif -} - -static void -fis_create_old(int argc, char *argv[]) -{ - int i, stat; - 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; - bool entry_addr_set = false; - bool flash_addr_set = false; - bool length_set = false; - bool img_size_set = false; - bool no_copy = false; - void *err_addr; - struct fis_image_desc *img = NULL; - bool defaults_assumed; - struct option_info opts[7]; - bool prog_ok = true; - - init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, - (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); - init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, - (void *)&exec_addr, (bool *)&exec_addr_set, "ram base address"); - init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, - (void *)&entry_addr, (bool *)&entry_addr_set, "entry point address"); - init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, - (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); - init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, - (void *)&length, (bool *)&length_set, "image length [in FLASH]"); - init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, - (void *)&img_size, (bool *)&img_size_set, "image size [actual data]"); - init_opts(&opts[6], 'n', false, OPTION_ARG_TYPE_FLG, - (void *)&no_copy, (bool *)0, "don't copy from RAM to FLASH, just update directory"); - if (!scan_opts(argc, argv, 2, opts, 7, (void *)&name, OPTION_ARG_TYPE_STR, "file name")) - { - fis_usage("invalid arguments"); - return; - } - - fis_read_directory(); - defaults_assumed = false; - if (name) { - // Search existing files to acquire defaults for params not specified: - img = fis_lookup(name, NULL); - if (img) { - // Found it, so get image size from there - if (!length_set) { - length_set = true; - length = img->size; - defaults_assumed = true; - } - } - } - if (!mem_addr_set && (load_address >= (CYG_ADDRESS)ram_start) && - (load_address_end) < (CYG_ADDRESS)ram_end) { - mem_addr = load_address; - mem_addr_set = true; - defaults_assumed = true; - // Get entry address from loader, unless overridden - if (!entry_addr_set) - entry_addr = entry_address; - if (!length_set) { - length = load_address_end - load_address; - length_set = true; - } else if (defaults_assumed && !img_size_set) { - /* We got length from the FIS table, so the size of the - actual loaded image becomes img_size */ - img_size = load_address_end - load_address; - img_size_set = true; - } - } - // Get the remaining fall-back values from the fis - if (img) { - if (!exec_addr_set) { - // Preserve "normal" behaviour - exec_addr_set = true; - exec_addr = flash_addr_set ? flash_addr : mem_addr; - } - if (!flash_addr_set) { - flash_addr_set = true; - flash_addr = img->flash_base; - defaults_assumed = true; - } - } - - if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) || - !length_set || !name) { - fis_usage("required parameter missing"); - return; - } - if (!img_size_set) { - img_size = length; - } - // 'length' is size of FLASH image, 'img_size' is actual data size - // Round up length to FLASH block size -#ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken - length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size; - if (length < img_size) { - diag_printf("Invalid FLASH image size/length combination\n"); - return; - } -#endif - if (flash_addr_set && - ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - _show_invalid_flash_address(flash_addr, stat); - return; - } - if (flash_addr_set && ((flash_addr & (flash_block_size-1)) != 0)) { - diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); - diag_printf(" must be 0x%x aligned\n", flash_block_size); - return; - } - if (strlen(name) >= sizeof(img->name)) { - diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); - return; - } - if (!no_copy) { - 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); - } - if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { - diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); - return; - } - } - // First, see if the image by this name has agreable properties - if (img) { - if (flash_addr_set && (img->flash_base != flash_addr)) { - diag_printf("Image found, but flash address (%p)\n" - " is incorrect (present image location %p)\n", - flash_addr, img->flash_base); - - return; - } - if (img->size != length) { - diag_printf("Image found, but length (0x%lx, necessitating image size 0x%lx)\n" - " is incorrect (present image size 0x%lx)\n", - img_size, length, img->size); - return; - } - if (!verify_action("An image named '%s' exists", name)) { - return; - } else { - if (defaults_assumed) { - if (no_copy && - !verify_action("* CAUTION * about to program '%s'\n at %p..%p from %p", - name, (void *)flash_addr, (void *)(flash_addr+img_size-1), - (void *)mem_addr)) { - return; // The guy gave up - } - } - } - } else { + struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; + int idx, num_chunks; + + num_chunks = find_free(chunks); + for (idx = 0; idx < num_chunks; idx++) { + if ((chunks[idx].end - chunks[idx].start) >= length) { + *addr = (CYG_ADDRESS) chunks[idx].start; + return true; + } + } + return false; +#endif +} + +static void fis_create_old(int argc, char *argv[]) +{ + int i, stat; + 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; + bool entry_addr_set = false; + bool flash_addr_set = false; + bool length_set = false; + bool img_size_set = false; + bool no_copy = false; + void *err_addr; + struct fis_image_desc *img = NULL; + bool defaults_assumed; + struct option_info opts[7]; + bool prog_ok = true; + + init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, + (void *)&mem_addr, (bool *) & mem_addr_set, + "memory base address"); + init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, (void *)&exec_addr, + (bool *) & exec_addr_set, "ram base address"); + init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, (void *)&entry_addr, + (bool *) & entry_addr_set, "entry point address"); + init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, (void *)&flash_addr, + (bool *) & flash_addr_set, "FLASH memory base address"); + init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, (void *)&length, + (bool *) & length_set, "image length [in FLASH]"); + init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, (void *)&img_size, + (bool *) & img_size_set, "image size [actual data]"); + init_opts(&opts[6], 'n', false, OPTION_ARG_TYPE_FLG, (void *)&no_copy, + (bool *) 0, + "don't copy from RAM to FLASH, just update directory"); + if (!scan_opts + (argc, argv, 2, opts, 7, (void *)&name, OPTION_ARG_TYPE_STR, + "file name")) { + fis_usage("invalid arguments"); + return; + } + + fis_read_directory(); + defaults_assumed = false; + if (name) { + // Search existing files to acquire defaults for params not specified: + img = fis_lookup(name, NULL); + if (img) { + // Found it, so get image size from there + if (!length_set) { + length_set = true; + length = img->size; + defaults_assumed = true; + } + } + } + if (!mem_addr_set && (load_address >= (CYG_ADDRESS) ram_start) && + (load_address_end) < (CYG_ADDRESS) ram_end) { + mem_addr = load_address; + mem_addr_set = true; + defaults_assumed = true; + // Get entry address from loader, unless overridden + if (!entry_addr_set) + entry_addr = entry_address; + if (!length_set) { + length = load_address_end - load_address; + length_set = true; + } else if (defaults_assumed && !img_size_set) { + /* We got length from the FIS table, so the size of the + actual loaded image becomes img_size */ + img_size = load_address_end - load_address; + img_size_set = true; + } + } + // Get the remaining fall-back values from the fis + if (img) { + if (!exec_addr_set) { + // Preserve "normal" behaviour + exec_addr_set = true; + exec_addr = flash_addr_set ? flash_addr : mem_addr; + } + if (!flash_addr_set) { + flash_addr_set = true; + flash_addr = img->flash_base; + defaults_assumed = true; + } + } + + if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) || + !length_set || !name) { + fis_usage("required parameter missing"); + return; + } + if (!img_size_set) { + img_size = length; + } + // 'length' is size of FLASH image, 'img_size' is actual data size + // Round up length to FLASH block size +#ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken + length = + ((length + flash_block_size - + 1) / flash_block_size) * flash_block_size; + if (length < img_size) { + diag_printf("Invalid FLASH image size/length combination\n"); + return; + } +#endif + if (flash_addr_set && + ((stat = flash_verify_addr((void *)flash_addr)) || + (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { + _show_invalid_flash_address(flash_addr, stat); + return; + } + if (flash_addr_set && ((flash_addr & (flash_block_size - 1)) != 0)) { + diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); + diag_printf(" must be 0x%x aligned\n", flash_block_size); + return; + } + if (strlen(name) >= sizeof(img->name)) { + diag_printf("Name is too long, must be less than %d chars\n", + (int)sizeof(img->name)); + return; + } + if (!no_copy) { + 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); + } + if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { + diag_printf + ("Can't locate %lx(%ld) bytes free in FLASH\n", + length, length); + return; + } + } + // First, see if the image by this name has agreable properties + if (img) { + if (flash_addr_set && (img->flash_base != flash_addr)) { + diag_printf("Image found, but flash address (%p)\n" + " is incorrect (present image location %p)\n", + flash_addr, img->flash_base); + + return; + } + if (img->size != length) { + diag_printf + ("Image found, but length (0x%lx, necessitating image size 0x%lx)\n" + " is incorrect (present image size 0x%lx)\n", + img_size, length, img->size); + return; + } + if (!verify_action("An image named '%s' exists", name)) { + return; + } else { + if (defaults_assumed) { + if (no_copy && + !verify_action + ("* CAUTION * about to program '%s'\n at %p..%p from %p", + name, (void *)flash_addr, + (void *)(flash_addr + img_size - 1), + (void *)mem_addr)) { + return; // The guy gave up + } + } + } + } else { #ifdef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS - // Make sure that any FLASH address specified directly is truly free - if (flash_addr_set && !no_copy) { - struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; - int idx, num_chunks; - bool is_free = false; - - num_chunks = find_free(chunks); - for (idx = 0; idx < num_chunks; idx++) { - if ((flash_addr >= chunks[idx].start) && - ((flash_addr+length-1) <= chunks[idx].end)) { - is_free = true; - } - } - if (!is_free) { - diag_printf("Invalid FLASH address - not free!\n"); - return; - } - } -#endif - // If not image by that name, try and find an empty slot - img = (struct fis_image_desc *)fis_work_block; - for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { - if (img->name[0] == (unsigned char)0xFF) { - break; - } - } - } - if (!no_copy) { - // Safety check - make sure the address range is not within the code we're running - if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { - diag_printf("Can't program this region - contains code in use!\n"); - return; - } - if (prog_ok) { - // Erase area to be programmed - if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { - diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); - prog_ok = false; - } - } - if (prog_ok) { - // Now program it - if ((stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { - diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); - prog_ok = false; - } - } - } - if (prog_ok) { - // Update directory - memset(img, 0, sizeof(*img)); - 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 : (CYG_ADDRESS)entry_address; // Hope it's been set - img->size = length; - img->data_length = img_size; + // Make sure that any FLASH address specified directly is truly free + if (flash_addr_set && !no_copy) { + struct free_chunk + chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; + int idx, num_chunks; + bool is_free = false; + + num_chunks = find_free(chunks); + for (idx = 0; idx < num_chunks; idx++) { + if ((flash_addr >= chunks[idx].start) && + ((flash_addr + length - 1) <= + chunks[idx].end)) { + is_free = true; + } + } + if (!is_free) { + diag_printf + ("Invalid FLASH address - not free!\n"); + return; + } + } +#endif + // If not image by that name, try and find an empty slot + img = (struct fis_image_desc *)fis_work_block; + for (i = 0; i < fisdir_size / sizeof(*img); i++, img++) { + if (img->name[0] == (unsigned char)0xFF) { + break; + } + } + } + if (!no_copy) { + // Safety check - make sure the address range is not within the code we're running + if (flash_code_overlaps + ((void *)flash_addr, (void *)(flash_addr + img_size - 1))) { + diag_printf + ("Can't program this region - contains code in use!\n"); + return; + } + if (prog_ok) { + // Erase area to be programmed + if ((stat = + flash_erase((void *)flash_addr, length, + (void **)&err_addr)) != 0) { + diag_printf("Can't erase region at %p: %s\n", + err_addr, flash_errmsg(stat)); + prog_ok = false; + } + } + if (prog_ok) { + // Now program it + if ((stat = + FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, + img_size, + (void **)&err_addr)) != 0) { + diag_printf("Can't program region at %p: %s\n", + err_addr, flash_errmsg(stat)); + prog_ok = false; + } + } + } + if (prog_ok) { + // Update directory + memset(img, 0, sizeof(*img)); + 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 : (CYG_ADDRESS) entry_address; // Hope it's been set + img->size = length; + img->data_length = img_size; #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK - if (!no_copy) { - img->file_cksum = cyg_crc32((unsigned char *)mem_addr, img_size); - } else { - // No way to compute this, sorry - img->file_cksum = 0; - } -#endif - fis_update_directory(); - } + if (!no_copy) { + img->file_cksum = + cyg_crc32((unsigned char *)mem_addr, img_size); + } else { + // No way to compute this, sorry + img->file_cksum = 0; + } +#endif + fis_update_directory(); + } } #if defined(CYGPKG_HAL_MIPS_AR2316) -static void -fis_create_accton(int argc, char *argv[]) -{ -*(volatile unsigned*)0xB1000090 |= 1;/*set GPIO0 to 1 to spi flash CS normal state*/ -*(volatile unsigned*)0xB1000098 |= 1;/*set GPIO0 to be output*/ -page_programming_supported = 1; -page_gpio = 0; -fis_create_old(argc,argv); - -} -static void -fis_create_256(int argc, char *argv[]) -{ -*(volatile unsigned*)0xB1000090 |= 1<<3;/*set GPIO0 to 1 to spi flash CS normal state*/ -*(volatile unsigned*)0xB1000098 |= 1<<3;/*set GPIO0 to be output*/ -page_programming_supported = 1; -page_gpio = 3; -fis_create_old(argc,argv); - -} -#endif -static void -fis_create(int argc, char *argv[]) -{ -page_programming_supported = 0; -page_gpio = 0; -fis_create_old(argc,argv); +static void fis_create_accton(int argc, char *argv[]) +{ + set_gpio(0,1); + page_programming_supported = 1; + page_gpio = 0; + fis_create_old(argc, argv); + +} + +static void fis_create_256(int argc, char *argv[]) +{ + set_gpio(3,1); + page_programming_supported = 1; + page_gpio = 3; + fis_create_old(argc, argv); + +} +#endif +static void fis_create(int argc, char *argv[]) +{ + page_programming_supported = 0; + page_gpio = 0; + fis_create_old(argc, argv); } extern void arm_fis_delete(char *); -static void -fis_load(int argc, char *argv[]) -{ - char *name; - struct fis_image_desc *img; - CYG_ADDRESS mem_addr; - bool mem_addr_set = false; - bool show_cksum = false; - struct option_info opts[3]; +static void fis_load(int argc, char *argv[]) +{ + char *name; + struct fis_image_desc *img; + CYG_ADDRESS mem_addr; + bool mem_addr_set = false; + bool show_cksum = false; + struct option_info opts[3]; #if defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) - unsigned long cksum; -#endif - int num_options; + unsigned long cksum; +#endif + int num_options; #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) || defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) - bool decompress = false; + bool decompress = false; #endif #if defined(CYGPRI_REDBOOT_7ZIP_FLASH) - bool ldecompress = false; -#endif - void *err_addr; - - init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, - (void *)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address"); - init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, - (void *)&show_cksum, (bool *)0, "display checksum"); - num_options = 2; + bool ldecompress = false; +#endif + void *err_addr; + + init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, + (void *)&mem_addr, (bool *) & mem_addr_set, + "memory [load] base address"); + init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, + (void *)&show_cksum, (bool *) 0, "display checksum"); + num_options = 2; #ifdef CYGPRI_REDBOOT_ZLIB_FLASH - init_opts(&opts[num_options], 'd', false, OPTION_ARG_TYPE_FLG, - (void *)&decompress, 0, "decompress"); - num_options++; + init_opts(&opts[num_options], 'd', false, OPTION_ARG_TYPE_FLG, + (void *)&decompress, 0, "decompress"); + num_options++; #endif #ifdef CYGPRI_REDBOOT_7ZIP_FLASH - init_opts(&opts[num_options], 'l', false, OPTION_ARG_TYPE_FLG, - (void *)&ldecompress, 0, "lzma"); - num_options++; -#endif - - CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); - - if (!scan_opts(argc, argv, 2, opts, num_options, (void *)&name, OPTION_ARG_TYPE_STR, "image name")) - { - fis_usage("invalid arguments"); - return; - } - if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) { - diag_printf("No image '%s' found\n", name); - return; - } - if (!mem_addr_set) { - mem_addr = img->mem_base; - } - // Load image from FLASH into RAM + init_opts(&opts[num_options], 'l', false, OPTION_ARG_TYPE_FLG, + (void *)&ldecompress, 0, "lzma"); + num_options++; +#endif + + CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); + + if (!scan_opts + (argc, argv, 2, opts, num_options, (void *)&name, + OPTION_ARG_TYPE_STR, "image name")) { + fis_usage("invalid arguments"); + return; + } + if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) { + diag_printf("No image '%s' found\n", name); + return; + } + if (!mem_addr_set) { + mem_addr = img->mem_base; + } + // Load image from FLASH into RAM #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS - if (!valid_address((void *)mem_addr)) { - diag_printf("Not a loadable image - try using -b ADDRESS option\n"); - return; - } + if (!valid_address((void *)mem_addr)) { + diag_printf + ("Not a loadable image - try using -b ADDRESS option\n"); + return; + } #endif #if defined(CYGPRI_REDBOOT_7ZIP_FLASH) - if (ldecompress) { - unsigned char *in_buf,*out_buf; - unsigned out_buf_len,in_buf_len; - int res; - in_buf = (unsigned char*) img->flash_base; - out_buf = (unsigned char*) mem_addr; - in_buf_len = img->data_length; - res = lzma_decode(in_buf,out_buf,in_buf_len,&out_buf_len); - if ( res!= 0 ) { - diag_printf("lzma_decode failed. res=%d\n",res); - }else { - diag_printf("Image loaded from %p-%p\n", out_buf,out_buf+out_buf_len); - } - load_address = mem_addr; - load_address_end = mem_addr + out_buf_len ; - fis_read_directory(); - } else + if (ldecompress) { + unsigned char *in_buf, *out_buf; + unsigned out_buf_len, in_buf_len; + int res; + in_buf = (unsigned char *)img->flash_base; + out_buf = (unsigned char *)mem_addr; + in_buf_len = img->data_length; + res = lzma_decode(in_buf, out_buf, in_buf_len, &out_buf_len); + if (res != 0) { + diag_printf("lzma_decode failed. res=%d\n", res); + } else { + diag_printf("Image loaded from %p-%p\n", out_buf, + out_buf + out_buf_len); + } + load_address = mem_addr; + load_address_end = mem_addr + out_buf_len; + fis_read_directory(); + } else #endif #ifdef CYGPRI_REDBOOT_ZLIB_FLASH - if (decompress) { - int err; - _pipe_t fis_load_pipe; - _pipe_t* p = &fis_load_pipe; - p->out_buf = (unsigned char*) mem_addr; - p->out_max = p->out_size = -1; - p->in_buf = (unsigned char*) img->flash_base; - p->in_avail = img->data_length; - - err = (*_dc_init)(p); - - if (0 == err) - err = (*_dc_inflate)(p); - - // Free used resources, do final translation of - // error value. - err = (*_dc_close)(p, err); - - if (0 != err && p->msg) { - diag_printf("decompression error: %s\n", p->msg); - } else { - diag_printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf); - } - - // Set load address/top - load_address = mem_addr; - load_address_end = (unsigned long)p->out_buf; - - // Reload fis directory - fis_read_directory(); - } else // dangling block -#endif - { - flash_read((void *)img->flash_base, (void *)mem_addr, img->data_length, (void **)&err_addr); - - // Set load address/top - load_address = mem_addr; - load_address_end = mem_addr + img->data_length; - } - entry_address = (unsigned long)img->entry_point; + if (decompress) { + int err; + _pipe_t fis_load_pipe; + _pipe_t *p = &fis_load_pipe; + p->out_buf = (unsigned char *)mem_addr; + p->out_max = p->out_size = -1; + p->in_buf = (unsigned char *)img->flash_base; + p->in_avail = img->data_length; + + err = (*_dc_init) (p); + + if (0 == err) + err = (*_dc_inflate) (p); + + // Free used resources, do final translation of + // error value. + err = (*_dc_close) (p, err); + + if (0 != err && p->msg) { + diag_printf("decompression error: %s\n", p->msg); + } else { + diag_printf("Image loaded from %p-%p\n", + (unsigned char *)mem_addr, p->out_buf); + } + + // Set load address/top + load_address = mem_addr; + load_address_end = (unsigned long)p->out_buf; + + // Reload fis directory + fis_read_directory(); + } else // dangling block +#endif + { + flash_read((void *)img->flash_base, (void *)mem_addr, + img->data_length, (void **)&err_addr); + + // Set load address/top + load_address = mem_addr; + load_address_end = mem_addr + img->data_length; + } + entry_address = (unsigned long)img->entry_point; #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK - cksum = cyg_crc32((unsigned char *)mem_addr, img->data_length); - if (show_cksum) { - diag_printf("Checksum: 0x%08lx\n", cksum); - } - // When decompressing, leave CRC checking to decompressor - if (!decompress && !ldecompress && img->file_cksum) { - if (cksum != img->file_cksum) { - diag_printf("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", - img->file_cksum, cksum); - entry_address = (unsigned long)NO_MEMORY; - } - } -#endif -} -#endif // CYGOPT_REDBOOT_FIS - - - + cksum = cyg_crc32((unsigned char *)mem_addr, img->data_length); + if (show_cksum) { + diag_printf("Checksum: 0x%08lx\n", cksum); + } + // When decompressing, leave CRC checking to decompressor + if (!decompress && !ldecompress && img->file_cksum) { + if (cksum != img->file_cksum) { + diag_printf + ("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", + img->file_cksum, cksum); + entry_address = (unsigned long)NO_MEMORY; + } + } +#endif +} +#endif // CYGOPT_REDBOOT_FIS // This is set non-zero if the FLASH subsystem has successfully been initialized int __flash_init = 0; -void -_flash_info(void) -{ - if (!__flash_init) return; - diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", - flash_start, (CYG_ADDRWORD)flash_end + 1, flash_num_blocks, (void *)flash_block_size); -} - -bool -do_flash_init(void) -{ - int stat; - - if (!__flash_init) { - __flash_init = 1; - if ((stat = flash_init(diag_printf)) != 0) { - diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); - 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(&flash_block_size, &flash_num_blocks); +void _flash_info(void) +{ + if (!__flash_init) + return; + diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", + flash_start, (CYG_ADDRWORD) flash_end + 1, flash_num_blocks, + (void *)flash_block_size); +} + +void diag_blink(void) +{ +#ifdef LEDCODE + static int counter = 0; + unsigned char leds[] = { + LED1_PIN, +#if LED2_PIN != 0xff + LED2_PIN, +#endif +#if LED3_PIN != 0xff + LED3_PIN, +#endif +#if LED4_PIN != 0xff + LED4_PIN, +#endif + }; + int len = sizeof(leds); + int i; + if (len == 1) { + set_gpio(LED1_PIN, (counter++) % 2); + } else { + for (i = 0; i < len; i++) { + set_gpio(leds[i], 0); + } + set_gpio(leds[counter++], 1); + if (counter == len) + counter = 0; + } +#endif +} + +bool do_flash_init(void) +{ + int stat; + + if (!__flash_init) { + __flash_init = 1; + if ((stat = flash_init(diag_printf)) != 0) { + diag_printf("FLASH: driver init failed: %s\n", + flash_errmsg(stat)); + 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(&flash_block_size, &flash_num_blocks); #ifdef CYGOPT_REDBOOT_FIS - fisdir_size = CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE; - fisdir_size = ((fisdir_size + flash_block_size - 1) / flash_block_size) * flash_block_size; + fisdir_size = + CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * + CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE; + fisdir_size = + ((fisdir_size + flash_block_size - + 1) / flash_block_size) * flash_block_size; # if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER) - fis_work_block = fis_zlib_common_buffer; - if(CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE < fisdir_size) { - diag_printf("FLASH: common buffer too small\n"); - return false; - } + fis_work_block = fis_zlib_common_buffer; + if (CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE < fisdir_size) { + diag_printf("FLASH: common buffer too small\n"); + return false; + } # else - workspace_end = (unsigned char *)(workspace_end-fisdir_size); - fis_work_block = workspace_end; + workspace_end = (unsigned char *)(workspace_end - fisdir_size); + fis_work_block = workspace_end; # endif - if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { - fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); - } else { - fis_addr = (void *)((CYG_ADDRESS)flash_start + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); - } - if (((CYG_ADDRESS)fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) { - diag_printf("FIS directory doesn't fit\n"); - return false; - } - fis_read_directory(); -#endif - } - return true; + if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { + fis_addr = (void *)((CYG_ADDRESS) flash_end + 1 + + (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK + * flash_block_size)); + } else { + fis_addr = (void *)((CYG_ADDRESS) flash_start + + (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK + * flash_block_size)); + } + if (((CYG_ADDRESS) fis_addr + fisdir_size - 1) > + (CYG_ADDRESS) flash_end) { + diag_printf("FIS directory doesn't fit\n"); + return false; + } + fis_read_directory(); +#endif + } + return true; } // Wrapper to avoid compiler warnings -static void -_do_flash_init(void) -{ - static int init_done = 0; - if (init_done) return; - init_done = 1; - do_flash_init(); +static void _do_flash_init(void) +{ + static int init_done = 0; + if (init_done) + return; + init_done = 1; + do_flash_init(); } RedBoot_init(_do_flash_init, RedBoot_INIT_FIRST); -static void -do_fis(int argc, char *argv[]) -{ - struct cmd *cmd; - - if (argc < 2) { - fis_usage("too few arguments"); - return; - } - if (!do_flash_init()) { - diag_printf("Sorry, no FLASH memory is available\n"); - return; - } - if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, - argv[1])) != (struct cmd *)0) { - (cmd->fun)(argc, argv); - return; - } - fis_usage("unrecognized command"); +static void do_fis(int argc, char *argv[]) +{ + struct cmd *cmd; + + if (argc < 2) { + fis_usage("too few arguments"); + return; + } + if (!do_flash_init()) { + diag_printf("Sorry, no FLASH memory is available\n"); + return; + } + if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, + argv[1])) != (struct cmd *)0) { + (cmd->fun) (argc, argv); + return; + } + fis_usage("unrecognized command"); } Index: /ar5315_microredboot/microredboot/ecos/packages/devs/flash/atheros/spiflash/current/src/spiflash.c =================================================================== --- /ar5315_microredboot/microredboot/ecos/packages/devs/flash/atheros/spiflash/current/src/spiflash.c (revision 12281) +++ /ar5315_microredboot/microredboot/ecos/packages/devs/flash/atheros/spiflash/current/src/spiflash.c (revision 12429) @@ -314,4 +314,5 @@ opcode = (PAGE_PROGRAM_OPCODE) | ((cyg_uint32)offset << 8); HAL_WRITE_UINT32(AR2316_SPI_OPCODE, opcode); + if (page_programming_supported) *(volatile unsigned*)0xB1000090 &= ~(1< +#include typedef struct { @@ -237,7 +238,25 @@ }; +static int s_memcmp(unsigned char *p1,unsigned char *p2,unsigned int len) +{ +unsigned int i; +for (i=0;i MAX_PHDR) { + printf("Too many program headers\n"); + return 0; + } + + offset = ehdr.e_phoff; /* =, not += !!! */ + + for (phx = 0; phx < ehdr.e_phnum; phx++) { + + memmove(&phdr[phx], (char *)(flash + offset), + sizeof(Elf32_Phdr)); + + offset += sizeof(Elf32_Phdr); + } + if (base) { + // Set address offset based on lowest address in file. + addr_offset = 0xFFFFFFFF; + for (phx = 0; phx < ehdr.e_phnum; phx++) { + if (phdr[phx].p_vaddr < addr_offset) { + addr_offset = phdr[phx].p_vaddr; + } + } + addr_offset = (unsigned long)base - addr_offset; + } else { + addr_offset = 0; + } + + for (phx = 0; phx < ehdr.e_phnum; phx++) { + if (phdr[phx].p_type == PT_LOAD) { + // Loadable segment + addr = (unsigned char *)phdr[phx].p_vaddr; + len = phdr[phx].p_filesz; + if ((unsigned long)addr < lowest_address) { + lowest_address = (unsigned long)addr; + } + addr += addr_offset; + if (offset > phdr[phx].p_offset) { + if ((phdr[phx].p_offset + len) < offset) { + printf + ("Can't load ELF file - program headers out of order\n"); + return 0; + } + addr += offset - phdr[phx].p_offset; + } else { + offset = phdr[phx].p_offset; /* _=_ */ + } + + memmove((char *)addr, (char *)(flash + offset), len); + offset += len; + len = 0; + + if ((unsigned long)(addr - addr_offset) > + highest_address) { + highest_address = + (unsigned long)(addr - addr_offset); + } + } + } /* for (phx... */ + // Save load base/top and entry + if (base) { + *load_address = base; + *load_address_end = base + (highest_address - lowest_address); + *entry_address = base + (ehdr.e_entry - lowest_address); + } else { + *load_address = lowest_address; + *load_address_end = highest_address; + *entry_address = ehdr.e_entry; + } + + // redboot_getc_terminate(false); + if (addr_offset) + printf("\nAddress offset = 0x%08X\n", (void *)addr_offset); + printf("Entry point: 0x%08X, address range: 0x%08X-0x%08X\n", + (void *)*entry_address, (void *)*load_address, + (void *)*load_address_end); + return 1; +} Index: /ar5315_microredboot/microredboot/boot/src/lib/lib.c =================================================================== --- /ar5315_microredboot/microredboot/boot/src/lib/lib.c (revision 12320) +++ /ar5315_microredboot/microredboot/boot/src/lib/lib.c (revision 12429) @@ -25,2 +25,29 @@ return sc - s; } + +void *memmove( void *s1, const void *s2, size_t n ) +{ + char *dst = (char *)s1; + const char *src = (const char *)s2; + if ((src < dst) && (dst < (src + n))) + { + // Have to copy backwards + src += n; + dst += n; + while (n--) + { + *--dst = *--src; + } + } + else + { + while (n--) + { + *dst++ = *src++; + } + } + + + return s1; +} // __memmove() + Index: /ar5315_microredboot/microredboot/boot/src/lib/elf.h =================================================================== --- /ar5315_microredboot/microredboot/boot/src/lib/elf.h (revision 12429) +++ /ar5315_microredboot/microredboot/boot/src/lib/elf.h (revision 12429) @@ -0,0 +1,710 @@ +#ifndef CYGONCE_REDBOOT_ELF_H +#define CYGONCE_REDBOOT_ELF_H + +//========================================================================== +// +// elf.h +// +// ELF file format definitions +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributors: nickg +// Date: 2000-11-15 +// Purpose: Define ELF file format +// Description: The types defined here describe the ELF file format. +// +// Usage: #include +// +//####DESCRIPTIONEND#### +// +//========================================================================== +// +// Quite a lot of this file was taken from the BSD exec_elf.h header file. +// Hence we should show you this... +// +/* $OpenBSD: exec_elf.h,v 1.20 1999/09/19 16:16:49 kstailey Exp $ */ +/* + * Copyright (c) 1995, 1996 Erik Theisen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +//========================================================================== + + +// ------------------------------------------------------------------------- +// Basic types: + +typedef unsigned int cyg_uint32; +typedef unsigned long long cyg_uint64; +typedef long long cyg_int64; +typedef unsigned short cyg_uint16; +typedef short cyg_int16; +typedef int cyg_int32; + +typedef cyg_uint32 Elf32_Addr; +typedef cyg_uint32 Elf32_Off; +typedef cyg_uint16 Elf32_Half; +typedef cyg_uint32 Elf32_Word; +typedef cyg_int32 Elf32_Sword; + +typedef cyg_uint64 Elf64_Addr; +typedef cyg_uint64 Elf64_Off; +typedef cyg_uint16 Elf64_Half; +typedef cyg_uint32 Elf64_Word; +typedef cyg_int32 Elf64_Sword; +typedef cyg_uint64 Elf64_Xword; +typedef cyg_int64 Elf64_Sxword; + +// ------------------------------------------------------------------------- +// ELF header + +#define EI_NIDENT 16 + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shtrndx; +} Elf32_Ehdr; + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shtrndx; +} Elf64_Ehdr; + +// ------------------------------------------------------------------------- +/* e_ident[] identification indexes */ + +#define EI_MAG0 0 /* file ID */ +#define EI_MAG1 1 /* file ID */ +#define EI_MAG2 2 /* file ID */ +#define EI_MAG3 3 /* file ID */ +#define EI_CLASS 4 /* file class */ +#define EI_DATA 5 /* data encoding */ +#define EI_VERSION 6 /* ELF header version */ +#define EI_OSABI 7 /* Operating system/ABI identification */ +#define EI_ABIVERSION 8 /* ABI version */ +#define EI_PAD 9 /* start of pad bytes */ + +// ------------------------------------------------------------------------- +/* e_ident[] magic number */ + +#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ +#define ELFMAG1 'E' /* e_ident[EI_MAG1] */ +#define ELFMAG2 'L' /* e_ident[EI_MAG2] */ +#define ELFMAG3 'F' /* e_ident[EI_MAG3] */ +#define ELFMAG "\177ELF" /* magic */ +#define SELFMAG 4 /* size of magic */ + +// ------------------------------------------------------------------------- +/* e_ident[] file class */ + +#define ELFCLASSNONE 0 /* invalid */ +#define ELFCLASS32 1 /* 32-bit objs */ +#define ELFCLASS64 2 /* 64-bit objs */ +#define ELFCLASSNUM 3 /* number of classes */ + +// ------------------------------------------------------------------------- +/* e_ident[] data encoding */ + +#define ELFDATANONE 0 /* invalid */ +#define ELFDATA2LSB 1 /* Little-Endian */ +#define ELFDATA2MSB 2 /* Big-Endian */ +#define ELFDATANUM 3 /* number of data encode defines */ + +// ------------------------------------------------------------------------- +/* e_ident */ + +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +// ------------------------------------------------------------------------- +/* e_type */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* relocatable file */ +#define ET_EXEC 2 /* executable file */ +#define ET_DYN 3 /* shared object file */ +#define ET_CORE 4 /* core file */ +#define ET_NUM 5 /* number of types */ +#define ET_LOOS 0xfe00 /* Operating system-specific */ +#define ET_HIOS 0xfeff /* Operating system-specific */ +#define ET_LOPROC 0xff00 /* reserved range for processor */ +#define ET_HIPROC 0xffff /* specific e_type */ + +// ------------------------------------------------------------------------- +/* e_machine */ +// The following values taken from 22 June 2000 SysV ABI spec, updated with +// extra values from binutils elf/common.h. + +#define EM_NONE 0 // No machine +#define EM_M32 1 // AT&T WE 32100 +#define EM_SPARC 2 // SPARC +#define EM_386 3 // Intel 80386 +#define EM_68K 4 // Motorola 68000 +#define EM_88K 5 // Motorola 88000 +#define EM_860 7 // Intel 80860 +#define EM_MIPS 8 // MIPS I Architecture +#define EM_S370 9 // IBM System/370 Processor +#define EM_MIPS_RS3_LE 10 // MIPS RS3000 Little-endian +#define EM_PARISC 15 // Hewlett-Packard PA-RISC +#define EM_VPP500 17 // Fujitsu VPP500 +#define EM_SPARC32PLUS 18 // Enhanced instruction set SPARC +#define EM_960 19 // Intel 80960 +#define EM_PPC 20 // PowerPC +#define EM_PPC64 21 // 64-bit PowerPC +#define EM_V800 36 // NEC V800 +#define EM_FR20 37 // Fujitsu FR20 +#define EM_RH32 38 // TRW RH-32 +#define EM_RCE 39 // Motorola RCE +#define EM_ARM 40 // Advanced RISC Machines ARM +#define EM_ALPHA 41 // Digital Alpha +#define EM_SH 42 // Hitachi SH +#define EM_SPARCV9 43 // SPARC Version 9 +#define EM_TRICORE 44 // Siemens Tricore embedded processor +#define EM_ARC 45 // Argonaut RISC Core, Argonaut Technologies Inc. +#define EM_H8_300 46 // Hitachi H8/300 +#define EM_H8_300H 47 // Hitachi H8/300H +#define EM_H8S 48 // Hitachi H8S +#define EM_H8_500 49 // Hitachi H8/500 +#define EM_IA_64 50 // Intel IA-64 processor architecture +#define EM_MIPS_X 51 // Stanford MIPS-X +#define EM_COLDFIRE 52 // Motorola ColdFire +#define EM_68HC12 53 // Motorola M68HC12 +#define EM_MMA 54 // Fujitsu MMA Multimedia Accelerator +#define EM_PCP 55 // Siemens PCP +#define EM_NCPU 56 // Sony nCPU embedded RISC processor +#define EM_NDR1 57 // Denso NDR1 microprocessor +#define EM_STARCORE 58 // Motorola Star*Core processor +#define EM_ME16 59 // Toyota ME16 processor +#define EM_ST100 60 // STMicroelectronics ST100 processor +#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor family +#define EM_FX66 66 // Siemens FX66 microcontroller +#define EM_ST9PLUS 67 // STMicroelectronics ST9+ 8/16 bit microcontroller +#define EM_ST7 68 // STMicroelectronics ST7 8-bit microcontroller +#define EM_68HC16 69 // Motorola MC68HC16 Microcontroller +#define EM_68HC11 70 // Motorola MC68HC11 Microcontroller +#define EM_68HC08 71 // Motorola MC68HC08 Microcontroller +#define EM_68HC05 72 // Motorola MC68HC05 Microcontroller +#define EM_SVX 73 // Silicon Graphics SVx +#define EM_ST19 74 // STMicroelectronics ST19 8-bit microcontroller +#define EM_VAX 75 // Digital VAX +#define EM_CRIS 76 // Axis Communications 32-bit embedded processor +#define EM_JAVELIN 77 // Infineon Technologies 32-bit embedded processor +#define EM_FIREPATH 78 // Element 14 64-bit DSP Processor +#define EM_ZSP 79 // LSI Logic 16-bit DSP Processor +#define EM_MMIX 80 // Donald Knuth's educational 64-bit processor +#define EM_HUANY 81 // Harvard University machine-independent object files +#define EM_PRISM 82 // SiTera Prism + +/* Cygnus PowerPC ELF backend. Written in the absence of an ABI. */ +#define EM_CYGNUS_POWERPC 0x9025 + +/* Old version of Sparc v9, from before the ABI; this should be + removed shortly. */ +#define EM_OLD_SPARCV9 11 + +/* Old version of PowerPC, this should be removed shortly. */ +#define EM_PPC_OLD 17 + +/* Cygnus ARC ELF backend. Written in the absence of an ABI. */ +#define EM_CYGNUS_ARC 0x9040 + +/* Cygnus M32R ELF backend. Written in the absence of an ABI. */ +#define EM_CYGNUS_M32R 0x9041 + +/* Alpha backend magic number. Written in the absence of an ABI. */ +//#define EM_ALPHA 0x9026 + +/* D10V backend magic number. Written in the absence of an ABI. */ +#define EM_CYGNUS_D10V 0x7650 + +/* D30V backend magic number. Written in the absence of an ABI. */ +#define EM_CYGNUS_D30V 0x7676 + +/* V850 backend magic number. Written in the absense of an ABI. */ +#define EM_CYGNUS_V850 0x9080 + +/* mn10200 and mn10300 backend magic numbers. + Written in the absense of an ABI. */ +#define EM_CYGNUS_MN10200 0xdead +#define EM_CYGNUS_MN10300 0xbeef + +/* FR30 magic number - no EABI available. */ +#define EM_CYGNUS_FR30 0x3330 + +/* AVR magic number + Written in the absense of an ABI. */ +#define EM_AVR 0x1057 + +// ------------------------------------------------------------------------- +/* Version */ + +#define EV_NONE 0 /* Invalid */ +#define EV_CURRENT 1 /* Current */ +#define EV_NUM 2 /* number of versions */ + +// ------------------------------------------------------------------------- +/* Section Header */ + +typedef struct { + Elf32_Word sh_name; /* name - index into section header + string table section */ + Elf32_Word sh_type; /* type */ + Elf32_Word sh_flags; /* flags */ + Elf32_Addr sh_addr; /* address */ + Elf32_Off sh_offset; /* file offset */ + Elf32_Word sh_size; /* section size */ + Elf32_Word sh_link; /* section header table index link */ + Elf32_Word sh_info; /* extra information */ + Elf32_Word sh_addralign; /* address alignment */ + Elf32_Word sh_entsize; /* section entry size */ +} Elf32_Shdr; + +typedef struct { + Elf64_Word sh_name; /* section name */ + Elf64_Word sh_type; /* section type */ + Elf64_Xword sh_flags; /* section flags */ + Elf64_Addr sh_addr; /* virtual address */ + Elf64_Off sh_offset; /* file offset */ + Elf64_Xword sh_size; /* section size */ + Elf64_Word sh_link; /* link to another */ + Elf64_Word sh_info; /* misc info */ + Elf64_Xword sh_addralign; /* memory alignment */ + Elf64_Xword sh_entsize; /* table entry size */ +} Elf64_Shdr; + +// ------------------------------------------------------------------------- +/* Special Section Indexes */ + +#define SHN_UNDEF 0 /* undefined */ +#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ +#define SHN_LOPROC 0xff00 /* reserved range for processor */ +#define SHN_HIPROC 0xff1f /* specific section indexes */ +#define SHN_LOOS 0xff20 /* reserved range for operating */ +#define SHN_HIOS 0xff3f /* system specific section indexes */ +#define SHN_ABS 0xfff1 /* absolute value */ +#define SHN_COMMON 0xfff2 /* common symbol */ +#define SHN_XINDEX 0xffff /* escape value for oversize index */ +#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ + +// ------------------------------------------------------------------------- +/* sh_type */ + +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_INIT_ARRAY 14 /* init procedure array */ +#define SHT_FINI_ARRAY 15 /* fini procedure array */ +#define SHT_PREINIT_ARRAY 16 /* preinit procedure array */ +#define SHT_GROUP 17 /* section group */ +#define SHT_SYMTAB_SHNDX 18 /* oversize index table */ +#define SHT_NUM 19 /* number of section types */ +#define SHT_LOOS 0x60000000 /* reserved range for O/S */ +#define SHT_HIOS 0x6fffffff /* specific section header types */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +// ------------------------------------------------------------------------- +/* Section names */ + +#define ELF_BSS ".bss" /* uninitialized data */ +#define ELF_DATA ".data" /* initialized data */ +#define ELF_DEBUG ".debug" /* debug */ +#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ +#define ELF_DYNSTR ".dynstr" /* dynamic string table */ +#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ +#define ELF_FINI ".fini" /* termination code */ +#define ELF_GOT ".got" /* global offset table */ +#define ELF_HASH ".hash" /* symbol hash table */ +#define ELF_INIT ".init" /* initialization code */ +#define ELF_REL_DATA ".rel.data" /* relocation data */ +#define ELF_REL_FINI ".rel.fini" /* relocation termination code */ +#define ELF_REL_INIT ".rel.init" /* relocation initialization code */ +#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ +#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ +#define ELF_REL_TEXT ".rel.text" /* relocation code */ +#define ELF_RODATA ".rodata" /* read-only data */ +#define ELF_SHSTRTAB ".shstrtab" /* section header string table */ +#define ELF_STRTAB ".strtab" /* string table */ +#define ELF_SYMTAB ".symtab" /* symbol table */ +#define ELF_TEXT ".text" /* code */ + +// ------------------------------------------------------------------------- +/* Section Attribute Flags - sh_flags */ + +#define SHF_WRITE 0x001 /* Writable */ +#define SHF_ALLOC 0x002 /* occupies memory */ +#define SHF_EXECINSTR 0x004 /* executable */ +#define SHF_MERGE 0x010 /* merge data */ +#define SHF_STRINGS 0x020 /* contains strings */ +#define SHF_INFO_LINK 0x040 /* link in sh_info field */ +#define SHF_LINK_ORDER 0x080 /* preserve link order */ +#define SHF_OS_NONCONFORMING 0x100 /* special OS-specific */ + /* processing needed */ +#define SHF_GROUP 0x200 /* member of group */ +#define SHF_MASKOS 0x0ff00000 /* reserved bits for OS */ + /* specific section attributes */ +#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ + /* specific section attributes */ + +// ------------------------------------------------------------------------- +/* Symbol Table Entry */ + +typedef struct { + Elf32_Word st_name; /* name - index into string table */ + Elf32_Addr st_value; /* symbol value */ + Elf32_Word st_size; /* symbol size */ + unsigned char st_info; /* type and binding */ + unsigned char st_other; /* visibility */ + Elf32_Half st_shndx; /* section header index */ +} Elf32_Sym; + +typedef struct { + Elf64_Word st_name; /* Symbol name index in str table */ + unsigned char st_info; /* type / binding attrs */ + unsigned char st_other; /* visibility */ + Elf64_Half st_shndx; /* section index of symbol */ + Elf64_Addr st_value; /* value of symbol */ + Elf64_Xword st_size; /* size of symbol */ +} Elf64_Sym; + +// ------------------------------------------------------------------------- +/* Symbol table index */ + +#define STN_UNDEF 0 /* undefined */ + +/* Extract symbol info - st_info */ +#define ELF32_ST_BIND(x) ((x) >> 4) +#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) +#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) + +#define ELF64_ST_BIND(x) ((x) >> 4) +#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf) +#define ELF64_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) + +#define ELF32_ST_VISIBILITY(o) ((o)&0x3) +#define ELF64_ST_VISIBILITY(o) ((o)&0x3) + +// ------------------------------------------------------------------------- +/* Symbol Binding - ELF32_ST_BIND - st_info */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_NUM 3 /* number of symbol bindings */ +#define STB_LOOS 10 /* reserved range for OS */ +#define STB_HIOS 12 /* specific symbol bindings */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific symbol bindings */ + +// ------------------------------------------------------------------------- +/* Symbol type - ELF32_ST_TYPE - st_info */ + +#define STT_NOTYPE 0 /* not specified */ +#define STT_OBJECT 1 /* data object */ +#define STT_FUNC 2 /* function */ +#define STT_SECTION 3 /* section */ +#define STT_FILE 4 /* file */ +#define STT_COMMON 5 /* common block */ +#define STT_NUM 6 /* number of symbol types */ +#define STT_LOOS 10 /* reserved range for OS */ +#define STT_HIOS 12 /* specific symbol types */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific symbol types */ + +// ------------------------------------------------------------------------- +// symbol visibility in st_other + +#define STV_DEFAULT 0 /* default to binding type */ +#define STV_INTERNAL 1 /* processor specific */ +#define STV_HIDDEN 2 /* invisible */ +#define STV_PROTECTED 3 /* non-premptable */ + +// ------------------------------------------------------------------------- +// 32 bit relocation records + +/* Relocation entry with implicit addend */ +typedef struct +{ + Elf32_Addr r_offset; /* offset of relocation */ + Elf32_Word r_info; /* symbol table index and type */ +} Elf32_Rel; + +/* Relocation entry with explicit addend */ +typedef struct +{ + Elf32_Addr r_offset; /* offset of relocation */ + Elf32_Word r_info; /* symbol table index and type */ + Elf32_Sword r_addend; +} Elf32_Rela; + +/* Extract relocation info - r_info */ +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((unsigned char) (i)) +#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) + +// ------------------------------------------------------------------------- +// 64 bit equivalents of above structures and macros. + +typedef struct { + Elf64_Addr r_offset; /* where to do it */ + Elf64_Xword r_info; /* index & type of relocation */ +} Elf64_Rel; + +typedef struct { + Elf64_Addr r_offset; /* where to do it */ + Elf64_Xword r_info; /* index & type of relocation */ + Elf64_Sxword r_addend; /* adjustment value */ +} Elf64_RelA; + +#define ELF64_R_SYM(info) ((info) >> 32) +#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF) +#define ELF64_R_INFO(s,t) (((s) << 32) + (u_int32_t)(t)) + +// ------------------------------------------------------------------------- +/* Program Header */ + +typedef struct { + Elf32_Word p_type; /* segment type */ + Elf32_Off p_offset; /* segment offset */ + Elf32_Addr p_vaddr; /* virtual address of segment */ + Elf32_Addr p_paddr; /* physical address - ignored? */ + Elf32_Word p_filesz; /* number of bytes in file for seg. */ + Elf32_Word p_memsz; /* number of bytes in mem. for seg. */ + Elf32_Word p_flags; /* flags */ + Elf32_Word p_align; /* memory alignment */ +} Elf32_Phdr; + +typedef struct { + Elf64_Word p_type; /* entry type */ + Elf64_Word p_flags; /* flags */ + Elf64_Off p_offset; /* offset */ + Elf64_Addr p_vaddr; /* virtual address */ + Elf64_Addr p_paddr; /* physical address */ + Elf64_Xword p_filesz; /* file size */ + Elf64_Xword p_memsz; /* memory size */ + Elf64_Xword p_align; /* memory & file alignment */ +} Elf64_Phdr; + +// ------------------------------------------------------------------------- +/* Segment types - p_type */ + +#define PT_NULL 0 /* unused */ +#define PT_LOAD 1 /* loadable segment */ +#define PT_DYNAMIC 2 /* dynamic linking section */ +#define PT_INTERP 3 /* the RTLD */ +#define PT_NOTE 4 /* auxiliary information */ +#define PT_SHLIB 5 /* reserved - purpose undefined */ +#define PT_PHDR 6 /* program header */ +#define PT_NUM 7 /* Number of segment types */ +#define PT_LOOS 0x60000000 /* reserved range for OS */ +#define PT_HIOS 0x6fffffff /* specific segment types */ +#define PT_LOPROC 0x70000000 /* reserved range for processor */ +#define PT_HIPROC 0x7fffffff /* specific segment types */ + +// ------------------------------------------------------------------------- +/* Segment flags - p_flags */ + +#define PF_X 0x1 /* Executable */ +#define PF_W 0x2 /* Writable */ +#define PF_R 0x4 /* Readable */ +#define PF_MASKOS 0x0ff00000 /* reserved bits for OS */ + /* specific segment flags */ +#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ + /* specific segment flags */ + +// ------------------------------------------------------------------------- +/* Dynamic structure */ + +typedef struct { + Elf32_Sword d_tag; /* controls meaning of d_val */ + union { + Elf32_Word d_val; /* Multiple meanings - see d_tag */ + Elf32_Addr d_ptr; /* program virtual address */ + } d_un; +} Elf32_Dyn; + +extern Elf32_Dyn _DYNAMIC[]; /* XXX not 64-bit clean */ + +typedef struct { + Elf64_Sxword d_tag; /* controls meaning of d_val */ + union { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +} Elf64_Dyn; + +// ------------------------------------------------------------------------- +/* Dynamic Array Tags - d_tag */ + +#define DT_NULL 0 /* marks end of _DYNAMIC array */ +#define DT_NEEDED 1 /* string table offset of needed lib */ +#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ +#define DT_PLTGOT 3 /* address PLT/GOT */ +#define DT_HASH 4 /* address of symbol hash table */ +#define DT_STRTAB 5 /* address of string table */ +#define DT_SYMTAB 6 /* address of symbol table */ +#define DT_RELA 7 /* address of relocation table */ +#define DT_RELASZ 8 /* size of relocation table */ +#define DT_RELAENT 9 /* size of relocation entry */ +#define DT_STRSZ 10 /* size of string table */ +#define DT_SYMENT 11 /* size of symbol table entry */ +#define DT_INIT 12 /* address of initialization func. */ +#define DT_FINI 13 /* address of termination function */ +#define DT_SONAME 14 /* string table offset of shared obj */ +#define DT_RPATH 15 /* string table offset of library + search path */ +#define DT_SYMBOLIC 16 /* start sym search in shared obj. */ +#define DT_REL 17 /* address of rel. tbl. w addends */ +#define DT_RELSZ 18 /* size of DT_REL relocation table */ +#define DT_RELENT 19 /* size of DT_REL relocation entry */ +#define DT_PLTREL 20 /* PLT referenced relocation entry */ +#define DT_DEBUG 21 /* bugger */ +#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ +#define DT_JMPREL 23 /* add. of PLT's relocation entries */ +#define DT_BIND_NOW 24 /* Bind now regardless of env setting */ +#define DT_INIT_ARRAY 25 /* init array address */ +#define DT_FINI_ARRAY 26 /* fini array address */ +#define DT_INIT_ARRAYSZ 27 /* init array size */ +#define DT_FINI_ARRAYSZ 28 /* fini array size */ +#define DT_RUNPATH 29 /* library search path */ +#define DT_FLAGS 30 /* flags */ +#define DT_ENCODING 32 /* encoding rules start here */ +#define DT_PREINIT_ARRAY 32 /* preinit array address */ +#define DT_PREINIT_ARRAYSZ 33 /* preinit array size */ +#define DT_NUM 26 /* Number used. */ +#define DT_LOOS 0x60000000 /* reserved range for OS */ +#define DT_HIOS 0x6fffffff /* specific dynamic array tags */ +#define DT_LOPROC 0x70000000 /* reserved range for processor */ +#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ + +// ------------------------------------------------------------------------- +// Values for DT_FLAGS entry + +#define DF_ORIGIN 0x1 /* Uses $ORIGIN substitution string */ +#define DF_SYMBOLIC 0x2 /* search for symbols here first */ +#define DF_TEXTREL 0x4 /* text may be relocatable */ +#define DF_BIND_NOW 0x8 /* bind references now, dammit */ + +// ------------------------------------------------------------------------- +/* Note Definitions */ + +typedef struct { + Elf32_Word namesz; + Elf32_Word descsz; + Elf32_Word type; +} Elf32_Note; + +typedef struct { + Elf64_Word namesz; + Elf64_Word descsz; + Elf64_Word type; +} Elf64_Note; + +// ------------------------------------------------------------------------- +// Hash table structure +// The same structure is used by both 32 and 64 bit formats + +typedef struct { + Elf32_Word nbucket; /* number of buckets */ + Elf32_Word nchain; /* number of chains */ + + /* The buckets follow this structure in memory and the chains + follow those. */ +} Elf_Hash; + +// ------------------------------------------------------------------------- +#endif // ifndef CYGONCE_REDBOOT_ELF_H +// EOF elf.h Index: /ar5315_microredboot/microredboot/boot/src/ramconfig.h =================================================================== --- /ar5315_microredboot/microredboot/boot/src/ramconfig.h (revision 12383) +++ /ar5315_microredboot/microredboot/boot/src/ramconfig.h (revision 12429) @@ -1,3 +1,2 @@ #define RAM_SIZE 0x2000000 -#define AR5312 1 #define RESETBUTTON 0x06