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