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