⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remote-mm.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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 + -