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