This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ECOS] Calling exit in a Redboot standalone Arm program


-- 
________________________________________________________________________
Pierre HABRAKEN - mailto:Pierre.Habraken@imag.fr
Tél: 04 76 82 72 83 - Fax: 04 76 82 72 87
IMAG-LSR BP72 38402 SAINT MARTIN D'HERES Cedex
________________________________________________________________________
2003-05-05  Pierre Habraken  <Pierre.Habraken@imag.fr>

   * cdl/redboot.cdl: Added option
   CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP for enabling (possibly
   single shot) programs to exit and return a termination status as
   their normal behavior (i.e. without raising a SIGTRAP).
   * src/syscall.c (__do_syscall, return_from_stub): Added conditionally
   compiled code to SYS_exit for returning to RedBoot main loop without
   raising a SIGTRAP, even when the calling program is not being
   debugged (use of a trampoline function suggested by Mark Salter).
   * src/main.c (cyg_start, call_breakpoint): Added code (following
   Jonathan Larmour's and Mark Salter's suggestions) to RedBoot main
   loop: a (context) savepoint is created before the thread of control
   is transferred to gdb stubs (through a trampoline procedure). This
   savepoint enables the stubs to return control back to the main loop
   by calling the return_to_redboot procedure (macro
   CYGACC_CALL_IF_MONITOR_RETURN). Procedure go_trampoline and variables
   go_saved_context and go_return_status have been respectively renamed
   to trampoline, saved_context and return_status.
--- redboot/current/cdl/redboot.cdl.inst	Fri May  2 16:51:42 2003
+++ redboot/current/cdl/redboot.cdl	Mon May  5 15:01:13 2003
@@ -841,6 +841,15 @@
                 display	"Does the HAL support 'gprof' profiling?"
                 no_define
             }
+
+            cdl_option CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP {
+                display "Do not raise SIGTRAP when program exits"
+                default_value 0
+                description "
+                    For some (single shot) newlib based programs,
+                    exiting and returning a termination status may be
+                    the normal expected behavior."
+            }
         }
     
         cdl_component CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER {
--- redboot/current/src/syscall.c.inst	Fri Jan 31 17:46:00 2003
+++ redboot/current/src/syscall.c	Mon May  5 13:24:36 2003
@@ -424,6 +424,13 @@
 
 #endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
 
+// Trampoline for returning to RedBoot
+static void
+return_from_stub(int exit_status)
+{
+   CYGACC_CALL_IF_MONITOR_RETURN(exit_status);
+}
+
 //
 //  Generic syscall handler.
 //
@@ -632,12 +639,19 @@
 
       case SYS_exit:
 	if (gdb_active) {
+#ifdef CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP
+	    __send_exit_status((int)arg1);
+	}
+	set_pc((target_register_t)return_from_stub);
+   err = arg1;
+#else
 	    *sig = SIGTRAP;
 	    err = func;
 	} else {
-	    CYGACC_CALL_IF_MONITOR_RETURN(arg1);
-	    // never returns
+	    set_pc((target_register_t)return_from_stub);
+       err = arg1;
 	}
+#endif // CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP
 	break;
 
       default:
--- redboot/current/src/main.c.inst	Mon Mar  3 18:49:40 2003
+++ redboot/current/src/main.c	Mon May  5 13:09:29 2003
@@ -76,9 +76,21 @@
 // Builtin Self Test (BIST)
 externC void bist(void);
 
-// Return path for code run from a go command
+// Path to code run from a go command or to GDB stubs
+static void trampoline(unsigned long entry);
+
+// Return path for code run from a go command or for GDB stubs
 static void return_to_redboot(int status);
 
+// Wrapper to breakpoint()
+static void call_breakpoint(void);
+
+// Address of area where current context is saved before executing
+// trampoline procedure
+static void * saved_context;
+
+// Status returned after trampoline execution
+static int return_status;
 
 // CLI command processing (defined in this file)
 RedBoot_cmd("version", 
@@ -171,6 +183,17 @@
     mon_write_char(c);
 }
 
+// Wrapper to breakpoint()
+static void
+call_breakpoint(void)
+{
+#ifdef HAL_ARCH_PROGRAM_NEW_STACK
+   HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
+#else
+   breakpoint(); // get GDB stubs started, with a proper environment, etc.
+#endif
+}
+
 //
 // This is the main entry point for RedBoot
 //
@@ -312,11 +335,15 @@
                 }
     
                 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
-#ifdef HAL_ARCH_PROGRAM_NEW_STACK
-                HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
-#else
-                breakpoint();  // Get GDB stubs started, with a proper environment, etc.
-#endif
+
+                // set up a temporary context that will take us to the
+                // trampoline
+                HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end,
+                                        call_breakpoint, trampoline, 0);
+
+                // switch context to trampoline (get GDB stubs started)
+                HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
+
 		dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
 		CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
             } else 
@@ -384,11 +411,8 @@
     return;
 }
 
-static void * go_saved_context;
-static int go_return_status;
-
 static void
-go_trampoline(unsigned long entry)
+trampoline(unsigned long entry)
 {
     typedef void code_fun(void);
     code_fun *fun = (code_fun *)entry;
@@ -408,8 +432,8 @@
 {
     CYGARC_HAL_SAVE_GP();
 
-    go_return_status = status;
-    HAL_THREAD_LOAD_CONTEXT(&go_saved_context);
+    return_status = status;
+    HAL_THREAD_LOAD_CONTEXT(&saved_context);
     // never returns
 
     // need this to balance above CYGARC_HAL_SAVE_GP on
@@ -470,10 +494,10 @@
     HAL_DCACHE_INVALIDATE_ALL();
 
     // set up a temporary context that will take us to the trampoline
-    HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, go_trampoline, 0);
+    HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, trampoline, 0);
 
     // switch context to trampoline
-    HAL_THREAD_SWITCH_CONTEXT(&go_saved_context, &workspace_end);
+    HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
 
     // we get back here by way of return_to_redboot()
 
@@ -487,7 +511,7 @@
 
     HAL_RESTORE_INTERRUPTS(oldints);
 
-    diag_printf("\nProgram completed with status %d\n", go_return_status);
+    diag_printf("\nProgram completed with status %d\n", return_status);
 }
 
 #ifdef HAL_PLATFORM_RESET

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]