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