diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 2 | ||||
-rw-r--r-- | common/cmd_bdinfo.c | 11 | ||||
-rw-r--r-- | common/cmd_bedbug.c | 575 | ||||
-rw-r--r-- | common/cmd_boot.c | 8 | ||||
-rw-r--r-- | common/cmd_bootm.c | 9 | ||||
-rw-r--r-- | common/cmd_date.c | 3 | ||||
-rw-r--r-- | common/cmd_elf.c | 8 | ||||
-rw-r--r-- | common/cmd_flash.c | 5 | ||||
-rw-r--r-- | common/cmd_ide.c | 5 | ||||
-rw-r--r-- | common/cmd_immap.c | 6 | ||||
-rw-r--r-- | common/cmd_load.c | 110 | ||||
-rw-r--r-- | common/cmd_log.c | 5 | ||||
-rw-r--r-- | common/cmd_nvedit.c | 4 | ||||
-rw-r--r-- | common/console.c | 18 | ||||
-rw-r--r-- | common/crc16.c | 106 | ||||
-rw-r--r-- | common/devices.c | 4 | ||||
-rw-r--r-- | common/dlmalloc.c | 4 | ||||
-rw-r--r-- | common/env_common.c | 10 | ||||
-rw-r--r-- | common/env_dataflash.c | 4 | ||||
-rw-r--r-- | common/env_eeprom.c | 4 | ||||
-rw-r--r-- | common/env_flash.c | 8 | ||||
-rw-r--r-- | common/env_nand.c | 116 | ||||
-rw-r--r-- | common/env_nowhere.c | 6 | ||||
-rw-r--r-- | common/env_nvram.c | 6 | ||||
-rw-r--r-- | common/exports.c | 3 | ||||
-rw-r--r-- | common/hush.c | 3 | ||||
-rw-r--r-- | common/lcd.c | 7 | ||||
-rw-r--r-- | common/lynxkdi.c | 3 | ||||
-rw-r--r-- | common/main.c | 64 | ||||
-rw-r--r-- | common/serial.c | 16 | ||||
-rw-r--r-- | common/soft_i2c.c | 5 | ||||
-rw-r--r-- | common/xyzModem.c | 739 |
32 files changed, 1401 insertions, 476 deletions
diff --git a/common/Makefile b/common/Makefile index 7dbf84a..eb0b5da 100644 --- a/common/Makefile +++ b/common/Makefile @@ -51,7 +51,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \ memsize.o miiphybb.o miiphyutil.o \ s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \ usb.o usb_kbd.o usb_storage.o \ - virtex2.o xilinx.o + virtex2.o xilinx.o crc16.o xyzModem.o OBJS = $(AOBJS) $(COBJS) diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 40e28dd..04fa4fa 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -28,6 +28,7 @@ #include <command.h> #include <net.h> /* for print_IPaddr */ +DECLARE_GLOBAL_DATA_PTR; #if (CONFIG_COMMANDS & CFG_CMD_BDI) static void print_num(const char *, ulong); @@ -39,8 +40,6 @@ static void print_str(const char *, const char *); int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; - int i; bd_t *bd = gd->bd; char buf[32]; @@ -127,8 +126,6 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; - int i; bd_t *bd = gd->bd; @@ -153,8 +150,6 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; - int i; bd_t *bd = gd->bd; @@ -187,8 +182,6 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; - int i; bd_t *bd = gd->bd; @@ -215,8 +208,6 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; - int i; bd_t *bd = gd->bd; diff --git a/common/cmd_bedbug.c b/common/cmd_bedbug.c index cdb379d..48086a6 100644 --- a/common/cmd_bedbug.c +++ b/common/cmd_bedbug.c @@ -11,187 +11,183 @@ #include <bedbug/regs.h> #include <bedbug/ppc.h> +DECLARE_GLOBAL_DATA_PTR; + #if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif -extern void show_regs __P((struct pt_regs*)); -extern int run_command __P((const char*, int)); +extern void show_regs __P ((struct pt_regs *)); +extern int run_command __P ((const char *, int)); extern char console_buffer[]; -ulong dis_last_addr = 0; /* Last address disassembled */ -ulong dis_last_len = 20; /* Default disassembler length */ -CPU_DEBUG_CTX bug_ctx; /* Bedbug context structure */ - +ulong dis_last_addr = 0; /* Last address disassembled */ +ulong dis_last_len = 20; /* Default disassembler length */ +CPU_DEBUG_CTX bug_ctx; /* Bedbug context structure */ + /* ====================================================================== * U-Boot's puts function does not append a newline, so the bedbug stuff * will use this for the output of the dis/assembler. * ====================================================================== */ -int bedbug_puts(const char *str) +int bedbug_puts (const char *str) { - /* -------------------------------------------------- */ + /* -------------------------------------------------- */ - printf( "%s\r\n", str ); - return 0; -} /* bedbug_puts */ + printf ("%s\r\n", str); + return 0; +} /* bedbug_puts */ + - /* ====================================================================== * Initialize the bug_ctx structure used by the bedbug debugger. This is * specific to the CPU since each has different debug registers and * settings. * ====================================================================== */ -void bedbug_init( void ) +void bedbug_init (void) { - /* -------------------------------------------------- */ + /* -------------------------------------------------- */ #if defined(CONFIG_4xx) - void bedbug405_init( void ); - bedbug405_init(); + void bedbug405_init (void); + + bedbug405_init (); #elif defined(CONFIG_8xx) - void bedbug860_init( void ); - bedbug860_init(); + void bedbug860_init (void); + + bedbug860_init (); #endif #if defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260) - /* Processors that are 603e core based */ - void bedbug603e_init( void ); + /* Processors that are 603e core based */ + void bedbug603e_init (void); - bedbug603e_init(); + bedbug603e_init (); #endif - return; -} /* bedbug_init */ + return; +} /* bedbug_init */ + - /* ====================================================================== * Entry point from the interpreter to the disassembler. Repeated calls * will resume from the last disassembled address. * ====================================================================== */ -int do_bedbug_dis (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - ulong addr; /* Address to start disassembly from */ - ulong len; /* # of instructions to disassemble */ - /* -------------------------------------------------- */ - - /* Setup to go from the last address if none is given */ - addr = dis_last_addr; - len = dis_last_len; - - if (argc < 2) - { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - if(( flag & CMD_FLAG_REPEAT ) == 0 ) - { - /* New command */ - addr = simple_strtoul( argv[1], NULL, 16 ); - - /* If an extra param is given then it is the length */ - if( argc > 2 ) - len = simple_strtoul( argv[2], NULL, 16 ); - } - - /* Run the disassembler */ - disppc( (unsigned char *)addr, 0, len, bedbug_puts, F_RADHEX ); - - dis_last_addr = addr + (len * 4); - dis_last_len = len; - return 0; -} /* do_bedbug_dis */ -U_BOOT_CMD( - ds, 3, 1, do_bedbug_dis, - "ds - disassemble memory\n", - "ds <address> [# instructions]\n" -); + ulong addr; /* Address to start disassembly from */ + ulong len; /* # of instructions to disassemble */ + + /* -------------------------------------------------- */ + + /* Setup to go from the last address if none is given */ + addr = dis_last_addr; + len = dis_last_len; + + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if ((flag & CMD_FLAG_REPEAT) == 0) { + /* New command */ + addr = simple_strtoul (argv[1], NULL, 16); + + /* If an extra param is given then it is the length */ + if (argc > 2) + len = simple_strtoul (argv[2], NULL, 16); + } + + /* Run the disassembler */ + disppc ((unsigned char *) addr, 0, len, bedbug_puts, F_RADHEX); + + dis_last_addr = addr + (len * 4); + dis_last_len = len; + return 0; +} /* do_bedbug_dis */ + +U_BOOT_CMD (ds, 3, 1, do_bedbug_dis, + "ds - disassemble memory\n", + "ds <address> [# instructions]\n"); /* ====================================================================== * Entry point from the interpreter to the assembler. Assembles * instructions in consecutive memory locations until a '.' (period) is * entered on a line by itself. * ====================================================================== */ -int do_bedbug_asm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - long mem_addr; /* Address to assemble into */ - unsigned long instr; /* Machine code for text */ - char prompt[ 15 ]; /* Prompt string for user input */ - int asm_err; /* Error code from the assembler*/ - /* -------------------------------------------------- */ - int rcode = 0; - - if (argc < 2) - { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - printf( "\nEnter '.' when done\n" ); - mem_addr = simple_strtoul( argv[ 1 ], NULL, 16 ); - - while( 1 ) - { - putc( '\n' ); - disppc( (unsigned char *)mem_addr, 0, 1, bedbug_puts, F_RADHEX ); - - sprintf( prompt, "%08lx: ", mem_addr ); - readline( prompt ); - - if( console_buffer[ 0 ] && strcmp( console_buffer, "." )) - { - if(( instr = asmppc( mem_addr, console_buffer, &asm_err )) != 0 ) - { - *(unsigned long *)mem_addr = instr; - mem_addr += 4; - } - else - { - printf( "*** Error: %s ***\n", asm_error_str( asm_err )); - rcode = 1; - } - } - else - { - break; - } - } - return rcode; -} /* do_bedbug_asm */ -U_BOOT_CMD( - as, 2, 0, do_bedbug_asm, - "as - assemble memory\n", - "as <address>\n" -); + long mem_addr; /* Address to assemble into */ + unsigned long instr; /* Machine code for text */ + char prompt[15]; /* Prompt string for user input */ + int asm_err; /* Error code from the assembler */ + + /* -------------------------------------------------- */ + int rcode = 0; + + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + printf ("\nEnter '.' when done\n"); + mem_addr = simple_strtoul (argv[1], NULL, 16); + + while (1) { + putc ('\n'); + disppc ((unsigned char *) mem_addr, 0, 1, bedbug_puts, + F_RADHEX); + + sprintf (prompt, "%08lx: ", mem_addr); + readline (prompt); + + if (console_buffer[0] && strcmp (console_buffer, ".")) { + if ((instr = + asmppc (mem_addr, console_buffer, + &asm_err)) != 0) { + *(unsigned long *) mem_addr = instr; + mem_addr += 4; + } else { + printf ("*** Error: %s ***\n", + asm_error_str (asm_err)); + rcode = 1; + } + } else { + break; + } + } + return rcode; +} /* do_bedbug_asm */ + +U_BOOT_CMD (as, 2, 0, do_bedbug_asm, + "as - assemble memory\n", "as <address>\n"); /* ====================================================================== * Used to set a break point from the interpreter. Simply calls into the * CPU-specific break point set routine. * ====================================================================== */ -int do_bedbug_break (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - /* -------------------------------------------------- */ - if( bug_ctx.do_break ) - (*bug_ctx.do_break)( cmdtp, flag, argc, argv ); - return 0; - -} /* do_bedbug_break */ -U_BOOT_CMD( - break, 3, 0, do_bedbug_break, - "break - set or clear a breakpoint\n", - " - Set or clear a breakpoint\n" - "break <address> - Break at an address\n" - "break off <bp#> - Disable breakpoint.\n" - "break show - List breakpoints.\n" -); + /* -------------------------------------------------- */ + if (bug_ctx.do_break) + (*bug_ctx.do_break) (cmdtp, flag, argc, argv); + return 0; + +} /* do_bedbug_break */ + +U_BOOT_CMD (break, 3, 0, do_bedbug_break, + "break - set or clear a breakpoint\n", + " - Set or clear a breakpoint\n" + "break <address> - Break at an address\n" + "break off <bp#> - Disable breakpoint.\n" + "break show - List breakpoints.\n"); /* ====================================================================== * Called from the debug interrupt routine. Simply calls the CPU-specific @@ -200,16 +196,16 @@ U_BOOT_CMD( void do_bedbug_breakpoint (struct pt_regs *regs) { - /* -------------------------------------------------- */ + /* -------------------------------------------------- */ - if( bug_ctx.break_isr ) - (*bug_ctx.break_isr)( regs ); + if (bug_ctx.break_isr) + (*bug_ctx.break_isr) (regs); - return; -} /* do_bedbug_breakpoint */ + return; +} /* do_bedbug_breakpoint */ + - /* ====================================================================== * Called from the CPU-specific breakpoint handling routine. Enter a * mini main loop until the stopped flag is cleared from the breakpoint @@ -218,81 +214,77 @@ void do_bedbug_breakpoint (struct pt_regs *regs) * This handles the parts of the debugger that are common to all CPU's. * ====================================================================== */ -void bedbug_main_loop( unsigned long addr, struct pt_regs *regs ) +void bedbug_main_loop (unsigned long addr, struct pt_regs *regs) { - int len; /* Length of command line */ - int flag; /* Command flags */ - int rc = 0; /* Result from run_command*/ - char prompt_str[ 20 ]; /* Prompt string */ - static char lastcommand[ CFG_CBSIZE ] = {0}; /* previous command */ - /* -------------------------------------------------- */ + int len; /* Length of command line */ + int flag; /* Command flags */ + int rc = 0; /* Result from run_command */ + char prompt_str[20]; /* Prompt string */ + static char lastcommand[CFG_CBSIZE] = { 0 }; /* previous command */ + /* -------------------------------------------------- */ - if( bug_ctx.clear ) - (*bug_ctx.clear)( bug_ctx.current_bp ); + if (bug_ctx.clear) + (*bug_ctx.clear) (bug_ctx.current_bp); - printf( "Breakpoint %d: ", bug_ctx.current_bp ); - disppc( (unsigned char *)addr, 0, 1, bedbug_puts, F_RADHEX ); + printf ("Breakpoint %d: ", bug_ctx.current_bp); + disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX); - bug_ctx.stopped = 1; - bug_ctx.regs = regs; + bug_ctx.stopped = 1; + bug_ctx.regs = regs; - sprintf( prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp ); + sprintf (prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp); - /* A miniature main loop */ - while( bug_ctx.stopped ) - { - len = readline( prompt_str ); + /* A miniature main loop */ + while (bug_ctx.stopped) { + len = readline (prompt_str); - flag = 0; /* assume no special flags for now */ + flag = 0; /* assume no special flags for now */ - if (len > 0) - strcpy( lastcommand, console_buffer ); - else if( len == 0 ) - flag |= CMD_FLAG_REPEAT; + if (len > 0) + strcpy (lastcommand, console_buffer); + else if (len == 0) + flag |= CMD_FLAG_REPEAT; - if (len == -1) - printf ("<INTERRUPT>\n"); - else - rc = run_command( lastcommand, flag ); + if (len == -1) + printf ("<INTERRUPT>\n"); + else + rc = run_command (lastcommand, flag); - if (rc <= 0) { - /* invalid command or not repeatable, forget it */ - lastcommand[0] = 0; - } - } + if (rc <= 0) { + /* invalid command or not repeatable, forget it */ + lastcommand[0] = 0; + } + } - bug_ctx.regs = NULL; - bug_ctx.current_bp = 0; + bug_ctx.regs = NULL; + bug_ctx.current_bp = 0; - return; -} /* bedbug_main_loop */ + return; +} /* bedbug_main_loop */ + - /* ====================================================================== * Interpreter command to continue from a breakpoint. Just clears the * stopped flag in the context so that the breakpoint routine will * return. * ====================================================================== */ -int do_bedbug_continue (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) - +int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - /* -------------------------------------------------- */ - - if( ! bug_ctx.stopped ) - { - printf( "Not at a breakpoint\n" ); - return 1; - } - - bug_ctx.stopped = 0; - return 0; -} /* do_bedbug_continue */ -U_BOOT_CMD( - continue, 1, 0, do_bedbug_continue, - "continue- continue from a breakpoint\n", - " - continue from a breakpoint.\n" -); + /* -------------------------------------------------- */ + + if (!bug_ctx.stopped) { + printf ("Not at a breakpoint\n"); + return 1; + } + + bug_ctx.stopped = 0; + return 0; +} /* do_bedbug_continue */ + +U_BOOT_CMD (continue, 1, 0, do_bedbug_continue, + "continue- continue from a breakpoint\n", + " - continue from a breakpoint.\n"); /* ====================================================================== * Interpreter command to continue to the next instruction, stepping into @@ -300,31 +292,30 @@ U_BOOT_CMD( * the address passes control to the CPU-specific set breakpoint routine * for the current breakpoint number. * ====================================================================== */ -int do_bedbug_step (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - unsigned long addr; /* Address to stop at */ - /* -------------------------------------------------- */ - - if( ! bug_ctx.stopped ) - { - printf( "Not at a breakpoint\n" ); - return 1; - } - - if( !find_next_address( (unsigned char *)&addr, FALSE, bug_ctx.regs )) - return 1; - - if( bug_ctx.set ) - (*bug_ctx.set)( bug_ctx.current_bp, addr ); - - bug_ctx.stopped = 0; - return 0; -} /* do_bedbug_step */ -U_BOOT_CMD( - step, 1, 1, do_bedbug_step, - "step - single step execution.\n", - " - single step execution.\n" -); + unsigned long addr; /* Address to stop at */ + + /* -------------------------------------------------- */ + + if (!bug_ctx.stopped) { + printf ("Not at a breakpoint\n"); + return 1; + } + + if (!find_next_address ((unsigned char *) &addr, FALSE, bug_ctx.regs)) + return 1; + + if (bug_ctx.set) + (*bug_ctx.set) (bug_ctx.current_bp, addr); + + bug_ctx.stopped = 0; + return 0; +} /* do_bedbug_step */ + +U_BOOT_CMD (step, 1, 1, do_bedbug_step, + "step - single step execution.\n", + " - single step execution.\n"); /* ====================================================================== * Interpreter command to continue to the next instruction, stepping over @@ -332,105 +323,97 @@ U_BOOT_CMD( * the address passes control to the CPU-specific set breakpoint routine * for the current breakpoint number. * ====================================================================== */ -int do_bedbug_next (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - unsigned long addr; /* Address to stop at */ - /* -------------------------------------------------- */ - - if( ! bug_ctx.stopped ) - { - printf( "Not at a breakpoint\n" ); - return 1; - } - - if( !find_next_address( (unsigned char *)&addr, TRUE, bug_ctx.regs )) - return 1; - - if( bug_ctx.set ) - (*bug_ctx.set)( bug_ctx.current_bp, addr ); - - bug_ctx.stopped = 0; - return 0; -} /* do_bedbug_next */ -U_BOOT_CMD( - next, 1, 1, do_bedbug_next, - "next - single step execution, stepping over subroutines.\n", - " - single step execution, stepping over subroutines.\n" -); + unsigned long addr; /* Address to stop at */ + + /* -------------------------------------------------- */ + + if (!bug_ctx.stopped) { + printf ("Not at a breakpoint\n"); + return 1; + } + + if (!find_next_address ((unsigned char *) &addr, TRUE, bug_ctx.regs)) + return 1; + + if (bug_ctx.set) + (*bug_ctx.set) (bug_ctx.current_bp, addr); + + bug_ctx.stopped = 0; + return 0; +} /* do_bedbug_next */ + +U_BOOT_CMD (next, 1, 1, do_bedbug_next, + "next - single step execution, stepping over subroutines.\n", + " - single step execution, stepping over subroutines.\n"); /* ====================================================================== * Interpreter command to print the current stack. This assumes an EABI * architecture, so it starts with GPR R1 and works back up the stack. * ====================================================================== */ -int do_bedbug_stack (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; - - unsigned long sp; /* Stack pointer */ - unsigned long func; /* LR from stack */ - int depth; /* Stack iteration level */ - int skip = 1; /* Flag to skip the first entry */ - unsigned long top; /* Top of memory address */ - /* -------------------------------------------------- */ - - if( ! bug_ctx.stopped ) - { - printf( "Not at a breakpoint\n" ); - return 1; - } - - top = gd->bd->bi_memstart + gd->bd->bi_memsize; - depth = 0; - - printf( "Depth PC\n" ); - printf( "----- --------\n" ); - printf( "%5d %08lx\n", depth++, bug_ctx.regs->nip ); - - sp = bug_ctx.regs->gpr[ 1 ]; - func = *(unsigned long *)(sp+4); - - while(( func < top ) && ( sp < top )) - { - if( !skip ) - printf( "%5d %08lx\n", depth++, func ); - else - --skip; - - sp = *(unsigned long *)sp; - func = *(unsigned long *)(sp+4); - } - return 0; -} /* do_bedbug_stack */ -U_BOOT_CMD( - where, 1, 1, do_bedbug_stack, - "where - Print the running stack.\n", - " - Print the running stack.\n" -); + unsigned long sp; /* Stack pointer */ + unsigned long func; /* LR from stack */ + int depth; /* Stack iteration level */ + int skip = 1; /* Flag to skip the first entry */ + unsigned long top; /* Top of memory address */ + + /* -------------------------------------------------- */ + + if (!bug_ctx.stopped) { + printf ("Not at a breakpoint\n"); + return 1; + } + + top = gd->bd->bi_memstart + gd->bd->bi_memsize; + depth = 0; + + printf ("Depth PC\n"); + printf ("----- --------\n"); + printf ("%5d %08lx\n", depth++, bug_ctx.regs->nip); + + sp = bug_ctx.regs->gpr[1]; + func = *(unsigned long *) (sp + 4); + + while ((func < top) && (sp < top)) { + if (!skip) + printf ("%5d %08lx\n", depth++, func); + else + --skip; + + sp = *(unsigned long *) sp; + func = *(unsigned long *) (sp + 4); + } + return 0; +} /* do_bedbug_stack */ + +U_BOOT_CMD (where, 1, 1, do_bedbug_stack, + "where - Print the running stack.\n", + " - Print the running stack.\n"); /* ====================================================================== * Interpreter command to dump the registers. Calls the CPU-specific * show registers routine. * ====================================================================== */ -int do_bedbug_rdump (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - /* -------------------------------------------------- */ - - if( ! bug_ctx.stopped ) - { - printf( "Not at a breakpoint\n" ); - return 1; - } - - show_regs( bug_ctx.regs ); - return 0; -} /* do_bedbug_rdump */ -U_BOOT_CMD( - rdump, 1, 1, do_bedbug_rdump, - "rdump - Show registers.\n", - " - Show registers.\n" -); + /* -------------------------------------------------- */ + + if (!bug_ctx.stopped) { + printf ("Not at a breakpoint\n"); + return 1; + } + + show_regs (bug_ctx.regs); + return 0; +} /* do_bedbug_rdump */ + +U_BOOT_CMD (rdump, 1, 1, do_bedbug_rdump, + "rdump - Show registers.\n", " - Show registers.\n"); /* ====================================================================== */ -#endif /* CFG_CMD_BEDBUG */ +#endif /* CFG_CMD_BEDBUG */ /* diff --git a/common/cmd_boot.c b/common/cmd_boot.c index 5b58d4e..e68f16f 100644 --- a/common/cmd_boot.c +++ b/common/cmd_boot.c @@ -28,14 +28,12 @@ #include <command.h> #include <net.h> - -/* -------------------------------------------------------------------- */ +#if defined(CONFIG_I386) +DECLARE_GLOBAL_DATA_PTR; +#endif int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { -#if defined(CONFIG_I386) - DECLARE_GLOBAL_DATA_PTR; -#endif ulong addr, rc; int rcode = 0; diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index aeb7842..fdf7180 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -38,6 +38,8 @@ #include <ft_build.h> #endif +DECLARE_GLOBAL_DATA_PTR; + /*cmd_boot.c*/ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); @@ -469,7 +471,6 @@ U_BOOT_CMD( static void fixup_silent_linux () { - DECLARE_GLOBAL_DATA_PTR; char buf[256], *start, *end; char *cmdline = getenv ("bootargs"); @@ -512,8 +513,6 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ulong *len_ptr, int verify) { - DECLARE_GLOBAL_DATA_PTR; - ulong sp; ulong len, checksum; ulong initrd_start, initrd_end; @@ -856,8 +855,6 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, ulong *len_ptr, int verify) { - DECLARE_GLOBAL_DATA_PTR; - image_header_t *hdr = &header; void (*loader)(bd_t *, image_header_t *, char *, char *); @@ -941,7 +938,6 @@ do_bootm_artos (cmd_tbl_t *cmdtp, int flag, ulong *len_ptr, int verify) { - DECLARE_GLOBAL_DATA_PTR; ulong top; char *s, *cmdline; char **fwenv, **ss; @@ -1370,7 +1366,6 @@ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong addr, ulong *len_ptr, int verify) { - DECLARE_GLOBAL_DATA_PTR; image_header_t *hdr = &header; void (*entry_point)(bd_t *); diff --git a/common/cmd_date.c b/common/cmd_date.c index a569d78..84932f7 100644 --- a/common/cmd_date.c +++ b/common/cmd_date.c @@ -28,6 +28,8 @@ #include <command.h> #include <rtc.h> +DECLARE_GLOBAL_DATA_PTR; + #if (CONFIG_COMMANDS & CFG_CMD_DATE) const char *weekdays[] = { @@ -40,7 +42,6 @@ int mk_date (char *, struct rtc_time *); int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; struct rtc_time tm; int rcode = 0; diff --git a/common/cmd_elf.c b/common/cmd_elf.c index eccf2e9..1d92bb3 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -19,6 +19,9 @@ #include <net.h> #include <elf.h> +#if defined(CONFIG_WALNUT) || defined(CFG_VXWORKS_MAC_PTR) +DECLARE_GLOBAL_DATA_PTR; +#endif #if (CONFIG_COMMANDS & CFG_CMD_ELF) @@ -78,11 +81,6 @@ int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * ====================================================================== */ int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { -#if defined(CONFIG_WALNUT) || \ - defined(CFG_VXWORKS_MAC_PTR) - DECLARE_GLOBAL_DATA_PTR; -#endif - unsigned long addr; /* Address of image */ unsigned long bootaddr; /* Address to put the bootline */ char *bootline; /* Text of the bootline */ diff --git a/common/cmd_flash.c b/common/cmd_flash.c index 0aa4783..201f4e3 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -455,6 +455,7 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #ifdef CONFIG_HAS_DATAFLASH int status; #endif + if (argc < 3) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; @@ -655,10 +656,10 @@ int flash_sect_protect (int p, ulong addr_first, ulong addr_last) #endif /* CFG_FLASH_PROTECTION */ } } + } #if defined(CFG_FLASH_PROTECTION) - if (!rcode) putc ('\n'); + puts (" done\n"); #endif /* CFG_FLASH_PROTECTION */ - } printf ("%sProtected %d sectors\n", p ? "" : "Un-", protected); diff --git a/common/cmd_ide.c b/common/cmd_ide.c index b67d35a..41621ba 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -60,6 +60,10 @@ unsigned long mips_io_port_base = 0; # define SHOW_BOOT_PROGRESS(arg) #endif +#ifdef CONFIG_IDE_8xx_DIRECT +DECLARE_GLOBAL_DATA_PTR; +#endif + #ifdef __PPC__ # define EIEIO __asm__ volatile ("eieio") # define SYNC __asm__ volatile ("sync") @@ -498,7 +502,6 @@ void ide_init (void) { #ifdef CONFIG_IDE_8xx_DIRECT - DECLARE_GLOBAL_DATA_PTR; volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); #endif diff --git a/common/cmd_immap.c b/common/cmd_immap.c index 559d7b4..fa79b45 100644 --- a/common/cmd_immap.c +++ b/common/cmd_immap.c @@ -41,6 +41,10 @@ #include <asm/iopin_8260.h> #endif +#if defined(CONFIG_8xx) || defined(CONFIG_8260) +DECLARE_GLOBAL_DATA_PTR; +#endif + static void unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { @@ -450,10 +454,8 @@ static void prbrg (int n, uint val) uint div16 = (val & CPM_BRG_DIV16) != 0; #if defined(CONFIG_8xx) - DECLARE_GLOBAL_DATA_PTR; ulong clock = gd->cpu_clk; #elif defined(CONFIG_8260) - DECLARE_GLOBAL_DATA_PTR; ulong clock = gd->brg_clk; #endif diff --git a/common/cmd_load.c b/common/cmd_load.c index 7498497..31fef81 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -29,10 +29,13 @@ #include <s_record.h> #include <net.h> #include <exports.h> +#include <xyzModem.h> +DECLARE_GLOBAL_DATA_PTR; #if (CONFIG_COMMANDS & CFG_CMD_LOADS) static ulong load_serial (ulong offset); +static ulong load_serial_ymodem (ulong offset); static int read_record (char *buf, ulong len); # if (CONFIG_COMMANDS & CFG_CMD_SAVES) static int save_serial (ulong offset, ulong size); @@ -53,7 +56,6 @@ int do_load_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *env_echo; int rcode = 0; #ifdef CFG_LOADS_BAUD_CHANGE - DECLARE_GLOBAL_DATA_PTR; int load_baudrate, current_baudrate; load_baudrate = current_baudrate = gd->baudrate; @@ -213,7 +215,6 @@ load_serial (ulong offset) static int read_record (char *buf, ulong len) { - DECLARE_GLOBAL_DATA_PTR; char *p; char c; @@ -256,7 +257,6 @@ int do_save_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong offset = 0; ulong size = 0; #ifdef CFG_LOADS_BAUD_CHANGE - DECLARE_GLOBAL_DATA_PTR; int save_baudrate, current_baudrate; save_baudrate = current_baudrate = gd->baudrate; @@ -433,8 +433,6 @@ char his_quote; /* quote chars he'll use */ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; - ulong offset = 0; ulong addr; int load_baudrate, current_baudrate; @@ -475,21 +473,31 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } } - printf ("## Ready for binary (kermit) download " - "to 0x%08lX at %d bps...\n", - offset, - load_baudrate); - addr = load_serial_bin (offset); + if (strcmp(argv[0],"loady")==0) { + printf ("## Ready for binary (ymodem) download " + "to 0x%08lX at %d bps...\n", + offset, + load_baudrate); + + addr = load_serial_ymodem (offset); - if (addr == ~0) { - load_addr = 0; - printf ("## Binary (kermit) download aborted\n"); - rcode = 1; } else { - printf ("## Start Addr = 0x%08lX\n", addr); - load_addr = addr; - } + printf ("## Ready for binary (kermit) download " + "to 0x%08lX at %d bps...\n", + offset, + load_baudrate); + addr = load_serial_bin (offset); + + if (addr == ~0) { + load_addr = 0; + printf ("## Binary (kermit) download aborted\n"); + rcode = 1; + } else { + printf ("## Start Addr = 0x%08lX\n", addr); + load_addr = addr; + } + } if (load_baudrate != current_baudrate) { printf ("## Switch baudrate to %d bps and press ESC ...\n", current_baudrate); @@ -963,6 +971,66 @@ START: } return ((ulong) os_data_addr - (ulong) bin_start_address); } + +static int getcxmodem(void) { + if (tstc()) + return (getc()); + return -1; +} +static ulong load_serial_ymodem (ulong offset) +{ + int size; + char buf[32]; + int err; + int res; + connection_info_t info; + char ymodemBuf[1024]; + ulong store_addr = ~0; + ulong addr = 0; + + size=0; + info.mode=xyzModem_ymodem; + res=xyzModem_stream_open(&info, &err); + if (!res) { + + while ((res=xyzModem_stream_read(ymodemBuf, 1024, &err)) > 0 ){ + store_addr = addr + offset; + size+=res; + addr+=res; +#ifndef CFG_NO_FLASH + if (addr2info(store_addr)) { + int rc; + + rc = flash_write((char *)ymodemBuf,store_addr,res); + if (rc != 0) { + flash_perror (rc); + return (~0); + } + } else +#endif + { + memcpy ((char *)(store_addr), ymodemBuf, res); + } + + } + } + else { + printf ("%s\n",xyzModem_error(err)); + } + + xyzModem_stream_close(&err); + xyzModem_stream_terminate(false,&getcxmodem); + + + flush_cache (offset, size); + + printf("## Total Size = 0x%08x = %d Bytes\n", size, size); + sprintf(buf, "%X", size); + setenv("filesize", buf); + + return offset; +} + #endif /* CFG_CMD_LOADB */ /* -------------------------------------------------------------------- */ @@ -1022,6 +1090,14 @@ U_BOOT_CMD( " with offset 'off' and baudrate 'baud'\n" ); +U_BOOT_CMD( + loady, 3, 0, do_load_serial_bin, + "loady - load binary file over serial line (ymodem mode)\n", + "[ off ] [ baud ]\n" + " - load binary file over serial line" + " with offset 'off' and baudrate 'baud'\n" +); + #endif /* CFG_CMD_LOADB */ /* -------------------------------------------------------------------- */ diff --git a/common/cmd_log.c b/common/cmd_log.c index efc9689..042a403 100644 --- a/common/cmd_log.c +++ b/common/cmd_log.c @@ -46,6 +46,8 @@ #include <post.h> #include <logbuff.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_LOGBUFFER) /* Local prototypes */ @@ -73,7 +75,6 @@ static unsigned long *ext_logged_chars; in linux/kernel/printk */ void logbuff_init_ptrs (void) { - DECLARE_GLOBAL_DATA_PTR; unsigned long *ext_tag; unsigned long post_word; char *s; @@ -139,8 +140,6 @@ static void logbuff_puts (const char *s) void logbuff_log(char *msg) { - DECLARE_GLOBAL_DATA_PTR; - if ((gd->post_log_word & LOGBUFF_INITIALIZED)) { logbuff_printk (msg); } else { diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index ecf1db4..6257fbd 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -50,6 +50,8 @@ #include <net.h> #endif +DECLARE_GLOBAL_DATA_PTR; + #if !defined(CFG_ENV_IS_IN_NVRAM) && \ !defined(CFG_ENV_IS_IN_EEPROM) && \ !defined(CFG_ENV_IS_IN_FLASH) && \ @@ -152,8 +154,6 @@ int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int _do_setenv (int flag, int argc, char *argv[]) { - DECLARE_GLOBAL_DATA_PTR; - int i, len, oldval; int console = -1; uchar *env, *nxt = NULL; diff --git a/common/console.c b/common/console.c index 3c535d2..e9f23be 100644 --- a/common/console.c +++ b/common/console.c @@ -27,6 +27,8 @@ #include <console.h> #include <exports.h> +DECLARE_GLOBAL_DATA_PTR; + #ifdef CONFIG_AMIGAONEG3SE int console_changed = 0; #endif @@ -48,7 +50,6 @@ extern int overwrite_console (void); static int console_setfile (int file, device_t * dev) { - DECLARE_GLOBAL_DATA_PTR; int error = 0; if (dev == NULL) @@ -161,8 +162,6 @@ void fprintf (int file, const char *fmt, ...) int getc (void) { - DECLARE_GLOBAL_DATA_PTR; - if (gd->flags & GD_FLG_DEVINIT) { /* Get from the standard input */ return fgetc (stdin); @@ -174,8 +173,6 @@ int getc (void) int tstc (void) { - DECLARE_GLOBAL_DATA_PTR; - if (gd->flags & GD_FLG_DEVINIT) { /* Test the standard input */ return ftstc (stdin); @@ -187,8 +184,6 @@ int tstc (void) void putc (const char c) { - DECLARE_GLOBAL_DATA_PTR; - #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -205,8 +200,6 @@ void putc (const char c) void puts (const char *s) { - DECLARE_GLOBAL_DATA_PTR; - #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -258,8 +251,6 @@ static int ctrlc_disabled = 0; /* see disable_ctrl() */ static int ctrlc_was_pressed = 0; int ctrlc (void) { - DECLARE_GLOBAL_DATA_PTR; - if (!ctrlc_disabled && gd->have_console) { if (tstc ()) { switch (getc ()) { @@ -370,8 +361,6 @@ int console_assign (int file, char *devname) /* Called before relocation - use serial functions */ int console_init_f (void) { - DECLARE_GLOBAL_DATA_PTR; - gd->have_console = 1; #ifdef CONFIG_SILENT_CONSOLE @@ -407,7 +396,6 @@ device_t *search_device (int flags, char *name) /* Called after the relocation - use desired console functions */ int console_init_r (void) { - DECLARE_GLOBAL_DATA_PTR; char *stdinname, *stdoutname, *stderrname; device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL; #ifdef CFG_CONSOLE_ENV_OVERWRITE @@ -499,8 +487,6 @@ int console_init_r (void) /* Called after the relocation - use desired console functions */ int console_init_r (void) { - DECLARE_GLOBAL_DATA_PTR; - device_t *inputdev = NULL, *outputdev = NULL; int i, items = ListNumItems (devlist); diff --git a/common/crc16.c b/common/crc16.c new file mode 100644 index 0000000..d571405 --- /dev/null +++ b/common/crc16.c @@ -0,0 +1,106 @@ +//========================================================================== +// +// crc16.c +// +// 16 bit CRC with polynomial x^16+x^12+x^5+1 +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 2002 Gary Thomas +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas,asl +// Date: 2001-01-31 +// Purpose: +// Description: +// +// This code is part of eCos (tm). +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include "crc.h" + +// Table of CRC constants - implements x^16+x^12+x^5+1 +static const uint16_t crc16_tab[] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, +}; + +uint16_t +cyg_crc16(unsigned char *buf, int len) +{ + int i; + uint16_t cksum; + + cksum = 0; + for (i = 0; i < len; i++) { + cksum = crc16_tab[((cksum>>8) ^ *buf++) & 0xFF] ^ (cksum << 8); + } + return cksum; +} + diff --git a/common/devices.c b/common/devices.c index bd4dfa0..ddf8f8e 100644 --- a/common/devices.c +++ b/common/devices.c @@ -34,6 +34,8 @@ #include <i2c.h> #endif +DECLARE_GLOBAL_DATA_PTR; + list_t devlist = 0; device_t *stdio_devices[] = { NULL, NULL, NULL }; char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" }; @@ -160,8 +162,6 @@ int device_deregister(char *devname) int devices_init (void) { #ifndef CONFIG_ARM /* already relocated for current ARM implementation */ - DECLARE_GLOBAL_DATA_PTR; - ulong relocation_offset = gd->reloc_off; int i; diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 0c04872..20c2069 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -949,6 +949,8 @@ void malloc_stats(); #endif /* 0 */ /* Moved to malloc.h */ #include <common.h> +DECLARE_GLOBAL_DATA_PTR; + /* Emulation of sbrk for WIN32 All code within the ifdef WIN32 is untested by me. @@ -1493,8 +1495,6 @@ static mbinptr av_[NAV * 2 + 2] = { void malloc_bin_reloc (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned long *p = (unsigned long *)(&av_[2]); int i; for (i=2; i<(sizeof(av_)/sizeof(mbinptr)); ++i) { diff --git a/common/env_common.c b/common/env_common.c index 3201135..eb33422 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -37,6 +37,8 @@ # define SHOW_BOOT_PROGRESS(arg) #endif +DECLARE_GLOBAL_DATA_PTR; + #ifdef CONFIG_AMIGAONEG3SE extern void enable_nvram(void); extern void disable_nvram(void); @@ -150,7 +152,6 @@ void env_crc_update (void) static uchar env_get_char_init (int index) { - DECLARE_GLOBAL_DATA_PTR; uchar c; /* if crc was bad, use the default environment */ @@ -167,7 +168,6 @@ static uchar env_get_char_init (int index) #ifdef CONFIG_AMIGAONEG3SE uchar env_get_char_memory (int index) { - DECLARE_GLOBAL_DATA_PTR; uchar retval; enable_nvram(); if (gd->env_valid) { @@ -181,8 +181,6 @@ uchar env_get_char_memory (int index) #else uchar env_get_char_memory (int index) { - DECLARE_GLOBAL_DATA_PTR; - if (gd->env_valid) { return ( *((uchar *)(gd->env_addr + index)) ); } else { @@ -193,8 +191,6 @@ uchar env_get_char_memory (int index) uchar *env_get_addr (int index) { - DECLARE_GLOBAL_DATA_PTR; - if (gd->env_valid) { return ( ((uchar *)(gd->env_addr + index)) ); } else { @@ -204,8 +200,6 @@ uchar *env_get_addr (int index) void env_relocate (void) { - DECLARE_GLOBAL_DATA_PTR; - DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__, gd->reloc_off); diff --git a/common/env_dataflash.c b/common/env_dataflash.c index 8834da0..93fff29 100644 --- a/common/env_dataflash.c +++ b/common/env_dataflash.c @@ -26,6 +26,8 @@ #include <linux/stddef.h> #include <dataflash.h> +DECLARE_GLOBAL_DATA_PTR; + env_t *env_ptr = NULL; char * env_name_spec = "dataflash"; @@ -68,8 +70,6 @@ int i; */ int env_init(void) { - DECLARE_GLOBAL_DATA_PTR; - ulong crc, len, new; unsigned off; uchar buf[64]; diff --git a/common/env_eeprom.c b/common/env_eeprom.c index 50c623e..2adc129 100644 --- a/common/env_eeprom.c +++ b/common/env_eeprom.c @@ -32,6 +32,8 @@ #include <environment.h> #include <linux/stddef.h> +DECLARE_GLOBAL_DATA_PTR; + env_t *env_ptr = NULL; char * env_name_spec = "EEPROM"; @@ -75,8 +77,6 @@ int saveenv(void) */ int env_init(void) { - DECLARE_GLOBAL_DATA_PTR; - ulong crc, len, new; unsigned off; uchar buf[64]; diff --git a/common/env_flash.c b/common/env_flash.c index a2ea9c4..1674b30 100644 --- a/common/env_flash.c +++ b/common/env_flash.c @@ -35,6 +35,8 @@ #include <linux/stddef.h> #include <malloc.h> +DECLARE_GLOBAL_DATA_PTR; + #if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) #define CMD_SAVEENV #elif defined(CFG_ENV_ADDR_REDUND) @@ -89,8 +91,6 @@ extern int default_environment_size; uchar env_get_char_spec (int index) { - DECLARE_GLOBAL_DATA_PTR; - return ( *((uchar *)(gd->env_addr + index)) ); } @@ -98,7 +98,6 @@ uchar env_get_char_spec (int index) int env_init(void) { - DECLARE_GLOBAL_DATA_PTR; int crc1_ok = 0, crc2_ok = 0; uchar flag1 = flash_addr->flags; @@ -260,7 +259,6 @@ Done: int env_init(void) { - DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_OMAP2420H4 int flash_probe(void); @@ -358,8 +356,6 @@ void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) || defined(CFG_ENV_ADDR_REDUND) #ifdef CFG_ENV_ADDR_REDUND - DECLARE_GLOBAL_DATA_PTR; - if (gd->env_addr != (ulong)&(flash_addr->data)) { env_t * etmp = flash_addr; ulong ltmp = end_addr; diff --git a/common/env_nand.c b/common/env_nand.c index dd27f7b..0a05b09 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -36,21 +36,19 @@ #include <command.h> #include <environment.h> #include <linux/stddef.h> +#include <malloc.h> #include <nand.h> #if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_NAND)) == (CFG_CMD_ENV|CFG_CMD_NAND)) #define CMD_SAVEENV +#elif defined(CFG_ENV_OFFSET_REDUND) +#error Cannot use CFG_ENV_OFFSET_REDUND without CFG_CMD_ENV & CFG_CMD_NAND #endif -#if defined(CFG_ENV_SIZE_REDUND) -#error CFG_ENV_SIZE_REDUND not supported yet +#if defined(CFG_ENV_SIZE_REDUND) && (CFG_ENV_SIZE_REDUND != CFG_ENV_SIZE) +#error CFG_ENV_SIZE_REDUND should be the same as CFG_ENV_SIZE #endif -#if defined(CFG_ENV_ADDR_REDUND) -#error CFG_ENV_ADDR_REDUND and CFG_ENV_IS_IN_NAND not supported yet -#endif - - #ifdef CONFIG_INFERNO #error CONFIG_INFERNO not supported yet #endif @@ -80,11 +78,10 @@ env_t *env_ptr = 0; /* local functions */ static void use_default(void); +DECLARE_GLOBAL_DATA_PTR; uchar env_get_char_spec (int index) { - DECLARE_GLOBAL_DATA_PTR; - return ( *((uchar *)(gd->env_addr + index)) ); } @@ -97,9 +94,7 @@ uchar env_get_char_spec (int index) */ int env_init(void) { - DECLARE_GLOBAL_DATA_PTR; - - gd->env_addr = (ulong)&default_environment[0]; + gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 1; return (0); @@ -110,6 +105,41 @@ int env_init(void) * The legacy NAND code saved the environment in the first NAND device i.e., * nand_dev_desc + 0. This is also the behaviour using the new NAND code. */ +#ifdef CFG_ENV_OFFSET_REDUND +int saveenv(void) +{ + ulong total; + int ret = 0; + + env_ptr->flags++; + total = CFG_ENV_SIZE; + + if(gd->env_valid == 1) { + puts ("Erasing redundant Nand..."); + if (nand_erase(&nand_info[0], + CFG_ENV_OFFSET_REDUND, CFG_ENV_SIZE)) + return 1; + puts ("Writing to redundant Nand... "); + ret = nand_write(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total, + (u_char*) env_ptr); + } else { + puts ("Erasing Nand..."); + if (nand_erase(&nand_info[0], + CFG_ENV_OFFSET, CFG_ENV_SIZE)) + return 1; + + puts ("Writing to Nand... "); + ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, + (u_char*) env_ptr); + } + if (ret || total != CFG_ENV_SIZE) + return 1; + + puts ("done\n"); + gd->env_valid = (gd->env_valid == 2 ? 1 : 2); + return ret; +} +#else /* ! CFG_ENV_OFFSET_REDUND */ int saveenv(void) { ulong total; @@ -128,9 +158,63 @@ int saveenv(void) puts ("done\n"); return ret; } +#endif /* CFG_ENV_OFFSET_REDUND */ #endif /* CMD_SAVEENV */ +#ifdef CFG_ENV_OFFSET_REDUND +void env_relocate_spec (void) +{ +#if !defined(ENV_IS_EMBEDDED) + ulong total; + int crc1_ok = 0, crc2_ok = 0; + env_t *tmp_env1, *tmp_env2; + + total = CFG_ENV_SIZE; + + tmp_env1 = (env_t *) malloc(CFG_ENV_SIZE); + tmp_env2 = (env_t *) malloc(CFG_ENV_SIZE); + + nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, + (u_char*) tmp_env1); + nand_read(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total, + (u_char*) tmp_env2); + + crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); + crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); + + if(!crc1_ok && !crc2_ok) + return use_default(); + else if(crc1_ok && !crc2_ok) + gd->env_valid = 1; + else if(!crc1_ok && crc2_ok) + gd->env_valid = 2; + else { + /* both ok - check serial */ + if(tmp_env1->flags == 255 && tmp_env2->flags == 0) + gd->env_valid = 2; + else if(tmp_env2->flags == 255 && tmp_env1->flags == 0) + gd->env_valid = 1; + else if(tmp_env1->flags > tmp_env2->flags) + gd->env_valid = 1; + else if(tmp_env2->flags > tmp_env1->flags) + gd->env_valid = 2; + else /* flags are equal - almost impossible */ + gd->env_valid = 1; + } + + free(env_ptr); + if(gd->env_valid == 1) { + env_ptr = tmp_env1; + free(tmp_env2); + } else { + env_ptr = tmp_env2; + free(tmp_env1); + } + +#endif /* ! ENV_IS_EMBEDDED */ +} +#else /* ! CFG_ENV_OFFSET_REDUND */ /* * The legacy NAND code saved the environment in the first NAND device i.e., * nand_dev_desc + 0. This is also the behaviour using the new NAND code. @@ -149,16 +233,14 @@ void env_relocate_spec (void) if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) return use_default(); #endif /* ! ENV_IS_EMBEDDED */ - } +#endif /* CFG_ENV_OFFSET_REDUND */ static void use_default() { - DECLARE_GLOBAL_DATA_PTR; - puts ("*** Warning - bad CRC or NAND, using default environment\n\n"); - if (default_environment_size > CFG_ENV_SIZE){ + if (default_environment_size > CFG_ENV_SIZE){ puts ("*** Error - default environment is too large\n\n"); return; } @@ -168,7 +250,7 @@ static void use_default() default_environment, default_environment_size); env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE); - gd->env_valid = 1; + gd->env_valid = 1; } diff --git a/common/env_nowhere.c b/common/env_nowhere.c index ee4237c..17ecc77 100644 --- a/common/env_nowhere.c +++ b/common/env_nowhere.c @@ -32,6 +32,8 @@ #include <environment.h> #include <linux/stddef.h> +DECLARE_GLOBAL_DATA_PTR; + env_t *env_ptr = NULL; extern uchar default_environment[]; @@ -44,8 +46,6 @@ void env_relocate_spec (void) uchar env_get_char_spec (int index) { - DECLARE_GLOBAL_DATA_PTR; - return ( *((uchar *)(gd->env_addr + index)) ); } @@ -56,8 +56,6 @@ uchar env_get_char_spec (int index) */ int env_init(void) { - DECLARE_GLOBAL_DATA_PTR; - gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 0; diff --git a/common/env_nvram.c b/common/env_nvram.c index a406e42..7c18896 100644 --- a/common/env_nvram.c +++ b/common/env_nvram.c @@ -42,6 +42,8 @@ #include <common.h> +DECLARE_GLOBAL_DATA_PTR; + #ifdef CFG_ENV_IS_IN_NVRAM /* Environment is in NVRAM */ #include <command.h> @@ -74,7 +76,6 @@ uchar env_get_char_spec (int index) return c; #else - DECLARE_GLOBAL_DATA_PTR; uchar retval; enable_nvram(); retval = *((uchar *)(gd->env_addr + index)); @@ -92,8 +93,6 @@ uchar env_get_char_spec (int index) return c; #else - DECLARE_GLOBAL_DATA_PTR; - return *((uchar *)(gd->env_addr + index)); #endif } @@ -135,7 +134,6 @@ int saveenv (void) */ int env_init (void) { - DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_AMIGAONEG3SE enable_nvram(); #endif diff --git a/common/exports.c b/common/exports.c index 9858217..ef25338 100644 --- a/common/exports.c +++ b/common/exports.c @@ -1,6 +1,8 @@ #include <common.h> #include <exports.h> +DECLARE_GLOBAL_DATA_PTR; + static void dummy(void) { } @@ -12,7 +14,6 @@ unsigned long get_version(void) void jumptable_init (void) { - DECLARE_GLOBAL_DATA_PTR; int i; gd->jt = (void **) malloc (XF_MAX * sizeof (void *)); diff --git a/common/hush.c b/common/hush.c index bb5041a..feb5627 100644 --- a/common/hush.c +++ b/common/hush.c @@ -138,6 +138,8 @@ extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); / #endif #ifdef __U_BOOT__ +DECLARE_GLOBAL_DATA_PTR; + #define EXIT_SUCCESS 0 #define EOF -1 #define syntax() syntax_err() @@ -3272,7 +3274,6 @@ int parse_file_outer(void) #ifdef __U_BOOT__ static void u_boot_hush_reloc(void) { - DECLARE_GLOBAL_DATA_PTR; unsigned long addr; struct reserved_combo *r; diff --git a/common/lcd.c b/common/lcd.c index e64972f..0be1912 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -50,7 +50,6 @@ #include <lcdvideo.h> #endif - #ifdef CONFIG_LCD /************************************************************************/ @@ -68,6 +67,8 @@ # endif #endif +DECLARE_GLOBAL_DATA_PTR; + ulong lcd_setmem (ulong addr); static void lcd_drawchars (ushort x, ushort y, uchar *str, int count); @@ -339,8 +340,6 @@ static void test_pattern (void) int drv_lcd_init (void) { - DECLARE_GLOBAL_DATA_PTR; - device_t lcddev; int rc; @@ -682,8 +681,6 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) static void *lcd_logo (void) { #ifdef CONFIG_LCD_INFO - DECLARE_GLOBAL_DATA_PTR; - char info[80]; char temp[32]; #endif /* CONFIG_LCD_INFO */ diff --git a/common/lynxkdi.c b/common/lynxkdi.c index ed1b595..76a271b 100644 --- a/common/lynxkdi.c +++ b/common/lynxkdi.c @@ -20,13 +20,14 @@ #if defined(CONFIG_LYNXKDI) #include <lynxkdi.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR) void lynxkdi_boot ( image_header_t *hdr ) { void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep); lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020; bd_t *kbd; - DECLARE_GLOBAL_DATA_PTR; u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204); memset( parms, 0, sizeof(*parms)); diff --git a/common/main.c b/common/main.c index 445cb18..758ef8d 100644 --- a/common/main.c +++ b/common/main.c @@ -36,6 +36,10 @@ #include <post.h> +#ifdef CONFIG_SILENT_CONSOLE +DECLARE_GLOBAL_DATA_PTR; +#endif + #if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY) extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* for do_reset() prototype */ #endif @@ -105,14 +109,10 @@ static __inline__ int abortboot(int bootdelay) u_int i; #ifdef CONFIG_SILENT_CONSOLE - { - DECLARE_GLOBAL_DATA_PTR; - - if (gd->flags & GD_FLG_SILENT) { - /* Restore serial console */ - console_assign (stdout, "serial"); - console_assign (stderr, "serial"); - } + if (gd->flags & GD_FLG_SILENT) { + /* Restore serial console */ + console_assign (stdout, "serial"); + console_assign (stderr, "serial"); } #endif @@ -195,17 +195,13 @@ static __inline__ int abortboot(int bootdelay) # endif #ifdef CONFIG_SILENT_CONSOLE - { - DECLARE_GLOBAL_DATA_PTR; - - if (abort) { - /* permanently enable normal console output */ - gd->flags &= ~(GD_FLG_SILENT); - } else if (gd->flags & GD_FLG_SILENT) { - /* Restore silent console */ - console_assign (stdout, "nulldev"); - console_assign (stderr, "nulldev"); - } + if (abort) { + /* permanently enable normal console output */ + gd->flags &= ~(GD_FLG_SILENT); + } else if (gd->flags & GD_FLG_SILENT) { + /* Restore silent console */ + console_assign (stdout, "nulldev"); + console_assign (stderr, "nulldev"); } #endif @@ -223,14 +219,10 @@ static __inline__ int abortboot(int bootdelay) int abort = 0; #ifdef CONFIG_SILENT_CONSOLE - { - DECLARE_GLOBAL_DATA_PTR; - - if (gd->flags & GD_FLG_SILENT) { - /* Restore serial console */ - console_assign (stdout, "serial"); - console_assign (stderr, "serial"); - } + if (gd->flags & GD_FLG_SILENT) { + /* Restore serial console */ + console_assign (stdout, "serial"); + console_assign (stderr, "serial"); } #endif @@ -279,17 +271,13 @@ static __inline__ int abortboot(int bootdelay) putc ('\n'); #ifdef CONFIG_SILENT_CONSOLE - { - DECLARE_GLOBAL_DATA_PTR; - - if (abort) { - /* permanently enable normal console output */ - gd->flags &= ~(GD_FLG_SILENT); - } else if (gd->flags & GD_FLG_SILENT) { - /* Restore silent console */ - console_assign (stdout, "nulldev"); - console_assign (stderr, "nulldev"); - } + if (abort) { + /* permanently enable normal console output */ + gd->flags &= ~(GD_FLG_SILENT); + } else if (gd->flags & GD_FLG_SILENT) { + /* Restore silent console */ + console_assign (stdout, "nulldev"); + console_assign (stderr, "nulldev"); } #endif diff --git a/common/serial.c b/common/serial.c index 22d8fd0..2acbd08 100644 --- a/common/serial.c +++ b/common/serial.c @@ -25,6 +25,8 @@ #include <serial.h> #include <devices.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_SERIAL_MULTI) static struct serial_device *serial_devices = NULL; @@ -49,8 +51,6 @@ struct serial_device *default_serial_console (void) static int serial_register (struct serial_device *dev) { - DECLARE_GLOBAL_DATA_PTR; - dev->init += gd->reloc_off; dev->setbrg += gd->reloc_off; dev->getc += gd->reloc_off; @@ -131,8 +131,6 @@ void serial_reinit_all (void) int serial_init (void) { - DECLARE_GLOBAL_DATA_PTR; - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { struct serial_device *dev = default_serial_console (); @@ -144,8 +142,6 @@ int serial_init (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { struct serial_device *dev = default_serial_console (); @@ -158,8 +154,6 @@ void serial_setbrg (void) int serial_getc (void) { - DECLARE_GLOBAL_DATA_PTR; - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { struct serial_device *dev = default_serial_console (); @@ -171,8 +165,6 @@ int serial_getc (void) int serial_tstc (void) { - DECLARE_GLOBAL_DATA_PTR; - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { struct serial_device *dev = default_serial_console (); @@ -184,8 +176,6 @@ int serial_tstc (void) void serial_putc (const char c) { - DECLARE_GLOBAL_DATA_PTR; - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { struct serial_device *dev = default_serial_console (); @@ -198,8 +188,6 @@ void serial_putc (const char c) void serial_puts (const char *s) { - DECLARE_GLOBAL_DATA_PTR; - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { struct serial_device *dev = default_serial_console (); diff --git a/common/soft_i2c.c b/common/soft_i2c.c index b3642da..bffcd44 100644 --- a/common/soft_i2c.c +++ b/common/soft_i2c.c @@ -39,6 +39,10 @@ /* #define DEBUG_I2C */ +#ifdef DEBUG_I2C +DECLARE_GLOBAL_DATA_PTR; +#endif + /*----------------------------------------------------------------------- * Definitions @@ -53,7 +57,6 @@ #ifdef DEBUG_I2C #define PRINTD(fmt,args...) do { \ - DECLARE_GLOBAL_DATA_PTR; \ if (gd->have_console) \ printf (fmt ,##args); \ } while (0) diff --git a/common/xyzModem.c b/common/xyzModem.c new file mode 100644 index 0000000..3c86b13 --- /dev/null +++ b/common/xyzModem.c @@ -0,0 +1,739 @@ +//========================================================================== +// +// xyzModem.c +// +// RedBoot stream handler for xyzModem protocol +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 2002 Gary Thomas +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas, tsmith, Yoshinori Sato +// Date: 2000-07-14 +// Purpose: +// Description: +// +// This code is part of RedBoot (tm). +// +//####DESCRIPTIONEND#### +// +//========================================================================== +#include <common.h> +#include <xyzModem.h> +#include <stdarg.h> +#include <crc.h> + +// Assumption - run xyzModem protocol over the console port + +// Values magic to the protocol +#define SOH 0x01 +#define STX 0x02 +#define EOT 0x04 +#define ACK 0x06 +#define BSP 0x08 +#define NAK 0x15 +#define CAN 0x18 +#define EOF 0x1A // ^Z for DOS officionados + +#define USE_YMODEM_LENGTH + +// Data & state local to the protocol +static struct { +#ifdef REDBOOT + hal_virtual_comm_table_t* __chan; +#else + int *__chan; +#endif + 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; +#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 + + +#ifndef REDBOOT //SB +typedef int cyg_int32; +int CYGACC_COMM_IF_GETC_TIMEOUT (char chan,char *c) { +#define DELAY 20 + unsigned long counter=0; + while (!tstc() && (counter < xyzModem_CHAR_TIMEOUT*1000/DELAY)) { + udelay(DELAY); + counter++; + } + if (tstc()) { + *c=getc(); + return 1; + } + return 0; +} + +void CYGACC_COMM_IF_PUTC(char x,char y) { + putc(y); +} + +// Validate a hex character +__inline__ static bool +_is_hex(char c) +{ + return (((c >= '0') && (c <= '9')) || + ((c >= 'A') && (c <= 'F')) || + ((c >= 'a') && (c <= 'f'))); +} + +// Convert a single hex nibble +__inline__ static int +_from_hex(char c) +{ + int ret = 0; + + if ((c >= '0') && (c <= '9')) { + ret = (c - '0'); + } else if ((c >= 'a') && (c <= 'f')) { + ret = (c - 'a' + 0x0a); + } else if ((c >= 'A') && (c <= 'F')) { + ret = (c - 'A' + 0x0A); + } + return ret; +} + +// Convert a character to lower case +__inline__ static char +_tolower(char c) +{ + if ((c >= 'A') && (c <= 'Z')) { + c = (c - 'A') + 'a'; + } + return c; +} + + + +// +// Parse (scan) a number +// +bool +parse_num(char *s, unsigned long *val, char **es, char *delim) +{ + bool first = true; + int radix = 10; + char c; + unsigned long result = 0; + int digit; + + while (*s == ' ') s++; + while (*s) { + if (first && (s[0] == '0') && (_tolower(s[1]) == 'x')) { + radix = 16; + s += 2; + } + first = false; + c = *s++; + if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) { + // Valid digit +#ifdef CYGPKG_HAL_MIPS + // FIXME: tx49 compiler generates 0x2539018 for MUL which + // isn't any good. + if (16 == radix) + result = result << 4; + else + result = 10 * result; + result += digit; +#else + result = (result * radix) + digit; +#endif + } else { + if (delim != (char *)0) { + // See if this character is one of the delimiters + char *dp = delim; + while (*dp && (c != *dp)) dp++; + if (*dp) break; // Found a good delimiter + } + return false; // Malformatted number + } + } + *val = result; + if (es != (char **)0) { + *es = s; + } + return true; +} + +#endif + +#define USE_SPRINTF +#ifdef DEBUG +#ifndef USE_SPRINTF +// +// Note: this debug setup only works if the target platform has two serial ports +// available so that the other one (currently only port 1) can be used for debug +// messages. +// +static int +zm_dprintf(char *fmt, ...) +{ + int cur_console; + va_list args; + + va_start(args, fmt); +#ifdef REDBOOT + cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + CYGACC_CALL_IF_SET_CONSOLE_COMM(1); +#endif + diag_vprintf(fmt, args); +#ifdef REDBOOT + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console); +#endif +} + +static void +zm_flush(void) +{ +} + +#else +// +// Note: this debug setup works by storing the strings in a fixed buffer +// +#define FINAL +#ifdef FINAL +static char *zm_out = (char *)0x00380000; +static char *zm_out_start = (char *)0x00380000; +#else +static char zm_buf[8192]; +static char *zm_out=zm_buf; +static char *zm_out_start = zm_buf; + +#endif +static int +zm_dprintf(char *fmt, ...) +{ + int len; + va_list args; + + 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; +#ifdef REDBOOT + while (*p) mon_write_char(*p++); +#endif + zm_out = zm_out_start; +} +#endif + +static void +zm_dump_buf(void *buf, int len) +{ +#ifdef REDBOOT + diag_vdump_buf_with_offset(zm_dprintf, buf, len, 0); +#else + +#endif +} + +static unsigned char zm_buf[2048]; +static unsigned char *zm_bp; + +static void +zm_new(void) +{ + zm_bp = zm_buf; +} + +static void +zm_save(unsigned char 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); +} + +#define ZM_DEBUG(x) x +#else +#define ZM_DEBUG(x) +#endif + +// Wait for the line to go idle +static void +xyzModem_flush(void) +{ + 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; +} + +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; + +// ZM_DEBUG(zm_out = zm_out_start); +#ifdef xyzModem_zmodem + if (info->mode == xyzModem_zmodem) { + *err = xyzModem_noZmodem; + return -1; + } +#endif + +#ifdef REDBOOT + // 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); +#else +// TODO: CHECK ! + int dummy; + xyz.__chan=&dummy; +#endif + 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; +#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) { +#ifdef USE_YMODEM_LENGTH + // skip filename + while (*xyz.bufp++); + // get the length + parse_num(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; +} + +int +xyzModem_stream_read(char *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; + +#if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH) + if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0) { +#else + 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--; + } + } + } + +#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); + } + } +#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 += 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); + ZM_DEBUG(zm_flush()); +} + +// Need to be able to clean out the input buffer, so have to take the +// 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; +#ifdef xyzModem_zmodem + case xyzModem_zmodem: + // Might support it some day I suppose. +#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); + } +} + +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; + } +} + +// +// RedBoot interface +// +#if 0 // SB +GETC_IO_FUNCS(xyzModem_io, xyzModem_stream_open, xyzModem_stream_close, + 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); +#endif |