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