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