GDB (API)
/home/stan/gdb/src/gdb/dink32-rom.c
Go to the documentation of this file.
00001 /* Remote debugging interface for DINK32 (PowerPC) ROM monitor for
00002    GDB, the GNU debugger.
00003    Copyright (C) 1997-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "gdbcore.h"
00022 #include "target.h"
00023 #include "monitor.h"
00024 #include "serial.h"
00025 #include "symfile.h" /* For generic_load() */
00026 #include "inferior.h"
00027 #include "regcache.h"
00028 
00029 static void dink32_open (char *args, int from_tty);
00030 
00031 static void
00032 dink32_supply_register (struct regcache *regcache, char *regname,
00033                         int regnamelen, char *val, int vallen)
00034 {
00035   int regno = 0;
00036 
00037   if (regnamelen < 2 || regnamelen > 4)
00038     return;
00039 
00040   switch (regname[0])
00041     {
00042     case 'R':
00043       if (regname[1] < '0' || regname[1] > '9')
00044         return;
00045       if (regnamelen == 2)
00046         regno = regname[1] - '0';
00047       else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9')
00048         regno = (regname[1] - '0') * 10 + (regname[2] - '0');
00049       else
00050         return;
00051       break;
00052     case 'F':
00053       if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9')
00054         return;
00055       if (regnamelen == 3)
00056         regno = 32 + regname[2] - '0';
00057       else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9')
00058         regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0');
00059       else
00060         return;
00061       break;
00062     case 'I':
00063       if (regnamelen != 2 || regname[1] != 'P')
00064         return;
00065       regno = 64;
00066       break;
00067     case 'M':
00068       if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R')
00069         return;
00070       regno = 65;
00071       break;
00072     case 'C':
00073       if (regnamelen != 2 || regname[1] != 'R')
00074         return;
00075       regno = 66;
00076       break;
00077     case 'S':
00078       if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R')
00079         return;
00080       else if (regname[3] == '8')
00081         regno = 67;
00082       else if (regname[3] == '9')
00083         regno = 68;
00084       else if (regname[3] == '1')
00085         regno = 69;
00086       else if (regname[3] == '0')
00087         regno = 70;
00088       else
00089         return;
00090       break;
00091     default:
00092       return;
00093     }
00094 
00095   monitor_supply_register (regcache, regno, val);
00096 }
00097 
00098 /* This array of registers needs to match the indexes used by GDB.
00099    The whole reason this exists is because the various ROM monitors
00100    use different names than GDB does, and don't support all the
00101    registers either.  */
00102 
00103 static char *dink32_regnames[] =
00104 {
00105   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
00106   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
00107   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
00108   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
00109 
00110   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
00111   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
00112   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
00113   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
00114 
00115   "srr0", "msr", "cr", "lr", "ctr", "xer", "xer"
00116 };
00117 
00118 static struct target_ops dink32_ops;
00119 
00120 static char *dink32_inits[] =
00121 {"\r", NULL};
00122 
00123 static struct monitor_ops dink32_cmds;
00124 
00125 static void
00126 dink32_open (char *args, int from_tty)
00127 {
00128   monitor_open (args, &dink32_cmds, from_tty);
00129 }
00130 
00131 extern initialize_file_ftype _initialize_dink32_rom; /* -Wmissing-prototypes */
00132 
00133 void
00134 _initialize_dink32_rom (void)
00135 {
00136   dink32_cmds.flags = MO_HEX_PREFIX | MO_GETMEM_NEEDS_RANGE
00137     | MO_FILL_USES_ADDR | MO_HANDLE_NL | MO_32_REGS_PAIRED
00138     | MO_SETREG_INTERACTIVE | MO_SETMEM_INTERACTIVE
00139     | MO_GETMEM_16_BOUNDARY | MO_CLR_BREAK_1_BASED | MO_SREC_ACK
00140     | MO_SREC_ACK_ROTATE;
00141   dink32_cmds.init = dink32_inits;
00142   dink32_cmds.cont = "go +\r";
00143   dink32_cmds.step = "tr +\r";
00144   dink32_cmds.set_break = "bp 0x%x\r";
00145   dink32_cmds.clr_break = "bp %d\r";
00146 #if 0                   /* Would need to follow strict alignment rules..  */
00147   dink32_cmds.fill = "mf %x %x %x\r";
00148 #endif
00149   dink32_cmds.setmem.cmdb = "mm -b %x\r";
00150   dink32_cmds.setmem.cmdw = "mm -w %x\r";
00151   dink32_cmds.setmem.cmdl = "mm %x\r";
00152   dink32_cmds.setmem.term = " ?  ";
00153   dink32_cmds.getmem.cmdb = "md %x\r";
00154   dink32_cmds.getmem.resp_delim = "        ";
00155   dink32_cmds.setreg.cmd = "rm %s\r";
00156   dink32_cmds.setreg.term = " ?  ";
00157   dink32_cmds.getreg.cmd = "rd %s\r";
00158   dink32_cmds.getreg.resp_delim = ": ";
00159   dink32_cmds.dump_registers = "rd r\r";
00160   dink32_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)";
00161   dink32_cmds.supply_register = dink32_supply_register;
00162   /* S-record download, via "keyboard port".  */
00163   dink32_cmds.load = "dl -k\r";
00164   dink32_cmds.loadresp = "Set Input Port : set to Keyboard Port\r";
00165   dink32_cmds.prompt = "DINK32_603 >>";
00166   dink32_cmds.line_term = "\r";
00167   dink32_cmds.target = &dink32_ops;
00168   dink32_cmds.stopbits = SERIAL_1_STOPBITS;
00169   dink32_cmds.regnames = dink32_regnames;
00170   dink32_cmds.magic = MONITOR_OPS_MAGIC;
00171 
00172   init_monitor_ops (&dink32_ops);
00173 
00174   dink32_ops.to_shortname = "dink32";
00175   dink32_ops.to_longname = "DINK32 monitor";
00176   dink32_ops.to_doc = "Debug using the DINK32 monitor.\n\
00177 Specify the serial device it is connected to (e.g. /dev/ttya).";
00178   dink32_ops.to_open = dink32_open;
00179 
00180   add_target (&dink32_ops);
00181 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines