]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/remote-rdi.c
PARAMS removal.
[thirdparty/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
a14ed312 47extern int isascii (int);
c906108c
SS
48
49/* Prototypes for local functions */
50
a14ed312 51static void arm_rdi_files_info (struct target_ops *ignore);
c906108c 52
a14ed312
KB
53static int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr,
54 int len, int should_write,
55 struct target_ops *target);
c906108c 56
a14ed312 57static void arm_rdi_prepare_to_store (void);
c906108c 58
a14ed312 59static void arm_rdi_fetch_registers (int regno);
c906108c 60
a14ed312 61static void arm_rdi_resume (int pid, int step, enum target_signal siggnal);
c906108c 62
a14ed312 63static int arm_rdi_start_remote (char *dummy);
c906108c 64
a14ed312 65static void arm_rdi_open (char *name, int from_tty);
c906108c 66
a14ed312 67static void arm_rdi_create_inferior (char *exec_file, char *args, char **env);
c906108c 68
a14ed312 69static void arm_rdi_close (int quitting);
c906108c 70
a14ed312 71static void arm_rdi_store_registers (int regno);
c906108c 72
a14ed312 73static void arm_rdi_mourn (void);
c906108c 74
a14ed312 75static void arm_rdi_send (char *buf);
c906108c 76
a14ed312 77static int arm_rdi_wait (int pid, struct target_waitstatus *status);
c906108c 78
a14ed312 79static void arm_rdi_kill (void);
c906108c 80
a14ed312 81static void arm_rdi_detach (char *args, int from_tty);
c906108c 82
a14ed312 83static void arm_rdi_interrupt (int signo);
c906108c 84
a14ed312 85static void arm_rdi_interrupt_twice (int signo);
c906108c 86
a14ed312 87static void interrupt_query (void);
c906108c 88
a14ed312 89static int arm_rdi_insert_breakpoint (CORE_ADDR, char *);
c906108c 90
a14ed312 91static int arm_rdi_remove_breakpoint (CORE_ADDR, char *);
c906108c 92
a14ed312 93static char *rdi_error_message (int err);
c906108c 94
a14ed312 95static enum target_signal rdi_error_signal (int err);
c906108c
SS
96
97/* Global variables. */
98
99struct target_ops arm_rdi_ops;
100
101static struct Dbg_ConfigBlock gdb_config;
102
103static struct Dbg_HostosInterface gdb_hostif;
104
105static int max_load_size;
106
107static int execute_status;
108
5c44784c 109/* Send heatbeat packets? */
4ce44c66 110static int rdi_heartbeat = 0;
5c44784c
JM
111
112/* Target has ROM at address 0. */
113static int rom_at_zero = 0;
114
115/* Enable logging? */
4ce44c66 116static int log_enable = 0;
5c44784c
JM
117
118/* Name of the log file. Default is "rdi.log". */
119static char *log_filename;
120
c906108c
SS
121/* A little list of breakpoints that have been set. */
122
c5aa993b
JM
123static struct local_bp_list_entry
124 {
125 CORE_ADDR addr;
126 PointHandle point;
127 struct local_bp_list_entry *next;
128 }
129 *local_bp_list;
c906108c 130\f
c5aa993b 131
c906108c
SS
132/* Stub for catch_errors. */
133
134static int
135arm_rdi_start_remote (dummy)
136 char *dummy;
137{
138 return 1;
139}
140
141/* Helper callbacks for the "host interface" structure. RDI functions call
142 these to forward output from the target system and so forth. */
143
144void
145voiddummy ()
146{
147 fprintf_unfiltered (gdb_stdout, "void dummy\n");
148}
149
150static void
151myprint (arg, format, ap)
152 PTR arg;
153 const char *format;
154 va_list ap;
155{
156 vfprintf_unfiltered (gdb_stdout, format, ap);
157}
158
159static void
160mywritec (arg, c)
161 PTR arg;
162 int c;
163{
164 if (isascii (c))
165 fputc_unfiltered (c, gdb_stdout);
166}
167
168static int
169mywrite (arg, buffer, len)
170 PTR arg;
171 char const *buffer;
172 int len;
173{
174 int i;
175 char *e;
176
177 e = (char *) buffer;
178 for (i = 0; i < len; i++)
c5aa993b 179 {
c906108c 180 if (isascii ((int) *e))
c5aa993b
JM
181 {
182 fputc_unfiltered ((int) *e, gdb_stdout);
183 e++;
184 }
185 }
c906108c
SS
186
187 return len;
188}
189
190static void
191mypause (arg)
192 PTR arg;
193{
194}
195
196/* These last two are tricky as we have to handle the special case of
197 being interrupted more carefully */
198
199static int
200myreadc (arg)
201 PTR arg;
c5aa993b 202{
c906108c
SS
203 return fgetc (stdin);
204}
205
206static char *
207mygets (arg, buffer, len)
208 PTR arg;
209 char *buffer;
210 int len;
211{
c5aa993b 212 return fgets (buffer, len, stdin);
c906108c
SS
213}
214
215/* Prevent multiple calls to angel_RDI_close(). */
216static int closed_already = 1;
217
218/* Open a connection to a remote debugger. NAME is the filename used
219 for communication. */
220
221static void
222arm_rdi_open (name, from_tty)
223 char *name;
224 int from_tty;
225{
226 int rslt, i;
227 unsigned long arg1, arg2;
5c44784c
JM
228 char *openArgs = NULL;
229 char *devName = NULL;
230 char *p;
c906108c
SS
231
232 if (name == NULL)
233 error ("To open an RDI connection, you need to specify what serial\n\
234device is attached to the remote system (e.g. /dev/ttya).");
235
5c44784c
JM
236 /* split name after whitespace, pass tail as arg to open command */
237
c2d11a7d 238 devName = xstrdup (name);
4ce44c66 239 p = strchr (devName, ' ');
5c44784c
JM
240 if (p)
241 {
242 *p = '\0';
243 ++p;
244
245 while (*p == ' ')
246 ++p;
247
248 openArgs = p;
249 }
250
c906108c
SS
251 /* Make the basic low-level connection. */
252
c5394b80 253 arm_rdi_close (0);
5c44784c 254 rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat);
c906108c
SS
255
256 if (rslt != adp_ok)
257 error ("Could not open device \"%s\"", name);
258
259 gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BIG_ENDIAN ? 1 : 0);
260 gdb_config.fpe = 1;
261 gdb_config.rditype = 2;
262 gdb_config.heartbeat_on = 1;
263 gdb_config.flags = 2;
264
265 gdb_hostif.dbgprint = myprint;
266 gdb_hostif.dbgpause = mypause;
267 gdb_hostif.dbgarg = NULL;
268 gdb_hostif.writec = mywritec;
269 gdb_hostif.readc = myreadc;
270 gdb_hostif.write = mywrite;
271 gdb_hostif.gets = mygets;
272 gdb_hostif.hostosarg = NULL;
273 gdb_hostif.reset = voiddummy;
274
275 rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
276 if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
c5aa993b 277 ; /* do nothing, this is the expected return */
c906108c
SS
278 else if (rslt)
279 {
280 printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
2acceee2 281 Adp_CloseDevice ();
4ce44c66 282 error ("RID_open failed\n");
c906108c
SS
283 }
284
285 rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
286 if (rslt)
287 {
288 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
289 }
290 rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
291 if (rslt)
292 {
293 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
294 }
295 rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
296 if (rslt)
297 {
298 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
299 }
300 rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
301 if (rslt)
302 {
303 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
304 }
305 rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
306 if (rslt)
307 {
308 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
309 }
310
311 rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
312 if (rslt)
313 {
314 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
315 }
316 max_load_size = arg1;
317
318 push_target (&arm_rdi_ops);
319
320 target_fetch_registers (-1);
321
322 rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
323 if (rslt)
324 {
325 printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
326 }
327
5c44784c
JM
328 arg1 = rom_at_zero ? 0x0 : 0x13b;
329
c906108c
SS
330 rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
331 if (rslt)
332 {
333 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
334 }
335
336 arg1 = (unsigned long) "";
337 rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
338 if (rslt)
339 {
340 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
341 }
342
343 /* Clear out any existing records of breakpoints. */
344 {
345 struct local_bp_list_entry *entry, *preventry = NULL;
346
347 for (entry = local_bp_list; entry != NULL; entry = entry->next)
348 {
349 if (preventry)
350 free (preventry);
351 }
352 }
353
354 printf_filtered ("Connected to ARM RDI target.\n");
355 closed_already = 0;
356 inferior_pid = 42;
357}
358
359/* Start an inferior process and set inferior_pid to its pid.
360 EXEC_FILE is the file to run.
361 ARGS is a string containing the arguments to the program.
362 ENV is the environment vector to pass. Errors reported with error().
363 On VxWorks and various standalone systems, we ignore exec_file. */
364/* This is called not only when we first attach, but also when the
365 user types "run" after having attached. */
366
367static void
368arm_rdi_create_inferior (exec_file, args, env)
369 char *exec_file;
370 char *args;
371 char **env;
372{
373 int len, rslt;
374 unsigned long arg1, arg2;
375 char *arg_buf;
376 CORE_ADDR entry_point;
377
378 if (exec_file == 0 || exec_bfd == 0)
c5aa993b 379 error ("No executable file specified.");
c906108c
SS
380
381 entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
382
c5aa993b 383 arm_rdi_kill ();
c906108c
SS
384 remove_breakpoints ();
385 init_wait_for_inferior ();
386
c5aa993b 387 len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
c906108c
SS
388 arg_buf = (char *) alloca (len);
389 arg_buf[0] = '\0';
390 strcat (arg_buf, exec_file);
391 strcat (arg_buf, " ");
392 strcat (arg_buf, args);
393
394 inferior_pid = 42;
c5aa993b 395 insert_breakpoints (); /* Needed to get correct instruction in cache */
c906108c
SS
396
397 if (env != NULL)
398 {
399 while (*env)
400 {
401 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
402 {
403 unsigned long top_of_memory;
404 char *end_of_num;
405
406 /* Set up memory limit */
407 top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1,
408 &end_of_num, 0);
d4f3574e 409 printf_filtered ("Setting top-of-memory to 0x%lx\n",
c906108c 410 top_of_memory);
c5aa993b 411
c906108c
SS
412 rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
413 if (rslt)
414 {
415 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
416 }
417 }
418 env++;
419 }
420 }
421
422 arg1 = (unsigned long) arg_buf;
c5aa993b 423 rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2);
c906108c
SS
424 if (rslt)
425 {
426 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
427 }
428
429 proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
430}
431
432/* This takes a program previously attached to and detaches it. After
433 this is done, GDB can be used to debug some other program. We
434 better not have left any breakpoints in the target program or it'll
435 die when it hits one. */
436
437static void
438arm_rdi_detach (args, from_tty)
439 char *args;
440 int from_tty;
441{
442 pop_target ();
443}
444
445/* Clean up connection to a remote debugger. */
446
447static void
448arm_rdi_close (quitting)
449 int quitting;
450{
451 int rslt;
452
c5aa993b 453 if (!closed_already)
c906108c
SS
454 {
455 rslt = angel_RDI_close ();
456 if (rslt)
457 {
458 printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
459 }
460 closed_already = 1;
461 inferior_pid = 0;
96baa820 462 Adp_CloseDevice ();
75660bc0 463 generic_mourn_inferior ();
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{
da59e081
JM
741 /* We remove the inserted breakpoints in case the user wants to
742 issue another target and load commands to rerun his application;
743 This is something that wouldn't work on a native target, for instance,
744 as the process goes away when the inferior exits, but it works with
745 some remote targets like this one. That is why this is done here. */
746 remove_breakpoints();
c906108c
SS
747 unpush_target (&arm_rdi_ops);
748 generic_mourn_inferior ();
749}
750\f
751/* While the RDI library keeps track of its own breakpoints, we need
752 to remember "handles" so that we can delete them later. Since
753 breakpoints get used for stepping, be careful not to leak memory
754 here. */
755
756static int
757arm_rdi_insert_breakpoint (addr, contents_cache)
758 CORE_ADDR addr;
759 char *contents_cache;
760{
761 int rslt;
762 PointHandle point;
763 struct local_bp_list_entry *entry;
764 int type = RDIPoint_EQ;
765
766 if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
767 type |= RDIPoint_16Bit;
768 rslt = angel_RDI_setbreak (addr, type, 0, &point);
769 if (rslt)
770 {
771 printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
772 }
773 entry =
774 (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
775 entry->addr = addr;
776 entry->point = point;
777 entry->next = local_bp_list;
778 local_bp_list = entry;
779 return rslt;
780}
781
782static int
783arm_rdi_remove_breakpoint (addr, contents_cache)
784 CORE_ADDR addr;
785 char *contents_cache;
786{
787 int rslt;
788 PointHandle point;
789 struct local_bp_list_entry *entry, *preventry;
790
791 for (entry = local_bp_list; entry != NULL; entry = entry->next)
792 {
793 if (entry->addr == addr)
794 {
795 break;
796 }
797 preventry = entry;
798 }
799 if (entry)
800 {
801 rslt = angel_RDI_clearbreak (entry->point);
802 if (rslt)
803 {
804 printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
805 }
806 /* Delete the breakpoint entry locally. */
807 if (entry == local_bp_list)
808 {
809 local_bp_list = entry->next;
810 }
811 else
812 {
813 preventry->next = entry->next;
814 }
815 free (entry);
816 }
817 return 0;
818}
819\f
820static char *
821rdi_error_message (err)
822 int err;
823{
824 switch (err)
825 {
c5aa993b 826 case RDIError_NoError:
c906108c
SS
827 return "no error";
828 case RDIError_Reset:
829 return "debuggee reset";
830 case RDIError_UndefinedInstruction:
831 return "undefined instruction";
832 case RDIError_SoftwareInterrupt:
833 return "SWI trapped";
834 case RDIError_PrefetchAbort:
835 return "prefetch abort, execution ran into unmapped memory?";
836 case RDIError_DataAbort:
837 return "data abort, no memory at specified address?";
838 case RDIError_AddressException:
839 return "address exception, access >26bit in 26bit mode";
840 case RDIError_IRQ:
841 return "IRQ, interrupt trapped";
842 case RDIError_FIQ:
843 return "FIQ, fast interrupt trapped";
844 case RDIError_Error:
845 return "a miscellaneous type of error";
846 case RDIError_BranchThrough0:
847 return "branch through location 0";
848 case RDIError_NotInitialised:
849 return "internal error, RDI_open not called first";
850 case RDIError_UnableToInitialise:
851 return "internal error, target world is broken";
852 case RDIError_WrongByteSex:
853 return "See Operator: WrongByteSex";
854 case RDIError_UnableToTerminate:
855 return "See Operator: Unable to Terminate";
856 case RDIError_BadInstruction:
857 return "bad instruction, illegal to execute this instruction";
858 case RDIError_IllegalInstruction:
859 return "illegal instruction, the effect of executing it is undefined";
860 case RDIError_BadCPUStateSetting:
861 return "internal error, tried to set SPSR of user mode";
862 case RDIError_UnknownCoPro:
863 return "unknown co-processor";
864 case RDIError_UnknownCoProState:
865 return "cannot execute co-processor request";
866 case RDIError_BadCoProState:
867 return "recognizably broken co-processor request";
868 case RDIError_BadPointType:
869 return "internal error, bad point yype";
870 case RDIError_UnimplementedType:
871 return "internal error, unimplemented type";
872 case RDIError_BadPointSize:
873 return "internal error, bad point size";
874 case RDIError_UnimplementedSize:
875 return "internal error, unimplemented size";
876 case RDIError_NoMorePoints:
877 return "last break/watch point was used";
878 case RDIError_BreakpointReached:
879 return "breakpoint reached";
880 case RDIError_WatchpointAccessed:
881 return "watchpoint accessed";
882 case RDIError_NoSuchPoint:
883 return "attempted to clear non-existent break/watch point";
884 case RDIError_ProgramFinishedInStep:
885 return "end of the program reached while stepping";
886 case RDIError_UserInterrupt:
887 return "you pressed Escape";
888 case RDIError_CantSetPoint:
889 return "no more break/watch points available";
890 case RDIError_IncompatibleRDILevels:
891 return "incompatible RDI levels";
892 case RDIError_LittleEndian:
893 return "debuggee is little endian";
894 case RDIError_BigEndian:
895 return "debuggee is big endian";
896 case RDIError_SoftInitialiseError:
897 return "recoverable error in RDI initialization";
898 case RDIError_InsufficientPrivilege:
899 return "internal error, supervisor state not accessible to monitor";
900 case RDIError_UnimplementedMessage:
901 return "internal error, unimplemented message";
902 case RDIError_UndefinedMessage:
903 return "internal error, undefined message";
904 default:
c5aa993b 905 return "undefined error message, should reset target";
c906108c
SS
906 }
907}
908
909/* Convert the ARM error messages to signals that GDB knows about. */
910
911static enum target_signal
912rdi_error_signal (err)
913 int err;
914{
915 switch (err)
916 {
917 case RDIError_NoError:
918 return 0;
919 case RDIError_Reset:
c5aa993b 920 return TARGET_SIGNAL_TERM; /* ??? */
c906108c
SS
921 case RDIError_UndefinedInstruction:
922 return TARGET_SIGNAL_ILL;
923 case RDIError_SoftwareInterrupt:
924 case RDIError_PrefetchAbort:
925 case RDIError_DataAbort:
926 return TARGET_SIGNAL_TRAP;
927 case RDIError_AddressException:
928 return TARGET_SIGNAL_SEGV;
929 case RDIError_IRQ:
930 case RDIError_FIQ:
931 return TARGET_SIGNAL_TRAP;
932 case RDIError_Error:
933 return TARGET_SIGNAL_TERM;
934 case RDIError_BranchThrough0:
935 return TARGET_SIGNAL_TRAP;
936 case RDIError_NotInitialised:
937 case RDIError_UnableToInitialise:
938 case RDIError_WrongByteSex:
939 case RDIError_UnableToTerminate:
940 return TARGET_SIGNAL_UNKNOWN;
941 case RDIError_BadInstruction:
942 case RDIError_IllegalInstruction:
943 return TARGET_SIGNAL_ILL;
944 case RDIError_BadCPUStateSetting:
945 case RDIError_UnknownCoPro:
946 case RDIError_UnknownCoProState:
947 case RDIError_BadCoProState:
948 case RDIError_BadPointType:
949 case RDIError_UnimplementedType:
950 case RDIError_BadPointSize:
951 case RDIError_UnimplementedSize:
952 case RDIError_NoMorePoints:
953 return TARGET_SIGNAL_UNKNOWN;
954 case RDIError_BreakpointReached:
955 case RDIError_WatchpointAccessed:
956 return TARGET_SIGNAL_TRAP;
957 case RDIError_NoSuchPoint:
958 case RDIError_ProgramFinishedInStep:
959 return TARGET_SIGNAL_UNKNOWN;
960 case RDIError_UserInterrupt:
961 return TARGET_SIGNAL_INT;
962 case RDIError_IncompatibleRDILevels:
963 case RDIError_LittleEndian:
964 case RDIError_BigEndian:
965 case RDIError_SoftInitialiseError:
966 case RDIError_InsufficientPrivilege:
967 case RDIError_UnimplementedMessage:
968 case RDIError_UndefinedMessage:
969 default:
c5aa993b 970 return TARGET_SIGNAL_UNKNOWN;
c906108c
SS
971 }
972}
973\f
974/* Define the target operations structure. */
975
976static void
977init_rdi_ops ()
978{
c5aa993b 979 arm_rdi_ops.to_shortname = "rdi";
c906108c
SS
980 arm_rdi_ops.to_longname = "ARM RDI";
981 arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\
c5aa993b
JM
982Specify the serial device it is connected to (e.g. /dev/ttya).";
983 arm_rdi_ops.to_open = arm_rdi_open;
984 arm_rdi_ops.to_close = arm_rdi_close;
985 arm_rdi_ops.to_detach = arm_rdi_detach;
986 arm_rdi_ops.to_resume = arm_rdi_resume;
987 arm_rdi_ops.to_wait = arm_rdi_wait;
c906108c
SS
988 arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers;
989 arm_rdi_ops.to_store_registers = arm_rdi_store_registers;
990 arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store;
991 arm_rdi_ops.to_xfer_memory = arm_rdi_xfer_memory;
992 arm_rdi_ops.to_files_info = arm_rdi_files_info;
993 arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
c5aa993b
JM
994 arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint;
995 arm_rdi_ops.to_kill = arm_rdi_kill;
996 arm_rdi_ops.to_load = generic_load;
c906108c
SS
997 arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
998 arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior;
999 arm_rdi_ops.to_stratum = process_stratum;
c5aa993b
JM
1000 arm_rdi_ops.to_has_all_memory = 1;
1001 arm_rdi_ops.to_has_memory = 1;
1002 arm_rdi_ops.to_has_stack = 1;
1003 arm_rdi_ops.to_has_registers = 1;
1004 arm_rdi_ops.to_has_execution = 1;
1005 arm_rdi_ops.to_magic = OPS_MAGIC;
c906108c
SS
1006}
1007
4ce44c66
JM
1008static void
1009rdilogfile_command (char *arg, int from_tty)
5c44784c
JM
1010{
1011 if (!arg || strlen (arg) == 0)
1012 {
1013 printf_filtered ("rdi log file is '%s'\n", log_filename);
1014 return;
1015 }
4ce44c66 1016
5c44784c
JM
1017 if (log_filename)
1018 free (log_filename);
4ce44c66 1019
c2d11a7d 1020 log_filename = xstrdup (arg);
5c44784c
JM
1021
1022 Adp_SetLogfile (log_filename);
1023}
1024
4ce44c66
JM
1025static void
1026rdilogenable_command (char *args, int from_tty)
5c44784c
JM
1027{
1028 if (!args || strlen (args) == 0)
1029 {
1030 printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled");
1031 return;
1032 }
4ce44c66
JM
1033
1034 if (!strcasecmp (args, "1") ||
1035 !strcasecmp (args, "y") ||
1036 !strcasecmp (args, "yes") ||
1037 !strcasecmp (args, "on") ||
1038 !strcasecmp (args, "t") ||
1039 !strcasecmp (args, "true"))
1040 Adp_SetLogEnable (log_enable = 1);
1041 else if (!strcasecmp (args, "0") ||
1042 !strcasecmp (args, "n") ||
1043 !strcasecmp (args, "no") ||
1044 !strcasecmp (args, "off") ||
1045 !strcasecmp (args, "f") ||
1046 !strcasecmp (args, "false"))
1047 Adp_SetLogEnable (log_enable = 0);
5c44784c
JM
1048 else
1049 printf_filtered ("rdilogenable: unrecognized argument '%s'\n"
4ce44c66 1050 " try y or n\n", args);
5c44784c
JM
1051}
1052
c906108c
SS
1053void
1054_initialize_remote_rdi ()
1055{
c5aa993b 1056 init_rdi_ops ();
c906108c 1057 add_target (&arm_rdi_ops);
5c44784c 1058
c2d11a7d 1059 log_filename = xstrdup ("rdi.log");
4ce44c66
JM
1060 Adp_SetLogfile (log_filename);
1061 Adp_SetLogEnable (log_enable);
5c44784c
JM
1062
1063 add_cmd ("rdilogfile", class_maintenance,
1064 rdilogfile_command,
1065 "Set filename for ADP packet log.\n\
1066This file is used to log Angel Debugger Protocol packets.\n\
1067With a single argument, sets the logfile name to that value.\n\
1068Without an argument, shows the current logfile name.\n\
1069See also: rdilogenable\n",
1070 &maintenancelist);
1071
4ce44c66 1072 add_cmd ("rdilogenable", class_maintenance,
5c44784c
JM
1073 rdilogenable_command,
1074 "Set enable logging of ADP packets.\n\
1075This will log ADP packets exchanged between gdb and the\n\
1076rdi target device.\n\
1077An argument of 1,t,true,y,yes will enable.\n\
1078An argument of 0,f,false,n,no will disabled.\n\
1079Withough an argument, it will display current state.\n",
1080 &maintenancelist);
1081
1082 add_show_from_set
1083 (add_set_cmd ("rdiromatzero", no_class,
1084 var_boolean, (char *) &rom_at_zero,
1085 "Set target has ROM at addr 0.\n\
1086A true value disables vector catching, false enables vector catching.\n\
1087This is evaluated at the time the 'target rdi' command is executed\n",
1088 &setlist),
4ce44c66 1089 &showlist);
5c44784c
JM
1090
1091 add_show_from_set
1092 (add_set_cmd ("rdiheartbeat", no_class,
1093 var_boolean, (char *) &rdi_heartbeat,
1094 "Set enable for ADP heartbeat packets.\n\
1095I don't know why you would want this. If you enable them,\n\
1096it will confuse ARM and EPI JTAG interface boxes as well\n\
1097as the Angel Monitor.\n",
1098 &setlist),
4ce44c66 1099 &showlist);
c906108c
SS
1100}
1101
1102/* A little dummy to make linking with the library succeed. */
1103
c5aa993b
JM
1104int
1105Fail ()
1106{
1107 return 0;
1108}