]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/remote-adapt.c
Phase 1 of the ptid_t changes.
[thirdparty/binutils-gdb.git] / gdb / remote-adapt.c
CommitLineData
c906108c 1/* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18.
b6ba6518
KB
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
3 2001 Free Software Foundation, Inc.
c906108c
SS
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
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
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.
c906108c 13
c5aa993b
JM
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.
c906108c 18
c5aa993b
JM
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. */
c906108c
SS
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
c5aa993b
JM
30 o - I can't get binary coff to load.
31 o - I can't get 19200 baud rate to work.
c906108c
SS
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"
c906108c
SS
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"
4e052eda 47#include "regcache.h"
c906108c
SS
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.
c5aa993b 52 */
c906108c
SS
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
c5aa993b
JM
78extern int a29k_freeze_mode;
79extern int processor_type;
80extern char *processor_name;
c906108c
SS
81#endif
82
83/* External data declarations */
c5aa993b 84extern int stop_soon_quietly; /* for wait_for_inferior */
c906108c
SS
85
86/* Forward data declarations */
c5aa993b 87extern struct target_ops adapt_ops; /* Forward declaration */
c906108c
SS
88
89/* Forward function declarations */
90static void adapt_fetch_registers ();
91static void adapt_store_registers ();
92static void adapt_close ();
c5aa993b 93static int adapt_clear_breakpoints ();
c906108c 94
c5aa993b 95#define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
c906108c
SS
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)
c5aa993b 104FILE *log_file = NULL;
c906108c
SS
105#endif
106
107static int timeout = 5;
108static 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. */
113int adapt_desc = -1;
114
115/* stream which is fdopen'd from adapt_desc. Only valid when
116 adapt_desc != -1. */
117FILE *adapt_stream;
118
119#define ON 1
120#define OFF 0
121static void
fba45db2 122rawmode (int desc, int turnon)
c906108c 123{
c5aa993b 124
c906108c
SS
125 TERMINAL sg;
126
127 if (desc < 0)
128 return;
129
130 ioctl (desc, TIOCGETP, &sg);
131
c5aa993b
JM
132 if (turnon)
133 {
c906108c 134#ifdef HAVE_TERMIO
c5aa993b 135 sg.c_lflag &= ~(ICANON);
c906108c 136#else
c5aa993b 137 sg.sg_flags |= RAW;
c906108c 138#endif
c5aa993b
JM
139 }
140 else
141 {
c906108c 142#ifdef HAVE_TERMIO
c5aa993b 143 sg.c_lflag |= ICANON;
c906108c 144#else
c5aa993b 145 sg.sg_flags &= ~(RAW);
c906108c 146#endif
c5aa993b 147 }
c906108c
SS
148 ioctl (desc, TIOCSETP, &sg);
149}
150
151/* Suck up all the input from the adapt */
fba45db2 152slurp_input (void)
c906108c
SS
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. */
168static int
fba45db2 169readchar (void)
c906108c
SS
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. */
199static void
fba45db2 200expect (char *string)
c906108c
SS
201{
202 char *p = string;
203
c5aa993b 204 fflush (adapt_stream);
8edbea78 205 immediate_quit++;
c906108c
SS
206 while (1)
207 {
c5aa993b 208 if (readchar () == *p)
c906108c
SS
209 {
210 p++;
211 if (*p == '\0')
212 {
8edbea78 213 immediate_quit--;
c906108c
SS
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. */
236static void
fba45db2 237expect_prompt (void)
c906108c
SS
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
c5aa993b 244 fflush (adapt_stream);
c906108c
SS
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). */
250static int
fba45db2 251get_hex_digit (int ignore_space)
c906108c
SS
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. */
275static void
fba45db2 276get_hex_byte (char *byt)
c906108c
SS
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 */
c5aa993b 286static long
fba45db2 287get_hex_word (void)
c906108c
SS
288{
289 long val;
290 int j;
c5aa993b 291
c906108c
SS
292 val = 0;
293 for (j = 0; j < 8; j++)
c5aa993b 294 val = (val << 4) + get_hex_digit (j == 0);
c906108c
SS
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. */
299static void
fba45db2 300get_hex_regs (int n, int regno)
c906108c 301{
c5aa993b
JM
302 long val;
303 while (n--)
304 {
305 val = get_hex_word ();
306 supply_register (regno++, (char *) &val);
307 }
c906108c
SS
308}
309/* Called when SIGALRM signal sent due to alarm() timeout. */
310#ifndef HAVE_TERMIO
311
c906108c
SS
312volatile int n_alarms;
313
314void
fba45db2 315adapt_timer (void)
c906108c
SS
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. */
326static 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
332static int need_artificial_trap = 0;
333
334void
fba45db2 335adapt_kill (char *arg, int from_tty)
c906108c 336{
c5aa993b
JM
337 fprintf (adapt_stream, "K");
338 fprintf (adapt_stream, "\r");
339 expect_prompt ();
c906108c
SS
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 */
345static void
fba45db2 346adapt_load (char *args, int fromtty)
c906108c 347{
c5aa993b
JM
348 FILE *fp;
349 int n;
350 char buffer[1024];
c906108c 351
c5aa993b
JM
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);
c906108c 374 }
c5aa993b
JM
375 while (n > 0);
376 if (n < 0)
377 {
378 perror ("writing ascii coff");
379 break;
c906108c 380 }
c5aa993b
JM
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);
c906108c 398 }
c5aa993b
JM
399 while (n > 0);
400 if (n < 0)
401 {
402 perror ("writing ascii coff");
403 break;
404 }
405 }
406 fclose (fp);
c906108c 407#endif
c5aa993b
JM
408 expect_prompt (); /* Skip garbage that comes out */
409 fprintf (adapt_stream, "\r");
410 expect_prompt ();
c906108c
SS
411}
412
413/* This is called not only when we first attach, but also when the
414 user types "run" after having attached. */
415void
fba45db2 416adapt_create_inferior (char *execfile, char *args, char **env)
c906108c
SS
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
c5aa993b
JM
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 }
c906108c
SS
448
449#ifdef NOTDEF
c5aa993b
JM
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 ();
c906108c 454#else
c5aa993b
JM
455 insert_breakpoints (); /* Needed to get correct instruction in cache */
456 proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
c906108c
SS
457#endif
458
c5aa993b
JM
459 }
460 else
461 {
462 printf_filtered ("Adapt not open yet.\n");
463 }
c906108c
SS
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
c5aa993b
JM
476static struct
477{
478 int rate, damn_b;
479}
480baudtab[] =
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 ,
c906108c
SS
550};
551
c5aa993b 552static int
fba45db2 553damn_b (int rate)
c906108c
SS
554{
555 int i;
556
557 for (i = 0; baudtab[i].rate != -1; i++)
c5aa993b
JM
558 if (rate == baudtab[i].rate)
559 return baudtab[i].damn_b;
560 return B38400; /* Random */
c906108c
SS
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
569static int baudrate = 9600;
570static void
fba45db2 571adapt_open (char *name, int from_tty)
c906108c
SS
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')
c5aa993b 586 erroid:
c906108c
SS
587 error ("\
588Please include the name of the device for the serial port,\n\
589the baud rate, and the name of the program to run on the remote system.");
c5aa993b 590 dev_name = (char *) xmalloc (p - name + 1);
c906108c
SS
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++)
c5aa993b
JM
596 /*EMPTY */ ;
597
c906108c
SS
598 if (1 != sscanf (p, "%d ", &baudrate))
599 goto erroid;
600
601 /* Skip the number and then the spaces */
602 for (; isdigit (*p); p++)
c5aa993b 603 /*EMPTY */ ;
c906108c 604 for (; isspace (*p); p++)
c5aa993b
JM
605 /*EMPTY */ ;
606
c906108c 607 if (prog_name != NULL)
b8c9b27d 608 xfree (prog_name);
c906108c
SS
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);
c5aa993b 617#if ! defined(COMPILE_CHECK)
c906108c
SS
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 */
c5aa993b
JM
655 write (adapt_desc, "\ 1", 1); /* Control A */
656 write (adapt_desc, "\r", 1);
c906108c 657 expect_prompt ();
c5aa993b 658
c906108c
SS
659 /* Hello? Are you there? */
660 write (adapt_desc, "\r", 1);
c5aa993b 661
c906108c
SS
662 expect_prompt ();
663
664 /* Clear any break points */
c5aa993b 665 adapt_clear_breakpoints ();
c906108c
SS
666
667 /* Print out some stuff, letting the user now what's going on */
c5aa993b
JM
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 }
c906108c
SS
677}
678
679/* Close out all files and local state before this target loses control. */
680
681static void
fba45db2 682adapt_close (int quitting)
c906108c
SS
683{
684
685 /* Clear any break points */
c5aa993b 686 adapt_clear_breakpoints ();
c906108c 687
c5aa993b
JM
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 }
c906108c
SS
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
c5aa993b
JM
704 /* Do not try to close adapt_desc again, later in the program. */
705 adapt_stream = NULL;
c906108c
SS
706 adapt_desc = -1;
707
708#if defined (LOG_FILE)
c5aa993b
JM
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 }
c906108c
SS
717#endif
718}
719
720/* Attach to the target that is already loaded and possibly running */
721static void
fba45db2 722adapt_attach (char *args, int from_tty)
c906108c
SS
723{
724
725 if (from_tty)
c5aa993b 726 printf_filtered ("Attaching to remote program %s.\n", prog_name);
c906108c
SS
727
728 /* Send the adapt a kill. It is ok if it is not already running */
c5aa993b
JM
729 fprintf (adapt_stream, "K\r");
730 fflush (adapt_stream);
731 expect_prompt (); /* Slurp the echo */
c906108c
SS
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. */
738void
fba45db2 739adapt_detach (char *args, int from_tty)
c906108c
SS
740{
741
c5aa993b
JM
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 */
c906108c
SS
749 if (from_tty)
750 printf_filtered ("Ending remote %s debugging\n", target_shortname);
751}
c5aa993b 752
c906108c
SS
753/* Tell the remote machine to resume. */
754
755void
39f77062 756adapt_resume (ptid_t ptid, int step, enum target_signal sig)
c906108c 757{
c5aa993b 758 if (step)
c906108c
SS
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. */
c5aa993b 777 expect_prompt ();
c906108c
SS
778 }
779}
780
781/* Wait until the remote machine stops, then return,
782 storing status in STATUS just as `wait' would. */
783
39f77062
KB
784ptid_t
785adapt_wait (ptid_t ptid, struct target_waitstatus *status)
c906108c
SS
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. */
c5aa993b 791
c906108c
SS
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--;
39f77062 818 return inferior_ptid;
c906108c
SS
819 }
820
c5aa993b
JM
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 */
c906108c
SS
826 ch_handled = 0;
827 ch = readchar ();
c5aa993b
JM
828 if (ch == *bp)
829 {
c906108c
SS
830 bp++;
831 if (*bp == '\0')
832 break;
833 ch_handled = 1;
834
835 *swallowed_p++ = ch;
c5aa993b
JM
836 }
837 else
c906108c 838 bp = bpt;
c5aa993b
JM
839 if (ch == *ep || *ep == '?')
840 {
c906108c
SS
841 ep++;
842 if (*ep == '\0')
843 break;
844
845 if (!ch_handled)
846 *swallowed_p++ = ch;
847 ch_handled = 1;
c5aa993b
JM
848 }
849 else
c906108c 850 ep = exitmsg;
c5aa993b
JM
851 if (!ch_handled)
852 {
c906108c
SS
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);
c5aa993b
JM
859 }
860 }
c906108c 861 expect_prompt ();
c5aa993b 862 if (*bp == '\0')
c906108c
SS
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;
39f77062 874 return inferior_ptid;
c906108c
SS
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. */
881static char *
fba45db2 882get_reg_name (int regno)
c906108c
SS
883{
884 static char buf[80];
c5aa993b 885 if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
c906108c
SS
886 sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
887#if defined(GR64_REGNUM)
c5aa993b 888 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
c906108c
SS
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);
c5aa993b 893 else if (regno == Q_REGNUM)
c906108c
SS
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);
c5aa993b
JM
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 }
c906108c
SS
909 else if (regno == GR1_REGNUM)
910 strcpy (buf, "GR001");
911 return buf;
912}
913
914/* Read the remote registers. */
915
916static void
fba45db2 917adapt_fetch_registers (void)
c906108c
SS
918{
919 int reg_index;
920 int regnum_index;
921 char tempbuf[10];
c5aa993b
JM
922 int sreg_buf[16];
923 int i, j;
c906108c
SS
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
c5aa993b 957 all in one fell swoop ("dw lr0,lr127"). */
c906108c
SS
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));
c5aa993b
JM
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 ();
c906108c
SS
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.
c5aa993b
JM
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]);
c906108c
SS
997 sprintf (tempbuf, "dw sr128\r");
998 write (adapt_desc, tempbuf, strlen (tempbuf));
c5aa993b
JM
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]);
c906108c
SS
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 */
1033static void
fba45db2 1034adapt_fetch_register (int regno)
c906108c
SS
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
1051static void
fba45db2 1052adapt_store_registers (void)
c906108c
SS
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);
c5aa993b 1063 for (i = 0; i < 15; ++i)
c906108c
SS
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);
c5aa993b 1072 for (i = 0; i < 15; ++i)
c906108c
SS
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);
c5aa993b 1081 for (i = 0; i < 15; ++i)
c906108c
SS
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,");
c5aa993b 1096 for (i = 0; i < 7; ++i)
c906108c
SS
1097 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1098 expect_prompt ();
1099 fprintf (adapt_stream, "s sr7,");
c5aa993b 1100 for (i = 7; i < 14; ++i)
c906108c
SS
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. */
1107void
fba45db2 1108adapt_store_register (int regno)
c906108c
SS
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
c5aa993b
JM
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. */
c906108c
SS
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
1135void
fba45db2 1136adapt_prepare_to_store (void)
c906108c
SS
1137{
1138 /* Do nothing, since we can store individual regs */
1139}
1140
c5aa993b 1141static CORE_ADDR
fba45db2 1142translate_addr (CORE_ADDR addr)
c906108c
SS
1143{
1144#if defined(KERNEL_DEBUGGING)
c5aa993b
JM
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 }
c906108c 1157#else
c5aa993b 1158 return (addr);
c906108c
SS
1159#endif
1160}
1161
1162
1163/* FIXME! Merge these two. */
1164int
29e57380
C
1165adapt_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)
c906108c
SS
1168{
1169
c5aa993b 1170 memaddr = translate_addr (memaddr);
c906108c
SS
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
1178void
fba45db2 1179adapt_files_info (void)
c906108c 1180{
c5aa993b
JM
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]);
c906108c
SS
1184}
1185
1186/* Copy LEN bytes of data from debugger memory at MYADDR
1187 to inferior's memory at MEMADDR. Returns errno value.
c5aa993b 1188 * sb/sh instructions don't work on unaligned addresses, when TU=1.
c906108c
SS
1189 */
1190int
fba45db2 1191adapt_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
1192{
1193 int i;
1194 unsigned int cps;
1195
1196 /* Turn TU bit off so we can do 'sb' commands */
c5aa993b 1197 cps = read_register (CPS_REGNUM);
c906108c 1198 if (cps & 0x00000800)
c5aa993b 1199 write_register (CPS_REGNUM, cps & ~(0x00000800));
c906108c
SS
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 {
c5aa993b 1207 fprintf (adapt_stream, "%x\r", ((unsigned char *) myaddr)[i]);
c906108c
SS
1208 expect_prompt ();
1209 }
1210 else
c5aa993b 1211 fprintf (adapt_stream, "%x,", ((unsigned char *) myaddr)[i]);
c906108c
SS
1212 }
1213 /* Restore the old value of cps if the TU bit was on */
1214 if (cps & 0x00000800)
c5aa993b 1215 write_register (CPS_REGNUM, cps);
c906108c
SS
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. */
1221int
fba45db2 1222adapt_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
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;
c5aa993b 1247
c906108c
SS
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
c5aa993b 1261#ifdef NOTDEF /* Why do this */
c906108c
SS
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
c5aa993b 1292static int num_brkpts = 0;
e082ddca
KB
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
c906108c 1299static int
e082ddca 1300adapt_insert_breakpoint (CORE_ADDR addr, char *save)
c906108c 1301{
c5aa993b
JM
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 }
c906108c
SS
1316
1317}
e082ddca
KB
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
c906108c 1323static int
e082ddca 1324adapt_remove_breakpoint (CORE_ADDR addr, char *save)
c906108c 1325{
c5aa993b
JM
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);
c906108c
SS
1335}
1336
1337/* Clear the adapts notion of what the break points are */
1338static int
fba45db2 1339adapt_clear_breakpoints (void)
c5aa993b
JM
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 }
c906108c
SS
1348 num_brkpts = 0;
1349}
1350static void
fba45db2 1351adapt_mourn (void)
c5aa993b
JM
1352{
1353 adapt_clear_breakpoints ();
1354 pop_target (); /* Pop back to no-child state */
c906108c
SS
1355 generic_mourn_inferior ();
1356}
1357
1358/* Display everthing we read in from the adapt until we match/see the
1359 * specified string
1360 */
1361static int
fba45db2 1362display_until (char *str)
c906108c 1363{
c5aa993b
JM
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);
c906108c 1383 }
c5aa993b 1384 }
c906108c
SS
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
1395void
fba45db2 1396adapt_com (char *args, int fromtty)
c906108c 1397{
c5aa993b
JM
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 ();
c906108c 1406
c5aa993b
JM
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 ();
c906108c 1441 }
c5aa993b
JM
1442 break;
1443 }
c906108c
SS
1444}
1445
1446/* Define the target subroutine names */
1447
c5aa993b 1448struct target_ops adapt_ops;
c906108c 1449
c5aa993b
JM
1450static void
1451init_adapt_ops (void)
c906108c 1452{
c5aa993b
JM
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;
c906108c
SS
1458 adapt_ops.to_attach = adapt_attach;
1459 adapt_ops.to_post_attach = NULL;
c5aa993b 1460 adapt_ops.to_require_attach = NULL;
c906108c
SS
1461 adapt_ops.to_detach = adapt_detach;
1462 adapt_ops.to_require_detach = NULL;
1463 adapt_ops.to_resume = adapt_resume;
c5aa993b 1464 adapt_ops.to_wait = adapt_wait;
c906108c 1465 adapt_ops.to_post_wait = NULL;
c5aa993b
JM
1466 adapt_ops.to_fetch_registers = adapt_fetch_register;
1467 adapt_ops.to_store_registers = adapt_store_register;
c906108c 1468 adapt_ops.to_prepare_to_store = adapt_prepare_to_store;
c5aa993b
JM
1469 adapt_ops.to_xfer_memory = adapt_xfer_inferior_memory;
1470 adapt_ops.to_files_info = adapt_files_info;
c906108c 1471 adapt_ops.to_insert_breakpoint = adapt_insert_breakpoint;
c5aa993b
JM
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;
c906108c
SS
1482 adapt_ops.to_post_startup_inferior = NULL;
1483 adapt_ops.to_acknowledge_created_inferior = NULL;
c5aa993b
JM
1484 adapt_ops.to_clone_and_follow_inferior = NULL;
1485 adapt_ops.to_post_follow_inferior_by_clone = NULL;
c906108c
SS
1486 adapt_ops.to_insert_fork_catchpoint = NULL;
1487 adapt_ops.to_remove_fork_catchpoint = NULL;
1488 adapt_ops.to_insert_vfork_catchpoint = NULL;
c5aa993b 1489 adapt_ops.to_remove_vfork_catchpoint = NULL;
c906108c
SS
1490 adapt_ops.to_has_forked = NULL;
1491 adapt_ops.to_has_vforked = NULL;
c5aa993b
JM
1492 adapt_ops.to_can_follow_vfork_prior_to_exec = NULL;
1493 adapt_ops.to_post_follow_vfork = NULL;
c906108c
SS
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;
c5aa993b
JM
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; */
c906108c 1504 adapt_ops.to_pid_to_exec_file = NULL;
c5aa993b
JM
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 */
c906108c
SS
1516
1517void
fba45db2 1518_initialize_remote_adapt (void)
c906108c 1519{
c5aa993b 1520 init_adapt_ops ();
c906108c
SS
1521 add_target (&adapt_ops);
1522 add_com ("adapt <command>", class_obscure, adapt_com,
c5aa993b 1523 "Send a command to the AMD Adapt remote monitor.");
c906108c 1524}