OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [remote-rdi.c] - Blame information for rev 1775

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.