GDB (API)
/home/stan/gdb/src/gdb/dbug-rom.c
Go to the documentation of this file.
00001 /* Remote debugging interface to dBUG ROM monitor for GDB, the GNU debugger.
00002    Copyright (C) 1996-2013 Free Software Foundation, Inc.
00003 
00004    Written by Stan Shebs of Cygnus Support.
00005 
00006    This file is part of GDB.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 3 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00020 
00021 /* dBUG is a monitor supplied on various Motorola boards, including
00022    m68k, ColdFire, and PowerPC-based designs.  The code here assumes
00023    the ColdFire, and (as of 9/25/96) has only been tested with a
00024    ColdFire IDP board.  */
00025 
00026 #include "defs.h"
00027 #include "gdbcore.h"
00028 #include "target.h"
00029 #include "monitor.h"
00030 #include "serial.h"
00031 #include "regcache.h"
00032 
00033 #include "m68k-tdep.h"
00034 
00035 static void dbug_open (char *args, int from_tty);
00036 
00037 static void
00038 dbug_supply_register (struct regcache *regcache, char *regname,
00039                       int regnamelen, char *val, int vallen)
00040 {
00041   int regno;
00042   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00043 
00044   if (regnamelen != 2)
00045     return;
00046 
00047   switch (regname[0])
00048     {
00049     case 'S':
00050       if (regname[1] != 'R')
00051         return;
00052       regno = gdbarch_ps_regnum (gdbarch);
00053       break;
00054     case 'P':
00055       if (regname[1] != 'C')
00056         return;
00057       regno = gdbarch_pc_regnum (gdbarch);
00058       break;
00059     case 'D':
00060       if (regname[1] < '0' || regname[1] > '7')
00061         return;
00062       regno = regname[1] - '0' + M68K_D0_REGNUM;
00063       break;
00064     case 'A':
00065       if (regname[1] < '0' || regname[1] > '7')
00066         return;
00067       regno = regname[1] - '0' + M68K_A0_REGNUM;
00068       break;
00069     default:
00070       return;
00071     }
00072 
00073   monitor_supply_register (regcache, regno, val);
00074 }
00075 
00076 /* This array of registers needs to match the indexes used by GDB.
00077    The whole reason this exists is because the various ROM monitors
00078    use different names than GDB does, and don't support all the
00079    registers either.  So, typing "info reg sp" becomes an "A7".  */
00080 
00081 static const char *
00082 dbug_regname (int index)
00083 {
00084   static char *regnames[] =
00085   {
00086     "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
00087     "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
00088     "SR", "PC"
00089     /* no float registers */
00090   };
00091 
00092   if (index >= ARRAY_SIZE (regnames) || index < 0)
00093     return NULL;
00094   else
00095     return regnames[index];
00096 
00097 }
00098 
00099 static struct target_ops dbug_ops;
00100 static struct monitor_ops dbug_cmds;
00101 
00102 static char *dbug_inits[] =
00103 {"\r", NULL};
00104 
00105 
00106 static void
00107 init_dbug_cmds (void)
00108 {
00109   dbug_cmds.flags = MO_CLR_BREAK_USES_ADDR
00110     | MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR;
00111   dbug_cmds.init = dbug_inits;  /* Init strings */
00112   dbug_cmds.cont = "go\r";      /* continue command */
00113   dbug_cmds.step = "trace\r";   /* single step */
00114   dbug_cmds.stop = NULL;        /* interrupt command */
00115   dbug_cmds.set_break = "br %x\r";      /* set a breakpoint */
00116   dbug_cmds.clr_break = "br -r %x\r";   /* clear a breakpoint */
00117   dbug_cmds.clr_all_break = "br -r\r";  /* clear all breakpoints */
00118   dbug_cmds.fill = "bf.b %x %x %x\r";   /* fill (start end val) */
00119   dbug_cmds.setmem.cmdb = "mm.b %x %x\r";       /* setmem.cmdb (addr, value) */
00120   dbug_cmds.setmem.cmdw = "mm.w %x %x\r";       /* setmem.cmdw (addr, value) */
00121   dbug_cmds.setmem.cmdl = "mm.l %x %x\r";       /* setmem.cmdl (addr, value) */
00122   dbug_cmds.setmem.cmdll = NULL;        /* setmem.cmdll (addr, value) */
00123   dbug_cmds.setmem.resp_delim = NULL;   /* setmem.resp_delim */
00124   dbug_cmds.setmem.term = NULL; /* setmem.term */
00125   dbug_cmds.setmem.term_cmd = NULL;     /* setmem.term_cmd */
00126   dbug_cmds.getmem.cmdb = "md.b %x %x\r";       /* getmem.cmdb (addr, addr2) */
00127   dbug_cmds.getmem.cmdw = "md.w %x %x\r";       /* getmem.cmdw (addr, addr2) */
00128   dbug_cmds.getmem.cmdl = "md.l %x %x\r";       /* getmem.cmdl (addr, addr2) */
00129   dbug_cmds.getmem.cmdll = NULL;        /* getmem.cmdll (addr, addr2) */
00130   dbug_cmds.getmem.resp_delim = ":";    /* getmem.resp_delim */
00131   dbug_cmds.getmem.term = NULL; /* getmem.term */
00132   dbug_cmds.getmem.term_cmd = NULL;     /* getmem.term_cmd */
00133   dbug_cmds.setreg.cmd = "rm %s %x\r";  /* setreg.cmd (name, value) */
00134   dbug_cmds.setreg.resp_delim = NULL;   /* setreg.resp_delim */
00135   dbug_cmds.setreg.term = NULL; /* setreg.term */
00136   dbug_cmds.setreg.term_cmd = NULL;     /* setreg.term_cmd */
00137   dbug_cmds.getreg.cmd = "rd %s\r";     /* getreg.cmd (name) */
00138   dbug_cmds.getreg.resp_delim = ":";    /* getreg.resp_delim */
00139   dbug_cmds.getreg.term = NULL; /* getreg.term */
00140   dbug_cmds.getreg.term_cmd = NULL;     /* getreg.term_cmd */
00141   dbug_cmds.dump_registers = "rd\r";    /* dump_registers */
00142                                         /* register_pattern */
00143   dbug_cmds.register_pattern = "\\(\\w+\\) +:\\([0-9a-fA-F]+\\b\\)";
00144   dbug_cmds.supply_register = dbug_supply_register;
00145   dbug_cmds.load = "dl\r";      /* download command */
00146   dbug_cmds.loadresp = "\n";    /* load response */
00147   dbug_cmds.prompt = "dBUG>";   /* monitor command prompt */
00148   dbug_cmds.line_term = "\r";   /* end-of-line terminator */
00149   dbug_cmds.cmd_end = NULL;     /* optional command terminator */
00150   dbug_cmds.target = &dbug_ops; /* target operations */
00151   dbug_cmds.stopbits = SERIAL_1_STOPBITS;       /* number of stop bits */
00152   dbug_cmds.regnames = NULL;    /* registers names */
00153   dbug_cmds.regname = dbug_regname;
00154   dbug_cmds.magic = MONITOR_OPS_MAGIC;  /* magic */
00155 }                               /* init_debug_ops */
00156 
00157 static void
00158 dbug_open (char *args, int from_tty)
00159 {
00160   monitor_open (args, &dbug_cmds, from_tty);
00161 }
00162 
00163 extern initialize_file_ftype _initialize_dbug_rom; /* -Wmissing-prototypes */
00164 
00165 void
00166 _initialize_dbug_rom (void)
00167 {
00168   init_dbug_cmds ();
00169   init_monitor_ops (&dbug_ops);
00170 
00171   dbug_ops.to_shortname = "dbug";
00172   dbug_ops.to_longname = "dBUG monitor";
00173   dbug_ops.to_doc = "Debug via the dBUG monitor.\n\
00174 Specify the serial device it is connected to (e.g. /dev/ttya).";
00175   dbug_ops.to_open = dbug_open;
00176 
00177   add_target (&dbug_ops);
00178 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines