]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/remote-rdi.c
2005-02-14 Andrew Cagney <cagney@gnu.org>
[thirdparty/binutils-gdb.git] / gdb / remote-rdi.c
CommitLineData
c906108c 1/* GDB interface to ARM RDI library.
0a65a603 2
3b64bf98 3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2004 Free Software
0a65a603 4 Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "gdb_string.h"
25#include <fcntl.h>
26#include "frame.h"
27#include "inferior.h"
28#include "bfd.h"
29#include "symfile.h"
30#include "target.h"
c906108c
SS
31#include "gdbcmd.h"
32#include "objfiles.h"
33#include "gdb-stabs.h"
34#include "gdbthread.h"
35#include "gdbcore.h"
da59e081 36#include "breakpoint.h"
fa58ee11 37#include "completer.h"
4e052eda 38#include "regcache.h"
9ae9b4ea 39#include "arm-tdep.h"
c906108c 40
c906108c
SS
41#include <signal.h>
42
43#include "rdi-share/ardi.h"
44#include "rdi-share/adp.h"
45#include "rdi-share/hsys.h"
46
a14ed312 47extern int isascii (int);
c906108c
SS
48
49/* Prototypes for local functions */
50
a14ed312 51static void arm_rdi_files_info (struct target_ops *ignore);
c906108c 52
a14ed312
KB
53static int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr,
54 int len, int should_write,
29e57380 55 struct mem_attrib *attrib,
a14ed312 56 struct target_ops *target);
c906108c 57
a14ed312 58static void arm_rdi_prepare_to_store (void);
c906108c 59
a14ed312 60static void arm_rdi_fetch_registers (int regno);
c906108c 61
39f77062
KB
62static void arm_rdi_resume (ptid_t pid, int step,
63 enum target_signal siggnal);
c906108c 64
a14ed312 65static void arm_rdi_open (char *name, int from_tty);
c906108c 66
a14ed312 67static void arm_rdi_close (int quitting);
c906108c 68
a14ed312 69static void arm_rdi_store_registers (int regno);
c906108c 70
cb90e81a 71static ptid_t arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status);
c906108c 72
a14ed312 73static void arm_rdi_kill (void);
c906108c 74
a14ed312 75static void arm_rdi_detach (char *args, int from_tty);
c906108c 76
a14ed312 77static int arm_rdi_insert_breakpoint (CORE_ADDR, char *);
c906108c 78
a14ed312 79static int arm_rdi_remove_breakpoint (CORE_ADDR, char *);
c906108c 80
a14ed312 81static char *rdi_error_message (int err);
c906108c 82
a14ed312 83static enum target_signal rdi_error_signal (int err);
c906108c
SS
84
85/* Global variables. */
86
87struct target_ops arm_rdi_ops;
88
89static struct Dbg_ConfigBlock gdb_config;
90
91static struct Dbg_HostosInterface gdb_hostif;
92
93static int max_load_size;
94
95static int execute_status;
96
5c44784c 97/* Send heatbeat packets? */
4ce44c66 98static int rdi_heartbeat = 0;
5c44784c
JM
99
100/* Target has ROM at address 0. */
101static int rom_at_zero = 0;
102
103/* Enable logging? */
4ce44c66 104static int log_enable = 0;
5c44784c
JM
105
106/* Name of the log file. Default is "rdi.log". */
107static char *log_filename;
108
c906108c
SS
109/* A little list of breakpoints that have been set. */
110
c5aa993b
JM
111static struct local_bp_list_entry
112 {
113 CORE_ADDR addr;
114 PointHandle point;
115 struct local_bp_list_entry *next;
116 }
117 *local_bp_list;
c906108c 118\f
c906108c
SS
119/* Helper callbacks for the "host interface" structure. RDI functions call
120 these to forward output from the target system and so forth. */
121
a78f21af 122static void
3bb04bdd 123voiddummy (void *dummy)
c906108c
SS
124{
125 fprintf_unfiltered (gdb_stdout, "void dummy\n");
126}
127
128static void
6ccc741d 129myprint (void *arg, const char *format, va_list ap)
c906108c
SS
130{
131 vfprintf_unfiltered (gdb_stdout, format, ap);
132}
133
134static void
6ccc741d 135mywritec (void *arg, int c)
c906108c
SS
136{
137 if (isascii (c))
138 fputc_unfiltered (c, gdb_stdout);
139}
140
141static int
6ccc741d 142mywrite (void *arg, char const *buffer, int len)
c906108c
SS
143{
144 int i;
145 char *e;
146
147 e = (char *) buffer;
148 for (i = 0; i < len; i++)
c5aa993b 149 {
c906108c 150 if (isascii ((int) *e))
c5aa993b
JM
151 {
152 fputc_unfiltered ((int) *e, gdb_stdout);
153 e++;
154 }
155 }
c906108c
SS
156
157 return len;
158}
159
160static void
6ccc741d 161mypause (void *arg)
c906108c
SS
162{
163}
164
165/* These last two are tricky as we have to handle the special case of
166 being interrupted more carefully */
167
168static int
6ccc741d 169myreadc (void *arg)
c5aa993b 170{
c906108c
SS
171 return fgetc (stdin);
172}
173
174static char *
6ccc741d 175mygets (void *arg, char *buffer, int len)
c906108c 176{
c5aa993b 177 return fgets (buffer, len, stdin);
c906108c
SS
178}
179
180/* Prevent multiple calls to angel_RDI_close(). */
181static int closed_already = 1;
182
183/* Open a connection to a remote debugger. NAME is the filename used
184 for communication. */
185
186static void
fba45db2 187arm_rdi_open (char *name, int from_tty)
c906108c
SS
188{
189 int rslt, i;
190 unsigned long arg1, arg2;
5c44784c
JM
191 char *openArgs = NULL;
192 char *devName = NULL;
193 char *p;
c906108c
SS
194
195 if (name == NULL)
8a3fe4f8
AC
196 error (_("To open an RDI connection, you need to specify what serial\n\
197device is attached to the remote system (e.g. /dev/ttya)."));
c906108c 198
5c44784c
JM
199 /* split name after whitespace, pass tail as arg to open command */
200
c2d11a7d 201 devName = xstrdup (name);
4ce44c66 202 p = strchr (devName, ' ');
5c44784c
JM
203 if (p)
204 {
205 *p = '\0';
206 ++p;
207
208 while (*p == ' ')
209 ++p;
210
211 openArgs = p;
212 }
213
c906108c
SS
214 /* Make the basic low-level connection. */
215
c5394b80 216 arm_rdi_close (0);
5c44784c 217 rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat);
c906108c
SS
218
219 if (rslt != adp_ok)
8a3fe4f8 220 error (_("Could not open device \"%s\""), name);
c906108c 221
d7449b42 222 gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 1 : 0);
c906108c
SS
223 gdb_config.fpe = 1;
224 gdb_config.rditype = 2;
225 gdb_config.heartbeat_on = 1;
226 gdb_config.flags = 2;
227
228 gdb_hostif.dbgprint = myprint;
229 gdb_hostif.dbgpause = mypause;
230 gdb_hostif.dbgarg = NULL;
231 gdb_hostif.writec = mywritec;
232 gdb_hostif.readc = myreadc;
233 gdb_hostif.write = mywrite;
234 gdb_hostif.gets = mygets;
235 gdb_hostif.hostosarg = NULL;
236 gdb_hostif.reset = voiddummy;
237
238 rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
239 if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
c5aa993b 240 ; /* do nothing, this is the expected return */
6ccc741d 241 else if (rslt != RDIError_NoError)
c906108c
SS
242 {
243 printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
2acceee2 244 Adp_CloseDevice ();
8a3fe4f8 245 error (_("RDI_open failed."));
c906108c
SS
246 }
247
248 rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
6ccc741d 249 if (rslt != RDIError_NoError)
c906108c
SS
250 {
251 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
252 }
253 rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
6ccc741d 254 if (rslt != RDIError_NoError)
c906108c
SS
255 {
256 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
257 }
258 rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
6ccc741d 259 if (rslt != RDIError_NoError)
c906108c
SS
260 {
261 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
262 }
263 rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
6ccc741d 264 if (rslt != RDIError_NoError)
c906108c
SS
265 {
266 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
267 }
268 rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
6ccc741d 269 if (rslt != RDIError_NoError)
c906108c
SS
270 {
271 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
272 }
273
274 rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
6ccc741d 275 if (rslt != RDIError_NoError)
c906108c
SS
276 {
277 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
278 }
279 max_load_size = arg1;
280
281 push_target (&arm_rdi_ops);
282
283 target_fetch_registers (-1);
284
285 rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
6ccc741d 286 if (rslt != RDIError_NoError)
c906108c
SS
287 {
288 printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
289 }
290
5c44784c
JM
291 arg1 = rom_at_zero ? 0x0 : 0x13b;
292
c906108c 293 rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
6ccc741d 294 if (rslt != RDIError_NoError)
c906108c
SS
295 {
296 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
297 }
298
299 arg1 = (unsigned long) "";
300 rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
6ccc741d 301 if (rslt != RDIError_NoError)
c906108c
SS
302 {
303 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
304 }
305
306 /* Clear out any existing records of breakpoints. */
307 {
308 struct local_bp_list_entry *entry, *preventry = NULL;
309
310 for (entry = local_bp_list; entry != NULL; entry = entry->next)
311 {
312 if (preventry)
b8c9b27d 313 xfree (preventry);
c906108c
SS
314 }
315 }
316
317 printf_filtered ("Connected to ARM RDI target.\n");
318 closed_already = 0;
39f77062 319 inferior_ptid = pid_to_ptid (42);
c906108c
SS
320}
321
39f77062 322/* Start an inferior process and set inferior_ptid to its pid.
c906108c
SS
323 EXEC_FILE is the file to run.
324 ARGS is a string containing the arguments to the program.
325 ENV is the environment vector to pass. Errors reported with error().
326 On VxWorks and various standalone systems, we ignore exec_file. */
327/* This is called not only when we first attach, but also when the
328 user types "run" after having attached. */
329
330static void
c27cda74 331arm_rdi_create_inferior (char *exec_file, char *args, char **env, int from_tty)
c906108c
SS
332{
333 int len, rslt;
334 unsigned long arg1, arg2;
335 char *arg_buf;
336 CORE_ADDR entry_point;
337
338 if (exec_file == 0 || exec_bfd == 0)
8a3fe4f8 339 error (_("No executable file specified."));
c906108c
SS
340
341 entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
342
c5aa993b 343 arm_rdi_kill ();
c906108c
SS
344 remove_breakpoints ();
345 init_wait_for_inferior ();
346
c5aa993b 347 len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
c906108c
SS
348 arg_buf = (char *) alloca (len);
349 arg_buf[0] = '\0';
350 strcat (arg_buf, exec_file);
351 strcat (arg_buf, " ");
352 strcat (arg_buf, args);
353
39f77062 354 inferior_ptid = pid_to_ptid (42);
c5aa993b 355 insert_breakpoints (); /* Needed to get correct instruction in cache */
c906108c
SS
356
357 if (env != NULL)
358 {
359 while (*env)
360 {
361 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
362 {
363 unsigned long top_of_memory;
364 char *end_of_num;
365
366 /* Set up memory limit */
367 top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1,
368 &end_of_num, 0);
d4f3574e 369 printf_filtered ("Setting top-of-memory to 0x%lx\n",
c906108c 370 top_of_memory);
c5aa993b 371
c906108c 372 rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
6ccc741d 373 if (rslt != RDIError_NoError)
c906108c
SS
374 {
375 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
376 }
377 }
378 env++;
379 }
380 }
381
382 arg1 = (unsigned long) arg_buf;
c5aa993b 383 rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2);
6ccc741d 384 if (rslt != RDIError_NoError)
c906108c
SS
385 {
386 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
387 }
388
389 proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
390}
391
392/* This takes a program previously attached to and detaches it. After
393 this is done, GDB can be used to debug some other program. We
394 better not have left any breakpoints in the target program or it'll
395 die when it hits one. */
396
397static void
fba45db2 398arm_rdi_detach (char *args, int from_tty)
c906108c
SS
399{
400 pop_target ();
401}
402
403/* Clean up connection to a remote debugger. */
404
405static void
fba45db2 406arm_rdi_close (int quitting)
c906108c
SS
407{
408 int rslt;
409
c5aa993b 410 if (!closed_already)
c906108c
SS
411 {
412 rslt = angel_RDI_close ();
6ccc741d 413 if (rslt != RDIError_NoError)
c906108c
SS
414 {
415 printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
416 }
417 closed_already = 1;
39f77062 418 inferior_ptid = null_ptid;
96baa820 419 Adp_CloseDevice ();
75660bc0 420 generic_mourn_inferior ();
c906108c
SS
421 }
422}
423\f
424/* Tell the remote machine to resume. */
425
426static void
39f77062 427arm_rdi_resume (ptid_t ptid, int step, enum target_signal siggnal)
c906108c
SS
428{
429 int rslt;
430 PointHandle point;
431
c5aa993b 432 if (0 /* turn on when hardware supports single-stepping */ )
c906108c
SS
433 {
434 rslt = angel_RDI_step (1, &point);
6ccc741d
RE
435 if (rslt != RDIError_NoError)
436 printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt));
c906108c
SS
437 }
438 else
439 {
440 char handle[4];
6ccc741d 441 CORE_ADDR pc = 0;
c906108c
SS
442
443 if (step)
444 {
9ae9b4ea 445 pc = read_register (ARM_PC_REGNUM);
c906108c
SS
446 pc = arm_get_next_pc (pc);
447 arm_rdi_insert_breakpoint (pc, handle);
448 }
6ccc741d 449
c906108c 450 execute_status = rslt = angel_RDI_execute (&point);
6ccc741d
RE
451 if (rslt != RDIError_NoError && rslt != RDIError_BreakpointReached)
452 printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt));
453
c906108c 454 if (step)
6ccc741d 455 arm_rdi_remove_breakpoint (pc, handle);
c906108c
SS
456 }
457}
458\f
c906108c
SS
459/* Wait until the remote machine stops, then return, storing status in
460 STATUS just as `wait' would. Returns "pid" (though it's not clear
461 what, if anything, that means in the case of this target). */
462
39f77062
KB
463static ptid_t
464arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status)
c906108c
SS
465{
466 status->kind = (execute_status == RDIError_NoError ?
c5aa993b 467 TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED);
c906108c
SS
468
469 /* convert stopped code from target into right signal */
470 status->value.sig = rdi_error_signal (execute_status);
471
39f77062 472 return inferior_ptid;
c906108c
SS
473}
474
475/* Read the remote registers into the block REGS. */
476
c906108c 477static void
fba45db2 478arm_rdi_fetch_registers (int regno)
c906108c
SS
479{
480 int rslt, rdi_regmask;
481 unsigned long rawreg, rawregs[32];
482 char cookedreg[4];
483
c5aa993b 484 if (regno == -1)
c906108c
SS
485 {
486 rslt = angel_RDI_CPUread (255, 0x27fff, rawregs);
6ccc741d 487 if (rslt != RDIError_NoError)
c906108c
SS
488 {
489 printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
490 }
491
492 for (regno = 0; regno < 15; regno++)
493 {
494 store_unsigned_integer (cookedreg, 4, rawregs[regno]);
23a6d369 495 regcache_raw_supply (current_regcache, regno, (char *) cookedreg);
c906108c
SS
496 }
497 store_unsigned_integer (cookedreg, 4, rawregs[15]);
23a6d369 498 regcache_raw_supply (current_regcache, ARM_PS_REGNUM, (char *) cookedreg);
9ae9b4ea 499 arm_rdi_fetch_registers (ARM_PC_REGNUM);
c906108c
SS
500 }
501 else
502 {
9ae9b4ea 503 if (regno == ARM_PC_REGNUM)
c906108c 504 rdi_regmask = RDIReg_PC;
9ae9b4ea 505 else if (regno == ARM_PS_REGNUM)
c906108c
SS
506 rdi_regmask = RDIReg_CPSR;
507 else if (regno < 0 || regno > 15)
508 {
509 rawreg = 0;
23a6d369 510 regcache_raw_supply (current_regcache, regno, (char *) &rawreg);
c906108c
SS
511 return;
512 }
513 else
514 rdi_regmask = 1 << regno;
515
516 rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg);
6ccc741d 517 if (rslt != RDIError_NoError)
c906108c
SS
518 {
519 printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
520 }
521 store_unsigned_integer (cookedreg, 4, rawreg);
23a6d369 522 regcache_raw_supply (current_regcache, regno, (char *) cookedreg);
c906108c
SS
523 }
524}
525
c5aa993b 526static void
fba45db2 527arm_rdi_prepare_to_store (void)
c906108c
SS
528{
529 /* Nothing to do. */
530}
531
532/* Store register REGNO, or all registers if REGNO == -1, from the contents
533 of REGISTERS. FIXME: ignores errors. */
534
535static void
fba45db2 536arm_rdi_store_registers (int regno)
c906108c
SS
537{
538 int rslt, rdi_regmask;
539
540 /* These need to be able to take 'floating point register' contents */
541 unsigned long rawreg[3], rawerreg[3];
542
c5aa993b 543 if (regno == -1)
c906108c
SS
544 {
545 for (regno = 0; regno < NUM_REGS; regno++)
546 arm_rdi_store_registers (regno);
547 }
548 else
549 {
4caf0990 550 deprecated_read_register_gen (regno, (char *) rawreg);
c906108c
SS
551 /* RDI manipulates data in host byte order, so convert now. */
552 store_unsigned_integer (rawerreg, 4, rawreg[0]);
553
9ae9b4ea 554 if (regno == ARM_PC_REGNUM)
c906108c 555 rdi_regmask = RDIReg_PC;
9ae9b4ea 556 else if (regno == ARM_PS_REGNUM)
c906108c
SS
557 rdi_regmask = RDIReg_CPSR;
558 else if (regno < 0 || regno > 15)
559 return;
560 else
561 rdi_regmask = 1 << regno;
562
563 rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg);
6ccc741d 564 if (rslt != RDIError_NoError)
c906108c
SS
565 {
566 printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt));
567 }
568 }
569}
570\f
571/* Read or write LEN bytes from inferior memory at MEMADDR,
572 transferring to or from debugger address MYADDR. Write to inferior
573 if SHOULD_WRITE is nonzero. Returns length of data written or
120abad8 574 read; 0 for error. TARGET is unused. */
c906108c 575
c906108c 576static int
0a65a603
AC
577arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
578 int should_write, struct mem_attrib *attrib,
579 struct target_ops *target)
c906108c
SS
580{
581 int rslt, i;
582
583 if (should_write)
584 {
585 rslt = angel_RDI_write (myaddr, memaddr, &len);
6ccc741d 586 if (rslt != RDIError_NoError)
c906108c
SS
587 {
588 printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt));
589 }
590 }
c5aa993b 591 else
c906108c
SS
592 {
593 rslt = angel_RDI_read (memaddr, myaddr, &len);
6ccc741d 594 if (rslt != RDIError_NoError)
c906108c
SS
595 {
596 printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt));
597 len = 0;
598 }
599 }
600 return len;
601}
602\f
603/* Display random info collected from the target. */
604
605static void
fba45db2 606arm_rdi_files_info (struct target_ops *ignore)
c906108c
SS
607{
608 char *file = "nothing";
609 int rslt;
610 unsigned long arg1, arg2;
611
612 rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
6ccc741d 613 if (rslt != RDIError_NoError)
c906108c
SS
614 {
615 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
616 }
617 if (arg1 & (1 << 15))
618 printf_filtered ("Target supports Thumb code.\n");
619 if (arg1 & (1 << 14))
620 printf_filtered ("Target can do profiling.\n");
621 if (arg1 & (1 << 4))
622 printf_filtered ("Target is real hardware.\n");
c5aa993b 623
c906108c 624 rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
6ccc741d 625 if (rslt != RDIError_NoError)
c906108c
SS
626 {
627 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
628 }
629 printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not"));
630
631 rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
6ccc741d 632 if (rslt != RDIError_NoError)
c906108c
SS
633 {
634 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
635 }
636 else
637 printf_filtered ("Target includes an EmbeddedICE.\n");
638}
639\f
640static void
fba45db2 641arm_rdi_kill (void)
c906108c
SS
642{
643 int rslt;
644
645 rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
6ccc741d 646 if (rslt != RDIError_NoError)
c906108c
SS
647 {
648 printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
649 }
650}
651
652static void
fba45db2 653arm_rdi_mourn_inferior (void)
c906108c 654{
da59e081
JM
655 /* We remove the inserted breakpoints in case the user wants to
656 issue another target and load commands to rerun his application;
657 This is something that wouldn't work on a native target, for instance,
658 as the process goes away when the inferior exits, but it works with
659 some remote targets like this one. That is why this is done here. */
660 remove_breakpoints();
c906108c
SS
661 unpush_target (&arm_rdi_ops);
662 generic_mourn_inferior ();
663}
664\f
665/* While the RDI library keeps track of its own breakpoints, we need
666 to remember "handles" so that we can delete them later. Since
667 breakpoints get used for stepping, be careful not to leak memory
668 here. */
669
670static int
fba45db2 671arm_rdi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
c906108c
SS
672{
673 int rslt;
674 PointHandle point;
675 struct local_bp_list_entry *entry;
676 int type = RDIPoint_EQ;
677
678 if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
679 type |= RDIPoint_16Bit;
680 rslt = angel_RDI_setbreak (addr, type, 0, &point);
6ccc741d 681 if (rslt != RDIError_NoError)
c906108c
SS
682 {
683 printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
684 }
685 entry =
686 (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
687 entry->addr = addr;
688 entry->point = point;
689 entry->next = local_bp_list;
690 local_bp_list = entry;
691 return rslt;
692}
693
694static int
fba45db2 695arm_rdi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
c906108c
SS
696{
697 int rslt;
698 PointHandle point;
6ccc741d 699 struct local_bp_list_entry **entryp, *dead;
c906108c 700
6ccc741d
RE
701 for (entryp = &local_bp_list; *entryp != NULL; entryp = &(*entryp)->next)
702 if ((*entryp)->addr == addr)
703 break;
704
705 if (*entryp)
c906108c 706 {
6ccc741d
RE
707 dead = *entryp;
708 rslt = angel_RDI_clearbreak (dead->point);
709 if (rslt != RDIError_NoError)
710 printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
711
c906108c 712 /* Delete the breakpoint entry locally. */
6ccc741d
RE
713 *entryp = dead->next;
714 xfree (dead);
c906108c 715 }
6ccc741d 716
c906108c
SS
717 return 0;
718}
6ccc741d 719
c906108c
SS
720\f
721static char *
fba45db2 722rdi_error_message (int err)
c906108c
SS
723{
724 switch (err)
725 {
c5aa993b 726 case RDIError_NoError:
c906108c
SS
727 return "no error";
728 case RDIError_Reset:
729 return "debuggee reset";
730 case RDIError_UndefinedInstruction:
731 return "undefined instruction";
732 case RDIError_SoftwareInterrupt:
733 return "SWI trapped";
734 case RDIError_PrefetchAbort:
735 return "prefetch abort, execution ran into unmapped memory?";
736 case RDIError_DataAbort:
737 return "data abort, no memory at specified address?";
738 case RDIError_AddressException:
739 return "address exception, access >26bit in 26bit mode";
740 case RDIError_IRQ:
741 return "IRQ, interrupt trapped";
742 case RDIError_FIQ:
743 return "FIQ, fast interrupt trapped";
744 case RDIError_Error:
745 return "a miscellaneous type of error";
746 case RDIError_BranchThrough0:
747 return "branch through location 0";
748 case RDIError_NotInitialised:
749 return "internal error, RDI_open not called first";
750 case RDIError_UnableToInitialise:
751 return "internal error, target world is broken";
752 case RDIError_WrongByteSex:
753 return "See Operator: WrongByteSex";
754 case RDIError_UnableToTerminate:
755 return "See Operator: Unable to Terminate";
756 case RDIError_BadInstruction:
757 return "bad instruction, illegal to execute this instruction";
758 case RDIError_IllegalInstruction:
759 return "illegal instruction, the effect of executing it is undefined";
760 case RDIError_BadCPUStateSetting:
761 return "internal error, tried to set SPSR of user mode";
762 case RDIError_UnknownCoPro:
763 return "unknown co-processor";
764 case RDIError_UnknownCoProState:
765 return "cannot execute co-processor request";
766 case RDIError_BadCoProState:
767 return "recognizably broken co-processor request";
768 case RDIError_BadPointType:
769 return "internal error, bad point yype";
770 case RDIError_UnimplementedType:
771 return "internal error, unimplemented type";
772 case RDIError_BadPointSize:
773 return "internal error, bad point size";
774 case RDIError_UnimplementedSize:
775 return "internal error, unimplemented size";
776 case RDIError_NoMorePoints:
777 return "last break/watch point was used";
778 case RDIError_BreakpointReached:
779 return "breakpoint reached";
780 case RDIError_WatchpointAccessed:
781 return "watchpoint accessed";
782 case RDIError_NoSuchPoint:
783 return "attempted to clear non-existent break/watch point";
784 case RDIError_ProgramFinishedInStep:
785 return "end of the program reached while stepping";
786 case RDIError_UserInterrupt:
787 return "you pressed Escape";
788 case RDIError_CantSetPoint:
789 return "no more break/watch points available";
790 case RDIError_IncompatibleRDILevels:
791 return "incompatible RDI levels";
792 case RDIError_LittleEndian:
793 return "debuggee is little endian";
794 case RDIError_BigEndian:
795 return "debuggee is big endian";
796 case RDIError_SoftInitialiseError:
797 return "recoverable error in RDI initialization";
798 case RDIError_InsufficientPrivilege:
799 return "internal error, supervisor state not accessible to monitor";
800 case RDIError_UnimplementedMessage:
801 return "internal error, unimplemented message";
802 case RDIError_UndefinedMessage:
803 return "internal error, undefined message";
804 default:
c5aa993b 805 return "undefined error message, should reset target";
c906108c
SS
806 }
807}
808
809/* Convert the ARM error messages to signals that GDB knows about. */
810
811static enum target_signal
fba45db2 812rdi_error_signal (int err)
c906108c
SS
813{
814 switch (err)
815 {
816 case RDIError_NoError:
817 return 0;
818 case RDIError_Reset:
c5aa993b 819 return TARGET_SIGNAL_TERM; /* ??? */
c906108c
SS
820 case RDIError_UndefinedInstruction:
821 return TARGET_SIGNAL_ILL;
822 case RDIError_SoftwareInterrupt:
823 case RDIError_PrefetchAbort:
824 case RDIError_DataAbort:
825 return TARGET_SIGNAL_TRAP;
826 case RDIError_AddressException:
827 return TARGET_SIGNAL_SEGV;
828 case RDIError_IRQ:
829 case RDIError_FIQ:
830 return TARGET_SIGNAL_TRAP;
831 case RDIError_Error:
832 return TARGET_SIGNAL_TERM;
833 case RDIError_BranchThrough0:
834 return TARGET_SIGNAL_TRAP;
835 case RDIError_NotInitialised:
836 case RDIError_UnableToInitialise:
837 case RDIError_WrongByteSex:
838 case RDIError_UnableToTerminate:
839 return TARGET_SIGNAL_UNKNOWN;
840 case RDIError_BadInstruction:
841 case RDIError_IllegalInstruction:
842 return TARGET_SIGNAL_ILL;
843 case RDIError_BadCPUStateSetting:
844 case RDIError_UnknownCoPro:
845 case RDIError_UnknownCoProState:
846 case RDIError_BadCoProState:
847 case RDIError_BadPointType:
848 case RDIError_UnimplementedType:
849 case RDIError_BadPointSize:
850 case RDIError_UnimplementedSize:
851 case RDIError_NoMorePoints:
852 return TARGET_SIGNAL_UNKNOWN;
853 case RDIError_BreakpointReached:
854 case RDIError_WatchpointAccessed:
855 return TARGET_SIGNAL_TRAP;
856 case RDIError_NoSuchPoint:
857 case RDIError_ProgramFinishedInStep:
858 return TARGET_SIGNAL_UNKNOWN;
859 case RDIError_UserInterrupt:
860 return TARGET_SIGNAL_INT;
861 case RDIError_IncompatibleRDILevels:
862 case RDIError_LittleEndian:
863 case RDIError_BigEndian:
864 case RDIError_SoftInitialiseError:
865 case RDIError_InsufficientPrivilege:
866 case RDIError_UnimplementedMessage:
867 case RDIError_UndefinedMessage:
868 default:
c5aa993b 869 return TARGET_SIGNAL_UNKNOWN;
c906108c
SS
870 }
871}
e9110f4f
FN
872
873static void
874arm_rdi_stop(void)
875{
876 angel_RDI_stop_request();
877}
878
c906108c
SS
879\f
880/* Define the target operations structure. */
881
882static void
fba45db2 883init_rdi_ops (void)
c906108c 884{
c5aa993b 885 arm_rdi_ops.to_shortname = "rdi";
c906108c
SS
886 arm_rdi_ops.to_longname = "ARM RDI";
887 arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\
c5aa993b
JM
888Specify the serial device it is connected to (e.g. /dev/ttya).";
889 arm_rdi_ops.to_open = arm_rdi_open;
890 arm_rdi_ops.to_close = arm_rdi_close;
891 arm_rdi_ops.to_detach = arm_rdi_detach;
892 arm_rdi_ops.to_resume = arm_rdi_resume;
893 arm_rdi_ops.to_wait = arm_rdi_wait;
e9110f4f 894 arm_rdi_ops.to_stop = arm_rdi_stop;
c906108c
SS
895 arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers;
896 arm_rdi_ops.to_store_registers = arm_rdi_store_registers;
897 arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store;
c8e73a31 898 arm_rdi_ops.deprecated_xfer_memory = arm_rdi_xfer_memory;
c906108c
SS
899 arm_rdi_ops.to_files_info = arm_rdi_files_info;
900 arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
c5aa993b
JM
901 arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint;
902 arm_rdi_ops.to_kill = arm_rdi_kill;
903 arm_rdi_ops.to_load = generic_load;
c906108c
SS
904 arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
905 arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior;
906 arm_rdi_ops.to_stratum = process_stratum;
c5aa993b
JM
907 arm_rdi_ops.to_has_all_memory = 1;
908 arm_rdi_ops.to_has_memory = 1;
909 arm_rdi_ops.to_has_stack = 1;
910 arm_rdi_ops.to_has_registers = 1;
911 arm_rdi_ops.to_has_execution = 1;
912 arm_rdi_ops.to_magic = OPS_MAGIC;
c906108c
SS
913}
914
4ce44c66
JM
915static void
916rdilogfile_command (char *arg, int from_tty)
5c44784c
JM
917{
918 if (!arg || strlen (arg) == 0)
919 {
920 printf_filtered ("rdi log file is '%s'\n", log_filename);
921 return;
922 }
4ce44c66 923
5c44784c 924 if (log_filename)
b8c9b27d 925 xfree (log_filename);
4ce44c66 926
c2d11a7d 927 log_filename = xstrdup (arg);
5c44784c
JM
928
929 Adp_SetLogfile (log_filename);
930}
931
4ce44c66
JM
932static void
933rdilogenable_command (char *args, int from_tty)
5c44784c
JM
934{
935 if (!args || strlen (args) == 0)
936 {
937 printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled");
938 return;
939 }
4ce44c66
JM
940
941 if (!strcasecmp (args, "1") ||
942 !strcasecmp (args, "y") ||
943 !strcasecmp (args, "yes") ||
944 !strcasecmp (args, "on") ||
945 !strcasecmp (args, "t") ||
946 !strcasecmp (args, "true"))
947 Adp_SetLogEnable (log_enable = 1);
948 else if (!strcasecmp (args, "0") ||
949 !strcasecmp (args, "n") ||
950 !strcasecmp (args, "no") ||
951 !strcasecmp (args, "off") ||
952 !strcasecmp (args, "f") ||
953 !strcasecmp (args, "false"))
954 Adp_SetLogEnable (log_enable = 0);
5c44784c
JM
955 else
956 printf_filtered ("rdilogenable: unrecognized argument '%s'\n"
4ce44c66 957 " try y or n\n", args);
5c44784c
JM
958}
959
a78f21af
AC
960extern initialize_file_ftype _initialize_remote_rdi; /* -Wmissing-prototypes */
961
c906108c 962void
fba45db2 963_initialize_remote_rdi (void)
c906108c 964{
fa58ee11
EZ
965 struct cmd_list_element *c;
966
c5aa993b 967 init_rdi_ops ();
c906108c 968 add_target (&arm_rdi_ops);
5c44784c 969
c2d11a7d 970 log_filename = xstrdup ("rdi.log");
4ce44c66
JM
971 Adp_SetLogfile (log_filename);
972 Adp_SetLogEnable (log_enable);
5c44784c 973
fa58ee11
EZ
974 c = add_cmd ("rdilogfile", class_maintenance,
975 rdilogfile_command,
0e2bd219
RE
976 "Set filename for ADP packet log.\n"
977 "This file is used to log Angel Debugger Protocol packets.\n"
978 "With a single argument, sets the logfile name to that value.\n"
979 "Without an argument, shows the current logfile name.\n"
980 "See also: rdilogenable\n",
981 &maintenancelist);
5ba2abeb 982 set_cmd_completer (c, filename_completer);
5c44784c 983
4ce44c66 984 add_cmd ("rdilogenable", class_maintenance,
5c44784c 985 rdilogenable_command,
0e2bd219
RE
986 "Set enable logging of ADP packets.\n"
987 "This will log ADP packets exchanged between gdb and the\n"
988 "rdi target device.\n"
989 "An argument of 1, t, true, y or yes will enable.\n"
990 "An argument of 0, f, false, n or no will disabled.\n"
991 "Withough an argument, it will display current state.\n",
5c44784c
JM
992 &maintenancelist);
993
7915a72c
AC
994 add_setshow_boolean_cmd ("rdiromatzero", no_class, &rom_at_zero, _("\
995Set target has ROM at addr 0."), _("\
996Show if target has ROM at addr 0."), _("\
3b64bf98 997A true value disables vector catching, false enables vector catching.\n\
7915a72c
AC
998This is evaluated at the time the 'target rdi' command is executed."),
999 NULL, /* FIXME: i18n: Target has ROM at addr 0 is %s. */
3b64bf98
AC
1000 NULL, NULL,
1001 &setlist, &showlist);
1002
7915a72c
AC
1003 add_setshow_boolean_cmd ("rdiheartbeat", no_class, &rdi_heartbeat, _("\
1004Set enable for ADP heartbeat packets."), _("\
1005Show enable for ADP heartbeat packets."), _("\
3b64bf98
AC
1006I don't know why you would want this. If you enable them,\n\
1007it will confuse ARM and EPI JTAG interface boxes as well\n\
7915a72c
AC
1008as the Angel Monitor."),
1009 NULL, /* FIXME: i18n: Enable for ADP heartbeat packets is %s. */
3b64bf98
AC
1010 NULL, NULL,
1011 &setlist, &showlist);
c906108c
SS
1012}
1013
1014/* A little dummy to make linking with the library succeed. */
1015
42c466d7 1016void
3bd3f01e 1017Fail (const char *ignored, ...)
c5aa993b 1018{
42c466d7 1019
c5aa993b 1020}