1 //==========================================================================
5 // RedBoot main routine
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
12 // Copyright (C) 2002, 2003, 2004 Gary Thomas
13 // Copyright (C) 2003, 2004, 2005, 2006 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.
37 // -------------------------------------------
38 //####ECOSGPLCOPYRIGHTEND####
39 //==========================================================================
40 //#####DESCRIPTIONBEGIN####
43 // Contributors: gthomas, tkoeller, eCosCentric
48 // This code is part of RedBoot (tm).
50 //####DESCRIPTIONEND####
52 //==========================================================================
57 #include <cyg/hal/hal_arch.h>
58 #include <cyg/hal/hal_intr.h>
59 #include <cyg/hal/hal_if.h>
60 #include <cyg/hal/hal_cache.h>
61 #include CYGHWR_MEMORY_LAYOUT_H
63 #ifdef CYGPKG_IO_ETH_DRIVERS
64 #include <cyg/io/eth/eth_drv.h> // Logical driver interfaces
67 #include <cyg/hal/hal_tables.h>
68 #include <cyg/infra/cyg_ass.h> // assertion macros
69 #include <cyg/infra/cyg_type.h>
70 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
71 #ifdef CYGBLD_HAL_PLATFORM_STUB_H
72 #include CYGBLD_HAL_PLATFORM_STUB_H
74 #include <cyg/hal/plf_stub.h>
77 extern void breakpoint(void);
80 // Builtin Self Test (BIST)
81 externC void bist(void);
83 // Path to code run from a go command or to GDB stubs
84 static void trampoline(unsigned long entry);
86 // Return path for code run from a go command or for GDB stubs
87 static void return_to_redboot(int status);
89 // Address of area where current context is saved before executing
90 // trampoline procedure
91 static void *saved_context;
93 // Status returned after trampoline execution
94 static int return_status;
97 // CLI command processing (defined in this file)
98 RedBoot_cmd("version",
99 "Display RedBoot version information",
109 static char go_usage[] = "[-w <timeout>] [-c] "
110 #ifdef CYGPKG_IO_ETH_DRIVERS
116 "Execute code at a location",
120 #ifdef HAL_PLATFORM_RESET
127 #ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
128 RedBoot_cmd("baudrate",
129 "Set/Query the system console baud rate",
135 // Define table boundaries
136 CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
137 CYG_HAL_TABLE_END( __RedBoot_INIT_TAB_END__, RedBoot_inits );
138 extern struct init_tab_entry __RedBoot_INIT_TAB__[], __RedBoot_INIT_TAB_END__;
140 CYG_HAL_TABLE_BEGIN( __RedBoot_CMD_TAB__, RedBoot_commands );
141 CYG_HAL_TABLE_END( __RedBoot_CMD_TAB_END__, RedBoot_commands );
142 extern struct cmd __RedBoot_CMD_TAB__[], __RedBoot_CMD_TAB_END__;
144 CYG_HAL_TABLE_BEGIN( __RedBoot_IDLE_TAB__, RedBoot_idle );
145 CYG_HAL_TABLE_END( __RedBoot_IDLE_TAB_END__, RedBoot_idle );
146 extern struct idle_tab_entry __RedBoot_IDLE_TAB__[], __RedBoot_IDLE_TAB_END__;
148 #ifdef HAL_ARCH_PROGRAM_NEW_STACK
149 extern void HAL_ARCH_PROGRAM_NEW_STACK(void *fun);
153 // [Null] Builtin [Power On] Self Test
155 void bist(void) CYGBLD_ATTRIB_WEAK;
166 do_version(int argc, char *argv[])
168 #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
171 #ifdef CYGPKG_REDBOOT_FLASH
172 externC void _flash_info(void);
174 char *version = CYGACC_CALL_IF_MONITOR_VERSION();
176 diag_printf(version);
177 #ifdef HAL_PLATFORM_CPU
178 diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
180 diag_printf("Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.\n");
181 diag_printf("Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited\n\n");
182 diag_printf("RAM: %p-%p, ", (void*)ram_start, (void*)ram_end);
183 diag_printf("[%p-%p]", mem_segments[0].start, mem_segments[0].end);
184 diag_printf(" available\n");
185 #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
186 for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) {
187 if (mem_segments[seg].start != NO_MEMORY) {
188 diag_printf(" %p-%p, ", mem_segments[seg].start, mem_segments[seg].end);
189 diag_printf("[%p-%p]", mem_segments[seg].start, mem_segments[seg].end);
190 diag_printf(" available\n");
194 #ifdef CYGPKG_REDBOOT_FLASH
200 // This function is called when RedBoot is idle (waiting for user
201 // input). It will call any registered "idle" routines, e.g. scan
202 // for incoming network connections, blank an LCD screen, etc.
205 do_idle(bool is_idle)
207 struct idle_tab_entry *idle_entry;
209 for (idle_entry = __RedBoot_IDLE_TAB__;
210 idle_entry != &__RedBoot_IDLE_TAB_END__; idle_entry++) {
211 (*idle_entry->fun)(is_idle);
215 // Wrapper used by diag_printf()
217 _mon_write_char(char c, void *param)
220 mon_write_char('\r');
226 // Handle illegal memory accesses (and other abort conditions)
228 static hal_jmp_buf error_jmpbuf;
229 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
230 __externC void *volatile __mem_fault_handler;
232 static void error_handler(void)
234 hal_longjmp(error_jmpbuf, 1);
240 // This is the main entry point for RedBoot
248 static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
252 struct init_tab_entry *init_entry;
253 extern char RedBoot_version[];
254 #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
258 // Export version information
259 CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
261 CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
263 // Make sure the channels are properly initialized.
264 diag_init_putc(_mon_write_char);
267 // Force console to output raw text - but remember the old setting
268 // so it can be restored if interaction with a debugger is
270 cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
271 CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
272 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
273 console_selected = false;
277 ram_start = (unsigned char *)CYGMEM_REGION_ram;
278 ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
279 #ifdef HAL_MEM_REAL_REGION_TOP
281 unsigned char *ram_end_tmp = ram_end;
282 ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp );
285 #ifdef CYGMEM_SECTION_heap1
286 workspace_start = (unsigned char *)CYGMEM_SECTION_heap1;
287 workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE);
289 workspace_start = (unsigned char *)CYGMEM_REGION_ram;
290 workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
293 if (ram_end < workspace_end) {
294 // when *less* SDRAM is installed than the possible maximum,
295 // but the heap1 region remains greater...
296 workspace_end = ram_end;
299 workspace_end_init = workspace_end;
301 // Nothing has ever been loaded into memory
302 entry_address = (unsigned long)NO_MEMORY;
306 #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER)
307 fis_zlib_common_buffer =
308 workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE;
311 #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
312 script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
315 for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) {
316 (*init_entry->fun)();
319 mem_segments[0].start = workspace_start;
320 mem_segments[0].end = workspace_end;
321 #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
322 for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) {
323 cyg_plf_memory_segment(seg, &mem_segments[seg].start, &mem_segments[seg].end);
327 #ifdef CYGSEM_REDBOOT_PLF_STARTUP
329 cyg_plf_redboot_startup();
333 #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
334 # ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
336 script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
340 // Give the guy a chance to abort any boot script
341 unsigned char *hold_script = script;
342 int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION;
343 diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
344 script_timeout_ms / 1000, script_timeout_ms % 1000);
346 res = _GETS_CTRLC; // Treat 0 timeout as ^C
347 while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
348 res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
349 if (res >= _GETS_OK) {
350 diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
351 script_timeout_ms / 1000, script_timeout_ms % 1000);
352 } else if (res != _GETS_TIMEOUT) {
355 script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
357 if (res == _GETS_CTRLC) {
358 script = NULL; // Disable script
360 script = hold_script; // Re-enable script
364 CYG_ASSERT(workspace_start < workspace_end,
365 "negative workspace size");
368 diag_printf("RedBoot> ");
371 #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
372 cmd_history = true; // Enable history collection
374 res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
375 #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
376 cmd_history = false; // Enable history collection
378 if (res == _GETS_TIMEOUT) {
381 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
382 if (res == _GETS_GDB) {
384 hal_virtual_comm_table_t *__chan;
386 // Special case of '$' - need to start GDB protocol
388 // Mask interrupts on all channels
389 for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) {
390 CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
391 __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
392 CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
395 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
397 // set up a temporary context that will take us to the trampoline
398 HAL_THREAD_INIT_CONTEXT(workspace_end,
399 breakpoint, trampoline,0);
401 // switch context to trampoline (get GDB stubs started)
402 HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
406 dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
407 CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
409 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
411 expand_aliases(line, sizeof(line));
413 if ((*command == '#') || (*command == '=')) {
415 if (*command == '=') {
416 // Print line on console
417 diag_printf("%s\n", &line[2]);
420 while (strlen(command) > 0) {
421 if ((cmd = parse(&command, &argc, &argv[0])) != NULL) {
422 // Try to handle aborts - messy because of the stack unwinding...
423 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
424 __mem_fault_handler = error_handler;
426 if (hal_setjmp(error_jmpbuf)) {
427 diag_printf("** command abort - illegal memory access?\n");
429 (cmd->fun)(argc, argv);
431 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
432 __mem_fault_handler = 0;
435 diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
446 show_help(struct cmd *cmd, struct cmd *cmd_end, char *which, char *pre)
454 while (cmd != cmd_end) {
456 if (which && (strncasecmp(which, cmd->str, len) != 0)) {
460 diag_printf("%s\n %s %s %s\n", cmd->help, pre, cmd->str, cmd->usage);
461 if ((cmd->sub_cmds != NULL) && (which != NULL)) {
462 show_help(cmd->sub_cmds, cmd->sub_cmds_end, 0, cmd->str);
470 do_help(int argc, char *argv[])
475 if (!scan_opts(argc, argv, 1, NULL, 0, &which, OPTION_ARG_TYPE_STR, "<topic>")) {
476 diag_printf("Invalid argument\n");
479 cmd = __RedBoot_CMD_TAB__;
480 show_help(cmd, &__RedBoot_CMD_TAB_END__, which, "");
485 trampoline(unsigned long entry)
487 typedef void code_fun(void);
488 code_fun *fun = (code_fun *)entry;
489 unsigned long oldints;
491 HAL_DISABLE_INTERRUPTS(oldints);
493 #ifdef HAL_ARCH_PROGRAM_NEW_STACK
494 HAL_ARCH_PROGRAM_NEW_STACK(fun);
499 HAL_THREAD_LOAD_CONTEXT(&saved_context);
503 return_to_redboot(int status)
505 CYGARC_HAL_SAVE_GP();
507 return_status = status;
508 HAL_THREAD_LOAD_CONTEXT(&saved_context);
511 // need this to balance above CYGARC_HAL_SAVE_GP on
512 // some platforms. It will never run, though.
513 CYGARC_HAL_RESTORE_GP();
517 do_go(int argc, char *argv[])
519 int i, cur, num_options = 0;
521 unsigned long oldints;
524 bool cache_enabled = false;
525 #ifdef CYGPKG_IO_ETH_DRIVERS
526 bool stop_net = false;
528 struct option_info opts[3];
530 hal_virtual_comm_table_t *__chan;
532 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
533 __mem_fault_handler = 0; // Let GDB handle any faults directly
535 entry = entry_address; // Default from last 'load' operation
536 init_opts(&opts[num_options++], 'w', true, OPTION_ARG_TYPE_NUM,
537 &wait_time, &wait_time_set, "wait timeout");
538 init_opts(&opts[num_options++], 'c', false, OPTION_ARG_TYPE_FLG,
539 &cache_enabled, NULL, "go with caches enabled");
540 #ifdef CYGPKG_IO_ETH_DRIVERS
541 init_opts(&opts[num_options++], 'n', false, OPTION_ARG_TYPE_FLG,
542 &stop_net, NULL, "go with network driver stopped");
545 CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options");
547 if (!scan_opts(argc, argv, 1, opts, num_options, &entry,
548 OPTION_ARG_TYPE_NUM, "starting address")) {
551 if (entry == (unsigned long)NO_MEMORY) {
552 err_printf("No entry point known - aborted\n");
556 int script_timeout_ms = wait_time * 1000;
557 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
558 unsigned char *hold_script = script;
561 diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
562 (void *)entry, wait_time);
563 while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
564 res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
565 if (res == _GETS_CTRLC) {
566 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
567 script = hold_script; // Re-enable script
571 script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
575 // Mask interrupts on all channels
576 cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
577 for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) {
578 CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
579 __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
580 CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
582 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
584 __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
585 CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
587 #ifdef CYGPKG_IO_ETH_DRIVERS
592 HAL_DISABLE_INTERRUPTS(oldints);
594 if (!cache_enabled) {
595 HAL_ICACHE_DISABLE();
596 HAL_DCACHE_DISABLE();
599 HAL_ICACHE_INVALIDATE_ALL();
600 HAL_DCACHE_INVALIDATE_ALL();
601 // set up a temporary context that will take us to the trampoline
602 HAL_THREAD_INIT_CONTEXT(workspace_end,
603 entry, trampoline, 0);
605 // switch context to trampoline
606 HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
608 // we get back here by way of return_to_redboot()
610 // undo the changes we made before switching context
611 if (!cache_enabled) {
616 CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);
618 HAL_RESTORE_INTERRUPTS(oldints);
620 diag_printf("\nProgram completed with status %d\n", return_status);
623 #ifdef HAL_PLATFORM_RESET
625 do_reset(int argc, char *argv[])
627 diag_printf("... Resetting.");
628 CYGACC_CALL_IF_DELAY_US(2 * 100000);
630 CYGACC_CALL_IF_RESET();
631 diag_printf("!! oops, RESET not working on this platform\n");
635 #ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
636 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
637 #include <flash_config.h>
641 set_comm_baud_rate(hal_virtual_comm_table_t *chan, int rate)
645 current_rate = CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_GETBAUD);
646 if (rate != current_rate)
647 return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);
653 set_console_baud_rate(int rate)
656 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
657 if (!console_selected) {
658 int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
660 // Set baud for all channels
661 for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++) {
662 CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
663 ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
667 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
670 ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
673 diag_printf("Setting console baud rate to %d failed\n", rate);
682 for (i = 0; i < ms; i++) {
683 CYGACC_CALL_IF_DELAY_US((cyg_int32)1000);
688 do_baud_rate(int argc, char *argv[])
690 int new_rate, ret, old_rate;
692 hal_virtual_comm_table_t *__chan;
693 struct option_info opts[1];
694 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
695 struct config_option opt;
698 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
699 &new_rate, &new_rate_set, "new baud rate");
700 if (!scan_opts(argc, argv, 1, opts, 1, NULL, 0, "")) {
703 __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
705 diag_printf("Baud rate will be changed to %d - update your settings\n", new_rate);
706 _sleep(500); // Give serial time to flush
707 old_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
708 ret = set_console_baud_rate(new_rate);
712 set_console_baud_rate(old_rate);
713 _sleep(500); // Give serial time to flush
714 diag_printf("\nret = %d\n", ret);
716 return; // Couldn't set the desired rate
718 // Make sure this new rate works or back off to previous value
719 // Sleep for a few seconds, then prompt to see if it works
720 _sleep(3000); // Give serial time to flush
721 if (!verify_action_with_timeout(5000, "Baud rate changed to %d", new_rate)) {
722 _sleep(500); // Give serial time to flush
723 set_console_baud_rate(old_rate);
724 _sleep(500); // Give serial time to flush
727 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
728 opt.type = CONFIG_INT;
730 opt.enable_sense = 1;
731 opt.key = "console_baud_rate";
733 flash_add_config(&opt, true);
736 ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
737 diag_printf("Baud rate = ");
739 diag_printf("unknown\n");
741 diag_printf("%d\n", ret);
748 // Validate an address to see if it is within any known RAM area
751 valid_address(unsigned char *addr)
755 for (seg = 0; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) {
756 if (mem_segments[seg].start != NO_MEMORY) {
757 if ((addr >= mem_segments[seg].start) && (addr < mem_segments[seg].end)) {
765 static unsigned long random;
766 /* provide at least _some_ sort of randomness */
767 #define MAX_LOOPS 1000
769 extern unsigned int hal_timer_count(void);
771 static void random_init(void)
776 unsigned int start = hal_timer_count();
778 start = hal_timer_count();
779 for (i = 0; i < MAX_LOOPS; i++) {
780 timer = hal_timer_count();
781 srand(random + timer);
785 RedBoot_init(random_init, RedBoot_INIT_FIRST);