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