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