Mercurial > ecos
view packages/cygmon/current/misc/monitor.c @ 76:435cced73e2f ecos-v1_3_1-release
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
| author | jlarmour |
|---|---|
| date | Tue, 28 Mar 2000 14:10:45 +0000 |
| parents | |
| children | 02ea4320376c |
line wrap: on
line source
//========================================================================== // // monitor.c // // Monitor shell and main routines for CygMON the Wonder Monitor // //========================================================================== //####COPYRIGHTBEGIN#### // // ------------------------------------------- // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.redhat.com/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations under // the License. // // The Original Code is eCos - Embedded Configurable Operating System, // released September 30, 1998. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND#### //========================================================================== //#####DESCRIPTIONBEGIN#### // // Author(s): // Contributors: gthomas // Date: 1999-10-20 // Purpose: Monitor shell and main routines for CygMON the Wonder Monitor // Description: // // //####DESCRIPTIONEND#### // //========================================================================= /* Platform-independent code for cygmon */ #include <stdlib.h> #include <unistd.h> #ifdef HAVE_BSP #include <bsp/bsp.h> #include <bsp/cpu.h> #include <bsp/hex-utils.h> #endif #include <monitor.h> #ifdef HAVE_BSP #include "cpu_info.h" #endif #include <ledit.h> #include <signal.h> #include <string.h> #include <ctype.h> #if USE_CYGMON_PROTOTYPES /* Use common prototypes */ /* Some of the composed board.h files compose these prototypes redundently, but if they dont, these are the common definitions */ #include "fmt_util.h" /* Interface to string formatting utilities */ #include "tservice.h" /* Interface to target specific services */ #include "generic-stub.h" /* from libstub */ #endif /* USE_CYGMON_PROTOTYPES */ static int cygmon_handle_exception (int sigval); static void monitor_take_control (void); #if CYGMON_SYSTEM_SERVICES extern int process_syscall (int syscall_num); #endif int stub_is_active = 0; mem_addr_t last_pc; #ifdef HAVE_BSP static int mon_dbg_handler(int exc_nr, void *regs); static int mon_kill_handler(int exc_nr, void *regs); #define __is_breakpoint_function() (get_pc() == (target_register_t)bsp_breakinsn) /* Global pointer to current set of saved registers. */ void *mon_saved_regs; /* Original BSP debug vector replaced by monitor. */ static bsp_handler_t old_dbg_vec; #else static int handle_signal (int signal_val); __PFI user_signal_handler = NULL; #endif #ifdef __ECOS__ extern (*__process_exception_vec)(int); #endif #ifdef MONITOR_CONTROL_INTERRUPTS /* This is set if the user wants interrupts enabled in the monitor. */ static int monitor_interrupts_enabled; #endif #if NOMAIN int monitor_main (int argc, char **argv) /* Suppress default main() junk */ #else int main (int argc, char **argv) #endif { #ifdef HAVE_BSP int cur_port; struct bsp_comm_info comm_info; #else /* Set up exception handling traps */ initialize_stub (); #endif initialize_mon (); #ifdef HAVE_BSP /* get info on debug channel */ cur_port = bsp_set_debug_comm(-1); bsp_sysinfo(BSP_INFO_COMM, cur_port, &comm_info); /* * If we're using a network interface, don't install * the cygmon vectors. Currently, we only support stub * mode over a network connection. */ if (comm_info.kind != BSP_COMM_ENET) { xprintf("\n"); version (); /* replace original BSP debug and kill handler with ours */ old_dbg_vec = bsp_install_dbg_handler(mon_dbg_handler); (void)bsp_install_kill_handler(mon_kill_handler); } else { /* This forces the console to use the gdb channel. */ bsp_set_console_comm(cur_port); } #else xprintf("\n"); version (); __process_exception_vec = cygmon_handle_exception; __process_exit_vec = monitor_take_control; #if CYGMON_SYSTEM_SERVICES __process_syscall_vec = process_syscall; #endif __process_signal_vec = handle_signal; __init_vec = install_breakpoints; __cleanup_vec = clear_breakpoints; #endif #if 0 #ifdef __ECOS__ __process_exception_vec = cygmon_handle_exception; #endif #endif while (1) { breakpoint (); if (switch_to_stub_flag) { xprintf("Switching to stub\n"); switch_to_stub_flag = 0; } } /* never reached */ exit (0); } /* Transfer control to gdb stub */ int transfer_to_stub () { /* Return back to the exception handler, but the exception handler should invoke the stub's exception handler instead of ours. */ #ifdef HAVE_BSP (void)bsp_install_dbg_handler(old_dbg_vec); #else __switch_to_stub (); #endif /* The stub is now active. */ stub_is_active = 1; return -1; } void clear_user_state (void) { #ifdef HAS_TIMER if (__timer_enabled ()) __settimer (0, 0); #endif clear_breakpoints (); #ifdef HAVE_BSP bsp_singlestep_cleanup(mon_saved_regs); #else user_signal_handler = NULL; __clear_single_step (); #endif } static void monitor_take_control (void) { stub_is_active = 0; #ifdef HAVE_BSP /* replace original BSP debug trap handler with ours */ (void)bsp_install_dbg_handler(mon_dbg_handler); #else clear_user_state (); __process_exception_vec = cygmon_handle_exception; #endif } #ifdef MONITOR_CONTROL_INTERRUPTS void monitor_enable_interrupts (void) { monitor_interrupts_enabled = 1; enable_interrupts (); } void monitor_disable_interrupts (void) { monitor_interrupts_enabled = 0; disable_interrupts (); } int monitor_interrupt_state (void) { return monitor_interrupts_enabled; } #endif static int cygmon_handle_exception (int sigval) { target_register_t pc; #ifdef MONITOR_CONTROL_INTERRUPTS if (monitor_interrupts_enabled) { if (! __in_interrupt) enable_interrupts (); } #endif #ifdef TARGET_EXCEPTION_CODE TARGET_EXCEPTION_CODE #endif #ifndef HAVE_BSP if (sigval != SIGKILL) if (handle_signal (sigval) == 0) return 0; #endif clear_user_state (); /* We may want to tweak the PC to point at the faulting instruction, for example. (breakpoints on x86). */ #ifdef TARGET_ADJUST_PC TARGET_ADJUST_PC #endif pc = get_pc(); MAKE_STD_ADDR (pc, &last_pc); if ((sigval == SIGTRAP) && __is_breakpoint_function()) { /* * This is the initial breakpoint inserted by the BSP * Don't print anything for this as it is confusing */ } else { if (sigval == SIGTRAP) xprintf ("Hit breakpoint"); else xprintf ("Got signal %d", sigval); xprintf (" at 0x%s\n", int2str (pc, 16, sizeof (target_register_t) * 2)); #ifdef DISASSEMBLER if (!__is_breakpoint_function ()) { do_dis (&last_pc); flush_dis (); } #endif } monitor_take_control (); return monitor_loop (); } #ifndef HAVE_BSP /* Returns 0 if the program should restart at the point at which the signal was received, -1 otherwise. */ static int handle_signal (int signal) { if (signal == SIGKILL) return -1; if (user_signal_handler != NULL) { int result = user_signal_handler (signal); switch (result) { /* Don't ignore potential hardware signals. */ case 3: if (signal == SIGSEGV || signal == SIGBUS || signal == SIGFPE || signal == SIGTRAP || signal == SIGILL) return -1; case 0: return 0; default: case 1: case 2: return -1; } } return -1; } #endif void version (void) { #ifdef HAVE_BSP struct bsp_platform_info platform; struct bsp_mem_info mem; int i; unsigned long u, totmem, topmem; #endif extern char *build_date; xprintf ("Cygmon, the Cygnus ROM monitor.\n"); xprintf ("Copyright(c) 1997, 1998, 1999, 2000 Red Hat\n\n"); xprintf ("Version: %s\nThis image was built on %s\n\n", VERSION, build_date); #ifdef HAVE_BSP bsp_sysinfo(BSP_INFO_PLATFORM, &platform); totmem = topmem = 0; i = 0; while (bsp_sysinfo(BSP_INFO_MEMORY, i++, &mem) == 0) { if (mem.kind == BSP_MEM_RAM) { totmem += mem.nbytes; u = (unsigned long)mem.virt_start + mem.nbytes; if (u > topmem) topmem = u; } } xprintf("CPU: %s\n", platform.cpu); xprintf("Board: %s\n", platform.board); if (*(platform.extra)) xprintf("%s\n", platform.extra); xprintf("Total RAM: %d bytes\n", totmem); xprintf("Top of RAM: 0x%x\n", topmem); #endif } #ifdef HAVE_BSP static int mon_kill_handler(int exc_nr, void *regs) { monitor_take_control(); return 1; } static int mon_dbg_handler(int exc_nr, void *regs) { int sig; unsigned long cur_pc; mon_saved_regs = regs; sig = bsp_get_signal(exc_nr, regs); cygmon_handle_exception(sig); cur_pc = bsp_get_pc(regs); if (cur_pc == (unsigned long)bsp_breakinsn) bsp_skip_instruction(regs); if (!stub_is_active) install_breakpoints(); return 1; } #endif
