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