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