1 //==========================================================================
5 // Monitor shell and main routines for CygMON the Wonder Monitor
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: gthomas, dmoseley
46 // Purpose: Monitor shell and main routines for CygMON the Wonder Monitor
50 //####DESCRIPTIONEND####
52 //=========================================================================
54 /* Platform-independent code for cygmon */
61 #include <bsp/hex-utils.h>
72 #if USE_CYGMON_PROTOTYPES
73 /* Use common prototypes */
74 /* Some of the composed board.h files compose these
75 prototypes redundently, but if they dont,
76 these are the common definitions */
77 #include "fmt_util.h" /* Interface to string formatting utilities */
78 #include "tservice.h" /* Interface to target specific services */
79 #include "generic-stub.h" /* from libstub */
80 #endif /* USE_CYGMON_PROTOTYPES */
82 static int cygmon_handle_exception (int sigval);
83 static void monitor_take_control (void);
85 #if CYGMON_SYSTEM_SERVICES
86 extern int process_syscall (int syscall_num);
87 #elif defined (USE_ECOS_HAL_EXCEPTIONS)
88 static int cygmon_process_syscall (int sigval);
91 int stub_is_active = 0;
96 #if !defined(USE_ECOS_HAL_EXCEPTIONS)
97 static int mon_dbg_handler(int exc_nr, void *regs);
98 static int mon_kill_handler(int exc_nr, void *regs);
99 #endif // USE_ECOS_HAL_EXCEPTIONS
101 #ifndef USE_ECOS_HAL_BREAKPOINTS
102 #define __is_breakpoint_function() (get_pc() == (target_register_t)bsp_breakinsn)
107 * This global flag is used by generic-stub.c to communicate to us that we
108 * are processing the breakpoint function within Cygmon itself.
110 extern int processing_breakpoint_function;
113 /* Global pointer to current set of saved registers. */
114 void *mon_saved_regs;
116 /* Original BSP debug vector replaced by monitor. */
117 #if !defined(USE_ECOS_HAL_EXCEPTIONS)
118 static bsp_handler_t old_dbg_vec;
119 #endif // !defined(USE_ECOS_HAL_EXCEPTIONS)
122 static int handle_signal (int signal_val);
124 __PFI user_signal_handler = NULL;
127 #if defined(__ECOS__)
128 #include <cyg/hal/hal_stub.h>
131 #if defined(__ECOS__) && !defined(PROCESS_EXCEPTION_VEC_PROTOTYPE_EXISTS)
132 #define PROCESS_EXCEPTION_VEC_PROTOTYPE_EXISTS
133 extern volatile __PFI (*__process_exception_vec)(int);
137 #ifdef MONITOR_CONTROL_INTERRUPTS
138 /* This is set if the user wants interrupts enabled in the monitor. */
139 static int monitor_interrupts_enabled;
144 int monitor_main (int argc, char **argv) /* Suppress default main() junk */
146 int main (int argc, char **argv)
151 struct bsp_comm_info comm_info;
153 /* Set up exception handling traps */
160 /* get info on debug channel */
161 cur_port = bsp_set_debug_comm(-1);
162 bsp_sysinfo(BSP_INFO_COMM, cur_port, &comm_info);
165 * If we're using a network interface, don't install
166 * the cygmon vectors. Currently, we only support stub
167 * mode over a network connection.
169 if (comm_info.kind != BSP_COMM_ENET)
174 /* replace original BSP debug and kill handler with ours */
175 #if !defined(USE_ECOS_HAL_EXCEPTIONS)
176 old_dbg_vec = bsp_install_dbg_handler(mon_dbg_handler);
177 (void)bsp_install_kill_handler(mon_kill_handler);
179 /* replace original BSP debug and kill handler with ours using eCos stuff */
180 __process_exception_vec = (__PFI)cygmon_handle_exception;
181 __process_syscall_vec = cygmon_process_syscall;
182 __process_exit_vec = monitor_take_control;
187 /* This forces the console to use the gdb channel. */
188 bsp_set_console_comm(cur_port);
194 __process_exception_vec = cygmon_handle_exception;
195 __process_exit_vec = monitor_take_control;
196 #if CYGMON_SYSTEM_SERVICES
197 __process_syscall_vec = process_syscall;
199 __process_signal_vec = handle_signal;
200 __init_vec = install_breakpoints;
201 __cleanup_vec = clear_breakpoints;
206 __process_exception_vec = cygmon_handle_exception;
213 if (switch_to_stub_flag)
215 xprintf("Switching to stub\n");
216 switch_to_stub_flag = 0;
225 /* Transfer control to gdb stub */
230 /* Return back to the exception handler, but the exception handler
231 should invoke the stub's exception handler instead of ours. */
232 #if defined(HAVE_BSP) && !defined(USE_ECOS_HAL_EXCEPTIONS)
233 (void)bsp_install_dbg_handler(old_dbg_vec);
238 /* The stub is now active. */
244 clear_user_state (void)
247 if (__timer_enabled ())
251 clear_breakpoints ();
254 user_signal_handler = NULL;
257 __clear_single_step ();
261 monitor_take_control (void)
264 switch_to_stub_flag = 0;
266 // Flush the unget state. This is because the ecos stub and Cygmon track this
268 bsp_debug_ungetc('\0');
270 #ifdef INITIALIZE_MON_EACH_TIME
271 // Call the per-stop initialization routine if it is defined.
272 INITIALIZE_MON_EACH_TIME();
275 #if defined(HAVE_BSP) && !defined(USE_ECOS_HAL_EXCEPTIONS)
276 /* replace original BSP debug trap handler with ours */
277 (void)bsp_install_dbg_handler(mon_dbg_handler);
280 __process_exception_vec = cygmon_handle_exception;
285 #ifdef MONITOR_CONTROL_INTERRUPTS
287 monitor_enable_interrupts (void)
289 monitor_interrupts_enabled = 1;
290 enable_interrupts ();
294 monitor_disable_interrupts (void)
296 monitor_interrupts_enabled = 0;
297 disable_interrupts ();
301 monitor_interrupt_state (void)
303 return monitor_interrupts_enabled;
307 #if defined(USE_ECOS_HAL_EXCEPTIONS)
308 externC HAL_SavedRegisters *_hal_registers;
309 extern int machine_syscall(HAL_SavedRegisters *regs);
311 cygmon_process_syscall (int sigval)
313 return machine_syscall(_hal_registers);
318 cygmon_handle_exception (int sigval)
320 target_register_t pc;
322 #ifdef MONITOR_CONTROL_INTERRUPTS
323 if (monitor_interrupts_enabled)
325 if (! __in_interrupt)
326 enable_interrupts ();
330 #ifdef TARGET_EXCEPTION_CODE
331 TARGET_EXCEPTION_CODE
335 if (sigval != SIGKILL)
336 if (handle_signal (sigval) == 0)
342 /* We may want to tweak the PC to point at the faulting instruction,
343 for example. (breakpoints on x86). */
344 #ifdef TARGET_ADJUST_PC
349 MAKE_STD_ADDR (pc, &last_pc);
352 if ((sigval == SIGTRAP) && (__is_breakpoint_function() || processing_breakpoint_function))
354 if ((sigval == SIGTRAP) && __is_breakpoint_function())
358 * This is the initial breakpoint inserted by the BSP
359 * Don't print anything for this as it is confusing
364 if (sigval == SIGTRAP)
365 xprintf ("Hit breakpoint");
367 xprintf ("Got signal %d", sigval);
369 xprintf (" at 0x%s\n", int2str (pc, 16, sizeof (target_register_t) * 2));
372 if (!__is_breakpoint_function ())
380 monitor_take_control ();
382 return monitor_loop ();
386 /* Returns 0 if the program should restart at the point at which the
387 signal was received, -1 otherwise. */
389 handle_signal (int signal)
391 if (signal == SIGKILL)
394 if (user_signal_handler != NULL)
396 int result = user_signal_handler (signal);
399 /* Don't ignore potential hardware signals. */
401 if (signal == SIGSEGV || signal == SIGBUS || signal == SIGFPE
402 || signal == SIGTRAP || signal == SIGILL)
423 struct bsp_platform_info platform;
424 struct bsp_mem_info mem;
426 unsigned long u, totmem, topmem;
428 extern char *build_date;
430 xprintf ("Cygmon, the Cygnus ROM monitor.\n");
431 xprintf ("Copyright(c) 1997, 1998, 1999, 2000 Red Hat\n\n");
432 xprintf ("Version: %s\nThis image was built on %s\n\n",
433 VERSION, build_date);
436 bsp_sysinfo(BSP_INFO_PLATFORM, &platform);
440 while (bsp_sysinfo(BSP_INFO_MEMORY, i++, &mem) == 0)
442 if (mem.kind == BSP_MEM_RAM)
444 totmem += mem.nbytes;
445 u = (unsigned long)mem.virt_start + mem.nbytes;
451 xprintf("CPU: %s\n", platform.cpu);
452 xprintf("Board: %s\n", platform.board);
453 if (*(platform.extra))
454 xprintf("%s\n", platform.extra);
455 xprintf("Total RAM: %d bytes\n", totmem);
456 xprintf("Top of RAM: 0x%x\n", topmem);
462 #if !defined(USE_ECOS_HAL_EXCEPTIONS)
464 mon_kill_handler(int exc_nr, void *regs)
466 monitor_take_control();
469 #endif // !defined(USE_ECOS_HAL_EXCEPTIONS)
471 #if !defined(USE_ECOS_HAL_EXCEPTIONS)
473 mon_dbg_handler(int exc_nr, void *regs)
476 unsigned long cur_pc;
478 mon_saved_regs = regs;
479 sig = bsp_get_signal(exc_nr, regs);
481 cygmon_handle_exception(sig);
483 cur_pc = bsp_get_pc(regs);
484 if (cur_pc == (unsigned long)bsp_breakinsn)
485 bsp_skip_instruction(regs);
488 install_breakpoints();
492 #endif // !defined(USE_ECOS_HAL_EXCEPTIONS)