xref: /openbsd-src/gnu/usr.bin/binutils/gdb/remote-est.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1e93f7393Sniklas /* Remote debugging interface for EST-300 ICE, for GDB
2b725ae77Skettenis    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
3b725ae77Skettenis    Free Software Foundation, Inc.
4e93f7393Sniklas    Contributed by Cygnus Support.
5e93f7393Sniklas 
6e93f7393Sniklas    Written by Steve Chamberlain for Cygnus Support.
7e93f7393Sniklas    Re-written by Stu Grossman of Cygnus Support
8e93f7393Sniklas 
9e93f7393Sniklas    This file is part of GDB.
10e93f7393Sniklas 
11e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
12e93f7393Sniklas    it under the terms of the GNU General Public License as published by
13e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
14e93f7393Sniklas    (at your option) any later version.
15e93f7393Sniklas 
16e93f7393Sniklas    This program is distributed in the hope that it will be useful,
17e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
18e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19e93f7393Sniklas    GNU General Public License for more details.
20e93f7393Sniklas 
21e93f7393Sniklas    You should have received a copy of the GNU General Public License
22e93f7393Sniklas    along with this program; if not, write to the Free Software
23b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
24b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
25e93f7393Sniklas 
26e93f7393Sniklas #include "defs.h"
27e93f7393Sniklas #include "gdbcore.h"
28e93f7393Sniklas #include "target.h"
29e93f7393Sniklas #include "monitor.h"
30e93f7393Sniklas #include "serial.h"
31b725ae77Skettenis #include "regcache.h"
32e93f7393Sniklas 
33b725ae77Skettenis #include "m68k-tdep.h"
34b725ae77Skettenis 
35b725ae77Skettenis static void est_open (char *args, int from_tty);
36e93f7393Sniklas 
37e93f7393Sniklas static void
est_supply_register(char * regname,int regnamelen,char * val,int vallen)38b725ae77Skettenis est_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 a "r30".
79e93f7393Sniklas  */
80e93f7393Sniklas 
81b725ae77Skettenis static const char *
est_regname(int index)82b725ae77Skettenis est_regname (int index)
83b725ae77Skettenis {
84b725ae77Skettenis 
85b725ae77Skettenis   static char *regnames[] =
86e93f7393Sniklas   {
87e93f7393Sniklas     "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
88e93f7393Sniklas     "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
89e93f7393Sniklas     "SR", "PC",
90e93f7393Sniklas   };
91e93f7393Sniklas 
92b725ae77Skettenis 
93b725ae77Skettenis   if ((index >= (sizeof (regnames) /  sizeof (regnames[0])))
94b725ae77Skettenis        || (index < 0) || (index >= NUM_REGS))
95b725ae77Skettenis     return NULL;
96b725ae77Skettenis   else
97b725ae77Skettenis     return regnames[index];
98b725ae77Skettenis }
99b725ae77Skettenis 
100e93f7393Sniklas /*
101e93f7393Sniklas  * Define the monitor command strings. Since these are passed directly
102e93f7393Sniklas  * through to a printf style function, we need can include formatting
103e93f7393Sniklas  * strings. We also need a CR or LF on the end.
104e93f7393Sniklas  */
105e93f7393Sniklas 
106e93f7393Sniklas static struct target_ops est_ops;
107e93f7393Sniklas 
108b725ae77Skettenis static char *est_inits[] =
109b725ae77Skettenis {"he\r",			/* Resets the prompt, and clears repeated cmds */
110e93f7393Sniklas  NULL};
111e93f7393Sniklas 
112b725ae77Skettenis static struct monitor_ops est_cmds;
113e93f7393Sniklas 
114e93f7393Sniklas static void
init_est_cmds(void)115b725ae77Skettenis init_est_cmds (void)
116b725ae77Skettenis {
117b725ae77Skettenis   est_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT |
118b725ae77Skettenis     MO_SREC_ACK | MO_SREC_ACK_PLUS;
119b725ae77Skettenis   est_cmds.init = est_inits;	/* Init strings */
120b725ae77Skettenis   est_cmds.cont = "go\r";	/* continue command */
121b725ae77Skettenis   est_cmds.step = "sidr\r";	/* single step */
122b725ae77Skettenis   est_cmds.stop = "\003";	/* ^C interrupts the program */
123b725ae77Skettenis   est_cmds.set_break = "sb %x\r";	/* set a breakpoint */
124b725ae77Skettenis   est_cmds.clr_break = "rb %x\r";	/* clear a breakpoint */
125b725ae77Skettenis   est_cmds.clr_all_break = "rb\r";	/* clear all breakpoints */
126b725ae77Skettenis   est_cmds.fill = "bfb %x %x %x\r";	/* fill (start end val) */
127b725ae77Skettenis   est_cmds.setmem.cmdb = "smb %x %x\r";		/* setmem.cmdb (addr, value) */
128b725ae77Skettenis   est_cmds.setmem.cmdw = "smw %x %x\r";		/* setmem.cmdw (addr, value) */
129b725ae77Skettenis   est_cmds.setmem.cmdl = "sml %x %x\r";		/* setmem.cmdl (addr, value) */
130b725ae77Skettenis   est_cmds.setmem.cmdll = NULL;	/* setmem.cmdll (addr, value) */
131b725ae77Skettenis   est_cmds.setmem.resp_delim = NULL;	/* setreg.resp_delim */
132b725ae77Skettenis   est_cmds.setmem.term = NULL;	/* setreg.term */
133b725ae77Skettenis   est_cmds.setmem.term_cmd = NULL;	/* setreg.term_cmd */
134b725ae77Skettenis   est_cmds.getmem.cmdb = "dmb %x %x\r";		/* getmem.cmdb (addr, len) */
135b725ae77Skettenis   est_cmds.getmem.cmdw = "dmw %x %x\r";		/* getmem.cmdw (addr, len) */
136b725ae77Skettenis   est_cmds.getmem.cmdl = "dml %x %x\r";		/* getmem.cmdl (addr, len) */
137b725ae77Skettenis   est_cmds.getmem.cmdll = NULL;	/* getmem.cmdll (addr, len) */
138b725ae77Skettenis   est_cmds.getmem.resp_delim = ": ";	/* getmem.resp_delim */
139b725ae77Skettenis   est_cmds.getmem.term = NULL;	/* getmem.term */
140b725ae77Skettenis   est_cmds.getmem.term_cmd = NULL;	/* getmem.term_cmd */
141b725ae77Skettenis   est_cmds.setreg.cmd = "sr %s %x\r";	/* setreg.cmd (name, value) */
142b725ae77Skettenis   est_cmds.setreg.resp_delim = NULL;	/* setreg.resp_delim */
143b725ae77Skettenis   est_cmds.setreg.term = NULL;	/* setreg.term */
144b725ae77Skettenis   est_cmds.setreg.term_cmd = NULL;	/* setreg.term_cmd */
145b725ae77Skettenis   est_cmds.getreg.cmd = "dr %s\r";	/* getreg.cmd (name) */
146b725ae77Skettenis   est_cmds.getreg.resp_delim = " = ";	/* getreg.resp_delim */
147b725ae77Skettenis   est_cmds.getreg.term = NULL;	/* getreg.term */
148b725ae77Skettenis   est_cmds.getreg.term_cmd = NULL;	/* getreg.term_cmd */
149b725ae77Skettenis   est_cmds.dump_registers = "dr\r";	/* dump_registers */
150b725ae77Skettenis   est_cmds.register_pattern = "\\(\\w+\\) = \\([0-9a-fA-F]+\\)";	/* register_pattern */
151*63addd46Skettenis   est_cmds.supply_register = est_supply_register;
152b725ae77Skettenis   est_cmds.load_routine = NULL;	/* load_routine (defaults to SRECs) */
153b725ae77Skettenis   est_cmds.load = "dl\r";	/* download command */
154b725ae77Skettenis   est_cmds.loadresp = "+";	/* load response */
155b725ae77Skettenis   est_cmds.prompt = ">BKM>";	/* monitor command prompt */
156b725ae77Skettenis   est_cmds.line_term = "\r";	/* end-of-line terminator */
157b725ae77Skettenis   est_cmds.cmd_end = NULL;	/* optional command terminator */
158b725ae77Skettenis   est_cmds.target = &est_ops;	/* target operations */
159b725ae77Skettenis   est_cmds.stopbits = SERIAL_1_STOPBITS;	/* number of stop bits */
160b725ae77Skettenis   est_cmds.regnames = NULL;
161b725ae77Skettenis   est_cmds.regname = est_regname; /*register names*/
162b725ae77Skettenis   est_cmds.magic = MONITOR_OPS_MAGIC;	/* magic */
163b725ae77Skettenis }				/* init_est_cmds */
164b725ae77Skettenis 
165b725ae77Skettenis static void
est_open(char * args,int from_tty)166b725ae77Skettenis est_open (char *args, int from_tty)
167e93f7393Sniklas {
168e93f7393Sniklas   monitor_open (args, &est_cmds, from_tty);
169e93f7393Sniklas }
170e93f7393Sniklas 
171b725ae77Skettenis extern initialize_file_ftype _initialize_est; /* -Wmissing-prototypes */
172b725ae77Skettenis 
173e93f7393Sniklas void
_initialize_est(void)174b725ae77Skettenis _initialize_est (void)
175e93f7393Sniklas {
176b725ae77Skettenis   init_est_cmds ();
177e93f7393Sniklas   init_monitor_ops (&est_ops);
178e93f7393Sniklas 
179e93f7393Sniklas   est_ops.to_shortname = "est";
180e93f7393Sniklas   est_ops.to_longname = "EST background debug monitor";
181e93f7393Sniklas   est_ops.to_doc = "Debug via the EST BDM.\n\
182e93f7393Sniklas Specify the serial device it is connected to (e.g. /dev/ttya).";
183e93f7393Sniklas   est_ops.to_open = est_open;
184e93f7393Sniklas 
185e93f7393Sniklas   add_target (&est_ops);
186e93f7393Sniklas }
187