comparison packages/redboot/current/src/main.c @ 556:f2b5df359050

Support return to redboot from go
author msalter
date Fri, 31 Jan 2003 16:45:57 +0000
parents 44f818173f96
children 17d4ac30ee71
comparison
equal deleted inserted replaced
555:ed761349f500 556:f2b5df359050
6 // 6 //
7 //========================================================================== 7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN#### 8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // ------------------------------------------- 9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System. 10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. 11 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
12 // Copyright (C) 2002 Gary Thomas 12 // Copyright (C) 2002 Gary Thomas
13 // 13 //
14 // eCos is free software; you can redistribute it and/or modify it under 14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free 15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version. 16 // Software Foundation; either version 2 or (at your option) any later version.
73 extern void breakpoint(void); 73 extern void breakpoint(void);
74 #endif 74 #endif
75 75
76 // Builtin Self Test (BIST) 76 // Builtin Self Test (BIST)
77 externC void bist(void); 77 externC void bist(void);
78
79 // Return path for code run from a go command
80 static void return_to_redboot(int status);
81
78 82
79 // CLI command processing (defined in this file) 83 // CLI command processing (defined in this file)
80 RedBoot_cmd("version", 84 RedBoot_cmd("version",
81 "Display RedBoot version information", 85 "Display RedBoot version information",
82 "", 86 "",
182 struct init_tab_entry *init_entry; 186 struct init_tab_entry *init_entry;
183 extern char RedBoot_version[]; 187 extern char RedBoot_version[];
184 188
185 // Export version information 189 // Export version information
186 CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version); 190 CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
191
192 CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
187 193
188 // Make sure the channels are properly initialized. 194 // Make sure the channels are properly initialized.
189 diag_init_putc(_mon_write_char); 195 diag_init_putc(_mon_write_char);
190 hal_if_diag_init(); 196 hal_if_diag_init();
191 197
376 cmd = __RedBoot_CMD_TAB__; 382 cmd = __RedBoot_CMD_TAB__;
377 show_help(cmd, &__RedBoot_CMD_TAB_END__, which, ""); 383 show_help(cmd, &__RedBoot_CMD_TAB_END__, which, "");
378 return; 384 return;
379 } 385 }
380 386
387 static void * go_saved_context;
388 static int go_return_status;
389
390 static void
391 go_trampoline(unsigned long entry)
392 {
393 typedef void code_fun(void);
394 code_fun *fun = (code_fun *)entry;
395 unsigned long oldints;
396
397 HAL_DISABLE_INTERRUPTS(oldints);
398
399 #ifdef HAL_ARCH_PROGRAM_NEW_STACK
400 HAL_ARCH_PROGRAM_NEW_STACK(fun);
401 #else
402 (*fun)();
403 #endif
404 }
405
406 static void
407 return_to_redboot(int status)
408 {
409 CYGARC_HAL_SAVE_GP();
410
411 go_return_status = status;
412 HAL_THREAD_LOAD_CONTEXT(&go_saved_context);
413 // never returns
414 }
415
381 void 416 void
382 do_go(int argc, char *argv[]) 417 do_go(int argc, char *argv[])
383 { 418 {
384 typedef void code_fun(void);
385 unsigned long entry; 419 unsigned long entry;
386 unsigned long oldints; 420 unsigned long oldints;
387 code_fun *fun;
388 bool wait_time_set; 421 bool wait_time_set;
389 int wait_time, res; 422 int wait_time, res;
390 struct option_info opts[1]; 423 bool cache_enabled = false;
424 struct option_info opts[2];
391 char line[8]; 425 char line[8];
392 hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS(); 426 hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
393 427
394 entry = entry_address; // Default from last 'load' operation 428 entry = entry_address; // Default from last 'load' operation
395 init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, 429 init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
396 (void **)&wait_time, (bool *)&wait_time_set, "wait timeout"); 430 (void **)&wait_time, (bool *)&wait_time_set, "wait timeout");
397 if (!scan_opts(argc, argv, 1, opts, 1, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address")) 431 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG,
432 (void **)&cache_enabled, (bool *)0, "go with caches enabled");
433 if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
398 { 434 {
399 return; 435 return;
400 } 436 }
401 if (wait_time_set) { 437 if (wait_time_set) {
402 int script_timeout_ms = wait_time * 1000; 438 int script_timeout_ms = wait_time * 1000;
417 script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; 453 script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
418 } 454 }
419 } 455 }
420 CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH); 456 CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
421 457
422 fun = (code_fun *)entry;
423 HAL_DISABLE_INTERRUPTS(oldints); 458 HAL_DISABLE_INTERRUPTS(oldints);
424 HAL_DCACHE_SYNC(); 459 HAL_DCACHE_SYNC();
425 HAL_ICACHE_DISABLE(); 460 if (!cache_enabled) {
426 HAL_DCACHE_DISABLE(); 461 HAL_ICACHE_DISABLE();
427 HAL_DCACHE_SYNC(); 462 HAL_DCACHE_DISABLE();
463 HAL_DCACHE_SYNC();
464 }
428 HAL_ICACHE_INVALIDATE_ALL(); 465 HAL_ICACHE_INVALIDATE_ALL();
429 HAL_DCACHE_INVALIDATE_ALL(); 466 HAL_DCACHE_INVALIDATE_ALL();
430 #ifdef HAL_ARCH_PROGRAM_NEW_STACK 467
431 HAL_ARCH_PROGRAM_NEW_STACK(fun); 468 // set up a temporary context that will take us to the trampoline
432 #else 469 HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, go_trampoline, 0);
433 (*fun)(); 470
434 #endif 471 // switch context to trampoline
472 HAL_THREAD_SWITCH_CONTEXT(&go_saved_context, &workspace_end);
473
474 // we get back here by way of return_to_redboot()
475
476 // undo the changes we made before switching context
477 if (!cache_enabled) {
478 HAL_ICACHE_ENABLE();
479 HAL_DCACHE_ENABLE();
480 }
481
482 CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);
483
484 HAL_RESTORE_INTERRUPTS(oldints);
485
486 diag_printf("\nProgram completed with status %d\n", go_return_status);
435 } 487 }
436 488
437 #ifdef HAL_PLATFORM_RESET 489 #ifdef HAL_PLATFORM_RESET
438 void 490 void
439 do_reset(int argc, char *argv[]) 491 do_reset(int argc, char *argv[])