📄 remote-mm.c
字号:
/* Remote debugging interface for Am290*0 running MiniMON monitor, for GDB. Copyright 1990, 1991, 1992 Free Software Foundation, Inc. Originally written by Daniel Mann at AMD.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* This is like remote.c but ecpects MiniMON to be running on the Am29000 target hardware. - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this file to gdb 3.95. I was unable to get this working on sun3os4 with termio, only with sgtty. Because we are only attempting to use this module to debug our kernel, which is already loaded when gdb is started up, I did not code up the file downloading facilities. As a result this module has only the stubs to download files. You should get tagged at compile time if you need to make any changes/additions. */ #include "defs.h"#include "inferior.h"#include "wait.h"#include "value.h"#include <ctype.h>#include <fcntl.h>#include <signal.h>#include <errno.h>#include <string.h>#include "terminal.h"#include "minimon.h"#include "target.h"/* Offset of member MEMBER in a struct of type TYPE. */#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)#define DRAIN_INPUT() (msg_recv_serial((union msg_t*)0))extern int stop_soon_quietly; /* for wait_for_inferior */static void mm_resume();static void mm_fetch_registers ();static int fetch_register ();static void mm_store_registers ();static int store_register ();static int regnum_to_srnum();static void mm_close ();static char* msg_str();static char* error_msg_str();static int expect_msg();static void init_target_mm();static int mm_memory_space();/* * Processor types. */#define TYPE_UNKNOWN 0#define TYPE_A29000 1#define TYPE_A29030 2#define TYPE_A29050 3static char *processor_name[] = { "Unknown", "A29000", "A29030", "A29050" };static int processor_type=TYPE_UNKNOWN;#define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)#define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE) #define LLOG_FILE "minimon.log"#if defined (LOG_FILE)FILE *log_file;#endif/* * Size of message buffers. I couldn't get memory reads to work when * the byte_count was larger than 512 (it may be a baud rate problem). */#define BUFER_SIZE 512 /* * Size of data area in message buffer on the TARGET (remote system). */#define MAXDATA_T (target_config.max_msg_size - \ offsetof(struct write_r_msg_t,data[0]))/* * Size of data area in message buffer on the HOST (gdb). */#define MAXDATA_H (BUFER_SIZE - offsetof(struct write_r_msg_t,data[0]))/* * Defined as the minimum size of data areas of the two message buffers */#define MAXDATA (MAXDATA_H < MAXDATA_T ? MAXDATA_H : MAXDATA_T)static char out_buf[BUFER_SIZE];static char in_buf[BUFER_SIZE];int msg_recv_serial();int msg_send_serial();#define MAX_RETRIES 5000extern struct target_ops mm_ops; /* Forward declaration */struct config_msg_t target_config; /* HIF needs this */union msg_t *out_msg_buf = (union msg_t*)out_buf;union msg_t *in_msg_buf = (union msg_t*)in_buf;static int timeout = 5;/* Descriptor for I/O to remote machine. Initialize it to -1 so that mm_open knows that we don't have a file open when the program starts. */int mm_desc = -1;/* stream which is fdopen'd from mm_desc. Only valid when mm_desc != -1. */FILE *mm_stream;/* Called when SIGALRM signal sent due to alarm() timeout. */#ifndef HAVE_TERMIO#ifndef __STDC__# ifndef volatile# define volatile /**/# endif#endifvolatile int n_alarms;static voidmm_timer (){#if 0 if (kiodebug) printf ("mm_timer called\n");#endif n_alarms++;}#endif /* HAVE_TERMIO *//* malloc'd name of the program on the remote system. */static char *prog_name = NULL;/* Number of SIGTRAPs we need to simulate. That is, the next NEED_ARTIFICIAL_TRAP calls to mm_wait should just return SIGTRAP without actually waiting for anything. *//**************************************************** REMOTE_CREATE_INFERIOR *//* This is called not only when we first attach, but also when the user types "run" after having attached. */static voidmm_create_inferior (execfile, args, env) char *execfile; char *args; char **env;{#define MAX_TOKENS 25#define BUFFER_SIZE 256 int token_count; int result; char *token[MAX_TOKENS]; char cmd_line[BUFFER_SIZE]; if (args && *args) error ("Can't pass arguments to remote mm process (yet)."); if (execfile == 0 /* || exec_bfd == 0 */ ) error ("No exec file specified"); if (!mm_stream) { printf("Minimon not open yet.\n"); return; } /* On ultra3 (NYU) we assume the kernel is already running so there is no file to download. FIXME: Fixed required here -> load your program, possibly with mm_load(). */ printf_filtered ("\n\Assuming you are at NYU debuging a kernel, i.e., no need to download.\n\n"); /* We will get a task spawn event immediately. */ init_wait_for_inferior (); clear_proceed_status (); stop_soon_quietly = 1; proceed(-1,-1,0); normal_stop ();}/**************************************************** REMOTE_MOURN_INFERIOR */static voidmm_mourn(){ pop_target (); /* Pop back to no-child state */ generic_mourn_inferior ();}/********************************************************************** damn_b*//* Translate baud rates from integers to damn B_codes. Unix should have outgrown this crap years ago, but even POSIX wouldn't buck it. */#ifndef B19200#define B19200 EXTA#endif#ifndef B38400#define B38400 EXTB#endifstatic struct {int rate, damn_b;} baudtab[] = { {0, B0}, {50, B50}, {75, B75}, {110, B110}, {134, B134}, {150, B150}, {200, B200}, {300, B300}, {600, B600}, {1200, B1200}, {1800, B1800}, {2400, B2400}, {4800, B4800}, {9600, B9600}, {19200, B19200}, {38400, B38400}, {-1, -1},};static int damn_b (rate) int rate;{ int i; for (i = 0; baudtab[i].rate != -1; i++) if (rate == baudtab[i].rate) return baudtab[i].damn_b; return B38400; /* Random */}/***************************************************************** REMOTE_OPEN** Open a connection to remote minimon. NAME is the filename used for communication, then a space, then the baud rate. 'target adapt /dev/ttya 9600 [prognam]' for example. */static char *dev_name;int baudrate = 9600;static voidmm_open (name, from_tty) char *name; int from_tty;{ TERMINAL sg; unsigned int prl; char *p; /* Find the first whitespace character, it separates dev_name from prog_name. */ for (p = name; p && *p && !isspace (*p); p++) ; if (p == 0 || *p == '\0')erroid: error ("Usage : <command> <serial-device> <baud-rate> [progname]"); dev_name = (char*)malloc (p - name + 1); strncpy (dev_name, name, p - name); dev_name[p - name] = '\0'; /* Skip over the whitespace after dev_name */ for (; isspace (*p); p++) /*EMPTY*/; if (1 != sscanf (p, "%d ", &baudrate)) goto erroid; /* Skip the number and then the spaces */ for (; isdigit (*p); p++) /*EMPTY*/; for (; isspace (*p); p++) /*EMPTY*/; if (prog_name != NULL) free (prog_name); prog_name = savestring (p, strlen (p)); if (mm_desc >= 0) close (mm_desc); mm_desc = open (dev_name, O_RDWR); if (mm_desc < 0) perror_with_name (dev_name); ioctl (mm_desc, TIOCGETP, &sg);#ifdef HAVE_TERMIO sg.c_cc[VMIN] = 0; /* read with timeout. */ sg.c_cc[VTIME] = timeout * 10; sg.c_lflag &= ~(ICANON | ECHO); sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);#else sg.sg_ispeed = damn_b (baudrate); sg.sg_ospeed = damn_b (baudrate); sg.sg_flags |= RAW; sg.sg_flags |= ANYP; sg.sg_flags &= ~ECHO;#endif ioctl (mm_desc, TIOCSETP, &sg); mm_stream = fdopen (mm_desc, "r+"); push_target (&mm_ops);#ifndef HAVE_TERMIO#ifndef NO_SIGINTERRUPT /* Cause SIGALRM's to make reads fail with EINTR instead of resuming the read. */ if (siginterrupt (SIGALRM, 1) != 0) perror ("mm_open: error in siginterrupt");#endif /* Set up read timeout timer. */ if ((void (*)) signal (SIGALRM, mm_timer) == (void (*)) -1) perror ("mm_open: error in signal");#endif#if defined (LOG_FILE) log_file = fopen (LOG_FILE, "w"); if (log_file == NULL) perror_with_name (LOG_FILE);#endif /* ** Initialize target configuration structure (global) */ DRAIN_INPUT(); out_msg_buf->config_req_msg.code = CONFIG_REQ; out_msg_buf->config_req_msg.length = 4*0; msg_send_serial(out_msg_buf); /* send config request message */ expect_msg(CONFIG,in_msg_buf,1); /* Determine the processor revision level */ /* FIXME: this code is the same as in remote-adapt.c */ prl = (unsigned int)read_register(CFG_REGNUM) >> 24; if (prl == 0x03) { processor_type = TYPE_A29000; } else if ((prl&0xf0) == 0x40) { /* 29030 = 0x4* */ processor_type = TYPE_A29030; fprintf_filtered(stderr,"WARNING: debugging of A29030 not tested.\n"); } else if ((prl&0xf0) == 0x20) { /* 29050 = 0x2* */ processor_type = TYPE_A29050; fprintf_filtered(stderr,"WARNING: debugging of A29050 not tested.\n"); } else { processor_type = TYPE_UNKNOWN; fprintf_filtered(stderr,"WARNING: processor type unknown.\n"); } /* Print out some stuff, letting the user now what's going on */ printf_filtered("Remote debugging on an %s connect to MiniMon via %s.\n", processor_name[processor_type],dev_name); /* FIXME: can this restriction be removed? */ printf_filtered("Remote debugging using virtual addresses works only\n"); printf_filtered("\twhen virtual addresses map 1:1 to physical addresses.\n"); if (processor_type != TYPE_A29050) { fprintf_filtered(stderr, "Freeze-mode debugging not available, and can only be done on an A29050.\n"); } target_config.code = CONFIG; target_config.length = 0; target_config.processor_id = in_msg_buf->config_msg.processor_id; target_config.version = in_msg_buf->config_msg.version; target_config.I_mem_start = in_msg_buf->config_msg.I_mem_start; target_config.I_mem_size = in_msg_buf->config_msg.I_mem_size; target_config.D_mem_start = in_msg_buf->config_msg.D_mem_start; target_config.D_mem_size = in_msg_buf->config_msg.D_mem_size; target_config.ROM_start = in_msg_buf->config_msg.ROM_start; target_config.ROM_size = in_msg_buf->config_msg.ROM_size; target_config.max_msg_size = in_msg_buf->config_msg.max_msg_size; target_config.max_bkpts = in_msg_buf->config_msg.max_bkpts; target_config.coprocessor = in_msg_buf->config_msg.coprocessor; target_config.reserved = in_msg_buf->config_msg.reserved; if (from_tty) { printf("Connected to MiniMON :\n"); printf(" Debugcore version %d.%d\n", 0x0f & (target_config.version >> 4), 0x0f & (target_config.version ) ); printf(" Configuration version %d.%d\n", 0x0f & (target_config.version >> 12), 0x0f & (target_config.version >> 8) ); printf(" Message system version %d.%d\n", 0x0f & (target_config.version >> 20), 0x0f & (target_config.version >> 16) ); printf(" Communication driver version %d.%d\n", 0x0f & (target_config.version >> 28), 0x0f & (target_config.version >> 24) ); } /* Leave the target running... * The above message stopped the target in the dbg core (MiniMon), * so restart the target out of MiniMon, */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -