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