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