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