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