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, ®val);
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 (¤t_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