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