1 //==========================================================================
5 // Standard interfaces for RedBoot
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
12 // Copyright (C) 2002, 2003, 2004, 2005 Gary Thomas
13 // Copyright (C) 2004, 2005 eCosCentric Limited
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //==========================================================================
43 //#####DESCRIPTIONBEGIN####
46 // Contributors: gthomas, tkoeller
51 // This code is part of RedBoot (tm).
53 //####DESCRIPTIONEND####
55 //==========================================================================
60 #include <pkgconf/redboot.h>
61 #include <pkgconf/hal.h>
62 #include <cyg/hal/hal_if.h>
63 #include <cyg/hal/hal_tables.h>
64 #include <cyg/hal/hal_endian.h>
65 #include <cyg/infra/diag.h>
66 #include <cyg/crc/crc.h>
69 #ifdef CYGPKG_REDBOOT_NETWORKING
71 #include <net/bootp.h>
72 // Determine an IP address for this node, using BOOTP
73 extern int __bootp_find_local_ip(bootp_header_t *info);
85 EXTERN char *argv[MAX_ARGV];
86 EXTERN unsigned char *ram_start, *ram_end;
87 EXTERN struct _mem_segment {
88 unsigned char *start, *end;
89 } mem_segments[CYGBLD_REDBOOT_MAX_MEM_SEGMENTS];
90 #define NO_MEMORY (unsigned char *)0xFFFFFFFF
91 EXTERN bool valid_address(unsigned char *addr);
92 EXTERN void cyg_plf_memory_segment(int seg, unsigned char **start, unsigned char **end);
93 EXTERN unsigned char *workspace_start, *workspace_end, *workspace_end_init;
95 // Data squirreled away after a load operation
96 EXTERN unsigned long entry_address;
97 EXTERN unsigned long load_address;
98 EXTERN unsigned long load_address_end;
101 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
102 EXTERN bool console_selected;
104 EXTERN bool console_echo;
105 EXTERN bool gdb_active;
106 #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
107 EXTERN bool cmd_history;
110 #ifdef CYGPKG_REDBOOT_NETWORKING
111 EXTERN bool have_net, use_bootp;
112 EXTERN bootp_header_t my_bootp_info;
114 EXTERN bool net_debug;
117 #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
119 EXTERN int script_timeout;
120 #ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
121 EXTERN int console_baud_rate;
125 #ifdef CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER
126 EXTERN unsigned char *fis_zlib_common_buffer;
129 #ifdef CYGSEM_REDBOOT_PLF_STARTUP
130 EXTERN void cyg_plf_redboot_startup(void);
134 typedef int _printf_fun(const char *fmt, ...);
135 externC int strcasecmp(const char *s1, const char *s2);
136 externC int strncasecmp(const char *s1, const char *s2, size_t len);
138 externC void mon_write_char(char c);
139 externC bool mon_read_char_with_timeout(char *c);
140 externC void mon_set_read_char_timeout(int ms);
141 externC bool verify_action(char *fmt, ...);
142 externC bool verify_action_with_timeout(int timeout, char *fmt, ...);
144 // Read a single line of input from the console, possibly with timeout
145 externC int _rb_gets(char *line, int len, int timeout);
146 // Just like _rb_gets(), except that the line buffer is assumed to contain
147 // valid input data. This provides an easy mechanism for edit-in-place.
148 externC int _rb_gets_preloaded(char *line, int len, int timeout);
149 // Result codes from 'gets()'
150 #define _GETS_TIMEOUT -1
151 #define _GETS_CTRLC -2
154 // Test for ^C on the console. This function should only be used if any
155 // other console input can be discarded, e.g. while performing some long
156 // computation, waiting for the network, etc. Returns 'true' if ^C typed.
157 externC bool _rb_break(int timeout);
159 // "console" selection
160 externC int start_console(void);
161 externC void end_console(int old_console);
164 #ifdef CYGSEM_REDBOOT_FLASH_ALIASES
165 externC char *flash_lookup_alias(char *alias, char *alias_buf);
167 externC void expand_aliases(char *line, int len);
170 // Stream I/O support
177 #ifdef CYGPKG_REDBOOT_NETWORKING
178 struct sockaddr_in *server;
183 int (*open)(connection_info_t *info, int *err);
184 void (*close)(int *err);
185 void (*terminate)(bool abort, int (*getc)(void));
186 int (*read)(void *buf, int size, int *err);
187 char *(*error)(int err);
190 #define GETC_IO_FUNCS(_label_, _open_, _close_, _terminate_, _read_, _error_) \
191 getc_io_funcs_t _label_ = { \
192 _open_, _close_, _terminate_, _read_, _error_ \
195 struct load_io_entry {
197 getc_io_funcs_t *funcs;
201 } CYG_HAL_TABLE_TYPE;
202 #define _RedBoot_load(_name_,_funcs_,_verbose_,_filename_,_mode_) \
203 struct load_io_entry _load_tab_##_funcs_##_name_ \
204 CYG_HAL_TABLE_QUALIFIED_ENTRY(RedBoot_load,_funcs_##_name) = \
205 { #_name_, &_funcs_, _verbose_, _filename_, _mode_ };
206 #define RedBoot_load(_name_,_funcs_,_verbose_,_filename_, _mode_) \
207 _RedBoot_load(_name_,_funcs_,_verbose_,_filename_,_mode_)
209 #ifdef CYGPKG_COMPRESS_ZLIB
210 // Decompression support
211 typedef struct _pipe {
212 unsigned char* in_buf; // only changed by producer
213 int in_avail; // only changed by producer
214 unsigned char* out_buf; // only changed by consumer (init by producer)
215 int out_size; // only changed by consumer (init by producer)
216 int out_max; // set by producer
217 const char* msg; // message from consumer
218 void* priv; // handler's data
221 typedef int _decompress_fun_init(_pipe_t*);
222 typedef int _decompress_fun_inflate(_pipe_t*);
223 typedef int _decompress_fun_close(_pipe_t*, int);
225 externC _decompress_fun_init* _dc_init;
226 externC _decompress_fun_inflate* _dc_inflate;
227 externC _decompress_fun_close* _dc_close;
228 #endif // CYGPKG_COMPRESS_ZLIB
230 // CLI support functions
231 externC bool parse_num(char *s, unsigned long *val, char **es, char *delim);
232 externC bool parse_bool(char *s, bool *val);
234 typedef void cmd_fun(int argc, char *argv[]);
240 struct cmd *sub_cmds, *sub_cmds_end;
241 } CYG_HAL_TABLE_TYPE;
242 externC struct cmd *cmd_search(struct cmd *tab, struct cmd *tabend, char *arg);
243 externC void cmd_usage(struct cmd *tab, struct cmd *tabend, char *prefix);
244 #define RedBoot_cmd(_s_,_h_,_u_,_f_) cmd_entry(_s_,_h_,_u_,_f_,0,0,RedBoot_commands)
245 #define RedBoot_nested_cmd(_s_,_h_,_u_,_f_,_subs_,_sube_) cmd_entry(_s_,_h_,_u_,_f_,_subs_,_sube_,RedBoot_commands)
246 #define _cmd_entry(_s_,_h_,_u_,_f_,_subs_,_sube_,_n_) \
248 struct cmd _cmd_tab_##_f_ CYG_HAL_TABLE_QUALIFIED_ENTRY(_n_,_f_) = {_s_, _h_, _u_, _f_, _subs_, _sube_};
249 #define cmd_entry(_s_,_h_,_u_,_f_,_subs_,_sube_,_n_) \
250 extern _cmd_entry(_s_,_h_,_u_,_f_,_subs_,_sube_,_n_)
251 #define local_cmd_entry(_s_,_h_,_u_,_f_,_n_) \
252 static _cmd_entry(_s_,_h_,_u_,_f_,0,0,_n_)
254 // Initialization functions
255 #define RedBoot_INIT_FIRST 0000
256 #define RedBoot_INIT_SECOND 0100
257 // Specify a 3 digit numeric value for proper prioritizing
258 #define RedBoot_INIT_PRIO(_n_) 1##_n_
259 #define RedBoot_INIT_BEFORE_NET 6900
260 #define RedBoot_INIT_NET 7000
261 #define RedBoot_INIT_AFTER_NET 7100
262 #define RedBoot_INIT_LAST 9999
263 typedef void void_fun(void);
264 typedef void_fun *void_fun_ptr;
265 struct init_tab_entry {
267 } CYG_HAL_TABLE_TYPE;
268 #define _RedBoot_init(_f_,_p_) \
269 struct init_tab_entry _init_tab_##_p_##_f_ \
270 CYG_HAL_TABLE_QUALIFIED_ENTRY(RedBoot_inits,_p_##_f_) = { _f_ };
271 #define RedBoot_init(_f_,_p_) _RedBoot_init(_f_,_p_)
273 // Main loop [idle] call-back functions
274 #define RedBoot_IDLE_FIRST 0000
275 #define RedBoot_IDLE_BEFORE_NETIO 3000
276 #define RedBoot_IDLE_NETIO 5000
277 #define RedBoot_IDLE_AFTER_NETIO 7000
278 #define RedBoot_IDLE_LAST 9999
279 typedef void idle_fun(bool);
280 typedef idle_fun *idle_fun_ptr;
281 struct idle_tab_entry {
283 } CYG_HAL_TABLE_TYPE;
284 #define _RedBoot_idle(_f_,_p_) \
285 struct idle_tab_entry _idle_tab_##_p_##_f_ \
286 CYG_HAL_TABLE_QUALIFIED_ENTRY(RedBoot_idle,_p_##_f_) = { _f_ };
287 #define RedBoot_idle(_f_,_p_) _RedBoot_idle(_f_,_p_)
289 // This function called when changing idle/not - mostly used by I/O
290 // to support idle when timeout, etc.
291 void do_idle(bool state);
293 // Option processing support
304 #define NUM_ELEMS(s) (sizeof(s)/sizeof(s[0]))
306 #define OPTION_ARG_TYPE_NUM 0 // Numeric data
307 #define OPTION_ARG_TYPE_STR 1 // Generic string
308 #define OPTION_ARG_TYPE_FLG 2 // Flag only
310 // Command line parsing
311 externC struct cmd *parse(char **line, int *argc, char **argv);
313 externC void init_opts(struct option_info *opts, char flag, bool takes_arg,
314 int arg_type, void *arg, bool *arg_set, char *name);
315 externC bool scan_opts(int argc, char *argv[], int first,
316 struct option_info *opts, int num_opts,
317 void *def_arg, int def_arg_type, char *def_descr);
319 externC int redboot_exec(char *command, ... );
321 externC void err_printf(const char *fmt, ... );
323 #ifdef CYGNUM_HAL_VIRTUAL_VECTOR_AUX_CHANNELS
324 #define CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS \
325 (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS+CYGNUM_HAL_VIRTUAL_VECTOR_AUX_CHANNELS)
327 #define CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS \
328 CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
331 #ifdef CYGPKG_REDBOOT_NETWORKING
332 //-----------------------------------------------------------------------------
334 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
336 // I would really like if we could just pull in cyg/ns/dns/dns.h, but
337 // that would require adding dummy <network.h> and <netinet/in.h> files.
339 // Host name / IP mapping
341 char *h_name; /* official name of host */
342 char **h_aliases; /* alias list */
343 int h_addrtype; /* host address type */
344 int h_length; /* length of address */
345 char **h_addr_list; /* list of addresses */
347 #define h_addr h_addr_list[0] /* for backward compatibility */
349 externC int redboot_dns_res_init(void);
350 externC void set_dns(char* new_ip);
351 externC void show_dns(void);
352 externC struct hostent *gethostbyname(const char *host);
353 externC int setdomainname(const char *, size_t);
358 #define DNS_SUCCESS 0
359 #define HOST_NOT_FOUND 1
361 #define NO_RECOVERY 3
365 _gethostbyname(const char* name, in_addr_t* host)
367 struct hostent* hent = gethostbyname(name);
369 memcpy(host, hent->h_addr_list[0], sizeof(in_addr_t));
372 // Fall back to inet_aton - gethostbyname may already have tried
373 // it, but we can't know for sure (the DNS IP may not have been
374 // valid, preventing the inet_aton).
375 return inet_aton(name, host);
379 _gethostbyname(const char* name, in_addr_t* host)
381 return inet_aton(name, host);
383 #endif // CYGPKG_REDBOOT_NETWORKING_DNS
384 #endif // CYGPKG_REDBOOT_NETWORKING
386 //-----------------------------------------------------------------------------
387 // String functions. Some of these are duplicates of the same functions in
390 // Validate a hex character
391 __inline__ static bool
394 return (((c >= '0') && (c <= '9')) ||
395 ((c >= 'A') && (c <= 'F')) ||
396 ((c >= 'a') && (c <= 'f')));
399 // Convert a single hex nibble
400 __inline__ static int
405 if ((c >= '0') && (c <= '9')) {
407 } else if ((c >= 'a') && (c <= 'f')) {
408 ret = (c - 'a' + 0x0a);
409 } else if ((c >= 'A') && (c <= 'F')) {
410 ret = (c - 'A' + 0x0A);
415 // Convert a character to lower case
416 __inline__ static char
419 if ((c >= 'A') && (c <= 'Z')) {
426 __inline__ static bool
429 return (((c >= 'a') && (c <= 'z')) ||
430 ((c >= 'A') && (c <= 'Z')));
434 __inline__ static bool
437 return ((c >= '0') && (c <= '9'));
441 __inline__ static bool
444 return (isalpha(c) || isdigit(c));
447 //----------------------------------------------------------------------------
449 #if defined(CYGSEM_REDBOOT_BSP_SYSCALLS)
451 // These are required by the ANSI C part of newlib (excluding system() of
463 //#define SYS_sbrk 11 - not currently a system call, but reserved.
466 #define SYS_argvlen 12
469 // These are extras added for one reason or another.
475 #define SYS_gettimeofday 19
478 #define SYS_interrupt 1000
479 #define SYS_meminfo 1001
481 #define __GET_SHARED 0xbaad // 47789 decimal
483 #ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
485 #define SYS_timer_call_back 2001
486 #define SYS_timer_frequency 2002
487 #define SYS_timer_reset 2003
489 #endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
490 #define SYS_rename 3001
491 #define SYS_isatty 3002
492 #define SYS_system 3003
494 #endif // CYGSEM_REDBOOT_BSP_SYSCALLS
497 //----------------------------------------------------------------------------
498 // Allow HAL to override RedBoot flash read/program operations.
499 #ifdef HAL_FLASH_READ
500 #define FLASH_READ(f, r, l, e) HAL_FLASH_READ((f),(r),(l),(e))
502 #define FLASH_READ(f, r, l, e) flash_read((f), (r), (l), (e))
505 #ifdef HAL_FLASH_PROGRAM
506 #define FLASH_PROGRAM(f, r, l, e) HAL_FLASH_PROGRAM((f),(r),(l),(e))
508 #define FLASH_PROGRAM(f, r, l, e) flash_program((f), (r), (l), (e))
512 // Define REDBOOT_FLASH_REVERSE_BYTEORDER if config and fis info is stored in flash
513 // with byte ordering opposite from CYG_BYTEORDER.
514 #if (defined(CYGOPT_REDBOOT_FLASH_BYTEORDER_MSBFIRST) && (CYG_BYTEORDER != CYG_MSBFIRST)) || \
515 (defined(CYGOPT_REDBOOT_FLASH_BYTEORDER_LSBFIRST) && (CYG_BYTEORDER != CYG_LSBFIRST))
516 #define REDBOOT_FLASH_REVERSE_BYTEORDER
519 #endif // _REDBOOT_H_