This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
RedBoot go command enhancement
- From: Mark Salter <msalter at redhat dot com>
- To: ecos-discuss at sources dot redhat dot com
- Date: Thu, 30 Jan 2003 11:12:49 -0500 (EST)
- Subject: [ECOS] RedBoot go command enhancement
Here's a patch I've been playing around with. It provides a
mechanism for programs started by the RedBoot go command to
return to the RedBoot prompt and have its exit status displayed.
It also adds a -c flag to the go command which prevents the
caches from being disabled before jumping to the program. I've
only tried it with standalone newlib/libgloss based apps, but
eCos apps should also be able to use the VV mechanism as well.
I thought I'd throw this out and solicit any comments.
--Mark
Index: hal/arm/arch/current/src/hal_syscall.c
===================================================================
RCS file: /home/cvs/ecc/ecc/hal/arm/arch/current/src/hal_syscall.c,v
retrieving revision 1.4
diff -u -p -5 -r1.4 hal_syscall.c
--- hal/arm/arch/current/src/hal_syscall.c 2002/05/21 21:07:52 1.4
+++ hal/arm/arch/current/src/hal_syscall.c 2003/01/30 16:02:41
@@ -104,16 +104,10 @@ hal_syscall_handler(void)
if ((get_register(PS) & CPSR_MODE_BITS) == CPSR_SUPERVISOR_MODE)
put_register(PC, get_register(IP));
else
put_register(PC, get_register(LR));
- if (func == SYS_exit) {
- // We want to stop in exit so that the user may poke around
- // to see why his app exited.
- return SIGTRAP;
- }
-
if (func == SYS_interrupt) {
// A console interrupt landed us here.
// Invoke the debug agent so as to cause a SIGINT.
return SIGINT;
}
Index: hal/common/current/include/hal_if.h
===================================================================
RCS file: /home/cvs/ecc/ecc/hal/common/current/include/hal_if.h,v
retrieving revision 1.32
diff -u -p -5 -r1.32 hal_if.h
--- hal/common/current/include/hal_if.h 2002/12/04 21:48:03 1.32
+++ hal/common/current/include/hal_if.h 2003/01/30 16:02:48
@@ -9,11 +9,11 @@
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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.
@@ -363,12 +363,13 @@ __call_COMM1(IF_GETC_TIMEOUT, cyg_bool,
#define CYGNUM_CALL_IF_RESET 16
#define CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG 17
#define CYGNUM_CALL_IF_DELAY_US 18
#define CYGNUM_CALL_IF_DBG_DATA 19
#define CYGNUM_CALL_IF_FLASH_CFG_OP 20
+#define CYGNUM_CALL_IF_MONITOR_RETURN 21
-#define CYGNUM_CALL_IF_LAST_ENTRY CYGNUM_CALL_IF_FLASH_CFG_OP
+#define CYGNUM_CALL_IF_LAST_ENTRY CYGNUM_CALL_IF_MONITOR_RETURN
#define CYGNUM_CALL_IF_INSTALL_BPT_FN 35
#define CYGNUM_CALL_IF_TABLE_SIZE 64
@@ -422,10 +423,11 @@ typedef int __call_if_console_interrupt_
typedef void (__call_if_delay_us_t)(cyg_int32 usecs);
typedef void (__call_if_install_bpt_fn_t)(void *__epc);
typedef cyg_bool (__call_if_flash_cfg_op_fn_t)(int __oper, char *__key,
void *__val, int __type);
typedef char *__call_if_monitor_version_t;
+typedef void (__call_if_monitor_return_t)(int status);
#ifndef CYGACC_CALL_IF_DEFINED
#define __data_VV(_n_,_tt_) \
static __inline__ _tt_ \
@@ -616,10 +618,16 @@ __call_voidVV1(CYGNUM_CALL_IF_INSTALL_BP
CYGACC_CALL_VV4(__call_if_flash_cfg_op_fn_t*, CYGNUM_CALL_IF_FLASH_CFG_OP, (_o_),(_k_),(_d_),(_t_))
__call_VV4(CYGNUM_CALL_IF_FLASH_CFG_OP, __call_if_flash_cfg_op_fn_t, cyg_bool, int, char *, void *, int)
#define CYGACC_CALL_IF_FLASH_CFG_OP_SET(_x_) \
hal_virtual_vector_table[CYGNUM_CALL_IF_FLASH_CFG_OP]=(CYG_ADDRWORD)(_x_)
#define CYGNUM_CALL_IF_FLASH_CFG_GET (0)
+
+#define CYGACC_CALL_IF_MONITOR_RETURN(_u_) \
+ CYGACC_CALL_VV1(__call_if_monitor_return_t*, CYGNUM_CALL_IF_MONITOR_RETURN, (_u_))
+__call_voidVV1(CYGNUM_CALL_IF_MONITOR_RETURN, __call_if_monitor_return_t, void, int)
+#define CYGACC_CALL_IF_MONITOR_RETURN_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_MONITOR_RETURN]=(CYG_ADDRWORD)(_x_)
// These need to be kept uptodate with the (unadorned) masters
// in RedBoot's flash_config.h:
#define CYGNUM_FLASH_CFG_OP_CONFIG_EMPTY 0
#define CYGNUM_FLASH_CFG_OP_CONFIG_BOOL 1
Index: redboot/current/src/main.c
===================================================================
RCS file: /home/cvs/ecc/ecc/redboot/current/src/main.c,v
retrieving revision 1.95
diff -u -p -5 -r1.95 main.c
--- redboot/current/src/main.c 2002/12/04 21:48:10 1.95
+++ redboot/current/src/main.c 2003/01/30 16:03:28
@@ -6,11 +6,11 @@
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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.
@@ -74,10 +74,14 @@ extern void breakpoint(void);
#endif
// Builtin Self Test (BIST)
externC void bist(void);
+// Return path for code run from a go command
+static void return_to_redboot(int status);
+
+
// CLI command processing (defined in this file)
RedBoot_cmd("version",
"Display RedBoot version information",
"",
do_version
@@ -183,10 +187,12 @@ cyg_start(void)
extern char RedBoot_version[];
// Export version information
CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
+ CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
+
// Make sure the channels are properly initialized.
diag_init_putc(_mon_write_char);
hal_if_diag_init();
// Force console to output raw text - but remember the old setting
@@ -376,27 +382,57 @@ do_help(int argc, char *argv[])
cmd = __RedBoot_CMD_TAB__;
show_help(cmd, &__RedBoot_CMD_TAB_END__, which, "");
return;
}
+void * go_saved_sp;
+static int go_return_status;
+
+static void
+go_trampoline(unsigned long entry)
+{
+ typedef void code_fun(void);
+ code_fun *fun = (code_fun *)entry;
+ unsigned long oldints;
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+
+#ifdef HAL_ARCH_PROGRAM_NEW_STACK
+ HAL_ARCH_PROGRAM_NEW_STACK(fun);
+#else
+ (*fun)();
+#endif
+}
+
+static void
+return_to_redboot(int status)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ go_return_status = status;
+ HAL_THREAD_LOAD_CONTEXT(&go_saved_sp);
+ // never returns
+}
+
void
do_go(int argc, char *argv[])
{
- typedef void code_fun(void);
unsigned long entry;
unsigned long oldints;
- code_fun *fun;
bool wait_time_set;
int wait_time, res;
- struct option_info opts[1];
+ bool cache_enabled = false;
+ struct option_info opts[2];
char line[8];
hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
entry = entry_address; // Default from last 'load' operation
init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
(void **)&wait_time, (bool *)&wait_time_set, "wait timeout");
- if (!scan_opts(argc, argv, 1, opts, 1, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
+ init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG,
+ (void **)&cache_enabled, (bool *)0, "go with caches enabled");
+ if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
{
return;
}
if (wait_time_set) {
int script_timeout_ms = wait_time * 1000;
@@ -417,23 +453,33 @@ do_go(int argc, char *argv[])
script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
}
}
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
- fun = (code_fun *)entry;
HAL_DISABLE_INTERRUPTS(oldints);
HAL_DCACHE_SYNC();
- HAL_ICACHE_DISABLE();
- HAL_DCACHE_DISABLE();
- HAL_DCACHE_SYNC();
+ if (!cache_enabled) {
+ HAL_ICACHE_DISABLE();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ }
HAL_ICACHE_INVALIDATE_ALL();
HAL_DCACHE_INVALIDATE_ALL();
-#ifdef HAL_ARCH_PROGRAM_NEW_STACK
- HAL_ARCH_PROGRAM_NEW_STACK(fun);
-#else
- (*fun)();
-#endif
+
+ HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, go_trampoline, 0);
+ HAL_THREAD_SWITCH_CONTEXT(&go_saved_sp, &workspace_end);
+
+ if (!cache_enabled) {
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_ENABLE();
+ }
+
+ CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);
+
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ diag_printf("\nProgram completed with status %d\n", go_return_status);
}
#ifdef HAL_PLATFORM_RESET
void
do_reset(int argc, char *argv[])
Index: redboot/current/src/syscall.c
===================================================================
RCS file: /home/cvs/ecc/ecc/redboot/current/src/syscall.c,v
retrieving revision 1.19
diff -u -p -5 -r1.19 syscall.c
--- redboot/current/src/syscall.c 2002/08/27 01:40:41 1.19
+++ redboot/current/src/syscall.c 2003/01/30 16:03:28
@@ -6,11 +6,11 @@
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
//
// 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.
//
@@ -50,10 +50,11 @@
//=========================================================================*/
#include <redboot.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_stub.h>
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS
#define NEWLIB_EIO 5 /* I/O error */
#define NEWLIB_ENOSYS 88 /* Syscall not supported */
@@ -626,10 +627,20 @@ __do_syscall(CYG_ADDRWORD func,
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
case __GET_SHARED:
*(__shared_t **)arg1 = &__shared_data;
break;
+
+ case SYS_exit:
+ if (gdb_active) {
+ *sig = SIGTRAP;
+ err = func;
+ } else {
+ CYGACC_CALL_IF_MONITOR_RETURN(arg1);
+ // never returns
+ }
+ break;
default:
return 0;
}
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss