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