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