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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-adapt.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18.
2
   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
3
   Contributed by David Wood at New York University (wood@lab.ultra.nyu.edu).
4
   Adapted from work done at Cygnus Support in remote-eb.c.
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
/* This is like remote.c but is for an esoteric situation--
24
   having a 29k board attached to an Adapt inline monitor.
25
   The  monitor is connected via serial line to a unix machine
26
   running gdb.
27
 
28
   3/91 -  developed on Sun3 OS 4.1, by David Wood
29
   o - I can't get binary coff to load.
30
   o - I can't get 19200 baud rate to work.
31
   7/91 o - Freeze mode tracing can be done on a 29050.  */
32
 
33
 
34
 
35
#include "defs.h"
36
#include "gdb_string.h"
37
#include "inferior.h"
38
#include "gdb_wait.h"
39
#include "value.h"
40
#include <ctype.h>
41
#include <fcntl.h>
42
#include <signal.h>
43
#include <errno.h>
44
#include "terminal.h"
45
#include "target.h"
46
#include "gdbcore.h"
47
 
48
/* This processor is getting rusty but I am trying to keep it
49
   up to date at least with data structure changes.
50
   Activate this block to compile just this file.
51
 */
52
#define COMPILE_CHECK 0
53
#if COMPILE_CHECK
54
#define Q_REGNUM 0
55
#define VAB_REGNUM 0
56
#define CPS_REGNUM 0
57
#define IPA_REGNUM 0
58
#define IPB_REGNUM 0
59
#define GR1_REGNUM 0
60
#define LR0_REGNUM 0
61
#define IPC_REGNUM 0
62
#define CR_REGNUM 0
63
#define BP_REGNUM 0
64
#define FC_REGNUM 0
65
#define INTE_REGNUM 0
66
#define EXO_REGNUM 0
67
#define GR96_REGNUM 0
68
#define NPC_REGNUM
69
#define FPE_REGNUM 0
70
#define PC2_REGNUM 0
71
#define FPS_REGNUM 0
72
#define ALU_REGNUM 0
73
#define LRU_REGNUM 0
74
#define TERMINAL int
75
#define RAW 1
76
#define ANYP 1
77
extern int a29k_freeze_mode;
78
extern int processor_type;
79
extern char *processor_name;
80
#endif
81
 
82
/* External data declarations */
83
extern int stop_soon_quietly;   /* for wait_for_inferior */
84
 
85
/* Forward data declarations */
86
extern struct target_ops adapt_ops;     /* Forward declaration */
87
 
88
/* Forward function declarations */
89
static void adapt_fetch_registers ();
90
static void adapt_store_registers ();
91
static void adapt_close ();
92
static int adapt_clear_breakpoints ();
93
 
94
#define FREEZE_MODE     (read_register(CPS_REGNUM) && 0x400)
95
#define USE_SHADOW_PC   ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
96
 
97
/* Can't seem to get binary coff working */
98
#define ASCII_COFF              /* Adapt will be downloaded with ascii coff */
99
 
100
/* FIXME: Replace with `set remotedebug'.  */
101
#define LOG_FILE "adapt.log"
102
#if defined (LOG_FILE)
103
FILE *log_file = NULL;
104
#endif
105
 
106
static int timeout = 5;
107
static char *dev_name;
108
 
109
/* Descriptor for I/O to remote machine.  Initialize it to -1 so that
110
   adapt_open knows that we don't have a file open when the program
111
   starts.  */
112
int adapt_desc = -1;
113
 
114
/* stream which is fdopen'd from adapt_desc.  Only valid when
115
   adapt_desc != -1.  */
116
FILE *adapt_stream;
117
 
118
#define ON      1
119
#define OFF     0
120
static void
121
rawmode (desc, turnon)
122
     int desc;
123
     int turnon;
124
{
125
 
126
  TERMINAL sg;
127
 
128
  if (desc < 0)
129
    return;
130
 
131
  ioctl (desc, TIOCGETP, &sg);
132
 
133
  if (turnon)
134
    {
135
#ifdef HAVE_TERMIO
136
      sg.c_lflag &= ~(ICANON);
137
#else
138
      sg.sg_flags |= RAW;
139
#endif
140
    }
141
  else
142
    {
143
#ifdef HAVE_TERMIO
144
      sg.c_lflag |= ICANON;
145
#else
146
      sg.sg_flags &= ~(RAW);
147
#endif
148
    }
149
  ioctl (desc, TIOCSETP, &sg);
150
}
151
 
152
/* Suck up all the input from the adapt */
153
slurp_input ()
154
{
155
  char buf[8];
156
 
157
#ifdef HAVE_TERMIO
158
  /* termio does the timeout for us.  */
159
  while (read (adapt_desc, buf, 8) > 0);
160
#else
161
  alarm (timeout);
162
  while (read (adapt_desc, buf, 8) > 0);
163
  alarm (0);
164
#endif
165
}
166
 
167
/* Read a character from the remote system, doing all the fancy
168
   timeout stuff.  */
169
static int
170
readchar ()
171
{
172
  char buf;
173
 
174
  buf = '\0';
175
#ifdef HAVE_TERMIO
176
  /* termio does the timeout for us.  */
177
  read (adapt_desc, &buf, 1);
178
#else
179
  alarm (timeout);
180
  if (read (adapt_desc, &buf, 1) < 0)
181
    {
182
      if (errno == EINTR)
183
        error ("Timeout reading from remote system.");
184
      else
185
        perror_with_name ("remote");
186
    }
187
  alarm (0);
188
#endif
189
 
190
  if (buf == '\0')
191
    error ("Timeout reading from remote system.");
192
#if defined (LOG_FILE)
193
  putc (buf & 0x7f, log_file);
194
#endif
195
  return buf & 0x7f;
196
}
197
 
198
/* Keep discarding input from the remote system, until STRING is found.
199
   Let the user break out immediately.  */
200
static void
201
expect (string)
202
     char *string;
203
{
204
  char *p = string;
205
 
206
  fflush (adapt_stream);
207
  immediate_quit = 1;
208
  while (1)
209
    {
210
      if (readchar () == *p)
211
        {
212
          p++;
213
          if (*p == '\0')
214
            {
215
              immediate_quit = 0;
216
              return;
217
            }
218
        }
219
      else
220
        p = string;
221
    }
222
}
223
 
224
/* Keep discarding input until we see the adapt prompt.
225
 
226
   The convention for dealing with the prompt is that you
227
   o give your command
228
   o *then* wait for the prompt.
229
 
230
   Thus the last thing that a procedure does with the serial line
231
   will be an expect_prompt().  Exception:  adapt_resume does not
232
   wait for the prompt, because the terminal is being handed over
233
   to the inferior.  However, the next thing which happens after that
234
   is a adapt_wait which does wait for the prompt.
235
   Note that this includes abnormal exit, e.g. error().  This is
236
   necessary to prevent getting into states from which we can't
237
   recover.  */
238
static void
239
expect_prompt ()
240
{
241
#if defined (LOG_FILE)
242
  /* This is a convenient place to do this.  The idea is to do it often
243
     enough that we never lose much data if we terminate abnormally.  */
244
  fflush (log_file);
245
#endif
246
  fflush (adapt_stream);
247
  expect ("\n# ");
248
}
249
 
250
/* Get a hex digit from the remote system & return its value.
251
   If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
252
static int
253
get_hex_digit (ignore_space)
254
     int ignore_space;
255
{
256
  int ch;
257
  while (1)
258
    {
259
      ch = readchar ();
260
      if (ch >= '0' && ch <= '9')
261
        return ch - '0';
262
      else if (ch >= 'A' && ch <= 'F')
263
        return ch - 'A' + 10;
264
      else if (ch >= 'a' && ch <= 'f')
265
        return ch - 'a' + 10;
266
      else if (ch == ' ' && ignore_space)
267
        ;
268
      else
269
        {
270
          expect_prompt ();
271
          error ("Invalid hex digit from remote system.");
272
        }
273
    }
274
}
275
 
276
/* Get a byte from adapt_desc and put it in *BYT.  Accept any number
277
   leading spaces.  */
278
static void
279
get_hex_byte (byt)
280
     char *byt;
281
{
282
  int val;
283
 
284
  val = get_hex_digit (1) << 4;
285
  val |= get_hex_digit (0);
286
  *byt = val;
287
}
288
 
289
/* Read a 32-bit hex word from the adapt, preceded by a space  */
290
static long
291
get_hex_word ()
292
{
293
  long val;
294
  int j;
295
 
296
  val = 0;
297
  for (j = 0; j < 8; j++)
298
    val = (val << 4) + get_hex_digit (j == 0);
299
  return val;
300
}
301
/* Get N 32-bit hex words from remote, each preceded by a space
302
   and put them in registers starting at REGNO.  */
303
static void
304
get_hex_regs (n, regno)
305
     int n;
306
     int regno;
307
{
308
  long val;
309
  while (n--)
310
    {
311
      val = get_hex_word ();
312
      supply_register (regno++, (char *) &val);
313
    }
314
}
315
/* Called when SIGALRM signal sent due to alarm() timeout.  */
316
#ifndef HAVE_TERMIO
317
 
318
#ifndef __STDC__
319
#ifndef volatile
320
#define volatile
321
/**/
322
# endif
323
#endif
324
volatile int n_alarms;
325
 
326
void
327
adapt_timer ()
328
{
329
#if 0
330
  if (kiodebug)
331
    printf ("adapt_timer called\n");
332
#endif
333
  n_alarms++;
334
}
335
#endif
336
 
337
/* malloc'd name of the program on the remote system.  */
338
static char *prog_name = NULL;
339
 
340
/* Number of SIGTRAPs we need to simulate.  That is, the next
341
   NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
342
   SIGTRAP without actually waiting for anything.  */
343
 
344
static int need_artificial_trap = 0;
345
 
346
void
347
adapt_kill (arg, from_tty)
348
     char *arg;
349
     int from_tty;
350
{
351
  fprintf (adapt_stream, "K");
352
  fprintf (adapt_stream, "\r");
353
  expect_prompt ();
354
}
355
/*
356
 * Download a file specified in 'args', to the adapt.
357
 * FIXME: Assumes the file to download is a binary coff file.
358
 */
359
static void
360
adapt_load (args, fromtty)
361
     char *args;
362
     int fromtty;
363
{
364
  FILE *fp;
365
  int n;
366
  char buffer[1024];
367
 
368
  if (!adapt_stream)
369
    {
370
      printf_filtered ("Adapt not open. Use 'target' command to open adapt\n");
371
      return;
372
    }
373
 
374
  /* OK, now read in the file.  Y=read, C=COFF, T=dTe port
375
     0=start address.  */
376
 
377
#ifdef ASCII_COFF               /* Ascii coff */
378
  fprintf (adapt_stream, "YA T,0\r");
379
  fflush (adapt_stream);        /* Just in case */
380
  /* FIXME: should check args for only 1 argument */
381
  sprintf (buffer, "cat %s | btoa > /tmp/#adapt-btoa", args);
382
  system (buffer);
383
  fp = fopen ("/tmp/#adapt-btoa", "r");
384
  rawmode (adapt_desc, OFF);
385
  while (n = fread (buffer, 1, 1024, fp))
386
    {
387
      do
388
        {
389
          n -= write (adapt_desc, buffer, n);
390
        }
391
      while (n > 0);
392
      if (n < 0)
393
        {
394
          perror ("writing ascii coff");
395
          break;
396
        }
397
    }
398
  fclose (fp);
399
  rawmode (adapt_desc, ON);
400
  system ("rm /tmp/#adapt-btoa");
401
#else /* Binary coff - can't get it to work . */
402
  fprintf (adapt_stream, "YC T,0\r");
403
  fflush (adapt_stream);        /* Just in case */
404
  if (!(fp = fopen (args, "r")))
405
    {
406
      printf_filtered ("Can't open %s\n", args);
407
      return;
408
    }
409
  while (n = fread (buffer, 1, 512, fp))
410
    {
411
      do
412
        {
413
          n -= write (adapt_desc, buffer, n);
414
        }
415
      while (n > 0);
416
      if (n < 0)
417
        {
418
          perror ("writing ascii coff");
419
          break;
420
        }
421
    }
422
  fclose (fp);
423
#endif
424
  expect_prompt ();             /* Skip garbage that comes out */
425
  fprintf (adapt_stream, "\r");
426
  expect_prompt ();
427
}
428
 
429
/* This is called not only when we first attach, but also when the
430
   user types "run" after having attached.  */
431
void
432
adapt_create_inferior (execfile, args, env)
433
     char *execfile;
434
     char *args;
435
     char **env;
436
{
437
  int entry_pt;
438
 
439
  if (args && *args)
440
    error ("Can't pass arguments to remote adapt process.");
441
 
442
  if (execfile == 0 || exec_bfd == 0)
443
    error ("No executable file specified");
444
 
445
  entry_pt = (int) bfd_get_start_address (exec_bfd);
446
 
447
  if (adapt_stream)
448
    {
449
      adapt_kill (NULL, NULL);
450
      adapt_clear_breakpoints ();
451
      init_wait_for_inferior ();
452
      /* Clear the input because what the adapt sends back is different
453
       * depending on whether it was running or not.
454
       */
455
      slurp_input ();           /* After this there should be a prompt */
456
      fprintf (adapt_stream, "\r");
457
      expect_prompt ();
458
      printf_filtered ("Do you want to download '%s' (y/n)? [y] : ", prog_name);
459
      {
460
        char buffer[10];
461
        gets (buffer);
462
        if (*buffer != 'n')
463
          {
464
            adapt_load (prog_name, 0);
465
          }
466
      }
467
 
468
#ifdef NOTDEF
469
      /* Set the PC and wait for a go/cont */
470
      fprintf (adapt_stream, "G %x,N\r", entry_pt);
471
      printf_filtered ("Now use the 'continue' command to start.\n");
472
      expect_prompt ();
473
#else
474
      insert_breakpoints ();    /* Needed to get correct instruction in cache */
475
      proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
476
#endif
477
 
478
    }
479
  else
480
    {
481
      printf_filtered ("Adapt not open yet.\n");
482
    }
483
}
484
 
485
/* Translate baud rates from integers to damn B_codes.  Unix should
486
   have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
487
 
488
#ifndef B19200
489
#define B19200 EXTA
490
#endif
491
#ifndef B38400
492
#define B38400 EXTB
493
#endif
494
 
495
static struct
496
{
497
  int rate, damn_b;
498
}
499
baudtab[] =
500
{
501
  {
502
    0, B0
503
  }
504
  ,
505
  {
506
    50, B50
507
  }
508
  ,
509
  {
510
    75, B75
511
  }
512
  ,
513
  {
514
    110, B110
515
  }
516
  ,
517
  {
518
    134, B134
519
  }
520
  ,
521
  {
522
    150, B150
523
  }
524
  ,
525
  {
526
    200, B200
527
  }
528
  ,
529
  {
530
    300, B300
531
  }
532
  ,
533
  {
534
    600, B600
535
  }
536
  ,
537
  {
538
    1200, B1200
539
  }
540
  ,
541
  {
542
    1800, B1800
543
  }
544
  ,
545
  {
546
    2400, B2400
547
  }
548
  ,
549
  {
550
    4800, B4800
551
  }
552
  ,
553
  {
554
    9600, B9600
555
  }
556
  ,
557
  {
558
    19200, B19200
559
  }
560
  ,
561
  {
562
    38400, B38400
563
  }
564
  ,
565
  {
566
    -1, -1
567
  }
568
  ,
569
};
570
 
571
static int
572
damn_b (rate)
573
     int rate;
574
{
575
  int i;
576
 
577
  for (i = 0; baudtab[i].rate != -1; i++)
578
    if (rate == baudtab[i].rate)
579
      return baudtab[i].damn_b;
580
  return B38400;                /* Random */
581
}
582
 
583
 
584
/* Open a connection to a remote debugger.
585
   NAME is the filename used for communication, then a space,
586
   then the baud rate.
587
 */
588
 
589
static int baudrate = 9600;
590
static void
591
adapt_open (name, from_tty)
592
     char *name;
593
     int from_tty;
594
{
595
  TERMINAL sg;
596
  unsigned int prl;
597
  char *p;
598
 
599
  /* Find the first whitespace character, it separates dev_name from
600
     prog_name.  */
601
  if (name == 0)
602
    goto erroid;
603
 
604
  for (p = name;
605
       *p != '\0' && !isspace (*p); p++)
606
    ;
607
  if (*p == '\0')
608
  erroid:
609
    error ("\
610
Please include the name of the device for the serial port,\n\
611
the baud rate, and the name of the program to run on the remote system.");
612
  dev_name = (char *) xmalloc (p - name + 1);
613
  strncpy (dev_name, name, p - name);
614
  dev_name[p - name] = '\0';
615
 
616
  /* Skip over the whitespace after dev_name */
617
  for (; isspace (*p); p++)
618
    /*EMPTY */ ;
619
 
620
  if (1 != sscanf (p, "%d ", &baudrate))
621
    goto erroid;
622
 
623
  /* Skip the number and then the spaces */
624
  for (; isdigit (*p); p++)
625
    /*EMPTY */ ;
626
  for (; isspace (*p); p++)
627
    /*EMPTY */ ;
628
 
629
  if (prog_name != NULL)
630
    free (prog_name);
631
  prog_name = savestring (p, strlen (p));
632
 
633
  adapt_close (0);
634
 
635
  adapt_desc = open (dev_name, O_RDWR);
636
  if (adapt_desc < 0)
637
    perror_with_name (dev_name);
638
  ioctl (adapt_desc, TIOCGETP, &sg);
639
#if ! defined(COMPILE_CHECK)
640
#ifdef HAVE_TERMIO
641
  sg.c_cc[VMIN] = 0;             /* read with timeout.  */
642
  sg.c_cc[VTIME] = timeout * 10;
643
  sg.c_lflag &= ~(ICANON | ECHO);
644
  sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
645
#else
646
  sg.sg_ispeed = damn_b (baudrate);
647
  sg.sg_ospeed = damn_b (baudrate);
648
  sg.sg_flags |= RAW | ANYP;
649
  sg.sg_flags &= ~ECHO;
650
#endif
651
 
652
  ioctl (adapt_desc, TIOCSETP, &sg);
653
  adapt_stream = fdopen (adapt_desc, "r+");
654
#endif /* compile_check */
655
  push_target (&adapt_ops);
656
 
657
#ifndef HAVE_TERMIO
658
#ifndef NO_SIGINTERRUPT
659
  /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
660
     the read.  */
661
  if (siginterrupt (SIGALRM, 1) != 0)
662
    perror ("adapt_open: error in siginterrupt");
663
#endif
664
 
665
  /* Set up read timeout timer.  */
666
  if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1)
667
    perror ("adapt_open: error in signal");
668
#endif
669
 
670
#if defined (LOG_FILE)
671
  log_file = fopen (LOG_FILE, "w");
672
  if (log_file == NULL)
673
    perror_with_name (LOG_FILE);
674
#endif
675
 
676
  /* Put this port into NORMAL mode, send the 'normal' character */
677
  write (adapt_desc, "", 1);   /* Control A */
678
  write (adapt_desc, "\r", 1);
679
  expect_prompt ();
680
 
681
  /* Hello?  Are you there?  */
682
  write (adapt_desc, "\r", 1);
683
 
684
  expect_prompt ();
685
 
686
  /* Clear any break points */
687
  adapt_clear_breakpoints ();
688
 
689
  /* Print out some stuff, letting the user now what's going on */
690
  printf_filtered ("Connected to an Adapt via %s.\n", dev_name);
691
  /* FIXME: can this restriction be removed? */
692
  printf_filtered ("Remote debugging using virtual addresses works only\n");
693
  printf_filtered ("\twhen virtual addresses map 1:1 to physical addresses.\n");
694
  if (processor_type != a29k_freeze_mode)
695
    {
696
      fprintf_filtered (gdb_stderr,
697
                        "Freeze-mode debugging not available, and can only be done on an A29050.\n");
698
    }
699
}
700
 
701
/* Close out all files and local state before this target loses control. */
702
 
703
static void
704
adapt_close (quitting)
705
     int quitting;
706
{
707
 
708
  /* Clear any break points */
709
  adapt_clear_breakpoints ();
710
 
711
  /* Put this port back into REMOTE mode */
712
  if (adapt_stream)
713
    {
714
      fflush (adapt_stream);
715
      sleep (1);                /* Let any output make it all the way back */
716
      write (adapt_desc, "R\r", 2);
717
    }
718
 
719
  /* Due to a bug in Unix, fclose closes not only the stdio stream,
720
     but also the file descriptor.  So we don't actually close
721
     adapt_desc.  */
722
  if (adapt_stream)
723
    fclose (adapt_stream);      /* This also closes adapt_desc */
724
  if (adapt_desc >= 0)
725
    /* close (adapt_desc); */
726
 
727
    /* Do not try to close adapt_desc again, later in the program.  */
728
    adapt_stream = NULL;
729
  adapt_desc = -1;
730
 
731
#if defined (LOG_FILE)
732
  if (log_file)
733
    {
734
      if (ferror (log_file))
735
        printf_filtered ("Error writing log file.\n");
736
      if (fclose (log_file) != 0)
737
        printf_filtered ("Error closing log file.\n");
738
      log_file = NULL;
739
    }
740
#endif
741
}
742
 
743
/* Attach to the target that is already loaded and possibly running */
744
static void
745
adapt_attach (args, from_tty)
746
     char *args;
747
     int from_tty;
748
{
749
 
750
  if (from_tty)
751
    printf_filtered ("Attaching to remote program %s.\n", prog_name);
752
 
753
  /* Send the adapt a kill. It is ok if it is not already running */
754
  fprintf (adapt_stream, "K\r");
755
  fflush (adapt_stream);
756
  expect_prompt ();             /* Slurp the echo */
757
}
758
 
759
 
760
/* Terminate the open connection to the remote debugger.
761
   Use this when you want to detach and do something else
762
   with your gdb.  */
763
void
764
adapt_detach (args, from_tty)
765
     char *args;
766
     int from_tty;
767
{
768
 
769
  if (adapt_stream)
770
    {                           /* Send it on its way (tell it to continue)  */
771
      adapt_clear_breakpoints ();
772
      fprintf (adapt_stream, "G\r");
773
    }
774
 
775
  pop_target ();                /* calls adapt_close to do the real work */
776
  if (from_tty)
777
    printf_filtered ("Ending remote %s debugging\n", target_shortname);
778
}
779
 
780
/* Tell the remote machine to resume.  */
781
 
782
void
783
adapt_resume (pid, step, sig)
784
     int pid, step;
785
     enum target_signal sig;
786
{
787
  if (step)
788
    {
789
      write (adapt_desc, "t 1,s\r", 6);
790
      /* Wait for the echo.  */
791
      expect ("t 1,s\r\n");
792
      /* Then comes a line containing the instruction we stepped to.  */
793
      expect ("@");
794
      /* Then we get the prompt.  */
795
      expect_prompt ();
796
 
797
      /* Force the next adapt_wait to return a trap.  Not doing anything
798
         about I/O from the target means that the user has to type
799
         "continue" to see any.  FIXME, this should be fixed.  */
800
      need_artificial_trap = 1;
801
    }
802
  else
803
    {
804
      write (adapt_desc, "G\r", 2);
805
      /* Swallow the echo.  */
806
      expect_prompt ();
807
    }
808
}
809
 
810
/* Wait until the remote machine stops, then return,
811
   storing status in STATUS just as `wait' would.  */
812
 
813
int
814
adapt_wait (status)
815
     struct target_waitstatus *status;
816
{
817
  /* Strings to look for.  '?' means match any single character.
818
     Note that with the algorithm we use, the initial character
819
     of the string cannot recur in the string, or we will not
820
     find some cases of the string in the input.  */
821
 
822
  static char bpt[] = "@";
823
  /* It would be tempting to look for "\n[__exit + 0x8]\n"
824
     but that requires loading symbols with "yc i" and even if
825
     we did do that we don't know that the file has symbols.  */
826
  static char exitmsg[] = "@????????I    JMPTI     GR121,LR0";
827
  char *bp = bpt;
828
  char *ep = exitmsg;
829
 
830
  /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars.  */
831
  char swallowed[50];
832
  /* Current position in swallowed.  */
833
  char *swallowed_p = swallowed;
834
 
835
  int ch;
836
  int ch_handled;
837
  int old_timeout = timeout;
838
  int old_immediate_quit = immediate_quit;
839
 
840
  status->kind = TARGET_WAITKIND_EXITED;
841
  status->value.integer = 0;
842
 
843
  if (need_artificial_trap != 0)
844
    {
845
      status->kind = TARGET_WAITKIND_STOPPED;
846
      status->value.sig = TARGET_SIGNAL_TRAP;
847
      need_artificial_trap--;
848
      return 0;
849
    }
850
 
851
  timeout = 0;                   /* Don't time out -- user program is running. */
852
  immediate_quit = 1;           /* Helps ability to QUIT */
853
  while (1)
854
    {
855
      QUIT;                     /* Let user quit and leave process running */
856
      ch_handled = 0;
857
      ch = readchar ();
858
      if (ch == *bp)
859
        {
860
          bp++;
861
          if (*bp == '\0')
862
            break;
863
          ch_handled = 1;
864
 
865
          *swallowed_p++ = ch;
866
        }
867
      else
868
        bp = bpt;
869
      if (ch == *ep || *ep == '?')
870
        {
871
          ep++;
872
          if (*ep == '\0')
873
            break;
874
 
875
          if (!ch_handled)
876
            *swallowed_p++ = ch;
877
          ch_handled = 1;
878
        }
879
      else
880
        ep = exitmsg;
881
      if (!ch_handled)
882
        {
883
          char *p;
884
          /* Print out any characters which have been swallowed.  */
885
          for (p = swallowed; p < swallowed_p; ++p)
886
            putc (*p, stdout);
887
          swallowed_p = swallowed;
888
          putc (ch, stdout);
889
        }
890
    }
891
  expect_prompt ();
892
  if (*bp == '\0')
893
    {
894
      status->kind = TARGET_WAITKIND_STOPPED;
895
      status->value.sig = TARGET_SIGNAL_TRAP;
896
    }
897
  else
898
    {
899
      status->kind = TARGET_WAITKIND_EXITED;
900
      status->value.integer = 0;
901
    }
902
  timeout = old_timeout;
903
  immediate_quit = old_immediate_quit;
904
  return 0;
905
}
906
 
907
/* Return the name of register number REGNO
908
   in the form input and output by adapt.
909
 
910
   Returns a pointer to a static buffer containing the answer.  */
911
static char *
912
get_reg_name (regno)
913
     int regno;
914
{
915
  static char buf[80];
916
  if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
917
    sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
918
#if defined(GR64_REGNUM)
919
  else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
920
    sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64);
921
#endif
922
  else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
923
    sprintf (buf, "LR%03d", regno - LR0_REGNUM);
924
  else if (regno == Q_REGNUM)
925
    strcpy (buf, "SR131");
926
  else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
927
    sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
928
  else if (regno == ALU_REGNUM)
929
    strcpy (buf, "SR132");
930
  else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
931
    sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
932
  else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM)
933
    {
934
      /* When a 29050 is in freeze-mode, read shadow pcs instead */
935
      if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC)
936
        sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20);
937
      else
938
        sprintf (buf, "SR%03d", regno - VAB_REGNUM);
939
    }
940
  else if (regno == GR1_REGNUM)
941
    strcpy (buf, "GR001");
942
  return buf;
943
}
944
 
945
/* Read the remote registers.  */
946
 
947
static void
948
adapt_fetch_registers ()
949
{
950
  int reg_index;
951
  int regnum_index;
952
  char tempbuf[10];
953
  int sreg_buf[16];
954
  int i, j;
955
 
956
/*
957
 * Global registers
958
 */
959
#if defined(GR64_REGNUM)
960
  write (adapt_desc, "dw gr64,gr95\r", 13);
961
  for (reg_index = 64, regnum_index = GR64_REGNUM;
962
       reg_index < 96;
963
       reg_index += 4, regnum_index += 4)
964
    {
965
      sprintf (tempbuf, "GR%03d ", reg_index);
966
      expect (tempbuf);
967
      get_hex_regs (4, regnum_index);
968
      expect ("\n");
969
    }
970
#endif
971
  write (adapt_desc, "dw gr96,gr127\r", 14);
972
  for (reg_index = 96, regnum_index = GR96_REGNUM;
973
       reg_index < 128;
974
       reg_index += 4, regnum_index += 4)
975
    {
976
      sprintf (tempbuf, "GR%03d ", reg_index);
977
      expect (tempbuf);
978
      get_hex_regs (4, regnum_index);
979
      expect ("\n");
980
    }
981
 
982
/*
983
 * Local registers
984
 */
985
  for (i = 0; i < 128; i += 32)
986
    {
987
      /* The PC has a tendency to hang if we get these
988
         all in one fell swoop ("dw lr0,lr127").  */
989
      sprintf (tempbuf, "dw lr%d\r", i);
990
      write (adapt_desc, tempbuf, strlen (tempbuf));
991
      for (reg_index = i, regnum_index = LR0_REGNUM + i;
992
           reg_index < i + 32;
993
           reg_index += 4, regnum_index += 4)
994
        {
995
          sprintf (tempbuf, "LR%03d ", reg_index);
996
          expect (tempbuf);
997
          get_hex_regs (4, regnum_index);
998
          expect ("\n");
999
        }
1000
    }
1001
 
1002
/*
1003
 * Special registers
1004
 */
1005
  sprintf (tempbuf, "dw sr0\r");
1006
  write (adapt_desc, tempbuf, strlen (tempbuf));
1007
  for (i = 0; i < 4; i++)
1008
    {                           /* SR0 - SR14 */
1009
      sprintf (tempbuf, "SR%3d", i * 4);
1010
      expect (tempbuf);
1011
      for (j = 0; j < (i == 3 ? 3 : 4); j++)
1012
        sreg_buf[i * 4 + j] = get_hex_word ();
1013
    }
1014
  expect_prompt ();
1015
  /*
1016
   * Read the pcs individually if we are in freeze mode.
1017
   * See get_reg_name(), it translates the register names for the pcs to
1018
   * the names of the shadow pcs.
1019
   */
1020
  if (USE_SHADOW_PC)
1021
    {
1022
      sreg_buf[10] = read_register (NPC_REGNUM);        /* pc0 */
1023
      sreg_buf[11] = read_register (PC_REGNUM);         /* pc1 */
1024
      sreg_buf[12] = read_register (PC2_REGNUM);        /* pc2 */
1025
    }
1026
  for (i = 0; i < 14; i++)       /* Supply vab -> lru */
1027
    supply_register (VAB_REGNUM + i, (char *) &sreg_buf[i]);
1028
  sprintf (tempbuf, "dw sr128\r");
1029
  write (adapt_desc, tempbuf, strlen (tempbuf));
1030
  for (i = 0; i < 2; i++)
1031
    {                           /* SR128 - SR135 */
1032
      sprintf (tempbuf, "SR%3d", 128 + i * 4);
1033
      expect (tempbuf);
1034
      for (j = 0; j < 4; j++)
1035
        sreg_buf[i * 4 + j] = get_hex_word ();
1036
    }
1037
  expect_prompt ();
1038
  supply_register (IPC_REGNUM, (char *) &sreg_buf[0]);
1039
  supply_register (IPA_REGNUM, (char *) &sreg_buf[1]);
1040
  supply_register (IPB_REGNUM, (char *) &sreg_buf[2]);
1041
  supply_register (Q_REGNUM, (char *) &sreg_buf[3]);
1042
  /* Skip ALU */
1043
  supply_register (BP_REGNUM, (char *) &sreg_buf[5]);
1044
  supply_register (FC_REGNUM, (char *) &sreg_buf[6]);
1045
  supply_register (CR_REGNUM, (char *) &sreg_buf[7]);
1046
 
1047
  /* There doesn't seem to be any way to get these.  */
1048
  {
1049
    int val = -1;
1050
    supply_register (FPE_REGNUM, (char *) &val);
1051
    supply_register (INTE_REGNUM, (char *) &val);
1052
    supply_register (FPS_REGNUM, (char *) &val);
1053
    supply_register (EXO_REGNUM, (char *) &val);
1054
  }
1055
 
1056
  write (adapt_desc, "dw gr1,gr1\r", 11);
1057
  expect ("GR001 ");
1058
  get_hex_regs (1, GR1_REGNUM);
1059
  expect_prompt ();
1060
}
1061
 
1062
/* Fetch register REGNO, or all registers if REGNO is -1.
1063
 */
1064
static void
1065
adapt_fetch_register (regno)
1066
     int regno;
1067
{
1068
  if (regno == -1)
1069
    adapt_fetch_registers ();
1070
  else
1071
    {
1072
      char *name = get_reg_name (regno);
1073
      fprintf (adapt_stream, "dw %s,%s\r", name, name);
1074
      expect (name);
1075
      expect (" ");
1076
      get_hex_regs (1, regno);
1077
      expect_prompt ();
1078
    }
1079
}
1080
 
1081
/* Store the remote registers from the contents of the block REGS.  */
1082
 
1083
static void
1084
adapt_store_registers ()
1085
{
1086
  int i, j;
1087
 
1088
  fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM));
1089
  expect_prompt ();
1090
 
1091
#if defined(GR64_REGNUM)
1092
  for (j = 0; j < 32; j += 16)
1093
    {
1094
      fprintf (adapt_stream, "s gr%d,", j + 64);
1095
      for (i = 0; i < 15; ++i)
1096
        fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i));
1097
      fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15));
1098
      expect_prompt ();
1099
    }
1100
#endif
1101
  for (j = 0; j < 32; j += 16)
1102
    {
1103
      fprintf (adapt_stream, "s gr%d,", j + 96);
1104
      for (i = 0; i < 15; ++i)
1105
        fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i));
1106
      fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15));
1107
      expect_prompt ();
1108
    }
1109
 
1110
  for (j = 0; j < 128; j += 16)
1111
    {
1112
      fprintf (adapt_stream, "s lr%d,", j);
1113
      for (i = 0; i < 15; ++i)
1114
        fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i));
1115
      fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15));
1116
      expect_prompt ();
1117
    }
1118
 
1119
  fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM),
1120
           read_register (IPA_REGNUM), read_register (IPB_REGNUM));
1121
  expect_prompt ();
1122
  fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM),
1123
           read_register (FC_REGNUM), read_register (CR_REGNUM));
1124
  expect_prompt ();
1125
  fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM));
1126
  expect_prompt ();
1127
  fprintf (adapt_stream, "s sr0,");
1128
  for (i = 0; i < 7; ++i)
1129
    fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1130
  expect_prompt ();
1131
  fprintf (adapt_stream, "s sr7,");
1132
  for (i = 7; i < 14; ++i)
1133
    fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1134
  expect_prompt ();
1135
}
1136
 
1137
/* Store register REGNO, or all if REGNO == -1.
1138
   Return errno value.  */
1139
void
1140
adapt_store_register (regno)
1141
     int regno;
1142
{
1143
  /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1144
  if (regno == -1)
1145
    adapt_store_registers ();
1146
  else
1147
    {
1148
      char *name = get_reg_name (regno);
1149
      fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno));
1150
      /* Setting GR1 changes the numbers of all the locals, so
1151
         invalidate the register cache.  Do this *after* calling
1152
         read_register, because we want read_register to return the
1153
         value that write_register has just stuffed into the registers
1154
         array, not the value of the register fetched from the
1155
         inferior.  */
1156
      if (regno == GR1_REGNUM)
1157
        registers_changed ();
1158
      expect_prompt ();
1159
    }
1160
}
1161
 
1162
/* Get ready to modify the registers array.  On machines which store
1163
   individual registers, this doesn't need to do anything.  On machines
1164
   which store all the registers in one fell swoop, this makes sure
1165
   that registers contains all the registers from the program being
1166
   debugged.  */
1167
 
1168
void
1169
adapt_prepare_to_store ()
1170
{
1171
  /* Do nothing, since we can store individual regs */
1172
}
1173
 
1174
static CORE_ADDR
1175
translate_addr (addr)
1176
     CORE_ADDR addr;
1177
{
1178
#if defined(KERNEL_DEBUGGING)
1179
  /* Check for a virtual address in the kernel */
1180
  /* Assume physical address of ublock is in  paddr_u register */
1181
  if (addr >= UVADDR)
1182
    {
1183
      /* PADDR_U register holds the physical address of the ublock */
1184
      CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
1185
      return (i + addr - (CORE_ADDR) UVADDR);
1186
    }
1187
  else
1188
    {
1189
      return (addr);
1190
    }
1191
#else
1192
  return (addr);
1193
#endif
1194
}
1195
 
1196
 
1197
/* FIXME!  Merge these two.  */
1198
int
1199
adapt_xfer_inferior_memory (memaddr, myaddr, len, write)
1200
     CORE_ADDR memaddr;
1201
     char *myaddr;
1202
     int len;
1203
     int write;
1204
{
1205
 
1206
  memaddr = translate_addr (memaddr);
1207
 
1208
  if (write)
1209
    return adapt_write_inferior_memory (memaddr, myaddr, len);
1210
  else
1211
    return adapt_read_inferior_memory (memaddr, myaddr, len);
1212
}
1213
 
1214
void
1215
adapt_files_info ()
1216
{
1217
  printf_filtered ("\tAttached to %s at %d baud and running program %s\n",
1218
                   dev_name, baudrate, prog_name);
1219
  printf_filtered ("\ton an %s processor.\n", processor_name[processor_type]);
1220
}
1221
 
1222
/* Copy LEN bytes of data from debugger memory at MYADDR
1223
   to inferior's memory at MEMADDR.  Returns errno value.
1224
   * sb/sh instructions don't work on unaligned addresses, when TU=1.
1225
 */
1226
int
1227
adapt_write_inferior_memory (memaddr, myaddr, len)
1228
     CORE_ADDR memaddr;
1229
     char *myaddr;
1230
     int len;
1231
{
1232
  int i;
1233
  unsigned int cps;
1234
 
1235
  /* Turn TU bit off so we can do 'sb' commands */
1236
  cps = read_register (CPS_REGNUM);
1237
  if (cps & 0x00000800)
1238
    write_register (CPS_REGNUM, cps & ~(0x00000800));
1239
 
1240
  for (i = 0; i < len; i++)
1241
    {
1242
      if ((i % 16) == 0)
1243
        fprintf (adapt_stream, "sb %x,", memaddr + i);
1244
      if ((i % 16) == 15 || i == len - 1)
1245
        {
1246
          fprintf (adapt_stream, "%x\r", ((unsigned char *) myaddr)[i]);
1247
          expect_prompt ();
1248
        }
1249
      else
1250
        fprintf (adapt_stream, "%x,", ((unsigned char *) myaddr)[i]);
1251
    }
1252
  /* Restore the old value of cps if the TU bit was on */
1253
  if (cps & 0x00000800)
1254
    write_register (CPS_REGNUM, cps);
1255
  return len;
1256
}
1257
 
1258
/* Read LEN bytes from inferior memory at MEMADDR.  Put the result
1259
   at debugger address MYADDR.  Returns errno value.  */
1260
int
1261
adapt_read_inferior_memory (memaddr, myaddr, len)
1262
     CORE_ADDR memaddr;
1263
     char *myaddr;
1264
     int len;
1265
{
1266
  int i;
1267
 
1268
  /* Number of bytes read so far.  */
1269
  int count;
1270
 
1271
  /* Starting address of this pass.  */
1272
  unsigned long startaddr;
1273
 
1274
  /* Number of bytes to read in this pass.  */
1275
  int len_this_pass;
1276
 
1277
  /* Note that this code works correctly if startaddr is just less
1278
     than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1279
     thing).  That is, something like
1280
     adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1281
     works--it never adds len to memaddr and gets 0.  */
1282
  /* However, something like
1283
     adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1284
     doesn't need to work.  Detect it and give up if there's an attempt
1285
     to do that.  */
1286
 
1287
  if (((memaddr - 1) + len) < memaddr)
1288
    return EIO;
1289
 
1290
  startaddr = memaddr;
1291
  count = 0;
1292
  while (count < len)
1293
    {
1294
      len_this_pass = 16;
1295
      if ((startaddr % 16) != 0)
1296
        len_this_pass -= startaddr % 16;
1297
      if (len_this_pass > (len - count))
1298
        len_this_pass = (len - count);
1299
 
1300
      fprintf (adapt_stream, "db %x,%x\r", startaddr,
1301
               (startaddr - 1) + len_this_pass);
1302
 
1303
#ifdef NOTDEF                   /* Why do this */
1304
      expect ("\n");
1305
      /* Look for 8 hex digits.  */
1306
      i = 0;
1307
      while (1)
1308
        {
1309
          if (isxdigit (readchar ()))
1310
            ++i;
1311
          else
1312
            {
1313
              expect_prompt ();
1314
              error ("Hex digit expected from remote system.");
1315
            }
1316
          if (i >= 8)
1317
            break;
1318
        }
1319
#endif /* NOTDEF */
1320
 
1321
      expect ("  ");
1322
 
1323
      for (i = 0; i < len_this_pass; i++)
1324
        get_hex_byte (&myaddr[count++]);
1325
 
1326
      expect_prompt ();
1327
 
1328
      startaddr += len_this_pass;
1329
    }
1330
  return count;
1331
}
1332
 
1333
#define MAX_BREAKS      8
1334
static int num_brkpts = 0;
1335
static int
1336
adapt_insert_breakpoint (addr, save)
1337
     CORE_ADDR addr;
1338
     char *save;                /* Throw away, let adapt save instructions */
1339
{
1340
  if (num_brkpts < MAX_BREAKS)
1341
    {
1342
      num_brkpts++;
1343
      fprintf (adapt_stream, "B %x", addr);
1344
      fprintf (adapt_stream, "\r");
1345
      expect_prompt ();
1346
      return (0);                /* Success */
1347
    }
1348
  else
1349
    {
1350
      fprintf_filtered (gdb_stderr,
1351
                      "Too many break points, break point not installed\n");
1352
      return (1);               /* Failure */
1353
    }
1354
 
1355
}
1356
static int
1357
adapt_remove_breakpoint (addr, save)
1358
     CORE_ADDR addr;
1359
     char *save;                /* Throw away, let adapt save instructions */
1360
{
1361
  if (num_brkpts > 0)
1362
    {
1363
      num_brkpts--;
1364
      fprintf (adapt_stream, "BR %x", addr);
1365
      fprintf (adapt_stream, "\r");
1366
      fflush (adapt_stream);
1367
      expect_prompt ();
1368
    }
1369
  return (0);
1370
}
1371
 
1372
/* Clear the adapts notion of what the break points are */
1373
static int
1374
adapt_clear_breakpoints ()
1375
{
1376
  if (adapt_stream)
1377
    {
1378
      fprintf (adapt_stream, "BR");     /* Clear all break points */
1379
      fprintf (adapt_stream, "\r");
1380
      fflush (adapt_stream);
1381
      expect_prompt ();
1382
    }
1383
  num_brkpts = 0;
1384
}
1385
static void
1386
adapt_mourn ()
1387
{
1388
  adapt_clear_breakpoints ();
1389
  pop_target ();                /* Pop back to no-child state */
1390
  generic_mourn_inferior ();
1391
}
1392
 
1393
/* Display everthing we read in from the adapt until we match/see the
1394
 * specified string
1395
 */
1396
static int
1397
display_until (str)
1398
     char *str;
1399
{
1400
  int i = 0, j, c;
1401
 
1402
  while (c = readchar ())
1403
    {
1404
      if (c == str[i])
1405
        {
1406
          i++;
1407
          if (i == strlen (str))
1408
            return;
1409
        }
1410
      else
1411
        {
1412
          if (i)
1413
            {
1414
              for (j = 0; j < i; j++)    /* Put everthing we matched */
1415
                putchar (str[j]);
1416
              i = 0;
1417
            }
1418
          putchar (c);
1419
        }
1420
    }
1421
 
1422
}
1423
 
1424
 
1425
/* Put a command string, in args, out to the adapt.  The adapt is assumed to
1426
   be in raw mode, all writing/reading done through adapt_desc.
1427
   Ouput from the adapt is placed on the users terminal until the
1428
   prompt from the adapt is seen.
1429
   FIXME: Can't handle commands that take input.  */
1430
 
1431
void
1432
adapt_com (args, fromtty)
1433
     char *args;
1434
     int fromtty;
1435
{
1436
  if (!adapt_stream)
1437
    {
1438
      printf_filtered ("Adapt not open.  Use the 'target' command to open.\n");
1439
      return;
1440
    }
1441
 
1442
  /* Clear all input so only command relative output is displayed */
1443
  slurp_input ();
1444
 
1445
  switch (islower (args[0]) ? toupper (args[0]) : args[0])
1446
    {
1447
    default:
1448
      printf_filtered ("Unknown/Unimplemented adapt command '%s'\n", args);
1449
      break;
1450
    case 'G':                   /* Go, begin execution */
1451
      write (adapt_desc, args, strlen (args));
1452
      write (adapt_desc, "\r", 1);
1453
      expect_prompt ();
1454
      break;
1455
    case 'B':                   /* Break points, B or BR */
1456
    case 'C':                   /* Check current 29k status (running/halted) */
1457
    case 'D':                   /* Display data/registers */
1458
    case 'I':                   /* Input from i/o space */
1459
    case 'J':                   /* Jam an instruction */
1460
    case 'K':                   /* Kill, stop execution */
1461
    case 'L':                   /* Disassemble */
1462
    case 'O':                   /* Output to i/o space */
1463
    case 'T':                   /* Trace */
1464
    case 'P':                   /* Pulse an input line */
1465
    case 'X':                   /* Examine special purpose registers */
1466
    case 'Z':                   /* Display trace buffer */
1467
      write (adapt_desc, args, strlen (args));
1468
      write (adapt_desc, "\r", 1);
1469
      expect (args);            /* Don't display the command */
1470
      display_until ("# ");
1471
      break;
1472
      /* Begin commands that take input in the form 'c x,y[,z...]' */
1473
    case 'S':                   /* Set memory or register */
1474
      if (strchr (args, ','))
1475
        {                       /* Assume it is properly formatted */
1476
          write (adapt_desc, args, strlen (args));
1477
          write (adapt_desc, "\r", 1);
1478
          expect_prompt ();
1479
        }
1480
      break;
1481
    }
1482
}
1483
 
1484
/* Define the target subroutine names */
1485
 
1486
struct target_ops adapt_ops;
1487
 
1488
static void
1489
init_adapt_ops (void)
1490
{
1491
  adapt_ops.to_shortname = "adapt";
1492
  adapt_ops.to_longname = "Remote AMD `Adapt' target";
1493
  adapt_ops.to_doc = "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232";
1494
  adapt_ops.to_open = adapt_open;
1495
  adapt_ops.to_close = adapt_close;
1496
  adapt_ops.to_attach = adapt_attach;
1497
  adapt_ops.to_post_attach = NULL;
1498
  adapt_ops.to_require_attach = NULL;
1499
  adapt_ops.to_detach = adapt_detach;
1500
  adapt_ops.to_require_detach = NULL;
1501
  adapt_ops.to_resume = adapt_resume;
1502
  adapt_ops.to_wait = adapt_wait;
1503
  adapt_ops.to_post_wait = NULL;
1504
  adapt_ops.to_fetch_registers = adapt_fetch_register;
1505
  adapt_ops.to_store_registers = adapt_store_register;
1506
  adapt_ops.to_prepare_to_store = adapt_prepare_to_store;
1507
  adapt_ops.to_xfer_memory = adapt_xfer_inferior_memory;
1508
  adapt_ops.to_files_info = adapt_files_info;
1509
  adapt_ops.to_insert_breakpoint = adapt_insert_breakpoint;
1510
  adapt_ops.to_remove_breakpoint = adapt_remove_breakpoint;
1511
  adapt_ops.to_terminal_init = 0;
1512
  adapt_ops.to_terminal_inferior = 0;
1513
  adapt_ops.to_terminal_ours_for_output = 0;
1514
  adapt_ops.to_terminal_ours = 0;
1515
  adapt_ops.to_terminal_info = 0;
1516
  adapt_ops.to_kill = adapt_kill;
1517
  adapt_ops.to_load = adapt_load;
1518
  adapt_ops.to_lookup_symbol = 0;
1519
  adapt_ops.to_create_inferior = adapt_create_inferior;
1520
  adapt_ops.to_post_startup_inferior = NULL;
1521
  adapt_ops.to_acknowledge_created_inferior = NULL;
1522
  adapt_ops.to_clone_and_follow_inferior = NULL;
1523
  adapt_ops.to_post_follow_inferior_by_clone = NULL;
1524
  adapt_ops.to_insert_fork_catchpoint = NULL;
1525
  adapt_ops.to_remove_fork_catchpoint = NULL;
1526
  adapt_ops.to_insert_vfork_catchpoint = NULL;
1527
  adapt_ops.to_remove_vfork_catchpoint = NULL;
1528
  adapt_ops.to_has_forked = NULL;
1529
  adapt_ops.to_has_vforked = NULL;
1530
  adapt_ops.to_can_follow_vfork_prior_to_exec = NULL;
1531
  adapt_ops.to_post_follow_vfork = NULL;
1532
  adapt_ops.to_insert_exec_catchpoint = NULL;
1533
  adapt_ops.to_remove_exec_catchpoint = NULL;
1534
  adapt_ops.to_has_execd = NULL;
1535
  adapt_ops.to_reported_exec_events_per_exec_call = NULL;
1536
  adapt_ops.to_has_exited = NULL;
1537
  adapt_ops.to_mourn_inferior = adapt_mourn;
1538
  adapt_ops.to_can_run = 0;
1539
  adapt_ops.to_notice_signals = 0;
1540
  adapt_ops.to_thread_alive = 0;
1541
  adapt_ops.to_stop = 0; /* process_stratum; */
1542
  adapt_ops.to_pid_to_exec_file = NULL;
1543
  adapt_ops.to_core_file_to_sym_file = NULL;
1544
  adapt_ops.to_stratum = 0;
1545
  adapt_ops.DONT_USE = 0;
1546
  adapt_ops.to_has_all_memory = 1;
1547
  adapt_ops.to_has_memory = 1;
1548
  adapt_ops.to_has_stack = 1;
1549
  adapt_ops.to_has_registers = 1;
1550
  adapt_ops.to_has_execution = 0;
1551
  adapt_ops.to_sections = 0;
1552
  adapt_ops.to_sections_end = 0;
1553
  adapt_ops.to_magic = OPS_MAGIC;
1554
}                               /* init_adapt_ops */
1555
 
1556
void
1557
_initialize_remote_adapt ()
1558
{
1559
  init_adapt_ops ();
1560
  add_target (&adapt_ops);
1561
  add_com ("adapt <command>", class_obscure, adapt_com,
1562
           "Send a command to the AMD Adapt remote monitor.");
1563
}

powered by: WebSVN 2.1.0

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