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 (desc
, turnon
)
131 ioctl (desc
, TIOCGETP
, &sg
);
136 sg
.c_lflag
&= ~(ICANON
);
144 sg
.c_lflag
|= ICANON
;
146 sg
.sg_flags
&= ~(RAW
);
149 ioctl (desc
, TIOCSETP
, &sg
);
152 /* Suck up all the input from the adapt */
158 /* termio does the timeout for us. */
159 while (read (adapt_desc
, buf
, 8) > 0);
162 while (read (adapt_desc
, buf
, 8) > 0);
167 /* Read a character from the remote system, doing all the fancy
176 /* termio does the timeout for us. */
177 read (adapt_desc
, &buf
, 1);
180 if (read (adapt_desc
, &buf
, 1) < 0)
183 error ("Timeout reading from remote system.");
185 perror_with_name ("remote");
191 error ("Timeout reading from remote system.");
192 #if defined (LOG_FILE)
193 putc (buf
& 0x7f, log_file
);
198 /* Keep discarding input from the remote system, until STRING is found.
199 Let the user break out immediately. */
206 fflush (adapt_stream
);
210 if (readchar () == *p
)
224 /* Keep discarding input until we see the adapt prompt.
226 The convention for dealing with the prompt is that you
228 o *then* wait for the prompt.
230 Thus the last thing that a procedure does with the serial line
231 will be an expect_prompt(). Exception: adapt_resume does not
232 wait for the prompt, because the terminal is being handed over
233 to the inferior. However, the next thing which happens after that
234 is a adapt_wait which does wait for the prompt.
235 Note that this includes abnormal exit, e.g. error(). This is
236 necessary to prevent getting into states from which we can't
241 #if defined (LOG_FILE)
242 /* This is a convenient place to do this. The idea is to do it often
243 enough that we never lose much data if we terminate abnormally. */
246 fflush (adapt_stream
);
250 /* Get a hex digit from the remote system & return its value.
251 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
253 get_hex_digit (ignore_space
)
260 if (ch
>= '0' && ch
<= '9')
262 else if (ch
>= 'A' && ch
<= 'F')
263 return ch
- 'A' + 10;
264 else if (ch
>= 'a' && ch
<= 'f')
265 return ch
- 'a' + 10;
266 else if (ch
== ' ' && ignore_space
)
271 error ("Invalid hex digit from remote system.");
276 /* Get a byte from adapt_desc and put it in *BYT. Accept any number
284 val
= get_hex_digit (1) << 4;
285 val
|= get_hex_digit (0);
289 /* Read a 32-bit hex word from the adapt, preceded by a space */
297 for (j
= 0; j
< 8; j
++)
298 val
= (val
<< 4) + get_hex_digit (j
== 0);
301 /* Get N 32-bit hex words from remote, each preceded by a space
302 and put them in registers starting at REGNO. */
304 get_hex_regs (n
, regno
)
311 val
= get_hex_word ();
312 supply_register (regno
++, (char *) &val
);
315 /* Called when SIGALRM signal sent due to alarm() timeout. */
324 volatile int n_alarms
;
331 printf ("adapt_timer called\n");
337 /* malloc'd name of the program on the remote system. */
338 static char *prog_name
= NULL
;
340 /* Number of SIGTRAPs we need to simulate. That is, the next
341 NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
342 SIGTRAP without actually waiting for anything. */
344 static int need_artificial_trap
= 0;
347 adapt_kill (arg
, from_tty
)
351 fprintf (adapt_stream
, "K");
352 fprintf (adapt_stream
, "\r");
356 * Download a file specified in 'args', to the adapt.
357 * FIXME: Assumes the file to download is a binary coff file.
360 adapt_load (args
, fromtty
)
370 printf_filtered ("Adapt not open. Use 'target' command to open adapt\n");
374 /* OK, now read in the file. Y=read, C=COFF, T=dTe port
377 #ifdef ASCII_COFF /* Ascii coff */
378 fprintf (adapt_stream
, "YA T,0\r");
379 fflush (adapt_stream
); /* Just in case */
380 /* FIXME: should check args for only 1 argument */
381 sprintf (buffer
, "cat %s | btoa > /tmp/#adapt-btoa", args
);
383 fp
= fopen ("/tmp/#adapt-btoa", "r");
384 rawmode (adapt_desc
, OFF
);
385 while (n
= fread (buffer
, 1, 1024, fp
))
389 n
-= write (adapt_desc
, buffer
, n
);
394 perror ("writing ascii coff");
399 rawmode (adapt_desc
, ON
);
400 system ("rm /tmp/#adapt-btoa");
401 #else /* Binary coff - can't get it to work . */
402 fprintf (adapt_stream
, "YC T,0\r");
403 fflush (adapt_stream
); /* Just in case */
404 if (!(fp
= fopen (args
, "r")))
406 printf_filtered ("Can't open %s\n", args
);
409 while (n
= fread (buffer
, 1, 512, fp
))
413 n
-= write (adapt_desc
, buffer
, n
);
418 perror ("writing ascii coff");
424 expect_prompt (); /* Skip garbage that comes out */
425 fprintf (adapt_stream
, "\r");
429 /* This is called not only when we first attach, but also when the
430 user types "run" after having attached. */
432 adapt_create_inferior (execfile
, args
, env
)
440 error ("Can't pass arguments to remote adapt process.");
442 if (execfile
== 0 || exec_bfd
== 0)
443 error ("No executable file specified");
445 entry_pt
= (int) bfd_get_start_address (exec_bfd
);
449 adapt_kill (NULL
, NULL
);
450 adapt_clear_breakpoints ();
451 init_wait_for_inferior ();
452 /* Clear the input because what the adapt sends back is different
453 * depending on whether it was running or not.
455 slurp_input (); /* After this there should be a prompt */
456 fprintf (adapt_stream
, "\r");
458 printf_filtered ("Do you want to download '%s' (y/n)? [y] : ", prog_name
);
464 adapt_load (prog_name
, 0);
469 /* Set the PC and wait for a go/cont */
470 fprintf (adapt_stream
, "G %x,N\r", entry_pt
);
471 printf_filtered ("Now use the 'continue' command to start.\n");
474 insert_breakpoints (); /* Needed to get correct instruction in cache */
475 proceed (entry_pt
, TARGET_SIGNAL_DEFAULT
, 0);
481 printf_filtered ("Adapt not open yet.\n");
485 /* Translate baud rates from integers to damn B_codes. Unix should
486 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
577 for (i
= 0; baudtab
[i
].rate
!= -1; i
++)
578 if (rate
== baudtab
[i
].rate
)
579 return baudtab
[i
].damn_b
;
580 return B38400
; /* Random */
584 /* Open a connection to a remote debugger.
585 NAME is the filename used for communication, then a space,
589 static int baudrate
= 9600;
591 adapt_open (name
, from_tty
)
599 /* Find the first whitespace character, it separates dev_name from
605 *p
!= '\0' && !isspace (*p
); p
++)
610 Please include the name of the device for the serial port,\n\
611 the baud rate, and the name of the program to run on the remote system.");
612 dev_name
= (char *) xmalloc (p
- name
+ 1);
613 strncpy (dev_name
, name
, p
- name
);
614 dev_name
[p
- name
] = '\0';
616 /* Skip over the whitespace after dev_name */
617 for (; isspace (*p
); p
++)
620 if (1 != sscanf (p
, "%d ", &baudrate
))
623 /* Skip the number and then the spaces */
624 for (; isdigit (*p
); p
++)
626 for (; isspace (*p
); p
++)
629 if (prog_name
!= NULL
)
631 prog_name
= savestring (p
, strlen (p
));
635 adapt_desc
= open (dev_name
, O_RDWR
);
637 perror_with_name (dev_name
);
638 ioctl (adapt_desc
, TIOCGETP
, &sg
);
639 #if ! defined(COMPILE_CHECK)
641 sg
.c_cc
[VMIN
] = 0; /* read with timeout. */
642 sg
.c_cc
[VTIME
] = timeout
* 10;
643 sg
.c_lflag
&= ~(ICANON
| ECHO
);
644 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | damn_b (baudrate
);
646 sg
.sg_ispeed
= damn_b (baudrate
);
647 sg
.sg_ospeed
= damn_b (baudrate
);
648 sg
.sg_flags
|= RAW
| ANYP
;
649 sg
.sg_flags
&= ~ECHO
;
652 ioctl (adapt_desc
, TIOCSETP
, &sg
);
653 adapt_stream
= fdopen (adapt_desc
, "r+");
654 #endif /* compile_check */
655 push_target (&adapt_ops
);
658 #ifndef NO_SIGINTERRUPT
659 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
661 if (siginterrupt (SIGALRM
, 1) != 0)
662 perror ("adapt_open: error in siginterrupt");
665 /* Set up read timeout timer. */
666 if ((void (*)) signal (SIGALRM
, adapt_timer
) == (void (*)) -1)
667 perror ("adapt_open: error in signal");
670 #if defined (LOG_FILE)
671 log_file
= fopen (LOG_FILE
, "w");
672 if (log_file
== NULL
)
673 perror_with_name (LOG_FILE
);
676 /* Put this port into NORMAL mode, send the 'normal' character */
677 write (adapt_desc
, "\ 1", 1); /* Control A */
678 write (adapt_desc
, "\r", 1);
681 /* Hello? Are you there? */
682 write (adapt_desc
, "\r", 1);
686 /* Clear any break points */
687 adapt_clear_breakpoints ();
689 /* Print out some stuff, letting the user now what's going on */
690 printf_filtered ("Connected to an Adapt via %s.\n", dev_name
);
691 /* FIXME: can this restriction be removed? */
692 printf_filtered ("Remote debugging using virtual addresses works only\n");
693 printf_filtered ("\twhen virtual addresses map 1:1 to physical addresses.\n");
694 if (processor_type
!= a29k_freeze_mode
)
696 fprintf_filtered (gdb_stderr
,
697 "Freeze-mode debugging not available, and can only be done on an A29050.\n");
701 /* Close out all files and local state before this target loses control. */
704 adapt_close (quitting
)
708 /* Clear any break points */
709 adapt_clear_breakpoints ();
711 /* Put this port back into REMOTE mode */
714 fflush (adapt_stream
);
715 sleep (1); /* Let any output make it all the way back */
716 write (adapt_desc
, "R\r", 2);
719 /* Due to a bug in Unix, fclose closes not only the stdio stream,
720 but also the file descriptor. So we don't actually close
723 fclose (adapt_stream
); /* This also closes adapt_desc */
725 /* close (adapt_desc); */
727 /* Do not try to close adapt_desc again, later in the program. */
731 #if defined (LOG_FILE)
734 if (ferror (log_file
))
735 printf_filtered ("Error writing log file.\n");
736 if (fclose (log_file
) != 0)
737 printf_filtered ("Error closing log file.\n");
743 /* Attach to the target that is already loaded and possibly running */
745 adapt_attach (args
, from_tty
)
751 printf_filtered ("Attaching to remote program %s.\n", prog_name
);
753 /* Send the adapt a kill. It is ok if it is not already running */
754 fprintf (adapt_stream
, "K\r");
755 fflush (adapt_stream
);
756 expect_prompt (); /* Slurp the echo */
760 /* Terminate the open connection to the remote debugger.
761 Use this when you want to detach and do something else
764 adapt_detach (args
, from_tty
)
770 { /* Send it on its way (tell it to continue) */
771 adapt_clear_breakpoints ();
772 fprintf (adapt_stream
, "G\r");
775 pop_target (); /* calls adapt_close to do the real work */
777 printf_filtered ("Ending remote %s debugging\n", target_shortname
);
780 /* Tell the remote machine to resume. */
783 adapt_resume (pid
, step
, sig
)
785 enum target_signal sig
;
789 write (adapt_desc
, "t 1,s\r", 6);
790 /* Wait for the echo. */
791 expect ("t 1,s\r\n");
792 /* Then comes a line containing the instruction we stepped to. */
794 /* Then we get the prompt. */
797 /* Force the next adapt_wait to return a trap. Not doing anything
798 about I/O from the target means that the user has to type
799 "continue" to see any. FIXME, this should be fixed. */
800 need_artificial_trap
= 1;
804 write (adapt_desc
, "G\r", 2);
805 /* Swallow the echo. */
810 /* Wait until the remote machine stops, then return,
811 storing status in STATUS just as `wait' would. */
815 struct target_waitstatus
*status
;
817 /* Strings to look for. '?' means match any single character.
818 Note that with the algorithm we use, the initial character
819 of the string cannot recur in the string, or we will not
820 find some cases of the string in the input. */
822 static char bpt
[] = "@";
823 /* It would be tempting to look for "\n[__exit + 0x8]\n"
824 but that requires loading symbols with "yc i" and even if
825 we did do that we don't know that the file has symbols. */
826 static char exitmsg
[] = "@????????I JMPTI GR121,LR0";
830 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
832 /* Current position in swallowed. */
833 char *swallowed_p
= swallowed
;
837 int old_timeout
= timeout
;
838 int old_immediate_quit
= immediate_quit
;
840 status
->kind
= TARGET_WAITKIND_EXITED
;
841 status
->value
.integer
= 0;
843 if (need_artificial_trap
!= 0)
845 status
->kind
= TARGET_WAITKIND_STOPPED
;
846 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
847 need_artificial_trap
--;
851 timeout
= 0; /* Don't time out -- user program is running. */
852 immediate_quit
= 1; /* Helps ability to QUIT */
855 QUIT
; /* Let user quit and leave process running */
869 if (ch
== *ep
|| *ep
== '?')
884 /* Print out any characters which have been swallowed. */
885 for (p
= swallowed
; p
< swallowed_p
; ++p
)
887 swallowed_p
= swallowed
;
894 status
->kind
= TARGET_WAITKIND_STOPPED
;
895 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
899 status
->kind
= TARGET_WAITKIND_EXITED
;
900 status
->value
.integer
= 0;
902 timeout
= old_timeout
;
903 immediate_quit
= old_immediate_quit
;
907 /* Return the name of register number REGNO
908 in the form input and output by adapt.
910 Returns a pointer to a static buffer containing the answer. */
916 if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
917 sprintf (buf
, "GR%03d", regno
- GR96_REGNUM
+ 96);
918 #if defined(GR64_REGNUM)
919 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32)
920 sprintf (buf
, "GR%03d", regno
- GR64_REGNUM
+ 64);
922 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
923 sprintf (buf
, "LR%03d", regno
- LR0_REGNUM
);
924 else if (regno
== Q_REGNUM
)
925 strcpy (buf
, "SR131");
926 else if (regno
>= BP_REGNUM
&& regno
<= CR_REGNUM
)
927 sprintf (buf
, "SR%03d", regno
- BP_REGNUM
+ 133);
928 else if (regno
== ALU_REGNUM
)
929 strcpy (buf
, "SR132");
930 else if (regno
>= IPC_REGNUM
&& regno
<= IPB_REGNUM
)
931 sprintf (buf
, "SR%03d", regno
- IPC_REGNUM
+ 128);
932 else if (regno
>= VAB_REGNUM
&& regno
<= LRU_REGNUM
)
934 /* When a 29050 is in freeze-mode, read shadow pcs instead */
935 if ((regno
>= NPC_REGNUM
&& regno
<= PC2_REGNUM
) && USE_SHADOW_PC
)
936 sprintf (buf
, "SR%03d", regno
- NPC_REGNUM
+ 20);
938 sprintf (buf
, "SR%03d", regno
- VAB_REGNUM
);
940 else if (regno
== GR1_REGNUM
)
941 strcpy (buf
, "GR001");
945 /* Read the remote registers. */
948 adapt_fetch_registers ()
959 #if defined(GR64_REGNUM)
960 write (adapt_desc
, "dw gr64,gr95\r", 13);
961 for (reg_index
= 64, regnum_index
= GR64_REGNUM
;
963 reg_index
+= 4, regnum_index
+= 4)
965 sprintf (tempbuf
, "GR%03d ", reg_index
);
967 get_hex_regs (4, regnum_index
);
971 write (adapt_desc
, "dw gr96,gr127\r", 14);
972 for (reg_index
= 96, regnum_index
= GR96_REGNUM
;
974 reg_index
+= 4, regnum_index
+= 4)
976 sprintf (tempbuf
, "GR%03d ", reg_index
);
978 get_hex_regs (4, regnum_index
);
985 for (i
= 0; i
< 128; i
+= 32)
987 /* The PC has a tendency to hang if we get these
988 all in one fell swoop ("dw lr0,lr127"). */
989 sprintf (tempbuf
, "dw lr%d\r", i
);
990 write (adapt_desc
, tempbuf
, strlen (tempbuf
));
991 for (reg_index
= i
, regnum_index
= LR0_REGNUM
+ i
;
993 reg_index
+= 4, regnum_index
+= 4)
995 sprintf (tempbuf
, "LR%03d ", reg_index
);
997 get_hex_regs (4, regnum_index
);
1005 sprintf (tempbuf
, "dw sr0\r");
1006 write (adapt_desc
, tempbuf
, strlen (tempbuf
));
1007 for (i
= 0; i
< 4; i
++)
1009 sprintf (tempbuf
, "SR%3d", i
* 4);
1011 for (j
= 0; j
< (i
== 3 ? 3 : 4); j
++)
1012 sreg_buf
[i
* 4 + j
] = get_hex_word ();
1016 * Read the pcs individually if we are in freeze mode.
1017 * See get_reg_name(), it translates the register names for the pcs to
1018 * the names of the shadow pcs.
1022 sreg_buf
[10] = read_register (NPC_REGNUM
); /* pc0 */
1023 sreg_buf
[11] = read_register (PC_REGNUM
); /* pc1 */
1024 sreg_buf
[12] = read_register (PC2_REGNUM
); /* pc2 */
1026 for (i
= 0; i
< 14; i
++) /* Supply vab -> lru */
1027 supply_register (VAB_REGNUM
+ i
, (char *) &sreg_buf
[i
]);
1028 sprintf (tempbuf
, "dw sr128\r");
1029 write (adapt_desc
, tempbuf
, strlen (tempbuf
));
1030 for (i
= 0; i
< 2; i
++)
1031 { /* SR128 - SR135 */
1032 sprintf (tempbuf
, "SR%3d", 128 + i
* 4);
1034 for (j
= 0; j
< 4; j
++)
1035 sreg_buf
[i
* 4 + j
] = get_hex_word ();
1038 supply_register (IPC_REGNUM
, (char *) &sreg_buf
[0]);
1039 supply_register (IPA_REGNUM
, (char *) &sreg_buf
[1]);
1040 supply_register (IPB_REGNUM
, (char *) &sreg_buf
[2]);
1041 supply_register (Q_REGNUM
, (char *) &sreg_buf
[3]);
1043 supply_register (BP_REGNUM
, (char *) &sreg_buf
[5]);
1044 supply_register (FC_REGNUM
, (char *) &sreg_buf
[6]);
1045 supply_register (CR_REGNUM
, (char *) &sreg_buf
[7]);
1047 /* There doesn't seem to be any way to get these. */
1050 supply_register (FPE_REGNUM
, (char *) &val
);
1051 supply_register (INTE_REGNUM
, (char *) &val
);
1052 supply_register (FPS_REGNUM
, (char *) &val
);
1053 supply_register (EXO_REGNUM
, (char *) &val
);
1056 write (adapt_desc
, "dw gr1,gr1\r", 11);
1058 get_hex_regs (1, GR1_REGNUM
);
1062 /* Fetch register REGNO, or all registers if REGNO is -1.
1065 adapt_fetch_register (regno
)
1069 adapt_fetch_registers ();
1072 char *name
= get_reg_name (regno
);
1073 fprintf (adapt_stream
, "dw %s,%s\r", name
, name
);
1076 get_hex_regs (1, regno
);
1081 /* Store the remote registers from the contents of the block REGS. */
1084 adapt_store_registers ()
1088 fprintf (adapt_stream
, "s gr1,%x\r", read_register (GR1_REGNUM
));
1091 #if defined(GR64_REGNUM)
1092 for (j
= 0; j
< 32; j
+= 16)
1094 fprintf (adapt_stream
, "s gr%d,", j
+ 64);
1095 for (i
= 0; i
< 15; ++i
)
1096 fprintf (adapt_stream
, "%x,", read_register (GR64_REGNUM
+ j
+ i
));
1097 fprintf (adapt_stream
, "%x\r", read_register (GR64_REGNUM
+ j
+ 15));
1101 for (j
= 0; j
< 32; j
+= 16)
1103 fprintf (adapt_stream
, "s gr%d,", j
+ 96);
1104 for (i
= 0; i
< 15; ++i
)
1105 fprintf (adapt_stream
, "%x,", read_register (GR96_REGNUM
+ j
+ i
));
1106 fprintf (adapt_stream
, "%x\r", read_register (GR96_REGNUM
+ j
+ 15));
1110 for (j
= 0; j
< 128; j
+= 16)
1112 fprintf (adapt_stream
, "s lr%d,", j
);
1113 for (i
= 0; i
< 15; ++i
)
1114 fprintf (adapt_stream
, "%x,", read_register (LR0_REGNUM
+ j
+ i
));
1115 fprintf (adapt_stream
, "%x\r", read_register (LR0_REGNUM
+ j
+ 15));
1119 fprintf (adapt_stream
, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM
),
1120 read_register (IPA_REGNUM
), read_register (IPB_REGNUM
));
1122 fprintf (adapt_stream
, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM
),
1123 read_register (FC_REGNUM
), read_register (CR_REGNUM
));
1125 fprintf (adapt_stream
, "s sr131,%x\r", read_register (Q_REGNUM
));
1127 fprintf (adapt_stream
, "s sr0,");
1128 for (i
= 0; i
< 7; ++i
)
1129 fprintf (adapt_stream
, "%x,", read_register (VAB_REGNUM
+ i
));
1131 fprintf (adapt_stream
, "s sr7,");
1132 for (i
= 7; i
< 14; ++i
)
1133 fprintf (adapt_stream
, "%x,", read_register (VAB_REGNUM
+ i
));
1137 /* Store register REGNO, or all if REGNO == -1.
1138 Return errno value. */
1140 adapt_store_register (regno
)
1143 /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1145 adapt_store_registers ();
1148 char *name
= get_reg_name (regno
);
1149 fprintf (adapt_stream
, "s %s,%x\r", name
, read_register (regno
));
1150 /* Setting GR1 changes the numbers of all the locals, so
1151 invalidate the register cache. Do this *after* calling
1152 read_register, because we want read_register to return the
1153 value that write_register has just stuffed into the registers
1154 array, not the value of the register fetched from the
1156 if (regno
== GR1_REGNUM
)
1157 registers_changed ();
1162 /* Get ready to modify the registers array. On machines which store
1163 individual registers, this doesn't need to do anything. On machines
1164 which store all the registers in one fell swoop, this makes sure
1165 that registers contains all the registers from the program being
1169 adapt_prepare_to_store ()
1171 /* Do nothing, since we can store individual regs */
1175 translate_addr (addr
)
1178 #if defined(KERNEL_DEBUGGING)
1179 /* Check for a virtual address in the kernel */
1180 /* Assume physical address of ublock is in paddr_u register */
1183 /* PADDR_U register holds the physical address of the ublock */
1184 CORE_ADDR i
= (CORE_ADDR
) read_register (PADDR_U_REGNUM
);
1185 return (i
+ addr
- (CORE_ADDR
) UVADDR
);
1197 /* FIXME! Merge these two. */
1199 adapt_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
1206 memaddr
= translate_addr (memaddr
);
1209 return adapt_write_inferior_memory (memaddr
, myaddr
, len
);
1211 return adapt_read_inferior_memory (memaddr
, myaddr
, len
);
1217 printf_filtered ("\tAttached to %s at %d baud and running program %s\n",
1218 dev_name
, baudrate
, prog_name
);
1219 printf_filtered ("\ton an %s processor.\n", processor_name
[processor_type
]);
1222 /* Copy LEN bytes of data from debugger memory at MYADDR
1223 to inferior's memory at MEMADDR. Returns errno value.
1224 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1227 adapt_write_inferior_memory (memaddr
, myaddr
, len
)
1235 /* Turn TU bit off so we can do 'sb' commands */
1236 cps
= read_register (CPS_REGNUM
);
1237 if (cps
& 0x00000800)
1238 write_register (CPS_REGNUM
, cps
& ~(0x00000800));
1240 for (i
= 0; i
< len
; i
++)
1243 fprintf (adapt_stream
, "sb %x,", memaddr
+ i
);
1244 if ((i
% 16) == 15 || i
== len
- 1)
1246 fprintf (adapt_stream
, "%x\r", ((unsigned char *) myaddr
)[i
]);
1250 fprintf (adapt_stream
, "%x,", ((unsigned char *) myaddr
)[i
]);
1252 /* Restore the old value of cps if the TU bit was on */
1253 if (cps
& 0x00000800)
1254 write_register (CPS_REGNUM
, cps
);
1258 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1259 at debugger address MYADDR. Returns errno value. */
1261 adapt_read_inferior_memory (memaddr
, myaddr
, len
)
1268 /* Number of bytes read so far. */
1271 /* Starting address of this pass. */
1272 unsigned long startaddr
;
1274 /* Number of bytes to read in this pass. */
1277 /* Note that this code works correctly if startaddr is just less
1278 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1279 thing). That is, something like
1280 adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1281 works--it never adds len to memaddr and gets 0. */
1282 /* However, something like
1283 adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1284 doesn't need to work. Detect it and give up if there's an attempt
1287 if (((memaddr
- 1) + len
) < memaddr
)
1290 startaddr
= memaddr
;
1295 if ((startaddr
% 16) != 0)
1296 len_this_pass
-= startaddr
% 16;
1297 if (len_this_pass
> (len
- count
))
1298 len_this_pass
= (len
- count
);
1300 fprintf (adapt_stream
, "db %x,%x\r", startaddr
,
1301 (startaddr
- 1) + len_this_pass
);
1303 #ifdef NOTDEF /* Why do this */
1305 /* Look for 8 hex digits. */
1309 if (isxdigit (readchar ()))
1314 error ("Hex digit expected from remote system.");
1323 for (i
= 0; i
< len_this_pass
; i
++)
1324 get_hex_byte (&myaddr
[count
++]);
1328 startaddr
+= len_this_pass
;
1333 #define MAX_BREAKS 8
1334 static int num_brkpts
= 0;
1336 adapt_insert_breakpoint (addr
, save
)
1338 char *save
; /* Throw away, let adapt save instructions */
1340 if (num_brkpts
< MAX_BREAKS
)
1343 fprintf (adapt_stream
, "B %x", addr
);
1344 fprintf (adapt_stream
, "\r");
1346 return (0); /* Success */
1350 fprintf_filtered (gdb_stderr
,
1351 "Too many break points, break point not installed\n");
1352 return (1); /* Failure */
1357 adapt_remove_breakpoint (addr
, save
)
1359 char *save
; /* Throw away, let adapt save instructions */
1364 fprintf (adapt_stream
, "BR %x", addr
);
1365 fprintf (adapt_stream
, "\r");
1366 fflush (adapt_stream
);
1372 /* Clear the adapts notion of what the break points are */
1374 adapt_clear_breakpoints ()
1378 fprintf (adapt_stream
, "BR"); /* Clear all break points */
1379 fprintf (adapt_stream
, "\r");
1380 fflush (adapt_stream
);
1388 adapt_clear_breakpoints ();
1389 pop_target (); /* Pop back to no-child state */
1390 generic_mourn_inferior ();
1393 /* Display everthing we read in from the adapt until we match/see the
1402 while (c
= readchar ())
1407 if (i
== strlen (str
))
1414 for (j
= 0; j
< i
; j
++) /* Put everthing we matched */
1425 /* Put a command string, in args, out to the adapt. The adapt is assumed to
1426 be in raw mode, all writing/reading done through adapt_desc.
1427 Ouput from the adapt is placed on the users terminal until the
1428 prompt from the adapt is seen.
1429 FIXME: Can't handle commands that take input. */
1432 adapt_com (args
, fromtty
)
1438 printf_filtered ("Adapt not open. Use the 'target' command to open.\n");
1442 /* Clear all input so only command relative output is displayed */
1445 switch (islower (args
[0]) ? toupper (args
[0]) : args
[0])
1448 printf_filtered ("Unknown/Unimplemented adapt command '%s'\n", args
);
1450 case 'G': /* Go, begin execution */
1451 write (adapt_desc
, args
, strlen (args
));
1452 write (adapt_desc
, "\r", 1);
1455 case 'B': /* Break points, B or BR */
1456 case 'C': /* Check current 29k status (running/halted) */
1457 case 'D': /* Display data/registers */
1458 case 'I': /* Input from i/o space */
1459 case 'J': /* Jam an instruction */
1460 case 'K': /* Kill, stop execution */
1461 case 'L': /* Disassemble */
1462 case 'O': /* Output to i/o space */
1463 case 'T': /* Trace */
1464 case 'P': /* Pulse an input line */
1465 case 'X': /* Examine special purpose registers */
1466 case 'Z': /* Display trace buffer */
1467 write (adapt_desc
, args
, strlen (args
));
1468 write (adapt_desc
, "\r", 1);
1469 expect (args
); /* Don't display the command */
1470 display_until ("# ");
1472 /* Begin commands that take input in the form 'c x,y[,z...]' */
1473 case 'S': /* Set memory or register */
1474 if (strchr (args
, ','))
1475 { /* Assume it is properly formatted */
1476 write (adapt_desc
, args
, strlen (args
));
1477 write (adapt_desc
, "\r", 1);
1484 /* Define the target subroutine names */
1486 struct target_ops adapt_ops
;
1489 init_adapt_ops (void)
1491 adapt_ops
.to_shortname
= "adapt";
1492 adapt_ops
.to_longname
= "Remote AMD `Adapt' target";
1493 adapt_ops
.to_doc
= "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232";
1494 adapt_ops
.to_open
= adapt_open
;
1495 adapt_ops
.to_close
= adapt_close
;
1496 adapt_ops
.to_attach
= adapt_attach
;
1497 adapt_ops
.to_post_attach
= NULL
;
1498 adapt_ops
.to_require_attach
= NULL
;
1499 adapt_ops
.to_detach
= adapt_detach
;
1500 adapt_ops
.to_require_detach
= NULL
;
1501 adapt_ops
.to_resume
= adapt_resume
;
1502 adapt_ops
.to_wait
= adapt_wait
;
1503 adapt_ops
.to_post_wait
= NULL
;
1504 adapt_ops
.to_fetch_registers
= adapt_fetch_register
;
1505 adapt_ops
.to_store_registers
= adapt_store_register
;
1506 adapt_ops
.to_prepare_to_store
= adapt_prepare_to_store
;
1507 adapt_ops
.to_xfer_memory
= adapt_xfer_inferior_memory
;
1508 adapt_ops
.to_files_info
= adapt_files_info
;
1509 adapt_ops
.to_insert_breakpoint
= adapt_insert_breakpoint
;
1510 adapt_ops
.to_remove_breakpoint
= adapt_remove_breakpoint
;
1511 adapt_ops
.to_terminal_init
= 0;
1512 adapt_ops
.to_terminal_inferior
= 0;
1513 adapt_ops
.to_terminal_ours_for_output
= 0;
1514 adapt_ops
.to_terminal_ours
= 0;
1515 adapt_ops
.to_terminal_info
= 0;
1516 adapt_ops
.to_kill
= adapt_kill
;
1517 adapt_ops
.to_load
= adapt_load
;
1518 adapt_ops
.to_lookup_symbol
= 0;
1519 adapt_ops
.to_create_inferior
= adapt_create_inferior
;
1520 adapt_ops
.to_post_startup_inferior
= NULL
;
1521 adapt_ops
.to_acknowledge_created_inferior
= NULL
;
1522 adapt_ops
.to_clone_and_follow_inferior
= NULL
;
1523 adapt_ops
.to_post_follow_inferior_by_clone
= NULL
;
1524 adapt_ops
.to_insert_fork_catchpoint
= NULL
;
1525 adapt_ops
.to_remove_fork_catchpoint
= NULL
;
1526 adapt_ops
.to_insert_vfork_catchpoint
= NULL
;
1527 adapt_ops
.to_remove_vfork_catchpoint
= NULL
;
1528 adapt_ops
.to_has_forked
= NULL
;
1529 adapt_ops
.to_has_vforked
= NULL
;
1530 adapt_ops
.to_can_follow_vfork_prior_to_exec
= NULL
;
1531 adapt_ops
.to_post_follow_vfork
= NULL
;
1532 adapt_ops
.to_insert_exec_catchpoint
= NULL
;
1533 adapt_ops
.to_remove_exec_catchpoint
= NULL
;
1534 adapt_ops
.to_has_execd
= NULL
;
1535 adapt_ops
.to_reported_exec_events_per_exec_call
= NULL
;
1536 adapt_ops
.to_has_exited
= NULL
;
1537 adapt_ops
.to_mourn_inferior
= adapt_mourn
;
1538 adapt_ops
.to_can_run
= 0;
1539 adapt_ops
.to_notice_signals
= 0;
1540 adapt_ops
.to_thread_alive
= 0;
1541 adapt_ops
.to_stop
= 0; /* process_stratum; */
1542 adapt_ops
.to_pid_to_exec_file
= NULL
;
1543 adapt_ops
.to_core_file_to_sym_file
= NULL
;
1544 adapt_ops
.to_stratum
= 0;
1545 adapt_ops
.DONT_USE
= 0;
1546 adapt_ops
.to_has_all_memory
= 1;
1547 adapt_ops
.to_has_memory
= 1;
1548 adapt_ops
.to_has_stack
= 1;
1549 adapt_ops
.to_has_registers
= 1;
1550 adapt_ops
.to_has_execution
= 0;
1551 adapt_ops
.to_sections
= 0;
1552 adapt_ops
.to_sections_end
= 0;
1553 adapt_ops
.to_magic
= OPS_MAGIC
;
1554 } /* init_adapt_ops */
1557 _initialize_remote_adapt ()
1560 add_target (&adapt_ops
);
1561 add_com ("adapt <command>", class_obscure
, adapt_com
,
1562 "Send a command to the AMD Adapt remote monitor.");