xref: /openbsd-src/gnu/usr.bin/binutils/gdb/abug-rom.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1e93f7393Sniklas /* Remote debugging interface for ABug Rom monitor for GDB, the GNU debugger.
2b725ae77Skettenis    Copyright 1995, 1996, 1998, 1999, 2000, 2001
3b725ae77Skettenis    Free Software Foundation, Inc.
4e93f7393Sniklas 
5e93f7393Sniklas    Written by Rob Savoye of Cygnus Support
6e93f7393Sniklas 
7e93f7393Sniklas    This file is part of GDB.
8e93f7393Sniklas 
9e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
10e93f7393Sniklas    it under the terms of the GNU General Public License as published by
11e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
12e93f7393Sniklas    (at your option) any later version.
13e93f7393Sniklas 
14e93f7393Sniklas    This program is distributed in the hope that it will be useful,
15e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
16e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17e93f7393Sniklas    GNU General Public License for more details.
18e93f7393Sniklas 
19e93f7393Sniklas    You should have received a copy of the GNU General Public License
20e93f7393Sniklas    along with this program; if not, write to the Free Software
21b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
22b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
23e93f7393Sniklas 
24e93f7393Sniklas #include "defs.h"
25e93f7393Sniklas #include "gdbcore.h"
26e93f7393Sniklas #include "target.h"
27e93f7393Sniklas #include "monitor.h"
28e93f7393Sniklas #include "serial.h"
29b725ae77Skettenis #include "regcache.h"
30e93f7393Sniklas 
31b725ae77Skettenis #include "m68k-tdep.h"
32b725ae77Skettenis 
33b725ae77Skettenis /* Prototypes for local functions. */
34b725ae77Skettenis 
35b725ae77Skettenis static void abug_open (char *args, int from_tty);
36e93f7393Sniklas 
37e93f7393Sniklas static void
abug_supply_register(char * regname,int regnamelen,char * val,int vallen)38b725ae77Skettenis abug_supply_register (char *regname, int regnamelen, char *val, int vallen)
39e93f7393Sniklas {
40e93f7393Sniklas   int regno;
41e93f7393Sniklas 
42e93f7393Sniklas   if (regnamelen != 2)
43e93f7393Sniklas     return;
44e93f7393Sniklas 
45e93f7393Sniklas   switch (regname[0])
46e93f7393Sniklas     {
47e93f7393Sniklas     case 'S':
48e93f7393Sniklas       if (regname[1] != 'R')
49e93f7393Sniklas 	return;
50e93f7393Sniklas       regno = PS_REGNUM;
51e93f7393Sniklas       break;
52e93f7393Sniklas     case 'P':
53e93f7393Sniklas       if (regname[1] != 'C')
54e93f7393Sniklas 	return;
55e93f7393Sniklas       regno = PC_REGNUM;
56e93f7393Sniklas       break;
57e93f7393Sniklas     case 'D':
58e93f7393Sniklas       if (regname[1] < '0' || regname[1] > '7')
59e93f7393Sniklas 	return;
60b725ae77Skettenis       regno = regname[1] - '0' + M68K_D0_REGNUM;
61e93f7393Sniklas       break;
62e93f7393Sniklas     case 'A':
63e93f7393Sniklas       if (regname[1] < '0' || regname[1] > '7')
64e93f7393Sniklas 	return;
65b725ae77Skettenis       regno = regname[1] - '0' + M68K_A0_REGNUM;
66e93f7393Sniklas       break;
67e93f7393Sniklas     default:
68e93f7393Sniklas       return;
69e93f7393Sniklas     }
70e93f7393Sniklas 
71e93f7393Sniklas   monitor_supply_register (regno, val);
72e93f7393Sniklas }
73e93f7393Sniklas 
74e93f7393Sniklas /*
75e93f7393Sniklas  * This array of registers needs to match the indexes used by GDB. The
76e93f7393Sniklas  * whole reason this exists is because the various ROM monitors use
77e93f7393Sniklas  * different names than GDB does, and don't support all the
78e93f7393Sniklas  * registers either. So, typing "info reg sp" becomes an "A7".
79e93f7393Sniklas  */
80e93f7393Sniklas 
81b725ae77Skettenis static const char *
abug_regname(int index)82b725ae77Skettenis abug_regname (int index)
83b725ae77Skettenis {
84b725ae77Skettenis   static char *regnames[] =
85e93f7393Sniklas   {
86e93f7393Sniklas     "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
87e93f7393Sniklas     "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
88e93f7393Sniklas     "PC",
89e93f7393Sniklas   };
90e93f7393Sniklas 
91b725ae77Skettenis   if ((index >= (sizeof (regnames) / sizeof (regnames[0])))
92b725ae77Skettenis        || (index < 0) || (index >= NUM_REGS))
93b725ae77Skettenis     return NULL;
94b725ae77Skettenis   else
95b725ae77Skettenis     return regnames[index];
96b725ae77Skettenis }
97b725ae77Skettenis 
98e93f7393Sniklas /*
99e93f7393Sniklas  * Define the monitor command strings. Since these are passed directly
100e93f7393Sniklas  * through to a printf style function, we need can include formatting
101e93f7393Sniklas  * strings. We also need a CR or LF on the end.
102e93f7393Sniklas  */
103e93f7393Sniklas 
104e93f7393Sniklas static struct target_ops abug_ops;
105e93f7393Sniklas 
106b725ae77Skettenis static char *abug_inits[] =
107b725ae77Skettenis {"\r", NULL};
108e93f7393Sniklas 
109b725ae77Skettenis static struct monitor_ops abug_cmds;
110b725ae77Skettenis 
111b725ae77Skettenis static void
init_abug_cmds(void)112b725ae77Skettenis init_abug_cmds (void)
113e93f7393Sniklas {
114b725ae77Skettenis   abug_cmds.flags = MO_CLR_BREAK_USES_ADDR;
115b725ae77Skettenis   abug_cmds.init = abug_inits;	/* Init strings */
116b725ae77Skettenis   abug_cmds.cont = "g\r";	/* continue command */
117b725ae77Skettenis   abug_cmds.step = "t\r";	/* single step */
118b725ae77Skettenis   abug_cmds.stop = NULL;	/* interrupt command */
119b725ae77Skettenis   abug_cmds.set_break = "br %x\r";	/* set a breakpoint */
120b725ae77Skettenis   abug_cmds.clr_break = "nobr %x\r";	/* clear a breakpoint */
121b725ae77Skettenis   abug_cmds.clr_all_break = "nobr\r";	/* clear all breakpoints */
122b725ae77Skettenis   abug_cmds.fill = "bf %x:%x %x;b\r";	/* fill (start count val) */
123b725ae77Skettenis   abug_cmds.setmem.cmdb = "ms %x %02x\r";	/* setmem.cmdb (addr, value) */
124b725ae77Skettenis   abug_cmds.setmem.cmdw = "ms %x %04x\r";	/* setmem.cmdw (addr, value) */
125b725ae77Skettenis   abug_cmds.setmem.cmdl = "ms %x %08x\r";	/* setmem.cmdl (addr, value) */
126b725ae77Skettenis   abug_cmds.setmem.cmdll = NULL;	/* setmem.cmdll (addr, value) */
127b725ae77Skettenis   abug_cmds.setmem.resp_delim = NULL;	/* setreg.resp_delim */
128b725ae77Skettenis   abug_cmds.setmem.term = NULL;	/* setreg.term */
129b725ae77Skettenis   abug_cmds.setmem.term_cmd = NULL;	/* setreg.term_cmd */
130b725ae77Skettenis   abug_cmds.getmem.cmdb = "md %x:%x;b\r";	/* getmem.cmdb (addr, len) */
131b725ae77Skettenis   abug_cmds.getmem.cmdw = "md %x:%x;b\r";	/* getmem.cmdw (addr, len) */
132b725ae77Skettenis   abug_cmds.getmem.cmdl = "md %x:%x;b\r";	/* getmem.cmdl (addr, len) */
133b725ae77Skettenis   abug_cmds.getmem.cmdll = NULL;	/* getmem.cmdll (addr, len) */
134b725ae77Skettenis   abug_cmds.getmem.resp_delim = " ";	/* getmem.resp_delim */
135b725ae77Skettenis   abug_cmds.getmem.term = NULL;	/* getmem.term */
136b725ae77Skettenis   abug_cmds.getmem.term_cmd = NULL;	/* getmem.term_cmd */
137b725ae77Skettenis   abug_cmds.setreg.cmd = "rm %s %x\r";	/* setreg.cmd (name, value) */
138b725ae77Skettenis   abug_cmds.setreg.resp_delim = "=";	/* setreg.resp_delim */
139b725ae77Skettenis   abug_cmds.setreg.term = "? ";	/* setreg.term */
140b725ae77Skettenis   abug_cmds.setreg.term_cmd = ".\r";	/* setreg.term_cmd */
141b725ae77Skettenis   abug_cmds.getreg.cmd = "rm %s\r";	/* getreg.cmd (name) */
142b725ae77Skettenis   abug_cmds.getreg.resp_delim = "=";	/* getreg.resp_delim */
143b725ae77Skettenis   abug_cmds.getreg.term = "? ";	/* getreg.term */
144b725ae77Skettenis   abug_cmds.getreg.term_cmd = ".\r";	/* getreg.term_cmd */
145b725ae77Skettenis   abug_cmds.dump_registers = "rd\r";	/* dump_registers */
146b725ae77Skettenis   abug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)";	/* register_pattern */
147*63addd46Skettenis   abug_cmds.supply_register = abug_supply_register;
148b725ae77Skettenis   abug_cmds.load_routine = NULL;	/* load_routine (defaults to SRECs) */
149b725ae77Skettenis   abug_cmds.load = "lo 0\r";	/* download command */
150b725ae77Skettenis   abug_cmds.loadresp = "\n";	/* load response */
151b725ae77Skettenis   abug_cmds.prompt = "135Bug>";	/* monitor command prompt */
152b725ae77Skettenis   abug_cmds.line_term = "\r";	/* end-of-line terminator */
153b725ae77Skettenis   abug_cmds.cmd_end = NULL;	/* optional command terminator */
154b725ae77Skettenis   abug_cmds.target = &abug_ops;	/* target operations */
155b725ae77Skettenis   abug_cmds.stopbits = SERIAL_1_STOPBITS;	/* number of stop bits */
156b725ae77Skettenis   abug_cmds.regnames = NULL;	/* registers names */
157b725ae77Skettenis   abug_cmds.regname = abug_regname;
158b725ae77Skettenis   abug_cmds.magic = MONITOR_OPS_MAGIC;	/* magic */
159e93f7393Sniklas };
160e93f7393Sniklas 
161e93f7393Sniklas static void
abug_open(char * args,int from_tty)162b725ae77Skettenis abug_open (char *args, int from_tty)
163e93f7393Sniklas {
164e93f7393Sniklas   monitor_open (args, &abug_cmds, from_tty);
165e93f7393Sniklas }
166e93f7393Sniklas 
167b725ae77Skettenis extern initialize_file_ftype _initialize_abug_rom; /* -Wmissing-prototypes */
168b725ae77Skettenis 
169e93f7393Sniklas void
_initialize_abug_rom(void)170b725ae77Skettenis _initialize_abug_rom (void)
171e93f7393Sniklas {
172b725ae77Skettenis   init_abug_cmds ();
173e93f7393Sniklas   init_monitor_ops (&abug_ops);
174e93f7393Sniklas 
175e93f7393Sniklas   abug_ops.to_shortname = "abug";
176e93f7393Sniklas   abug_ops.to_longname = "ABug monitor";
177e93f7393Sniklas   abug_ops.to_doc = "Debug via the ABug monitor.\n\
178e93f7393Sniklas Specify the serial device it is connected to (e.g. /dev/ttya).";
179e93f7393Sniklas   abug_ops.to_open = abug_open;
180e93f7393Sniklas 
181e93f7393Sniklas   add_target (&abug_ops);
182e93f7393Sniklas }
183