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