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