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