Mercurial > ecos
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[]) |
