1 /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18.
2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
3 Contributed by David Wood at New York University (wood@lab.ultra.nyu.edu).
4 Adapted from work done at Cygnus Support in remote-eb.c.
6 This file is part of GDB.
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.
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.
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. */
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
28 3/91 - developed on Sun3 OS 4.1, by David Wood
29 o - I can't get binary coff to load.
30 o - I can't get 19200 baud rate to work.
31 7/91 o - Freeze mode tracing can be done on a 29050. */
36 #include "gdb_string.h"
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.
52 #define COMPILE_CHECK 0
77 extern int a29k_freeze_mode
;
78 extern int processor_type
;
79 extern char *processor_name
;
82 /* External data declarations */
83 extern int stop_soon_quietly
; /* for wait_for_inferior */
85 /* Forward data declarations */
86 extern struct target_ops adapt_ops
; /* Forward declaration */
88 /* Forward function declarations */
89 static void adapt_fetch_registers ();
90 static void adapt_store_registers ();
91 static void adapt_close ();
92 static int adapt_clear_breakpoints ();
94 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
95 #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
97 /* Can't seem to get binary coff working */
98 #define ASCII_COFF /* Adapt will be downloaded with ascii coff */
100 /* FIXME: Replace with `set remotedebug'. */
101 #define LOG_FILE "adapt.log"
102 #if defined (LOG_FILE)
103 FILE *log_file
= NULL
;
106 static int timeout
= 5;
107 static char *dev_name
;
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
114 /* stream which is fdopen'd from adapt_desc. Only valid when
121 rawmode (int desc
, int turnon
)
129 ioctl (desc
, TIOCGETP
, &sg
);
134 sg
.c_lflag
&= ~(ICANON
);
142 sg
.c_lflag
|= ICANON
;
144 sg
.sg_flags
&= ~(RAW
);
147 ioctl (desc
, TIOCSETP
, &sg
);
150 /* Suck up all the input from the adapt */
156 /* termio does the timeout for us. */
157 while (read (adapt_desc
, buf
, 8) > 0);
160 while (read (adapt_desc
, buf
, 8) > 0);
165 /* Read a character from the remote system, doing all the fancy
174 /* termio does the timeout for us. */
175 read (adapt_desc
, &buf
, 1);
178 if (read (adapt_desc
, &buf
, 1) < 0)
181 error ("Timeout reading from remote system.");
183 perror_with_name ("remote");
189 error ("Timeout reading from remote system.");
190 #if defined (LOG_FILE)
191 putc (buf
& 0x7f, log_file
);
196 /* Keep discarding input from the remote system, until STRING is found.
197 Let the user break out immediately. */
199 expect (char *string
)
203 fflush (adapt_stream
);
207 if (readchar () == *p
)
221 /* Keep discarding input until we see the adapt prompt.
223 The convention for dealing with the prompt is that you
225 o *then* wait for the prompt.
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
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. */
243 fflush (adapt_stream
);
247 /* Get a hex digit from the remote system & return its value.
248 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
250 get_hex_digit (int ignore_space
)
256 if (ch
>= '0' && ch
<= '9')
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
)
267 error ("Invalid hex digit from remote system.");
272 /* Get a byte from adapt_desc and put it in *BYT. Accept any number
275 get_hex_byte (char *byt
)
279 val
= get_hex_digit (1) << 4;
280 val
|= get_hex_digit (0);
284 /* Read a 32-bit hex word from the adapt, preceded by a space */
292 for (j
= 0; j
< 8; j
++)
293 val
= (val
<< 4) + get_hex_digit (j
== 0);
296 /* Get N 32-bit hex words from remote, each preceded by a space
297 and put them in registers starting at REGNO. */
299 get_hex_regs (int n
, int regno
)
304 val
= get_hex_word ();
305 supply_register (regno
++, (char *) &val
);
308 /* Called when SIGALRM signal sent due to alarm() timeout. */
317 volatile int n_alarms
;
324 printf ("adapt_timer called\n");
330 /* malloc'd name of the program on the remote system. */
331 static char *prog_name
= NULL
;
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. */
337 static int need_artificial_trap
= 0;
340 adapt_kill (char *arg
, int from_tty
)
342 fprintf (adapt_stream
, "K");
343 fprintf (adapt_stream
, "\r");
347 * Download a file specified in 'args', to the adapt.
348 * FIXME: Assumes the file to download is a binary coff file.
351 adapt_load (char *args
, int fromtty
)
359 printf_filtered ("Adapt not open. Use 'target' command to open adapt\n");
363 /* OK, now read in the file. Y=read, C=COFF, T=dTe port
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
);
372 fp
= fopen ("/tmp/#adapt-btoa", "r");
373 rawmode (adapt_desc
, OFF
);
374 while (n
= fread (buffer
, 1, 1024, fp
))
378 n
-= write (adapt_desc
, buffer
, n
);
383 perror ("writing ascii coff");
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")))
395 printf_filtered ("Can't open %s\n", args
);
398 while (n
= fread (buffer
, 1, 512, fp
))
402 n
-= write (adapt_desc
, buffer
, n
);
407 perror ("writing ascii coff");
413 expect_prompt (); /* Skip garbage that comes out */
414 fprintf (adapt_stream
, "\r");
418 /* This is called not only when we first attach, but also when the
419 user types "run" after having attached. */
421 adapt_create_inferior (char *execfile
, char *args
, char **env
)
426 error ("Can't pass arguments to remote adapt process.");
428 if (execfile
== 0 || exec_bfd
== 0)
429 error ("No executable file specified");
431 entry_pt
= (int) bfd_get_start_address (exec_bfd
);
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.
441 slurp_input (); /* After this there should be a prompt */
442 fprintf (adapt_stream
, "\r");
444 printf_filtered ("Do you want to download '%s' (y/n)? [y] : ", prog_name
);
450 adapt_load (prog_name
, 0);
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");
460 insert_breakpoints (); /* Needed to get correct instruction in cache */
461 proceed (entry_pt
, TARGET_SIGNAL_DEFAULT
, 0);
467 printf_filtered ("Adapt not open yet.\n");
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. */
562 for (i
= 0; baudtab
[i
].rate
!= -1; i
++)
563 if (rate
== baudtab
[i
].rate
)
564 return baudtab
[i
].damn_b
;
565 return B38400
; /* Random */
569 /* Open a connection to a remote debugger.
570 NAME is the filename used for communication, then a space,
574 static int baudrate
= 9600;
576 adapt_open (char *name
, int from_tty
)
582 /* Find the first whitespace character, it separates dev_name from
588 *p
!= '\0' && !isspace (*p
); p
++)
593 Please include the name of the device for the serial port,\n\
594 the baud rate, and the name of the program to run on the remote system.");
595 dev_name
= (char *) xmalloc (p
- name
+ 1);
596 strncpy (dev_name
, name
, p
- name
);
597 dev_name
[p
- name
] = '\0';
599 /* Skip over the whitespace after dev_name */
600 for (; isspace (*p
); p
++)
603 if (1 != sscanf (p
, "%d ", &baudrate
))
606 /* Skip the number and then the spaces */
607 for (; isdigit (*p
); p
++)
609 for (; isspace (*p
); p
++)
612 if (prog_name
!= NULL
)
614 prog_name
= savestring (p
, strlen (p
));
618 adapt_desc
= open (dev_name
, O_RDWR
);
620 perror_with_name (dev_name
);
621 ioctl (adapt_desc
, TIOCGETP
, &sg
);
622 #if ! defined(COMPILE_CHECK)
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
);
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
;
635 ioctl (adapt_desc
, TIOCSETP
, &sg
);
636 adapt_stream
= fdopen (adapt_desc
, "r+");
637 #endif /* compile_check */
638 push_target (&adapt_ops
);
641 #ifndef NO_SIGINTERRUPT
642 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
644 if (siginterrupt (SIGALRM
, 1) != 0)
645 perror ("adapt_open: error in siginterrupt");
648 /* Set up read timeout timer. */
649 if ((void (*)) signal (SIGALRM
, adapt_timer
) == (void (*)) -1)
650 perror ("adapt_open: error in signal");
653 #if defined (LOG_FILE)
654 log_file
= fopen (LOG_FILE
, "w");
655 if (log_file
== NULL
)
656 perror_with_name (LOG_FILE
);
659 /* Put this port into NORMAL mode, send the 'normal' character */
660 write (adapt_desc
, "\x01", 1); /* Control A */
661 write (adapt_desc
, "\r", 1);
664 /* Hello? Are you there? */
665 write (adapt_desc
, "\r", 1);
669 /* Clear any break points */
670 adapt_clear_breakpoints ();
672 /* Print out some stuff, letting the user now what's going on */
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
)
679 fprintf_filtered (gdb_stderr
,
680 "Freeze-mode debugging not available, and can only be done on an A29050.\n");
684 /* Close out all files and local state before this target loses control. */
687 adapt_close (int quitting
)
690 /* Clear any break points */
691 adapt_clear_breakpoints ();
693 /* Put this port back into REMOTE mode */
696 fflush (adapt_stream
);
697 sleep (1); /* Let any output make it all the way back */
698 write (adapt_desc
, "R\r", 2);
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
705 fclose (adapt_stream
); /* This also closes adapt_desc */
707 /* close (adapt_desc); */
709 /* Do not try to close adapt_desc again, later in the program. */
713 #if defined (LOG_FILE)
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");
725 /* Attach to the target that is already loaded and possibly running */
727 adapt_attach (char *args
, int from_tty
)
731 printf_filtered ("Attaching to remote program %s.\n", prog_name
);
733 /* Send the adapt a kill. It is ok if it is not already running */
734 fprintf (adapt_stream
, "K\r");
735 fflush (adapt_stream
);
736 expect_prompt (); /* Slurp the echo */
740 /* Terminate the open connection to the remote debugger.
741 Use this when you want to detach and do something else
744 adapt_detach (char *args
, int from_tty
)
748 { /* Send it on its way (tell it to continue) */
749 adapt_clear_breakpoints ();
750 fprintf (adapt_stream
, "G\r");
753 pop_target (); /* calls adapt_close to do the real work */
755 printf_filtered ("Ending remote %s debugging\n", target_shortname
);
758 /* Tell the remote machine to resume. */
761 adapt_resume (int pid
, int step
, enum target_signal sig
)
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. */
770 /* Then we get the prompt. */
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;
780 write (adapt_desc
, "G\r", 2);
781 /* Swallow the echo. */
786 /* Wait until the remote machine stops, then return,
787 storing status in STATUS just as `wait' would. */
790 adapt_wait (struct target_waitstatus
*status
)
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. */
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";
805 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
807 /* Current position in swallowed. */
808 char *swallowed_p
= swallowed
;
812 int old_timeout
= timeout
;
813 int old_immediate_quit
= immediate_quit
;
815 status
->kind
= TARGET_WAITKIND_EXITED
;
816 status
->value
.integer
= 0;
818 if (need_artificial_trap
!= 0)
820 status
->kind
= TARGET_WAITKIND_STOPPED
;
821 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
822 need_artificial_trap
--;
826 timeout
= 0; /* Don't time out -- user program is running. */
827 immediate_quit
= 1; /* Helps ability to QUIT */
830 QUIT
; /* Let user quit and leave process running */
844 if (ch
== *ep
|| *ep
== '?')
859 /* Print out any characters which have been swallowed. */
860 for (p
= swallowed
; p
< swallowed_p
; ++p
)
862 swallowed_p
= swallowed
;
869 status
->kind
= TARGET_WAITKIND_STOPPED
;
870 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
874 status
->kind
= TARGET_WAITKIND_EXITED
;
875 status
->value
.integer
= 0;
877 timeout
= old_timeout
;
878 immediate_quit
= old_immediate_quit
;
882 /* Return the name of register number REGNO
883 in the form input and output by adapt.
885 Returns a pointer to a static buffer containing the answer. */
887 get_reg_name (int regno
)
890 if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
891 sprintf (buf
, "GR%03d", regno
- GR96_REGNUM
+ 96);
892 #if defined(GR64_REGNUM)
893 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32)
894 sprintf (buf
, "GR%03d", regno
- GR64_REGNUM
+ 64);
896 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
897 sprintf (buf
, "LR%03d", regno
- LR0_REGNUM
);
898 else if (regno
== Q_REGNUM
)
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);
906 else if (regno
>= VAB_REGNUM
&& regno
<= LRU_REGNUM
)
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);
912 sprintf (buf
, "SR%03d", regno
- VAB_REGNUM
);
914 else if (regno
== GR1_REGNUM
)
915 strcpy (buf
, "GR001");
919 /* Read the remote registers. */
922 adapt_fetch_registers (void)
933 #if defined(GR64_REGNUM)
934 write (adapt_desc
, "dw gr64,gr95\r", 13);
935 for (reg_index
= 64, regnum_index
= GR64_REGNUM
;
937 reg_index
+= 4, regnum_index
+= 4)
939 sprintf (tempbuf
, "GR%03d ", reg_index
);
941 get_hex_regs (4, regnum_index
);
945 write (adapt_desc
, "dw gr96,gr127\r", 14);
946 for (reg_index
= 96, regnum_index
= GR96_REGNUM
;
948 reg_index
+= 4, regnum_index
+= 4)
950 sprintf (tempbuf
, "GR%03d ", reg_index
);
952 get_hex_regs (4, regnum_index
);
959 for (i
= 0; i
< 128; i
+= 32)
961 /* The PC has a tendency to hang if we get these
962 all in one fell swoop ("dw lr0,lr127"). */
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
;
967 reg_index
+= 4, regnum_index
+= 4)
969 sprintf (tempbuf
, "LR%03d ", reg_index
);
971 get_hex_regs (4, regnum_index
);
979 sprintf (tempbuf
, "dw sr0\r");
980 write (adapt_desc
, tempbuf
, strlen (tempbuf
));
981 for (i
= 0; i
< 4; i
++)
983 sprintf (tempbuf
, "SR%3d", i
* 4);
985 for (j
= 0; j
< (i
== 3 ? 3 : 4); j
++)
986 sreg_buf
[i
* 4 + j
] = get_hex_word ();
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.
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 */
1000 for (i
= 0; i
< 14; i
++) /* Supply vab -> lru */
1001 supply_register (VAB_REGNUM
+ i
, (char *) &sreg_buf
[i
]);
1002 sprintf (tempbuf
, "dw sr128\r");
1003 write (adapt_desc
, tempbuf
, strlen (tempbuf
));
1004 for (i
= 0; i
< 2; i
++)
1005 { /* SR128 - SR135 */
1006 sprintf (tempbuf
, "SR%3d", 128 + i
* 4);
1008 for (j
= 0; j
< 4; j
++)
1009 sreg_buf
[i
* 4 + j
] = get_hex_word ();
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]);
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]);
1021 /* There doesn't seem to be any way to get these. */
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
);
1030 write (adapt_desc
, "dw gr1,gr1\r", 11);
1032 get_hex_regs (1, GR1_REGNUM
);
1036 /* Fetch register REGNO, or all registers if REGNO is -1.
1039 adapt_fetch_register (int regno
)
1042 adapt_fetch_registers ();
1045 char *name
= get_reg_name (regno
);
1046 fprintf (adapt_stream
, "dw %s,%s\r", name
, name
);
1049 get_hex_regs (1, regno
);
1054 /* Store the remote registers from the contents of the block REGS. */
1057 adapt_store_registers (void)
1061 fprintf (adapt_stream
, "s gr1,%x\r", read_register (GR1_REGNUM
));
1064 #if defined(GR64_REGNUM)
1065 for (j
= 0; j
< 32; j
+= 16)
1067 fprintf (adapt_stream
, "s gr%d,", j
+ 64);
1068 for (i
= 0; i
< 15; ++i
)
1069 fprintf (adapt_stream
, "%x,", read_register (GR64_REGNUM
+ j
+ i
));
1070 fprintf (adapt_stream
, "%x\r", read_register (GR64_REGNUM
+ j
+ 15));
1074 for (j
= 0; j
< 32; j
+= 16)
1076 fprintf (adapt_stream
, "s gr%d,", j
+ 96);
1077 for (i
= 0; i
< 15; ++i
)
1078 fprintf (adapt_stream
, "%x,", read_register (GR96_REGNUM
+ j
+ i
));
1079 fprintf (adapt_stream
, "%x\r", read_register (GR96_REGNUM
+ j
+ 15));
1083 for (j
= 0; j
< 128; j
+= 16)
1085 fprintf (adapt_stream
, "s lr%d,", j
);
1086 for (i
= 0; i
< 15; ++i
)
1087 fprintf (adapt_stream
, "%x,", read_register (LR0_REGNUM
+ j
+ i
));
1088 fprintf (adapt_stream
, "%x\r", read_register (LR0_REGNUM
+ j
+ 15));
1092 fprintf (adapt_stream
, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM
),
1093 read_register (IPA_REGNUM
), read_register (IPB_REGNUM
));
1095 fprintf (adapt_stream
, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM
),
1096 read_register (FC_REGNUM
), read_register (CR_REGNUM
));
1098 fprintf (adapt_stream
, "s sr131,%x\r", read_register (Q_REGNUM
));
1100 fprintf (adapt_stream
, "s sr0,");
1101 for (i
= 0; i
< 7; ++i
)
1102 fprintf (adapt_stream
, "%x,", read_register (VAB_REGNUM
+ i
));
1104 fprintf (adapt_stream
, "s sr7,");
1105 for (i
= 7; i
< 14; ++i
)
1106 fprintf (adapt_stream
, "%x,", read_register (VAB_REGNUM
+ i
));
1110 /* Store register REGNO, or all if REGNO == -1.
1111 Return errno value. */
1113 adapt_store_register (int regno
)
1115 /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1117 adapt_store_registers ();
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
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
1128 if (regno
== GR1_REGNUM
)
1129 registers_changed ();
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
1141 adapt_prepare_to_store (void)
1143 /* Do nothing, since we can store individual regs */
1147 translate_addr (CORE_ADDR addr
)
1149 #if defined(KERNEL_DEBUGGING)
1150 /* Check for a virtual address in the kernel */
1151 /* Assume physical address of ublock is in paddr_u register */
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
);
1168 /* FIXME! Merge these two. */
1170 adapt_xfer_inferior_memory (CORE_ADDR memaddr
, char *myaddr
, int len
, int write
)
1173 memaddr
= translate_addr (memaddr
);
1176 return adapt_write_inferior_memory (memaddr
, myaddr
, len
);
1178 return adapt_read_inferior_memory (memaddr
, myaddr
, len
);
1182 adapt_files_info (void)
1184 printf_filtered ("\tAttached to %s at %d baud and running program %s\n",
1185 dev_name
, baudrate
, prog_name
);
1186 printf_filtered ("\ton an %s processor.\n", processor_name
[processor_type
]);
1189 /* Copy LEN bytes of data from debugger memory at MYADDR
1190 to inferior's memory at MEMADDR. Returns errno value.
1191 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1194 adapt_write_inferior_memory (CORE_ADDR memaddr
, char *myaddr
, int len
)
1199 /* Turn TU bit off so we can do 'sb' commands */
1200 cps
= read_register (CPS_REGNUM
);
1201 if (cps
& 0x00000800)
1202 write_register (CPS_REGNUM
, cps
& ~(0x00000800));
1204 for (i
= 0; i
< len
; i
++)
1207 fprintf (adapt_stream
, "sb %x,", memaddr
+ i
);
1208 if ((i
% 16) == 15 || i
== len
- 1)
1210 fprintf (adapt_stream
, "%x\r", ((unsigned char *) myaddr
)[i
]);
1214 fprintf (adapt_stream
, "%x,", ((unsigned char *) myaddr
)[i
]);
1216 /* Restore the old value of cps if the TU bit was on */
1217 if (cps
& 0x00000800)
1218 write_register (CPS_REGNUM
, cps
);
1222 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1223 at debugger address MYADDR. Returns errno value. */
1225 adapt_read_inferior_memory (CORE_ADDR memaddr
, char *myaddr
, int len
)
1229 /* Number of bytes read so far. */
1232 /* Starting address of this pass. */
1233 unsigned long startaddr
;
1235 /* Number of bytes to read in this pass. */
1238 /* Note that this code works correctly if startaddr is just less
1239 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1240 thing). That is, something like
1241 adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1242 works--it never adds len to memaddr and gets 0. */
1243 /* However, something like
1244 adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1245 doesn't need to work. Detect it and give up if there's an attempt
1248 if (((memaddr
- 1) + len
) < memaddr
)
1251 startaddr
= memaddr
;
1256 if ((startaddr
% 16) != 0)
1257 len_this_pass
-= startaddr
% 16;
1258 if (len_this_pass
> (len
- count
))
1259 len_this_pass
= (len
- count
);
1261 fprintf (adapt_stream
, "db %x,%x\r", startaddr
,
1262 (startaddr
- 1) + len_this_pass
);
1264 #ifdef NOTDEF /* Why do this */
1266 /* Look for 8 hex digits. */
1270 if (isxdigit (readchar ()))
1275 error ("Hex digit expected from remote system.");
1284 for (i
= 0; i
< len_this_pass
; i
++)
1285 get_hex_byte (&myaddr
[count
++]);
1289 startaddr
+= len_this_pass
;
1294 #define MAX_BREAKS 8
1295 static int num_brkpts
= 0;
1297 adapt_insert_breakpoint (addr
, save
)
1299 char *save
; /* Throw away, let adapt save instructions */
1301 if (num_brkpts
< MAX_BREAKS
)
1304 fprintf (adapt_stream
, "B %x", addr
);
1305 fprintf (adapt_stream
, "\r");
1307 return (0); /* Success */
1311 fprintf_filtered (gdb_stderr
,
1312 "Too many break points, break point not installed\n");
1313 return (1); /* Failure */
1318 adapt_remove_breakpoint (addr
, save
)
1320 char *save
; /* Throw away, let adapt save instructions */
1325 fprintf (adapt_stream
, "BR %x", addr
);
1326 fprintf (adapt_stream
, "\r");
1327 fflush (adapt_stream
);
1333 /* Clear the adapts notion of what the break points are */
1335 adapt_clear_breakpoints (void)
1339 fprintf (adapt_stream
, "BR"); /* Clear all break points */
1340 fprintf (adapt_stream
, "\r");
1341 fflush (adapt_stream
);
1349 adapt_clear_breakpoints ();
1350 pop_target (); /* Pop back to no-child state */
1351 generic_mourn_inferior ();
1354 /* Display everthing we read in from the adapt until we match/see the
1358 display_until (char *str
)
1362 while (c
= readchar ())
1367 if (i
== strlen (str
))
1374 for (j
= 0; j
< i
; j
++) /* Put everthing we matched */
1385 /* Put a command string, in args, out to the adapt. The adapt is assumed to
1386 be in raw mode, all writing/reading done through adapt_desc.
1387 Ouput from the adapt is placed on the users terminal until the
1388 prompt from the adapt is seen.
1389 FIXME: Can't handle commands that take input. */
1392 adapt_com (char *args
, int fromtty
)
1396 printf_filtered ("Adapt not open. Use the 'target' command to open.\n");
1400 /* Clear all input so only command relative output is displayed */
1403 switch (islower (args
[0]) ? toupper (args
[0]) : args
[0])
1406 printf_filtered ("Unknown/Unimplemented adapt command '%s'\n", args
);
1408 case 'G': /* Go, begin execution */
1409 write (adapt_desc
, args
, strlen (args
));
1410 write (adapt_desc
, "\r", 1);
1413 case 'B': /* Break points, B or BR */
1414 case 'C': /* Check current 29k status (running/halted) */
1415 case 'D': /* Display data/registers */
1416 case 'I': /* Input from i/o space */
1417 case 'J': /* Jam an instruction */
1418 case 'K': /* Kill, stop execution */
1419 case 'L': /* Disassemble */
1420 case 'O': /* Output to i/o space */
1421 case 'T': /* Trace */
1422 case 'P': /* Pulse an input line */
1423 case 'X': /* Examine special purpose registers */
1424 case 'Z': /* Display trace buffer */
1425 write (adapt_desc
, args
, strlen (args
));
1426 write (adapt_desc
, "\r", 1);
1427 expect (args
); /* Don't display the command */
1428 display_until ("# ");
1430 /* Begin commands that take input in the form 'c x,y[,z...]' */
1431 case 'S': /* Set memory or register */
1432 if (strchr (args
, ','))
1433 { /* Assume it is properly formatted */
1434 write (adapt_desc
, args
, strlen (args
));
1435 write (adapt_desc
, "\r", 1);
1442 /* Define the target subroutine names */
1444 struct target_ops adapt_ops
;
1447 init_adapt_ops (void)
1449 adapt_ops
.to_shortname
= "adapt";
1450 adapt_ops
.to_longname
= "Remote AMD `Adapt' target";
1451 adapt_ops
.to_doc
= "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232";
1452 adapt_ops
.to_open
= adapt_open
;
1453 adapt_ops
.to_close
= adapt_close
;
1454 adapt_ops
.to_attach
= adapt_attach
;
1455 adapt_ops
.to_post_attach
= NULL
;
1456 adapt_ops
.to_require_attach
= NULL
;
1457 adapt_ops
.to_detach
= adapt_detach
;
1458 adapt_ops
.to_require_detach
= NULL
;
1459 adapt_ops
.to_resume
= adapt_resume
;
1460 adapt_ops
.to_wait
= adapt_wait
;
1461 adapt_ops
.to_post_wait
= NULL
;
1462 adapt_ops
.to_fetch_registers
= adapt_fetch_register
;
1463 adapt_ops
.to_store_registers
= adapt_store_register
;
1464 adapt_ops
.to_prepare_to_store
= adapt_prepare_to_store
;
1465 adapt_ops
.to_xfer_memory
= adapt_xfer_inferior_memory
;
1466 adapt_ops
.to_files_info
= adapt_files_info
;
1467 adapt_ops
.to_insert_breakpoint
= adapt_insert_breakpoint
;
1468 adapt_ops
.to_remove_breakpoint
= adapt_remove_breakpoint
;
1469 adapt_ops
.to_terminal_init
= 0;
1470 adapt_ops
.to_terminal_inferior
= 0;
1471 adapt_ops
.to_terminal_ours_for_output
= 0;
1472 adapt_ops
.to_terminal_ours
= 0;
1473 adapt_ops
.to_terminal_info
= 0;
1474 adapt_ops
.to_kill
= adapt_kill
;
1475 adapt_ops
.to_load
= adapt_load
;
1476 adapt_ops
.to_lookup_symbol
= 0;
1477 adapt_ops
.to_create_inferior
= adapt_create_inferior
;
1478 adapt_ops
.to_post_startup_inferior
= NULL
;
1479 adapt_ops
.to_acknowledge_created_inferior
= NULL
;
1480 adapt_ops
.to_clone_and_follow_inferior
= NULL
;
1481 adapt_ops
.to_post_follow_inferior_by_clone
= NULL
;
1482 adapt_ops
.to_insert_fork_catchpoint
= NULL
;
1483 adapt_ops
.to_remove_fork_catchpoint
= NULL
;
1484 adapt_ops
.to_insert_vfork_catchpoint
= NULL
;
1485 adapt_ops
.to_remove_vfork_catchpoint
= NULL
;
1486 adapt_ops
.to_has_forked
= NULL
;
1487 adapt_ops
.to_has_vforked
= NULL
;
1488 adapt_ops
.to_can_follow_vfork_prior_to_exec
= NULL
;
1489 adapt_ops
.to_post_follow_vfork
= NULL
;
1490 adapt_ops
.to_insert_exec_catchpoint
= NULL
;
1491 adapt_ops
.to_remove_exec_catchpoint
= NULL
;
1492 adapt_ops
.to_has_execd
= NULL
;
1493 adapt_ops
.to_reported_exec_events_per_exec_call
= NULL
;
1494 adapt_ops
.to_has_exited
= NULL
;
1495 adapt_ops
.to_mourn_inferior
= adapt_mourn
;
1496 adapt_ops
.to_can_run
= 0;
1497 adapt_ops
.to_notice_signals
= 0;
1498 adapt_ops
.to_thread_alive
= 0;
1499 adapt_ops
.to_stop
= 0; /* process_stratum; */
1500 adapt_ops
.to_pid_to_exec_file
= NULL
;
1501 adapt_ops
.to_core_file_to_sym_file
= NULL
;
1502 adapt_ops
.to_stratum
= 0;
1503 adapt_ops
.DONT_USE
= 0;
1504 adapt_ops
.to_has_all_memory
= 1;
1505 adapt_ops
.to_has_memory
= 1;
1506 adapt_ops
.to_has_stack
= 1;
1507 adapt_ops
.to_has_registers
= 1;
1508 adapt_ops
.to_has_execution
= 0;
1509 adapt_ops
.to_sections
= 0;
1510 adapt_ops
.to_sections_end
= 0;
1511 adapt_ops
.to_magic
= OPS_MAGIC
;
1512 } /* init_adapt_ops */
1515 _initialize_remote_adapt (void)
1518 add_target (&adapt_ops
);
1519 add_com ("adapt <command>", class_obscure
, adapt_com
,
1520 "Send a command to the AMD Adapt remote monitor.");