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
#include <cyg/io/flash.h>
#include <fis.h>
#include <sib.h>
-#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
#ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT
#include <wince.h>
"[-f]",
fis_init,
FIS_cmds
- );
+ );
#ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
# define FIS_LIST_OPTS "[-c] [-d]"
#else
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 <memory_load_address>] [-c] "
+ "[-b <memory_load_address>] [-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 <mem_base>] [-l <image_length>] [-s <data_length>]\n"
" [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>",
fis_create,
FIS_cmds
- );
+ );
#endif
// Raw flash access functions
"-f <flash_addr> -l <length>",
fis_erase,
FIS_cmds
- );
+ );
#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
local_cmd_entry("lock",
"LOCK FLASH contents",
"[-f <flash_addr> -l <length>] [name]",
fis_lock,
FIS_cmds
- );
+ );
local_cmd_entry("unlock",
"UNLOCK FLASH contents",
"[-f <flash_addr> -l <length>] [name]",
fis_unlock,
FIS_cmds
- );
+ );
#endif
local_cmd_entry("write",
"Write raw data directly to FLASH",
"-f <flash_addr> -b <mem_base> -l <image_length>",
fis_write,
FIS_cmds
- );
+ );
// Define table boundaries
CYG_HAL_TABLE_BEGIN( __FIS_cmds_TAB__, FIS_cmds);
// 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;
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
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);
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)
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;
} 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)
#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
{
*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;
*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;
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
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;
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,
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));
}
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));
}
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));
}
#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));
}
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));
}
// 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;
(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
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) {
} 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
}
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) {
} 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) {
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;
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;
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);
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",
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) {
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;
}
// 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);
#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");
}
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;
// 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
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
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);
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);
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
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);
}
//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;
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) {
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));
}
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);
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");
}
// -f - specify a flash address
#endif
//
-void
+void
do_load(int argc, char *argv[])
{
int res, num_options;
#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
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;
}
return;
}
}
- if (port_set)
+ if (port_set)
host.sin_port = port;
#endif
if (chan >= CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS) {
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;
}
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);
}
}
} 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)
spillover_ok = true;
}
#endif
- if (raw && !(base_addr_set
+ if (raw && !(base_addr_set
#ifdef CYGBLD_REDBOOT_LOAD_INTO_FLASH
|| flash_addr_set
#endif
*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
if ((res = redboot_getc()) < 0) {
err = getc_info.err;
break;
- }
+ }
type[i] = res;
}
if (res >= 0) {
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);
}
}
}
// Author(s): gthomas
// Contributors: gthomas, tkoeller, eCosCentric
// Date: 2000-07-14
-// Purpose:
-// Description:
-//
+// Purpose:
+// Description:
+//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
#include CYGHWR_MEMORY_LAYOUT_H
#ifdef CYGPKG_IO_ETH_DRIVERS
-#include <cyg/io/eth/eth_drv.h> // Logical driver interfaces
+#include <cyg/io/eth/eth_drv.h> // Logical driver interfaces
#endif
#include <cyg/hal/hal_tables.h>
-#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
#include <cyg/infra/cyg_type.h>
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
#ifdef CYGBLD_HAL_PLATFORM_STUB_H
// 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?",
- "[<topic>]",
- do_help
- );
+RedBoot_cmd("version",
+ "Display RedBoot version information",
+ "",
+ do_version
+ );
+RedBoot_cmd("help",
+ "Help about help?",
+ "[<topic>]",
+ do_help
+ );
static char go_usage[] = "[-w <timeout>] [-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 <rate>]",
- do_baud_rate
- );
+RedBoot_cmd("baudrate",
+ "Set/Query the system console baud rate",
+ "[-b <rate>]",
+ do_baud_rate
+ );
#endif
// Define table boundaries
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)
{
}
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
}
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);
}
//
//
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
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, "<topic>")) {
- 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, "<topic>")) {
+ 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
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
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;
}
// Author(s): gthomas
// Contributors: gthomas
// Date: 2000-07-14
-// Purpose:
-// Description:
-//
+// Purpose:
+// Description:
+//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
#include <redboot.h>
#include <net/net.h>
-#include <cyg/hal/hal_misc.h> // Helper functions
-#include <cyg/hal/hal_if.h> // HAL I/O interfaces
+#include <cyg/hal/hal_misc.h> // Helper functions
+#include <cyg/hal/hal_if.h> // HAL I/O interfaces
#include <cyg/hal/drv_api.h>
#include <cyg/hal/hal_intr.h>
-#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#include <flash_config.h>
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
#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;
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
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
}
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
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 <local_ip_address>[/<mask_len>]] [-h <server_address>]"
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
" [-d <dns_server_address>]"
-#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN
- " [-D <dns_domain_name>]"
+#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN
+ " [-D <dns_domain_name>]"
#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
// Author(s): gthomas
// Contributors: gthomas
// Date: 2000-07-14
-// Purpose:
-// Description:
-//
+// Purpose:
+// Description:
+//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
#include <cyg/hal/hal_if.h>
#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 */
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
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.
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);
}
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);
}
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;
+ }
}
/*
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);
+ }
}
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);
}
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"));
}
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;
}
/*
__tcp_so_reuseaddr(tcp_socket_t *s)
{
// BSPLOG(bsp_log("__tcp_so_reuseaddr.\n"));
- s->reuse = 0x01;
+ s->reuse = 0x01;
}
/*
__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"));
}
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);
}
/*
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);
}
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"));
}
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;
}
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;
}
/*
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;
}
-
-
// Author(s): gthomas
// Contributors: gthomas
// Date: 2000-07-14
-// Purpose:
-// Description:
-//
+// Purpose:
+// Description:
+//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
// TFTP client support
-#include <redboot.h> // have_net
+#include <redboot.h> // have_net
#include <net/net.h>
#include <net/tftp.h>
#include <net/tftp_support.h>
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;
}
//
#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 <timeout>] [-h <host>]",
- ce_load
- );
+ "ceconnect",
+ "Set up a connection to the CE host PC over TCP/IP and download the run-time image",
+ "[-v] [-t <timeout>] [-h <host>]",
+ ce_load
+ );
#endif
///////////////////////////////////////////////////////////////////////////////////////////////
{
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)) {
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;
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 {
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) {
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;
}
}
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;
// 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++) {
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));
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");
}
// 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
// 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
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
// 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
ce_send_frame(net);
}
#endif
-
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))
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
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
// 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
#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
// 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
// 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)
// 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
// 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
//
// 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
// Author(s): gthomas
// Contributors: gthomas, tsmith, Yoshinori Sato
// Date: 2000-07-14
-// Purpose:
-// Description:
-//
+// Purpose:
+// Description:
+//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
// 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
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
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];
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
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());
}
// 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);