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