OSDN Git Service

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