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
sh3_supply_register(char * regname,int regnamelen,char * val,int vallen)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
sh3_load(struct serial * desc,char * file,int hashmark)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
init_sh3_cmds(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
sh3_open(char * args,int from_tty)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
sh3e_open(char * args,int from_tty)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
sh3_close(int quitting)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
_initialize_sh3_rom(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 }
401