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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-rdi.c] - Blame information for rev 1774

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

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

powered by: WebSVN 2.1.0

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