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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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