xref: /openbsd-src/gnu/usr.bin/binutils/gdb/remote-m32r-sdi.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Remote debugging interface for M32R/SDI.
2b725ae77Skettenis 
3*11efff7fSkettenis    Copyright 2003, 2004 Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    Contributed by Renesas Technology Co.
6b725ae77Skettenis    Written by Kei Sakamoto <sakamoto.kei@renesas.com>.
7b725ae77Skettenis 
8b725ae77Skettenis    This file is part of GDB.
9b725ae77Skettenis 
10b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
11b725ae77Skettenis    it under the terms of the GNU General Public License as published by
12b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
13b725ae77Skettenis    (at your option) any later version.
14b725ae77Skettenis 
15b725ae77Skettenis    This program is distributed in the hope that it will be useful,
16b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
17b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18b725ae77Skettenis    GNU General Public License for more details.
19b725ae77Skettenis 
20b725ae77Skettenis    You should have received a copy of the GNU General Public License
21b725ae77Skettenis    along with this program; if not, write to the Free Software
22b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
23b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
24b725ae77Skettenis 
25b725ae77Skettenis #include "defs.h"
26b725ae77Skettenis #include "gdbcmd.h"
27b725ae77Skettenis #include "gdbcore.h"
28b725ae77Skettenis #include "inferior.h"
29b725ae77Skettenis #include "target.h"
30b725ae77Skettenis #include "regcache.h"
31b725ae77Skettenis #include "gdb_string.h"
32b725ae77Skettenis #include <ctype.h>
33b725ae77Skettenis #include <signal.h>
34b725ae77Skettenis #include <netinet/in.h>
35b725ae77Skettenis #include <sys/types.h>
36b725ae77Skettenis #include <sys/time.h>
37b725ae77Skettenis #include <signal.h>
38b725ae77Skettenis #include <time.h>
39b725ae77Skettenis 
40b725ae77Skettenis 
41b725ae77Skettenis #include "serial.h"
42b725ae77Skettenis 
43b725ae77Skettenis /* Descriptor for I/O to remote machine.  */
44b725ae77Skettenis 
45b725ae77Skettenis static struct serial *sdi_desc = NULL;
46b725ae77Skettenis 
47b725ae77Skettenis #define SDI_TIMEOUT 30
48b725ae77Skettenis 
49b725ae77Skettenis 
50b725ae77Skettenis #define SDIPORT 3232
51b725ae77Skettenis 
52b725ae77Skettenis static char chip_name[64];
53b725ae77Skettenis 
54b725ae77Skettenis static int step_mode;
55b725ae77Skettenis static unsigned long last_pc_addr = 0xffffffff;
56b725ae77Skettenis static unsigned char last_pc_addr_data[2];
57b725ae77Skettenis 
58b725ae77Skettenis static int mmu_on = 0;
59b725ae77Skettenis 
60b725ae77Skettenis static int use_ib_breakpoints = 1;
61b725ae77Skettenis 
62b725ae77Skettenis #define MAX_BREAKPOINTS 1024
63b725ae77Skettenis static int max_ib_breakpoints;
64b725ae77Skettenis static unsigned long bp_address[MAX_BREAKPOINTS];
65b725ae77Skettenis static unsigned char bp_data[MAX_BREAKPOINTS][4];
66b725ae77Skettenis 
67b725ae77Skettenis /* dbt -> nop */
68b725ae77Skettenis static const unsigned char dbt_bp_entry[] = {
69b725ae77Skettenis   0x10, 0xe0, 0x70, 0x00
70b725ae77Skettenis };
71b725ae77Skettenis 
72b725ae77Skettenis #define MAX_ACCESS_BREAKS 4
73b725ae77Skettenis static int max_access_breaks;
74b725ae77Skettenis static unsigned long ab_address[MAX_ACCESS_BREAKS];
75b725ae77Skettenis static unsigned int ab_type[MAX_ACCESS_BREAKS];
76b725ae77Skettenis static unsigned int ab_size[MAX_ACCESS_BREAKS];
77b725ae77Skettenis static CORE_ADDR hit_watchpoint_addr = 0;
78b725ae77Skettenis 
79b725ae77Skettenis static int interrupted = 0;
80b725ae77Skettenis 
81b725ae77Skettenis /* Forward data declarations */
82b725ae77Skettenis extern struct target_ops m32r_ops;
83b725ae77Skettenis 
84b725ae77Skettenis 
85b725ae77Skettenis /* Commands */
86b725ae77Skettenis #define SDI_OPEN                 1
87b725ae77Skettenis #define SDI_CLOSE                2
88b725ae77Skettenis #define SDI_RELEASE              3
89b725ae77Skettenis #define SDI_READ_CPU_REG         4
90b725ae77Skettenis #define SDI_WRITE_CPU_REG        5
91b725ae77Skettenis #define SDI_READ_MEMORY          6
92b725ae77Skettenis #define SDI_WRITE_MEMORY         7
93b725ae77Skettenis #define SDI_EXEC_CPU             8
94b725ae77Skettenis #define SDI_STOP_CPU             9
95b725ae77Skettenis #define SDI_WAIT_FOR_READY      10
96b725ae77Skettenis #define SDI_GET_ATTR            11
97b725ae77Skettenis #define SDI_SET_ATTR            12
98b725ae77Skettenis #define SDI_STATUS              13
99b725ae77Skettenis 
100b725ae77Skettenis /* Attributes */
101b725ae77Skettenis #define SDI_ATTR_NAME            1
102b725ae77Skettenis #define SDI_ATTR_BRK             2
103b725ae77Skettenis #define SDI_ATTR_ABRK            3
104b725ae77Skettenis #define SDI_ATTR_CACHE           4
105b725ae77Skettenis #define SDI_CACHE_TYPE_M32102    0
106b725ae77Skettenis #define SDI_CACHE_TYPE_CHAOS     1
107b725ae77Skettenis #define SDI_ATTR_MEM_ACCESS      5
108b725ae77Skettenis #define SDI_MEM_ACCESS_DEBUG_DMA 0
109b725ae77Skettenis #define SDI_MEM_ACCESS_MON_CODE  1
110b725ae77Skettenis 
111b725ae77Skettenis /* Registers */
112b725ae77Skettenis #define SDI_REG_R0               0
113b725ae77Skettenis #define SDI_REG_R1               1
114b725ae77Skettenis #define SDI_REG_R2               2
115b725ae77Skettenis #define SDI_REG_R3               3
116b725ae77Skettenis #define SDI_REG_R4               4
117b725ae77Skettenis #define SDI_REG_R5               5
118b725ae77Skettenis #define SDI_REG_R6               6
119b725ae77Skettenis #define SDI_REG_R7               7
120b725ae77Skettenis #define SDI_REG_R8               8
121b725ae77Skettenis #define SDI_REG_R9               9
122b725ae77Skettenis #define SDI_REG_R10             10
123b725ae77Skettenis #define SDI_REG_R11             11
124b725ae77Skettenis #define SDI_REG_R12             12
125b725ae77Skettenis #define SDI_REG_FP              13
126b725ae77Skettenis #define SDI_REG_LR              14
127b725ae77Skettenis #define SDI_REG_SP              15
128b725ae77Skettenis #define SDI_REG_PSW             16
129b725ae77Skettenis #define SDI_REG_CBR             17
130b725ae77Skettenis #define SDI_REG_SPI             18
131b725ae77Skettenis #define SDI_REG_SPU             19
132b725ae77Skettenis #define SDI_REG_CR4             20
133b725ae77Skettenis #define SDI_REG_EVB             21
134b725ae77Skettenis #define SDI_REG_BPC             22
135b725ae77Skettenis #define SDI_REG_CR7             23
136b725ae77Skettenis #define SDI_REG_BBPSW           24
137b725ae77Skettenis #define SDI_REG_CR9             25
138b725ae77Skettenis #define SDI_REG_CR10            26
139b725ae77Skettenis #define SDI_REG_CR11            27
140b725ae77Skettenis #define SDI_REG_CR12            28
141b725ae77Skettenis #define SDI_REG_WR              29
142b725ae77Skettenis #define SDI_REG_BBPC            30
143b725ae77Skettenis #define SDI_REG_PBP             31
144b725ae77Skettenis #define SDI_REG_ACCH            32
145b725ae77Skettenis #define SDI_REG_ACCL            33
146b725ae77Skettenis #define SDI_REG_ACC1H           34
147b725ae77Skettenis #define SDI_REG_ACC1L           35
148b725ae77Skettenis 
149b725ae77Skettenis 
150b725ae77Skettenis /* Low level communication functions */
151b725ae77Skettenis 
152b725ae77Skettenis /* Check an ack packet from the target */
153b725ae77Skettenis static int
get_ack(void)154b725ae77Skettenis get_ack (void)
155b725ae77Skettenis {
156b725ae77Skettenis   int c;
157b725ae77Skettenis 
158b725ae77Skettenis   if (!sdi_desc)
159b725ae77Skettenis     return -1;
160b725ae77Skettenis 
161b725ae77Skettenis   c = serial_readchar (sdi_desc, SDI_TIMEOUT);
162b725ae77Skettenis 
163b725ae77Skettenis   if (c < 0)
164b725ae77Skettenis     return -1;
165b725ae77Skettenis 
166b725ae77Skettenis   if (c != '+')			/* error */
167b725ae77Skettenis     return -1;
168b725ae77Skettenis 
169b725ae77Skettenis   return 0;
170b725ae77Skettenis }
171b725ae77Skettenis 
172b725ae77Skettenis /* Send data to the target and check an ack packet */
173b725ae77Skettenis static int
send_data(void * buf,int len)174b725ae77Skettenis send_data (void *buf, int len)
175b725ae77Skettenis {
176b725ae77Skettenis   int ret;
177b725ae77Skettenis 
178b725ae77Skettenis   if (!sdi_desc)
179b725ae77Skettenis     return -1;
180b725ae77Skettenis 
181b725ae77Skettenis   if (serial_write (sdi_desc, buf, len) != 0)
182b725ae77Skettenis     return -1;
183b725ae77Skettenis 
184b725ae77Skettenis   if (get_ack () == -1)
185b725ae77Skettenis     return -1;
186b725ae77Skettenis 
187b725ae77Skettenis   return len;
188b725ae77Skettenis }
189b725ae77Skettenis 
190b725ae77Skettenis /* Receive data from the target */
191b725ae77Skettenis static int
recv_data(void * buf,int len)192b725ae77Skettenis recv_data (void *buf, int len)
193b725ae77Skettenis {
194b725ae77Skettenis   int total = 0;
195b725ae77Skettenis   int c;
196b725ae77Skettenis 
197b725ae77Skettenis   if (!sdi_desc)
198b725ae77Skettenis     return -1;
199b725ae77Skettenis 
200b725ae77Skettenis   while (total < len)
201b725ae77Skettenis     {
202b725ae77Skettenis       c = serial_readchar (sdi_desc, SDI_TIMEOUT);
203b725ae77Skettenis 
204b725ae77Skettenis       if (c < 0)
205b725ae77Skettenis 	return -1;
206b725ae77Skettenis 
207b725ae77Skettenis       ((unsigned char *) buf)[total++] = c;
208b725ae77Skettenis     }
209b725ae77Skettenis 
210b725ae77Skettenis   return len;
211b725ae77Skettenis }
212b725ae77Skettenis 
213b725ae77Skettenis /* Store unsigned long parameter on packet */
214b725ae77Skettenis static void
store_long_parameter(void * buf,long val)215b725ae77Skettenis store_long_parameter (void *buf, long val)
216b725ae77Skettenis {
217b725ae77Skettenis   val = htonl (val);
218b725ae77Skettenis   memcpy (buf, &val, 4);
219b725ae77Skettenis }
220b725ae77Skettenis 
221*11efff7fSkettenis static int
send_cmd(unsigned char cmd)222*11efff7fSkettenis send_cmd (unsigned char cmd)
223*11efff7fSkettenis {
224*11efff7fSkettenis   unsigned char buf[1];
225*11efff7fSkettenis   buf[0] = cmd;
226*11efff7fSkettenis   return send_data (buf, 1);
227*11efff7fSkettenis }
228*11efff7fSkettenis 
229*11efff7fSkettenis static int
send_one_arg_cmd(unsigned char cmd,unsigned char arg1)230*11efff7fSkettenis send_one_arg_cmd (unsigned char cmd, unsigned char arg1)
231*11efff7fSkettenis {
232*11efff7fSkettenis   unsigned char buf[2];
233*11efff7fSkettenis   buf[0] = cmd;
234*11efff7fSkettenis   buf[1] = arg1;
235*11efff7fSkettenis   return send_data (buf, 2);
236*11efff7fSkettenis }
237*11efff7fSkettenis 
238*11efff7fSkettenis static int
send_two_arg_cmd(unsigned char cmd,unsigned char arg1,unsigned long arg2)239*11efff7fSkettenis send_two_arg_cmd (unsigned char cmd, unsigned char arg1, unsigned long arg2)
240*11efff7fSkettenis {
241*11efff7fSkettenis   unsigned char buf[6];
242*11efff7fSkettenis   buf[0] = cmd;
243*11efff7fSkettenis   buf[1] = arg1;
244*11efff7fSkettenis   store_long_parameter (buf + 2, arg2);
245*11efff7fSkettenis   return send_data (buf, 6);
246*11efff7fSkettenis }
247*11efff7fSkettenis 
248*11efff7fSkettenis static int
send_three_arg_cmd(unsigned char cmd,unsigned long arg1,unsigned long arg2,unsigned long arg3)249*11efff7fSkettenis send_three_arg_cmd (unsigned char cmd, unsigned long arg1, unsigned long arg2,
250*11efff7fSkettenis 		    unsigned long arg3)
251*11efff7fSkettenis {
252*11efff7fSkettenis   unsigned char buf[13];
253*11efff7fSkettenis   buf[0] = cmd;
254*11efff7fSkettenis   store_long_parameter (buf + 1, arg1);
255*11efff7fSkettenis   store_long_parameter (buf + 5, arg2);
256*11efff7fSkettenis   store_long_parameter (buf + 9, arg3);
257*11efff7fSkettenis   return send_data (buf, 13);
258*11efff7fSkettenis }
259*11efff7fSkettenis 
260*11efff7fSkettenis static unsigned char
recv_char_data(void)261*11efff7fSkettenis recv_char_data (void)
262*11efff7fSkettenis {
263*11efff7fSkettenis   unsigned char val;
264*11efff7fSkettenis   recv_data (&val, 1);
265*11efff7fSkettenis   return val;
266*11efff7fSkettenis }
267*11efff7fSkettenis 
268*11efff7fSkettenis static unsigned long
recv_long_data(void)269*11efff7fSkettenis recv_long_data (void)
270*11efff7fSkettenis {
271*11efff7fSkettenis   unsigned long val;
272*11efff7fSkettenis   recv_data (&val, 4);
273*11efff7fSkettenis   return ntohl (val);
274*11efff7fSkettenis }
275*11efff7fSkettenis 
276*11efff7fSkettenis 
277b725ae77Skettenis /* Check if MMU is on */
278b725ae77Skettenis static void
check_mmu_status(void)279b725ae77Skettenis check_mmu_status (void)
280b725ae77Skettenis {
281b725ae77Skettenis   unsigned long val;
282b725ae77Skettenis 
283b725ae77Skettenis   /* Read PC address */
284*11efff7fSkettenis   if (send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BPC) == -1)
285b725ae77Skettenis     return;
286*11efff7fSkettenis   val = recv_long_data ();
287b725ae77Skettenis   if ((val & 0xc0000000) == 0x80000000)
288b725ae77Skettenis     {
289b725ae77Skettenis       mmu_on = 1;
290b725ae77Skettenis       return;
291b725ae77Skettenis     }
292b725ae77Skettenis 
293b725ae77Skettenis   /* Read EVB address */
294*11efff7fSkettenis   if (send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_EVB) == -1)
295b725ae77Skettenis     return;
296*11efff7fSkettenis   val = recv_long_data ();
297b725ae77Skettenis   if ((val & 0xc0000000) == 0x80000000)
298b725ae77Skettenis     {
299b725ae77Skettenis       mmu_on = 1;
300b725ae77Skettenis       return;
301b725ae77Skettenis     }
302b725ae77Skettenis 
303b725ae77Skettenis   mmu_on = 0;
304b725ae77Skettenis }
305b725ae77Skettenis 
306b725ae77Skettenis 
307b725ae77Skettenis /* This is called not only when we first attach, but also when the
308b725ae77Skettenis    user types "run" after having attached.  */
309b725ae77Skettenis static void
m32r_create_inferior(char * execfile,char * args,char ** env,int from_tty)310*11efff7fSkettenis m32r_create_inferior (char *execfile, char *args, char **env, int from_tty)
311b725ae77Skettenis {
312b725ae77Skettenis   CORE_ADDR entry_pt;
313b725ae77Skettenis 
314b725ae77Skettenis   if (args && *args)
315b725ae77Skettenis     error ("Cannot pass arguments to remote STDEBUG process");
316b725ae77Skettenis 
317b725ae77Skettenis   if (execfile == 0 || exec_bfd == 0)
318b725ae77Skettenis     error ("No executable file specified");
319b725ae77Skettenis 
320b725ae77Skettenis   if (remote_debug)
321b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_create_inferior(%s,%s)\n", execfile,
322b725ae77Skettenis 			args);
323b725ae77Skettenis 
324b725ae77Skettenis   entry_pt = bfd_get_start_address (exec_bfd);
325b725ae77Skettenis 
326b725ae77Skettenis   /* The "process" (board) is already stopped awaiting our commands, and
327b725ae77Skettenis      the program is already downloaded.  We just set its PC and go.  */
328b725ae77Skettenis 
329b725ae77Skettenis   clear_proceed_status ();
330b725ae77Skettenis 
331b725ae77Skettenis   /* Tell wait_for_inferior that we've started a new process.  */
332b725ae77Skettenis   init_wait_for_inferior ();
333b725ae77Skettenis 
334b725ae77Skettenis   /* Set up the "saved terminal modes" of the inferior
335b725ae77Skettenis      based on what modes we are starting it with.  */
336b725ae77Skettenis   target_terminal_init ();
337b725ae77Skettenis 
338b725ae77Skettenis   /* Install inferior's terminal modes.  */
339b725ae77Skettenis   target_terminal_inferior ();
340b725ae77Skettenis 
341b725ae77Skettenis   proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
342b725ae77Skettenis }
343b725ae77Skettenis 
344b725ae77Skettenis /* Open a connection to a remote debugger.
345b725ae77Skettenis    NAME is the filename used for communication.  */
346b725ae77Skettenis 
347b725ae77Skettenis static void
m32r_open(char * args,int from_tty)348b725ae77Skettenis m32r_open (char *args, int from_tty)
349b725ae77Skettenis {
350b725ae77Skettenis   struct hostent *host_ent;
351b725ae77Skettenis   struct sockaddr_in server_addr;
352b725ae77Skettenis   char *port_str, hostname[256];
353b725ae77Skettenis   int port;
354b725ae77Skettenis   int i, n;
355b725ae77Skettenis   int yes = 1;
356b725ae77Skettenis 
357b725ae77Skettenis   if (remote_debug)
358b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_open(%d)\n", from_tty);
359b725ae77Skettenis 
360b725ae77Skettenis   target_preopen (from_tty);
361b725ae77Skettenis 
362b725ae77Skettenis   push_target (&m32r_ops);
363b725ae77Skettenis 
364b725ae77Skettenis   if (args == NULL)
365b725ae77Skettenis     sprintf (hostname, "localhost:%d", SDIPORT);
366b725ae77Skettenis   else
367b725ae77Skettenis     {
368b725ae77Skettenis       port_str = strchr (args, ':');
369b725ae77Skettenis       if (port_str == NULL)
370b725ae77Skettenis 	sprintf (hostname, "%s:%d", args, SDIPORT);
371b725ae77Skettenis       else
372b725ae77Skettenis 	strcpy (hostname, args);
373b725ae77Skettenis     }
374b725ae77Skettenis 
375b725ae77Skettenis   sdi_desc = serial_open (hostname);
376b725ae77Skettenis   if (!sdi_desc)
377b725ae77Skettenis     error ("Connection refused\n");
378b725ae77Skettenis 
379b725ae77Skettenis   if (get_ack () == -1)
380b725ae77Skettenis     error ("Cannot connect to SDI target\n");
381b725ae77Skettenis 
382*11efff7fSkettenis   if (send_cmd (SDI_OPEN) == -1)
383b725ae77Skettenis     error ("Cannot connect to SDI target\n");
384b725ae77Skettenis 
385b725ae77Skettenis   /* Get maximum number of ib breakpoints */
386*11efff7fSkettenis   send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_BRK);
387*11efff7fSkettenis   max_ib_breakpoints = recv_char_data ();
388b725ae77Skettenis   if (remote_debug)
389b725ae77Skettenis     printf_filtered ("Max IB Breakpoints = %d\n", max_ib_breakpoints);
390b725ae77Skettenis 
391b725ae77Skettenis   /* Initialize breakpoints. */
392b725ae77Skettenis   for (i = 0; i < MAX_BREAKPOINTS; i++)
393b725ae77Skettenis     bp_address[i] = 0xffffffff;
394b725ae77Skettenis 
395b725ae77Skettenis   /* Get maximum number of access breaks. */
396*11efff7fSkettenis   send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_ABRK);
397*11efff7fSkettenis   max_access_breaks = recv_char_data ();
398b725ae77Skettenis   if (remote_debug)
399b725ae77Skettenis     printf_filtered ("Max Access Breaks = %d\n", max_access_breaks);
400b725ae77Skettenis 
401b725ae77Skettenis   /* Initialize access breask. */
402b725ae77Skettenis   for (i = 0; i < MAX_ACCESS_BREAKS; i++)
403b725ae77Skettenis     ab_address[i] = 0x00000000;
404b725ae77Skettenis 
405b725ae77Skettenis   check_mmu_status ();
406b725ae77Skettenis 
407b725ae77Skettenis   /* Get the name of chip on target board. */
408*11efff7fSkettenis   send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_NAME);
409b725ae77Skettenis   recv_data (chip_name, 64);
410b725ae77Skettenis 
411b725ae77Skettenis   if (from_tty)
412b725ae77Skettenis     printf_filtered ("Remote %s connected to %s\n", target_shortname,
413b725ae77Skettenis 		     chip_name);
414b725ae77Skettenis }
415b725ae77Skettenis 
416b725ae77Skettenis /* Close out all files and local state before this target loses control. */
417b725ae77Skettenis 
418b725ae77Skettenis static void
m32r_close(int quitting)419b725ae77Skettenis m32r_close (int quitting)
420b725ae77Skettenis {
421b725ae77Skettenis   if (remote_debug)
422b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_close(%d)\n", quitting);
423b725ae77Skettenis 
424b725ae77Skettenis   if (sdi_desc)
425b725ae77Skettenis     {
426*11efff7fSkettenis       send_cmd (SDI_CLOSE);
427b725ae77Skettenis       serial_close (sdi_desc);
428b725ae77Skettenis       sdi_desc = NULL;
429b725ae77Skettenis     }
430b725ae77Skettenis 
431b725ae77Skettenis   inferior_ptid = null_ptid;
432b725ae77Skettenis   return;
433b725ae77Skettenis }
434b725ae77Skettenis 
435b725ae77Skettenis /* Tell the remote machine to resume.  */
436b725ae77Skettenis 
437b725ae77Skettenis static void
m32r_resume(ptid_t ptid,int step,enum target_signal sig)438b725ae77Skettenis m32r_resume (ptid_t ptid, int step, enum target_signal sig)
439b725ae77Skettenis {
440b725ae77Skettenis   unsigned long pc_addr, bp_addr, ab_addr;
441*11efff7fSkettenis   int ib_breakpoints;
442b725ae77Skettenis   unsigned char buf[13];
443b725ae77Skettenis   int i;
444b725ae77Skettenis 
445b725ae77Skettenis   if (remote_debug)
446b725ae77Skettenis     {
447b725ae77Skettenis       if (step)
448b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(step)\n");
449b725ae77Skettenis       else
450b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(cont)\n");
451b725ae77Skettenis     }
452b725ae77Skettenis 
453b725ae77Skettenis   check_mmu_status ();
454b725ae77Skettenis 
455b725ae77Skettenis   pc_addr = read_pc ();
456b725ae77Skettenis   if (remote_debug)
457b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "pc <= 0x%lx\n", pc_addr);
458b725ae77Skettenis 
459b725ae77Skettenis   /* At pc address there is a parallel instruction with +2 offset,
460b725ae77Skettenis      so we have to make it a serial instruction or avoid it. */
461b725ae77Skettenis   if (pc_addr == last_pc_addr)
462b725ae77Skettenis     {
463b725ae77Skettenis       /* Avoid a parallel nop. */
464b725ae77Skettenis       if (last_pc_addr_data[0] == 0xf0 && last_pc_addr_data[1] == 0x00)
465b725ae77Skettenis 	{
466b725ae77Skettenis 	  pc_addr += 2;
467b725ae77Skettenis 	  /* Now we can forget this instruction. */
468b725ae77Skettenis 	  last_pc_addr = 0xffffffff;
469b725ae77Skettenis 	}
470b725ae77Skettenis       /* Clear a parallel bit. */
471b725ae77Skettenis       else
472b725ae77Skettenis 	{
473b725ae77Skettenis 	  buf[0] = SDI_WRITE_MEMORY;
474b725ae77Skettenis 	  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
475b725ae77Skettenis 	    store_long_parameter (buf + 1, pc_addr);
476b725ae77Skettenis 	  else
477b725ae77Skettenis 	    store_long_parameter (buf + 1, pc_addr - 1);
478b725ae77Skettenis 	  store_long_parameter (buf + 5, 1);
479b725ae77Skettenis 	  buf[9] = last_pc_addr_data[0] & 0x7f;
480b725ae77Skettenis 	  send_data (buf, 10);
481b725ae77Skettenis 	}
482b725ae77Skettenis     }
483b725ae77Skettenis 
484b725ae77Skettenis   /* Set PC. */
485*11efff7fSkettenis   send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BPC, pc_addr);
486b725ae77Skettenis 
487b725ae77Skettenis   /* step mode. */
488b725ae77Skettenis   step_mode = step;
489b725ae77Skettenis   if (step)
490b725ae77Skettenis     {
491b725ae77Skettenis       /* Set PBP. */
492*11efff7fSkettenis       send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PBP, pc_addr | 1);
493b725ae77Skettenis     }
494b725ae77Skettenis   else
495b725ae77Skettenis     {
496*11efff7fSkettenis       /* Unset PBP. */
497*11efff7fSkettenis       send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PBP, 0x00000000);
498*11efff7fSkettenis     }
499b725ae77Skettenis 
500b725ae77Skettenis   if (use_ib_breakpoints)
501b725ae77Skettenis     ib_breakpoints = max_ib_breakpoints;
502b725ae77Skettenis   else
503b725ae77Skettenis     ib_breakpoints = 0;
504b725ae77Skettenis 
505b725ae77Skettenis   /* Set ib breakpoints. */
506b725ae77Skettenis   for (i = 0; i < ib_breakpoints; i++)
507b725ae77Skettenis     {
508b725ae77Skettenis       bp_addr = bp_address[i];
509b725ae77Skettenis 
510*11efff7fSkettenis       if (bp_addr == 0xffffffff)
511*11efff7fSkettenis 	continue;
512*11efff7fSkettenis 
513*11efff7fSkettenis       /* Set PBP. */
514*11efff7fSkettenis       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
515*11efff7fSkettenis 	send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
516*11efff7fSkettenis 			    0x00000006);
517*11efff7fSkettenis       else
518*11efff7fSkettenis 	send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
519*11efff7fSkettenis 			    0x06000000);
520*11efff7fSkettenis 
521*11efff7fSkettenis       send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8080 + 4 * i, 4, bp_addr);
522b725ae77Skettenis     }
523b725ae77Skettenis 
524b725ae77Skettenis   /* Set dbt breakpoints. */
525b725ae77Skettenis   for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
526b725ae77Skettenis     {
527b725ae77Skettenis       bp_addr = bp_address[i];
528*11efff7fSkettenis 
529*11efff7fSkettenis       if (bp_addr == 0xffffffff)
530*11efff7fSkettenis 	continue;
531*11efff7fSkettenis 
532b725ae77Skettenis       if (!mmu_on)
533b725ae77Skettenis 	bp_addr &= 0x7fffffff;
534b725ae77Skettenis 
535b725ae77Skettenis       /* Write DBT instruction. */
536b725ae77Skettenis       buf[0] = SDI_WRITE_MEMORY;
537b725ae77Skettenis       store_long_parameter (buf + 1, bp_addr);
538b725ae77Skettenis       store_long_parameter (buf + 5, 4);
539*11efff7fSkettenis       if ((bp_addr & 2) == 0 && bp_addr != (pc_addr & 0xfffffffc))
540*11efff7fSkettenis 	{
541b725ae77Skettenis 	  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
542b725ae77Skettenis 	    {
543b725ae77Skettenis 	      buf[9] = dbt_bp_entry[0];
544b725ae77Skettenis 	      buf[10] = dbt_bp_entry[1];
545b725ae77Skettenis 	      buf[11] = dbt_bp_entry[2];
546b725ae77Skettenis 	      buf[12] = dbt_bp_entry[3];
547b725ae77Skettenis 	    }
548b725ae77Skettenis 	  else
549b725ae77Skettenis 	    {
550b725ae77Skettenis 	      buf[9] = dbt_bp_entry[3];
551b725ae77Skettenis 	      buf[10] = dbt_bp_entry[2];
552b725ae77Skettenis 	      buf[11] = dbt_bp_entry[1];
553b725ae77Skettenis 	      buf[12] = dbt_bp_entry[0];
554b725ae77Skettenis 	    }
555b725ae77Skettenis 	}
556b725ae77Skettenis       else
557b725ae77Skettenis 	{
558b725ae77Skettenis 	  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
559*11efff7fSkettenis 	    {
560*11efff7fSkettenis 	      if ((bp_addr & 2) == 0)
561b725ae77Skettenis 		{
562b725ae77Skettenis 		  buf[9] = dbt_bp_entry[0];
563b725ae77Skettenis 		  buf[10] = dbt_bp_entry[1];
564*11efff7fSkettenis 		  buf[11] = bp_data[i][2] & 0x7f;
565*11efff7fSkettenis 		  buf[12] = bp_data[i][3];
566*11efff7fSkettenis 		}
567*11efff7fSkettenis 	      else
568*11efff7fSkettenis 		{
569*11efff7fSkettenis 		  buf[9] = bp_data[i][0];
570*11efff7fSkettenis 		  buf[10] = bp_data[i][1];
571*11efff7fSkettenis 		  buf[11] = dbt_bp_entry[0];
572*11efff7fSkettenis 		  buf[12] = dbt_bp_entry[1];
573*11efff7fSkettenis 		}
574*11efff7fSkettenis 	    }
575*11efff7fSkettenis 	  else
576*11efff7fSkettenis 	    {
577*11efff7fSkettenis 	      if ((bp_addr & 2) == 0)
578*11efff7fSkettenis 		{
579*11efff7fSkettenis 		  buf[9] = bp_data[i][0];
580*11efff7fSkettenis 		  buf[10] = bp_data[i][1] & 0x7f;
581*11efff7fSkettenis 		  buf[11] = dbt_bp_entry[1];
582*11efff7fSkettenis 		  buf[12] = dbt_bp_entry[0];
583b725ae77Skettenis 		}
584b725ae77Skettenis 	      else
585b725ae77Skettenis 		{
586b725ae77Skettenis 		  buf[9] = dbt_bp_entry[1];
587b725ae77Skettenis 		  buf[10] = dbt_bp_entry[0];
588*11efff7fSkettenis 		  buf[11] = bp_data[i][2];
589*11efff7fSkettenis 		  buf[12] = bp_data[i][3];
590b725ae77Skettenis 		}
591b725ae77Skettenis 	    }
592b725ae77Skettenis 	}
593*11efff7fSkettenis       send_data (buf, 13);
594*11efff7fSkettenis     }
595b725ae77Skettenis 
596b725ae77Skettenis   /* Set access breaks. */
597b725ae77Skettenis   for (i = 0; i < max_access_breaks; i++)
598b725ae77Skettenis     {
599b725ae77Skettenis       ab_addr = ab_address[i];
600*11efff7fSkettenis 
601*11efff7fSkettenis       if (ab_addr == 0x00000000)
602*11efff7fSkettenis 	continue;
603*11efff7fSkettenis 
604b725ae77Skettenis       /* DBC register */
605b725ae77Skettenis       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
606b725ae77Skettenis 	{
607b725ae77Skettenis 	  switch (ab_type[i])
608b725ae77Skettenis 	    {
609b725ae77Skettenis 	    case 0:		/* write watch */
610*11efff7fSkettenis 	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
611*11efff7fSkettenis 				  0x00000086);
612b725ae77Skettenis 	      break;
613b725ae77Skettenis 	    case 1:		/* read watch */
614*11efff7fSkettenis 	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
615*11efff7fSkettenis 				  0x00000046);
616b725ae77Skettenis 	      break;
617b725ae77Skettenis 	    case 2:		/* access watch */
618*11efff7fSkettenis 	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
619*11efff7fSkettenis 				  0x00000006);
620b725ae77Skettenis 	      break;
621b725ae77Skettenis 	    }
622b725ae77Skettenis 	}
623b725ae77Skettenis       else
624b725ae77Skettenis 	{
625b725ae77Skettenis 	  switch (ab_type[i])
626b725ae77Skettenis 	    {
627b725ae77Skettenis 	    case 0:		/* write watch */
628*11efff7fSkettenis 	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
629*11efff7fSkettenis 				  0x86000000);
630b725ae77Skettenis 	      break;
631b725ae77Skettenis 	    case 1:		/* read watch */
632*11efff7fSkettenis 	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
633*11efff7fSkettenis 				  0x46000000);
634b725ae77Skettenis 	      break;
635b725ae77Skettenis 	    case 2:		/* access watch */
636*11efff7fSkettenis 	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
637*11efff7fSkettenis 				  0x06000000);
638b725ae77Skettenis 	      break;
639b725ae77Skettenis 	    }
640b725ae77Skettenis 	}
641b725ae77Skettenis 
642b725ae77Skettenis       /* DBAH register */
643*11efff7fSkettenis       send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8180 + 4 * i, 4, ab_addr);
644b725ae77Skettenis 
645b725ae77Skettenis       /* DBAL register */
646*11efff7fSkettenis       send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8200 + 4 * i, 4,
647*11efff7fSkettenis 			  0xffffffff);
648b725ae77Skettenis 
649b725ae77Skettenis       /* DBD register */
650*11efff7fSkettenis       send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8280 + 4 * i, 4,
651*11efff7fSkettenis 			  0x00000000);
652b725ae77Skettenis 
653b725ae77Skettenis       /* DBDM register */
654*11efff7fSkettenis       send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8300 + 4 * i, 4,
655*11efff7fSkettenis 			  0x00000000);
656b725ae77Skettenis     }
657b725ae77Skettenis 
658*11efff7fSkettenis   /* Resume program. */
659*11efff7fSkettenis   send_cmd (SDI_EXEC_CPU);
660b725ae77Skettenis 
661b725ae77Skettenis   /* Without this, some commands which require an active target (such as kill)
662b725ae77Skettenis      won't work.  This variable serves (at least) double duty as both the pid
663b725ae77Skettenis      of the target process (if it has such), and as a flag indicating that a
664b725ae77Skettenis      target is active.  These functions should be split out into seperate
665b725ae77Skettenis      variables, especially since GDB will someday have a notion of debugging
666b725ae77Skettenis      several processes.  */
667b725ae77Skettenis   inferior_ptid = pid_to_ptid (32);
668b725ae77Skettenis 
669b725ae77Skettenis   return;
670b725ae77Skettenis }
671b725ae77Skettenis 
672b725ae77Skettenis /* Wait until the remote machine stops, then return,
673b725ae77Skettenis    storing status in STATUS just as `wait' would.  */
674b725ae77Skettenis 
675b725ae77Skettenis static void
gdb_cntrl_c(int signo)676b725ae77Skettenis gdb_cntrl_c (int signo)
677b725ae77Skettenis {
678b725ae77Skettenis   if (remote_debug)
679b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "interrupt\n");
680b725ae77Skettenis   interrupted = 1;
681b725ae77Skettenis }
682b725ae77Skettenis 
683b725ae77Skettenis static ptid_t
m32r_wait(ptid_t ptid,struct target_waitstatus * status)684b725ae77Skettenis m32r_wait (ptid_t ptid, struct target_waitstatus *status)
685b725ae77Skettenis {
686b725ae77Skettenis   static RETSIGTYPE (*prev_sigint) ();
687b725ae77Skettenis   unsigned long bp_addr, pc_addr;
688*11efff7fSkettenis   int ib_breakpoints;
689b725ae77Skettenis   long i;
690b725ae77Skettenis   unsigned char buf[13];
691b725ae77Skettenis   unsigned long val;
692b725ae77Skettenis   int ret, c;
693b725ae77Skettenis 
694b725ae77Skettenis   if (remote_debug)
695b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_wait()\n");
696b725ae77Skettenis 
697b725ae77Skettenis   status->kind = TARGET_WAITKIND_EXITED;
698b725ae77Skettenis   status->value.sig = 0;
699b725ae77Skettenis 
700b725ae77Skettenis   interrupted = 0;
701b725ae77Skettenis   prev_sigint = signal (SIGINT, gdb_cntrl_c);
702b725ae77Skettenis 
703b725ae77Skettenis   /* Wait for ready */
704b725ae77Skettenis   buf[0] = SDI_WAIT_FOR_READY;
705b725ae77Skettenis   if (serial_write (sdi_desc, buf, 1) != 0)
706b725ae77Skettenis     error ("Remote connection closed");
707b725ae77Skettenis 
708b725ae77Skettenis   while (1)
709b725ae77Skettenis     {
710b725ae77Skettenis       c = serial_readchar (sdi_desc, SDI_TIMEOUT);
711b725ae77Skettenis       if (c < 0)
712b725ae77Skettenis 	error ("Remote connection closed");
713b725ae77Skettenis 
714b725ae77Skettenis       if (c == '-')		/* error */
715b725ae77Skettenis 	{
716b725ae77Skettenis 	  status->kind = TARGET_WAITKIND_STOPPED;
717b725ae77Skettenis 	  status->value.sig = TARGET_SIGNAL_HUP;
718b725ae77Skettenis 	  return inferior_ptid;
719b725ae77Skettenis 	}
720b725ae77Skettenis       else if (c == '+')	/* stopped */
721b725ae77Skettenis 	break;
722b725ae77Skettenis 
723b725ae77Skettenis       if (interrupted)
724b725ae77Skettenis 	ret = serial_write (sdi_desc, "!", 1);	/* packet to interrupt */
725b725ae77Skettenis       else
726b725ae77Skettenis 	ret = serial_write (sdi_desc, ".", 1);	/* packet to wait */
727b725ae77Skettenis       if (ret != 0)
728b725ae77Skettenis 	error ("Remote connection closed");
729b725ae77Skettenis     }
730b725ae77Skettenis 
731b725ae77Skettenis   status->kind = TARGET_WAITKIND_STOPPED;
732b725ae77Skettenis   if (interrupted)
733b725ae77Skettenis     status->value.sig = TARGET_SIGNAL_INT;
734b725ae77Skettenis   else
735b725ae77Skettenis     status->value.sig = TARGET_SIGNAL_TRAP;
736b725ae77Skettenis 
737b725ae77Skettenis   interrupted = 0;
738b725ae77Skettenis   signal (SIGINT, prev_sigint);
739b725ae77Skettenis 
740b725ae77Skettenis   check_mmu_status ();
741b725ae77Skettenis 
742b725ae77Skettenis   /* Recover parallel bit. */
743b725ae77Skettenis   if (last_pc_addr != 0xffffffff)
744b725ae77Skettenis     {
745b725ae77Skettenis       buf[0] = SDI_WRITE_MEMORY;
746b725ae77Skettenis       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
747b725ae77Skettenis 	store_long_parameter (buf + 1, last_pc_addr);
748b725ae77Skettenis       else
749b725ae77Skettenis 	store_long_parameter (buf + 1, last_pc_addr - 1);
750b725ae77Skettenis       store_long_parameter (buf + 5, 1);
751b725ae77Skettenis       buf[9] = last_pc_addr_data[0];
752b725ae77Skettenis       send_data (buf, 10);
753b725ae77Skettenis       last_pc_addr = 0xffffffff;
754b725ae77Skettenis     }
755b725ae77Skettenis 
756b725ae77Skettenis   if (use_ib_breakpoints)
757b725ae77Skettenis     ib_breakpoints = max_ib_breakpoints;
758b725ae77Skettenis   else
759b725ae77Skettenis     ib_breakpoints = 0;
760b725ae77Skettenis 
761b725ae77Skettenis   /* Set back pc by 2 if m32r is stopped with dbt. */
762*11efff7fSkettenis   last_pc_addr = 0xffffffff;
763*11efff7fSkettenis   send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BPC);
764*11efff7fSkettenis   pc_addr = recv_long_data () - 2;
765b725ae77Skettenis   for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
766b725ae77Skettenis     {
767b725ae77Skettenis       if (pc_addr == bp_address[i])
768b725ae77Skettenis 	{
769*11efff7fSkettenis 	  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BPC, pc_addr);
770b725ae77Skettenis 
771b725ae77Skettenis 	  /* If there is a parallel instruction with +2 offset at pc
772b725ae77Skettenis 	     address, we have to take care of it later. */
773b725ae77Skettenis 	  if ((pc_addr & 0x2) != 0)
774b725ae77Skettenis 	    {
775b725ae77Skettenis 	      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
776b725ae77Skettenis 		{
777b725ae77Skettenis 		  if ((bp_data[i][2] & 0x80) != 0)
778b725ae77Skettenis 		    {
779b725ae77Skettenis 		      last_pc_addr = pc_addr;
780b725ae77Skettenis 		      last_pc_addr_data[0] = bp_data[i][2];
781b725ae77Skettenis 		      last_pc_addr_data[1] = bp_data[i][3];
782b725ae77Skettenis 		    }
783b725ae77Skettenis 		}
784b725ae77Skettenis 	      else
785b725ae77Skettenis 		{
786b725ae77Skettenis 		  if ((bp_data[i][1] & 0x80) != 0)
787b725ae77Skettenis 		    {
788b725ae77Skettenis 		      last_pc_addr = pc_addr;
789b725ae77Skettenis 		      last_pc_addr_data[0] = bp_data[i][1];
790b725ae77Skettenis 		      last_pc_addr_data[1] = bp_data[i][0];
791b725ae77Skettenis 		    }
792b725ae77Skettenis 		}
793b725ae77Skettenis 	    }
794b725ae77Skettenis 	  break;
795b725ae77Skettenis 	}
796b725ae77Skettenis     }
797b725ae77Skettenis 
798b725ae77Skettenis   /* Remove ib breakpoints. */
799b725ae77Skettenis   for (i = 0; i < ib_breakpoints; i++)
800b725ae77Skettenis     {
801b725ae77Skettenis       if (bp_address[i] != 0xffffffff)
802*11efff7fSkettenis 	send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
803*11efff7fSkettenis 			    0x00000000);
804b725ae77Skettenis     }
805b725ae77Skettenis   /* Remove dbt breakpoints. */
806b725ae77Skettenis   for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
807b725ae77Skettenis     {
808b725ae77Skettenis       bp_addr = bp_address[i];
809b725ae77Skettenis       if (bp_addr != 0xffffffff)
810b725ae77Skettenis 	{
811b725ae77Skettenis 	  if (!mmu_on)
812b725ae77Skettenis 	    bp_addr &= 0x7fffffff;
813*11efff7fSkettenis 	  buf[0] = SDI_READ_MEMORY;
814b725ae77Skettenis 	  store_long_parameter (buf + 1, bp_addr & 0xfffffffc);
815b725ae77Skettenis 	  store_long_parameter (buf + 5, 4);
816b725ae77Skettenis 	  buf[9] = bp_data[i][0];
817b725ae77Skettenis 	  buf[10] = bp_data[i][1];
818b725ae77Skettenis 	  buf[11] = bp_data[i][2];
819b725ae77Skettenis 	  buf[12] = bp_data[i][3];
820b725ae77Skettenis 	  send_data (buf, 13);
821b725ae77Skettenis 	}
822b725ae77Skettenis     }
823b725ae77Skettenis 
824b725ae77Skettenis   /* Remove access breaks. */
825b725ae77Skettenis   hit_watchpoint_addr = 0;
826b725ae77Skettenis   for (i = 0; i < max_access_breaks; i++)
827b725ae77Skettenis     {
828b725ae77Skettenis       if (ab_address[i] != 0x00000000)
829b725ae77Skettenis 	{
830b725ae77Skettenis 	  buf[0] = SDI_READ_MEMORY;
831b725ae77Skettenis 	  store_long_parameter (buf + 1, 0xffff8100 + 4 * i);
832b725ae77Skettenis 	  store_long_parameter (buf + 5, 4);
833b725ae77Skettenis 	  serial_write (sdi_desc, buf, 9);
834b725ae77Skettenis 	  c = serial_readchar (sdi_desc, SDI_TIMEOUT);
835b725ae77Skettenis 	  if (c != '-' && recv_data (buf, 4) != -1)
836b725ae77Skettenis 	    {
837b725ae77Skettenis 	      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
838b725ae77Skettenis 		{
839b725ae77Skettenis 		  if ((buf[3] & 0x1) == 0x1)
840b725ae77Skettenis 		    hit_watchpoint_addr = ab_address[i];
841b725ae77Skettenis 		}
842b725ae77Skettenis 	      else
843b725ae77Skettenis 		{
844b725ae77Skettenis 		  if ((buf[0] & 0x1) == 0x1)
845b725ae77Skettenis 		    hit_watchpoint_addr = ab_address[i];
846b725ae77Skettenis 		}
847b725ae77Skettenis 	    }
848b725ae77Skettenis 
849*11efff7fSkettenis 	  send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
850*11efff7fSkettenis 			      0x00000000);
851b725ae77Skettenis 	}
852b725ae77Skettenis     }
853b725ae77Skettenis 
854b725ae77Skettenis   if (remote_debug)
855b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "pc => 0x%lx\n", pc_addr);
856b725ae77Skettenis 
857b725ae77Skettenis   return inferior_ptid;
858b725ae77Skettenis }
859b725ae77Skettenis 
860b725ae77Skettenis /* Terminate the open connection to the remote debugger.
861b725ae77Skettenis    Use this when you want to detach and do something else
862b725ae77Skettenis    with your gdb.  */
863b725ae77Skettenis static void
m32r_detach(char * args,int from_tty)864b725ae77Skettenis m32r_detach (char *args, int from_tty)
865b725ae77Skettenis {
866b725ae77Skettenis   if (remote_debug)
867b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_detach(%d)\n", from_tty);
868b725ae77Skettenis 
869b725ae77Skettenis   m32r_resume (inferior_ptid, 0, 0);
870b725ae77Skettenis 
871b725ae77Skettenis   /* calls m32r_close to do the real work */
872b725ae77Skettenis   pop_target ();
873b725ae77Skettenis   if (from_tty)
874b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "Ending remote %s debugging\n",
875b725ae77Skettenis 			target_shortname);
876b725ae77Skettenis }
877b725ae77Skettenis 
878b725ae77Skettenis /* Return the id of register number REGNO. */
879b725ae77Skettenis 
880b725ae77Skettenis static int
get_reg_id(int regno)881b725ae77Skettenis get_reg_id (int regno)
882b725ae77Skettenis {
883b725ae77Skettenis   switch (regno)
884b725ae77Skettenis     {
885b725ae77Skettenis     case 20:
886b725ae77Skettenis       return SDI_REG_BBPC;
887b725ae77Skettenis     case 21:
888b725ae77Skettenis       return SDI_REG_BPC;
889b725ae77Skettenis     case 22:
890b725ae77Skettenis       return SDI_REG_ACCL;
891b725ae77Skettenis     case 23:
892b725ae77Skettenis       return SDI_REG_ACCH;
893b725ae77Skettenis     case 24:
894b725ae77Skettenis       return SDI_REG_EVB;
895b725ae77Skettenis     }
896b725ae77Skettenis 
897b725ae77Skettenis   return regno;
898b725ae77Skettenis }
899b725ae77Skettenis 
900b725ae77Skettenis /* Read the remote registers into the block REGS.  */
901b725ae77Skettenis 
902b725ae77Skettenis static void m32r_fetch_register (int);
903b725ae77Skettenis 
904b725ae77Skettenis static void
m32r_fetch_registers(void)905b725ae77Skettenis m32r_fetch_registers (void)
906b725ae77Skettenis {
907b725ae77Skettenis   int regno;
908b725ae77Skettenis 
909b725ae77Skettenis   for (regno = 0; regno < NUM_REGS; regno++)
910b725ae77Skettenis     m32r_fetch_register (regno);
911b725ae77Skettenis }
912b725ae77Skettenis 
913b725ae77Skettenis /* Fetch register REGNO, or all registers if REGNO is -1.
914b725ae77Skettenis    Returns errno value.  */
915b725ae77Skettenis static void
m32r_fetch_register(int regno)916b725ae77Skettenis m32r_fetch_register (int regno)
917b725ae77Skettenis {
918b725ae77Skettenis   unsigned long val, val2, regid;
919b725ae77Skettenis 
920b725ae77Skettenis   if (regno == -1)
921b725ae77Skettenis     m32r_fetch_registers ();
922b725ae77Skettenis   else
923b725ae77Skettenis     {
924b725ae77Skettenis       char buffer[MAX_REGISTER_SIZE];
925b725ae77Skettenis 
926b725ae77Skettenis       regid = get_reg_id (regno);
927*11efff7fSkettenis       send_one_arg_cmd (SDI_READ_CPU_REG, regid);
928*11efff7fSkettenis       val = recv_long_data ();
929b725ae77Skettenis 
930b725ae77Skettenis       if (regid == SDI_REG_PSW)
931b725ae77Skettenis 	{
932*11efff7fSkettenis 	  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
933*11efff7fSkettenis 	  val2 = recv_long_data ();
934b725ae77Skettenis 	  val = ((0x00c1 & val2) << 8) | ((0xc100 & val) >> 8);
935b725ae77Skettenis 	}
936b725ae77Skettenis 
937b725ae77Skettenis       if (remote_debug)
938b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "m32r_fetch_register(%d,0x%08lx)\n",
939b725ae77Skettenis 			    regno, val);
940b725ae77Skettenis 
941b725ae77Skettenis       /* We got the number the register holds, but gdb expects to see a
942b725ae77Skettenis          value in the target byte ordering.  */
943b725ae77Skettenis       store_unsigned_integer (buffer, 4, val);
944*11efff7fSkettenis       regcache_raw_supply (current_regcache, regno, buffer);
945b725ae77Skettenis     }
946b725ae77Skettenis   return;
947b725ae77Skettenis }
948b725ae77Skettenis 
949b725ae77Skettenis /* Store the remote registers from the contents of the block REGS.  */
950b725ae77Skettenis 
951b725ae77Skettenis static void m32r_store_register (int);
952b725ae77Skettenis 
953b725ae77Skettenis static void
m32r_store_registers(void)954b725ae77Skettenis m32r_store_registers (void)
955b725ae77Skettenis {
956b725ae77Skettenis   int regno;
957b725ae77Skettenis 
958b725ae77Skettenis   for (regno = 0; regno < NUM_REGS; regno++)
959b725ae77Skettenis     m32r_store_register (regno);
960b725ae77Skettenis 
961b725ae77Skettenis   registers_changed ();
962b725ae77Skettenis }
963b725ae77Skettenis 
964b725ae77Skettenis /* Store register REGNO, or all if REGNO == 0.
965b725ae77Skettenis    Return errno value.  */
966b725ae77Skettenis static void
m32r_store_register(int regno)967b725ae77Skettenis m32r_store_register (int regno)
968b725ae77Skettenis {
969b725ae77Skettenis   int regid;
970b725ae77Skettenis   ULONGEST regval, tmp;
971b725ae77Skettenis 
972b725ae77Skettenis   if (regno == -1)
973b725ae77Skettenis     m32r_store_registers ();
974b725ae77Skettenis   else
975b725ae77Skettenis     {
976b725ae77Skettenis       regcache_cooked_read_unsigned (current_regcache, regno, &regval);
977b725ae77Skettenis       regid = get_reg_id (regno);
978b725ae77Skettenis 
979b725ae77Skettenis       if (regid == SDI_REG_PSW)
980b725ae77Skettenis 	{
981b725ae77Skettenis 	  unsigned long psw, bbpsw;
982b725ae77Skettenis 
983*11efff7fSkettenis 	  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_PSW);
984*11efff7fSkettenis 	  psw = recv_long_data ();
985b725ae77Skettenis 
986*11efff7fSkettenis 	  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
987*11efff7fSkettenis 	  bbpsw = recv_long_data ();
988b725ae77Skettenis 
989b725ae77Skettenis 	  tmp = (0x00c1 & psw) | ((0x00c1 & regval) << 8);
990*11efff7fSkettenis 	  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PSW, tmp);
991b725ae77Skettenis 
992b725ae77Skettenis 	  tmp = (0x0030 & bbpsw) | ((0xc100 & regval) >> 8);
993*11efff7fSkettenis 	  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BBPSW, tmp);
994b725ae77Skettenis 	}
995b725ae77Skettenis       else
996b725ae77Skettenis 	{
997*11efff7fSkettenis 	  send_two_arg_cmd (SDI_WRITE_CPU_REG, regid, regval);
998b725ae77Skettenis 	}
999b725ae77Skettenis 
1000b725ae77Skettenis       if (remote_debug)
1001b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "m32r_store_register(%d,0x%08lu)\n",
1002b725ae77Skettenis 			    regno, (unsigned long) regval);
1003b725ae77Skettenis     }
1004b725ae77Skettenis }
1005b725ae77Skettenis 
1006b725ae77Skettenis /* Get ready to modify the registers array.  On machines which store
1007b725ae77Skettenis    individual registers, this doesn't need to do anything.  On machines
1008b725ae77Skettenis    which store all the registers in one fell swoop, this makes sure
1009b725ae77Skettenis    that registers contains all the registers from the program being
1010b725ae77Skettenis    debugged.  */
1011b725ae77Skettenis 
1012b725ae77Skettenis static void
m32r_prepare_to_store(void)1013b725ae77Skettenis m32r_prepare_to_store (void)
1014b725ae77Skettenis {
1015b725ae77Skettenis   /* Do nothing, since we can store individual regs */
1016b725ae77Skettenis   if (remote_debug)
1017b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_prepare_to_store()\n");
1018b725ae77Skettenis }
1019b725ae77Skettenis 
1020b725ae77Skettenis static void
m32r_files_info(struct target_ops * target)1021b725ae77Skettenis m32r_files_info (struct target_ops *target)
1022b725ae77Skettenis {
1023b725ae77Skettenis   char *file = "nothing";
1024b725ae77Skettenis 
1025b725ae77Skettenis   if (exec_bfd)
1026b725ae77Skettenis     {
1027b725ae77Skettenis       file = bfd_get_filename (exec_bfd);
1028b725ae77Skettenis       printf_filtered ("\tAttached to %s running program %s\n",
1029b725ae77Skettenis 		       chip_name, file);
1030b725ae77Skettenis     }
1031b725ae77Skettenis }
1032b725ae77Skettenis 
1033b725ae77Skettenis /* Read/Write memory.  */
1034b725ae77Skettenis static int
m32r_xfer_memory(CORE_ADDR memaddr,char * myaddr,int len,int write,struct mem_attrib * attrib,struct target_ops * target)1035b725ae77Skettenis m32r_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
1036b725ae77Skettenis 		  int write,
1037b725ae77Skettenis 		  struct mem_attrib *attrib, struct target_ops *target)
1038b725ae77Skettenis {
1039b725ae77Skettenis   unsigned long taddr;
1040b725ae77Skettenis   unsigned char buf[0x2000];
1041b725ae77Skettenis   int ret, c;
1042b725ae77Skettenis 
1043b725ae77Skettenis   taddr = memaddr;
1044b725ae77Skettenis 
1045b725ae77Skettenis   if (!mmu_on)
1046b725ae77Skettenis     {
1047b725ae77Skettenis       if ((taddr & 0xa0000000) == 0x80000000)
1048b725ae77Skettenis 	taddr &= 0x7fffffff;
1049b725ae77Skettenis     }
1050b725ae77Skettenis 
1051b725ae77Skettenis   if (remote_debug)
1052b725ae77Skettenis     {
1053b725ae77Skettenis       if (write)
1054b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%08lx,%d,write)\n",
1055b725ae77Skettenis 			    memaddr, len);
1056b725ae77Skettenis       else
1057b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%08lx,%d,read)\n",
1058b725ae77Skettenis 			    memaddr, len);
1059b725ae77Skettenis     }
1060b725ae77Skettenis 
1061b725ae77Skettenis   if (write)
1062b725ae77Skettenis     {
1063b725ae77Skettenis       buf[0] = SDI_WRITE_MEMORY;
1064b725ae77Skettenis       store_long_parameter (buf + 1, taddr);
1065b725ae77Skettenis       store_long_parameter (buf + 5, len);
1066b725ae77Skettenis       if (len < 0x1000)
1067b725ae77Skettenis 	{
1068b725ae77Skettenis 	  memcpy (buf + 9, myaddr, len);
1069b725ae77Skettenis 	  ret = send_data (buf, len + 9) - 9;
1070b725ae77Skettenis 	}
1071b725ae77Skettenis       else
1072b725ae77Skettenis 	{
1073b725ae77Skettenis 	  if (serial_write (sdi_desc, buf, 9) != 0)
1074b725ae77Skettenis 	    {
1075b725ae77Skettenis 	      if (remote_debug)
1076b725ae77Skettenis 		fprintf_unfiltered (gdb_stdlog,
1077b725ae77Skettenis 				    "m32r_xfer_memory() failed\n");
1078b725ae77Skettenis 	      return 0;
1079b725ae77Skettenis 	    }
1080b725ae77Skettenis 	  ret = send_data (myaddr, len);
1081b725ae77Skettenis 	}
1082b725ae77Skettenis     }
1083b725ae77Skettenis   else
1084b725ae77Skettenis     {
1085b725ae77Skettenis       buf[0] = SDI_READ_MEMORY;
1086b725ae77Skettenis       store_long_parameter (buf + 1, taddr);
1087b725ae77Skettenis       store_long_parameter (buf + 5, len);
1088b725ae77Skettenis       if (serial_write (sdi_desc, buf, 9) != 0)
1089b725ae77Skettenis 	{
1090b725ae77Skettenis 	  if (remote_debug)
1091b725ae77Skettenis 	    fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n");
1092b725ae77Skettenis 	  return 0;
1093b725ae77Skettenis 	}
1094b725ae77Skettenis 
1095b725ae77Skettenis       c = serial_readchar (sdi_desc, SDI_TIMEOUT);
1096b725ae77Skettenis       if (c < 0 || c == '-')
1097b725ae77Skettenis 	{
1098b725ae77Skettenis 	  if (remote_debug)
1099b725ae77Skettenis 	    fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n");
1100b725ae77Skettenis 	  return 0;
1101b725ae77Skettenis 	}
1102b725ae77Skettenis 
1103b725ae77Skettenis       ret = recv_data (myaddr, len);
1104b725ae77Skettenis     }
1105b725ae77Skettenis 
1106b725ae77Skettenis   if (ret <= 0)
1107b725ae77Skettenis     {
1108b725ae77Skettenis       if (remote_debug)
1109b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() fails\n");
1110b725ae77Skettenis       return 0;
1111b725ae77Skettenis     }
1112b725ae77Skettenis 
1113b725ae77Skettenis   return ret;
1114b725ae77Skettenis }
1115b725ae77Skettenis 
1116b725ae77Skettenis static void
m32r_kill(void)1117b725ae77Skettenis m32r_kill (void)
1118b725ae77Skettenis {
1119b725ae77Skettenis   if (remote_debug)
1120b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_kill()\n");
1121b725ae77Skettenis 
1122b725ae77Skettenis   inferior_ptid = null_ptid;
1123b725ae77Skettenis 
1124b725ae77Skettenis   return;
1125b725ae77Skettenis }
1126b725ae77Skettenis 
1127b725ae77Skettenis /* Clean up when a program exits.
1128b725ae77Skettenis 
1129b725ae77Skettenis    The program actually lives on in the remote processor's RAM, and may be
1130b725ae77Skettenis    run again without a download.  Don't leave it full of breakpoint
1131b725ae77Skettenis    instructions.  */
1132b725ae77Skettenis 
1133b725ae77Skettenis static void
m32r_mourn_inferior(void)1134b725ae77Skettenis m32r_mourn_inferior (void)
1135b725ae77Skettenis {
1136b725ae77Skettenis   if (remote_debug)
1137b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_mourn_inferior()\n");
1138b725ae77Skettenis 
1139b725ae77Skettenis   remove_breakpoints ();
1140b725ae77Skettenis   generic_mourn_inferior ();
1141b725ae77Skettenis }
1142b725ae77Skettenis 
1143b725ae77Skettenis static int
m32r_insert_breakpoint(CORE_ADDR addr,char * shadow)1144b725ae77Skettenis m32r_insert_breakpoint (CORE_ADDR addr, char *shadow)
1145b725ae77Skettenis {
1146b725ae77Skettenis   int ib_breakpoints;
1147b725ae77Skettenis   unsigned char buf[13];
1148b725ae77Skettenis   int i, c;
1149b725ae77Skettenis 
1150b725ae77Skettenis   if (remote_debug)
1151b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%08lx,\"%s\")\n",
1152b725ae77Skettenis 			addr, shadow);
1153b725ae77Skettenis 
1154b725ae77Skettenis   if (use_ib_breakpoints)
1155b725ae77Skettenis     ib_breakpoints = max_ib_breakpoints;
1156b725ae77Skettenis   else
1157b725ae77Skettenis     ib_breakpoints = 0;
1158b725ae77Skettenis 
1159b725ae77Skettenis   for (i = 0; i < MAX_BREAKPOINTS; i++)
1160b725ae77Skettenis     {
1161b725ae77Skettenis       if (bp_address[i] == 0xffffffff)
1162b725ae77Skettenis 	{
1163b725ae77Skettenis 	  bp_address[i] = addr;
1164b725ae77Skettenis 	  if (i >= ib_breakpoints)
1165b725ae77Skettenis 	    {
1166b725ae77Skettenis 	      buf[0] = SDI_READ_MEMORY;
1167b725ae77Skettenis 	      if (mmu_on)
1168b725ae77Skettenis 		store_long_parameter (buf + 1, addr & 0xfffffffc);
1169b725ae77Skettenis 	      else
1170b725ae77Skettenis 		store_long_parameter (buf + 1, addr & 0x7ffffffc);
1171b725ae77Skettenis 	      store_long_parameter (buf + 5, 4);
1172b725ae77Skettenis 	      serial_write (sdi_desc, buf, 9);
1173b725ae77Skettenis 	      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
1174b725ae77Skettenis 	      if (c != '-')
1175b725ae77Skettenis 		recv_data (bp_data[i], 4);
1176b725ae77Skettenis 	    }
1177b725ae77Skettenis 	  return 0;
1178b725ae77Skettenis 	}
1179b725ae77Skettenis     }
1180b725ae77Skettenis 
1181b725ae77Skettenis   error ("Too many breakpoints");
1182b725ae77Skettenis   return 1;
1183b725ae77Skettenis }
1184b725ae77Skettenis 
1185b725ae77Skettenis static int
m32r_remove_breakpoint(CORE_ADDR addr,char * shadow)1186b725ae77Skettenis m32r_remove_breakpoint (CORE_ADDR addr, char *shadow)
1187b725ae77Skettenis {
1188b725ae77Skettenis   int i;
1189b725ae77Skettenis 
1190b725ae77Skettenis   if (remote_debug)
1191b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%08lx,\"%s\")\n",
1192b725ae77Skettenis 			addr, shadow);
1193b725ae77Skettenis 
1194b725ae77Skettenis   for (i = 0; i < MAX_BREAKPOINTS; i++)
1195b725ae77Skettenis     {
1196b725ae77Skettenis       if (bp_address[i] == addr)
1197b725ae77Skettenis 	{
1198b725ae77Skettenis 	  bp_address[i] = 0xffffffff;
1199b725ae77Skettenis 	  break;
1200b725ae77Skettenis 	}
1201b725ae77Skettenis     }
1202b725ae77Skettenis 
1203b725ae77Skettenis   return 0;
1204b725ae77Skettenis }
1205b725ae77Skettenis 
1206b725ae77Skettenis static void
m32r_load(char * args,int from_tty)1207b725ae77Skettenis m32r_load (char *args, int from_tty)
1208b725ae77Skettenis {
1209b725ae77Skettenis   struct cleanup *old_chain;
1210b725ae77Skettenis   asection *section;
1211b725ae77Skettenis   bfd *pbfd;
1212b725ae77Skettenis   bfd_vma entry;
1213b725ae77Skettenis   char *filename;
1214b725ae77Skettenis   int quiet;
1215b725ae77Skettenis   int nostart;
1216b725ae77Skettenis   time_t start_time, end_time;	/* Start and end times of download */
1217b725ae77Skettenis   unsigned long data_count;	/* Number of bytes transferred to memory */
1218b725ae77Skettenis   int ret;
1219b725ae77Skettenis   static RETSIGTYPE (*prev_sigint) ();
1220b725ae77Skettenis 
1221b725ae77Skettenis   /* for direct tcp connections, we can do a fast binary download */
1222b725ae77Skettenis   quiet = 0;
1223b725ae77Skettenis   nostart = 0;
1224b725ae77Skettenis   filename = NULL;
1225b725ae77Skettenis 
1226b725ae77Skettenis   while (*args != '\000')
1227b725ae77Skettenis     {
1228b725ae77Skettenis       char *arg;
1229b725ae77Skettenis 
1230b725ae77Skettenis       while (isspace (*args))
1231b725ae77Skettenis 	args++;
1232b725ae77Skettenis 
1233b725ae77Skettenis       arg = args;
1234b725ae77Skettenis 
1235b725ae77Skettenis       while ((*args != '\000') && !isspace (*args))
1236b725ae77Skettenis 	args++;
1237b725ae77Skettenis 
1238b725ae77Skettenis       if (*args != '\000')
1239b725ae77Skettenis 	*args++ = '\000';
1240b725ae77Skettenis 
1241b725ae77Skettenis       if (*arg != '-')
1242b725ae77Skettenis 	filename = arg;
1243b725ae77Skettenis       else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
1244b725ae77Skettenis 	quiet = 1;
1245b725ae77Skettenis       else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
1246b725ae77Skettenis 	nostart = 1;
1247b725ae77Skettenis       else
1248b725ae77Skettenis 	error ("Unknown option `%s'", arg);
1249b725ae77Skettenis     }
1250b725ae77Skettenis 
1251b725ae77Skettenis   if (!filename)
1252b725ae77Skettenis     filename = get_exec_file (1);
1253b725ae77Skettenis 
1254b725ae77Skettenis   pbfd = bfd_openr (filename, gnutarget);
1255b725ae77Skettenis   if (pbfd == NULL)
1256b725ae77Skettenis     {
1257b725ae77Skettenis       perror_with_name (filename);
1258b725ae77Skettenis       return;
1259b725ae77Skettenis     }
1260b725ae77Skettenis   old_chain = make_cleanup_bfd_close (pbfd);
1261b725ae77Skettenis 
1262b725ae77Skettenis   if (!bfd_check_format (pbfd, bfd_object))
1263b725ae77Skettenis     error ("\"%s\" is not an object file: %s", filename,
1264b725ae77Skettenis 	   bfd_errmsg (bfd_get_error ()));
1265b725ae77Skettenis 
1266b725ae77Skettenis   start_time = time (NULL);
1267b725ae77Skettenis   data_count = 0;
1268b725ae77Skettenis 
1269b725ae77Skettenis   interrupted = 0;
1270b725ae77Skettenis   prev_sigint = signal (SIGINT, gdb_cntrl_c);
1271b725ae77Skettenis 
1272b725ae77Skettenis   for (section = pbfd->sections; section; section = section->next)
1273b725ae77Skettenis     {
1274b725ae77Skettenis       if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
1275b725ae77Skettenis 	{
1276b725ae77Skettenis 	  bfd_vma section_address;
1277b725ae77Skettenis 	  bfd_size_type section_size;
1278b725ae77Skettenis 	  file_ptr fptr;
1279b725ae77Skettenis 	  int n;
1280b725ae77Skettenis 
1281b725ae77Skettenis 	  section_address = bfd_section_lma (pbfd, section);
1282*11efff7fSkettenis 	  section_size = bfd_get_section_size (section);
1283b725ae77Skettenis 
1284b725ae77Skettenis 	  if (!mmu_on)
1285b725ae77Skettenis 	    {
1286b725ae77Skettenis 	      if ((section_address & 0xa0000000) == 0x80000000)
1287b725ae77Skettenis 		section_address &= 0x7fffffff;
1288b725ae77Skettenis 	    }
1289b725ae77Skettenis 
1290b725ae77Skettenis 	  if (!quiet)
1291b725ae77Skettenis 	    printf_filtered ("[Loading section %s at 0x%lx (%d bytes)]\n",
1292b725ae77Skettenis 			     bfd_get_section_name (pbfd, section),
1293b725ae77Skettenis 			     section_address, (int) section_size);
1294b725ae77Skettenis 
1295b725ae77Skettenis 	  fptr = 0;
1296b725ae77Skettenis 
1297b725ae77Skettenis 	  data_count += section_size;
1298b725ae77Skettenis 
1299b725ae77Skettenis 	  n = 0;
1300b725ae77Skettenis 	  while (section_size > 0)
1301b725ae77Skettenis 	    {
1302b725ae77Skettenis 	      char unsigned buf[0x1000 + 9];
1303b725ae77Skettenis 	      int count;
1304b725ae77Skettenis 
1305b725ae77Skettenis 	      count = min (section_size, 0x1000);
1306b725ae77Skettenis 
1307b725ae77Skettenis 	      buf[0] = SDI_WRITE_MEMORY;
1308b725ae77Skettenis 	      store_long_parameter (buf + 1, section_address);
1309b725ae77Skettenis 	      store_long_parameter (buf + 5, count);
1310b725ae77Skettenis 
1311b725ae77Skettenis 	      bfd_get_section_contents (pbfd, section, buf + 9, fptr, count);
1312b725ae77Skettenis 	      if (send_data (buf, count + 9) <= 0)
1313b725ae77Skettenis 		error ("Error while downloading %s section.",
1314b725ae77Skettenis 		       bfd_get_section_name (pbfd, section));
1315b725ae77Skettenis 
1316b725ae77Skettenis 	      if (!quiet)
1317b725ae77Skettenis 		{
1318b725ae77Skettenis 		  printf_unfiltered (".");
1319b725ae77Skettenis 		  if (n++ > 60)
1320b725ae77Skettenis 		    {
1321b725ae77Skettenis 		      printf_unfiltered ("\n");
1322b725ae77Skettenis 		      n = 0;
1323b725ae77Skettenis 		    }
1324b725ae77Skettenis 		  gdb_flush (gdb_stdout);
1325b725ae77Skettenis 		}
1326b725ae77Skettenis 
1327b725ae77Skettenis 	      section_address += count;
1328b725ae77Skettenis 	      fptr += count;
1329b725ae77Skettenis 	      section_size -= count;
1330b725ae77Skettenis 
1331b725ae77Skettenis 	      if (interrupted)
1332b725ae77Skettenis 		break;
1333b725ae77Skettenis 	    }
1334b725ae77Skettenis 
1335b725ae77Skettenis 	  if (!quiet && !interrupted)
1336b725ae77Skettenis 	    {
1337b725ae77Skettenis 	      printf_unfiltered ("done.\n");
1338b725ae77Skettenis 	      gdb_flush (gdb_stdout);
1339b725ae77Skettenis 	    }
1340b725ae77Skettenis 	}
1341b725ae77Skettenis 
1342b725ae77Skettenis       if (interrupted)
1343b725ae77Skettenis 	{
1344b725ae77Skettenis 	  printf_unfiltered ("Interrupted.\n");
1345b725ae77Skettenis 	  break;
1346b725ae77Skettenis 	}
1347b725ae77Skettenis     }
1348b725ae77Skettenis 
1349b725ae77Skettenis   interrupted = 0;
1350b725ae77Skettenis   signal (SIGINT, prev_sigint);
1351b725ae77Skettenis 
1352b725ae77Skettenis   end_time = time (NULL);
1353b725ae77Skettenis 
1354b725ae77Skettenis   /* Make the PC point at the start address */
1355b725ae77Skettenis   if (exec_bfd)
1356b725ae77Skettenis     write_pc (bfd_get_start_address (exec_bfd));
1357b725ae77Skettenis 
1358b725ae77Skettenis   inferior_ptid = null_ptid;	/* No process now */
1359b725ae77Skettenis 
1360b725ae77Skettenis   /* This is necessary because many things were based on the PC at the time
1361b725ae77Skettenis      that we attached to the monitor, which is no longer valid now that we
1362b725ae77Skettenis      have loaded new code (and just changed the PC).  Another way to do this
1363b725ae77Skettenis      might be to call normal_stop, except that the stack may not be valid,
1364b725ae77Skettenis      and things would get horribly confused... */
1365b725ae77Skettenis 
1366b725ae77Skettenis   clear_symtab_users ();
1367b725ae77Skettenis 
1368b725ae77Skettenis   if (!nostart)
1369b725ae77Skettenis     {
1370b725ae77Skettenis       entry = bfd_get_start_address (pbfd);
1371b725ae77Skettenis 
1372b725ae77Skettenis       if (!quiet)
1373b725ae77Skettenis 	printf_unfiltered ("[Starting %s at 0x%lx]\n", filename, entry);
1374b725ae77Skettenis     }
1375b725ae77Skettenis 
1376b725ae77Skettenis   print_transfer_performance (gdb_stdout, data_count, 0,
1377b725ae77Skettenis 			      end_time - start_time);
1378b725ae77Skettenis 
1379b725ae77Skettenis   do_cleanups (old_chain);
1380b725ae77Skettenis }
1381b725ae77Skettenis 
1382b725ae77Skettenis static void
m32r_stop(void)1383b725ae77Skettenis m32r_stop (void)
1384b725ae77Skettenis {
1385b725ae77Skettenis   if (remote_debug)
1386b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_stop()\n");
1387b725ae77Skettenis 
1388*11efff7fSkettenis   send_cmd (SDI_STOP_CPU);
1389b725ae77Skettenis 
1390b725ae77Skettenis   return;
1391b725ae77Skettenis }
1392b725ae77Skettenis 
1393b725ae77Skettenis 
1394b725ae77Skettenis /* Tell whether this target can support a hardware breakpoint.  CNT
1395b725ae77Skettenis    is the number of hardware breakpoints already installed.  This
1396b725ae77Skettenis    implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro.  */
1397b725ae77Skettenis 
1398b725ae77Skettenis int
m32r_can_use_hw_watchpoint(int type,int cnt,int othertype)1399b725ae77Skettenis m32r_can_use_hw_watchpoint (int type, int cnt, int othertype)
1400b725ae77Skettenis {
1401b725ae77Skettenis   return sdi_desc != NULL && cnt < max_access_breaks;
1402b725ae77Skettenis }
1403b725ae77Skettenis 
1404b725ae77Skettenis /* Set a data watchpoint.  ADDR and LEN should be obvious.  TYPE is 0
1405b725ae77Skettenis    for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
1406b725ae77Skettenis    watchpoint. */
1407b725ae77Skettenis 
1408b725ae77Skettenis int
m32r_insert_watchpoint(CORE_ADDR addr,int len,int type)1409b725ae77Skettenis m32r_insert_watchpoint (CORE_ADDR addr, int len, int type)
1410b725ae77Skettenis {
1411b725ae77Skettenis   int i;
1412b725ae77Skettenis 
1413b725ae77Skettenis   if (remote_debug)
1414b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_insert_watchpoint(%08lx,%d,%d)\n",
1415b725ae77Skettenis 			addr, len, type);
1416b725ae77Skettenis 
1417b725ae77Skettenis   for (i = 0; i < MAX_ACCESS_BREAKS; i++)
1418b725ae77Skettenis     {
1419b725ae77Skettenis       if (ab_address[i] == 0x00000000)
1420b725ae77Skettenis 	{
1421b725ae77Skettenis 	  ab_address[i] = addr;
1422b725ae77Skettenis 	  ab_size[i] = len;
1423b725ae77Skettenis 	  ab_type[i] = type;
1424b725ae77Skettenis 	  return 0;
1425b725ae77Skettenis 	}
1426b725ae77Skettenis     }
1427b725ae77Skettenis 
1428b725ae77Skettenis   error ("Too many watchpoints");
1429b725ae77Skettenis   return 1;
1430b725ae77Skettenis }
1431b725ae77Skettenis 
1432b725ae77Skettenis int
m32r_remove_watchpoint(CORE_ADDR addr,int len,int type)1433b725ae77Skettenis m32r_remove_watchpoint (CORE_ADDR addr, int len, int type)
1434b725ae77Skettenis {
1435b725ae77Skettenis   int i;
1436b725ae77Skettenis 
1437b725ae77Skettenis   if (remote_debug)
1438b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_remove_watchpoint(%08lx,%d,%d)\n",
1439b725ae77Skettenis 			addr, len, type);
1440b725ae77Skettenis 
1441b725ae77Skettenis   for (i = 0; i < MAX_ACCESS_BREAKS; i++)
1442b725ae77Skettenis     {
1443b725ae77Skettenis       if (ab_address[i] == addr)
1444b725ae77Skettenis 	{
1445b725ae77Skettenis 	  ab_address[i] = 0x00000000;
1446b725ae77Skettenis 	  break;
1447b725ae77Skettenis 	}
1448b725ae77Skettenis     }
1449b725ae77Skettenis 
1450b725ae77Skettenis   return 0;
1451b725ae77Skettenis }
1452b725ae77Skettenis 
1453*11efff7fSkettenis int
m32r_stopped_data_address(struct target_ops * target,CORE_ADDR * addr_p)1454*11efff7fSkettenis m32r_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
1455b725ae77Skettenis {
1456*11efff7fSkettenis   int rc = 0;
1457*11efff7fSkettenis   if (hit_watchpoint_addr != 0x00000000)
1458*11efff7fSkettenis     {
1459*11efff7fSkettenis       *addr_p = hit_watchpoint_addr;
1460*11efff7fSkettenis       rc = 1;
1461*11efff7fSkettenis     }
1462*11efff7fSkettenis   return rc;
1463b725ae77Skettenis }
1464b725ae77Skettenis 
1465b725ae77Skettenis int
m32r_stopped_by_watchpoint(void)1466b725ae77Skettenis m32r_stopped_by_watchpoint (void)
1467b725ae77Skettenis {
1468*11efff7fSkettenis   CORE_ADDR addr;
1469*11efff7fSkettenis   return m32r_stopped_data_address (&current_target, &addr);
1470b725ae77Skettenis }
1471b725ae77Skettenis 
1472b725ae77Skettenis 
1473b725ae77Skettenis static void
sdireset_command(char * args,int from_tty)1474b725ae77Skettenis sdireset_command (char *args, int from_tty)
1475b725ae77Skettenis {
1476b725ae77Skettenis   if (remote_debug)
1477b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n");
1478b725ae77Skettenis 
1479*11efff7fSkettenis   send_cmd (SDI_OPEN);
1480b725ae77Skettenis 
1481b725ae77Skettenis   inferior_ptid = null_ptid;
1482b725ae77Skettenis }
1483b725ae77Skettenis 
1484b725ae77Skettenis 
1485b725ae77Skettenis static void
sdistatus_command(char * args,int from_tty)1486b725ae77Skettenis sdistatus_command (char *args, int from_tty)
1487b725ae77Skettenis {
1488b725ae77Skettenis   unsigned char buf[4096];
1489b725ae77Skettenis   int i, c;
1490b725ae77Skettenis 
1491b725ae77Skettenis   if (remote_debug)
1492b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n");
1493b725ae77Skettenis 
1494b725ae77Skettenis   if (!sdi_desc)
1495b725ae77Skettenis     return;
1496b725ae77Skettenis 
1497*11efff7fSkettenis   send_cmd (SDI_STATUS);
1498b725ae77Skettenis   for (i = 0; i < 4096; i++)
1499b725ae77Skettenis     {
1500b725ae77Skettenis       c = serial_readchar (sdi_desc, SDI_TIMEOUT);
1501b725ae77Skettenis       if (c < 0)
1502b725ae77Skettenis 	return;
1503b725ae77Skettenis       buf[i] = c;
1504b725ae77Skettenis       if (c == 0)
1505b725ae77Skettenis 	break;
1506b725ae77Skettenis     }
1507b725ae77Skettenis 
1508b725ae77Skettenis   printf_filtered ("%s", buf);
1509b725ae77Skettenis }
1510b725ae77Skettenis 
1511b725ae77Skettenis 
1512b725ae77Skettenis static void
debug_chaos_command(char * args,int from_tty)1513b725ae77Skettenis debug_chaos_command (char *args, int from_tty)
1514b725ae77Skettenis {
1515b725ae77Skettenis   unsigned char buf[3];
1516b725ae77Skettenis 
1517b725ae77Skettenis   buf[0] = SDI_SET_ATTR;
1518b725ae77Skettenis   buf[1] = SDI_ATTR_CACHE;
1519b725ae77Skettenis   buf[2] = SDI_CACHE_TYPE_CHAOS;
1520b725ae77Skettenis   send_data (buf, 3);
1521b725ae77Skettenis }
1522b725ae77Skettenis 
1523b725ae77Skettenis 
1524b725ae77Skettenis static void
use_debug_dma_command(char * args,int from_tty)1525b725ae77Skettenis use_debug_dma_command (char *args, int from_tty)
1526b725ae77Skettenis {
1527b725ae77Skettenis   unsigned char buf[3];
1528b725ae77Skettenis 
1529b725ae77Skettenis   buf[0] = SDI_SET_ATTR;
1530b725ae77Skettenis   buf[1] = SDI_ATTR_MEM_ACCESS;
1531b725ae77Skettenis   buf[2] = SDI_MEM_ACCESS_DEBUG_DMA;
1532b725ae77Skettenis   send_data (buf, 3);
1533b725ae77Skettenis }
1534b725ae77Skettenis 
1535b725ae77Skettenis static void
use_mon_code_command(char * args,int from_tty)1536b725ae77Skettenis use_mon_code_command (char *args, int from_tty)
1537b725ae77Skettenis {
1538b725ae77Skettenis   unsigned char buf[3];
1539b725ae77Skettenis 
1540b725ae77Skettenis   buf[0] = SDI_SET_ATTR;
1541b725ae77Skettenis   buf[1] = SDI_ATTR_MEM_ACCESS;
1542b725ae77Skettenis   buf[2] = SDI_MEM_ACCESS_MON_CODE;
1543b725ae77Skettenis   send_data (buf, 3);
1544b725ae77Skettenis }
1545b725ae77Skettenis 
1546b725ae77Skettenis 
1547b725ae77Skettenis static void
use_ib_breakpoints_command(char * args,int from_tty)1548b725ae77Skettenis use_ib_breakpoints_command (char *args, int from_tty)
1549b725ae77Skettenis {
1550b725ae77Skettenis   use_ib_breakpoints = 1;
1551b725ae77Skettenis }
1552b725ae77Skettenis 
1553b725ae77Skettenis static void
use_dbt_breakpoints_command(char * args,int from_tty)1554b725ae77Skettenis use_dbt_breakpoints_command (char *args, int from_tty)
1555b725ae77Skettenis {
1556b725ae77Skettenis   use_ib_breakpoints = 0;
1557b725ae77Skettenis }
1558b725ae77Skettenis 
1559b725ae77Skettenis 
1560b725ae77Skettenis /* Define the target subroutine names */
1561b725ae77Skettenis 
1562b725ae77Skettenis struct target_ops m32r_ops;
1563b725ae77Skettenis 
1564b725ae77Skettenis static void
init_m32r_ops(void)1565b725ae77Skettenis init_m32r_ops (void)
1566b725ae77Skettenis {
1567b725ae77Skettenis   m32r_ops.to_shortname = "m32rsdi";
1568b725ae77Skettenis   m32r_ops.to_longname = "Remote M32R debugging over SDI interface";
1569b725ae77Skettenis   m32r_ops.to_doc = "Use an M32R board using SDI debugging protocol.";
1570b725ae77Skettenis   m32r_ops.to_open = m32r_open;
1571b725ae77Skettenis   m32r_ops.to_close = m32r_close;
1572b725ae77Skettenis   m32r_ops.to_detach = m32r_detach;
1573b725ae77Skettenis   m32r_ops.to_resume = m32r_resume;
1574b725ae77Skettenis   m32r_ops.to_wait = m32r_wait;
1575b725ae77Skettenis   m32r_ops.to_fetch_registers = m32r_fetch_register;
1576b725ae77Skettenis   m32r_ops.to_store_registers = m32r_store_register;
1577b725ae77Skettenis   m32r_ops.to_prepare_to_store = m32r_prepare_to_store;
1578*11efff7fSkettenis   m32r_ops.deprecated_xfer_memory = m32r_xfer_memory;
1579b725ae77Skettenis   m32r_ops.to_files_info = m32r_files_info;
1580b725ae77Skettenis   m32r_ops.to_insert_breakpoint = m32r_insert_breakpoint;
1581b725ae77Skettenis   m32r_ops.to_remove_breakpoint = m32r_remove_breakpoint;
1582b725ae77Skettenis   m32r_ops.to_can_use_hw_breakpoint = m32r_can_use_hw_watchpoint;
1583b725ae77Skettenis   m32r_ops.to_insert_watchpoint = m32r_insert_watchpoint;
1584b725ae77Skettenis   m32r_ops.to_remove_watchpoint = m32r_remove_watchpoint;
1585b725ae77Skettenis   m32r_ops.to_stopped_by_watchpoint = m32r_stopped_by_watchpoint;
1586b725ae77Skettenis   m32r_ops.to_stopped_data_address = m32r_stopped_data_address;
1587b725ae77Skettenis   m32r_ops.to_kill = m32r_kill;
1588b725ae77Skettenis   m32r_ops.to_load = m32r_load;
1589b725ae77Skettenis   m32r_ops.to_create_inferior = m32r_create_inferior;
1590b725ae77Skettenis   m32r_ops.to_mourn_inferior = m32r_mourn_inferior;
1591b725ae77Skettenis   m32r_ops.to_stop = m32r_stop;
1592b725ae77Skettenis   m32r_ops.to_stratum = process_stratum;
1593b725ae77Skettenis   m32r_ops.to_has_all_memory = 1;
1594b725ae77Skettenis   m32r_ops.to_has_memory = 1;
1595b725ae77Skettenis   m32r_ops.to_has_stack = 1;
1596b725ae77Skettenis   m32r_ops.to_has_registers = 1;
1597b725ae77Skettenis   m32r_ops.to_has_execution = 1;
1598b725ae77Skettenis   m32r_ops.to_magic = OPS_MAGIC;
1599b725ae77Skettenis };
1600b725ae77Skettenis 
1601b725ae77Skettenis 
1602b725ae77Skettenis extern initialize_file_ftype _initialize_remote_m32r;
1603b725ae77Skettenis 
1604b725ae77Skettenis void
_initialize_remote_m32r(void)1605b725ae77Skettenis _initialize_remote_m32r (void)
1606b725ae77Skettenis {
1607b725ae77Skettenis   int i;
1608b725ae77Skettenis 
1609b725ae77Skettenis   init_m32r_ops ();
1610b725ae77Skettenis 
1611b725ae77Skettenis   /* Initialize breakpoints. */
1612b725ae77Skettenis   for (i = 0; i < MAX_BREAKPOINTS; i++)
1613b725ae77Skettenis     bp_address[i] = 0xffffffff;
1614b725ae77Skettenis 
1615b725ae77Skettenis   /* Initialize access breaks. */
1616b725ae77Skettenis   for (i = 0; i < MAX_ACCESS_BREAKS; i++)
1617b725ae77Skettenis     ab_address[i] = 0x00000000;
1618b725ae77Skettenis 
1619b725ae77Skettenis   add_target (&m32r_ops);
1620b725ae77Skettenis 
1621b725ae77Skettenis   add_com ("sdireset", class_obscure, sdireset_command,
1622b725ae77Skettenis 	   "Reset SDI connection.");
1623b725ae77Skettenis 
1624b725ae77Skettenis   add_com ("sdistatus", class_obscure, sdistatus_command,
1625b725ae77Skettenis 	   "Show status of SDI connection.");
1626b725ae77Skettenis 
1627b725ae77Skettenis   add_com ("debug_chaos", class_obscure, debug_chaos_command,
1628b725ae77Skettenis 	   "Debug M32R/Chaos.");
1629b725ae77Skettenis 
1630b725ae77Skettenis   add_com ("use_debug_dma", class_obscure, use_debug_dma_command,
1631b725ae77Skettenis 	   "Use debug DMA mem access.");
1632b725ae77Skettenis   add_com ("use_mon_code", class_obscure, use_mon_code_command,
1633b725ae77Skettenis 	   "Use mon code mem access.");
1634b725ae77Skettenis 
1635b725ae77Skettenis   add_com ("use_ib_break", class_obscure, use_ib_breakpoints_command,
1636b725ae77Skettenis 	   "Set breakpoints by IB break.");
1637b725ae77Skettenis   add_com ("use_dbt_break", class_obscure, use_dbt_breakpoints_command,
1638b725ae77Skettenis 	   "Set breakpoints by dbt.");
1639b725ae77Skettenis }
1640