import gdb-19990422 snapshot
[deliverable/binutils-gdb.git] / gdb / sh3-rom.c
CommitLineData
c906108c
SS
1/* Remote target glue for the Hitachi SH-3 ROM monitor.
2 Copyright 1995, 1996 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20#include "defs.h"
21#include "gdbcore.h"
22#include "target.h"
23#include "monitor.h"
24#include "serial.h"
25#include "srec.h"
26
27static serial_t parallel;
28static int parallel_in_use;
29
30static void sh3_open PARAMS ((char *args, int from_tty));
31
32static void
33sh3_supply_register (regname, regnamelen, val, vallen)
34 char *regname;
35 int regnamelen;
36 char *val;
37 int vallen;
38{
39 int numregs;
40 int regno;
41
42 numregs = 1;
43 regno = -1;
44
45 if (regnamelen == 2)
46 {
47 switch (regname[0])
48 {
49 case 'S':
50 if (regname[1] == 'R')
51 regno = SR_REGNUM;
52 break;
53 case 'P':
54 if (regname[1] == 'C')
55 regno = PC_REGNUM;
56 else if (regname[1] == 'R')
57 regno = PR_REGNUM;
58 break;
59 }
60 }
61 else if (regnamelen == 3)
62 {
63 switch (regname[0])
64 {
65 case 'G':
66 case 'V':
67 if (regname[1] == 'B' && regname[2] == 'R')
7a292a7a
SS
68 {
69 if (regname[0] == 'G')
70 regno = VBR_REGNUM;
71 else
72 regno = GBR_REGNUM;
73 }
c906108c
SS
74 break;
75 case 'S':
76 if (regname[1] == 'S' && regname[2] == 'R')
77 regno = SSR_REGNUM;
78 else if (regname[1] == 'P' && regname[2] == 'C')
79 regno = SPC_REGNUM;
80 break;
81 }
82 }
83 else if (regnamelen == 4)
84 {
85 switch (regname[0])
86 {
87 case 'M':
88 if (regname[1] == 'A' && regname[2] == 'C')
7a292a7a
SS
89 {
90 if (regname[3] == 'H')
91 regno = MACH_REGNUM;
92 else if (regname[3] == 'L')
93 regno = MACL_REGNUM;
94 }
c906108c
SS
95 break;
96 case 'R':
97 if (regname[1] == '0' && regname[2] == '-' && regname[3] == '7')
98 {
99 regno = R0_REGNUM;
100 numregs = 8;
101 }
102 }
103 }
104 else if (regnamelen == 5)
105 {
106 if (regname[1] == '8' && regname[2] == '-' && regname[3] == '1'
107 && regname[4] =='5')
108 {
109 regno = R0_REGNUM + 8;
110 numregs = 8;
111 }
112 }
113 else if (regnamelen == 17)
114 {
115 }
116
117 if (regno >= 0)
118 while (numregs-- > 0)
119 val = monitor_supply_register (regno++, val);
120}
121
122static void
123sh3_load (desc, file, hashmark)
124 serial_t desc;
125 char *file;
126 int hashmark;
127{
128 if (parallel_in_use)
129 {
130 monitor_printf("pl;s\r");
131 load_srec (parallel, file, 0, 80, SREC_ALL, hashmark, NULL);
132 monitor_expect_prompt (NULL, 0);
133 }
134 else
135 {
136 monitor_printf ("il;s:x\r");
137 monitor_expect ("\005", NULL, 0); /* Look for ENQ */
138 SERIAL_WRITE (desc, "\006", 1); /* Send ACK */
139 monitor_expect ("LO x\r", NULL, 0); /* Look for filename */
140
141 load_srec (desc, file, 0, 80, SREC_ALL, hashmark, NULL);
142
143 monitor_expect ("\005", NULL, 0); /* Look for ENQ */
144 SERIAL_WRITE (desc, "\006", 1); /* Send ACK */
145 monitor_expect_prompt (NULL, 0);
146 }
147}
148
149/* This array of registers need to match the indexes used by GDB.
150 This exists because the various ROM monitors use different strings
151 than does GDB, and don't necessarily support all the registers
152 either. So, typing "info reg sp" becomes a "r30". */
153
154static char *sh3_regnames[NUM_REGS] = {
155 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
156 "R8", "R9", "R10", "R11","R12", "R13", "R14", "R15",
157 "PC", "PR", "GBR", "VBR","MACH","MACL", "SR",
158 NULL, NULL,
159 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
160 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
161 "SSR", "SPC",
162 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
163 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
164 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
165 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
166};
167
168static char *sh3e_regnames[NUM_REGS] = {
169 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
170 "R8", "R9", "R10", "R11","R12", "R13", "R14", "R15",
171 "PC", "PR", "GBR", "VBR","MACH","MACL", "SR",
172 "FPUL", "FPSCR",
173 "FR0", "FR1", "FR2", "FR3", "FR4", "FR5", "FR6", "FR7",
174 "FR8", "FR9", "FR10", "FR11", "FR12", "FR13", "FR14", "FR15",
175 "SSR","SPC",
176 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
177 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
178 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
179 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
180};
181
182/* Define the monitor command strings. Since these are passed directly
183 through to a printf style function, we may include formatting
184 strings. We also need a CR or LF on the end. */
185
186static struct target_ops sh3_ops, sh3e_ops;
187
188static char *sh3_inits[] = {"\003", NULL}; /* Exits sub-command mode & download cmds */
189
190static struct monitor_ops sh3_cmds ;
191
192static void
193init_sh3_cmds(void)
194{
195 sh3_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_GETMEM_READ_SINGLE ; /* flags */
196 sh3_cmds.init = sh3_inits; /* monitor init string */
197 sh3_cmds.cont = "g\r"; /* continue command */
198 sh3_cmds.step = "s\r"; /* single step */
199 sh3_cmds.stop = "\003"; /* Interrupt program */
200 sh3_cmds.set_break = "b %x\r"; /* set a breakpoint */
201 sh3_cmds.clr_break = "b -%x\r"; /* clear a breakpoint */
202 sh3_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */
203 sh3_cmds.fill = "f %x @%x %x\r"; /* fill (start len val) */
204 sh3_cmds.setmem.cmdb = "m %x %x\r"; /* setmem.cmdb (addr, value) */
205 sh3_cmds.setmem.cmdw = "m %x %x;w\r"; /* setmem.cmdw (addr, value) */
206 sh3_cmds.setmem.cmdl = "m %x %x;l\r"; /* setmem.cmdl (addr, value) */
207 sh3_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
208 sh3_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
209 sh3_cmds.setmem.term = NULL; /* setreg.term */
210 sh3_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
211 sh3_cmds.getmem.cmdb = "m %x\r"; /* getmem.cmdb (addr, len) */
212 sh3_cmds.getmem.cmdw = "m %x;w\r"; /* getmem.cmdw (addr, len) */
213 sh3_cmds.getmem.cmdl = "m %x;l\r"; /* getmem.cmdl (addr, len) */
214 sh3_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
215 sh3_cmds.getmem.resp_delim = "^ [0-9A-F]+ "; /* getmem.resp_delim */
216 sh3_cmds.getmem.term = "? "; /* getmem.term */
217 sh3_cmds.getmem.term_cmd = ".\r"; /* getmem.term_cmd */
218 sh3_cmds.setreg.cmd = ".%s %x\r"; /* setreg.cmd (name, value) */
219 sh3_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
220 sh3_cmds.setreg.term = NULL; /* setreg.term */
221 sh3_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
222 sh3_cmds.getreg.cmd = ".%s\r"; /* getreg.cmd (name) */
223 sh3_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
224 sh3_cmds.getreg.term = "? "; /* getreg.term */
225 sh3_cmds.getreg.term_cmd = ".\r" ; /* getreg.term_cmd */
226 sh3_cmds.dump_registers = "r\r"; /* dump_registers */
227 sh3_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\( +[0-9a-fA-F]+\\b\\)*\\)";
228 sh3_cmds.supply_register = sh3_supply_register ; /* supply_register */
229 sh3_cmds.load_routine = sh3_load; /* load_routine */
230 sh3_cmds.load = NULL; /* download command */
231 sh3_cmds.loadresp = NULL; /* Load response */
232 sh3_cmds.prompt = "\n:"; /* monitor command prompt */
233 sh3_cmds.line_term = "\r"; /* end-of-line terminator */
234 sh3_cmds.cmd_end = ".\r"; /* optional command terminator */
235 sh3_cmds.target = &sh3_ops; /* target operations */
236 sh3_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
237 sh3_cmds.regnames = sh3_regnames; /* registers names */
238 sh3_cmds.magic = MONITOR_OPS_MAGIC ; /* magic */
239} /* init_sh3_cmds */
240
241/* This monitor structure is identical except for a couple slots, so
242 we will fill it in from the base structure when needed. */
243
244static struct monitor_ops sh3e_cmds;
245
246static void
247sh3_open (args, from_tty)
248 char *args;
249 int from_tty;
250{
251 char *serial_port_name = args;
252 char *parallel_port_name = 0;
253
254 if (args)
255 {
256 char *cursor = serial_port_name = strsave (args);
257
258 while (*cursor && *cursor != ' ')
259 cursor++;
260
261 if (*cursor)
262 *cursor++ = 0;
263
264 while (*cursor == ' ')
265 cursor++;
266
267 if (*cursor)
268 parallel_port_name = cursor;
269 }
270
271 monitor_open (serial_port_name, &sh3_cmds, from_tty);
272
273 if (parallel_port_name)
274 {
275 parallel = SERIAL_OPEN (parallel_port_name);
276
277 if (!parallel)
278 perror_with_name ("Unable to open parallel port.");
279
280 parallel_in_use = 1;
281 }
282
283 /* If we connected successfully, we know the processor is an SH3. */
284 set_architecture_from_arch_mach (bfd_arch_sh, bfd_mach_sh3);
285}
286
287
288static void
289sh3e_open (args, from_tty)
290 char *args;
291 int from_tty;
292{
293 char *serial_port_name = args;
294 char *parallel_port_name = 0;
295
296 if (args)
297 {
298 char *cursor = serial_port_name = strsave (args);
299
300 while (*cursor && *cursor != ' ')
301 cursor++;
302
303 if (*cursor)
304 *cursor++ = 0;
305
306 while (*cursor == ' ')
307 cursor++;
308
309 if (*cursor)
310 parallel_port_name = cursor;
311 }
312
313 /* Set up the SH-3E monitor commands structure. */
314
315 memcpy (&sh3e_cmds, &sh3_cmds, sizeof (struct monitor_ops));
316
317 sh3e_cmds.target = &sh3e_ops;
318 sh3e_cmds.regnames = sh3e_regnames;
319
320 monitor_open (serial_port_name, &sh3e_cmds, from_tty);
321
322 if (parallel_port_name)
323 {
324 parallel = SERIAL_OPEN (parallel_port_name);
325
326 if (!parallel)
327 perror_with_name ("Unable to open parallel port.");
328
329 parallel_in_use = 1;
330 }
331
332 /* If we connected successfully, we know the processor is an SH3E. */
333 set_architecture_from_arch_mach (bfd_arch_sh, bfd_mach_sh3);
334}
335
336static void
337sh3_close (quitting)
338 int quitting;
339{
340 monitor_close (quitting);
341 if (parallel_in_use) {
342 SERIAL_CLOSE (parallel);
343 parallel_in_use = 0;
344 }
345}
346
347void
348_initialize_sh3_rom ()
349{
350 init_sh3_cmds() ;
351 init_monitor_ops (&sh3_ops);
352
353 sh3_ops.to_shortname = "sh3";
354 sh3_ops.to_longname = "Hitachi SH-3 rom monitor";
355
356 sh3_ops.to_doc =
357#ifdef _WINDOWS
358 /* On windows we can talk through the parallel port too. */
359 "Debug on a Hitachi eval board running the SH-3 rom monitor.\n"
360 "Specify the serial device it is connected to (e.g. com2).\n"
361 "If you want to use the parallel port to download to it, specify that\n"
362 "as the second argument. (e.g. lpt1)";
363#else
364 "Debug on a Hitachi eval board running the SH-3 rom monitor.\n\
365Specify the serial device it is connected to (e.g. /dev/ttya).";
366#endif
367
368 sh3_ops.to_open = sh3_open;
369 sh3_ops.to_close = sh3_close;
370
371 add_target (&sh3_ops);
372
373 /* Setup the SH3e, which has float registers. */
374
375 init_monitor_ops (&sh3e_ops);
376
377 sh3e_ops.to_shortname = "sh3e";
378 sh3e_ops.to_longname = "Hitachi SH-3E rom monitor";
379
380 sh3e_ops.to_doc =
381#ifdef _WINDOWS
382 /* On windows we can talk through the parallel port too. */
383 "Debug on a Hitachi eval board running the SH-3E rom monitor.\n"
384 "Specify the serial device it is connected to (e.g. com2).\n"
385 "If you want to use the parallel port to download to it, specify that\n"
386 "as the second argument. (e.g. lpt1)";
387#else
388 "Debug on a Hitachi eval board running the SH-3E rom monitor.\n\
389Specify the serial device it is connected to (e.g. /dev/ttya).";
390#endif
391
392 sh3e_ops.to_open = sh3e_open;
393 sh3e_ops.to_close = sh3_close;
394
395 add_target (&sh3e_ops);
396}
This page took 0.036927 seconds and 4 git commands to generate.