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