xref: /openbsd-src/gnu/usr.bin/binutils/gdb/m32r-rom.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Remote debugging interface to m32r and mon2000 ROM monitors for GDB,
2b725ae77Skettenis    the GNU debugger.
3*11efff7fSkettenis 
4*11efff7fSkettenis    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2004 Free Software
5*11efff7fSkettenis    Foundation, Inc.
6b725ae77Skettenis 
7b725ae77Skettenis    Adapted by Michael Snyder of Cygnus Support.
8b725ae77Skettenis 
9b725ae77Skettenis    This file is part of GDB.
10b725ae77Skettenis 
11b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
12b725ae77Skettenis    it under the terms of the GNU General Public License as published by
13b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
14b725ae77Skettenis    (at your option) any later version.
15b725ae77Skettenis 
16b725ae77Skettenis    This program is distributed in the hope that it will be useful,
17b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
18b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19b725ae77Skettenis    GNU General Public License for more details.
20b725ae77Skettenis 
21b725ae77Skettenis    You should have received a copy of the GNU General Public License
22b725ae77Skettenis    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.  */
25b725ae77Skettenis 
26b725ae77Skettenis /* This module defines communication with the Renesas m32r monitor */
27b725ae77Skettenis 
28b725ae77Skettenis #include "defs.h"
29b725ae77Skettenis #include "gdbcore.h"
30b725ae77Skettenis #include "target.h"
31b725ae77Skettenis #include "monitor.h"
32b725ae77Skettenis #include "serial.h"
33b725ae77Skettenis #include "symtab.h"
34b725ae77Skettenis #include "command.h"
35b725ae77Skettenis #include "gdbcmd.h"
36b725ae77Skettenis #include "symfile.h"		/* for generic load */
37b725ae77Skettenis #include <time.h>		/* for time_t */
38b725ae77Skettenis #include "gdb_string.h"
39b725ae77Skettenis #include "objfiles.h"		/* for ALL_OBJFILES etc. */
40b725ae77Skettenis #include "inferior.h"		/* for write_pc() */
41b725ae77Skettenis #include <ctype.h>
42b725ae77Skettenis #include "regcache.h"
43b725ae77Skettenis 
44b725ae77Skettenis /*
45b725ae77Skettenis  * All this stuff just to get my host computer's IP address!
46b725ae77Skettenis  */
47b725ae77Skettenis #include <sys/types.h>
48b725ae77Skettenis #include <netdb.h>		/* for hostent */
49b725ae77Skettenis #include <netinet/in.h>		/* for struct in_addr */
50b725ae77Skettenis #if 1
51b725ae77Skettenis #include <arpa/inet.h>		/* for inet_ntoa */
52b725ae77Skettenis #endif
53b725ae77Skettenis 
54b725ae77Skettenis static char *board_addr;	/* user-settable IP address for M32R-EVA */
55b725ae77Skettenis static char *server_addr;	/* user-settable IP address for gdb host */
56b725ae77Skettenis static char *download_path;	/* user-settable path for SREC files     */
57b725ae77Skettenis 
58b725ae77Skettenis 
59b725ae77Skettenis /* REGNUM */
60b725ae77Skettenis #define PSW_REGNUM      16
61b725ae77Skettenis #define SPI_REGNUM      18
62b725ae77Skettenis #define SPU_REGNUM      19
63b725ae77Skettenis #define ACCL_REGNUM     22
64b725ae77Skettenis #define ACCH_REGNUM     23
65b725ae77Skettenis 
66b725ae77Skettenis 
67b725ae77Skettenis /*
68b725ae77Skettenis  * Function: m32r_load_1 (helper function)
69b725ae77Skettenis  */
70b725ae77Skettenis 
71b725ae77Skettenis static void
m32r_load_section(bfd * abfd,asection * s,void * obj)72b725ae77Skettenis m32r_load_section (bfd *abfd, asection *s, void *obj)
73b725ae77Skettenis {
74b725ae77Skettenis   unsigned int *data_count = obj;
75b725ae77Skettenis   if (s->flags & SEC_LOAD)
76b725ae77Skettenis     {
77b725ae77Skettenis       bfd_size_type section_size = bfd_section_size (abfd, s);
78b725ae77Skettenis       bfd_vma section_base = bfd_section_lma (abfd, s);
79b725ae77Skettenis       unsigned int buffer, i;
80b725ae77Skettenis 
81b725ae77Skettenis       *data_count += section_size;
82b725ae77Skettenis 
83b725ae77Skettenis       printf_filtered ("Loading section %s, size 0x%lx lma ",
84b725ae77Skettenis 		       bfd_section_name (abfd, s), section_size);
85b725ae77Skettenis       print_address_numeric (section_base, 1, gdb_stdout);
86b725ae77Skettenis       printf_filtered ("\n");
87b725ae77Skettenis       gdb_flush (gdb_stdout);
88b725ae77Skettenis       monitor_printf ("%s mw\r", paddr_nz (section_base));
89b725ae77Skettenis       for (i = 0; i < section_size; i += 4)
90b725ae77Skettenis 	{
91b725ae77Skettenis 	  QUIT;
92b725ae77Skettenis 	  monitor_expect (" -> ", NULL, 0);
93b725ae77Skettenis 	  bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);
94b725ae77Skettenis 	  monitor_printf ("%x\n", buffer);
95b725ae77Skettenis 	}
96b725ae77Skettenis       monitor_expect (" -> ", NULL, 0);
97b725ae77Skettenis       monitor_printf ("q\n");
98b725ae77Skettenis       monitor_expect_prompt (NULL, 0);
99b725ae77Skettenis     }
100b725ae77Skettenis }
101b725ae77Skettenis 
102b725ae77Skettenis static int
m32r_load_1(void * dummy)103b725ae77Skettenis m32r_load_1 (void *dummy)
104b725ae77Skettenis {
105b725ae77Skettenis   int data_count = 0;
106b725ae77Skettenis 
107b725ae77Skettenis   bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count);
108b725ae77Skettenis   return data_count;
109b725ae77Skettenis }
110b725ae77Skettenis 
111b725ae77Skettenis /*
112b725ae77Skettenis  * Function: m32r_load (an alternate way to load)
113b725ae77Skettenis  */
114b725ae77Skettenis 
115b725ae77Skettenis static void
m32r_load(char * filename,int from_tty)116b725ae77Skettenis m32r_load (char *filename, int from_tty)
117b725ae77Skettenis {
118b725ae77Skettenis   bfd *abfd;
119b725ae77Skettenis   asection *s;
120b725ae77Skettenis   unsigned int i, data_count = 0;
121b725ae77Skettenis   time_t start_time, end_time;	/* for timing of download */
122b725ae77Skettenis 
123b725ae77Skettenis   if (filename == NULL || filename[0] == 0)
124b725ae77Skettenis     filename = get_exec_file (1);
125b725ae77Skettenis 
126b725ae77Skettenis   abfd = bfd_openr (filename, 0);
127b725ae77Skettenis   if (!abfd)
128b725ae77Skettenis     error ("Unable to open file %s\n", filename);
129b725ae77Skettenis   if (bfd_check_format (abfd, bfd_object) == 0)
130b725ae77Skettenis     error ("File is not an object file\n");
131b725ae77Skettenis   start_time = time (NULL);
132b725ae77Skettenis #if 0
133b725ae77Skettenis   for (s = abfd->sections; s; s = s->next)
134b725ae77Skettenis     if (s->flags & SEC_LOAD)
135b725ae77Skettenis       {
136b725ae77Skettenis 	bfd_size_type section_size = bfd_section_size (abfd, s);
137b725ae77Skettenis 	bfd_vma section_base = bfd_section_vma (abfd, s);
138b725ae77Skettenis 	unsigned int buffer;
139b725ae77Skettenis 
140b725ae77Skettenis 	data_count += section_size;
141b725ae77Skettenis 
142b725ae77Skettenis 	printf_filtered ("Loading section %s, size 0x%lx vma ",
143b725ae77Skettenis 			 bfd_section_name (abfd, s), section_size);
144b725ae77Skettenis 	print_address_numeric (section_base, 1, gdb_stdout);
145b725ae77Skettenis 	printf_filtered ("\n");
146b725ae77Skettenis 	gdb_flush (gdb_stdout);
147b725ae77Skettenis 	monitor_printf ("%x mw\r", section_base);
148b725ae77Skettenis 	for (i = 0; i < section_size; i += 4)
149b725ae77Skettenis 	  {
150b725ae77Skettenis 	    monitor_expect (" -> ", NULL, 0);
151b725ae77Skettenis 	    bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);
152b725ae77Skettenis 	    monitor_printf ("%x\n", buffer);
153b725ae77Skettenis 	  }
154b725ae77Skettenis 	monitor_expect (" -> ", NULL, 0);
155b725ae77Skettenis 	monitor_printf ("q\n");
156b725ae77Skettenis 	monitor_expect_prompt (NULL, 0);
157b725ae77Skettenis       }
158b725ae77Skettenis #else
159b725ae77Skettenis   if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL)))
160b725ae77Skettenis     {
161b725ae77Skettenis       monitor_printf ("q\n");
162b725ae77Skettenis       return;
163b725ae77Skettenis     }
164b725ae77Skettenis #endif
165b725ae77Skettenis   end_time = time (NULL);
166b725ae77Skettenis   printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));
167b725ae77Skettenis   print_transfer_performance (gdb_stdout, data_count, 0,
168b725ae77Skettenis 			      end_time - start_time);
169b725ae77Skettenis 
170b725ae77Skettenis   /* Finally, make the PC point at the start address */
171b725ae77Skettenis   if (exec_bfd)
172b725ae77Skettenis     write_pc (bfd_get_start_address (exec_bfd));
173b725ae77Skettenis 
174b725ae77Skettenis   inferior_ptid = null_ptid;	/* No process now */
175b725ae77Skettenis 
176b725ae77Skettenis   /* This is necessary because many things were based on the PC at the
177b725ae77Skettenis      time that we attached to the monitor, which is no longer valid
178b725ae77Skettenis      now that we have loaded new code (and just changed the PC).
179b725ae77Skettenis      Another way to do this might be to call normal_stop, except that
180b725ae77Skettenis      the stack may not be valid, and things would get horribly
181b725ae77Skettenis      confused... */
182b725ae77Skettenis 
183b725ae77Skettenis   clear_symtab_users ();
184b725ae77Skettenis }
185b725ae77Skettenis 
186b725ae77Skettenis static void
m32r_load_gen(char * filename,int from_tty)187b725ae77Skettenis m32r_load_gen (char *filename, int from_tty)
188b725ae77Skettenis {
189b725ae77Skettenis   generic_load (filename, from_tty);
190b725ae77Skettenis }
191b725ae77Skettenis 
192b725ae77Skettenis static void m32r_open (char *args, int from_tty);
193b725ae77Skettenis static void mon2000_open (char *args, int from_tty);
194b725ae77Skettenis 
195b725ae77Skettenis /* This array of registers needs to match the indexes used by GDB. The
196b725ae77Skettenis    whole reason this exists is because the various ROM monitors use
197b725ae77Skettenis    different names than GDB does, and don't support all the registers
198b725ae77Skettenis    either. So, typing "info reg sp" becomes an "A7". */
199b725ae77Skettenis 
200b725ae77Skettenis static char *m32r_regnames[] =
201b725ae77Skettenis   { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
202b725ae77Skettenis   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
203b725ae77Skettenis   "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch",
204b725ae77Skettenis };
205b725ae77Skettenis 
206b725ae77Skettenis static void
m32r_supply_register(char * regname,int regnamelen,char * val,int vallen)207b725ae77Skettenis m32r_supply_register (char *regname, int regnamelen, char *val, int vallen)
208b725ae77Skettenis {
209b725ae77Skettenis   int regno;
210b725ae77Skettenis   int num_regs = sizeof (m32r_regnames) / sizeof (m32r_regnames[0]);
211b725ae77Skettenis 
212b725ae77Skettenis   for (regno = 0; regno < num_regs; regno++)
213b725ae77Skettenis     if (strncmp (regname, m32r_regnames[regno], regnamelen) == 0)
214b725ae77Skettenis       break;
215b725ae77Skettenis 
216b725ae77Skettenis   if (regno >= num_regs)
217b725ae77Skettenis     return;			/* no match */
218b725ae77Skettenis 
219b725ae77Skettenis   if (regno == ACCL_REGNUM)
220b725ae77Skettenis     {				/* special handling for 64-bit acc reg */
221b725ae77Skettenis       monitor_supply_register (ACCH_REGNUM, val);
222b725ae77Skettenis       val = strchr (val, ':');	/* skip past ':' to get 2nd word */
223b725ae77Skettenis       if (val != NULL)
224b725ae77Skettenis 	monitor_supply_register (ACCL_REGNUM, val + 1);
225b725ae77Skettenis     }
226b725ae77Skettenis   else
227b725ae77Skettenis     {
228b725ae77Skettenis       monitor_supply_register (regno, val);
229b725ae77Skettenis       if (regno == PSW_REGNUM)
230b725ae77Skettenis 	{
231b725ae77Skettenis 	  unsigned long psw = strtoul (val, NULL, 16);
232b725ae77Skettenis 	  char *zero = "00000000", *one = "00000001";
233b725ae77Skettenis 
234b725ae77Skettenis #ifdef SM_REGNUM
235b725ae77Skettenis 	  /* Stack mode bit */
236b725ae77Skettenis 	  monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero);
237b725ae77Skettenis #endif
238b725ae77Skettenis #ifdef BSM_REGNUM
239b725ae77Skettenis 	  /* Backup stack mode bit */
240b725ae77Skettenis 	  monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero);
241b725ae77Skettenis #endif
242b725ae77Skettenis #ifdef IE_REGNUM
243b725ae77Skettenis 	  /* Interrupt enable bit */
244b725ae77Skettenis 	  monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero);
245b725ae77Skettenis #endif
246b725ae77Skettenis #ifdef BIE_REGNUM
247b725ae77Skettenis 	  /* Backup interrupt enable bit */
248b725ae77Skettenis 	  monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero);
249b725ae77Skettenis #endif
250b725ae77Skettenis #ifdef COND_REGNUM
251b725ae77Skettenis 	  /* Condition bit (carry etc.) */
252b725ae77Skettenis 	  monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero);
253b725ae77Skettenis #endif
254b725ae77Skettenis #ifdef CBR_REGNUM
255b725ae77Skettenis 	  monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero);
256b725ae77Skettenis #endif
257b725ae77Skettenis #ifdef BPC_REGNUM
258b725ae77Skettenis 	  monitor_supply_register (BPC_REGNUM, zero);	/* KLUDGE:   (???????) */
259b725ae77Skettenis #endif
260b725ae77Skettenis #ifdef BCARRY_REGNUM
261b725ae77Skettenis 	  monitor_supply_register (BCARRY_REGNUM, zero);	/* KLUDGE: (??????) */
262b725ae77Skettenis #endif
263b725ae77Skettenis 	}
264b725ae77Skettenis 
265b725ae77Skettenis       if (regno == SPI_REGNUM || regno == SPU_REGNUM)
266b725ae77Skettenis 	{			/* special handling for stack pointer (spu or spi) */
267b725ae77Skettenis 	  ULONGEST stackmode, psw;
268b725ae77Skettenis 	  regcache_cooked_read_unsigned (current_regcache, PSW_REGNUM, &psw);
269b725ae77Skettenis 	  stackmode = psw & 0x80;
270b725ae77Skettenis 
271b725ae77Skettenis 	  if (regno == SPI_REGNUM && !stackmode)	/* SP == SPI */
272b725ae77Skettenis 	    monitor_supply_register (SP_REGNUM, val);
273b725ae77Skettenis 	  else if (regno == SPU_REGNUM && stackmode)	/* SP == SPU */
274b725ae77Skettenis 	    monitor_supply_register (SP_REGNUM, val);
275b725ae77Skettenis 	}
276b725ae77Skettenis     }
277b725ae77Skettenis }
278b725ae77Skettenis 
279b725ae77Skettenis /* m32r RevC board monitor */
280b725ae77Skettenis 
281b725ae77Skettenis static struct target_ops m32r_ops;
282b725ae77Skettenis 
283b725ae77Skettenis static char *m32r_inits[] = { "\r", NULL };
284b725ae77Skettenis 
285b725ae77Skettenis static struct monitor_ops m32r_cmds;
286b725ae77Skettenis 
287b725ae77Skettenis static void
init_m32r_cmds(void)288b725ae77Skettenis init_m32r_cmds (void)
289b725ae77Skettenis {
290b725ae77Skettenis   m32r_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;
291b725ae77Skettenis   m32r_cmds.init = m32r_inits;	/* Init strings */
292b725ae77Skettenis   m32r_cmds.cont = "go\r";	/* continue command */
293b725ae77Skettenis   m32r_cmds.step = "step\r";	/* single step */
294b725ae77Skettenis   m32r_cmds.stop = NULL;	/* interrupt command */
295b725ae77Skettenis   m32r_cmds.set_break = "%x +bp\r";	/* set a breakpoint */
296b725ae77Skettenis   m32r_cmds.clr_break = "%x -bp\r";	/* clear a breakpoint */
297b725ae77Skettenis   m32r_cmds.clr_all_break = "bpoff\r";	/* clear all breakpoints */
298b725ae77Skettenis   m32r_cmds.fill = "%x %x %x fill\r";	/* fill (start length val) */
299b725ae77Skettenis   m32r_cmds.setmem.cmdb = "%x 1 %x fill\r";	/* setmem.cmdb (addr, value) */
300b725ae77Skettenis   m32r_cmds.setmem.cmdw = "%x 1 %x fillh\r";	/* setmem.cmdw (addr, value) */
301b725ae77Skettenis   m32r_cmds.setmem.cmdl = "%x 1 %x fillw\r";	/* setmem.cmdl (addr, value) */
302b725ae77Skettenis   m32r_cmds.setmem.cmdll = NULL;	/* setmem.cmdll (addr, value) */
303b725ae77Skettenis   m32r_cmds.setmem.resp_delim = NULL;	/* setmem.resp_delim */
304b725ae77Skettenis   m32r_cmds.setmem.term = NULL;	/* setmem.term */
305b725ae77Skettenis   m32r_cmds.setmem.term_cmd = NULL;	/* setmem.term_cmd */
306b725ae77Skettenis   m32r_cmds.getmem.cmdb = "%x %x dump\r";	/* getmem.cmdb (addr, len) */
307b725ae77Skettenis   m32r_cmds.getmem.cmdw = NULL;	/* getmem.cmdw (addr, len) */
308b725ae77Skettenis   m32r_cmds.getmem.cmdl = NULL;	/* getmem.cmdl (addr, len) */
309b725ae77Skettenis   m32r_cmds.getmem.cmdll = NULL;	/* getmem.cmdll (addr, len) */
310b725ae77Skettenis   m32r_cmds.getmem.resp_delim = ": ";	/* getmem.resp_delim */
311b725ae77Skettenis   m32r_cmds.getmem.term = NULL;	/* getmem.term */
312b725ae77Skettenis   m32r_cmds.getmem.term_cmd = NULL;	/* getmem.term_cmd */
313b725ae77Skettenis   m32r_cmds.setreg.cmd = "%x to %%%s\r";	/* setreg.cmd (name, value) */
314b725ae77Skettenis   m32r_cmds.setreg.resp_delim = NULL;	/* setreg.resp_delim */
315b725ae77Skettenis   m32r_cmds.setreg.term = NULL;	/* setreg.term */
316b725ae77Skettenis   m32r_cmds.setreg.term_cmd = NULL;	/* setreg.term_cmd */
317b725ae77Skettenis   m32r_cmds.getreg.cmd = NULL;	/* getreg.cmd (name) */
318b725ae77Skettenis   m32r_cmds.getreg.resp_delim = NULL;	/* getreg.resp_delim */
319b725ae77Skettenis   m32r_cmds.getreg.term = NULL;	/* getreg.term */
320b725ae77Skettenis   m32r_cmds.getreg.term_cmd = NULL;	/* getreg.term_cmd */
321b725ae77Skettenis   m32r_cmds.dump_registers = ".reg\r";	/* dump_registers */
322b725ae77Skettenis   m32r_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)";	/* register_pattern */
323*11efff7fSkettenis   m32r_cmds.supply_register = m32r_supply_register;
324b725ae77Skettenis   m32r_cmds.load_routine = NULL;	/* load_routine (defaults to SRECs) */
325b725ae77Skettenis   m32r_cmds.load = NULL;	/* download command */
326b725ae77Skettenis   m32r_cmds.loadresp = NULL;	/* load response */
327b725ae77Skettenis   m32r_cmds.prompt = "ok ";	/* monitor command prompt */
328b725ae77Skettenis   m32r_cmds.line_term = "\r";	/* end-of-line terminator */
329b725ae77Skettenis   m32r_cmds.cmd_end = NULL;	/* optional command terminator */
330b725ae77Skettenis   m32r_cmds.target = &m32r_ops;	/* target operations */
331b725ae77Skettenis   m32r_cmds.stopbits = SERIAL_1_STOPBITS;	/* number of stop bits */
332b725ae77Skettenis   m32r_cmds.regnames = m32r_regnames;	/* registers names */
333b725ae77Skettenis   m32r_cmds.magic = MONITOR_OPS_MAGIC;	/* magic */
334b725ae77Skettenis }				/* init_m32r_cmds */
335b725ae77Skettenis 
336b725ae77Skettenis static void
m32r_open(char * args,int from_tty)337b725ae77Skettenis m32r_open (char *args, int from_tty)
338b725ae77Skettenis {
339b725ae77Skettenis   monitor_open (args, &m32r_cmds, from_tty);
340b725ae77Skettenis }
341b725ae77Skettenis 
342b725ae77Skettenis /* Mon2000 monitor (MSA2000 board) */
343b725ae77Skettenis 
344b725ae77Skettenis static struct target_ops mon2000_ops;
345b725ae77Skettenis static struct monitor_ops mon2000_cmds;
346b725ae77Skettenis 
347b725ae77Skettenis static void
init_mon2000_cmds(void)348b725ae77Skettenis init_mon2000_cmds (void)
349b725ae77Skettenis {
350b725ae77Skettenis   mon2000_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;
351b725ae77Skettenis   mon2000_cmds.init = m32r_inits;	/* Init strings */
352b725ae77Skettenis   mon2000_cmds.cont = "go\r";	/* continue command */
353b725ae77Skettenis   mon2000_cmds.step = "step\r";	/* single step */
354b725ae77Skettenis   mon2000_cmds.stop = NULL;	/* interrupt command */
355b725ae77Skettenis   mon2000_cmds.set_break = "%x +bp\r";	/* set a breakpoint */
356b725ae77Skettenis   mon2000_cmds.clr_break = "%x -bp\r";	/* clear a breakpoint */
357b725ae77Skettenis   mon2000_cmds.clr_all_break = "bpoff\r";	/* clear all breakpoints */
358b725ae77Skettenis   mon2000_cmds.fill = "%x %x %x fill\r";	/* fill (start length val) */
359b725ae77Skettenis   mon2000_cmds.setmem.cmdb = "%x 1 %x fill\r";	/* setmem.cmdb (addr, value) */
360b725ae77Skettenis   mon2000_cmds.setmem.cmdw = "%x 1 %x fillh\r";	/* setmem.cmdw (addr, value) */
361b725ae77Skettenis   mon2000_cmds.setmem.cmdl = "%x 1 %x fillw\r";	/* setmem.cmdl (addr, value) */
362b725ae77Skettenis   mon2000_cmds.setmem.cmdll = NULL;	/* setmem.cmdll (addr, value) */
363b725ae77Skettenis   mon2000_cmds.setmem.resp_delim = NULL;	/* setmem.resp_delim */
364b725ae77Skettenis   mon2000_cmds.setmem.term = NULL;	/* setmem.term */
365b725ae77Skettenis   mon2000_cmds.setmem.term_cmd = NULL;	/* setmem.term_cmd */
366b725ae77Skettenis   mon2000_cmds.getmem.cmdb = "%x %x dump\r";	/* getmem.cmdb (addr, len) */
367b725ae77Skettenis   mon2000_cmds.getmem.cmdw = NULL;	/* getmem.cmdw (addr, len) */
368b725ae77Skettenis   mon2000_cmds.getmem.cmdl = NULL;	/* getmem.cmdl (addr, len) */
369b725ae77Skettenis   mon2000_cmds.getmem.cmdll = NULL;	/* getmem.cmdll (addr, len) */
370b725ae77Skettenis   mon2000_cmds.getmem.resp_delim = ": ";	/* getmem.resp_delim */
371b725ae77Skettenis   mon2000_cmds.getmem.term = NULL;	/* getmem.term */
372b725ae77Skettenis   mon2000_cmds.getmem.term_cmd = NULL;	/* getmem.term_cmd */
373b725ae77Skettenis   mon2000_cmds.setreg.cmd = "%x to %%%s\r";	/* setreg.cmd (name, value) */
374b725ae77Skettenis   mon2000_cmds.setreg.resp_delim = NULL;	/* setreg.resp_delim */
375b725ae77Skettenis   mon2000_cmds.setreg.term = NULL;	/* setreg.term */
376b725ae77Skettenis   mon2000_cmds.setreg.term_cmd = NULL;	/* setreg.term_cmd */
377b725ae77Skettenis   mon2000_cmds.getreg.cmd = NULL;	/* getreg.cmd (name) */
378b725ae77Skettenis   mon2000_cmds.getreg.resp_delim = NULL;	/* getreg.resp_delim */
379b725ae77Skettenis   mon2000_cmds.getreg.term = NULL;	/* getreg.term */
380b725ae77Skettenis   mon2000_cmds.getreg.term_cmd = NULL;	/* getreg.term_cmd */
381b725ae77Skettenis   mon2000_cmds.dump_registers = ".reg\r";	/* dump_registers */
382b725ae77Skettenis   mon2000_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)";	/* register_pattern */
383*11efff7fSkettenis   mon2000_cmds.supply_register = m32r_supply_register;
384b725ae77Skettenis   mon2000_cmds.load_routine = NULL;	/* load_routine (defaults to SRECs) */
385b725ae77Skettenis   mon2000_cmds.load = NULL;	/* download command */
386b725ae77Skettenis   mon2000_cmds.loadresp = NULL;	/* load response */
387b725ae77Skettenis   mon2000_cmds.prompt = "Mon2000>";	/* monitor command prompt */
388b725ae77Skettenis   mon2000_cmds.line_term = "\r";	/* end-of-line terminator */
389b725ae77Skettenis   mon2000_cmds.cmd_end = NULL;	/* optional command terminator */
390b725ae77Skettenis   mon2000_cmds.target = &mon2000_ops;	/* target operations */
391b725ae77Skettenis   mon2000_cmds.stopbits = SERIAL_1_STOPBITS;	/* number of stop bits */
392b725ae77Skettenis   mon2000_cmds.regnames = m32r_regnames;	/* registers names */
393b725ae77Skettenis   mon2000_cmds.magic = MONITOR_OPS_MAGIC;	/* magic */
394b725ae77Skettenis }				/* init_mon2000_cmds */
395b725ae77Skettenis 
396b725ae77Skettenis static void
mon2000_open(char * args,int from_tty)397b725ae77Skettenis mon2000_open (char *args, int from_tty)
398b725ae77Skettenis {
399b725ae77Skettenis   monitor_open (args, &mon2000_cmds, from_tty);
400b725ae77Skettenis }
401b725ae77Skettenis 
402b725ae77Skettenis static void
m32r_upload_command(char * args,int from_tty)403b725ae77Skettenis m32r_upload_command (char *args, int from_tty)
404b725ae77Skettenis {
405b725ae77Skettenis   bfd *abfd;
406b725ae77Skettenis   asection *s;
407b725ae77Skettenis   time_t start_time, end_time;	/* for timing of download */
408b725ae77Skettenis   int resp_len, data_count = 0;
409b725ae77Skettenis   char buf[1024];
410b725ae77Skettenis   struct hostent *hostent;
411b725ae77Skettenis   struct in_addr inet_addr;
412b725ae77Skettenis 
413b725ae77Skettenis   /* first check to see if there's an ethernet port! */
414b725ae77Skettenis   monitor_printf ("ust\r");
415b725ae77Skettenis   resp_len = monitor_expect_prompt (buf, sizeof (buf));
416b725ae77Skettenis   if (!strchr (buf, ':'))
417b725ae77Skettenis     error ("No ethernet connection!");
418b725ae77Skettenis 
419b725ae77Skettenis   if (board_addr == 0)
420b725ae77Skettenis     {
421b725ae77Skettenis       /* scan second colon in the output from the "ust" command */
422b725ae77Skettenis       char *myIPaddress = strchr (strchr (buf, ':') + 1, ':') + 1;
423b725ae77Skettenis 
424b725ae77Skettenis       while (isspace (*myIPaddress))
425b725ae77Skettenis 	myIPaddress++;
426b725ae77Skettenis 
427b725ae77Skettenis       if (!strncmp (myIPaddress, "0.0.", 4))	/* empty */
428b725ae77Skettenis 	error
429b725ae77Skettenis 	  ("Please use 'set board-address' to set the M32R-EVA board's IP address.");
430b725ae77Skettenis       if (strchr (myIPaddress, '('))
431b725ae77Skettenis 	*(strchr (myIPaddress, '(')) = '\0';	/* delete trailing junk */
432b725ae77Skettenis       board_addr = xstrdup (myIPaddress);
433b725ae77Skettenis     }
434b725ae77Skettenis   if (server_addr == 0)
435b725ae77Skettenis     {
436b725ae77Skettenis       buf[0] = 0;
437b725ae77Skettenis       gethostname (buf, sizeof (buf));
438b725ae77Skettenis       if (buf[0] != 0)
439b725ae77Skettenis 	{
440b725ae77Skettenis 	  hostent = gethostbyname (buf);
441b725ae77Skettenis 	  if (hostent != 0)
442b725ae77Skettenis 	    {
443b725ae77Skettenis #if 1
444b725ae77Skettenis 	      memcpy (&inet_addr.s_addr, hostent->h_addr,
445b725ae77Skettenis 		      sizeof (inet_addr.s_addr));
446b725ae77Skettenis 	      server_addr = (char *) inet_ntoa (inet_addr);
447b725ae77Skettenis #else
448b725ae77Skettenis 	      server_addr = (char *) inet_ntoa (hostent->h_addr);
449b725ae77Skettenis #endif
450b725ae77Skettenis 	    }
451b725ae77Skettenis 	}
452b725ae77Skettenis       if (server_addr == 0)	/* failed? */
453b725ae77Skettenis 	error
454b725ae77Skettenis 	  ("Need to know gdb host computer's IP address (use 'set server-address')");
455b725ae77Skettenis     }
456b725ae77Skettenis 
457b725ae77Skettenis   if (args == 0 || args[0] == 0)	/* no args: upload the current file */
458b725ae77Skettenis     args = get_exec_file (1);
459b725ae77Skettenis 
460b725ae77Skettenis   if (args[0] != '/' && download_path == 0)
461b725ae77Skettenis     {
462b725ae77Skettenis       if (current_directory)
463b725ae77Skettenis 	download_path = xstrdup (current_directory);
464b725ae77Skettenis       else
465b725ae77Skettenis 	error
466b725ae77Skettenis 	  ("Need to know default download path (use 'set download-path')");
467b725ae77Skettenis     }
468b725ae77Skettenis 
469b725ae77Skettenis   start_time = time (NULL);
470b725ae77Skettenis   monitor_printf ("uhip %s\r", server_addr);
471b725ae77Skettenis   resp_len = monitor_expect_prompt (buf, sizeof (buf));	/* parse result? */
472b725ae77Skettenis   monitor_printf ("ulip %s\r", board_addr);
473b725ae77Skettenis   resp_len = monitor_expect_prompt (buf, sizeof (buf));	/* parse result? */
474b725ae77Skettenis   if (args[0] != '/')
475b725ae77Skettenis     monitor_printf ("up %s\r", download_path);	/* use default path */
476b725ae77Skettenis   else
477b725ae77Skettenis     monitor_printf ("up\r");	/* rooted filename/path */
478b725ae77Skettenis   resp_len = monitor_expect_prompt (buf, sizeof (buf));	/* parse result? */
479b725ae77Skettenis 
480b725ae77Skettenis   if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec"))
481b725ae77Skettenis     monitor_printf ("ul %s\r", args);
482b725ae77Skettenis   else				/* add ".srec" suffix */
483b725ae77Skettenis     monitor_printf ("ul %s.srec\r", args);
484b725ae77Skettenis   resp_len = monitor_expect_prompt (buf, sizeof (buf));	/* parse result? */
485b725ae77Skettenis 
486b725ae77Skettenis   if (buf[0] == 0 || strstr (buf, "complete") == 0)
487b725ae77Skettenis     error
488b725ae77Skettenis       ("Upload file not found: %s.srec\nCheck IP addresses and download path.",
489b725ae77Skettenis        args);
490b725ae77Skettenis   else
491b725ae77Skettenis     printf_filtered (" -- Ethernet load complete.\n");
492b725ae77Skettenis 
493b725ae77Skettenis   end_time = time (NULL);
494b725ae77Skettenis   abfd = bfd_openr (args, 0);
495b725ae77Skettenis   if (abfd != NULL)
496b725ae77Skettenis     {				/* Download is done -- print section statistics */
497b725ae77Skettenis       if (bfd_check_format (abfd, bfd_object) == 0)
498b725ae77Skettenis 	{
499b725ae77Skettenis 	  printf_filtered ("File is not an object file\n");
500b725ae77Skettenis 	}
501b725ae77Skettenis       for (s = abfd->sections; s; s = s->next)
502b725ae77Skettenis 	if (s->flags & SEC_LOAD)
503b725ae77Skettenis 	  {
504b725ae77Skettenis 	    bfd_size_type section_size = bfd_section_size (abfd, s);
505b725ae77Skettenis 	    bfd_vma section_base = bfd_section_lma (abfd, s);
506b725ae77Skettenis 	    unsigned int buffer;
507b725ae77Skettenis 
508b725ae77Skettenis 	    data_count += section_size;
509b725ae77Skettenis 
510b725ae77Skettenis 	    printf_filtered ("Loading section %s, size 0x%lx lma ",
511b725ae77Skettenis 			     bfd_section_name (abfd, s), section_size);
512b725ae77Skettenis 	    print_address_numeric (section_base, 1, gdb_stdout);
513b725ae77Skettenis 	    printf_filtered ("\n");
514b725ae77Skettenis 	    gdb_flush (gdb_stdout);
515b725ae77Skettenis 	  }
516b725ae77Skettenis       /* Finally, make the PC point at the start address */
517b725ae77Skettenis       write_pc (bfd_get_start_address (abfd));
518b725ae77Skettenis       printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));
519b725ae77Skettenis       print_transfer_performance (gdb_stdout, data_count, 0,
520b725ae77Skettenis 				  end_time - start_time);
521b725ae77Skettenis     }
522b725ae77Skettenis   inferior_ptid = null_ptid;	/* No process now */
523b725ae77Skettenis 
524b725ae77Skettenis   /* This is necessary because many things were based on the PC at the
525b725ae77Skettenis      time that we attached to the monitor, which is no longer valid
526b725ae77Skettenis      now that we have loaded new code (and just changed the PC).
527b725ae77Skettenis      Another way to do this might be to call normal_stop, except that
528b725ae77Skettenis      the stack may not be valid, and things would get horribly
529b725ae77Skettenis      confused... */
530b725ae77Skettenis 
531b725ae77Skettenis   clear_symtab_users ();
532b725ae77Skettenis }
533b725ae77Skettenis 
534b725ae77Skettenis void
_initialize_m32r_rom(void)535b725ae77Skettenis _initialize_m32r_rom (void)
536b725ae77Skettenis {
537b725ae77Skettenis   /* Initialize m32r RevC monitor target */
538b725ae77Skettenis   init_m32r_cmds ();
539b725ae77Skettenis   init_monitor_ops (&m32r_ops);
540b725ae77Skettenis 
541b725ae77Skettenis   m32r_ops.to_shortname = "m32r";
542b725ae77Skettenis   m32r_ops.to_longname = "m32r monitor";
543b725ae77Skettenis   m32r_ops.to_load = m32r_load_gen;	/* monitor lacks a download command */
544b725ae77Skettenis   m32r_ops.to_doc = "Debug via the m32r monitor.\n\
545b725ae77Skettenis Specify the serial device it is connected to (e.g. /dev/ttya).";
546b725ae77Skettenis   m32r_ops.to_open = m32r_open;
547b725ae77Skettenis   add_target (&m32r_ops);
548b725ae77Skettenis 
549b725ae77Skettenis   /* Initialize mon2000 monitor target */
550b725ae77Skettenis   init_mon2000_cmds ();
551b725ae77Skettenis   init_monitor_ops (&mon2000_ops);
552b725ae77Skettenis 
553b725ae77Skettenis   mon2000_ops.to_shortname = "mon2000";
554b725ae77Skettenis   mon2000_ops.to_longname = "Mon2000 monitor";
555b725ae77Skettenis   mon2000_ops.to_load = m32r_load_gen;	/* monitor lacks a download command */
556b725ae77Skettenis   mon2000_ops.to_doc = "Debug via the Mon2000 monitor.\n\
557b725ae77Skettenis Specify the serial device it is connected to (e.g. /dev/ttya).";
558b725ae77Skettenis   mon2000_ops.to_open = mon2000_open;
559b725ae77Skettenis   add_target (&mon2000_ops);
560b725ae77Skettenis 
561*11efff7fSkettenis   add_setshow_string_cmd ("download-path", class_obscure, &download_path, "\
562*11efff7fSkettenis Set the default path for downloadable SREC files.", "\
563*11efff7fSkettenis Show the default path for downloadable SREC files.", "\
564*11efff7fSkettenis Determines the default path for downloadable SREC files.", "\
565*11efff7fSkettenis The default path for downloadable SREC files is %s.",
566b725ae77Skettenis 		   NULL, NULL, &setlist, &showlist);
567b725ae77Skettenis 
568*11efff7fSkettenis   add_setshow_string_cmd ("board-address", class_obscure, &board_addr, "\
569*11efff7fSkettenis Set IP address for M32R-EVA target board.", "\
570*11efff7fSkettenis Show IP address for M32R-EVA target board.", "\
571*11efff7fSkettenis Determine the IP address for M32R-EVA target board.", "\
572*11efff7fSkettenis IP address for M32R-EVA target board is %s",
573b725ae77Skettenis 		   NULL, NULL, &setlist, &showlist);
574b725ae77Skettenis 
575*11efff7fSkettenis   add_setshow_string_cmd ("server-address", class_obscure, &server_addr, "\
576*11efff7fSkettenis Set IP address for download server (GDB's host computer).", "\
577*11efff7fSkettenis Show IP address for download server (GDB's host computer).", "\
578*11efff7fSkettenis Determine the IP address for download server (GDB's host computer).", "\
579*11efff7fSkettenis IP address for download server (GDB's host computer) is %s.",
580b725ae77Skettenis 		   NULL, NULL, &setlist, &showlist);
581b725ae77Skettenis 
582b725ae77Skettenis   add_com ("upload", class_obscure, m32r_upload_command,
583b725ae77Skettenis 	   "Upload the srec file via the monitor's Ethernet upload capability.");
584b725ae77Skettenis 
585b725ae77Skettenis   add_com ("tload", class_obscure, m32r_load, "test upload command.");
586b725ae77Skettenis }
587