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