Protoization.
[external/binutils.git] / gdb / remote-rdi.c
1 /* GDB interface to ARM RDI library.
2    Copyright 1997, 1998 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include "defs.h"
22 #include "gdb_string.h"
23 #include <fcntl.h>
24 #include "frame.h"
25 #include "inferior.h"
26 #include "bfd.h"
27 #include "symfile.h"
28 #include "target.h"
29 #include "gdb_wait.h"
30 #include "gdbcmd.h"
31 #include "objfiles.h"
32 #include "gdb-stabs.h"
33 #include "gdbthread.h"
34 #include "gdbcore.h"
35 #include "breakpoint.h"
36
37 #ifdef USG
38 #include <sys/types.h>
39 #endif
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 target_ops *target);
56
57 static void arm_rdi_prepare_to_store (void);
58
59 static void arm_rdi_fetch_registers (int regno);
60
61 static void arm_rdi_resume (int pid, int step, enum target_signal siggnal);
62
63 static int arm_rdi_start_remote (char *dummy);
64
65 static void arm_rdi_open (char *name, int from_tty);
66
67 static void arm_rdi_create_inferior (char *exec_file, char *args, char **env);
68
69 static void arm_rdi_close (int quitting);
70
71 static void arm_rdi_store_registers (int regno);
72
73 static void arm_rdi_mourn (void);
74
75 static void arm_rdi_send (char *buf);
76
77 static int arm_rdi_wait (int pid, 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 void arm_rdi_interrupt (int signo);
84
85 static void arm_rdi_interrupt_twice (int signo);
86
87 static void interrupt_query (void);
88
89 static int arm_rdi_insert_breakpoint (CORE_ADDR, char *);
90
91 static int arm_rdi_remove_breakpoint (CORE_ADDR, char *);
92
93 static char *rdi_error_message (int err);
94
95 static enum target_signal rdi_error_signal (int err);
96
97 /* Global variables.  */
98
99 struct target_ops arm_rdi_ops;
100
101 static struct Dbg_ConfigBlock gdb_config;
102
103 static struct Dbg_HostosInterface gdb_hostif;
104
105 static int max_load_size;
106
107 static int execute_status;
108
109 /* Send heatbeat packets? */
110 static int rdi_heartbeat = 0;
111
112 /* Target has ROM at address 0. */
113 static int rom_at_zero = 0;
114
115 /* Enable logging? */
116 static int log_enable = 0;
117
118 /* Name of the log file. Default is "rdi.log". */
119 static char *log_filename;
120
121 /* A little list of breakpoints that have been set.  */
122
123 static struct local_bp_list_entry
124   {
125     CORE_ADDR addr;
126     PointHandle point;
127     struct local_bp_list_entry *next;
128   }
129  *local_bp_list;
130 \f
131
132 /* Stub for catch_errors.  */
133
134 static int
135 arm_rdi_start_remote (char *dummy)
136 {
137   return 1;
138 }
139
140 /* Helper callbacks for the "host interface" structure.  RDI functions call
141    these to forward output from the target system and so forth.  */
142
143 void
144 voiddummy (void *dummy)
145 {
146   fprintf_unfiltered (gdb_stdout, "void dummy\n");
147 }
148
149 static void
150 myprint (PTR arg, const char *format, va_list ap)
151 {
152   vfprintf_unfiltered (gdb_stdout, format, ap);
153 }
154
155 static void
156 mywritec (PTR arg, int c)
157 {
158   if (isascii (c))
159     fputc_unfiltered (c, gdb_stdout);
160 }
161
162 static int
163 mywrite (PTR arg, char const *buffer, int len)
164 {
165   int i;
166   char *e;
167
168   e = (char *) buffer;
169   for (i = 0; i < len; i++)
170     {
171       if (isascii ((int) *e))
172         {
173           fputc_unfiltered ((int) *e, gdb_stdout);
174           e++;
175         }
176     }
177
178   return len;
179 }
180
181 static void
182 mypause (PTR arg)
183 {
184 }
185
186 /* These last two are tricky as we have to handle the special case of
187    being interrupted more carefully */
188
189 static int
190 myreadc (PTR arg)
191 {
192   return fgetc (stdin);
193 }
194
195 static char *
196 mygets (PTR arg, char *buffer, int len)
197 {
198   return fgets (buffer, len, stdin);
199 }
200
201 /* Prevent multiple calls to angel_RDI_close().  */
202 static int closed_already = 1;
203
204 /* Open a connection to a remote debugger.  NAME is the filename used
205    for communication.  */
206
207 static void
208 arm_rdi_open (char *name, int from_tty)
209 {
210   int rslt, i;
211   unsigned long arg1, arg2;
212   char *openArgs = NULL;
213   char *devName = NULL;
214   char *p;
215
216   if (name == NULL)
217     error ("To open an RDI connection, you need to specify what serial\n\
218 device is attached to the remote system (e.g. /dev/ttya).");
219
220   /* split name after whitespace, pass tail as arg to open command */
221
222   devName = xstrdup (name);
223   p = strchr (devName, ' ');
224   if (p)
225     {
226       *p = '\0';
227       ++p;
228
229       while (*p == ' ')
230         ++p;
231
232       openArgs = p;
233     }
234
235   /* Make the basic low-level connection.  */
236
237   arm_rdi_close (0);
238   rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat);
239
240   if (rslt != adp_ok)
241     error ("Could not open device \"%s\"", name);
242
243   gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BIG_ENDIAN ? 1 : 0);
244   gdb_config.fpe = 1;
245   gdb_config.rditype = 2;
246   gdb_config.heartbeat_on = 1;
247   gdb_config.flags = 2;
248
249   gdb_hostif.dbgprint = myprint;
250   gdb_hostif.dbgpause = mypause;
251   gdb_hostif.dbgarg = NULL;
252   gdb_hostif.writec = mywritec;
253   gdb_hostif.readc = myreadc;
254   gdb_hostif.write = mywrite;
255   gdb_hostif.gets = mygets;
256   gdb_hostif.hostosarg = NULL;
257   gdb_hostif.reset = voiddummy;
258
259   rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
260   if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
261     ;                           /* do nothing, this is the expected return */
262   else if (rslt)
263     {
264       printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
265       Adp_CloseDevice ();
266       error ("RDI_open failed\n");
267     }
268
269   rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
270   if (rslt)
271     {
272       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
273     }
274   rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
275   if (rslt)
276     {
277       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
278     }
279   rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
280   if (rslt)
281     {
282       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
283     }
284   rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
285   if (rslt)
286     {
287       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
288     }
289   rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
290   if (rslt)
291     {
292       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
293     }
294
295   rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
296   if (rslt)
297     {
298       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
299     }
300   max_load_size = arg1;
301
302   push_target (&arm_rdi_ops);
303
304   target_fetch_registers (-1);
305
306   rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
307   if (rslt)
308     {
309       printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
310     }
311
312   arg1 = rom_at_zero ? 0x0 : 0x13b;
313
314   rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
315   if (rslt)
316     {
317       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
318     }
319
320   arg1 = (unsigned long) "";
321   rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
322   if (rslt)
323     {
324       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
325     }
326
327   /* Clear out any existing records of breakpoints.  */
328   {
329     struct local_bp_list_entry *entry, *preventry = NULL;
330
331     for (entry = local_bp_list; entry != NULL; entry = entry->next)
332       {
333         if (preventry)
334           free (preventry);
335       }
336   }
337
338   printf_filtered ("Connected to ARM RDI target.\n");
339   closed_already = 0;
340   inferior_pid = 42;
341 }
342
343 /* Start an inferior process and set inferior_pid to its pid.
344    EXEC_FILE is the file to run.
345    ARGS is a string containing the arguments to the program.
346    ENV is the environment vector to pass.  Errors reported with error().
347    On VxWorks and various standalone systems, we ignore exec_file.  */
348 /* This is called not only when we first attach, but also when the
349    user types "run" after having attached.  */
350
351 static void
352 arm_rdi_create_inferior (char *exec_file, char *args, char **env)
353 {
354   int len, rslt;
355   unsigned long arg1, arg2;
356   char *arg_buf;
357   CORE_ADDR entry_point;
358
359   if (exec_file == 0 || exec_bfd == 0)
360     error ("No executable file specified.");
361
362   entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
363
364   arm_rdi_kill ();
365   remove_breakpoints ();
366   init_wait_for_inferior ();
367
368   len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
369   arg_buf = (char *) alloca (len);
370   arg_buf[0] = '\0';
371   strcat (arg_buf, exec_file);
372   strcat (arg_buf, " ");
373   strcat (arg_buf, args);
374
375   inferior_pid = 42;
376   insert_breakpoints ();        /* Needed to get correct instruction in cache */
377
378   if (env != NULL)
379     {
380       while (*env)
381         {
382           if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
383             {
384               unsigned long top_of_memory;
385               char *end_of_num;
386
387               /* Set up memory limit */
388               top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1,
389                                        &end_of_num, 0);
390               printf_filtered ("Setting top-of-memory to 0x%lx\n",
391                                top_of_memory);
392
393               rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
394               if (rslt)
395                 {
396                   printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
397                 }
398             }
399           env++;
400         }
401     }
402
403   arg1 = (unsigned long) arg_buf;
404   rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2);
405   if (rslt)
406     {
407       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
408     }
409
410   proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
411 }
412
413 /* This takes a program previously attached to and detaches it.  After
414    this is done, GDB can be used to debug some other program.  We
415    better not have left any breakpoints in the target program or it'll
416    die when it hits one.  */
417
418 static void
419 arm_rdi_detach (char *args, int from_tty)
420 {
421   pop_target ();
422 }
423
424 /* Clean up connection to a remote debugger.  */
425
426 static void
427 arm_rdi_close (int quitting)
428 {
429   int rslt;
430
431   if (!closed_already)
432     {
433       rslt = angel_RDI_close ();
434       if (rslt)
435         {
436           printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
437         }
438       closed_already = 1;
439       inferior_pid = 0;
440       Adp_CloseDevice ();
441       generic_mourn_inferior ();
442     }
443 }
444 \f
445 /* Tell the remote machine to resume.  */
446
447 static void
448 arm_rdi_resume (int pid, int step, enum target_signal siggnal)
449 {
450   int rslt;
451   PointHandle point;
452
453   if (0 /* turn on when hardware supports single-stepping */ )
454     {
455       rslt = angel_RDI_step (1, &point);
456       if (rslt)
457         {
458           printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt));
459         }
460     }
461   else
462     {
463       char handle[4];
464       CORE_ADDR pc;
465
466       if (step)
467         {
468           pc = read_register (PC_REGNUM);
469           pc = arm_get_next_pc (pc);
470           arm_rdi_insert_breakpoint (pc, handle);
471         }
472       execute_status = rslt = angel_RDI_execute (&point);
473       if (rslt == RDIError_BreakpointReached)
474         ;
475       else if (rslt)
476         {
477           printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt));
478         }
479       if (step)
480         {
481           arm_rdi_remove_breakpoint (pc, handle);
482         }
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 int
514 arm_rdi_wait (int pid, 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_pid;
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)
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 (PS_REGNUM, (char *) cookedreg);
550       arm_rdi_fetch_registers (PC_REGNUM);
551     }
552   else
553     {
554       if (regno == PC_REGNUM)
555         rdi_regmask = RDIReg_PC;
556       else if (regno == 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)
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       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 == PC_REGNUM)
606         rdi_regmask = RDIReg_PC;
607       else if (regno == 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)
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 target_ops *target)
631 {
632   int rslt, i;
633
634   if (should_write)
635     {
636       rslt = angel_RDI_write (myaddr, memaddr, &len);
637       if (rslt)
638         {
639           printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt));
640         }
641     }
642   else
643     {
644       rslt = angel_RDI_read (memaddr, myaddr, &len);
645       if (rslt)
646         {
647           printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt));
648           len = 0;
649         }
650     }
651   return len;
652 }
653 \f
654 /* Display random info collected from the target.  */
655
656 static void
657 arm_rdi_files_info (struct target_ops *ignore)
658 {
659   char *file = "nothing";
660   int rslt;
661   unsigned long arg1, arg2;
662
663   rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
664   if (rslt)
665     {
666       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
667     }
668   if (arg1 & (1 << 15))
669     printf_filtered ("Target supports Thumb code.\n");
670   if (arg1 & (1 << 14))
671     printf_filtered ("Target can do profiling.\n");
672   if (arg1 & (1 << 4))
673     printf_filtered ("Target is real hardware.\n");
674
675   rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
676   if (rslt)
677     {
678       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
679     }
680   printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not"));
681
682   rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
683   if (rslt)
684     {
685       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
686     }
687   else
688     printf_filtered ("Target includes an EmbeddedICE.\n");
689 }
690 \f
691 static void
692 arm_rdi_kill (void)
693 {
694   int rslt;
695
696   rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
697   if (rslt)
698     {
699       printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
700     }
701 }
702
703 static void
704 arm_rdi_mourn_inferior (void)
705 {
706   /* We remove the inserted breakpoints in case the user wants to
707      issue another target and load commands to rerun his application;
708      This is something that wouldn't work on a native target, for instance,
709      as the process goes away when the inferior exits, but it works with
710      some remote targets like this one.  That is why this is done here. */
711   remove_breakpoints();
712   unpush_target (&arm_rdi_ops);
713   generic_mourn_inferior ();
714 }
715 \f
716 /* While the RDI library keeps track of its own breakpoints, we need
717    to remember "handles" so that we can delete them later.  Since
718    breakpoints get used for stepping, be careful not to leak memory
719    here.  */
720
721 static int
722 arm_rdi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
723 {
724   int rslt;
725   PointHandle point;
726   struct local_bp_list_entry *entry;
727   int type = RDIPoint_EQ;
728
729   if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
730     type |= RDIPoint_16Bit;
731   rslt = angel_RDI_setbreak (addr, type, 0, &point);
732   if (rslt)
733     {
734       printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
735     }
736   entry =
737     (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
738   entry->addr = addr;
739   entry->point = point;
740   entry->next = local_bp_list;
741   local_bp_list = entry;
742   return rslt;
743 }
744
745 static int
746 arm_rdi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
747 {
748   int rslt;
749   PointHandle point;
750   struct local_bp_list_entry *entry, *preventry;
751
752   for (entry = local_bp_list; entry != NULL; entry = entry->next)
753     {
754       if (entry->addr == addr)
755         {
756           break;
757         }
758       preventry = entry;
759     }
760   if (entry)
761     {
762       rslt = angel_RDI_clearbreak (entry->point);
763       if (rslt)
764         {
765           printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
766         }
767       /* Delete the breakpoint entry locally.  */
768       if (entry == local_bp_list)
769         {
770           local_bp_list = entry->next;
771         }
772       else
773         {
774           preventry->next = entry->next;
775         }
776       free (entry);
777     }
778   return 0;
779 }
780 \f
781 static char *
782 rdi_error_message (int err)
783 {
784   switch (err)
785     {
786     case RDIError_NoError:
787       return "no error";
788     case RDIError_Reset:
789       return "debuggee reset";
790     case RDIError_UndefinedInstruction:
791       return "undefined instruction";
792     case RDIError_SoftwareInterrupt:
793       return "SWI trapped";
794     case RDIError_PrefetchAbort:
795       return "prefetch abort, execution ran into unmapped memory?";
796     case RDIError_DataAbort:
797       return "data abort, no memory at specified address?";
798     case RDIError_AddressException:
799       return "address exception, access >26bit in 26bit mode";
800     case RDIError_IRQ:
801       return "IRQ, interrupt trapped";
802     case RDIError_FIQ:
803       return "FIQ, fast interrupt trapped";
804     case RDIError_Error:
805       return "a miscellaneous type of error";
806     case RDIError_BranchThrough0:
807       return "branch through location 0";
808     case RDIError_NotInitialised:
809       return "internal error, RDI_open not called first";
810     case RDIError_UnableToInitialise:
811       return "internal error, target world is broken";
812     case RDIError_WrongByteSex:
813       return "See Operator: WrongByteSex";
814     case RDIError_UnableToTerminate:
815       return "See Operator: Unable to Terminate";
816     case RDIError_BadInstruction:
817       return "bad instruction, illegal to execute this instruction";
818     case RDIError_IllegalInstruction:
819       return "illegal instruction, the effect of executing it is undefined";
820     case RDIError_BadCPUStateSetting:
821       return "internal error, tried to set SPSR of user mode";
822     case RDIError_UnknownCoPro:
823       return "unknown co-processor";
824     case RDIError_UnknownCoProState:
825       return "cannot execute co-processor request";
826     case RDIError_BadCoProState:
827       return "recognizably broken co-processor request";
828     case RDIError_BadPointType:
829       return "internal error, bad point yype";
830     case RDIError_UnimplementedType:
831       return "internal error, unimplemented type";
832     case RDIError_BadPointSize:
833       return "internal error, bad point size";
834     case RDIError_UnimplementedSize:
835       return "internal error, unimplemented size";
836     case RDIError_NoMorePoints:
837       return "last break/watch point was used";
838     case RDIError_BreakpointReached:
839       return "breakpoint reached";
840     case RDIError_WatchpointAccessed:
841       return "watchpoint accessed";
842     case RDIError_NoSuchPoint:
843       return "attempted to clear non-existent break/watch point";
844     case RDIError_ProgramFinishedInStep:
845       return "end of the program reached while stepping";
846     case RDIError_UserInterrupt:
847       return "you pressed Escape";
848     case RDIError_CantSetPoint:
849       return "no more break/watch points available";
850     case RDIError_IncompatibleRDILevels:
851       return "incompatible RDI levels";
852     case RDIError_LittleEndian:
853       return "debuggee is little endian";
854     case RDIError_BigEndian:
855       return "debuggee is big endian";
856     case RDIError_SoftInitialiseError:
857       return "recoverable error in RDI initialization";
858     case RDIError_InsufficientPrivilege:
859       return "internal error, supervisor state not accessible to monitor";
860     case RDIError_UnimplementedMessage:
861       return "internal error, unimplemented message";
862     case RDIError_UndefinedMessage:
863       return "internal error, undefined message";
864     default:
865       return "undefined error message, should reset target";
866     }
867 }
868
869 /* Convert the ARM error messages to signals that GDB knows about.  */
870
871 static enum target_signal
872 rdi_error_signal (int err)
873 {
874   switch (err)
875     {
876     case RDIError_NoError:
877       return 0;
878     case RDIError_Reset:
879       return TARGET_SIGNAL_TERM;        /* ??? */
880     case RDIError_UndefinedInstruction:
881       return TARGET_SIGNAL_ILL;
882     case RDIError_SoftwareInterrupt:
883     case RDIError_PrefetchAbort:
884     case RDIError_DataAbort:
885       return TARGET_SIGNAL_TRAP;
886     case RDIError_AddressException:
887       return TARGET_SIGNAL_SEGV;
888     case RDIError_IRQ:
889     case RDIError_FIQ:
890       return TARGET_SIGNAL_TRAP;
891     case RDIError_Error:
892       return TARGET_SIGNAL_TERM;
893     case RDIError_BranchThrough0:
894       return TARGET_SIGNAL_TRAP;
895     case RDIError_NotInitialised:
896     case RDIError_UnableToInitialise:
897     case RDIError_WrongByteSex:
898     case RDIError_UnableToTerminate:
899       return TARGET_SIGNAL_UNKNOWN;
900     case RDIError_BadInstruction:
901     case RDIError_IllegalInstruction:
902       return TARGET_SIGNAL_ILL;
903     case RDIError_BadCPUStateSetting:
904     case RDIError_UnknownCoPro:
905     case RDIError_UnknownCoProState:
906     case RDIError_BadCoProState:
907     case RDIError_BadPointType:
908     case RDIError_UnimplementedType:
909     case RDIError_BadPointSize:
910     case RDIError_UnimplementedSize:
911     case RDIError_NoMorePoints:
912       return TARGET_SIGNAL_UNKNOWN;
913     case RDIError_BreakpointReached:
914     case RDIError_WatchpointAccessed:
915       return TARGET_SIGNAL_TRAP;
916     case RDIError_NoSuchPoint:
917     case RDIError_ProgramFinishedInStep:
918       return TARGET_SIGNAL_UNKNOWN;
919     case RDIError_UserInterrupt:
920       return TARGET_SIGNAL_INT;
921     case RDIError_IncompatibleRDILevels:
922     case RDIError_LittleEndian:
923     case RDIError_BigEndian:
924     case RDIError_SoftInitialiseError:
925     case RDIError_InsufficientPrivilege:
926     case RDIError_UnimplementedMessage:
927     case RDIError_UndefinedMessage:
928     default:
929       return TARGET_SIGNAL_UNKNOWN;
930     }
931 }
932 \f
933 /* Define the target operations structure.  */
934
935 static void
936 init_rdi_ops (void)
937 {
938   arm_rdi_ops.to_shortname = "rdi";
939   arm_rdi_ops.to_longname = "ARM RDI";
940   arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\
941 Specify the serial device it is connected to (e.g. /dev/ttya).";
942   arm_rdi_ops.to_open = arm_rdi_open;
943   arm_rdi_ops.to_close = arm_rdi_close;
944   arm_rdi_ops.to_detach = arm_rdi_detach;
945   arm_rdi_ops.to_resume = arm_rdi_resume;
946   arm_rdi_ops.to_wait = arm_rdi_wait;
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     free (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   init_rdi_ops ();
1016   add_target (&arm_rdi_ops);
1017
1018   log_filename = xstrdup ("rdi.log");
1019   Adp_SetLogfile (log_filename);
1020   Adp_SetLogEnable (log_enable);
1021
1022   add_cmd ("rdilogfile", class_maintenance,
1023            rdilogfile_command,
1024            "Set filename for ADP packet log.\n\
1025 This file is used to log Angel Debugger Protocol packets.\n\
1026 With a single argument, sets the logfile name to that value.\n\
1027 Without an argument, shows the current logfile name.\n\
1028 See also: rdilogenable\n",
1029            &maintenancelist);
1030
1031   add_cmd ("rdilogenable", class_maintenance,
1032            rdilogenable_command,
1033            "Set enable logging of ADP packets.\n\
1034 This will log ADP packets exchanged between gdb and the\n\
1035 rdi target device.\n\
1036 An argument of 1,t,true,y,yes will enable.\n\
1037 An argument of 0,f,false,n,no will disabled.\n\
1038 Withough an argument, it will display current state.\n",
1039            &maintenancelist);
1040
1041   add_show_from_set
1042     (add_set_cmd ("rdiromatzero", no_class,
1043                   var_boolean, (char *) &rom_at_zero,
1044                   "Set target has ROM at addr 0.\n\
1045 A true value disables vector catching, false enables vector catching.\n\
1046 This is evaluated at the time the 'target rdi' command is executed\n",
1047                   &setlist),
1048      &showlist);
1049
1050   add_show_from_set
1051     (add_set_cmd ("rdiheartbeat", no_class,
1052                   var_boolean, (char *) &rdi_heartbeat,
1053                   "Set enable for ADP heartbeat packets.\n\
1054 I don't know why you would want this. If you enable them,\n\
1055 it will confuse ARM and EPI JTAG interface boxes as well\n\
1056 as the Angel Monitor.\n",
1057                   &setlist),
1058      &showlist);
1059 }
1060
1061 /* A little dummy to make linking with the library succeed. */
1062
1063 int
1064 Fail (void)
1065 {
1066   return 0;
1067 }