From b74aa0012a7d6c15b552df0d66a4601bb10a6b1a Mon Sep 17 00:00:00 2001 From: lothar Date: Thu, 14 Jan 2010 17:58:00 +0000 Subject: [PATCH] TX51 pre-release --- packages/redboot/v2_0/cdl/redboot.cdl | 12 + packages/redboot/v2_0/src/flash.c | 1184 +++++++++--------- packages/redboot/v2_0/src/load.c | 74 +- packages/redboot/v2_0/src/main.c | 878 ++++++------- packages/redboot/v2_0/src/net/net_io.c | 1211 +++++++++--------- packages/redboot/v2_0/src/net/tcp.c | 1234 ++++++++++--------- packages/redboot/v2_0/src/net/tftp_client.c | 401 +++--- packages/redboot/v2_0/src/wince.c | 44 +- packages/redboot/v2_0/src/winceinc.h | 177 +-- packages/redboot/v2_0/src/xyzModem.c | 785 ++++++------ 10 files changed, 3006 insertions(+), 2994 deletions(-) diff --git a/packages/redboot/v2_0/cdl/redboot.cdl b/packages/redboot/v2_0/cdl/redboot.cdl index 879da343..39a94524 100644 --- a/packages/redboot/v2_0/cdl/redboot.cdl +++ b/packages/redboot/v2_0/cdl/redboot.cdl @@ -245,6 +245,18 @@ cdl_package CYGPKG_REDBOOT { compile -library=libextras.a xyzModem.c } + cdl_option CYGPKG_REDBOOT_CFLAGS_ADD { + display "Additional compiler flags" + active_if CYGBLD_BUILD_REDBOOT_WITH_XYZMODEM + flavor data + no_define + default_value { "-Wno-inline" } + description " + This option modifies the set of compiler flags for + building the eCos infra package. These flags are used + in addition to the set of global flags." + } + cdl_option CYGBLD_REDBOOT_LOAD_INTO_FLASH { display "Allow the load-command write into Flash." default_value 0 diff --git a/packages/redboot/v2_0/src/flash.c b/packages/redboot/v2_0/src/flash.c index b3f0beaa..caefc0c0 100644 --- a/packages/redboot/v2_0/src/flash.c +++ b/packages/redboot/v2_0/src/flash.c @@ -58,7 +58,7 @@ #include #include #include -#include // assertion macros +#include // assertion macros #ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT #include @@ -79,7 +79,7 @@ local_cmd_entry("init", "[-f]", fis_init, FIS_cmds - ); + ); #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK # define FIS_LIST_OPTS "[-c] [-d]" #else @@ -90,52 +90,52 @@ local_cmd_entry("list", FIS_LIST_OPTS, fis_list, FIS_cmds - ); + ); local_cmd_entry("free", "Display free [available] locations within FLASH Image System [FIS]", "", fis_free, FIS_cmds - ); + ); local_cmd_entry("delete", "Delete an image from FLASH Image System [FIS]", "name", fis_delete, FIS_cmds - ); + ); static char fis_load_usage[] = #ifdef CYGPRI_REDBOOT_ZLIB_FLASH - "[-d] " + "[-d] " #endif - "[-b ] [-c] " + "[-b ] [-c] " #ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT - "[-w]" + "[-w]" #endif - "name\n" - "Options:\n" + "name\n" + "Options:\n" #ifdef CYGPRI_REDBOOT_ZLIB_FLASH - "\t-d: decompress\n" + "\t-d: decompress\n" #endif - "\t-c: print checksum\n" + "\t-c: print checksum\n" #ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT - "\t-w: load as Windows CE image\n" + "\t-w: load as Windows CE image\n" #endif - ; + ; local_cmd_entry("load", "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 - ); + ); #endif // Raw flash access functions @@ -144,27 +144,27 @@ local_cmd_entry("erase", "-f -l ", fis_erase, FIS_cmds - ); + ); #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING local_cmd_entry("lock", "LOCK FLASH contents", "[-f -l ] [name]", fis_lock, FIS_cmds - ); + ); local_cmd_entry("unlock", "UNLOCK FLASH contents", "[-f -l ] [name]", fis_unlock, FIS_cmds - ); + ); #endif local_cmd_entry("write", "Write raw data directly to FLASH", "-f -b -l ", fis_write, FIS_cmds - ); + ); // Define table boundaries CYG_HAL_TABLE_BEGIN( __FIS_cmds_TAB__, FIS_cmds); @@ -175,11 +175,11 @@ extern struct cmd __FIS_cmds_TAB__[], __FIS_cmds_TAB_END__; // CLI function static cmd_fun do_fis; RedBoot_nested_cmd("fis", - "Manage FLASH images", - "{cmds}", - do_fis, - __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__ - ); + "Manage FLASH images", + "{cmds}", + do_fis, + __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__ + ); // Local data used by these routines void *flash_start, *flash_end; @@ -201,15 +201,15 @@ extern struct _config *config; static void fis_usage(char *why) { - diag_printf("*** invalid 'fis' command: %s\n", why); - cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); + 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", flash_start, flash_end); + diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); + diag_printf(" valid range is %p-%p\n", flash_start, flash_end); } #ifdef CYGOPT_REDBOOT_FIS @@ -219,10 +219,10 @@ _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat) static inline void fis_endian_fixup(void *addr) { #ifdef REDBOOT_FLASH_REVERSE_BYTEORDER - struct fis_image_desc *p = addr; - int cnt = fisdir_size / sizeof(struct fis_image_desc); + struct fis_image_desc *p = addr; + int cnt = fisdir_size / sizeof(struct fis_image_desc); - while (cnt-- > 0) { + 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); @@ -231,36 +231,36 @@ static inline void fis_endian_fixup(void *addr) 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; + void *err_addr; - FLASH_READ(fis_addr, fis_work_block, fisdir_size, &err_addr); - fis_endian_fixup(fis_work_block); + FLASH_READ(fis_addr, fis_work_block, fisdir_size, &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; + int i; + struct fis_image_desc *img; - fis_read_directory(); + fis_read_directory(); - img = (struct fis_image_desc *)fis_work_block; - for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { + img = (struct fis_image_desc *)fis_work_block; + for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { if ((img->u.name[0] != 0xFF) && (strcasecmp(name, img->u.name) == 0)) { if (num) *num = i; return img; } - } - return NULL; + } + return NULL; } int fis_start_update_directory(int autolock) @@ -288,7 +288,7 @@ int fis_start_update_directory(int autolock) img = fis_work_block; memcpy(img->u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC, - CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH); + CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH); img->u.valid_info.valid_flag[0] = CYG_REDBOOT_RFIS_IN_PROGRESS; img->u.valid_info.valid_flag[1] = CYG_REDBOOT_RFIS_IN_PROGRESS; img->u.valid_info.version_count = img->u.valid_info.version_count+1; @@ -347,13 +347,13 @@ fis_update_directory(int autolock, int error) } else { //success void *tmp_fis_addr = (void *)((CYG_ADDRESS)fis_addr + - CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH); + CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH); img->u.valid_info.valid_flag[0] = CYG_REDBOOT_RFIS_VALID; img->u.valid_info.valid_flag[1] = CYG_REDBOOT_RFIS_VALID; flash_program(tmp_fis_addr, img->u.valid_info.valid_flag, - sizeof(img->u.valid_info.valid_flag), &err_addr); + sizeof(img->u.valid_info.valid_flag), &err_addr); } #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING if (do_autolock) @@ -361,37 +361,37 @@ fis_update_directory(int autolock, int error) #endif #else // CYGOPT_REDBOOT_REDUNDANT_FIS - int blk_size = fisdir_size; - int stat; + int blk_size = fisdir_size; + int stat; - fis_endian_fixup(fis_work_block); + 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); - blk_size += cfg_size; + memcpy((char *)fis_work_block+fisdir_size, config, cfg_size); + conf_endian_fixup((char *)fis_work_block+fisdir_size); + blk_size += cfg_size; #endif #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING - if (do_autolock) + if (do_autolock) flash_unlock((void *)fis_addr, blk_size, &err_addr); #endif - if ((stat = flash_erase(fis_addr, flash_block_size, &err_addr)) != 0) { + if ((stat = flash_erase(fis_addr, flash_block_size, &err_addr)) != 0) { diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat)); - } else { + } else { if ((stat = FLASH_PROGRAM(fis_addr, fis_work_block, - flash_block_size, &err_addr)) != 0) { + flash_block_size, &err_addr)) != 0) { diag_printf("Error writing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat)); } - } - fis_endian_fixup(fis_work_block); + } + fis_endian_fixup(fis_work_block); #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING - if (do_autolock) + if (do_autolock) flash_lock((void *)fis_addr, blk_size, &err_addr); #endif #endif // CYGOPT_REDBOOT_REDUNDANT_FIS - return 0; + return 0; } #ifdef CYGOPT_REDBOOT_REDUNDANT_FIS @@ -401,14 +401,14 @@ fis_get_valid_buf(struct fis_image_desc *img0, struct fis_image_desc *img1, int { *update_was_interrupted = 0; if (strncmp(img1->u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC, - CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH) != 0) { + CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH) != 0) { //buf0 must be valid if (img0->u.valid_info.version_count > 0) { *update_was_interrupted = 1; } return 0; } else if (strncmp(img0->u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC, - CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH) != 0) { + CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH) != 0) { //buf1 must be valid if (img1->u.valid_info.version_count > 0) { *update_was_interrupted = 1; @@ -422,7 +422,7 @@ fis_get_valid_buf(struct fis_image_desc *img0, struct fis_image_desc *img1, int *update_was_interrupted = 1; return 0; } else if ((img0->u.valid_info.valid_flag[0] != CYG_REDBOOT_RFIS_VALID) || - (img0->u.valid_info.valid_flag[1] != CYG_REDBOOT_RFIS_VALID)) { + (img0->u.valid_info.valid_flag[1] != CYG_REDBOOT_RFIS_VALID)) { //buf1 must be valid *update_was_interrupted = 1; return 1; @@ -435,23 +435,23 @@ fis_get_valid_buf(struct fis_image_desc *img0, struct fis_image_desc *img1, int void fis_erase_redundant_directory(void) { - int stat; - void *err_addr; + int stat; + void *err_addr; #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL - // Ensure [quietly] that the directory is unlocked before trying - // to update - flash_unlock((void *)redundant_fis_addr, fisdir_size, - &err_addr); + // Ensure [quietly] that the directory is unlocked before trying + // to update + flash_unlock((void *)redundant_fis_addr, fisdir_size, + &err_addr); #endif - if ((stat = flash_erase(redundant_fis_addr, fisdir_size, - &err_addr)) != 0) { + if ((stat = flash_erase(redundant_fis_addr, fisdir_size, + &err_addr)) != 0) { diag_printf("Error erasing 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 *)redundant_fis_addr, fisdir_size, &err_addr); + // Ensure [quietly] that the directory is locked after the update + flash_lock((void *)redundant_fis_addr, fisdir_size, &err_addr); #endif } #endif @@ -459,119 +459,119 @@ fis_erase_redundant_directory(void) static void fis_init(int argc, char *argv[]) { - 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, - &full_init, NULL, "full initialization, erases all of flash"); - if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) { + 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, + &full_init, NULL, "full initialization, erases all of flash"); + if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) { return; - } + } - if (!verify_action("About to initialize [format] FLASH image system")) { + if (!verify_action("About to initialize [format] FLASH image system")) { diag_printf("** Aborted\n"); return; - } - diag_printf("*** Initialize FLASH Image System\n"); + } + 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 ? + redboot_image_size = flash_block_size > MIN_REDBOOT_IMAGE_SIZE ? flash_block_size : MIN_REDBOOT_IMAGE_SIZE; - img = fis_work_block; - memset(img, 0xFF, fisdir_size); // Start with erased data + img = fis_work_block; + memset(img, 0xFF, fisdir_size); // Start with erased data #ifdef CYGOPT_REDBOOT_REDUNDANT_FIS - //create the valid flag entry - memset(img, 0, sizeof(struct fis_image_desc)); - strcpy(img->u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC); - img->u.valid_info.valid_flag[0] = CYG_REDBOOT_RFIS_VALID; - img->u.valid_info.valid_flag[1] = CYG_REDBOOT_RFIS_VALID; - img->u.valid_info.version_count = 0; - img++; + //create the valid flag entry + memset(img, 0, sizeof(struct fis_image_desc)); + strcpy(img->u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC); + img->u.valid_info.valid_flag[0] = CYG_REDBOOT_RFIS_VALID; + img->u.valid_info.valid_flag[1] = CYG_REDBOOT_RFIS_VALID; + img->u.valid_info.version_count = 0; + img++; #endif - // Create a pseudo image for RedBoot + // Create a pseudo image for RedBoot #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE - memset(img, 0, sizeof(*img)); - strcpy(img->u.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->u.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->u.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->u.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; + // 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->u.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; + memset(img, 0, sizeof(*img)); + strcpy(img->u.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->u.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->u.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->u.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->u.name, "FIS directory"); - img->flash_base = (CYG_ADDRESS)fis_addr; - img->mem_base = (CYG_ADDRESS)fis_addr; - img->size = fisdir_size; - img++; - - //create the entry for the redundant fis table + // And a descriptor for the configuration data + memset(img, 0, sizeof(*img)); + strcpy(img->u.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->u.name, "FIS directory"); + img->flash_base = (CYG_ADDRESS)fis_addr; + img->mem_base = (CYG_ADDRESS)fis_addr; + img->size = fisdir_size; + img++; + + //create the entry for the redundant fis table #ifdef CYGOPT_REDBOOT_REDUNDANT_FIS - memset(img, 0, sizeof(*img)); - strcpy(img->u.name, "Redundant FIS"); - img->flash_base = (CYG_ADDRESS)redundant_fis_addr; - img->mem_base = (CYG_ADDRESS)redundant_fis_addr; - img->size = fisdir_size; - img++; + memset(img, 0, sizeof(*img)); + strcpy(img->u.name, "Redundant FIS"); + img->flash_base = (CYG_ADDRESS)redundant_fis_addr; + img->mem_base = (CYG_ADDRESS)redundant_fis_addr; + img->size = fisdir_size; + img++; #endif #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. - { + // 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; @@ -598,13 +598,13 @@ fis_init(int argc, char *argv[]) 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. + // Do this after creating the initialized table because that inherently + // calculates where the high water mark of default RedBoot images is. - if (full_init) { + if (full_init) { unsigned long erase_size; CYG_ADDRESS erase_start; // Erase everything except default RedBoot images, fis block, @@ -616,7 +616,7 @@ fis_init(int argc, char *argv[]) if ( erase_size > erase_start ) { erase_size -= erase_start; if ((stat = flash_erase((void *)erase_start, erase_size, - &err_addr)) != 0) { + &err_addr)) != 0) { diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); } @@ -626,16 +626,16 @@ fis_init(int argc, char *argv[]) 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 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, - &err_addr)) != 0) { + &err_addr)) != 0) { diag_printf(" initialization failed %p: %s\n", err_addr, flash_errmsg(stat)); } @@ -646,7 +646,7 @@ fis_init(int argc, char *argv[]) erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between fis and config data } if ((stat = flash_erase((void *)erase_start, erase_size, - &err_addr)) != 0) { + &err_addr)) != 0) { diag_printf(" initialization failed %p: %s\n", err_addr, flash_errmsg(stat)); } @@ -654,7 +654,7 @@ fis_init(int argc, char *argv[]) #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, - &err_addr)) != 0) { + &err_addr)) != 0) { diag_printf(" initialization failed %p: %s\n", err_addr, flash_errmsg(stat)); } @@ -664,7 +664,7 @@ fis_init(int argc, char *argv[]) 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, - &err_addr)) != 0) { + &err_addr)) != 0) { diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); } @@ -673,56 +673,56 @@ fis_init(int argc, char *argv[]) // 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 { + } else { diag_printf(" Warning: device contents not erased, some blocks may not be usable\n"); #endif - } - fis_start_update_directory(0); - fis_update_directory(0, 0); + } + fis_start_update_directory(0); + fis_update_directory(0, 0); #ifdef CYGOPT_REDBOOT_REDUNDANT_FIS - fis_erase_redundant_directory(); + fis_erase_redundant_directory(); #endif } static void fis_list(int argc, char *argv[]) { - struct fis_image_desc *img; - int i = 0, image_indx; - bool show_cksums = false; - bool show_datalen = false; - struct option_info opts[2]; - unsigned long last_addr, lowest_addr; - bool image_found; + struct fis_image_desc *img; + int i = 0, 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; + // FIXME: this is somewhat half-baked + extern void arm_fis_list(void); + arm_fis_list(); + return; #endif - init_opts(&opts[i++], 'd', false, OPTION_ARG_TYPE_FLG, - &show_datalen, NULL, "display data length"); + init_opts(&opts[i++], 'd', false, OPTION_ARG_TYPE_FLG, + &show_datalen, NULL, "display data length"); #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK - init_opts(&opts[i++], 'c', false, OPTION_ARG_TYPE_FLG, - &show_cksums, NULL, "display checksums"); + init_opts(&opts[i++], 'c', false, OPTION_ARG_TYPE_FLG, + &show_cksums, NULL, "display checksums"); #endif - if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { + if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { return; - } - fis_read_directory(); + } + 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", + // 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 { + last_addr = 0; + image_indx = 0; + do { image_found = false; lowest_addr = 0xFFFFFFFF; img = fis_work_block; @@ -750,70 +750,70 @@ fis_list(int argc, char *argv[]) (unsigned long)img->entry_point); } last_addr = lowest_addr + 1; - } while (image_found == true); + } 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); - 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 = fis_work_block; - for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { - if (img->u.name[0] != 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) { - int j; - // make room for new chunk - for (j = num_chunks; j > idx + 1; j--) - chunks[j] = chunks[j-1]; - 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; - } + 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); + 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 = fis_work_block; + for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { + if (img->u.name[0] != 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) { + int j; + // make room for new chunk + for (j = num_chunks; j > idx + 1; j--) + chunks[j] = chunks[j-1]; + 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; + } } - chunks[idx].end = img->flash_base; - } - break; } - } } - } - return num_chunks; + return num_chunks; } #endif // CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS @@ -821,17 +821,17 @@ static void fis_free(int argc, char *argv[]) { #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS - unsigned long *fis_ptr, *fis_end, flash_data; - unsigned long *area_start; - void *err_addr; + unsigned long *fis_ptr, *fis_end, flash_data; + unsigned long *area_start; + void *err_addr; FLASH_Enable(flash_start, flash_end); - // Do not search the area reserved for pre-RedBoot systems: - fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + + // Do not search the area reserved for pre-RedBoot systems: + fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); - fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; - area_start = fis_ptr; - while (fis_ptr < fis_end) { + 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), &err_addr); if (flash_data != 0xFFFFFFFF) { if (area_start != fis_ptr) { @@ -852,22 +852,22 @@ fis_free(int argc, char *argv[]) } else { fis_ptr += flash_block_size / sizeof(CYG_ADDRESS); } - } - if (area_start != fis_ptr) { + } + if (area_start != fis_ptr) { diag_printf(" 0x%08x .. 0x%08x\n", (CYG_ADDRESS)area_start, (CYG_ADDRESS)fis_ptr); - } + } FLASH_Disable(flash_start, flash_end); #else - struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; - int idx, num_chunks; + 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++) { + num_chunks = find_free(chunks); + for (idx = 0; idx < num_chunks; idx++) { diag_printf(" 0x%08x .. 0x%08x\n", chunks[idx].start, chunks[idx].end); - } + } #endif } @@ -876,17 +876,17 @@ 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; + 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 + + // Do not search the area reserved for pre-RedBoot systems: + fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); - fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; + fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; FLASH_Enable(fis_ptr, fis_end); - area_start = fis_ptr; - while (fis_ptr < fis_end) { + area_start = fis_ptr; + while (fis_ptr < fis_end) { flash_read(fis_ptr, &flash_data, sizeof(unsigned long), &err_addr); if (flash_data != 0xFFFFFFFF) { if (area_start != fis_ptr) { @@ -909,73 +909,73 @@ fis_find_free(CYG_ADDRESS *addr, unsigned long length) } else { fis_ptr += flash_block_size / sizeof(CYG_ADDRESS); } - } + } FLASH_Disable((void *)((CYG_ADDRESS)flash_start + - CYGNUM_REDBOOT_FLASH_RESERVED_BASE), fis_end); - if (area_start != fis_ptr) { + CYGNUM_REDBOOT_FLASH_RESERVED_BASE), fis_end); + if (area_start != fis_ptr) { if (fis_ptr - area_start >= length / sizeof(unsigned)) { *addr = (CYG_ADDRESS)area_start; return true; } - } - return false; + } + return false; #else - struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; - int idx, num_chunks; + 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++) { + num_chunks = find_free(chunks); + for (idx = 0; idx < num_chunks; idx++) { if (chunks[idx].end + 1 - chunks[idx].start >= length) { *addr = (CYG_ADDRESS)chunks[idx].start; return true; } - } - return false; + } + return false; #endif } static void fis_create(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, - &mem_addr, &mem_addr_set, "memory base address"); - init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, - &exec_addr, &exec_addr_set, "ram base address"); - init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, - &entry_addr, &entry_addr_set, "entry point address"); - init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, - &flash_addr, &flash_addr_set, "FLASH memory base address"); - init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, - &length, &length_set, "image length [in FLASH]"); - init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, - &img_size, &img_size_set, "image size [actual data]"); - init_opts(&opts[6], 'n', false, OPTION_ARG_TYPE_FLG, - &no_copy, NULL, "don't copy from RAM to FLASH, just update directory"); - if (!scan_opts(argc, argv, 2, opts, 7, &name, OPTION_ARG_TYPE_STR, "file name")) { + 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, + &mem_addr, &mem_addr_set, "memory base address"); + init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, + &exec_addr, &exec_addr_set, "ram base address"); + init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, + &entry_addr, &entry_addr_set, "entry point address"); + init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, + &flash_addr, &flash_addr_set, "FLASH memory base address"); + init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, + &length, &length_set, "image length [in FLASH]"); + init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, + &img_size, &img_size_set, "image size [actual data]"); + init_opts(&opts[6], 'n', false, OPTION_ARG_TYPE_FLG, + &no_copy, NULL, "don't copy from RAM to FLASH, just update directory"); + if (!scan_opts(argc, argv, 2, opts, 7, &name, OPTION_ARG_TYPE_STR, "file name")) { fis_usage("invalid arguments"); return; } - fis_read_directory(); - defaults_assumed = false; - if (name) { + 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) { @@ -986,8 +986,8 @@ fis_create(int argc, char *argv[]) defaults_assumed = true; } } - } - if (!mem_addr_set && (load_address >= (CYG_ADDRESS)ram_start) && + } + 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; @@ -1004,9 +1004,9 @@ fis_create(int argc, char *argv[]) img_size = load_address_end - load_address; img_size_set = true; } - } - // Get the remaining fall-back values from the fis - if (img) { + } + // Get the remaining fall-back values from the fis + if (img) { if (!exec_addr_set) { // Preserve "normal" behaviour exec_addr_set = true; @@ -1017,42 +1017,42 @@ fis_create(int argc, char *argv[]) flash_addr = img->flash_base; defaults_assumed = true; } - } + } - if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) || + if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) || !length_set || !name) { fis_usage("required parameter missing"); return; - } - if (!img_size_set) { + } + 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 + } + // '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) { + 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 && + if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { + (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)) { + } + 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->u.name)) { + } + if (strlen(name) >= sizeof(img->u.name)) { diag_printf("Name is too long, must be less than %d chars\n", sizeof(img->u.name)); return; - } - if (!no_copy) { + } + 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); @@ -1062,9 +1062,9 @@ fis_create(int argc, char *argv[]) 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) { + } + // 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", @@ -1084,14 +1084,14 @@ fis_create(int argc, char *argv[]) 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)) { + name, (void *)flash_addr, + (void *)(flash_addr + img_size - 1), + (void *)mem_addr)) { return; // The guy gave up } } } - } else { + } 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) { @@ -1123,11 +1123,11 @@ fis_create(int argc, char *argv[]) diag_printf("Can't find an empty slot in FIS directory!\n"); return; } - } - if (!no_copy) { + } + 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))) { + (void *)(flash_addr + img_size - 1))) { diag_printf("Can't program this region - contains code in use!\n"); return; } @@ -1145,15 +1145,15 @@ fis_create(int argc, char *argv[]) // Now program it FLASH_Enable((void *)flash_addr, (void *)(flash_addr + length)); stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, - img_size, &err_addr); + img_size, &err_addr); FLASH_Disable((void *)flash_addr, (void *)(flash_addr + length)); if (stat != 0) { diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } } - } - if (prog_ok) { + } + if (prog_ok) { // Update directory memset(img, 0, sizeof(*img)); strcpy(img->u.name, name); @@ -1172,130 +1172,130 @@ fis_create(int argc, char *argv[]) #endif fis_start_update_directory(0); fis_update_directory(0, 0); - } + } } extern void arm_fis_delete(char *); static void fis_delete(int argc, char *argv[]) { - char *name; - int num_reserved, i, stat; - void *err_addr; - struct fis_image_desc *img; + char *name; + int num_reserved, i, stat; + void *err_addr; + struct fis_image_desc *img; - if (!scan_opts(argc, argv, 2, 0, 0, &name, OPTION_ARG_TYPE_STR, "image name")) { + if (!scan_opts(argc, argv, 2, 0, 0, &name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; } #ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB - // FIXME: this is somewhat half-baked - arm_fis_delete(name); - return; + // FIXME: this is somewhat half-baked + arm_fis_delete(name); + return; #endif - img = (struct fis_image_desc *)fis_work_block; - num_reserved = 0; + img = (struct fis_image_desc *)fis_work_block; + num_reserved = 0; #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE - num_reserved++; + num_reserved++; #endif #ifdef CYGOPT_REDBOOT_FIS_REDBOOT - num_reserved++; + num_reserved++; #endif #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP - num_reserved++; + num_reserved++; #endif #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST - num_reserved++; + num_reserved++; #endif #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH) - num_reserved++; + num_reserved++; #endif #if 1 // And the descriptor for the descriptor table itself - num_reserved++; + num_reserved++; #endif - img = fis_lookup(name, &i); - if (img) { - if (i < num_reserved) { - diag_printf("Sorry, '%s' is a reserved image and cannot be deleted\n", img->u.name); - return; - } - if (!verify_action("Delete image '%s'", name)) { - return; - } - } else { + img = fis_lookup(name, &i); + if (img) { + if (i < num_reserved) { + diag_printf("Sorry, '%s' is a reserved image and cannot be deleted\n", img->u.name); + return; + } + if (!verify_action("Delete image '%s'", name)) { + return; + } + } else { diag_printf("No image '%s' found\n", name); - return; - } - // Erase Data blocks (free space) - if ((stat = flash_erase((void *)img->flash_base, img->size, &err_addr)) != 0) { + return; + } + // Erase Data blocks (free space) + if ((stat = flash_erase((void *)img->flash_base, img->size, &err_addr)) != 0) { diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); - } else { + } else { img->u.name[0] = 0xFF; fis_start_update_directory(0); fis_update_directory(0, 0); - } + } } 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; - bool load_ce = false; - struct option_info opts[4]; + char *name; + struct fis_image_desc *img; + CYG_ADDRESS mem_addr; + bool mem_addr_set = false; + bool show_cksum = false; + bool load_ce = false; + struct option_info opts[4]; #if defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) - unsigned long cksum; + unsigned long cksum; #endif - int num_options = 0; + int num_options = 0; #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) || defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) - bool decompress = false; + bool decompress = false; #endif - void *err_addr; + void *err_addr; - init_opts(&opts[num_options++], 'b', true, OPTION_ARG_TYPE_NUM, - &mem_addr, &mem_addr_set, "memory [load] base address"); - init_opts(&opts[num_options++], 'c', false, OPTION_ARG_TYPE_FLG, - &show_cksum, NULL, "display checksum"); + init_opts(&opts[num_options++], 'b', true, OPTION_ARG_TYPE_NUM, + &mem_addr, &mem_addr_set, "memory [load] base address"); + init_opts(&opts[num_options++], 'c', false, OPTION_ARG_TYPE_FLG, + &show_cksum, NULL, "display checksum"); #ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT - init_opts(&opts[num_options++], 'w', false, OPTION_ARG_TYPE_FLG, - &load_ce, NULL, "parse as Windows CE image"); + init_opts(&opts[num_options++], 'w', false, OPTION_ARG_TYPE_FLG, + &load_ce, NULL, "parse as Windows CE image"); #endif #ifdef CYGPRI_REDBOOT_ZLIB_FLASH - init_opts(&opts[num_options++], 'd', false, OPTION_ARG_TYPE_FLG, - &decompress, 0, "decompress"); + init_opts(&opts[num_options++], 'd', false, OPTION_ARG_TYPE_FLG, + &decompress, 0, "decompress"); #endif - CYG_ASSERT(num_options <= num_options, "Too many options"); + CYG_ASSERT(num_options <= num_options, "Too many options"); - if (!scan_opts(argc, argv, 2, opts, num_options, &name, - OPTION_ARG_TYPE_STR, "image name")) { + if (!scan_opts(argc, argv, 2, opts, num_options, &name, + OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; - } - if ((img = fis_lookup(name, NULL)) == NULL) { + } + if ((img = fis_lookup(name, NULL)) == NULL) { diag_printf("No image '%s' found\n", name); return; - } - if (!mem_addr_set || load_ce) { + } + if (!mem_addr_set || load_ce) { mem_addr = img->mem_base; - } - // Load image from FLASH into RAM + } + // Load image from FLASH into RAM #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS - if (!valid_address((void *)mem_addr)) { + if (!valid_address((void *)mem_addr)) { if (!load_ce) { diag_printf("Not a loadable image - try using -b ADDRESS option\n"); } else { diag_printf("Not a loadable image\n"); } return; - } + } #endif #ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT - if (load_ce) { + if (load_ce) { if (mem_addr_set) { diag_printf("Warning: -b argument ignored for Windows CE image\n"); } @@ -1312,10 +1312,10 @@ fis_load(int argc, char *argv[]) load_address = mem_addr; load_address_end = mem_addr + img->data_length; return; - } + } #endif #ifdef CYGPRI_REDBOOT_ZLIB_FLASH - if (decompress) { + if (decompress) { int err; _pipe_t fis_load_pipe; _pipe_t *p = &fis_load_pipe; @@ -1345,41 +1345,41 @@ fis_load(int argc, char *argv[]) // Reload fis directory fis_read_directory(); - } else // dangling block + } else // dangling block #endif - { - int err; - - FLASH_Enable((void *)img->flash_base, (void *)(img->flash_base + img->size)); - err = flash_read((void *)img->flash_base, (void *)mem_addr, - img->data_length, &err_addr); - FLASH_Disable((void *)img->flash_base, (void *)(img->flash_base + img->size)); - if (err != FLASH_ERR_OK) { - diag_printf("** Error: Failed to load image from flash\n"); - return; - } + { + int err; - // Set load address/top - load_address = mem_addr; - load_address_end = mem_addr + img->data_length; + FLASH_Enable((void *)img->flash_base, (void *)(img->flash_base + img->size)); + err = flash_read((void *)img->flash_base, (void *)mem_addr, + img->data_length, &err_addr); + FLASH_Disable((void *)img->flash_base, (void *)(img->flash_base + img->size)); + if (err != FLASH_ERR_OK) { + diag_printf("** Error: Failed to load image from flash\n"); + return; } - entry_address = (unsigned long)img->entry_point; + + // 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) { + 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 && img->file_cksum) { + } + // When decompressing, leave CRC checking to decompressor + if (!decompress && 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 - diag_printf("image loaded 0x%08lx-0x%08lx, assumed entry at 0x%08lx\n", + diag_printf("image loaded 0x%08lx-0x%08lx, assumed entry at 0x%08lx\n", load_address, load_address_end - 1, entry_address); } #endif // CYGOPT_REDBOOT_FIS @@ -1387,125 +1387,125 @@ fis_load(int argc, char *argv[]) static void fis_write(int argc, char *argv[]) { - int stat; - unsigned long length; - CYG_ADDRESS mem_addr, flash_addr; - bool mem_addr_set = false; - bool flash_addr_set = false; - bool length_set = false; - void *err_addr; - struct option_info opts[3]; - bool prog_ok; - - init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, - &mem_addr, &mem_addr_set, "memory base address"); - init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM, - &flash_addr, &flash_addr_set, "FLASH memory base address"); - init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM, - &length, &length_set, "image length [in FLASH]"); - if (!scan_opts(argc, argv, 2, opts, 3, 0, 0, 0)) - { - fis_usage("invalid arguments"); - return; - } + int stat; + unsigned long length; + CYG_ADDRESS mem_addr, flash_addr; + bool mem_addr_set = false; + bool flash_addr_set = false; + bool length_set = false; + void *err_addr; + struct option_info opts[3]; + bool prog_ok; + + init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, + &mem_addr, &mem_addr_set, "memory base address"); + init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM, + &flash_addr, &flash_addr_set, "FLASH memory base address"); + init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM, + &length, &length_set, "image length [in FLASH]"); + if (!scan_opts(argc, argv, 2, opts, 3, 0, 0, 0)) + { + fis_usage("invalid arguments"); + return; + } - if (!mem_addr_set || !flash_addr_set || !length_set) { + if (!mem_addr_set || !flash_addr_set || !length_set) { fis_usage("required parameter missing"); return; - } + } - // Round up length to FLASH block 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; + length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size; #endif - if (flash_addr_set && + if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { + (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)) { + } + if (flash_addr_set && flash_addr & (flash_block_size-1)) { diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); diag_printf(" must be 0x%x aligned\n", flash_block_size); return; - } - if ((mem_addr < (CYG_ADDRESS)ram_start) || + } + if ((mem_addr < (CYG_ADDRESS)ram_start) || ((mem_addr + length) >= (CYG_ADDRESS)ram_end)) { diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); - } - // 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 + length - 1))) { + } + // 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 + length - 1))) { diag_printf("Can't program this region - contains code in use!\n"); return; - } - if (!verify_action("* CAUTION * about to program FLASH\n at %p..%p from %p", - (void *)flash_addr, (void *)(flash_addr + length - 1), - (void *)mem_addr)) { + } + if (!verify_action("* CAUTION * about to program FLASH\n at %p..%p from %p", + (void *)flash_addr, (void *)(flash_addr + length - 1), + (void *)mem_addr)) { return; // The guy gave up - } - prog_ok = true; - if (prog_ok) { + } + prog_ok = true; + if (prog_ok) { // Erase area to be programmed if ((stat = flash_erase((void *)flash_addr, length, &err_addr)) != 0) { diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } - } - if (prog_ok) { + } + if (prog_ok) { // Now program it stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, length, &err_addr); if (stat != 0) { diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } - } + } } static void fis_erase(int argc, char *argv[]) { - int stat; - unsigned long length; - CYG_ADDRESS flash_addr; - bool flash_addr_set = false; - bool length_set = false; - void *err_addr; - struct option_info opts[2]; - - init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, - &flash_addr, &flash_addr_set, "FLASH memory base address"); - init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, - &length, &length_set, "length"); - if (!scan_opts(argc, argv, 2, opts, 2, NULL, 0, NULL)) - { - fis_usage("invalid arguments"); - return; - } + int stat; + unsigned long length; + CYG_ADDRESS flash_addr; + bool flash_addr_set = false; + bool length_set = false; + void *err_addr; + struct option_info opts[2]; + + init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, + &flash_addr, &flash_addr_set, "FLASH memory base address"); + init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, + &length, &length_set, "length"); + if (!scan_opts(argc, argv, 2, opts, 2, NULL, 0, NULL)) + { + fis_usage("invalid arguments"); + return; + } - if (!flash_addr_set || !length_set) { + if (!flash_addr_set || !length_set) { fis_usage("missing argument"); return; - } - if (flash_addr_set && + } + if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { + (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)) { + } + if (flash_addr_set && flash_addr & (flash_block_size-1)) { diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); diag_printf(" must be 0x%x aligned\n", flash_block_size); return; - } - // 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 + length - 1))) { + } + // 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 + length - 1))) { diag_printf("Can't erase this region - contains code in use!\n"); return; - } - if ((stat = flash_erase((void *)flash_addr, length, &err_addr)) != 0) { + } + if ((stat = flash_erase((void *)flash_addr, length, &err_addr)) != 0) { diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); - } + } } #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING @@ -1513,26 +1513,26 @@ fis_erase(int argc, char *argv[]) static void fis_lock(int argc, char *argv[]) { - char *name; - int stat; - unsigned long length; - CYG_ADDRESS flash_addr; - bool flash_addr_set = false; - bool length_set = false; - void *err_addr; - struct option_info opts[2]; - - init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, - &flash_addr, &flash_addr_set, "FLASH memory base address"); - init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, - &length, &length_set, "length"); - if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name")) { + char *name; + int stat; + unsigned long length; + CYG_ADDRESS flash_addr; + bool flash_addr_set = false; + bool length_set = false; + void *err_addr; + struct option_info opts[2]; + + init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, + &flash_addr, &flash_addr_set, "FLASH memory base address"); + init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, + &length, &length_set, "length"); + if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; } #ifdef CYGOPT_REDBOOT_FIS - /* Get parameters from image if specified */ - if (name) { + /* Get parameters from image if specified */ + if (name) { struct fis_image_desc *img; if ((img = fis_lookup(name, NULL)) == NULL) { diag_printf("No image '%s' found\n", name); @@ -1541,45 +1541,45 @@ fis_lock(int argc, char *argv[]) flash_addr = img->flash_base; length = img->size; - } else + } else #endif if (!flash_addr_set || !length_set) { fis_usage("missing argument"); return; } - if (flash_addr_set && + if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { + (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { _show_invalid_flash_address(flash_addr, stat); return; - } - if ((stat = flash_lock((void *)flash_addr, length, &err_addr)) != 0) { + } + if ((stat = flash_lock((void *)flash_addr, length, &err_addr)) != 0) { diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat)); - } + } } static void fis_unlock(int argc, char *argv[]) { - char *name; - int stat; - unsigned long length; - CYG_ADDRESS flash_addr; - bool flash_addr_set = false; - bool length_set = false; - void *err_addr; - struct option_info opts[2]; - - init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, - &flash_addr, &flash_addr_set, "FLASH memory base address"); - init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, - &length, &length_set, "length"); - if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name")) { + char *name; + int stat; + unsigned long length; + CYG_ADDRESS flash_addr; + bool flash_addr_set = false; + bool length_set = false; + void *err_addr; + struct option_info opts[2]; + + init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, + &flash_addr, &flash_addr_set, "FLASH memory base address"); + init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, + &length, &length_set, "length"); + if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; } #ifdef CYGOPT_REDBOOT_FIS - if (name) { + if (name) { struct fis_image_desc *img; if ((img = fis_lookup(name, NULL)) == NULL) { diag_printf("No image '%s' found\n", name); @@ -1588,22 +1588,22 @@ fis_unlock(int argc, char *argv[]) flash_addr = img->flash_base; length = img->size; - } else + } else #endif if (!flash_addr_set || !length_set) { fis_usage("missing argument"); return; } - if (flash_addr_set && + if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { + (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { _show_invalid_flash_address(flash_addr, stat); return; - } + } - if ((stat = flash_unlock((void *)flash_addr, length, &err_addr)) != 0) { + if ((stat = flash_unlock((void *)flash_addr, length, &err_addr)) != 0) { diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat)); - } + } } #endif @@ -1613,8 +1613,8 @@ int __flash_init = 0; void _flash_info(void) { - if (!__flash_init) return; - diag_printf("FLASH: %p - 0x%x, %d blocks of 0x%08x bytes each.\n", + if (!__flash_init) return; + diag_printf("FLASH: %p - 0x%x, %d blocks of 0x%08x bytes each.\n", flash_start, (CYG_ADDRWORD)flash_end + 1, flash_num_blocks, flash_block_size); } @@ -1633,10 +1633,10 @@ do_flash_init(void) //check the size of fis_valid_info CYG_ASSERT((sizeof(struct fis_valid_info) <= sizeof(img0.u.name)), - "fis_valid_info size mismatch"); + "fis_valid_info size mismatch"); //try to check the alignment of version_count CYG_ASSERT(((&img0.u.valid_info.version_count - &img0) % sizeof(unsigned long) == 0), - "alignment problem"); + "alignment problem"); #endif if (!__flash_init) { __flash_init = 1; @@ -1696,12 +1696,12 @@ do_flash_init(void) if (CYGNUM_REDBOOT_FIS_REDUNDANT_DIRECTORY_BLOCK < 0) { redundant_fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 + - (CYGNUM_REDBOOT_FIS_REDUNDANT_DIRECTORY_BLOCK * - flash_block_size)); + (CYGNUM_REDBOOT_FIS_REDUNDANT_DIRECTORY_BLOCK * + flash_block_size)); } else { redundant_fis_addr = (void *)((CYG_ADDRESS)flash_start + - (CYGNUM_REDBOOT_FIS_REDUNDANT_DIRECTORY_BLOCK * - flash_block_size)); + (CYGNUM_REDBOOT_FIS_REDUNDANT_DIRECTORY_BLOCK * + flash_block_size)); } if (((CYG_ADDRESS)redundant_fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) { @@ -1712,12 +1712,12 @@ do_flash_init(void) FLASH_READ(redundant_fis_addr, &img1, sizeof(img1), &err_addr); if (strncmp(img0.u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC, - CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH) != 0) { - memset(&img0, 0, sizeof(img0)); - } + CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH) != 0) { + memset(&img0, 0, sizeof(img0)); + } if (strncmp(img1.u.valid_info.magic_name, CYG_REDBOOT_RFIS_VALID_MAGIC, - CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH) != 0) { + CYG_REDBOOT_RFIS_VALID_MAGIC_LENGTH) != 0) { memset(&img1, 0, sizeof(img0)); } @@ -1751,10 +1751,10 @@ do_flash_init(void) static void _do_flash_init(void) { - static int init_done = 0; - if (init_done) return; - init_done = 1; - do_flash_init(); + static int init_done = 0; + if (init_done) return; + init_done = 1; + do_flash_init(); } RedBoot_init(_do_flash_init, RedBoot_INIT_FIRST); @@ -1762,20 +1762,20 @@ RedBoot_init(_do_flash_init, RedBoot_INIT_FIRST); static void do_fis(int argc, char *argv[]) { - struct cmd *cmd; + struct cmd *cmd; - if (argc < 2) { + if (argc < 2) { fis_usage("too few arguments"); return; - } - if (do_flash_init() < 0) { - diag_printf("Sorry, no FLASH memory is available\n"); - return; - } - if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, - argv[1])) != NULL) { + } + if (do_flash_init() < 0) { + diag_printf("Sorry, no FLASH memory is available\n"); + return; + } + if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, + argv[1])) != NULL) { (cmd->fun)(argc, argv); return; - } - fis_usage("unrecognized command"); + } + fis_usage("unrecognized command"); } diff --git a/packages/redboot/v2_0/src/load.c b/packages/redboot/v2_0/src/load.c index 26844135..b575d8ec 100644 --- a/packages/redboot/v2_0/src/load.c +++ b/packages/redboot/v2_0/src/load.c @@ -682,7 +682,7 @@ load_srec_image(getc_t getc, unsigned long base, bool swap16bit) // -f - specify a flash address #endif // -void +void do_load(int argc, char *argv[]) { int res, num_options; @@ -693,8 +693,8 @@ do_load(int argc, char *argv[]) #ifdef CYGPKG_REDBOOT_NETWORKING struct sockaddr_in host; bool hostname_set, port_set; - unsigned int port; // int because it's an OPTION_ARG_TYPE_NUM, - // but will be cast to short + unsigned int port; // int because it's an OPTION_ARG_TYPE_NUM, + // but will be cast to short char *hostname; #endif #ifdef CYGBLD_REDBOOT_LOAD_INTO_FLASH @@ -725,44 +725,44 @@ do_load(int argc, char *argv[]) host.sin_port = 0; #endif - init_opts(&opts[0], 'v', false, OPTION_ARG_TYPE_FLG, - (void *)&verbose, 0, "verbose"); - init_opts(&opts[1], 'r', false, OPTION_ARG_TYPE_FLG, - (void *)&raw, 0, "load raw data"); - init_opts(&opts[2], 'b', true, OPTION_ARG_TYPE_NUM, - (void *)&base, (bool *)&base_addr_set, "load address"); - init_opts(&opts[3], 'm', true, OPTION_ARG_TYPE_STR, - (void *)&mode_str, (bool *)&mode_str_set, "download mode (TFTP, xyzMODEM, or disk)"); - init_opts(&opts[4], 'z', false, OPTION_ARG_TYPE_FLG, - (void *)&swap16bit, 0, "swap endianness on 16 bit"); + init_opts(&opts[0], 'v', false, OPTION_ARG_TYPE_FLG, + &verbose, 0, "verbose"); + init_opts(&opts[1], 'r', false, OPTION_ARG_TYPE_FLG, + &raw, 0, "load raw data"); + init_opts(&opts[2], 'b', true, OPTION_ARG_TYPE_NUM, + &base, &base_addr_set, "load address"); + init_opts(&opts[3], 'm', true, OPTION_ARG_TYPE_STR, + &mode_str, &mode_str_set, "download mode (TFTP, xyzMODEM, or disk)"); + init_opts(&opts[4], 'z', false, OPTION_ARG_TYPE_FLG, + &swap16bit, 0, "swap endianness on 16 bit"); num_options = 5; #if CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS > 1 - init_opts(&opts[num_options], 'c', true, OPTION_ARG_TYPE_NUM, - (void *)&chan, (bool *)&chan_set, "I/O channel"); + init_opts(&opts[num_options], 'c', true, OPTION_ARG_TYPE_NUM, + &chan, &chan_set, "I/O channel"); num_options++; #endif #ifdef CYGPKG_REDBOOT_NETWORKING - init_opts(&opts[num_options], 'h', true, OPTION_ARG_TYPE_STR, - (void *)&hostname, (bool *)&hostname_set, "host name or IP address"); + init_opts(&opts[num_options], 'h', true, OPTION_ARG_TYPE_STR, + &hostname, &hostname_set, "host name or IP address"); num_options++; - init_opts(&opts[num_options], 'p', true, OPTION_ARG_TYPE_NUM, - (void *)&port, (bool *)&port_set, "TCP port"); + init_opts(&opts[num_options], 'p', true, OPTION_ARG_TYPE_NUM, + &port, &port_set, "TCP port"); num_options++; #endif #ifdef CYGBLD_BUILD_REDBOOT_WITH_ZLIB - init_opts(&opts[num_options], 'd', false, OPTION_ARG_TYPE_FLG, - (void *)&decompress, 0, "decompress"); + init_opts(&opts[num_options], 'd', false, OPTION_ARG_TYPE_FLG, + &decompress, 0, "decompress"); num_options++; #endif #ifdef CYGBLD_REDBOOT_LOAD_INTO_FLASH init_opts(&opts[num_options], 'f', true, OPTION_ARG_TYPE_NUM, - (void *)&base, (bool *)&flash_addr_set, "flash address"); + &base, &flash_addr_set, "flash address"); num_options++; #endif CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); - - if (!scan_opts(argc, argv, 1, opts, num_options, - (void *)&filename, OPTION_ARG_TYPE_STR, "file name")) { + + if (!scan_opts(argc, argv, 1, opts, num_options, + &filename, OPTION_ARG_TYPE_STR, "file name")) { return; } @@ -783,7 +783,7 @@ do_load(int argc, char *argv[]) return; } } - if (port_set) + if (port_set) host.sin_port = port; #endif if (chan >= CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS) { @@ -791,7 +791,7 @@ do_load(int argc, char *argv[]) return; } if (mode_str_set) { - for (io_tab = __RedBoot_LOAD_TAB__; + for (io_tab = __RedBoot_LOAD_TAB__; io_tab != &__RedBoot_LOAD_TAB_END__; io_tab++) { if (strncasecmp(&mode_str[0], io_tab->name, strlen(&mode_str[0])) == 0) { io = io_tab->funcs; @@ -800,7 +800,7 @@ do_load(int argc, char *argv[]) } if (!io) { diag_printf("Invalid 'mode': %s. Valid modes are:", mode_str); - for (io_tab = __RedBoot_LOAD_TAB__; + for (io_tab = __RedBoot_LOAD_TAB__; io_tab != &__RedBoot_LOAD_TAB_END__; io_tab++) { diag_printf(" %s", io_tab->name); } @@ -817,9 +817,9 @@ do_load(int argc, char *argv[]) } } else { char *which = ""; - io_tab = (struct load_io_entry *)NULL; // Default + io_tab = NULL; // Default #ifdef CYGPKG_REDBOOT_NETWORKING -#ifdef CYGSEM_REDBOOT_NET_TFTP_DOWNLOAD +#ifdef CYGSEM_REDBOOT_NET_TFTP_DOWNLOAD which = "TFTP"; io = &tftp_io; #elif defined(CYGSEM_REDBOOT_NET_HTTP_DOWNLOAD) @@ -860,7 +860,7 @@ do_load(int argc, char *argv[]) spillover_ok = true; } #endif - if (raw && !(base_addr_set + if (raw && !(base_addr_set #ifdef CYGBLD_REDBOOT_LOAD_INTO_FLASH || flash_addr_set #endif @@ -935,16 +935,15 @@ do_load(int argc, char *argv[]) *mp++ = res; } } - end = (unsigned long) mp; + end = (unsigned long)mp; // Save load base/top - load_address_end = end; - entry_address = base; // best guess + entry_address = base; // best guess redboot_getc_terminate(false); if (0 == err) - diag_printf("Raw file loaded %p-%p, assumed entry at %p\n", + diag_printf("Raw file loaded %p-%p, assumed entry at %p\n", (void *)load_address, (void *)(load_address_end - 1), (void*)entry_address); } else { // Read initial header - to determine file [image] type @@ -952,7 +951,7 @@ do_load(int argc, char *argv[]) if ((res = redboot_getc()) < 0) { err = getc_info.err; break; - } + } type[i] = res; } if (res >= 0) { @@ -972,8 +971,9 @@ do_load(int argc, char *argv[]) end = load_srec_image(redboot_getc, base, false); } } else { + unsigned long *tt = (unsigned long *)type; redboot_getc_terminate(true); - err_printf("Unrecognized image type: 0x%lx\n", *(unsigned long *)type); + err_printf("Unrecognized image type: 0x%lx\n", *tt); } } } diff --git a/packages/redboot/v2_0/src/main.c b/packages/redboot/v2_0/src/main.c index 9f1b3d8a..04d7cdf4 100644 --- a/packages/redboot/v2_0/src/main.c +++ b/packages/redboot/v2_0/src/main.c @@ -42,9 +42,9 @@ // Author(s): gthomas // Contributors: gthomas, tkoeller, eCosCentric // Date: 2000-07-14 -// Purpose: -// Description: -// +// Purpose: +// Description: +// // This code is part of RedBoot (tm). // //####DESCRIPTIONEND#### @@ -60,11 +60,11 @@ #include CYGHWR_MEMORY_LAYOUT_H #ifdef CYGPKG_IO_ETH_DRIVERS -#include // Logical driver interfaces +#include // Logical driver interfaces #endif #include -#include // assertion macros +#include // assertion macros #include #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS #ifdef CYGBLD_HAL_PLATFORM_STUB_H @@ -87,48 +87,48 @@ static void return_to_redboot(int status); // Address of area where current context is saved before executing // trampoline procedure -static void * saved_context; +static void *saved_context; // Status returned after trampoline execution static int return_status; - + // CLI command processing (defined in this file) -RedBoot_cmd("version", - "Display RedBoot version information", - "", - do_version - ); -RedBoot_cmd("help", - "Help about help?", - "[]", - do_help - ); +RedBoot_cmd("version", + "Display RedBoot version information", + "", + do_version + ); +RedBoot_cmd("help", + "Help about help?", + "[]", + do_help + ); static char go_usage[] = "[-w ] [-c] " #ifdef CYGPKG_IO_ETH_DRIVERS - "[-n] " + "[-n] " #endif - "[entry]"; + "[entry]"; -RedBoot_cmd("go", - "Execute code at a location", - go_usage, - do_go - ); +RedBoot_cmd("go", + "Execute code at a location", + go_usage, + do_go + ); #ifdef HAL_PLATFORM_RESET -RedBoot_cmd("reset", - "Reset the system", - "", - do_reset - ); +RedBoot_cmd("reset", + "Reset the system", + "", + do_reset + ); #endif #ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE -RedBoot_cmd("baudrate", - "Set/Query the system console baud rate", - "[-b ]", - do_baud_rate - ); +RedBoot_cmd("baudrate", + "Set/Query the system console baud rate", + "[-b ]", + do_baud_rate + ); #endif // Define table boundaries @@ -148,13 +148,13 @@ extern struct idle_tab_entry __RedBoot_IDLE_TAB__[], __RedBoot_IDLE_TAB_END__; extern void HAL_ARCH_PROGRAM_NEW_STACK(void *fun); #endif -// +// // [Null] Builtin [Power On] Self Test // void bist(void) CYGBLD_ATTRIB_WEAK; void -bist(void) +bist(void) { } @@ -165,33 +165,33 @@ void do_version(int argc, char *argv[]) { #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1 - int seg; + int seg; #endif #ifdef CYGPKG_REDBOOT_FLASH - externC void _flash_info(void); + externC void _flash_info(void); #endif - char *version = CYGACC_CALL_IF_MONITOR_VERSION(); + char *version = CYGACC_CALL_IF_MONITOR_VERSION(); - diag_printf(version); + diag_printf(version); #ifdef HAL_PLATFORM_CPU - diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA); + diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA); #endif - diag_printf("Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.\n"); - diag_printf("Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited\n\n"); - diag_printf("RAM: %p-%p, ", (void*)ram_start, (void*)ram_end); - diag_printf("[%p-%p]", mem_segments[0].start, mem_segments[0].end); - diag_printf(" available\n"); + diag_printf("Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.\n"); + diag_printf("Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited\n\n"); + diag_printf("RAM: %p-%p, ", (void*)ram_start, (void*)ram_end); + diag_printf("[%p-%p]", mem_segments[0].start, mem_segments[0].end); + diag_printf(" available\n"); #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1 - for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) { - if (mem_segments[seg].start != NO_MEMORY) { - diag_printf(" %p-%p, ", mem_segments[seg].start, mem_segments[seg].end); - diag_printf("[%p-%p]", mem_segments[seg].start, mem_segments[seg].end); - diag_printf(" available\n"); - } - } + for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) { + if (mem_segments[seg].start != NO_MEMORY) { + diag_printf(" %p-%p, ", mem_segments[seg].start, mem_segments[seg].end); + diag_printf("[%p-%p]", mem_segments[seg].start, mem_segments[seg].end); + diag_printf(" available\n"); + } + } #endif #ifdef CYGPKG_REDBOOT_FLASH - _flash_info(); + _flash_info(); #endif } @@ -203,22 +203,22 @@ do_version(int argc, char *argv[]) void do_idle(bool is_idle) { - struct idle_tab_entry *idle_entry; + struct idle_tab_entry *idle_entry; - for (idle_entry = __RedBoot_IDLE_TAB__; - idle_entry != &__RedBoot_IDLE_TAB_END__; idle_entry++) { - (*idle_entry->fun)(is_idle); - } + for (idle_entry = __RedBoot_IDLE_TAB__; + idle_entry != &__RedBoot_IDLE_TAB_END__; idle_entry++) { + (*idle_entry->fun)(is_idle); + } } // Wrapper used by diag_printf() static void _mon_write_char(char c, void *param) { - if (c == '\n') { - mon_write_char('\r'); - } - mon_write_char(c); + if (c == '\n') { + mon_write_char('\r'); + } + mon_write_char(c); } // @@ -226,11 +226,11 @@ _mon_write_char(char c, void *param) // static hal_jmp_buf error_jmpbuf; #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS -__externC void* volatile __mem_fault_handler; +__externC void *volatile __mem_fault_handler; static void error_handler(void) { - hal_longjmp(error_jmpbuf, 1); + hal_longjmp(error_jmpbuf, 1); } #endif @@ -242,392 +242,392 @@ static void error_handler(void) void cyg_start(void) { - int res = 0; - bool prompt = true; - static char line[CYGPKG_REDBOOT_MAX_CMD_LINE]; - char *command; - struct cmd *cmd; - int cur; - struct init_tab_entry *init_entry; - extern char RedBoot_version[]; + int res = 0; + bool prompt = true; + static char line[CYGPKG_REDBOOT_MAX_CMD_LINE]; + char *command; + struct cmd *cmd; + int cur; + struct init_tab_entry *init_entry; + extern char RedBoot_version[]; #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1 - int seg; + int seg; #endif - // Export version information - CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version); + // Export version information + CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version); - CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot); + CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot); - // Make sure the channels are properly initialized. - diag_init_putc(_mon_write_char); - hal_if_diag_init(); + // Make sure the channels are properly initialized. + diag_init_putc(_mon_write_char); + hal_if_diag_init(); - // Force console to output raw text - but remember the old setting - // so it can be restored if interaction with a debugger is - // required. - cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL); + // Force console to output raw text - but remember the old setting + // so it can be restored if interaction with a debugger is + // required. + cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL); #ifdef CYGPKG_REDBOOT_ANY_CONSOLE - console_selected = false; + console_selected = false; #endif - console_echo = true; + console_echo = true; - ram_start = (unsigned char *)CYGMEM_REGION_ram; - ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE); + ram_start = (unsigned char *)CYGMEM_REGION_ram; + ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE); #ifdef HAL_MEM_REAL_REGION_TOP - { - unsigned char *ram_end_tmp = ram_end; - ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp ); - } + { + unsigned char *ram_end_tmp = ram_end; + ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp ); + } #endif #ifdef CYGMEM_SECTION_heap1 - workspace_start = (unsigned char *)CYGMEM_SECTION_heap1; - workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE); + workspace_start = (unsigned char *)CYGMEM_SECTION_heap1; + workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE); #else - workspace_start = (unsigned char *)CYGMEM_REGION_ram; - workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE); + workspace_start = (unsigned char *)CYGMEM_REGION_ram; + workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE); #endif - if (ram_end < workspace_end) { - // when *less* SDRAM is installed than the possible maximum, - // but the heap1 region remains greater... - workspace_end = ram_end; - } + if (ram_end < workspace_end) { + // when *less* SDRAM is installed than the possible maximum, + // but the heap1 region remains greater... + workspace_end = ram_end; + } - workspace_end_init=workspace_end; + workspace_end_init = workspace_end; - // Nothing has ever been loaded into memory - entry_address = (unsigned long)NO_MEMORY; + // Nothing has ever been loaded into memory + entry_address = (unsigned long)NO_MEMORY; - bist(); + bist(); #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER) - fis_zlib_common_buffer = - workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE; + fis_zlib_common_buffer = + workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE; #endif #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT - script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT; + script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT; #endif - for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) { - (*init_entry->fun)(); - } + for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) { + (*init_entry->fun)(); + } - mem_segments[0].start = workspace_start; - mem_segments[0].end = workspace_end; + mem_segments[0].start = workspace_start; + mem_segments[0].end = workspace_end; #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1 - for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) { - cyg_plf_memory_segment(seg, &mem_segments[seg].start, &mem_segments[seg].end); - } + for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) { + cyg_plf_memory_segment(seg, &mem_segments[seg].start, &mem_segments[seg].end); + } #endif #ifdef CYGSEM_REDBOOT_PLF_STARTUP - cyg_plf_redboot_startup(); + cyg_plf_redboot_startup(); #endif - do_version(0,0); + do_version(0, 0); #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT # ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT - if (!script) { - script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT; - } -# endif - if (script) { - // Give the guy a chance to abort any boot script - unsigned char *hold_script = script; - int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION; - diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", - script_timeout_ms / 1000, script_timeout_ms % 1000); - script = NULL; - res = _GETS_CTRLC; // Treat 0 timeout as ^C - while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { - res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); - if (res >= _GETS_OK) { - diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", - script_timeout_ms / 1000, script_timeout_ms % 1000); - } else if (res != _GETS_TIMEOUT) { - break; - } - script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; + if (!script) { + script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT; } - if (res == _GETS_CTRLC) { - script = NULL; // Disable script - } else { - script = hold_script; // Re-enable script +# endif + if (script) { + // Give the guy a chance to abort any boot script + unsigned char *hold_script = script; + int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION; + diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", + script_timeout_ms / 1000, script_timeout_ms % 1000); + script = NULL; + res = _GETS_CTRLC; // Treat 0 timeout as ^C + while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { + res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); + if (res >= _GETS_OK) { + diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", + script_timeout_ms / 1000, script_timeout_ms % 1000); + } else if (res != _GETS_TIMEOUT) { + break; + } + script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; + } + if (res == _GETS_CTRLC) { + script = NULL; // Disable script + } else { + script = hold_script; // Re-enable script + } } - } -#endif - CYG_ASSERT(workspace_start < workspace_end, - "negative workspace size"); - while (true) { - if (prompt) { - diag_printf("RedBoot> "); - prompt = false; - } +#endif + CYG_ASSERT(workspace_start < workspace_end, + "negative workspace size"); + while (true) { + if (prompt) { + diag_printf("RedBoot> "); + prompt = false; + } #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 - cmd_history = true; // Enable history collection + cmd_history = true; // Enable history collection #endif - res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); + res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 - cmd_history = false; // Enable history collection + cmd_history = false; // Enable history collection #endif - if (res == _GETS_TIMEOUT) { - // No input arrived - } else { + if (res == _GETS_TIMEOUT) { + // No input arrived + } else { #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - if (res == _GETS_GDB) { - int dbgchan; - hal_virtual_comm_table_t *__chan; - int i; - // Special case of '$' - need to start GDB protocol - gdb_active = true; - // Mask interrupts on all channels - for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) { - CYGACC_CALL_IF_SET_CONSOLE_COMM(i); - __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE ); - } - - CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); - - // set up a temporary context that will take us to the trampoline - HAL_THREAD_INIT_CONTEXT(workspace_end, - breakpoint, trampoline,0); - - // switch context to trampoline (get GDB stubs started) - HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end); - - gdb_active = false; - - dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan); - } else + if (res == _GETS_GDB) { + int dbgchan; + hal_virtual_comm_table_t *__chan; + int i; + // Special case of '$' - need to start GDB protocol + gdb_active = true; + // Mask interrupts on all channels + for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) { + CYGACC_CALL_IF_SET_CONSOLE_COMM(i); + __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE ); + } + + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); + + // set up a temporary context that will take us to the trampoline + HAL_THREAD_INIT_CONTEXT(workspace_end, + breakpoint, trampoline,0); + + // switch context to trampoline (get GDB stubs started) + HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end); + + gdb_active = false; + + dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan); + } else #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - { - expand_aliases(line, sizeof(line)); - command = line; - if ((*command == '#') || (*command == '=')) { - // Special cases - if (*command == '=') { - // Print line on console - diag_printf("%s\n", &line[2]); - } - } else { - while (strlen(command) > 0) { - if ((cmd = parse(&command, &argc, &argv[0])) != NULL) { - // Try to handle aborts - messy because of the stack unwinding... + { + expand_aliases(line, sizeof(line)); + command = line; + if ((*command == '#') || (*command == '=')) { + // Special cases + if (*command == '=') { + // Print line on console + diag_printf("%s\n", &line[2]); + } + } else { + while (strlen(command) > 0) { + if ((cmd = parse(&command, &argc, &argv[0])) != NULL) { + // Try to handle aborts - messy because of the stack unwinding... #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - __mem_fault_handler = error_handler; + __mem_fault_handler = error_handler; #endif - if (hal_setjmp(error_jmpbuf)) { - diag_printf("** command abort - illegal memory access?\n"); - } else { - (cmd->fun)(argc, argv); - } + if (hal_setjmp(error_jmpbuf)) { + diag_printf("** command abort - illegal memory access?\n"); + } else { + (cmd->fun)(argc, argv); + } #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - __mem_fault_handler = 0; -#endif - } else { - diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]); - } - } - } - prompt = true; - } - } - } + __mem_fault_handler = 0; +#endif + } else { + diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]); + } + } + } + prompt = true; + } + } + } } void show_help(struct cmd *cmd, struct cmd *cmd_end, char *which, char *pre) { - bool show; - int len = 0; - - if (which) { - len = strlen(which); - } - while (cmd != cmd_end) { - show = true; - if (which && (strncasecmp(which, cmd->str, len) != 0)) { - show = false; - } - if (show) { - diag_printf("%s\n %s %s %s\n", cmd->help, pre, cmd->str, cmd->usage); - if ((cmd->sub_cmds != NULL) && (which != NULL)) { - show_help(cmd->sub_cmds, cmd->sub_cmds_end, 0, cmd->str); - } - } - cmd++; - } + bool show; + int len = 0; + + if (which) { + len = strlen(which); + } + while (cmd != cmd_end) { + show = true; + if (which && (strncasecmp(which, cmd->str, len) != 0)) { + show = false; + } + if (show) { + diag_printf("%s\n %s %s %s\n", cmd->help, pre, cmd->str, cmd->usage); + if ((cmd->sub_cmds != NULL) && (which != NULL)) { + show_help(cmd->sub_cmds, cmd->sub_cmds_end, 0, cmd->str); + } + } + cmd++; + } } void do_help(int argc, char *argv[]) { - struct cmd *cmd; - char *which = NULL; - - if (!scan_opts(argc, argv, 1, 0, 0, &which, OPTION_ARG_TYPE_STR, "")) { - diag_printf("Invalid argument\n"); - return; - } - cmd = __RedBoot_CMD_TAB__; - show_help(cmd, &__RedBoot_CMD_TAB_END__, which, ""); - return; + struct cmd *cmd; + char *which = NULL; + + if (!scan_opts(argc, argv, 1, NULL, 0, &which, OPTION_ARG_TYPE_STR, "")) { + diag_printf("Invalid argument\n"); + return; + } + cmd = __RedBoot_CMD_TAB__; + show_help(cmd, &__RedBoot_CMD_TAB_END__, which, ""); + return; } static void trampoline(unsigned long entry) { - typedef void code_fun(void); - code_fun *fun = (code_fun *)entry; - unsigned long oldints; + typedef void code_fun(void); + code_fun *fun = (code_fun *)entry; + unsigned long oldints; - HAL_DISABLE_INTERRUPTS(oldints); + HAL_DISABLE_INTERRUPTS(oldints); #ifdef HAL_ARCH_PROGRAM_NEW_STACK - HAL_ARCH_PROGRAM_NEW_STACK(fun); + HAL_ARCH_PROGRAM_NEW_STACK(fun); #else - (*fun)(); + (*fun)(); #endif - HAL_THREAD_LOAD_CONTEXT(&saved_context); + HAL_THREAD_LOAD_CONTEXT(&saved_context); } static void return_to_redboot(int status) { - CYGARC_HAL_SAVE_GP(); + CYGARC_HAL_SAVE_GP(); - return_status = status; - HAL_THREAD_LOAD_CONTEXT(&saved_context); - // never returns + return_status = status; + HAL_THREAD_LOAD_CONTEXT(&saved_context); + // never returns - // need this to balance above CYGARC_HAL_SAVE_GP on - // some platforms. It will never run, though. - CYGARC_HAL_RESTORE_GP(); + // need this to balance above CYGARC_HAL_SAVE_GP on + // some platforms. It will never run, though. + CYGARC_HAL_RESTORE_GP(); } void do_go(int argc, char *argv[]) { - int i, cur, num_options = 0; - unsigned long entry; - unsigned long oldints; - bool wait_time_set; - int wait_time, res; - bool cache_enabled = false; + int i, cur, num_options = 0; + unsigned long entry; + unsigned long oldints; + bool wait_time_set; + int wait_time, res; + bool cache_enabled = false; #ifdef CYGPKG_IO_ETH_DRIVERS - bool stop_net = false; + bool stop_net = false; #endif - struct option_info opts[3]; - char line[8]; - hal_virtual_comm_table_t *__chan; + struct option_info opts[3]; + char line[8]; + hal_virtual_comm_table_t *__chan; #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - __mem_fault_handler = 0; // Let GDB handle any faults directly + __mem_fault_handler = 0; // Let GDB handle any faults directly #endif - entry = entry_address; // Default from last 'load' operation - init_opts(&opts[num_options++], 'w', true, OPTION_ARG_TYPE_NUM, - &wait_time, &wait_time_set, "wait timeout"); - init_opts(&opts[num_options++], 'c', false, OPTION_ARG_TYPE_FLG, - &cache_enabled, NULL, "go with caches enabled"); + entry = entry_address; // Default from last 'load' operation + init_opts(&opts[num_options++], 'w', true, OPTION_ARG_TYPE_NUM, + &wait_time, &wait_time_set, "wait timeout"); + init_opts(&opts[num_options++], 'c', false, OPTION_ARG_TYPE_FLG, + &cache_enabled, NULL, "go with caches enabled"); #ifdef CYGPKG_IO_ETH_DRIVERS - init_opts(&opts[num_options++], 'n', false, OPTION_ARG_TYPE_FLG, - &stop_net, NULL, "go with network driver stopped"); -#endif - - CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); - - if (!scan_opts(argc, argv, 1, opts, num_options, &entry, - OPTION_ARG_TYPE_NUM, "starting address")) { - return; - } - if (entry == (unsigned long)NO_MEMORY) { - err_printf("No entry point known - aborted\n"); - return; - } - if (wait_time_set) { - int script_timeout_ms = wait_time * 1000; + init_opts(&opts[num_options++], 'n', false, OPTION_ARG_TYPE_FLG, + &stop_net, NULL, "go with network driver stopped"); +#endif + + CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); + + if (!scan_opts(argc, argv, 1, opts, num_options, &entry, + OPTION_ARG_TYPE_NUM, "starting address")) { + return; + } + if (entry == (unsigned long)NO_MEMORY) { + err_printf("No entry point known - aborted\n"); + return; + } + if (wait_time_set) { + int script_timeout_ms = wait_time * 1000; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG - unsigned char *hold_script = script; - script = NULL; -#endif - diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", - (void *)entry, wait_time); - while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { - res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); - if (res == _GETS_CTRLC) { + unsigned char *hold_script = script; + script = NULL; +#endif + diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", + (void *)entry, wait_time); + while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { + res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); + if (res == _GETS_CTRLC) { #ifdef CYGSEM_REDBOOT_FLASH_CONFIG - script = hold_script; // Re-enable script -#endif - return; - } - script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; - } - } - - // Mask interrupts on all channels - cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) { - CYGACC_CALL_IF_SET_CONSOLE_COMM(i); - __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE ); - } - CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); + script = hold_script; // Re-enable script +#endif + return; + } + script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; + } + } - __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH); + // Mask interrupts on all channels + cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) { + CYGACC_CALL_IF_SET_CONSOLE_COMM(i); + __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE ); + } + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); + + __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH); #ifdef CYGPKG_IO_ETH_DRIVERS - if (stop_net) - eth_drv_stop(); -#endif - - HAL_DISABLE_INTERRUPTS(oldints); - HAL_DCACHE_SYNC(); - if (!cache_enabled) { - HAL_ICACHE_DISABLE(); - HAL_DCACHE_DISABLE(); + if (stop_net) + eth_drv_stop(); +#endif + + HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); - } - HAL_ICACHE_INVALIDATE_ALL(); - HAL_DCACHE_INVALIDATE_ALL(); - // set up a temporary context that will take us to the trampoline - HAL_THREAD_INIT_CONTEXT(workspace_end, - entry, trampoline, 0); + if (!cache_enabled) { + HAL_ICACHE_DISABLE(); + HAL_DCACHE_DISABLE(); + HAL_DCACHE_SYNC(); + } + HAL_ICACHE_INVALIDATE_ALL(); + HAL_DCACHE_INVALIDATE_ALL(); + // set up a temporary context that will take us to the trampoline + HAL_THREAD_INIT_CONTEXT(workspace_end, + entry, trampoline, 0); - // switch context to trampoline - HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end); + // switch context to trampoline + HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end); - // we get back here by way of return_to_redboot() + // we get back here by way of return_to_redboot() - // undo the changes we made before switching context - if (!cache_enabled) { - HAL_ICACHE_ENABLE(); - HAL_DCACHE_ENABLE(); - } + // undo the changes we made before switching context + if (!cache_enabled) { + HAL_ICACHE_ENABLE(); + HAL_DCACHE_ENABLE(); + } - CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH); + CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH); - HAL_RESTORE_INTERRUPTS(oldints); + HAL_RESTORE_INTERRUPTS(oldints); - diag_printf("\nProgram completed with status %d\n", return_status); + diag_printf("\nProgram completed with status %d\n", return_status); } #ifdef HAL_PLATFORM_RESET void do_reset(int argc, char *argv[]) { - diag_printf("... Resetting."); - CYGACC_CALL_IF_DELAY_US(2*100000); - diag_printf("\n"); - CYGACC_CALL_IF_RESET(); - diag_printf("!! oops, RESET not working on this platform\n"); + diag_printf("... Resetting."); + CYGACC_CALL_IF_DELAY_US(2 * 100000); + diag_printf("\n"); + CYGACC_CALL_IF_RESET(); + diag_printf("!! oops, RESET not working on this platform\n"); } #endif @@ -639,107 +639,107 @@ do_reset(int argc, char *argv[]) static int set_comm_baud_rate(hal_virtual_comm_table_t *chan, int rate) { - int current_rate; + int current_rate; - current_rate = CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_GETBAUD); - if (rate != current_rate) - return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate); + current_rate = CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_GETBAUD); + if (rate != current_rate) + return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate); - return 0; + return 0; } int set_console_baud_rate(int rate) { - int ret = -1; + int ret = -1; #ifdef CYGPKG_REDBOOT_ANY_CONSOLE - if (!console_selected) { - int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - int i; - // Set baud for all channels - for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++) { - CYGACC_CALL_IF_SET_CONSOLE_COMM(i); - ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate); - if (ret < 0) - break; - } - CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); - } else -#endif - ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate); - - if (ret < 0) - diag_printf("Setting console baud rate to %d failed\n", rate); - - return ret; + if (!console_selected) { + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + int i; + // Set baud for all channels + for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++) { + CYGACC_CALL_IF_SET_CONSOLE_COMM(i); + ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate); + if (ret < 0) + break; + } + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); + } else +#endif + ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate); + + if (ret < 0) + diag_printf("Setting console baud rate to %d failed\n", rate); + + return ret; } static void _sleep(int ms) { - int i; - for (i = 0; i < ms; i++) { - CYGACC_CALL_IF_DELAY_US((cyg_int32)1000); - } + int i; + for (i = 0; i < ms; i++) { + CYGACC_CALL_IF_DELAY_US((cyg_int32)1000); + } } void do_baud_rate(int argc, char *argv[]) { - int new_rate, ret, old_rate; - bool new_rate_set; - hal_virtual_comm_table_t *__chan; - struct option_info opts[1]; + int new_rate, ret, old_rate; + bool new_rate_set; + hal_virtual_comm_table_t *__chan; + struct option_info opts[1]; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG - struct config_option opt; -#endif - - init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, - &new_rate, &new_rate_set, "new baud rate"); - if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) { - return; - } - __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); - if (new_rate_set) { - diag_printf("Baud rate will be changed to %d - update your settings\n", new_rate); - _sleep(500); // Give serial time to flush - old_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD); - ret = set_console_baud_rate(new_rate); - if (ret < 0) { - if (old_rate > 0) { - // Try to restore - set_console_baud_rate(old_rate); - _sleep(500); // Give serial time to flush - diag_printf("\nret = %d\n", ret); - } - return; // Couldn't set the desired rate - } - // Make sure this new rate works or back off to previous value - // Sleep for a few seconds, then prompt to see if it works - _sleep(3000); // Give serial time to flush - if (!verify_action_with_timeout(5000, "Baud rate changed to %d", new_rate)) { - _sleep(500); // Give serial time to flush - set_console_baud_rate(old_rate); - _sleep(500); // Give serial time to flush - return; - } + struct config_option opt; +#endif + + init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, + &new_rate, &new_rate_set, "new baud rate"); + if (!scan_opts(argc, argv, 1, opts, 1, NULL, 0, "")) { + return; + } + __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); + if (new_rate_set) { + diag_printf("Baud rate will be changed to %d - update your settings\n", new_rate); + _sleep(500); // Give serial time to flush + old_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD); + ret = set_console_baud_rate(new_rate); + if (ret < 0) { + if (old_rate > 0) { + // Try to restore + set_console_baud_rate(old_rate); + _sleep(500); // Give serial time to flush + diag_printf("\nret = %d\n", ret); + } + return; // Couldn't set the desired rate + } + // Make sure this new rate works or back off to previous value + // Sleep for a few seconds, then prompt to see if it works + _sleep(3000); // Give serial time to flush + if (!verify_action_with_timeout(5000, "Baud rate changed to %d", new_rate)) { + _sleep(500); // Give serial time to flush + set_console_baud_rate(old_rate); + _sleep(500); // Give serial time to flush + return; + } #ifdef CYGSEM_REDBOOT_FLASH_CONFIG - opt.type = CONFIG_INT; - opt.enable = NULL; - opt.enable_sense = 1; - opt.key = "console_baud_rate"; - opt.dflt = new_rate; - flash_add_config(&opt, true); -#endif - } else { - ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD); - diag_printf("Baud rate = "); - if (ret <= 0) { - diag_printf("unknown\n"); - } else { - diag_printf("%d\n", ret); - } - } + opt.type = CONFIG_INT; + opt.enable = NULL; + opt.enable_sense = 1; + opt.key = "console_baud_rate"; + opt.dflt = new_rate; + flash_add_config(&opt, true); +#endif + } else { + ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD); + diag_printf("Baud rate = "); + if (ret <= 0) { + diag_printf("unknown\n"); + } else { + diag_printf("%d\n", ret); + } + } } #endif @@ -749,14 +749,14 @@ do_baud_rate(int argc, char *argv[]) bool valid_address(unsigned char *addr) { - int seg; - - for (seg = 0; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) { - if (mem_segments[seg].start != NO_MEMORY) { - if ((addr >= mem_segments[seg].start) && (addr < mem_segments[seg].end)) { - return true; - } - } - } - return false; + int seg; + + for (seg = 0; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) { + if (mem_segments[seg].start != NO_MEMORY) { + if ((addr >= mem_segments[seg].start) && (addr < mem_segments[seg].end)) { + return true; + } + } + } + return false; } diff --git a/packages/redboot/v2_0/src/net/net_io.c b/packages/redboot/v2_0/src/net/net_io.c index 2430ac07..499d5d74 100644 --- a/packages/redboot/v2_0/src/net/net_io.c +++ b/packages/redboot/v2_0/src/net/net_io.c @@ -44,9 +44,9 @@ // Author(s): gthomas // Contributors: gthomas // Date: 2000-07-14 -// Purpose: -// Description: -// +// Purpose: +// Description: +// // This code is part of RedBoot (tm). // //####DESCRIPTIONEND#### @@ -55,34 +55,34 @@ #include #include -#include // Helper functions -#include // HAL I/O interfaces +#include // Helper functions +#include // HAL I/O interfaces #include #include -#include // assertion macros +#include // assertion macros #ifdef CYGSEM_REDBOOT_FLASH_CONFIG #include RedBoot_config_option("GDB connection port", - gdb_port, - ALWAYS_ENABLED, true, - CONFIG_INT, - CYGNUM_REDBOOT_NETWORKING_TCP_PORT - ); + gdb_port, + ALWAYS_ENABLED, true, + CONFIG_INT, + CYGNUM_REDBOOT_NETWORKING_TCP_PORT + ); RedBoot_config_option("Network debug at boot time", - net_debug, - ALWAYS_ENABLED, true, - CONFIG_BOOL, - false - ); + net_debug, + ALWAYS_ENABLED, true, + CONFIG_BOOL, + false + ); #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1) RedBoot_config_option("Default network device", - net_device, - ALWAYS_ENABLED, true, - CONFIG_NETPORT, - CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE - ); + net_device, + ALWAYS_ENABLED, true, + CONFIG_NETPORT, + CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE + ); #endif // Note: the following options are related. If 'bootp' is false, then // the other values are used in the configuration. Because of the way @@ -96,58 +96,58 @@ RedBoot_config_option("Default network device", #define CYGSEM_REDBOOT_DEFAULT_NO_BOOTP 0 #endif RedBoot_config_option("Use BOOTP for network configuration", - bootp, - ALWAYS_ENABLED, true, - CONFIG_BOOL, - !CYGSEM_REDBOOT_DEFAULT_NO_BOOTP - ); + bootp, + ALWAYS_ENABLED, true, + CONFIG_BOOL, + !CYGSEM_REDBOOT_DEFAULT_NO_BOOTP + ); RedBoot_config_option("Local IP address", - bootp_my_ip, - "bootp", false, - CONFIG_IP, - 0 - ); + bootp_my_ip, + "bootp", false, + CONFIG_IP, + 0 + ); #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY RedBoot_config_option("Local IP address mask", - bootp_my_ip_mask, - "bootp", false, - CONFIG_IP, - 0 - ); + bootp_my_ip_mask, + "bootp", false, + CONFIG_IP, + 0 + ); RedBoot_config_option("Gateway IP address", - bootp_my_gateway_ip, - "bootp", false, - CONFIG_IP, - 0 - ); + bootp_my_gateway_ip, + "bootp", false, + CONFIG_IP, + 0 + ); #endif RedBoot_config_option("Default server IP address", - bootp_server_ip, - ALWAYS_ENABLED, true, - CONFIG_IP, - 0 - ); + bootp_server_ip, + ALWAYS_ENABLED, true, + CONFIG_IP, + 0 + ); // Note: the following options are related too. RedBoot_config_option("Force console for special debug messages", - info_console_force, - ALWAYS_ENABLED, true, - CONFIG_BOOL, - false - ); + info_console_force, + ALWAYS_ENABLED, true, + CONFIG_BOOL, + false + ); RedBoot_config_option("Console number for special debug messages", - info_console_number, - "info_console_force", true, - CONFIG_INT, - 0 - ); + info_console_number, + "info_console_force", true, + CONFIG_INT, + 0 + ); #endif #define TCP_CHANNEL CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS #ifdef DEBUG_TCP int show_tcp = 0; -#endif +#endif static tcp_socket_t tcp_sock; static int state; @@ -168,330 +168,330 @@ static void net_io_revert_console(void); static void net_io_putc(void*, cyg_uint8); // Special characters used by Telnet - must be interpretted here -#define TELNET_IAC 0xFF // Interpret as command (escape) -#define TELNET_IP 0xF4 // Interrupt process -#define TELNET_WILL 0xFB // I Will do XXX -#define TELNET_WONT 0xFC // I Won't do XXX -#define TELNET_DO 0xFD // Will you XXX -#define TELNET_DONT 0xFE // Don't you XXX -#define TELNET_TM 0x06 // Time marker (special DO/WONT after IP) +#define TELNET_IAC 0xFF // Interpret as command (escape) +#define TELNET_IP 0xF4 // Interrupt process +#define TELNET_WILL 0xFB // I Will do XXX +#define TELNET_WONT 0xFC // I Won't do XXX +#define TELNET_DO 0xFD // Will you XXX +#define TELNET_DONT 0xFE // Don't you XXX +#define TELNET_TM 0x06 // Time marker (special DO/WONT after IP) static cyg_bool -_net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch) +_net_io_getc_nonblock(void *__ch_data, cyg_uint8 *ch) { - if (in_buflen == 0) { - __tcp_poll(); - if (tcp_sock.state == _CLOSE_WAIT) { - // This connection is breaking - if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) { - __tcp_close(&tcp_sock); - return false; - } - } - if (tcp_sock.state == _CLOSED) { - // The connection is gone - net_io_revert_console(); - *ch = '\n'; - return true; - } - in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf)); - in_bufp = in_buf; + if (in_buflen == 0) { + __tcp_poll(); + if (tcp_sock.state == _CLOSE_WAIT) { + // This connection is breaking + if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) { + __tcp_close(&tcp_sock); + return false; + } + } + if (tcp_sock.state == _CLOSED) { + // The connection is gone + net_io_revert_console(); + *ch = '\n'; + return true; + } + in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf)); + in_bufp = in_buf; #ifdef DEBUG_TCP - if (show_tcp && (in_buflen > 0)) { - int old_console; - old_console = start_console(); - diag_printf("%s:%d\n", __FUNCTION__, __LINE__); - diag_dump_buf(in_buf, in_buflen); - end_console(old_console); - } + if (show_tcp && (in_buflen > 0)) { + int old_console; + old_console = start_console(); + diag_printf("%s:%d\n", __FUNCTION__, __LINE__); + diag_dump_buf(in_buf, in_buflen); + end_console(old_console); + } #endif // DEBUG_TCP - } - if (in_buflen) { - *ch = *in_bufp++; - in_buflen--; - return true; - } else { - return false; - } + } + if (in_buflen) { + *ch = *in_bufp++; + in_buflen--; + return true; + } else { + return false; + } } static cyg_bool -net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch) +net_io_getc_nonblock(void *__ch_data, cyg_uint8 *ch) { - cyg_uint8 esc; - - if (!_net_io_getc_nonblock(__ch_data, ch)) - return false; - - if (gdb_active || *ch != TELNET_IAC) - return true; - - // Telnet escape - need to read/handle more - while (!_net_io_getc_nonblock(__ch_data, &esc)) ; - - switch (esc) { - case TELNET_IAC: - // The other special case - escaped escape - return true; - case TELNET_IP: - // Special case for ^C == Interrupt Process - *ch = 0x03; - // Just in case the other end needs synchronizing - net_io_putc(__ch_data, TELNET_IAC); - net_io_putc(__ch_data, TELNET_WONT); - net_io_putc(__ch_data, TELNET_TM); - net_io_flush(); - return true; - case TELNET_DO: - // Telnet DO option - while (!_net_io_getc_nonblock(__ch_data, &esc)) ; - // Respond with WONT option - net_io_putc(__ch_data, TELNET_IAC); - net_io_putc(__ch_data, TELNET_WONT); - net_io_putc(__ch_data, esc); - return false; // Ignore this whole thing! - case TELNET_WILL: - // Telnet WILL option - while (!_net_io_getc_nonblock(__ch_data, &esc)) ; - // Respond with DONT option - net_io_putc(__ch_data, TELNET_IAC); - net_io_putc(__ch_data, TELNET_DONT); - net_io_putc(__ch_data, esc); - return false; // Ignore this whole thing! - default: - return false; - } + cyg_uint8 esc; + + if (!_net_io_getc_nonblock(__ch_data, ch)) + return false; + + if (gdb_active || *ch != TELNET_IAC) + return true; + + // Telnet escape - need to read/handle more + while (!_net_io_getc_nonblock(__ch_data, &esc)) ; + + switch (esc) { + case TELNET_IAC: + // The other special case - escaped escape + return true; + case TELNET_IP: + // Special case for ^C == Interrupt Process + *ch = 0x03; + // Just in case the other end needs synchronizing + net_io_putc(__ch_data, TELNET_IAC); + net_io_putc(__ch_data, TELNET_WONT); + net_io_putc(__ch_data, TELNET_TM); + net_io_flush(); + return true; + case TELNET_DO: + // Telnet DO option + while (!_net_io_getc_nonblock(__ch_data, &esc)) ; + // Respond with WONT option + net_io_putc(__ch_data, TELNET_IAC); + net_io_putc(__ch_data, TELNET_WONT); + net_io_putc(__ch_data, esc); + return false; // Ignore this whole thing! + case TELNET_WILL: + // Telnet WILL option + while (!_net_io_getc_nonblock(__ch_data, &esc)) ; + // Respond with DONT option + net_io_putc(__ch_data, TELNET_IAC); + net_io_putc(__ch_data, TELNET_DONT); + net_io_putc(__ch_data, esc); + return false; // Ignore this whole thing! + default: + return false; + } } static cyg_uint8 -net_io_getc(void* __ch_data) +net_io_getc(void *__ch_data) { - cyg_uint8 ch; - int idle_timeout = 10; // 10ms - - CYGARC_HAL_SAVE_GP(); - while (true) { - if (net_io_getc_nonblock(__ch_data, &ch)) break; - if (--idle_timeout == 0) { - net_io_flush(); - idle_timeout = 10; - } - } - CYGARC_HAL_RESTORE_GP(); - return ch; + cyg_uint8 ch; + int idle_timeout = 10; // 10ms + + CYGARC_HAL_SAVE_GP(); + while (true) { + if (net_io_getc_nonblock(__ch_data, &ch)) break; + if (--idle_timeout == 0) { + net_io_flush(); + idle_timeout = 10; + } + } + CYGARC_HAL_RESTORE_GP(); + return ch; } static void net_io_flush(void) { - int n; - char *bp = out_buf; + int n; + char *bp = out_buf; #ifdef DEBUG_TCP - if (show_tcp) { - int old_console; - old_console = start_console(); - diag_printf("%s.%d\n", __FUNCTION__, __LINE__); - diag_dump_buf(out_buf, out_buflen); - end_console(old_console); - } + if (show_tcp) { + int old_console; + old_console = start_console(); + diag_printf("%s.%d\n", __FUNCTION__, __LINE__); + diag_dump_buf(out_buf, out_buflen); + end_console(old_console); + } #endif // SHOW_TCP - n = __tcp_write_block(&tcp_sock, bp, out_buflen); - if (n < 0) { - // The connection is gone! - net_io_revert_console(); - } else { - out_buflen -= n; - bp += n; - } - out_bufp = out_buf; out_buflen = 0; - // Check interrupt flag - if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) { - CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); - cyg_hal_user_break(0); - } + n = __tcp_write_block(&tcp_sock, bp, out_buflen); + if (n < 0) { + // The connection is gone! + net_io_revert_console(); + } else { + out_buflen -= n; + bp += n; + } + out_bufp = out_buf; out_buflen = 0; + // Check interrupt flag + if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) { + CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); + cyg_hal_user_break(0); + } } static void -net_io_putc(void* __ch_data, cyg_uint8 c) +net_io_putc(void *__ch_data, cyg_uint8 c) { - static bool have_dollar, have_hash; - static int hash_count; - - CYGARC_HAL_SAVE_GP(); - *out_bufp++ = c; - if (c == '$') have_dollar = true; - if (have_dollar && (c == '#')) { - have_hash = true; - hash_count = 0; - } - if ((++out_buflen == sizeof(out_buf)) || - (flush_output_lines && c == '\n') || - (have_hash && (++hash_count == 3))) { - net_io_flush(); - have_dollar = false; - } - CYGARC_HAL_RESTORE_GP(); + static bool have_dollar, have_hash; + static int hash_count; + + CYGARC_HAL_SAVE_GP(); + *out_bufp++ = c; + if (c == '$') have_dollar = true; + if (have_dollar && (c == '#')) { + have_hash = true; + hash_count = 0; + } + if ((++out_buflen == sizeof(out_buf)) || + (flush_output_lines && c == '\n') || + (have_hash && (++hash_count == 3))) { + net_io_flush(); + have_dollar = false; + } + CYGARC_HAL_RESTORE_GP(); } static void -net_io_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len) +net_io_write(void *__ch_data, const cyg_uint8 *__buf, cyg_uint32 __len) { - int old_console; + int old_console; - old_console = start_console(); - diag_printf("%s.%d\n", __FUNCTION__, __LINE__); - end_console(old_console); + old_console = start_console(); + diag_printf("%s.%d\n", __FUNCTION__, __LINE__); + end_console(old_console); #if 0 - CYGARC_HAL_SAVE_GP(); + CYGARC_HAL_SAVE_GP(); - while(__len-- > 0) - net_io_putc(__ch_data, *__buf++); + while(__len-- > 0) + net_io_putc(__ch_data, *__buf++); - CYGARC_HAL_RESTORE_GP(); + CYGARC_HAL_RESTORE_GP(); #endif } static void -net_io_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) +net_io_read(void *__ch_data, cyg_uint8 *__buf, cyg_uint32 __len) { - int old_console; + int old_console; - old_console = start_console(); - diag_printf("%s.%d\n", __FUNCTION__, __LINE__); - end_console(old_console); + old_console = start_console(); + diag_printf("%s.%d\n", __FUNCTION__, __LINE__); + end_console(old_console); #if 0 - CYGARC_HAL_SAVE_GP(); + CYGARC_HAL_SAVE_GP(); - while(__len-- > 0) - *__buf++ = net_io_getc(__ch_data); + while(__len-- > 0) + *__buf++ = net_io_getc(__ch_data); - CYGARC_HAL_RESTORE_GP(); + CYGARC_HAL_RESTORE_GP(); #endif } static cyg_bool -net_io_getc_timeout(void* __ch_data, cyg_uint8* ch) +net_io_getc_timeout(void *__ch_data, cyg_uint8 *ch) { - int delay_count; - cyg_bool res; + int delay_count; + cyg_bool res; - CYGARC_HAL_SAVE_GP(); - net_io_flush(); // Make sure any output has been sent - delay_count = _timeout; + CYGARC_HAL_SAVE_GP(); + net_io_flush(); // Make sure any output has been sent + delay_count = _timeout; - for(;;) { - res = net_io_getc_nonblock(__ch_data, ch); - if (res || 0 == delay_count--) - break; - } + for(;;) { + res = net_io_getc_nonblock(__ch_data, ch); + if (res || 0 == delay_count--) + break; + } - CYGARC_HAL_RESTORE_GP(); + CYGARC_HAL_RESTORE_GP(); - return res; + return res; } static int net_io_control(void *__ch_data, __comm_control_cmd_t __func, ...) { - static int vector = 0; - int ret = 0; - static int irq_state = 0; - - CYGARC_HAL_SAVE_GP(); - - switch (__func) { - case __COMMCTL_IRQ_ENABLE: - irq_state = 1; - if (vector == 0) { - vector = eth_drv_int_vector(); - } - HAL_INTERRUPT_UNMASK(vector); - break; - case __COMMCTL_IRQ_DISABLE: - ret = irq_state; - irq_state = 0; - if (vector == 0) { - vector = eth_drv_int_vector(); - } - HAL_INTERRUPT_MASK(vector); - break; - case __COMMCTL_DBG_ISR_VECTOR: - ret = vector; - break; - case __COMMCTL_SET_TIMEOUT: - { - va_list ap; - - va_start(ap, __func); - - ret = _timeout; - _timeout = va_arg(ap, cyg_uint32); - - va_end(ap); - break; - } - case __COMMCTL_FLUSH_OUTPUT: - net_io_flush(); - break; - case __COMMCTL_ENABLE_LINE_FLUSH: - flush_output_lines = true; - break; - case __COMMCTL_DISABLE_LINE_FLUSH: - flush_output_lines = false; - break; - default: - break; - } - CYGARC_HAL_RESTORE_GP(); - return ret; + static int vector = 0; + int ret = 0; + static int irq_state = 0; + + CYGARC_HAL_SAVE_GP(); + + switch (__func) { + case __COMMCTL_IRQ_ENABLE: + irq_state = 1; + if (vector == 0) { + vector = eth_drv_int_vector(); + } + HAL_INTERRUPT_UNMASK(vector); + break; + case __COMMCTL_IRQ_DISABLE: + ret = irq_state; + irq_state = 0; + if (vector == 0) { + vector = eth_drv_int_vector(); + } + HAL_INTERRUPT_MASK(vector); + break; + case __COMMCTL_DBG_ISR_VECTOR: + ret = vector; + break; + case __COMMCTL_SET_TIMEOUT: + { + va_list ap; + + va_start(ap, __func); + + ret = _timeout; + _timeout = va_arg(ap, cyg_uint32); + + va_end(ap); + break; + } + case __COMMCTL_FLUSH_OUTPUT: + net_io_flush(); + break; + case __COMMCTL_ENABLE_LINE_FLUSH: + flush_output_lines = true; + break; + case __COMMCTL_DISABLE_LINE_FLUSH: + flush_output_lines = false; + break; + default: + break; + } + CYGARC_HAL_RESTORE_GP(); + return ret; } static int -net_io_isr(void *__ch_data, int* __ctrlc, - CYG_ADDRWORD __vector, CYG_ADDRWORD __data) +net_io_isr(void *__ch_data, int *__ctrlc, + CYG_ADDRWORD __vector, CYG_ADDRWORD __data) { - char ch; - - CYGARC_HAL_SAVE_GP(); - *__ctrlc = 0; - if (net_io_getc_nonblock(__ch_data, &ch)) { - if (ch == 0x03) { - *__ctrlc = 1; - } - } - CYGARC_HAL_RESTORE_GP(); - return CYG_ISR_HANDLED; + char ch; + + CYGARC_HAL_SAVE_GP(); + *__ctrlc = 0; + if (net_io_getc_nonblock(__ch_data, &ch)) { + if (ch == 0x03) { + *__ctrlc = 1; + } + } + CYGARC_HAL_RESTORE_GP(); + return CYG_ISR_HANDLED; } // TEMP -int +int start_console(void) { - int cur_console = - CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + int cur_console = + CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); #ifdef CYGSEM_REDBOOT_FLASH_CONFIG - int i = 0; - if ( flash_get_config( "info_console_force", &i, CONFIG_BOOL) ) - if ( i ) - if ( ! flash_get_config( "info_console_number", &i, CONFIG_INT) ) - i = 0; // the default, if that call failed. - if ( i ) - CYGACC_CALL_IF_SET_CONSOLE_COMM(i); - else -#endif - CYGACC_CALL_IF_SET_CONSOLE_COMM(0); - - return cur_console; + int i = 0; + if ( flash_get_config( "info_console_force", &i, CONFIG_BOOL) ) + if ( i ) + if ( ! flash_get_config( "info_console_number", &i, CONFIG_INT) ) + i = 0; // the default, if that call failed. + if ( i ) + CYGACC_CALL_IF_SET_CONSOLE_COMM(i); + else +#endif + CYGACC_CALL_IF_SET_CONSOLE_COMM(0); + + return cur_console; } void end_console(int old_console) { - // Restore original console - CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console); + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console); } // TEMP @@ -499,60 +499,60 @@ static void net_io_revert_console(void) { #ifdef CYGPKG_REDBOOT_ANY_CONSOLE - console_selected = false; + console_selected = false; #endif - CYGACC_CALL_IF_SET_CONSOLE_COMM(orig_console); - CYGACC_CALL_IF_SET_DEBUG_COMM(orig_debug); - console_echo = true; + CYGACC_CALL_IF_SET_CONSOLE_COMM(orig_console); + CYGACC_CALL_IF_SET_DEBUG_COMM(orig_debug); + console_echo = true; } static void net_io_assume_console(void) { #ifdef CYGPKG_REDBOOT_ANY_CONSOLE - console_selected = true; + console_selected = true; #endif - console_echo = false; - orig_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL); - orig_debug = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - CYGACC_CALL_IF_SET_DEBUG_COMM(TCP_CHANNEL); + console_echo = false; + orig_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL); + orig_debug = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + CYGACC_CALL_IF_SET_DEBUG_COMM(TCP_CHANNEL); } static void net_io_init(void) { - static int init = 0; - if (!init) { - hal_virtual_comm_table_t* comm; - int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - - // Setup procs in the vector table - CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL); - comm = CYGACC_CALL_IF_CONSOLE_PROCS(); - //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan); - CYGACC_COMM_IF_WRITE_SET(*comm, net_io_write); - CYGACC_COMM_IF_READ_SET(*comm, net_io_read); - CYGACC_COMM_IF_PUTC_SET(*comm, net_io_putc); - CYGACC_COMM_IF_GETC_SET(*comm, net_io_getc); - CYGACC_COMM_IF_CONTROL_SET(*comm, net_io_control); - CYGACC_COMM_IF_DBG_ISR_SET(*comm, net_io_isr); - CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, net_io_getc_timeout); - - // Disable interrupts via this interface to set static - // state into correct state. - net_io_control( comm, __COMMCTL_IRQ_DISABLE ); - - // Restore original console - CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); - - init = 1; - gdb_active = false; - } - __tcp_listen(&tcp_sock, gdb_port); - state = tcp_sock.state; + static int init = 0; + if (!init) { + hal_virtual_comm_table_t *comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + + // Setup procs in the vector table + CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL); + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan); + CYGACC_COMM_IF_WRITE_SET(*comm, net_io_write); + CYGACC_COMM_IF_READ_SET(*comm, net_io_read); + CYGACC_COMM_IF_PUTC_SET(*comm, net_io_putc); + CYGACC_COMM_IF_GETC_SET(*comm, net_io_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, net_io_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, net_io_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, net_io_getc_timeout); + + // Disable interrupts via this interface to set static + // state into correct state. + net_io_control( comm, __COMMCTL_IRQ_DISABLE ); + + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); + + init = 1; + gdb_active = false; + } + __tcp_listen(&tcp_sock, gdb_port); + state = tcp_sock.state; #ifdef DEBUG_TCP - diag_printf("show tcp = %p\n", (void *)&show_tcp); + diag_printf("show tcp = %p\n", &show_tcp); #endif } @@ -560,22 +560,22 @@ net_io_init(void) void net_io_test(bool is_idle) { - if (!is_idle) return; // Only care about idle case - if (!have_net) return; - __tcp_poll(); - if (state != tcp_sock.state) { - // Something has changed - if (tcp_sock.state == _ESTABLISHED) { - // A new connection has arrived - net_io_assume_console(); - in_bufp = in_buf; in_buflen = 1; *in_bufp = '\r'; - out_bufp = out_buf; out_buflen = 0; - } - if (tcp_sock.state == _CLOSED) { - net_io_init(); // Get ready for another connection - } - } - state = tcp_sock.state; + if (!is_idle) return; // Only care about idle case + if (!have_net) return; + __tcp_poll(); + if (state != tcp_sock.state) { + // Something has changed + if (tcp_sock.state == _ESTABLISHED) { + // A new connection has arrived + net_io_assume_console(); + in_bufp = in_buf; in_buflen = 1; *in_bufp = '\r'; + out_bufp = out_buf; out_buflen = 0; + } + if (tcp_sock.state == _CLOSED) { + net_io_init(); // Get ready for another connection + } + } + state = tcp_sock.state; } // This schedules the 'net_io_test()' function to be run by RedBoot's @@ -599,340 +599,341 @@ RedBoot_init(net_init, RedBoot_INIT_NET); static void show_addrs(void) { - diag_printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr)); + diag_printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr)); #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY - diag_printf("/%s", inet_ntoa((in_addr_t *)&__local_ip_mask)); - diag_printf(", Gateway: %s\n", inet_ntoa((in_addr_t *)&__local_ip_gate)); + diag_printf("/%s", inet_ntoa((in_addr_t *)&__local_ip_mask)); + diag_printf(", Gateway: %s\n", inet_ntoa((in_addr_t *)&__local_ip_gate)); #else - diag_printf(", "); + diag_printf(", "); #endif - diag_printf("Default server: %s", inet_ntoa(&my_bootp_info.bp_siaddr)); + diag_printf("Default server: %s", inet_ntoa(&my_bootp_info.bp_siaddr)); #ifdef CYGPKG_REDBOOT_NETWORKING_DNS - show_dns(); + show_dns(); #endif - diag_printf("\n"); + diag_printf("\n"); } #ifdef CYGSEM_REDBOOT_FLASH_CONFIG static void flash_get_IP(char *id, ip_addr_t *val) { - ip_addr_t my_ip; - int i; - - if (flash_get_config(id, &my_ip, CONFIG_IP)) { - if (my_ip[0] != 0 || my_ip[1] != 0 || - my_ip[2] != 0 || my_ip[3] != 0) { - // 'id' is set to something so let it override any static IP - for (i=0; i<4; i++) - (*val)[i] = my_ip[i]; - } - } + ip_addr_t my_ip; + int i; + + if (flash_get_config(id, &my_ip, CONFIG_IP)) { + if (my_ip[0] != 0 || my_ip[1] != 0 || + my_ip[2] != 0 || my_ip[3] != 0) { + // 'id' is set to something so let it override any static IP + for (i=0; i<4; i++) + (*val)[i] = my_ip[i]; + } + } } #endif static cyg_netdevtab_entry_t * net_devtab_entry(unsigned index) { - cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index]; + cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index]; - if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__) - return NULL; + if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__) + return NULL; - return t; + return t; } const char * net_devname(unsigned index) { - cyg_netdevtab_entry_t *t = net_devtab_entry(index); - if (t) - return t->name; - return NULL; + cyg_netdevtab_entry_t *t = net_devtab_entry(index); + if (t) + return t->name; + return NULL; } int net_devindex(char *name) { - const char *devname; - int index; + const char *devname; + int index; - for (index = 0; (devname = net_devname(index)) != NULL; index++) - if (!strcmp(name, devname)) - return index; - return -1; + for (index = 0; (devname = net_devname(index)) != NULL; index++) + if (!strcmp(name, devname)) + return index; + return -1; } static void show_eth_info(void) { - diag_printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", - __local_enet_sc->dev_name, - __local_enet_addr[0], - __local_enet_addr[1], - __local_enet_addr[2], - __local_enet_addr[3], - __local_enet_addr[4], - __local_enet_addr[5]); + diag_printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", + __local_enet_sc->dev_name, + __local_enet_addr[0], + __local_enet_addr[1], + __local_enet_addr[2], + __local_enet_addr[3], + __local_enet_addr[4], + __local_enet_addr[5]); } void net_init(void) { - cyg_netdevtab_entry_t *t; - unsigned index; - struct eth_drv_sc *primary_net = (struct eth_drv_sc *)0; + cyg_netdevtab_entry_t *t; + unsigned index; + struct eth_drv_sc *primary_net = (struct eth_drv_sc *)0; #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1) - char *default_devname = CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE; - int default_index; + char *default_devname = CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE; + int default_index; #endif #ifdef CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR - char ip_addr[16]; + char ip_addr[16]; #endif - // Set defaults as appropriate + // Set defaults as appropriate #ifdef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP - use_bootp = false; + use_bootp = false; #else - use_bootp = true; + use_bootp = true; #endif #ifdef CYGDBG_REDBOOT_NET_DEBUG - net_debug = true; + net_debug = true; #else - net_debug = false; + net_debug = false; #endif - gdb_port = CYGNUM_REDBOOT_NETWORKING_TCP_PORT; + gdb_port = CYGNUM_REDBOOT_NETWORKING_TCP_PORT; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG - // Fetch values from saved config data, if available + // Fetch values from saved config data, if available #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1) - flash_get_config("net_device", &default_devname, CONFIG_NETPORT); + flash_get_config("net_device", &default_devname, CONFIG_NETPORT); #endif - flash_get_config("net_debug", &net_debug, CONFIG_BOOL); - flash_get_config("gdb_port", &gdb_port, CONFIG_INT); - flash_get_config("bootp", &use_bootp, CONFIG_BOOL); - if (!use_bootp) { - flash_get_IP("bootp_my_ip", &__local_ip_addr); + flash_get_config("net_debug", &net_debug, CONFIG_BOOL); + flash_get_config("gdb_port", &gdb_port, CONFIG_INT); + flash_get_config("bootp", &use_bootp, CONFIG_BOOL); + if (!use_bootp) { + flash_get_IP("bootp_my_ip", &__local_ip_addr); #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY - flash_get_IP("bootp_my_ip_mask", &__local_ip_mask); - flash_get_IP("bootp_my_gateway_ip", &__local_ip_gate); + flash_get_IP("bootp_my_ip_mask", &__local_ip_mask); + flash_get_IP("bootp_my_gateway_ip", &__local_ip_gate); #endif - } + } #endif # ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG - // Don't override if the user has deliberately set something more - // verbose. - if (0 == cyg_io_eth_net_debug) - cyg_io_eth_net_debug = net_debug; + // Don't override if the user has deliberately set something more + // verbose. + if (0 == cyg_io_eth_net_debug) + cyg_io_eth_net_debug = net_debug; # endif - have_net = false; - // Make sure the recv buffers are set up - eth_drv_buffers_init(); - __pktbuf_init(); + have_net = false; + // Make sure the recv buffers are set up + eth_drv_buffers_init(); + __pktbuf_init(); - // Initialize network device(s). + // Initialize network device(s). #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1) - default_index = net_devindex(default_devname); - if (default_index < 0) - default_index = 0; + default_index = net_devindex(default_devname); + if (default_index < 0) + default_index = 0; #ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE - if ((t = net_devtab_entry(default_index)) != NULL && t->init(t)) { - t->status = CYG_NETDEVTAB_STATUS_AVAIL; - primary_net = __local_enet_sc; - } else + if ((t = net_devtab_entry(default_index)) != NULL && t->init(t)) { + t->status = CYG_NETDEVTAB_STATUS_AVAIL; + primary_net = __local_enet_sc; + } else #endif #endif // (CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1) - for (index = 0; (t = net_devtab_entry(index)) != NULL; index++) { + for (index = 0; (t = net_devtab_entry(index)) != NULL; index++) { #ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE - if (index == default_index) - continue; -#endif - if (t->init(t)) { - t->status = CYG_NETDEVTAB_STATUS_AVAIL; - if (primary_net == (struct eth_drv_sc *)0) { - primary_net = __local_enet_sc; - } + if (index == default_index) + continue; +#endif + if (t->init(t)) { + t->status = CYG_NETDEVTAB_STATUS_AVAIL; + if (primary_net == (struct eth_drv_sc *)0) { + primary_net = __local_enet_sc; + } #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1) # ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE - break; + break; # else - if (index == default_index) { - primary_net = __local_enet_sc; - } + if (index == default_index) { + primary_net = __local_enet_sc; + } # endif // CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE #endif - } - } - __local_enet_sc = primary_net; - - if (!__local_enet_sc) { - diag_printf("No network interfaces found\n"); - return; - } - // Initialize the network [if present] - if (use_bootp) { - if (__bootp_find_local_ip(&my_bootp_info) == 0) { - have_net = true; - } else { - // Is it an unset address, or has it been set to a static addr - if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 && - __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) { - show_eth_info(); - diag_printf("Can't get BOOTP info for device!\n"); - } else { - diag_printf("Can't get BOOTP info, using default IP address\n"); - have_net = true; - } - } - } else { - if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 && - __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) { - show_eth_info(); - diag_printf("No IP info for device!\n"); - } else { - enet_addr_t enet_addr; - have_net = true; // Assume values in FLASH were OK - // Tell the world that we are using this fixed IP address - if (__arp_request((ip_addr_t *)__local_ip_addr, &enet_addr, 1) >= 0) { - diag_printf("Warning: IP address %s in use\n", - inet_ntoa((in_addr_t *)&__local_ip_addr)); - } - } - } - if (have_net) { - show_eth_info(); + } + } + __local_enet_sc = primary_net; + + if (!__local_enet_sc) { + diag_printf("No network interfaces found\n"); + return; + } + // Initialize the network [if present] + if (use_bootp) { + if (__bootp_find_local_ip(&my_bootp_info) == 0) { + have_net = true; + } else { + // Is it an unset address, or has it been set to a static addr + if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 && + __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) { + show_eth_info(); + diag_printf("Can't get BOOTP info for device!\n"); + } else { + diag_printf("Can't get BOOTP info, using default IP address\n"); + have_net = true; + } + } + } else { + if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 && + __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) { + show_eth_info(); + diag_printf("No IP info for device!\n"); + } else { + enet_addr_t enet_addr; + have_net = true; // Assume values in FLASH were OK + // Tell the world that we are using this fixed IP address + if (__arp_request((ip_addr_t *)__local_ip_addr, &enet_addr, 1) >= 0) { + diag_printf("Warning: IP address %s in use\n", + inet_ntoa((in_addr_t *)&__local_ip_addr)); + } + } + } + if (have_net) { + show_eth_info(); #ifdef CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR - diag_sprintf(ip_addr, "%d.%d.%d.%d", - CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR); - inet_aton(ip_addr, &my_bootp_info.bp_siaddr); + diag_sprintf(ip_addr, "%d.%d.%d.%d", + CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR); + inet_aton(ip_addr, &my_bootp_info.bp_siaddr); #endif #ifdef CYGSEM_REDBOOT_FLASH_CONFIG - flash_get_IP("bootp_server_ip", (ip_addr_t *)&my_bootp_info.bp_siaddr); + flash_get_IP("bootp_server_ip", (ip_addr_t *)&my_bootp_info.bp_siaddr); #endif #ifdef CYGPKG_REDBOOT_NETWORKING_DNS - redboot_dns_res_init(); + redboot_dns_res_init(); #endif - show_addrs(); - net_io_init(); - } + show_addrs(); + net_io_init(); + } } static char usage[] = "[-b] [-l [/]] [-h ]" #ifdef CYGPKG_REDBOOT_NETWORKING_DNS " [-d ]" -#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN - " [-D ]" +#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN + " [-D ]" #endif #endif - ; + ; // Exported CLI function static void do_ip_addr(int argc, char *argv[]); -RedBoot_cmd("ip_address", - "Set/change IP addresses", - usage, - do_ip_addr - ); +RedBoot_cmd("ip_address", + "Set/change IP addresses", + usage, + do_ip_addr + ); -void +void do_ip_addr(int argc, char *argv[]) { - struct option_info opts[5]; - char *ip_addr, *host_addr; - bool ip_addr_set, host_addr_set; - bool do_bootp = false; - struct sockaddr_in host; + struct option_info opts[5]; + char *ip_addr, *host_addr; + bool ip_addr_set, host_addr_set; + bool do_bootp = false; + struct sockaddr_in host; #ifdef CYGPKG_REDBOOT_NETWORKING_DNS - char *dns_addr; - bool dns_addr_set; -#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN - char *dns_domain; - bool dns_domain_set; -#endif -#endif - int num_opts; - - if (!have_net) { - net_init(); - } - if (!have_net) { - diag_printf("Sorry, networking is not available.\n"); - return; - } - - init_opts(&opts[0], 'l', true, OPTION_ARG_TYPE_STR, - &ip_addr, &ip_addr_set, "local IP address"); - init_opts(&opts[1], 'h', true, OPTION_ARG_TYPE_STR, - &host_addr, &host_addr_set, "default server address"); - init_opts(&opts[2], 'b', false, OPTION_ARG_TYPE_FLG, - &do_bootp, 0, "use BOOTP"); - num_opts = 3; + char *dns_addr; + bool dns_addr_set; +#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN + char *dns_domain; + bool dns_domain_set; +#endif +#endif + int num_opts; + + if (!have_net) { + net_init(); + } +#if 0 + if (!have_net) { + diag_printf("Sorry, networking is not available.\n"); + return; + } +#endif + init_opts(&opts[0], 'l', true, OPTION_ARG_TYPE_STR, + &ip_addr, &ip_addr_set, "local IP address"); + init_opts(&opts[1], 'h', true, OPTION_ARG_TYPE_STR, + &host_addr, &host_addr_set, "default server address"); + init_opts(&opts[2], 'b', false, OPTION_ARG_TYPE_FLG, + &do_bootp, 0, "use BOOTP"); + num_opts = 3; #ifdef CYGPKG_REDBOOT_NETWORKING_DNS - init_opts(&opts[num_opts], 'd', true, OPTION_ARG_TYPE_STR, - (void *)&dns_addr, (bool *)&dns_addr_set, "DNS server address"); - num_opts++; -#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN - init_opts(&opts[num_opts], 'D', true, OPTION_ARG_TYPE_STR, - (void *)&dns_domain, (bool *)&dns_domain_set, "DNS domain"); - num_opts++; -#endif -#endif - CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options"); - - if (!scan_opts(argc, argv, 1, opts, num_opts, 0, 0, "")) { - return; - } - if (do_bootp) { - if (__bootp_find_local_ip(&my_bootp_info) != 0) { - diag_printf("Failed to get BOOTP address\n"); - } - } - if (ip_addr_set) { + init_opts(&opts[num_opts], 'd', true, OPTION_ARG_TYPE_STR, + &dns_addr, &dns_addr_set, "DNS server address"); + num_opts++; +#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN + init_opts(&opts[num_opts], 'D', true, OPTION_ARG_TYPE_STR, + &dns_domain, &dns_domain_set, "DNS domain"); + num_opts++; +#endif +#endif + CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options"); + + if (!scan_opts(argc, argv, 1, opts, num_opts, 0, 0, "")) { + return; + } + if (do_bootp) { + if (__bootp_find_local_ip(&my_bootp_info) != 0) { + diag_printf("Failed to get BOOTP address\n"); + } + } + if (ip_addr_set) { #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY - char *slash_pos; - /* see if the (optional) mask length was given */ - if( (slash_pos = strchr(ip_addr, '/')) ) { - unsigned long mask_len; - unsigned long mask; - *slash_pos = '\0'; - slash_pos++; - if( !parse_num(slash_pos, &mask_len, 0, 0) || - mask_len <= 0 || mask_len > 32 ) { - diag_printf("Invalid mask length: %s\n", slash_pos); - return; - } - mask = htonl((0xffffffff << (32-mask_len))&0xffffffff); - memcpy(&__local_ip_mask, &mask, 4); - } -#endif - if (!_gethostbyname(ip_addr, (in_addr_t *)&host)) { - diag_printf("Invalid local IP address: %s\n", ip_addr); - return; - } - // Of course, each address goes in its own place :-) - memcpy(&__local_ip_addr, &host.sin_addr, sizeof(host.sin_addr)); - } - if (host_addr_set) { - if (!_gethostbyname(host_addr, (in_addr_t *)&host)) { - diag_printf("Invalid server address: %s\n", host_addr); - return; - } - my_bootp_info.bp_siaddr = host.sin_addr; - } + char *slash_pos; + /* see if the (optional) mask length was given */ + if( (slash_pos = strchr(ip_addr, '/')) ) { + unsigned long mask_len; + unsigned long mask; + *slash_pos = '\0'; + slash_pos++; + if( !parse_num(slash_pos, &mask_len, 0, 0) || + mask_len <= 0 || mask_len > 32 ) { + diag_printf("Invalid mask length: %s\n", slash_pos); + return; + } + mask = htonl((~0 << (32 - mask_len)) & ~0); + memcpy(&__local_ip_mask, &mask, 4); + } +#endif + if (!_gethostbyname(ip_addr, (in_addr_t *)&host)) { + diag_printf("Invalid local IP address: %s\n", ip_addr); + return; + } + // Of course, each address goes in its own place :-) + memcpy(&__local_ip_addr, &host.sin_addr, sizeof(host.sin_addr)); + } + if (host_addr_set) { + if (!_gethostbyname(host_addr, (in_addr_t *)&host)) { + diag_printf("Invalid server address: %s\n", host_addr); + return; + } + my_bootp_info.bp_siaddr = host.sin_addr; + } #ifdef CYGPKG_REDBOOT_NETWORKING_DNS - if (dns_addr_set) { - set_dns(dns_addr); - } -#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN - if (dns_domain_set) { - setdomainname(dns_domain, strlen(dns_domain)); - } -#endif -#endif - show_addrs(); - if (!have_net) { - have_net = true; - net_io_init(); - } + if (dns_addr_set) { + set_dns(dns_addr); + } +#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN + if (dns_domain_set) { + setdomainname(dns_domain, strlen(dns_domain)); + } +#endif +#endif + show_addrs(); + if (!have_net) { + have_net = true; + net_io_init(); + } } // EOF net_io.c diff --git a/packages/redboot/v2_0/src/net/tcp.c b/packages/redboot/v2_0/src/net/tcp.c index a8d36396..0ae62445 100644 --- a/packages/redboot/v2_0/src/net/tcp.c +++ b/packages/redboot/v2_0/src/net/tcp.c @@ -44,9 +44,9 @@ // Author(s): gthomas // Contributors: gthomas // Date: 2000-07-14 -// Purpose: -// Description: -// +// Purpose: +// Description: +// // This code is part of RedBoot (tm). // //####DESCRIPTIONEND#### @@ -58,7 +58,7 @@ #include #define MAX_TCP_SEGMENT (ETH_MAX_PKTLEN - (sizeof(eth_header_t) + sizeof(ip_header_t))) -#define MAX_TCP_DATA (MAX_TCP_SEGMENT - sizeof(tcp_header_t)) +#define MAX_TCP_DATA (MAX_TCP_SEGMENT - sizeof(tcp_header_t)) /* sequence number comparison macros */ @@ -77,24 +77,24 @@ static void do_close(void *p); static char * flags_to_str(octet f) { - static char str[7], *p; - - p = str; - - if (f & TCP_FLAG_FIN) - *p++ = 'F'; - if (f & TCP_FLAG_SYN) - *p++ = 'S'; - if (f & TCP_FLAG_RST) - *p++ = 'R'; - if (f & TCP_FLAG_PSH) - *p++ = 'P'; - if (f & TCP_FLAG_ACK) - *p++ = 'A'; - if (f & TCP_FLAG_URG) - *p++ = 'U'; - *p = '\0'; - return str; + static char str[7], *p; + + p = str; + + if (f & TCP_FLAG_FIN) + *p++ = 'F'; + if (f & TCP_FLAG_SYN) + *p++ = 'S'; + if (f & TCP_FLAG_RST) + *p++ = 'R'; + if (f & TCP_FLAG_PSH) + *p++ = 'P'; + if (f & TCP_FLAG_ACK) + *p++ = 'A'; + if (f & TCP_FLAG_URG) + *p++ = 'U'; + *p = '\0'; + return str; } #endif @@ -110,76 +110,82 @@ static tcp_socket_t *tcp_list; static void tcp_send(tcp_socket_t *s, int flags, int resend) { - tcp_header_t *tcp; - ip_header_t *ip; - pktbuf_t *pkt = &s->pkt; - unsigned short cksum; - dword tcp_magic; - int tcp_magic_size = sizeof(tcp_magic); - - ip = pkt->ip_hdr; - tcp = pkt->tcp_hdr; - - if (flags & TCP_FLAG_SYN) { - /* If SYN, assume no data and send MSS option in tcp header */ - pkt->pkt_bytes = sizeof(tcp_header_t) + 4; - tcp->hdr_len = 6; - tcp_magic = htonl(0x02040000 | MAX_TCP_DATA); - memcpy((unsigned char *)(tcp+1), &tcp_magic, tcp_magic_size); - s->data_bytes = 0; - } else { - pkt->pkt_bytes = s->data_bytes + sizeof(tcp_header_t); - tcp->hdr_len = 5; - } - - /* tcp header */ - tcp->reserved = 0; - tcp->seqnum = htonl(s->seq); - tcp->acknum = htonl(s->ack); - tcp->checksum = 0; - - if (!resend) { - tcp->src_port = htons(s->our_port); - tcp->dest_port = htons(s->his_port); - tcp->flags = flags; - /* always set PUSH flag if sending data */ - if (s->data_bytes) - tcp->flags |= TCP_FLAG_PSH; - tcp->window = htons(MAX_TCP_DATA); - tcp->urgent = 0; + tcp_header_t *tcp; + ip_header_t *ip; + pktbuf_t *pkt = &s->pkt; + unsigned short cksum; + dword tcp_magic; + int tcp_magic_size = sizeof(tcp_magic); + + ip = pkt->ip_hdr; + tcp = pkt->tcp_hdr; + + if (flags & TCP_FLAG_SYN) { + /* If SYN, assume no data and send MSS option in tcp header */ + pkt->pkt_bytes = sizeof(tcp_header_t) + 4; + tcp->hdr_len = 6; + tcp_magic = htonl(0x02040000 | MAX_TCP_DATA); + memcpy((unsigned char *)(tcp+1), &tcp_magic, tcp_magic_size); + s->data_bytes = 0; + } else { + pkt->pkt_bytes = s->data_bytes + sizeof(tcp_header_t); + tcp->hdr_len = 5; + } - /* fill in some pseudo-header fields */ - memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t)); - memcpy(ip->destination, s->his_addr.ip_addr, sizeof(ip_addr_t)); - ip->protocol = IP_PROTO_TCP; - } + /* tcp header */ + tcp->reserved = 0; + tcp->seqnum = htonl(s->seq); + tcp->acknum = htonl(s->ack); + tcp->checksum = 0; + + if (!resend) { + tcp->src_port = htons(s->our_port); + tcp->dest_port = htons(s->his_port); + tcp->flags = flags; + /* always set PUSH flag if sending data */ + if (s->data_bytes) + tcp->flags |= TCP_FLAG_PSH; + tcp->window = htons(MAX_TCP_DATA); + tcp->urgent = 0; + + /* fill in some pseudo-header fields */ + memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t)); + memcpy(ip->destination, s->his_addr.ip_addr, sizeof(ip_addr_t)); + ip->protocol = IP_PROTO_TCP; + } - /* another pseudo-header field */ - ip->length = htons(pkt->pkt_bytes); + /* another pseudo-header field */ + ip->length = htons(pkt->pkt_bytes); - /* compute tcp checksum */ - cksum = __sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip)); - tcp->checksum = htons(cksum); + /* compute tcp checksum */ + cksum = __sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip)); + tcp->checksum = htons(cksum); - __ip_send(pkt, IP_PROTO_TCP, &s->his_addr); + __ip_send(pkt, IP_PROTO_TCP, &s->his_addr); - // HACK! If this delay is not present, then if the target system sends - // back data (not just an ACK), then somehow we miss it :-( - CYGACC_CALL_IF_DELAY_US(2*1000); + // HACK! If this delay is not present, then if the target system sends + // back data (not just an ACK), then somehow we miss it :-( + CYGACC_CALL_IF_DELAY_US(2*1000); - BSPLOG(bsp_log("tcp_send: state[%d] flags[%s] ack[%x] data[%d].\n", - s->state, flags_to_str(tcp->flags), s->ack, s->data_bytes)); + BSPLOG(bsp_log("tcp_send: state[%d] flags[%s] ack[%x] data[%d].\n", + s->state, flags_to_str(tcp->flags), s->ack, s->data_bytes)); - if (s->state == _TIME_WAIT) { - // If 'reuse' is set on socket, close after 1 second, otherwise 2 minutes - __timer_set(&s->timer, s->reuse ? 1000 : 120000, do_close, s); - } - else if ((tcp->flags & (TCP_FLAG_FIN | TCP_FLAG_SYN)) || s->data_bytes) - __timer_set(&s->timer, 1000, do_retrans, s); + if (s->state == _TIME_WAIT) { + // If 'reuse' is set on socket, close after 1 second, otherwise 2 minutes + __timer_set(&s->timer, s->reuse ? 1000 : 120000, do_close, s); + } + else if ((tcp->flags & (TCP_FLAG_FIN | TCP_FLAG_SYN)) || s->data_bytes) + __timer_set(&s->timer, 1000, do_retrans, s); } static pktbuf_t ack_pkt; -static word ack_buf[ETH_MIN_PKTLEN/sizeof(word)]; +static union { + word w[ETH_MIN_PKTLEN / sizeof(word)]; + struct { + ip_header_t ip; + tcp_header_t tcp; + }; +} ack_buf; /* * Send an ack. @@ -187,43 +193,43 @@ static word ack_buf[ETH_MIN_PKTLEN/sizeof(word)]; static void send_ack(tcp_socket_t *s) { - tcp_header_t *tcp; - ip_header_t *ip; - unsigned short cksum; - - ack_pkt.buf = ack_buf; - ack_pkt.bufsize = sizeof(ack_buf); - ack_pkt.ip_hdr = ip = (ip_header_t *)ack_buf; - ack_pkt.tcp_hdr = tcp = (tcp_header_t *)(ip + 1); - ack_pkt.pkt_bytes = sizeof(tcp_header_t); - - /* tcp header */ - tcp->hdr_len = 5; - tcp->reserved = 0; - tcp->seqnum = htonl(s->seq); - tcp->acknum = htonl(s->ack); - tcp->checksum = 0; - - tcp->src_port = htons(s->our_port); - tcp->dest_port = htons(s->his_port); - tcp->flags = TCP_FLAG_ACK; - - tcp->window = htons(MAX_TCP_DATA); - tcp->urgent = 0; - - /* fill in some pseudo-header fields */ - memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t)); - memcpy(ip->destination, s->his_addr.ip_addr, sizeof(ip_addr_t)); - ip->protocol = IP_PROTO_TCP; - - /* another pseudo-header field */ - ip->length = htons(sizeof(tcp_header_t)); - - /* compute tcp checksum */ - cksum = __sum((word *)tcp, sizeof(*tcp), __pseudo_sum(ip)); - tcp->checksum = htons(cksum); - - __ip_send(&ack_pkt, IP_PROTO_TCP, &s->his_addr); + tcp_header_t *tcp; + ip_header_t *ip; + unsigned short cksum; + + ack_pkt.buf = ack_buf.w; + ack_pkt.bufsize = sizeof(ack_buf.w); + ack_pkt.ip_hdr = ip = &ack_buf.ip; + ack_pkt.tcp_hdr = tcp = &ack_buf.tcp;//(tcp_header_t *)(ip + 1); + ack_pkt.pkt_bytes = sizeof(tcp_header_t); + + /* tcp header */ + tcp->hdr_len = 5; + tcp->reserved = 0; + tcp->seqnum = htonl(s->seq); + tcp->acknum = htonl(s->ack); + tcp->checksum = 0; + + tcp->src_port = htons(s->our_port); + tcp->dest_port = htons(s->his_port); + tcp->flags = TCP_FLAG_ACK; + + tcp->window = htons(MAX_TCP_DATA); + tcp->urgent = 0; + + /* fill in some pseudo-header fields */ + memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t)); + memcpy(ip->destination, s->his_addr.ip_addr, sizeof(ip_addr_t)); + ip->protocol = IP_PROTO_TCP; + + /* another pseudo-header field */ + ip->length = htons(sizeof(tcp_header_t)); + + /* compute tcp checksum */ + cksum = __sum((word *)tcp, sizeof(*tcp), __pseudo_sum(ip)); + tcp->checksum = htons(cksum); + + __ip_send(&ack_pkt, IP_PROTO_TCP, &s->his_addr); } @@ -233,43 +239,43 @@ send_ack(tcp_socket_t *s) static void send_reset(pktbuf_t *pkt, ip_route_t *r) { - ip_header_t *ip = pkt->ip_hdr; - tcp_header_t *tcp = pkt->tcp_hdr; - dword seq, ack; - word src, dest; - word cksum; - - seq = ntohl(tcp->acknum); - ack = ntohl(tcp->seqnum); - src = ntohs(tcp->dest_port); - dest = ntohs(tcp->src_port); - - tcp = (tcp_header_t *)(ip + 1); - pkt->pkt_bytes = sizeof(tcp_header_t); - - /* tcp header */ - tcp->hdr_len = 5; - tcp->reserved = 0; - tcp->seqnum = htonl(seq); - tcp->acknum = htonl(ack); - tcp->window = htons(1024); - tcp->urgent = 0; - tcp->checksum = 0; - tcp->src_port = htons(src); - tcp->dest_port = htons(dest); - tcp->flags = TCP_FLAG_RST | TCP_FLAG_ACK; - - /* fill in some pseudo-header fields */ - memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t)); - memcpy(ip->destination, r->ip_addr, sizeof(ip_addr_t)); - ip->protocol = IP_PROTO_TCP; - ip->length = htons(pkt->pkt_bytes); - - /* compute tcp checksum */ - cksum = __sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip)); - tcp->checksum = htons(cksum); - - __ip_send(pkt, IP_PROTO_TCP, r); + ip_header_t *ip = pkt->ip_hdr; + tcp_header_t *tcp = pkt->tcp_hdr; + dword seq, ack; + word src, dest; + word cksum; + + seq = ntohl(tcp->acknum); + ack = ntohl(tcp->seqnum); + src = ntohs(tcp->dest_port); + dest = ntohs(tcp->src_port); + + tcp = (tcp_header_t *)(ip + 1); + pkt->pkt_bytes = sizeof(tcp_header_t); + + /* tcp header */ + tcp->hdr_len = 5; + tcp->reserved = 0; + tcp->seqnum = htonl(seq); + tcp->acknum = htonl(ack); + tcp->window = htons(1024); + tcp->urgent = 0; + tcp->checksum = 0; + tcp->src_port = htons(src); + tcp->dest_port = htons(dest); + tcp->flags = TCP_FLAG_RST | TCP_FLAG_ACK; + + /* fill in some pseudo-header fields */ + memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t)); + memcpy(ip->destination, r->ip_addr, sizeof(ip_addr_t)); + ip->protocol = IP_PROTO_TCP; + ip->length = htons(pkt->pkt_bytes); + + /* compute tcp checksum */ + cksum = __sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip)); + tcp->checksum = htons(cksum); + + __ip_send(pkt, IP_PROTO_TCP, r); } @@ -280,16 +286,16 @@ send_reset(pktbuf_t *pkt, ip_route_t *r) static void unlink_socket(tcp_socket_t *s) { - tcp_socket_t *prev, *tp; - - for (prev = NULL, tp = tcp_list; tp; prev = tp, tp = tp->next) - if (tp == s) { - BSPLOG(bsp_log("unlink tcp socket.\n")); - if (prev) - prev->next = s->next; - else - tcp_list = s->next; - } + tcp_socket_t *prev, *tp; + + for (prev = NULL, tp = tcp_list; tp; prev = tp, tp = tp->next) + if (tp == s) { + BSPLOG(bsp_log("unlink tcp socket.\n")); + if (prev) + prev->next = s->next; + else + tcp_list = s->next; + } } /* @@ -298,32 +304,32 @@ unlink_socket(tcp_socket_t *s) static void do_retrans(void *p) { - BSPLOG(bsp_log("tcp do_retrans.\n")); - tcp_send((tcp_socket_t *)p, 0, 1); + BSPLOG(bsp_log("tcp do_retrans.\n")); + tcp_send((tcp_socket_t *)p, 0, 1); } static void do_close(void *p) { - BSPLOG(bsp_log("tcp do_close.\n")); - /* close connection */ - ((tcp_socket_t *)p)->state = _CLOSED; - unlink_socket(p); + BSPLOG(bsp_log("tcp do_close.\n")); + /* close connection */ + ((tcp_socket_t *)p)->state = _CLOSED; + unlink_socket(p); } static void free_rxlist(tcp_socket_t *s) { - pktbuf_t *p; + pktbuf_t *p; - BSPLOG(bsp_log("tcp free_rxlist.\n")); + BSPLOG(bsp_log("tcp free_rxlist.\n")); - while ((p = s->rxlist) != NULL) { - s->rxlist = p->next; - __pktbuf_free(p); - } + while ((p = s->rxlist) != NULL) { + s->rxlist = p->next; + __pktbuf_free(p); + } } @@ -333,11 +339,11 @@ free_rxlist(tcp_socket_t *s) static void do_reset(tcp_socket_t *s) { - /* close connection */ - s->state = _CLOSED; - __timer_cancel(&s->timer); - free_rxlist(s); - unlink_socket(s); + /* close connection */ + s->state = _CLOSED; + __timer_cancel(&s->timer); + free_rxlist(s); + unlink_socket(s); } @@ -348,85 +354,85 @@ do_reset(tcp_socket_t *s) static int handle_data(tcp_socket_t *s, pktbuf_t *pkt) { - tcp_header_t *tcp = pkt->tcp_hdr; - unsigned int diff, seq; - int data_len; - char *data_ptr; - pktbuf_t *p; - - data_len = pkt->pkt_bytes - (tcp->hdr_len << 2); - data_ptr = ((char *)tcp) + (tcp->hdr_len << 2); - - seq = ntohl(tcp->seqnum); - - BSPLOG(bsp_log("tcp data: seq[%x] len[%d].\n", seq, data_len)); - - if (SEQ_LE(seq, s->ack)) { - /* - * Figure difference between which byte we're expecting and which byte - * is sent first. Adjust data length and data pointer accordingly. - */ - diff = s->ack - seq; - data_len -= diff; - data_ptr += diff; - - if (data_len > 0) { - /* queue the new data */ - s->ack += data_len; - pkt->next = NULL; - if ((p = s->rxlist) != NULL) { - while (p->next) - p = p->next; - p->next = pkt; - BSPLOG(bsp_log("tcp data: Add pkt[%x] len[%d].\n", - pkt, data_len)); - } else { - s->rxlist = pkt; - s->rxcnt = data_len; - s->rxptr = data_ptr; - BSPLOG(bsp_log("tcp data: pkt[%x] len[%d].\n", - pkt, data_len)); - } - return 1; + tcp_header_t *tcp = pkt->tcp_hdr; + unsigned int diff, seq; + int data_len; + char *data_ptr; + pktbuf_t *p; + + data_len = pkt->pkt_bytes - (tcp->hdr_len << 2); + data_ptr = ((char *)tcp) + (tcp->hdr_len << 2); + + seq = ntohl(tcp->seqnum); + + BSPLOG(bsp_log("tcp data: seq[%x] len[%d].\n", seq, data_len)); + + if (SEQ_LE(seq, s->ack)) { + /* + * Figure difference between which byte we're expecting and which byte + * is sent first. Adjust data length and data pointer accordingly. + */ + diff = s->ack - seq; + data_len -= diff; + data_ptr += diff; + + if (data_len > 0) { + /* queue the new data */ + s->ack += data_len; + pkt->next = NULL; + if ((p = s->rxlist) != NULL) { + while (p->next) + p = p->next; + p->next = pkt; + BSPLOG(bsp_log("tcp data: Add pkt[%x] len[%d].\n", + pkt, data_len)); + } else { + s->rxlist = pkt; + s->rxcnt = data_len; + s->rxptr = data_ptr; + BSPLOG(bsp_log("tcp data: pkt[%x] len[%d].\n", + pkt, data_len)); + } + return 1; + } } - } - return 0; + return 0; } static void handle_ack(tcp_socket_t *s, pktbuf_t *pkt) { - tcp_header_t *tcp = pkt->tcp_hdr; - dword ack; - int advance; - char *dp; + tcp_header_t *tcp = pkt->tcp_hdr; + dword ack; + int advance; + char *dp; - /* process ack value in packet */ - ack = ntohl(tcp->acknum); + /* process ack value in packet */ + ack = ntohl(tcp->acknum); - BSPLOG(bsp_log("Rcvd tcp ACK %x\n", ack)); + BSPLOG(bsp_log("Rcvd tcp ACK %x\n", ack)); - if (SEQ_GT(ack, s->seq)) { - __timer_cancel(&s->timer); - advance = ack - s->seq; - if (advance > s->data_bytes) - advance = s->data_bytes; - - BSPLOG(bsp_log("seq advance %d", advance)); - - if (advance > 0) { - s->seq += advance; - s->data_bytes -= advance; - if (s->data_bytes) { - /* other end ack'd only part of the pkt */ - BSPLOG(bsp_log(" %d bytes left", s->data_bytes)); - dp = (char *)(s->pkt.tcp_hdr + 1); - memcpy(dp, dp + advance, s->data_bytes); - } + if (SEQ_GT(ack, s->seq)) { + __timer_cancel(&s->timer); + advance = ack - s->seq; + if (advance > s->data_bytes) + advance = s->data_bytes; + + BSPLOG(bsp_log("seq advance %d", advance)); + + if (advance > 0) { + s->seq += advance; + s->data_bytes -= advance; + if (s->data_bytes) { + /* other end ack'd only part of the pkt */ + BSPLOG(bsp_log(" %d bytes left", s->data_bytes)); + dp = (char *)(s->pkt.tcp_hdr + 1); + memcpy(dp, dp + advance, s->data_bytes); + } + } } - } - BSPLOG(bsp_log("\n")); + BSPLOG(bsp_log("\n")); } @@ -436,243 +442,243 @@ handle_ack(tcp_socket_t *s, pktbuf_t *pkt) void __tcp_handler(pktbuf_t *pkt, ip_route_t *r) { - tcp_header_t *tcp = pkt->tcp_hdr; - ip_header_t *ip = pkt->ip_hdr; - tcp_socket_t *prev,*s; - dword ack; - int queued = 0; - - /* set length for pseudo sum calculation */ - ip->length = htons(pkt->pkt_bytes); - - if (__sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip)) == 0) { - for (prev = NULL, s = tcp_list; s; prev = s, s = s->next) { - if (s->our_port == ntohs(tcp->dest_port)) { - if (s->his_port == 0) - break; - if (s->his_port == ntohs(tcp->src_port) && - !memcmp(r->ip_addr, s->his_addr.ip_addr, sizeof(ip_addr_t))) - break; - } - } - - if (s) { - /* found the socket this packet belongs to */ - - /* refresh his ethernet address */ - memcpy(s->his_addr.enet_addr, r->enet_addr, sizeof(enet_addr_t)); - - if (s->state != _SYN_RCVD && tcp->flags & TCP_FLAG_RST) { - BSPLOG(bsp_log("TCP_FLAG_RST rcvd\n")); - do_reset(s); - __pktbuf_free(pkt); - return; - } - - switch (s->state) { - - case _SYN_SENT: - /* active open not supported */ - if (tcp->flags != (TCP_FLAG_SYN | TCP_FLAG_ACK)) { - do_reset(s); - __pktbuf_free(pkt); - return; - } - s->state = _ESTABLISHED; - s->ack = ntohl(tcp->seqnum) + 1; - s->seq = ntohl(tcp->acknum); - __timer_cancel(&s->timer); - send_ack(s); - break; - - case _LISTEN: - if (tcp->flags & TCP_FLAG_SYN) { - s->state = _SYN_RCVD; - s->ack = ntohl(tcp->seqnum) + 1; - s->his_port = ntohs(tcp->src_port); - memcpy(s->his_addr.ip_addr, r->ip_addr, sizeof(ip_addr_t)); - s->data_bytes = 0; - - BSPLOG(bsp_log("SYN from %d.%d.%d.%d:%d (seq %x)\n", - s->his_addr.ip_addr[0],s->his_addr.ip_addr[1], - s->his_addr.ip_addr[2],s->his_addr.ip_addr[3], - s->his_port, ntohl(tcp->seqnum))); - - tcp_send(s, TCP_FLAG_SYN | TCP_FLAG_ACK, 0); - } - else - send_reset(pkt, r); - break; - - case _SYN_RCVD: - BSPLOG(bsp_log("_SYN_RCVD timer cancel.\n")); - __timer_cancel(&s->timer); - - /* go back to _LISTEN state if reset */ - if (tcp->flags & TCP_FLAG_RST) { - s->state = _LISTEN; - - BSPLOG(bsp_log("_SYN_RCVD --> _LISTEN\n")); - - } else if (tcp->flags & TCP_FLAG_SYN) { - /* apparently our SYN/ACK was lost? */ - tcp_send(s, 0, 1); - - BSPLOG(bsp_log("retransmitting SYN/ACK\n")); - - } else if ((tcp->flags & TCP_FLAG_ACK) && - ntohl(tcp->acknum) == (s->seq + 1)) { - /* we've established the connection */ - s->state = _ESTABLISHED; - s->seq++; - - BSPLOG(bsp_log("ACK received - connection established\n")); + tcp_header_t *tcp = pkt->tcp_hdr; + ip_header_t *ip = pkt->ip_hdr; + tcp_socket_t *prev,*s; + dword ack; + int queued = 0; + + /* set length for pseudo sum calculation */ + ip->length = htons(pkt->pkt_bytes); + + if (__sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip)) == 0) { + for (prev = NULL, s = tcp_list; s; prev = s, s = s->next) { + if (s->our_port == ntohs(tcp->dest_port)) { + if (s->his_port == 0) + break; + if (s->his_port == ntohs(tcp->src_port) && + !memcmp(r->ip_addr, s->his_addr.ip_addr, sizeof(ip_addr_t))) + break; + } } - break; - - case _ESTABLISHED: - case _CLOSE_WAIT: - ack = s->ack; /* save original ack */ - if (tcp->flags & TCP_FLAG_ACK) - handle_ack(s, pkt); - queued = handle_data(s, pkt); + if (s) { + /* found the socket this packet belongs to */ - if ((tcp->flags & TCP_FLAG_FIN) && - ntohl(tcp->seqnum) == s->ack) { + /* refresh his ethernet address */ + memcpy(s->his_addr.enet_addr, r->enet_addr, sizeof(enet_addr_t)); - BSPLOG(bsp_log("FIN received - going to _CLOSE_WAIT\n")); + if (s->state != _SYN_RCVD && tcp->flags & TCP_FLAG_RST) { + BSPLOG(bsp_log("TCP_FLAG_RST rcvd\n")); + do_reset(s); + __pktbuf_free(pkt); + return; + } - s->ack++; - s->state = _CLOSE_WAIT; - } - /* - * Send an ack if neccessary. - */ - if (s->ack != ack || pkt->pkt_bytes > (tcp->hdr_len << 2)) - send_ack(s); - break; - - case _LAST_ACK: - if (tcp->flags & TCP_FLAG_ACK) { - handle_ack(s, pkt); - if (ntohl(tcp->acknum) == (s->seq + 1)) { - BSPLOG(bsp_log("_LAST_ACK --> _CLOSED\n")); - s->state = _CLOSED; - unlink_socket(s); - } - } - break; - - case _FIN_WAIT_1: - if (tcp->flags & TCP_FLAG_ACK) { - handle_ack(s, pkt); - if (ntohl(tcp->acknum) == (s->seq + 1)) { - /* got ACK for FIN packet */ - s->seq++; - if (tcp->flags & TCP_FLAG_FIN) { - BSPLOG(bsp_log("_FIN_WAIT_1 --> _TIME_WAIT\n")); - s->ack++; - s->state = _TIME_WAIT; - send_ack(s); - } else { - s->state = _FIN_WAIT_2; - BSPLOG(bsp_log("_FIN_WAIT_1 --> _FIN_WAIT_2\n")); + switch (s->state) { + + case _SYN_SENT: + /* active open not supported */ + if (tcp->flags != (TCP_FLAG_SYN | TCP_FLAG_ACK)) { + do_reset(s); + __pktbuf_free(pkt); + return; + } + s->state = _ESTABLISHED; + s->ack = ntohl(tcp->seqnum) + 1; + s->seq = ntohl(tcp->acknum); + __timer_cancel(&s->timer); + send_ack(s); + break; + + case _LISTEN: + if (tcp->flags & TCP_FLAG_SYN) { + s->state = _SYN_RCVD; + s->ack = ntohl(tcp->seqnum) + 1; + s->his_port = ntohs(tcp->src_port); + memcpy(s->his_addr.ip_addr, r->ip_addr, sizeof(ip_addr_t)); + s->data_bytes = 0; + + BSPLOG(bsp_log("SYN from %d.%d.%d.%d:%d (seq %x)\n", + s->his_addr.ip_addr[0],s->his_addr.ip_addr[1], + s->his_addr.ip_addr[2],s->his_addr.ip_addr[3], + s->his_port, ntohl(tcp->seqnum))); + + tcp_send(s, TCP_FLAG_SYN | TCP_FLAG_ACK, 0); + } + else + send_reset(pkt, r); + break; + + case _SYN_RCVD: + BSPLOG(bsp_log("_SYN_RCVD timer cancel.\n")); + __timer_cancel(&s->timer); + + /* go back to _LISTEN state if reset */ + if (tcp->flags & TCP_FLAG_RST) { + s->state = _LISTEN; + + BSPLOG(bsp_log("_SYN_RCVD --> _LISTEN\n")); + + } else if (tcp->flags & TCP_FLAG_SYN) { + /* apparently our SYN/ACK was lost? */ + tcp_send(s, 0, 1); + + BSPLOG(bsp_log("retransmitting SYN/ACK\n")); + + } else if ((tcp->flags & TCP_FLAG_ACK) && + ntohl(tcp->acknum) == (s->seq + 1)) { + /* we've established the connection */ + s->state = _ESTABLISHED; + s->seq++; + + BSPLOG(bsp_log("ACK received - connection established\n")); + } + break; + + case _ESTABLISHED: + case _CLOSE_WAIT: + ack = s->ack; /* save original ack */ + if (tcp->flags & TCP_FLAG_ACK) + handle_ack(s, pkt); + + queued = handle_data(s, pkt); + + if ((tcp->flags & TCP_FLAG_FIN) && + ntohl(tcp->seqnum) == s->ack) { + + BSPLOG(bsp_log("FIN received - going to _CLOSE_WAIT\n")); + + s->ack++; + s->state = _CLOSE_WAIT; + } + /* + * Send an ack if neccessary. + */ + if (s->ack != ack || pkt->pkt_bytes > (tcp->hdr_len << 2)) + send_ack(s); + break; + + case _LAST_ACK: + if (tcp->flags & TCP_FLAG_ACK) { + handle_ack(s, pkt); + if (ntohl(tcp->acknum) == (s->seq + 1)) { + BSPLOG(bsp_log("_LAST_ACK --> _CLOSED\n")); + s->state = _CLOSED; + unlink_socket(s); + } + } + break; + + case _FIN_WAIT_1: + if (tcp->flags & TCP_FLAG_ACK) { + handle_ack(s, pkt); + if (ntohl(tcp->acknum) == (s->seq + 1)) { + /* got ACK for FIN packet */ + s->seq++; + if (tcp->flags & TCP_FLAG_FIN) { + BSPLOG(bsp_log("_FIN_WAIT_1 --> _TIME_WAIT\n")); + s->ack++; + s->state = _TIME_WAIT; + send_ack(s); + } else { + s->state = _FIN_WAIT_2; + BSPLOG(bsp_log("_FIN_WAIT_1 --> _FIN_WAIT_2\n")); + } + break; /* All done for now */ + } + } + /* At this point, no ACK for FIN has been seen, so check for + simultaneous close */ + if (tcp->flags & TCP_FLAG_FIN) { + BSPLOG(bsp_log("_FIN_WAIT_1 --> _CLOSING\n")); + __timer_cancel(&s->timer); + s->ack++; + s->state = _CLOSING; + /* FIN is resent so the timeout and retry for this packet + will also take care of timeout and resend of the + previously sent FIN (which got us to FIN_WAIT_1). While + not technically correct, resending FIN only causes a + duplicate FIN (same sequence number) which should be + ignored by the other end. */ + tcp_send(s, TCP_FLAG_FIN | TCP_FLAG_ACK, 0); + } + break; + + case _FIN_WAIT_2: + queued = handle_data(s, pkt); + if (tcp->flags & TCP_FLAG_FIN) { + BSPLOG(bsp_log("_FIN_WAIT_2 --> _TIME_WAIT\n")); + s->ack++; + s->state = _TIME_WAIT; + send_ack(s); + } + break; + + case _CLOSING: + if (tcp->flags & TCP_FLAG_ACK) { + handle_ack(s, pkt); + if (ntohl(tcp->acknum) == (s->seq + 1)) { + /* got ACK for FIN packet */ + BSPLOG(bsp_log("_CLOSING --> _TIME_WAIT\n")); + __timer_cancel(&s->timer); + s->state = _TIME_WAIT; + } + } + break; + + case _TIME_WAIT: + BSPLOG(bsp_log("_TIME_WAIT resend.\n")); + if (tcp->flags & TCP_FLAG_FIN) + tcp_send(s, 0, 1); /* just resend ack */ + break; } - break; /* All done for now */ - } - } - /* At this point, no ACK for FIN has been seen, so check for - simultaneous close */ - if (tcp->flags & TCP_FLAG_FIN) { - BSPLOG(bsp_log("_FIN_WAIT_1 --> _CLOSING\n")); - __timer_cancel(&s->timer); - s->ack++; - s->state = _CLOSING; - /* FIN is resent so the timeout and retry for this packet - will also take care of timeout and resend of the - previously sent FIN (which got us to FIN_WAIT_1). While - not technically correct, resending FIN only causes a - duplicate FIN (same sequence number) which should be - ignored by the other end. */ - tcp_send(s, TCP_FLAG_FIN | TCP_FLAG_ACK, 0); - } - break; - - case _FIN_WAIT_2: - queued = handle_data(s, pkt); - if (tcp->flags & TCP_FLAG_FIN) { - BSPLOG(bsp_log("_FIN_WAIT_2 --> _TIME_WAIT\n")); - s->ack++; - s->state = _TIME_WAIT; - send_ack(s); + } else { + BSPLOG(bsp_log("Unexpected segment from: %d.%d.%d.%d:%d\n", + r->ip_addr[0], r->ip_addr[1], r->ip_addr[3], + r->ip_addr[4], ntohs(tcp->src_port))); + send_reset(pkt, r); } - break; - - case _CLOSING: - if (tcp->flags & TCP_FLAG_ACK) { - handle_ack(s, pkt); - if (ntohl(tcp->acknum) == (s->seq + 1)) { - /* got ACK for FIN packet */ - BSPLOG(bsp_log("_CLOSING --> _TIME_WAIT\n")); - __timer_cancel(&s->timer); - s->state = _TIME_WAIT; - } - } - break; - - case _TIME_WAIT: - BSPLOG(bsp_log("_TIME_WAIT resend.\n")); - if (tcp->flags & TCP_FLAG_FIN) - tcp_send(s, 0, 1); /* just resend ack */ - break; - } - } else { - BSPLOG(bsp_log("Unexpected segment from: %d.%d.%d.%d:%d\n", - r->ip_addr[0], r->ip_addr[1], r->ip_addr[3], - r->ip_addr[4], ntohs(tcp->src_port))); - send_reset(pkt, r); } - } - if (!queued) - __pktbuf_free(pkt); + if (!queued) + __pktbuf_free(pkt); } void __tcp_poll(void) { - __enet_poll(); - __timer_poll(); + __enet_poll(); + __timer_poll(); } int __tcp_listen(tcp_socket_t *s, word port) { - BSPLOG(bsp_log("tcp_listen: s[%p] port[%x]\n", s, port)); + BSPLOG(bsp_log("tcp_listen: s[%p] port[%x]\n", s, port)); - memset(s, 0, sizeof(tcp_socket_t)); - s->state = _LISTEN; - s->our_port = port; - s->pkt.buf = (word *)s->pktbuf; - s->pkt.bufsize = ETH_MAX_PKTLEN; - s->pkt.ip_hdr = (ip_header_t *)s->pkt.buf; - s->pkt.tcp_hdr = (tcp_header_t *)(s->pkt.ip_hdr + 1); + memset(s, 0, sizeof(tcp_socket_t)); + s->state = _LISTEN; + s->our_port = port; + s->pkt.buf = (word *)s->pktbuf; + s->pkt.bufsize = ETH_MAX_PKTLEN; + s->pkt.ip_hdr = (ip_header_t *)s->pkt.buf; + s->pkt.tcp_hdr = (tcp_header_t *)(s->pkt.ip_hdr + 1); - s->next = tcp_list; + s->next = tcp_list; #if 0 - /* limit to one open socket at a time */ - if (s->next) { - BSPLOG(bsp_log("tcp_listen: recursion error\n")); - BSPLOG(while(1)); - } + /* limit to one open socket at a time */ + if (s->next) { + BSPLOG(bsp_log("tcp_listen: recursion error\n")); + BSPLOG(while(1)); + } #endif - - tcp_list = s; - return 0; + tcp_list = s; + + return 0; } /* @@ -682,7 +688,7 @@ void __tcp_so_reuseaddr(tcp_socket_t *s) { // BSPLOG(bsp_log("__tcp_so_reuseaddr.\n")); - s->reuse = 0x01; + s->reuse = 0x01; } /* @@ -692,8 +698,8 @@ void __tcp_drain(tcp_socket_t *s) { // BSPLOG(bsp_log("__tcp_drain.\n")); - while (s->state != _CLOSED && s->data_bytes) - __tcp_poll(); + while (s->state != _CLOSED && s->data_bytes) + __tcp_poll(); // BSPLOG(bsp_log("__tcp_drain done.\n")); } @@ -704,18 +710,18 @@ __tcp_drain(tcp_socket_t *s) static void do_abort(void *s) { - BSPLOG(bsp_log("do_abort: send RST\n")); - tcp_send((tcp_socket_t *)s, TCP_FLAG_ACK | TCP_FLAG_RST, 0); - __timer_cancel(&abort_timer); - ((tcp_socket_t *)s)->state = _CLOSED; - free_rxlist((tcp_socket_t *)s); - unlink_socket((tcp_socket_t *)s); + BSPLOG(bsp_log("do_abort: send RST\n")); + tcp_send((tcp_socket_t *)s, TCP_FLAG_ACK | TCP_FLAG_RST, 0); + __timer_cancel(&abort_timer); + ((tcp_socket_t *)s)->state = _CLOSED; + free_rxlist((tcp_socket_t *)s); + unlink_socket((tcp_socket_t *)s); } void __tcp_abort(tcp_socket_t *s, unsigned long delay) { - __timer_set(&abort_timer, delay, do_abort, s); + __timer_set(&abort_timer, delay, do_abort, s); } /* @@ -724,19 +730,19 @@ __tcp_abort(tcp_socket_t *s, unsigned long delay) void __tcp_close(tcp_socket_t *s) { - __tcp_drain(s); - if (s->state == _ESTABLISHED || s->state == _SYN_RCVD) { - BSPLOG(bsp_log("__tcp_close: going to _FIN_WAIT_1\n")); - s->state = _FIN_WAIT_1; - tcp_send(s, TCP_FLAG_ACK | TCP_FLAG_FIN, 0); - } else if (s->state == _CLOSE_WAIT) { - - BSPLOG(bsp_log("__tcp_close: going to _LAST_ACK\n")); - - s->state = _LAST_ACK; - tcp_send(s, TCP_FLAG_ACK | TCP_FLAG_FIN, 0); - } - free_rxlist(s); + __tcp_drain(s); + if (s->state == _ESTABLISHED || s->state == _SYN_RCVD) { + BSPLOG(bsp_log("__tcp_close: going to _FIN_WAIT_1\n")); + s->state = _FIN_WAIT_1; + tcp_send(s, TCP_FLAG_ACK | TCP_FLAG_FIN, 0); + } else if (s->state == _CLOSE_WAIT) { + + BSPLOG(bsp_log("__tcp_close: going to _LAST_ACK\n")); + + s->state = _LAST_ACK; + tcp_send(s, TCP_FLAG_ACK | TCP_FLAG_FIN, 0); + } + free_rxlist(s); } @@ -746,10 +752,10 @@ __tcp_close(tcp_socket_t *s) void __tcp_close_wait(tcp_socket_t *s) { - BSPLOG(bsp_log("__tcp_close_wait.\n")); - while (s->state != _CLOSED) - __tcp_poll(); - BSPLOG(bsp_log("__tcp_close_wait done.\n")); + BSPLOG(bsp_log("__tcp_close_wait.\n")); + while (s->state != _CLOSED) + __tcp_poll(); + BSPLOG(bsp_log("__tcp_close_wait done.\n")); } @@ -759,59 +765,59 @@ __tcp_close_wait(tcp_socket_t *s) int __tcp_read(tcp_socket_t *s, void *buf, int len) { - int nread; - pktbuf_t *pkt; - tcp_header_t *tcp; - - if (len <= 0 || s->rxcnt == 0) - return 0; - - if (s->state != _ESTABLISHED && s->rxcnt == 0) - return -1; - - nread = 0; - while (len) { - if (len < s->rxcnt) { - memcpy(buf, s->rxptr, len); - BSPLOG(bsp_log("tcp_read: read %d bytes.\n", len)); - s->rxptr += len; - s->rxcnt -= len; - nread += len; + int nread; + pktbuf_t *pkt; + tcp_header_t *tcp; + + if (len <= 0 || s->rxcnt == 0) + return 0; + + if (s->state != _ESTABLISHED && s->rxcnt == 0) + return -1; + + nread = 0; + while (len) { + if (len < s->rxcnt) { + memcpy(buf, s->rxptr, len); + BSPLOG(bsp_log("tcp_read: read %d bytes.\n", len)); + s->rxptr += len; + s->rxcnt -= len; + nread += len; + + BSPLOG(bsp_log("tcp_read: %d bytes left in rxlist head.\n", + s->rxcnt)); + + break; + } else { + memcpy(buf, s->rxptr, s->rxcnt); + BSPLOG(bsp_log("tcp_read: read %d bytes. pkt[%x] freed.\n", + s->rxcnt, s->rxlist)); + nread += s->rxcnt; + buf = (char *)buf + s->rxcnt; + len -= s->rxcnt; + + /* setup for next packet in list */ + pkt = s->rxlist; + s->rxlist = pkt->next; + __pktbuf_free(pkt); + + if ((pkt = s->rxlist) != NULL) { + tcp = pkt->tcp_hdr; + s->rxcnt = pkt->pkt_bytes - (tcp->hdr_len << 2); + s->rxptr = ((char *)tcp) + (tcp->hdr_len << 2); + + BSPLOG(bsp_log("tcp_read: next pkt[%x] has %d bytes.\n", + s->rxlist, s->rxcnt)); + } else { - BSPLOG(bsp_log("tcp_read: %d bytes left in rxlist head.\n", - s->rxcnt)); + BSPLOG(bsp_log("tcp_read: no more data.\n")); - break; - } else { - memcpy(buf, s->rxptr, s->rxcnt); - BSPLOG(bsp_log("tcp_read: read %d bytes. pkt[%x] freed.\n", - s->rxcnt, s->rxlist)); - nread += s->rxcnt; - buf = (char *)buf + s->rxcnt; - len -= s->rxcnt; - - /* setup for next packet in list */ - pkt = s->rxlist; - s->rxlist = pkt->next; - __pktbuf_free(pkt); - - if ((pkt = s->rxlist) != NULL) { - tcp = pkt->tcp_hdr; - s->rxcnt = pkt->pkt_bytes - (tcp->hdr_len << 2); - s->rxptr = ((char *)tcp) + (tcp->hdr_len << 2); - - BSPLOG(bsp_log("tcp_read: next pkt[%x] has %d bytes.\n", - s->rxlist, s->rxcnt)); - } else { - - BSPLOG(bsp_log("tcp_read: no more data.\n")); - - s->rxcnt = 0; - break; - } + s->rxcnt = 0; + break; + } + } } - } - return nread; + return nread; } @@ -821,26 +827,26 @@ __tcp_read(tcp_socket_t *s, void *buf, int len) int __tcp_write(tcp_socket_t *s, void *buf, int len) { - tcp_header_t *tcp = s->pkt.tcp_hdr; + tcp_header_t *tcp = s->pkt.tcp_hdr; - if (len <= 0) - return 0; + if (len <= 0) + return 0; - if (s->state != _ESTABLISHED && s->state != _CLOSE_WAIT) - return -1; + if (s->state != _ESTABLISHED && s->state != _CLOSE_WAIT) + return -1; - if (s->data_bytes) - return 0; + if (s->data_bytes) + return 0; - if (len > MAX_TCP_DATA) - len = MAX_TCP_DATA; + if (len > MAX_TCP_DATA) + len = MAX_TCP_DATA; - memcpy(tcp + 1, buf, len); - s->data_bytes = len; + memcpy(tcp + 1, buf, len); + s->data_bytes = len; - tcp_send(s, TCP_FLAG_ACK, 0); + tcp_send(s, TCP_FLAG_ACK, 0); - return len; + return len; } /* @@ -850,73 +856,71 @@ __tcp_write(tcp_socket_t *s, void *buf, int len) int __tcp_write_block(tcp_socket_t *s, void *buf, int len) { - int total = 0; - int n; - - while (len) { - if (s->state == _CLOSE_WAIT) { - // This connection is tring to close - // This connection is breaking - if (s->data_bytes == 0 && s->rxcnt == 0) - __tcp_close(s); - } - if (s->state == _CLOSED) { - // The connection is gone! - return -1; - } - n = __tcp_write(s, buf, len); - if (n > 0) { - len -= n; - buf = (char *)buf + n; - total += n; - } - __tcp_poll(); - } - __tcp_drain(s); - return total; + int total = 0; + int n; + + while (len) { + if (s->state == _CLOSE_WAIT) { + // This connection is tring to close + // This connection is breaking + if (s->data_bytes == 0 && s->rxcnt == 0) + __tcp_close(s); + } + if (s->state == _CLOSED) { + // The connection is gone! + return -1; + } + n = __tcp_write(s, buf, len); + if (n > 0) { + len -= n; + buf = (char *)buf + n; + total += n; + } + __tcp_poll(); + } + __tcp_drain(s); + return total; } /* * Establish a new [outgoing] connection, with a timeout. */ -int -__tcp_open(tcp_socket_t *s, struct sockaddr_in *host, - word port, int timeout, int *err) +int +__tcp_open(tcp_socket_t *s, struct sockaddr_in *host, + word port, int timeout, int *err) { - // Fill in socket details - memset(s, 0, sizeof(tcp_socket_t)); - s->state = _SYN_SENT; - s->our_port = port; - s->his_port = host->sin_port; - s->pkt.buf = (word *)s->pktbuf; - s->pkt.bufsize = ETH_MAX_PKTLEN; - s->pkt.ip_hdr = (ip_header_t *)s->pkt.buf; - s->pkt.tcp_hdr = (tcp_header_t *)(s->pkt.ip_hdr + 1); - s->seq = (port << 16) | 0xDE77; - s->ack = 0; - if (__arp_lookup((ip_addr_t *)&host->sin_addr, &s->his_addr) < 0) { - diag_printf("%s: Can't find address of server\n", __FUNCTION__); - return -1; - } - s->next = tcp_list; - tcp_list = s; - - // Send off the SYN packet to open the connection - tcp_send(s, TCP_FLAG_SYN, 0); - // Wait for connection to establish - while (s->state != _ESTABLISHED) { - if (s->state == _CLOSED) { - diag_printf("TCP open - host closed connection\n"); - return -1; - } - if (--timeout <= 0) { - diag_printf("TCP open - connection timed out\n"); - return -1; - } - MS_TICKS_DELAY(); - __tcp_poll(); - } - return 0; + // Fill in socket details + memset(s, 0, sizeof(tcp_socket_t)); + s->state = _SYN_SENT; + s->our_port = port; + s->his_port = host->sin_port; + s->pkt.buf = (word *)s->pktbuf; + s->pkt.bufsize = ETH_MAX_PKTLEN; + s->pkt.ip_hdr = (ip_header_t *)s->pkt.buf; + s->pkt.tcp_hdr = (tcp_header_t *)(s->pkt.ip_hdr + 1); + s->seq = (port << 16) | 0xDE77; + s->ack = 0; + if (__arp_lookup((ip_addr_t *)&host->sin_addr, &s->his_addr) < 0) { + diag_printf("%s: Can't find address of server\n", __FUNCTION__); + return -1; + } + s->next = tcp_list; + tcp_list = s; + + // Send off the SYN packet to open the connection + tcp_send(s, TCP_FLAG_SYN, 0); + // Wait for connection to establish + while (s->state != _ESTABLISHED) { + if (s->state == _CLOSED) { + diag_printf("TCP open - host closed connection\n"); + return -1; + } + if (--timeout <= 0) { + diag_printf("TCP open - connection timed out\n"); + return -1; + } + MS_TICKS_DELAY(); + __tcp_poll(); + } + return 0; } - - diff --git a/packages/redboot/v2_0/src/net/tftp_client.c b/packages/redboot/v2_0/src/net/tftp_client.c index 7f471f60..49333dba 100644 --- a/packages/redboot/v2_0/src/net/tftp_client.c +++ b/packages/redboot/v2_0/src/net/tftp_client.c @@ -44,9 +44,9 @@ // Author(s): gthomas // Contributors: gthomas // Date: 2000-07-14 -// Purpose: -// Description: -// +// Purpose: +// Description: +// // This code is part of RedBoot (tm). // //####DESCRIPTIONEND#### @@ -55,7 +55,7 @@ // TFTP client support -#include // have_net +#include // have_net #include #include #include @@ -64,249 +64,252 @@ static int get_port = 7700; static struct { - bool open; - int total_timeouts, packets_received; - unsigned long last_good_block; - int avail, actual_len; - struct sockaddr_in local_addr, from_addr; - char data[SEGSIZE+sizeof(struct tftphdr)]; - char *bufp; + bool open; + int total_timeouts, packets_received; + unsigned long last_good_block; + int avail, actual_len; + struct sockaddr_in local_addr, from_addr; + union { + char buf[SEGSIZE + sizeof(struct tftphdr)]; + struct tftphdr hdr; + } data; + char *bufp; } tftp_stream; int tftp_stream_open(connection_info_t *info, - int *err) + int *err) { - struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data; - char *cp, *fp; - char test_buf; + struct tftphdr *hdr = &tftp_stream.data.hdr; + char *cp, *fp; + char test_buf; - if (!have_net || tftp_stream.open) { - *err = TFTP_INVALID; // Already open - return -1; - } + if (!have_net || tftp_stream.open) { + *err = TFTP_INVALID; // Already open + return -1; + } - // Create initial request - hdr->th_opcode = htons(RRQ); // Read file - cp = (char *)&hdr->th_stuff; - fp = info->filename; - while (*fp) *cp++ = *fp++; - *cp++ = '\0'; - // Since this is used for downloading data, OCTET (binary) is the - // only mode that makes sense. - fp = "OCTET"; - while (*fp) *cp++ = *fp++; - *cp++ = '\0'; + // Create initial request + hdr->th_opcode = htons(RRQ); // Read file + cp = (char *)&hdr->th_stuff; + fp = info->filename; + while (*fp) *cp++ = *fp++; + *cp++ = '\0'; + // Since this is used for downloading data, OCTET (binary) is the + // only mode that makes sense. + fp = "OCTET"; + while (*fp) *cp++ = *fp++; + *cp++ = '\0'; - memset(&tftp_stream.local_addr, 0, sizeof(tftp_stream.local_addr)); - tftp_stream.local_addr.sin_family = AF_INET; - tftp_stream.local_addr.sin_addr.s_addr = htonl(INADDR_ANY); - tftp_stream.local_addr.sin_port = htons(get_port++); + memset(&tftp_stream.local_addr, 0, sizeof(tftp_stream.local_addr)); + tftp_stream.local_addr.sin_family = AF_INET; + tftp_stream.local_addr.sin_addr.s_addr = htonl(INADDR_ANY); + tftp_stream.local_addr.sin_port = htons(get_port++); - if (info->server->sin_port == 0) { - info->server->sin_port = htons(TFTP_PORT); - } else { - info->server->sin_port = htons(info->server->sin_port); - } + if (info->server->sin_port == 0) { + info->server->sin_port = htons(TFTP_PORT); + } else { + info->server->sin_port = htons(info->server->sin_port); + } - // Send request - note: RFC 1350 (TFTP rev 2) indicates that this should be - // only as long as required to hold the request, with the nul terminator. - // Some servers silently go to lunch if the request is not the correct size. - if (__udp_sendto(tftp_stream.data, cp-(char *)hdr, - info->server, &tftp_stream.local_addr) < 0) { - // Problem sending request - *err = TFTP_NETERR; - return -1; - } + // Send request - note: RFC 1350 (TFTP rev 2) indicates that this should be + // only as long as required to hold the request, with the nul terminator. + // Some servers silently go to lunch if the request is not the correct size. + if (__udp_sendto(tftp_stream.data.buf, cp-(char *)hdr, + info->server, &tftp_stream.local_addr) < 0) { + // Problem sending request + *err = TFTP_NETERR; + return -1; + } - tftp_stream.open = true; - tftp_stream.avail = 0; - tftp_stream.actual_len = -1; - tftp_stream.last_good_block = 0; - tftp_stream.total_timeouts = 0; - tftp_stream.from_addr.sin_port = 0; - tftp_stream.packets_received = 0; + tftp_stream.open = true; + tftp_stream.avail = 0; + tftp_stream.actual_len = -1; + tftp_stream.last_good_block = 0; + tftp_stream.total_timeouts = 0; + tftp_stream.from_addr.sin_port = 0; + tftp_stream.packets_received = 0; - // Try and read the first byte [block] since no errors are - // reported until then. - if (tftp_stream_read(&test_buf, 1, err) == 1) { - // Back up [rewind] over this datum - tftp_stream.bufp--; - tftp_stream.avail++; - return 0; // Open and first read successful - } else { - tftp_stream.open = false; - return -1; // Couldn't read - } + // Try and read the first byte [block] since no errors are + // reported until then. + if (tftp_stream_read(&test_buf, 1, err) == 1) { + // Back up [rewind] over this datum + tftp_stream.bufp--; + tftp_stream.avail++; + return 0; // Open and first read successful + } else { + tftp_stream.open = false; + return -1; // Couldn't read + } } static int tftp_ack(int *err) { - struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data; - // ACK last packet so server can shut down - if (tftp_stream.packets_received > 0) { - hdr->th_opcode = htons(ACK); - hdr->th_block = htons((cyg_uint16)tftp_stream.last_good_block & 0xFFFF); - if (__udp_sendto(tftp_stream.data, 4 /* FIXME */, - &tftp_stream.from_addr, &tftp_stream.local_addr) < 0) { - // Problem sending ACK - *err = TFTP_NETERR; - return -1; - } - } - return 0; + struct tftphdr *hdr = &tftp_stream.data.hdr; + // ACK last packet so server can shut down + if (tftp_stream.packets_received > 0) { + hdr->th_opcode = htons(ACK); + hdr->th_block = htons((cyg_uint16)tftp_stream.last_good_block & 0xFFFF); + if (__udp_sendto(tftp_stream.data.buf, 4 /* FIXME */, + &tftp_stream.from_addr, &tftp_stream.local_addr) < 0) { + // Problem sending ACK + *err = TFTP_NETERR; + return -1; + } + } + return 0; } static int tftp_error_ack(int *err, short code, char *msg) { - struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data; + struct tftphdr *hdr = &tftp_stream.data.hdr; - if (strlen(msg) > (SEGSIZE-1)) { - *(msg + SEGSIZE) = 0; - } + if (strlen(msg) > (SEGSIZE - 1)) { + *(msg + SEGSIZE) = '\0'; + } - if (tftp_stream.packets_received > 0) { - hdr->th_opcode = htons(ERROR); - hdr->th_code = code; - strcpy((char *)&hdr->th_data, msg); - if (__udp_sendto(tftp_stream.data, (5 + strlen(msg)), - &tftp_stream.from_addr, &tftp_stream.local_addr) < 0) { - // Problem sending ACK - *err = TFTP_NETERR; - return -1; - } - } - return 0; + if (tftp_stream.packets_received > 0) { + hdr->th_opcode = htons(ERROR); + hdr->th_code = code; + strcpy((char *)&hdr->th_data, msg); + if (__udp_sendto(tftp_stream.data.buf, (5 + strlen(msg)), + &tftp_stream.from_addr, &tftp_stream.local_addr) < 0) { + // Problem sending ACK + *err = TFTP_NETERR; + return -1; + } + } + return 0; } void tftp_stream_close(int *err) { - if (tftp_stream.open == true) { - tftp_ack(err); - tftp_stream.open = false; - } + if (tftp_stream.open == true) { + tftp_ack(err); + tftp_stream.open = false; + } } void tftp_stream_terminate(bool abort, - int (*getc)(void)) + int (*getc)(void)) { - int err; + int err; - if (abort) - tftp_error_ack(&err, EUNDEF, "redboot tftp_stream_terminate"); - else - tftp_ack(&err); + if (abort) + tftp_error_ack(&err, EUNDEF, "redboot tftp_stream_terminate"); + else + tftp_ack(&err); - tftp_stream.open = false; + tftp_stream.open = false; } int tftp_stream_read(void *buf, - int len, - int *err) + int len, + int *err) { - int total_bytes = 0; - int size, recv_len, data_len; - struct timeval timeout; - struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data; + int total_bytes = 0; + int size, recv_len, data_len; + struct timeval timeout; + struct tftphdr *hdr = &tftp_stream.data.hdr; - while (total_bytes < len) { - // Move any bytes which we've already read/buffered - if (tftp_stream.avail > 0) { - size = tftp_stream.avail; - if (size > (len - total_bytes)) size = len - total_bytes; - memcpy(buf, tftp_stream.bufp, size); - buf = (char *)buf + size; - tftp_stream.bufp += size; - tftp_stream.avail -= size; - total_bytes += size; - } else { - if (tftp_ack(err) < 0) { - return -1; - } - if ((tftp_stream.actual_len >= 0) && (tftp_stream.actual_len < SEGSIZE)) { - // Out of data - break; - } - timeout.tv_sec = (tftp_stream.last_good_block == 0) ? 10*TFTP_TIMEOUT_PERIOD : TFTP_TIMEOUT_PERIOD; - timeout.tv_usec = 0; - recv_len = sizeof(tftp_stream.data); - if ((data_len = __udp_recvfrom(&tftp_stream.data[0], recv_len, &tftp_stream.from_addr, - &tftp_stream.local_addr, &timeout)) < 0) { - // No data, try again - diag_printf("TFTP timed out %d/%d\n", tftp_stream.total_timeouts+1, TFTP_TIMEOUT_MAX); - if ((++tftp_stream.total_timeouts > TFTP_TIMEOUT_MAX) || - (tftp_stream.last_good_block == 0)) { - // Timeout - no data received - *err = TFTP_TIMEOUT; - return -1; - } - // Send out the ACK for the last block - maybe server will retry - if (tftp_ack(err) < 0) { - return -1; - } - } else { - tftp_stream.packets_received++; - if (ntohs(hdr->th_opcode) == DATA) { - if (ntohs(hdr->th_block) == (cyg_uint16)((tftp_stream.last_good_block+1) & 0xFFFF)) { - // Consume this data - data_len -= 4; /* Sizeof TFTP header */ - tftp_stream.avail = tftp_stream.actual_len = data_len; - tftp_stream.bufp = hdr->th_data; - tftp_stream.last_good_block++; - } - } else { - if (ntohs(hdr->th_opcode) == ERROR) { - *err = ntohs(hdr->th_code); - return -1; - } else { - // What kind of packet is this? - *err = TFTP_PROTOCOL; - return -1; - } - } - } - } - } - return total_bytes; + while (total_bytes < len) { + // Move any bytes which we've already read/buffered + if (tftp_stream.avail > 0) { + size = tftp_stream.avail; + if (size > (len - total_bytes)) size = len - total_bytes; + memcpy(buf, tftp_stream.bufp, size); + buf = (char *)buf + size; + tftp_stream.bufp += size; + tftp_stream.avail -= size; + total_bytes += size; + } else { + if (tftp_ack(err) < 0) { + return -1; + } + if ((tftp_stream.actual_len >= 0) && (tftp_stream.actual_len < SEGSIZE)) { + // Out of data + break; + } + timeout.tv_sec = (tftp_stream.last_good_block == 0) ? 10*TFTP_TIMEOUT_PERIOD : TFTP_TIMEOUT_PERIOD; + timeout.tv_usec = 0; + recv_len = sizeof(tftp_stream.data.buf); + if ((data_len = __udp_recvfrom(&tftp_stream.data.buf[0], recv_len, &tftp_stream.from_addr, + &tftp_stream.local_addr, &timeout)) < 0) { + // No data, try again + diag_printf("TFTP timed out %d/%d\n", tftp_stream.total_timeouts+1, TFTP_TIMEOUT_MAX); + if ((++tftp_stream.total_timeouts > TFTP_TIMEOUT_MAX) || + (tftp_stream.last_good_block == 0)) { + // Timeout - no data received + *err = TFTP_TIMEOUT; + return -1; + } + // Send out the ACK for the last block - maybe server will retry + if (tftp_ack(err) < 0) { + return -1; + } + } else { + tftp_stream.packets_received++; + if (ntohs(hdr->th_opcode) == DATA) { + if (ntohs(hdr->th_block) == (cyg_uint16)((tftp_stream.last_good_block+1) & 0xFFFF)) { + // Consume this data + data_len -= 4; /* Sizeof TFTP header */ + tftp_stream.avail = tftp_stream.actual_len = data_len; + tftp_stream.bufp = hdr->th_data; + tftp_stream.last_good_block++; + } + } else { + if (ntohs(hdr->th_opcode) == ERROR) { + *err = ntohs(hdr->th_code); + return -1; + } else { + // What kind of packet is this? + *err = TFTP_PROTOCOL; + return -1; + } + } + } + } + } + return total_bytes; } char * tftp_error(int err) { - char *errmsg = "Unknown error"; + char *errmsg = "Unknown error"; - switch (err) { - case TFTP_ENOTFOUND: - return "file not found"; - case TFTP_EACCESS: - return "access violation"; - case TFTP_ENOSPACE: - return "disk full or allocation exceeded"; - case TFTP_EBADOP: - return "illegal TFTP operation"; - case TFTP_EBADID: - return "unknown transfer ID"; - case TFTP_EEXISTS: - return "file already exists"; - case TFTP_ENOUSER: - return "no such user"; - case TFTP_TIMEOUT: - return "operation timed out"; - case TFTP_NETERR: - return "some sort of network error"; - case TFTP_INVALID: - return "invalid parameter"; - case TFTP_PROTOCOL: - return "protocol violation"; - case TFTP_TOOLARGE: - return "file is larger than buffer"; - } - return errmsg; + switch (err) { + case TFTP_ENOTFOUND: + return "file not found"; + case TFTP_EACCESS: + return "access violation"; + case TFTP_ENOSPACE: + return "disk full or allocation exceeded"; + case TFTP_EBADOP: + return "illegal TFTP operation"; + case TFTP_EBADID: + return "unknown transfer ID"; + case TFTP_EEXISTS: + return "file already exists"; + case TFTP_ENOUSER: + return "no such user"; + case TFTP_TIMEOUT: + return "operation timed out"; + case TFTP_NETERR: + return "some sort of network error"; + case TFTP_INVALID: + return "invalid parameter"; + case TFTP_PROTOCOL: + return "protocol violation"; + case TFTP_TOOLARGE: + return "file is larger than buffer"; + } + return errmsg; } // diff --git a/packages/redboot/v2_0/src/wince.c b/packages/redboot/v2_0/src/wince.c index d8324dd1..dc26041d 100755 --- a/packages/redboot/v2_0/src/wince.c +++ b/packages/redboot/v2_0/src/wince.c @@ -133,11 +133,11 @@ void ce_process_edbg(ce_net *net, ce_bin *bin); #ifdef CYGPKG_REDBOOT_NETWORKING // Redboot network based commands RedBoot_cmd( - "ceconnect", - "Set up a connection to the CE host PC over TCP/IP and download the run-time image", - "[-v] [-t ] [-h ]", - ce_load - ); + "ceconnect", + "Set up a connection to the CE host PC over TCP/IP and download the run-time image", + "[-v] [-t ] [-h ]", + ce_load + ); #endif /////////////////////////////////////////////////////////////////////////////////////////////// @@ -161,7 +161,7 @@ bool ce_is_bin_image(void *image, int imglen) { if (imglen < CE_BIN_SIGN_LEN) { diag_printf("Not a valid CE image: image size %u shorter than minimum %u\n", - imglen, CE_BIN_SIGN_LEN); + imglen, CE_BIN_SIGN_LEN); return 0; } if (is_rom_addr(image)) { @@ -169,7 +169,7 @@ bool ce_is_bin_image(void *image, int imglen) void *err_addr; if (flash_read(image, sign_buf, - CE_BIN_SIGN_LEN, &err_addr) != FLASH_ERR_OK) { + CE_BIN_SIGN_LEN, &err_addr) != FLASH_ERR_OK) { return 0; } return memcmp(sign_buf, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0; @@ -244,7 +244,7 @@ int ce_parse_bin(ce_bin *bin) void *err_addr; if (flash_read(pbData, &bin->parsePtr[bin->parseLen], - copyLen, &err_addr) != FLASH_ERR_OK) { + copyLen, &err_addr) != FLASH_ERR_OK) { return CE_PR_ERROR; } } else { @@ -259,7 +259,7 @@ int ce_parse_bin(ce_bin *bin) bin->rtiPhysAddr = CE_FIX_ADDRESS(bin->rtiPhysAddr); if (!is_ram_addr(bin->rtiPhysAddr)) { diag_printf("Invalid address %08lx in CE_PS_RTI_ADDR section\n", - bin->rtiPhysAddr); + bin->rtiPhysAddr); return CE_PR_ERROR; } } else if (bin->parseState == CE_PS_E_ADDR) { @@ -267,7 +267,7 @@ int ce_parse_bin(ce_bin *bin) bin->ePhysAddr = CE_FIX_ADDRESS(bin->ePhysAddr); if (!is_ram_addr(bin->ePhysAddr)) { diag_printf("Invalid address %08lx in CE_PS_E_ADDR section\n", - bin->ePhysAddr); + bin->ePhysAddr); return CE_PR_ERROR; } } @@ -299,7 +299,7 @@ int ce_parse_bin(ce_bin *bin) void *err_addr; if (flash_read(pbData, bin->parsePtr, - copyLen, &err_addr) != FLASH_ERR_OK) { + copyLen, &err_addr) != FLASH_ERR_OK) { return CE_PR_ERROR; } pbData += copyLen; @@ -387,8 +387,8 @@ bool ce_lookup_ep_bin(ce_bin *bin) // Lookup entry point header = (ce_rom_hdr*)CE_FIX_ADDRESS(*(unsigned int*)(bin->rtiPhysAddr + - ROM_SIGNATURE_OFFSET + - sizeof(unsigned int))); + ROM_SIGNATURE_OFFSET + + sizeof(unsigned int))); tentry = (ce_toc_entry*)(header + 1); for (i = 0; i < header->nummods; i++) { @@ -461,7 +461,7 @@ void setup_std_drv_globals(ce_std_driver_globals *std_drv_glb) std_drv_glb->header.bspVersion = 1; std_drv_glb->kitl.flags = 0; - diag_sprintf(std_drv_glb->deviceId, "Triton"); + diag_sprintf(std_drv_glb->deviceId, "Triton"); #ifdef CYGPKG_REDBOOT_NETWORKING memcpy(&std_drv_glb->kitl.mac[0], __local_enet_addr, sizeof(__local_enet_addr)); @@ -631,7 +631,7 @@ void ce_load(int argc, char *argv[]) if (verbose) { if (use_timeout) { diag_printf("Waiting for connection, timeout %d sec\n", - timeout); + timeout); } else { diag_printf("Waiting for connection, enter ^C to abort\n"); } @@ -743,7 +743,7 @@ int ce_recv_frame(ce_net *net, int timeout) // Receive UDP packet net->dataLen = __udp_recvfrom(net->data, sizeof(net->data), &net->srvAddrRecv, - &net->locAddr, &timeo); + &net->locAddr, &timeo); if (net->dataLen < 0) { // Error! No data available @@ -827,8 +827,8 @@ int ce_send_bootme(ce_net *net) // Some diag output ... if (net->verbose) { diag_printf("Sending BOOTME request [%d] to %s\n", - net->secNum, - inet_ntoa((in_addr_t *)&net->srvAddrSend)); + net->secNum, + inet_ntoa((in_addr_t *)&net->srvAddrSend)); } // Send packet @@ -854,7 +854,8 @@ int ce_process_download(ce_net *net, ce_bin *bin) int ret = CE_PR_MORE; if (net->dataLen >= 2) { - switch (ntohs(*(unsigned short*)net->data)) { + unsigned short *wdata = (unsigned short*)net->data; + switch (ntohs(*wdata)) { case EDBG_CMD_WRITE_REQ: if (!net->link) { // Check file name for WRITE request @@ -867,8 +868,8 @@ int ce_process_download(ce_net *net, ce_bin *bin) // Some diag output if (net->verbose) { diag_printf("Locked Down download link, IP: %s, port: %d\n", - inet_ntoa((in_addr_t *)&net->srvAddrRecv), - net->srvAddrRecv.sin_port); + inet_ntoa((in_addr_t *)&net->srvAddrRecv), + net->srvAddrRecv.sin_port); } // Lock down EShell download link @@ -1016,4 +1017,3 @@ void ce_process_edbg(ce_net *net, ce_bin *bin) ce_send_frame(net); } #endif - diff --git a/packages/redboot/v2_0/src/winceinc.h b/packages/redboot/v2_0/src/winceinc.h index 63d9c675..446bb146 100755 --- a/packages/redboot/v2_0/src/winceinc.h +++ b/packages/redboot/v2_0/src/winceinc.h @@ -7,13 +7,13 @@ typedef struct { - unsigned int id; // Protocol identifier ("EDBG" on the wire) - unsigned char service; // Service identifier - unsigned char flags; // Flags (see defs below) - unsigned char seqNum; // For detection of dropped packets - unsigned char cmd; // For administrative messages - unsigned char data[1]; // Cmd specific data starts here (format is determined by - // Cmd, len is determined by UDP packet size) + unsigned int id; // Protocol identifier ("EDBG" on the wire) + unsigned char service; // Service identifier + unsigned char flags; // Flags (see defs below) + unsigned char seqNum; // For detection of dropped packets + unsigned char cmd; // For administrative messages + unsigned char data[1]; // Cmd specific data starts here (format is determined by + // Cmd, len is determined by UDP packet size) } eth_dbg_hdr; #define OFFSETOF(s,m) ((unsigned int)&(((s*)0)->m)) @@ -25,17 +25,17 @@ typedef struct unsigned char versionMinor; // Bootloader version unsigned short macAddr[3]; // Ether address of device (net byte order) unsigned int ipAddr; // IP address of device (net byte order) - char platformId[17]; // Platform Id string (NULL terminated) - char deviceName[17]; // Device name string (NULL terminated). Should include + char platformId[17]; // Platform Id string (NULL terminated) + char deviceName[17]; // Device name string (NULL terminated). Should include // platform and number based on Ether address (e.g. Odo42, CEPCLS2346, etc) - unsigned char cpuId; // CPU identifier (upper nibble = type) + unsigned char cpuId; // CPU identifier (upper nibble = type) // The following fields were added in CE 3.0 Platform Builder release - unsigned char bootmeVer; // BOOTME Version. + unsigned char bootmeVer; // BOOTME Version. // Must be in the range 2 -> EDBG_CURRENT_BOOTME_VERSION, or // remaining fields will be ignored by Eshell and defaults will be used. - unsigned int bootFlags; // Boot Flags + unsigned int bootFlags; // Boot Flags unsigned short downloadPort; // Download Port (net byte order) (0 -> EDBG_DOWNLOAD_PORT) - unsigned short svcPort; // Service Port (net byte order) (0 -> EDBG_SVC_PORT) + unsigned short svcPort; // Service Port (net byte order) (0 -> EDBG_SVC_PORT) } edbg_bootme_data; // Packet size @@ -48,39 +48,39 @@ typedef struct typedef struct { unsigned char sign[CE_BIN_SIGN_LEN]; - unsigned int rtiPhysAddr; - unsigned int rtiPhysLen; + unsigned long rtiPhysAddr; + unsigned long rtiPhysLen; } ce_bin_hdr; typedef struct { - unsigned int physAddr; - unsigned int physLen; - unsigned int chkSum; + unsigned long physAddr; + unsigned long physLen; + unsigned long chkSum; unsigned char data[1]; } ce_bin_entry; // CE ROM image structures #define ROM_SIGNATURE_OFFSET 0x40 // Offset from the image's physfirst address to the ROM signature. -#define ROM_SIGNATURE 0x43454345 // Signature +#define ROM_SIGNATURE 0x43454345 // Signature #define ROM_TOC_POINTER_OFFSET 0x44 // Offset from the image's physfirst address to the TOC pointer. #define ROM_TOC_OFFSET_OFFSET 0x48 // Offset from the image's physfirst address to the TOC offset (from physfirst). typedef struct { - unsigned int dllfirst; // first DLL address - unsigned int dlllast; // last DLL address - unsigned int physfirst; // first physical address - unsigned int physlast; // highest physical address - unsigned int nummods; // number of TOCentry's - unsigned int ramStart; // start of RAM - unsigned int ramFree; // start of RAM free space - unsigned int ramEnd; // end of RAM + unsigned int dllfirst; // first DLL address + unsigned int dlllast; // last DLL address + unsigned int physfirst; // first physical address + unsigned int physlast; // highest physical address + unsigned int nummods; // number of TOCentry's + unsigned int ramStart; // start of RAM + unsigned int ramFree; // start of RAM free space + unsigned int ramEnd; // end of RAM unsigned int copyEntries; // number of copy section entries - unsigned int copyOffset; // offset to copy section - unsigned int profileLen; // length of PROFentries RAM + unsigned int copyOffset; // offset to copy section + unsigned int profileLen; // length of PROFentries RAM unsigned int profileOffset; // offset to PROFentries - unsigned int numfiles; // number of FILES + unsigned int numfiles; // number of FILES unsigned int kernelFlags; // optional kernel flags from ROMFLAGS .bib config option unsigned int fsRamPercent; // Percentage of RAM used for filesystem // from FSRAMPERCENT .bib config option @@ -89,73 +89,73 @@ typedef struct // byte 2 = #4K chunks/Mbyte of RAM for filesystem 4-6Mbytes 0-255 // byte 3 = #4K chunks/Mbyte of RAM for filesystem > 6Mbytes 0-255 - unsigned int drivglobStart; // device driver global starting address - unsigned int drivglobLen; // device driver global length - unsigned short cpuType; // CPU (machine) Type - unsigned short miscFlags; // Miscellaneous flags - void* extensions; // pointer to ROM Header extensions - unsigned int trackingStart; // tracking memory starting address - unsigned int trackingLen; // tracking memory ending address + unsigned int drivglobStart; // device driver global starting address + unsigned int drivglobLen; // device driver global length + unsigned short cpuType; // CPU (machine) Type + unsigned short miscFlags; // Miscellaneous flags + void* extensions; // pointer to ROM Header extensions + unsigned int trackingStart; // tracking memory starting address + unsigned int trackingLen; // tracking memory ending address } ce_rom_hdr; // Win32 FILETIME strcuture typedef struct { - unsigned int loDateTime; - unsigned int hiDateTime; + unsigned int loDateTime; + unsigned int hiDateTime; } ce_file_time; // Table Of Contents entry structure typedef struct { - unsigned int fileAttributes; - ce_file_time fileTime; - unsigned int fileSize; - char* fileName; - unsigned int e32Offset; // Offset to E32 structure - unsigned int o32Offset; // Offset to O32 structure - unsigned int loadOffset; // MODULE load buffer offset + unsigned int fileAttributes; + ce_file_time fileTime; + unsigned int fileSize; + char* fileName; + unsigned int e32Offset; // Offset to E32 structure + unsigned int o32Offset; // Offset to O32 structure + unsigned int loadOffset; // MODULE load buffer offset } ce_toc_entry; typedef struct -{ /* Extra information header block */ - unsigned int rva; /* Virtual relative address of info */ - unsigned int size; /* Size of information block */ +{ /* Extra information header block */ + unsigned int rva; /* Virtual relative address of info */ + unsigned int size; /* Size of information block */ } e32_info; #define ROM_EXTRA 9 typedef struct { - unsigned short e32_objcnt; /* Number of memory objects */ - unsigned short e32_imageflags; /* Image flags */ - unsigned int e32_entryrva; /* Relative virt. addr. of entry point */ - unsigned int e32_vbase; /* Virtual base address of module */ - unsigned short e32_subsysmajor;/* The subsystem major version number */ - unsigned short e32_subsysminor;/* The subsystem minor version number */ - unsigned int e32_stackmax; /* Maximum stack size */ - unsigned int e32_vsize; /* Virtual size of the entire image */ - unsigned int e32_sect14rva; /* section 14 rva */ - unsigned int e32_sect14size; /* section 14 size */ - unsigned int e32_timestamp; /* Time EXE/DLL was created/modified */ - e32_info e32_unit[ ROM_EXTRA ]; /* Array of extra info units */ - unsigned short e32_subsys; /* The subsystem type */ + unsigned short e32_objcnt; /* Number of memory objects */ + unsigned short e32_imageflags; /* Image flags */ + unsigned int e32_entryrva; /* Relative virt. addr. of entry point */ + unsigned int e32_vbase; /* Virtual base address of module */ + unsigned short e32_subsysmajor;/* The subsystem major version number */ + unsigned short e32_subsysminor;/* The subsystem minor version number */ + unsigned int e32_stackmax; /* Maximum stack size */ + unsigned int e32_vsize; /* Virtual size of the entire image */ + unsigned int e32_sect14rva; /* section 14 rva */ + unsigned int e32_sect14size; /* section 14 size */ + unsigned int e32_timestamp; /* Time EXE/DLL was created/modified */ + e32_info e32_unit[ ROM_EXTRA ]; /* Array of extra info units */ + unsigned short e32_subsys; /* The subsystem type */ } e32_rom; #pragma pack(1) // OS config msg -#define EDBG_FL_DBGMSG 0x01 // Debug messages -#define EDBG_FL_PPSH 0x02 // Text shell -#define EDBG_FL_KDBG 0x04 // Kernel debugger -#define EDBG_FL_CLEANBOOT 0x08 // Force a clean boot +#define EDBG_FL_DBGMSG 0x01 // Debug messages +#define EDBG_FL_PPSH 0x02 // Text shell +#define EDBG_FL_KDBG 0x04 // Kernel debugger +#define EDBG_FL_CLEANBOOT 0x08 // Force a clean boot typedef struct { - unsigned char flags; // Flags that will be used to determine what features are - // enabled over ethernet (saved in driver globals by bootloader) + unsigned char flags; // Flags that will be used to determine what features are + // enabled over ethernet (saved in driver globals by bootloader) unsigned char kitlTransport; // Tells KITL which transport to start // The following specify addressing info, only valid if the corresponding @@ -189,10 +189,11 @@ typedef struct #pragma pack(4) -typedef struct { - unsigned long signature; - unsigned short oalVersion; - unsigned short bspVersion; +typedef struct +{ + unsigned long signature; + unsigned short oalVersion; + unsigned short bspVersion; } OAL_ARGS_HEADER; typedef struct _DEVICE_LOCATION @@ -246,7 +247,7 @@ externC unsigned long _KARO_STRUCT_SIZE; // Byte string for Id field (note - must not conflict with valid TFTP // opcodes (0-5), as we share the download port with TFTP) -#define EDBG_ID 0x47424445 // "EDBG" +#define EDBG_ID 0x47424445 // "EDBG" // Defs for reserved values of the Service field @@ -265,7 +266,7 @@ externC unsigned long _KARO_STRUCT_SIZE; // Service Ids from 3-FE are used for user apps -#define NUM_DFLT_EDBG_SERVICES 3 +#define NUM_DFLT_EDBG_SERVICES 3 // Size of send and receive windows (except for stop and wait mode) @@ -273,19 +274,19 @@ externC unsigned long _KARO_STRUCT_SIZE; // The window size can be negotiated up to this amount if a client provides // enough memory. -#define EDBG_MAX_WINDOW_SIZE 16 +#define EDBG_MAX_WINDOW_SIZE 16 // Max size for an EDBG frame. Based on ethernet MTU - protocol overhead. // Limited to one MTU because we don't do IP fragmentation on device. -#define EDBG_MAX_DATA_SIZE 1446 +#define EDBG_MAX_DATA_SIZE 1446 // Defs for Flags field. -#define EDBG_FL_FROM_DEV 0x01 // Set if message is from the device -#define EDBG_FL_NACK 0x02 // Set if frame is a nack -#define EDBG_FL_ACK 0x04 // Set if frame is an ack -#define EDBG_FL_SYNC 0x08 // Can be used to reset sequence # to 0 -#define EDBG_FL_ADMIN_RESP 0x10 // For admin messages, indicate whether this is a response +#define EDBG_FL_FROM_DEV 0x01 // Set if message is from the device +#define EDBG_FL_NACK 0x02 // Set if frame is a nack +#define EDBG_FL_ACK 0x04 // Set if frame is an ack +#define EDBG_FL_SYNC 0x08 // Can be used to reset sequence # to 0 +#define EDBG_FL_ADMIN_RESP 0x10 // For admin messages, indicate whether this is a response // Definitions for Cmd field (used for administrative messages) // Msgs from device @@ -294,20 +295,20 @@ externC unsigned long _KARO_STRUCT_SIZE; // Msgs from PC #define EDBG_CMD_SETDEBUG 1 // Used to set debug zones on device (TBD) #define EDBG_CMD_JUMPIMG 2 // Command to tell bootloader to jump to existing - // flash or RAM image. Data is same as CMD_OS_CONFIG. + // flash or RAM image. Data is same as CMD_OS_CONFIG. #define EDBG_CMD_OS_CONFIG 3 // Configure OS for debug ethernet services #define EDBG_CMD_QUERYINFO 4 // "Ping" device, and return information (same fmt as bootme) #define EDBG_CMD_RESET 5 // Command to have platform perform SW reset (e.g. so it - // can be reprogrammed). Support for this command is - // processor dependant, and may not be implemented - // on all platforms (requires HW mods for Odo). + // can be reprogrammed). Support for this command is + // processor dependant, and may not be implemented + // on all platforms (requires HW mods for Odo). // Msgs from device or PC #define EDBG_CMD_SVC_CONFIG 6 #define EDBG_CMD_SVC_DATA 7 #define EDBG_CMD_DEBUGBREAK 8 // Break into debugger // Structures for Data portion of EDBG packets -#define EDBG_MAX_DEV_NAMELEN 16 +#define EDBG_MAX_DEV_NAMELEN 16 // BOOTME message - Devices broadcast this message when booted to request configuration #define EDBG_CURRENT_BOOTME_VERSION 2 @@ -318,10 +319,10 @@ externC unsigned long _KARO_STRUCT_SIZE; // // Always download image -#define EDBG_BOOTFLAG_FORCE_DOWNLOAD 0x00000001 +#define EDBG_BOOTFLAG_FORCE_DOWNLOAD 0x00000001 // Support passive-kitl -#define EDBG_CAPS_PASSIVEKITL 0x00010000 +#define EDBG_CAPS_PASSIVEKITL 0x00010000 // Defs for CPUId #define EDBG_CPU_TYPE_SHX 0x10 diff --git a/packages/redboot/v2_0/src/xyzModem.c b/packages/redboot/v2_0/src/xyzModem.c index cb0e197c..c99d5a81 100644 --- a/packages/redboot/v2_0/src/xyzModem.c +++ b/packages/redboot/v2_0/src/xyzModem.c @@ -44,9 +44,9 @@ // Author(s): gthomas // Contributors: gthomas, tsmith, Yoshinori Sato // Date: 2000-07-14 -// Purpose: -// Description: -// +// Purpose: +// Description: +// // This code is part of RedBoot (tm). // //####DESCRIPTIONEND#### @@ -72,22 +72,22 @@ // Data & state local to the protocol static struct { - hal_virtual_comm_table_t* __chan; - unsigned char pkt[1024], *bufp; - unsigned char blk,cblk,crc1,crc2; - unsigned char next_blk; // Expected block - int len, mode, total_retries; - int total_SOH, total_STX, total_CAN; - bool crc_mode, at_eof, tx_ack; + hal_virtual_comm_table_t* __chan; + unsigned char pkt[1024], *bufp; + unsigned char blk,cblk,crc1,crc2; + unsigned char next_blk; // Expected block + int len, mode, total_retries; + int total_SOH, total_STX, total_CAN; + bool crc_mode, at_eof, tx_ack; #ifdef USE_YMODEM_LENGTH - unsigned long file_length, read_length; + unsigned long file_length, read_length; #endif } xyz; -#define xyzModem_CHAR_TIMEOUT 2000 // 2 seconds -#define xyzModem_MAX_RETRIES 20 -#define xyzModem_MAX_RETRIES_WITH_CRC 10 -#define xyzModem_CAN_COUNT 3 // Wait for 3 CAN before quitting +#define xyzModem_CHAR_TIMEOUT 2000 // 2 seconds +#define xyzModem_MAX_RETRIES 20 +#define xyzModem_MAX_RETRIES_WITH_CRC 10 +#define xyzModem_CAN_COUNT 3 // Wait for 3 CAN before quitting #ifdef DEBUG #ifndef USE_SPRINTF @@ -99,14 +99,14 @@ static struct { static int zm_dprintf(char *fmt, ...) { - int cur_console; - va_list args; - - va_start(args, fmt); - cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - CYGACC_CALL_IF_SET_CONSOLE_COMM(1); - diag_vprintf(fmt, args); - CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console); + int cur_console; + va_list args; + + va_start(args, fmt); + cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + CYGACC_CALL_IF_SET_CONSOLE_COMM(1); + diag_vprintf(fmt, args); + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console); } static void @@ -124,28 +124,28 @@ static char *zm_out_start = (char *)0x00380000; static int zm_dprintf(char *fmt, ...) { - int len; - va_list args; + int len; + va_list args; - va_start(args, fmt); - len = diag_vsprintf(zm_out, fmt, args); - zm_out += len; - return len; + va_start(args, fmt); + len = diag_vsprintf(zm_out, fmt, args); + zm_out += len; + return len; } static void zm_flush(void) { - char *p = zm_out_start; - while (*p) mon_write_char(*p++); - zm_out = zm_out_start; + char *p = zm_out_start; + while (*p) mon_write_char(*p++); + zm_out = zm_out_start; } #endif static void zm_dump_buf(void *buf, int len) { - diag_vdump_buf_with_offset(zm_dprintf, buf, len, 0); + diag_vdump_buf_with_offset(zm_dprintf, buf, len, 0); } static unsigned char zm_buf[2048]; @@ -154,20 +154,20 @@ static unsigned char *zm_bp; static void zm_new(void) { - zm_bp = zm_buf; + zm_bp = zm_buf; } static void zm_save(unsigned char c) { - *zm_bp++ = c; + *zm_bp++ = c; } static void zm_dump(int line) { - zm_dprintf("Packet at line: %d\n", line); - zm_dump_buf(zm_buf, zm_bp-zm_buf); + zm_dprintf("Packet at line: %d\n", line); + zm_dump_buf(zm_buf, zm_bp-zm_buf); } #define ZM_DEBUG(x) x @@ -179,330 +179,330 @@ zm_dump(int line) static void xyzModem_flush(void) { - int res; - char c; - while (true) { - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); - if (!res) return; - } + int res; + char c; + while (true) { + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); + if (!res) return; + } } static int xyzModem_get_hdr(void) { - char c; - int res; - bool hdr_found = false; - int i, can_total, hdr_chars; - unsigned short cksum; - - ZM_DEBUG(zm_new()); - // Find the start of a header - can_total = 0; - hdr_chars = 0; - - if (xyz.tx_ack) { - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - xyz.tx_ack = false; - } - while (!hdr_found) { - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); - ZM_DEBUG(zm_save(c)); - if (res) { - hdr_chars++; - switch (c) { - case SOH: - xyz.total_SOH++; - case STX: - if (c == STX) xyz.total_STX++; - hdr_found = true; - break; - case CAN: - xyz.total_CAN++; - ZM_DEBUG(zm_dump(__LINE__)); - if (++can_total == xyzModem_CAN_COUNT) { - return xyzModem_cancel; - } else { - // Wait for multiple CAN to avoid early quits - break; - } - case EOT: - // EOT only supported if no noise - if (hdr_chars == 1) { - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - ZM_DEBUG(zm_dprintf("ACK on EOT #%d\n", __LINE__)); - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_eof; - } - default: - // Ignore, waiting for start of header - ; - } - } else { - // Data stream timed out - xyzModem_flush(); // Toss any current input - ZM_DEBUG(zm_dump(__LINE__)); - CYGACC_CALL_IF_DELAY_US((cyg_int32)250000); - return xyzModem_timeout; - } - } - - // Header found, now read the data - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.blk); - ZM_DEBUG(zm_save(xyz.blk)); - if (!res) { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; - } - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.cblk); - ZM_DEBUG(zm_save(xyz.cblk)); - if (!res) { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; - } - xyz.len = (c == SOH) ? 128 : 1024; - xyz.bufp = xyz.pkt; - for (i = 0; i < xyz.len; i++) { - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); - ZM_DEBUG(zm_save(c)); - if (res) { - xyz.pkt[i] = c; - } else { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; - } - } - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.crc1); - ZM_DEBUG(zm_save(xyz.crc1)); - if (!res) { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; - } - if (xyz.crc_mode) { - res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.crc2); - ZM_DEBUG(zm_save(xyz.crc2)); - if (!res) { - ZM_DEBUG(zm_dump(__LINE__)); - return xyzModem_timeout; - } - } - ZM_DEBUG(zm_dump(__LINE__)); - // Validate the message - if ((xyz.blk ^ xyz.cblk) != (unsigned char)0xFF) { - ZM_DEBUG(zm_dprintf("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk, (xyz.blk ^ xyz.cblk))); - ZM_DEBUG(zm_dump_buf(xyz.pkt, xyz.len)); - xyzModem_flush(); - return xyzModem_frame; - } - // Verify checksum/CRC - if (xyz.crc_mode) { - cksum = cyg_crc16(xyz.pkt, xyz.len); - if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) { - ZM_DEBUG(zm_dprintf("CRC error - recvd: %02x%02x, computed: %x\n", - xyz.crc1, xyz.crc2, cksum & 0xFFFF)); - return xyzModem_cksum; - } - } else { - cksum = 0; - for (i = 0; i < xyz.len; i++) { - cksum += xyz.pkt[i]; - } - if (xyz.crc1 != (cksum & 0xFF)) { - ZM_DEBUG(zm_dprintf("Checksum error - recvd: %x, computed: %x\n", xyz.crc1, cksum & 0xFF)); - return xyzModem_cksum; - } - } - // If we get here, the message passes [structural] muster - return 0; + char c; + int res; + bool hdr_found = false; + int i, can_total, hdr_chars; + unsigned short cksum; + + ZM_DEBUG(zm_new()); + // Find the start of a header + can_total = 0; + hdr_chars = 0; + + if (xyz.tx_ack) { + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); + xyz.tx_ack = false; + } + while (!hdr_found) { + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); + ZM_DEBUG(zm_save(c)); + if (res) { + hdr_chars++; + switch (c) { + case SOH: + xyz.total_SOH++; + case STX: + if (c == STX) xyz.total_STX++; + hdr_found = true; + break; + case CAN: + xyz.total_CAN++; + ZM_DEBUG(zm_dump(__LINE__)); + if (++can_total == xyzModem_CAN_COUNT) { + return xyzModem_cancel; + } + // Wait for multiple CAN to avoid early quits + break; + case EOT: + // EOT only supported if no noise + if (hdr_chars == 1) { + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); + ZM_DEBUG(zm_dprintf("ACK on EOT #%d\n", __LINE__)); + ZM_DEBUG(zm_dump(__LINE__)); + return xyzModem_eof; + } + break; + default: + // Ignore, waiting for start of header + ; + } + } else { + // Data stream timed out + xyzModem_flush(); // Toss any current input + ZM_DEBUG(zm_dump(__LINE__)); + CYGACC_CALL_IF_DELAY_US((cyg_int32)250000); + return xyzModem_timeout; + } + } + + // Header found, now read the data + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.blk); + ZM_DEBUG(zm_save(xyz.blk)); + if (!res) { + ZM_DEBUG(zm_dump(__LINE__)); + return xyzModem_timeout; + } + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.cblk); + ZM_DEBUG(zm_save(xyz.cblk)); + if (!res) { + ZM_DEBUG(zm_dump(__LINE__)); + return xyzModem_timeout; + } + xyz.len = (c == SOH) ? 128 : 1024; + xyz.bufp = xyz.pkt; + for (i = 0; i < xyz.len; i++) { + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c); + ZM_DEBUG(zm_save(c)); + if (res) { + xyz.pkt[i] = c; + } else { + ZM_DEBUG(zm_dump(__LINE__)); + return xyzModem_timeout; + } + } + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.crc1); + ZM_DEBUG(zm_save(xyz.crc1)); + if (!res) { + ZM_DEBUG(zm_dump(__LINE__)); + return xyzModem_timeout; + } + if (xyz.crc_mode) { + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.crc2); + ZM_DEBUG(zm_save(xyz.crc2)); + if (!res) { + ZM_DEBUG(zm_dump(__LINE__)); + return xyzModem_timeout; + } + } + ZM_DEBUG(zm_dump(__LINE__)); + // Validate the message + if ((xyz.blk ^ xyz.cblk) != (unsigned char)0xFF) { + ZM_DEBUG(zm_dprintf("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk, (xyz.blk ^ xyz.cblk))); + ZM_DEBUG(zm_dump_buf(xyz.pkt, xyz.len)); + xyzModem_flush(); + return xyzModem_frame; + } + // Verify checksum/CRC + if (xyz.crc_mode) { + cksum = cyg_crc16(xyz.pkt, xyz.len); + if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) { + ZM_DEBUG(zm_dprintf("CRC error - recvd: %02x%02x, computed: %x\n", + xyz.crc1, xyz.crc2, cksum & 0xFFFF)); + return xyzModem_cksum; + } + } else { + cksum = 0; + for (i = 0; i < xyz.len; i++) { + cksum += xyz.pkt[i]; + } + if (xyz.crc1 != (cksum & 0xFF)) { + ZM_DEBUG(zm_dprintf("Checksum error - recvd: %x, computed: %x\n", xyz.crc1, cksum & 0xFF)); + return xyzModem_cksum; + } + } + // If we get here, the message passes [structural] muster + return 0; } -int +int xyzModem_stream_open(connection_info_t *info, int *err) { - int console_chan, stat=0; - int retries = xyzModem_MAX_RETRIES; - int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; + int console_chan, stat=0; + int retries = xyzModem_MAX_RETRIES; + int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; // ZM_DEBUG(zm_out = zm_out_start); #ifdef xyzModem_zmodem - if (info->mode == xyzModem_zmodem) { - *err = xyzModem_noZmodem; - return -1; - } + if (info->mode == xyzModem_zmodem) { + *err = xyzModem_noZmodem; + return -1; + } #endif - // Set up the I/O channel. Note: this allows for using a different port in the future - console_chan = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - if (info->chan >= 0) { - CYGACC_CALL_IF_SET_CONSOLE_COMM(info->chan); - } else { - CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan); - } - xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan); - CYGACC_COMM_IF_CONTROL(*xyz.__chan, __COMMCTL_SET_TIMEOUT, xyzModem_CHAR_TIMEOUT); - xyz.len = 0; - xyz.crc_mode = true; - xyz.at_eof = false; - xyz.tx_ack = false; - xyz.mode = info->mode; - xyz.total_retries = 0; - xyz.total_SOH = 0; - xyz.total_STX = 0; - xyz.total_CAN = 0; + // Set up the I/O channel. Note: this allows for using a different port in the future + console_chan = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + if (info->chan >= 0) { + CYGACC_CALL_IF_SET_CONSOLE_COMM(info->chan); + } else { + CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan); + } + xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan); + CYGACC_COMM_IF_CONTROL(*xyz.__chan, __COMMCTL_SET_TIMEOUT, xyzModem_CHAR_TIMEOUT); + xyz.len = 0; + xyz.crc_mode = true; + xyz.at_eof = false; + xyz.tx_ack = false; + xyz.mode = info->mode; + xyz.total_retries = 0; + xyz.total_SOH = 0; + xyz.total_STX = 0; + xyz.total_CAN = 0; #ifdef USE_YMODEM_LENGTH - xyz.read_length = 0; - xyz.file_length = 0; + xyz.read_length = 0; + xyz.file_length = 0; #endif - - CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - - if (xyz.mode == xyzModem_xmodem) { - // X-modem doesn't have an information header - exit here - xyz.next_blk = 1; - return 0; - } - - while (retries-- > 0) { - stat = xyzModem_get_hdr(); - if (stat == 0) { - // Y-modem file information header - if (xyz.blk == 0) { + + CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); + + if (xyz.mode == xyzModem_xmodem) { + // X-modem doesn't have an information header - exit here + xyz.next_blk = 1; + return 0; + } + + while (retries-- > 0) { + stat = xyzModem_get_hdr(); + if (stat == 0) { + // Y-modem file information header + if (xyz.blk == 0) { #ifdef USE_YMODEM_LENGTH - // skip filename - while (*xyz.bufp++); - // get the length - parse_num((char *)xyz.bufp, &xyz.file_length, NULL, " "); + // skip filename + while (*xyz.bufp++); + // get the length + parse_num((char *)xyz.bufp, &xyz.file_length, NULL, " "); #endif - // The rest of the file name data block quietly discarded - xyz.tx_ack = true; - } - xyz.next_blk = 1; - xyz.len = 0; - return 0; - } else - if (stat == xyzModem_timeout) { - if (--crc_retries <= 0) xyz.crc_mode = false; - CYGACC_CALL_IF_DELAY_US(5*100000); // Extra delay for startup - CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__)); - } - if (stat == xyzModem_cancel) { - break; - } - } - *err = stat; - ZM_DEBUG(zm_flush()); - return -1; + // The rest of the file name data block quietly discarded + xyz.tx_ack = true; + } + xyz.next_blk = 1; + xyz.len = 0; + return 0; + } else + if (stat == xyzModem_timeout) { + if (--crc_retries <= 0) xyz.crc_mode = false; + CYGACC_CALL_IF_DELAY_US(5*100000); // Extra delay for startup + CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); + xyz.total_retries++; + ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__)); + } + if (stat == xyzModem_cancel) { + break; + } + } + *err = stat; + ZM_DEBUG(zm_flush()); + return -1; } -int +int xyzModem_stream_read(void *buf, int size, int *err) { - int stat, total, len; - int retries; - - total = 0; - stat = xyzModem_cancel; - // Try and get 'size' bytes into the buffer - while (!xyz.at_eof && (size > 0)) { - if (xyz.len == 0) { - retries = xyzModem_MAX_RETRIES; - while (retries-- > 0) { - stat = xyzModem_get_hdr(); - if (stat == 0) { - if (xyz.blk == xyz.next_blk) { - xyz.tx_ack = true; - ZM_DEBUG(zm_dprintf("ACK block %d (%d)\n", xyz.blk, __LINE__)); - xyz.next_blk = (xyz.next_blk + 1) & 0xFF; + int stat, total, len; + int retries; + + total = 0; + stat = xyzModem_cancel; + // Try and get 'size' bytes into the buffer + while (!xyz.at_eof && (size > 0)) { + if (xyz.len == 0) { + retries = xyzModem_MAX_RETRIES; + while (retries-- > 0) { + stat = xyzModem_get_hdr(); + if (stat == 0) { + if (xyz.blk == xyz.next_blk) { + xyz.tx_ack = true; + ZM_DEBUG(zm_dprintf("ACK block %d (%d)\n", xyz.blk, __LINE__)); + xyz.next_blk = (xyz.next_blk + 1) & 0xFF; #if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH) - if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0) { + if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0) { #else - if (1) { + if (1) { #endif - // Data blocks can be padded with ^Z (EOF) characters - // This code tries to detect and remove them - if ((xyz.bufp[xyz.len-1] == EOF) && - (xyz.bufp[xyz.len-2] == EOF) && - (xyz.bufp[xyz.len-3] == EOF)) { - while (xyz.len && (xyz.bufp[xyz.len-1] == EOF)) { - xyz.len--; - } - } - } + // Data blocks can be padded with ^Z (EOF) characters + // This code tries to detect and remove them + if ((xyz.bufp[xyz.len-1] == EOF) && + (xyz.bufp[xyz.len-2] == EOF) && + (xyz.bufp[xyz.len-3] == EOF)) { + while (xyz.len && (xyz.bufp[xyz.len-1] == EOF)) { + xyz.len--; + } + } + } #ifdef USE_YMODEM_LENGTH - // See if accumulated length exceeds that of the file. - // If so, reduce size (i.e., cut out pad bytes) - // Only do this for Y-modem (and Z-modem should it ever - // be supported since it can fall back to Y-modem mode). - if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length) { - xyz.read_length += xyz.len; - if (xyz.read_length > xyz.file_length) { - xyz.len -= (xyz.read_length - xyz.file_length); - } - } + // See if accumulated length exceeds that of the file. + // If so, reduce size (i.e., cut out pad bytes) + // Only do this for Y-modem (and Z-modem should it ever + // be supported since it can fall back to Y-modem mode). + if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length) { + xyz.read_length += xyz.len; + if (xyz.read_length > xyz.file_length) { + xyz.len -= (xyz.read_length - xyz.file_length); + } + } #endif - break; - } else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF)) { - // Just re-ACK this so sender will get on with it - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - continue; // Need new header - } else { - stat = xyzModem_sequence; - } - } - if (stat == xyzModem_cancel) { - break; - } - if (stat == xyzModem_eof) { - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__)); - if (xyz.mode == xyzModem_ymodem) { - CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG(zm_dprintf("Reading Final Header\n")); - stat = xyzModem_get_hdr(); - CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - ZM_DEBUG(zm_dprintf("FINAL ACK (%d)\n", __LINE__)); - } - xyz.at_eof = true; - break; - } - CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); - xyz.total_retries++; - ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__)); - } - if (stat < 0) { - *err = stat; - xyz.len = -1; - return total; - } - } - // Don't "read" data from the EOF protocol package - if (!xyz.at_eof) { - len = xyz.len; - if (size < len) len = size; - memcpy(buf, xyz.bufp, len); - size -= len; - buf = (char *)buf + len; - total += len; - xyz.len -= len; - xyz.bufp += len; - } - } - return total; + break; + } else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF)) { + // Just re-ACK this so sender will get on with it + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); + continue; // Need new header + } else { + stat = xyzModem_sequence; + } + } + if (stat == xyzModem_cancel) { + break; + } + if (stat == xyzModem_eof) { + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); + ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__)); + if (xyz.mode == xyzModem_ymodem) { + CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); + xyz.total_retries++; + ZM_DEBUG(zm_dprintf("Reading Final Header\n")); + stat = xyzModem_get_hdr(); + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); + ZM_DEBUG(zm_dprintf("FINAL ACK (%d)\n", __LINE__)); + } + xyz.at_eof = true; + break; + } + CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); + xyz.total_retries++; + ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__)); + } + if (stat < 0) { + *err = stat; + xyz.len = -1; + return total; + } + } + // Don't "read" data from the EOF protocol package + if (!xyz.at_eof) { + len = xyz.len; + if (size < len) len = size; + memcpy(buf, xyz.bufp, len); + size -= len; + buf = (char *)buf + len; + total += len; + xyz.len -= len; + xyz.bufp += len; + } + } + return total; } void xyzModem_stream_close(int *err) { - diag_printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", - xyz.crc_mode ? "CRC" : "Cksum", - xyz.total_SOH, xyz.total_STX, xyz.total_CAN, - xyz.total_retries); + diag_printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", + xyz.crc_mode ? "CRC" : "Cksum", + xyz.total_SOH, xyz.total_STX, xyz.total_CAN, + xyz.total_retries); // ZM_DEBUG(zm_flush()); } @@ -510,88 +510,79 @@ xyzModem_stream_close(int *err) // getc void xyzModem_stream_terminate(bool abort, int (*getc)(void)) { - int c; - - if (abort) { - ZM_DEBUG(zm_dprintf("!!!! TRANSFER ABORT !!!!\n")); - switch (xyz.mode) { - case xyzModem_xmodem: - case xyzModem_ymodem: - // The X/YMODEM Spec seems to suggest that multiple CAN followed by an equal - // number of Backspaces is a friendly way to get the other end to abort. - CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); - CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); - CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); - CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); - CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); - CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); - CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); - CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); - // Now consume the rest of what's waiting on the line. - ZM_DEBUG(zm_dprintf("Flushing serial line.\n")); - xyzModem_flush(); - xyz.at_eof = true; - break; + int c; + + if (abort) { + ZM_DEBUG(zm_dprintf("!!!! TRANSFER ABORT !!!!\n")); + switch (xyz.mode) { + case xyzModem_xmodem: + case xyzModem_ymodem: + // The X/YMODEM Spec seems to suggest that multiple CAN followed by an equal + // number of Backspaces is a friendly way to get the other end to abort. + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + // Now consume the rest of what's waiting on the line. + ZM_DEBUG(zm_dprintf("Flushing serial line.\n")); + xyzModem_flush(); + xyz.at_eof = true; + break; #ifdef xyzModem_zmodem - case xyzModem_zmodem: - // Might support it some day I suppose. + case xyzModem_zmodem: + // Might support it some day I suppose. + break; #endif - break; - } - } else { - ZM_DEBUG(zm_dprintf("Engaging cleanup mode...\n")); - // Consume any trailing crap left in the inbuffer from - // previous recieved blocks. Since very few files are an exact multiple - // of the transfer block size, there will almost always be some gunk here. - // If we don't eat it now, RedBoot will think the user typed it. - ZM_DEBUG(zm_dprintf("Trailing gunk:\n")); - while ((c = (*getc)()) > -1) ; - ZM_DEBUG(zm_dprintf("\n")); - // Make a small delay to give terminal programs like minicom - // time to get control again after their file transfer program - // exits. - CYGACC_CALL_IF_DELAY_US((cyg_int32)250000); - } + } + } else { + ZM_DEBUG(zm_dprintf("Engaging cleanup mode...\n")); + // Consume any trailing crap left in the inbuffer from + // previous recieved blocks. Since very few files are an exact multiple + // of the transfer block size, there will almost always be some gunk here. + // If we don't eat it now, RedBoot will think the user typed it. + ZM_DEBUG(zm_dprintf("Trailing gunk:\n")); + while ((c = (*getc)()) > -1) ; + ZM_DEBUG(zm_dprintf("\n")); + // Make a small delay to give terminal programs like minicom + // time to get control again after their file transfer program + // exits. + CYGACC_CALL_IF_DELAY_US((cyg_int32)250000); + } } char * xyzModem_error(int err) { - switch (err) { - case xyzModem_access: - return "Can't access file"; - break; - case xyzModem_noZmodem: - return "Sorry, zModem not available yet"; - break; - case xyzModem_timeout: - return "Timed out"; - break; - case xyzModem_eof: - return "End of file"; - break; - case xyzModem_cancel: - return "Cancelled"; - break; - case xyzModem_frame: - return "Invalid framing"; - break; - case xyzModem_cksum: - return "CRC/checksum error"; - break; - case xyzModem_sequence: - return "Block sequence error"; - break; - default: - return "Unknown error"; - break; - } + switch (err) { + case xyzModem_access: + return "Can't access file"; + case xyzModem_noZmodem: + return "Sorry, zModem not available yet"; + case xyzModem_timeout: + return "Timed out"; + case xyzModem_eof: + return "End of file"; + case xyzModem_cancel: + return "Cancelled"; + case xyzModem_frame: + return "Invalid framing"; + case xyzModem_cksum: + return "CRC/checksum error"; + case xyzModem_sequence: + return "Block sequence error"; + default: + return "Unknown error"; + } } // // RedBoot interface // GETC_IO_FUNCS(xyzModem_io, xyzModem_stream_open, xyzModem_stream_close, - xyzModem_stream_terminate, xyzModem_stream_read, xyzModem_error); + xyzModem_stream_terminate, xyzModem_stream_read, xyzModem_error); RedBoot_load(xmodem, xyzModem_io, false, false, xyzModem_xmodem); RedBoot_load(ymodem, xyzModem_io, false, false, xyzModem_ymodem); -- 2.39.5