[ECOS] RedBoot go command enhancement

Mark Salter msalter@redhat.com
Thu Jan 30 16:17:00 GMT 2003


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



More information about the Ecos-discuss mailing list