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., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 /* This is like remote.c but is for an esoteric situation--
23 having a 29k board attached to an Adapt inline monitor.
24 The monitor is connected via serial line to a unix machine
27 3/91 - developed on Sun3 OS 4.1, by David Wood
28 o - I can't get binary coff to load.
29 o - I can't get 19200 baud rate to work.
30 7/91 o - Freeze mode tracing can be done on a 29050. */
45 /* External data declarations */
46 extern int stop_soon_quietly
; /* for wait_for_inferior */
48 /* Forward data declarations */
49 extern struct target_ops adapt_ops
; /* Forward declaration */
51 /* Forward function declarations */
52 static void adapt_fetch_registers ();
53 static void adapt_store_registers ();
54 static void adapt_close ();
55 static int adapt_clear_breakpoints();
57 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
58 #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
60 /* Can't seem to get binary coff working */
61 #define ASCII_COFF /* Adapt will be downloaded with ascii coff */
63 /* FIXME: Replace with `set remotedebug'. */
64 #define LOG_FILE "adapt.log"
65 #if defined (LOG_FILE)
69 static int timeout
= 5;
70 static char *dev_name
;
72 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
73 adapt_open knows that we don't have a file open when the program
77 /* stream which is fdopen'd from adapt_desc. Only valid when
93 ioctl (desc
, TIOCGETP
, &sg
);
97 sg
.c_lflag
&= ~(ICANON
);
103 sg
.c_lflag
|= ICANON
;
105 sg
.sg_flags
&= ~(RAW
);
108 ioctl (desc
, TIOCSETP
, &sg
);
111 /* Suck up all the input from the adapt */
117 /* termio does the timeout for us. */
118 while (read (adapt_desc
, buf
, 8) > 0);
121 while (read (adapt_desc
, buf
, 8) > 0);
126 /* Read a character from the remote system, doing all the fancy
135 /* termio does the timeout for us. */
136 read (adapt_desc
, &buf
, 1);
139 if (read (adapt_desc
, &buf
, 1) < 0)
142 error ("Timeout reading from remote system.");
144 perror_with_name ("remote");
150 error ("Timeout reading from remote system.");
151 #if defined (LOG_FILE)
152 putc (buf
& 0x7f, log_file
);
157 /* Keep discarding input from the remote system, until STRING is found.
158 Let the user break out immediately. */
165 fflush(adapt_stream
);
169 if (readchar() == *p
)
183 /* Keep discarding input until we see the adapt prompt.
185 The convention for dealing with the prompt is that you
187 o *then* wait for the prompt.
189 Thus the last thing that a procedure does with the serial line
190 will be an expect_prompt(). Exception: adapt_resume does not
191 wait for the prompt, because the terminal is being handed over
192 to the inferior. However, the next thing which happens after that
193 is a adapt_wait which does wait for the prompt.
194 Note that this includes abnormal exit, e.g. error(). This is
195 necessary to prevent getting into states from which we can't
200 #if defined (LOG_FILE)
201 /* This is a convenient place to do this. The idea is to do it often
202 enough that we never lose much data if we terminate abnormally. */
205 fflush(adapt_stream
);
209 /* Get a hex digit from the remote system & return its value.
210 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
212 get_hex_digit (ignore_space
)
219 if (ch
>= '0' && ch
<= '9')
221 else if (ch
>= 'A' && ch
<= 'F')
222 return ch
- 'A' + 10;
223 else if (ch
>= 'a' && ch
<= 'f')
224 return ch
- 'a' + 10;
225 else if (ch
== ' ' && ignore_space
)
230 error ("Invalid hex digit from remote system.");
235 /* Get a byte from adapt_desc and put it in *BYT. Accept any number
243 val
= get_hex_digit (1) << 4;
244 val
|= get_hex_digit (0);
248 /* Read a 32-bit hex word from the adapt, preceded by a space */
256 for (j
= 0; j
< 8; j
++)
257 val
= (val
<< 4) + get_hex_digit (j
== 0);
260 /* Get N 32-bit hex words from remote, each preceded by a space
261 and put them in registers starting at REGNO. */
263 get_hex_regs (n
, regno
)
269 val
= get_hex_word();
270 supply_register(regno
++,(char *) &val
);
273 /* Called when SIGALRM signal sent due to alarm() timeout. */
278 # define volatile /**/
281 volatile int n_alarms
;
288 printf ("adapt_timer called\n");
294 /* malloc'd name of the program on the remote system. */
295 static char *prog_name
= NULL
;
297 /* Number of SIGTRAPs we need to simulate. That is, the next
298 NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
299 SIGTRAP without actually waiting for anything. */
301 static int need_artificial_trap
= 0;
304 adapt_kill(arg
,from_tty
)
308 fprintf (adapt_stream
, "K");
309 fprintf (adapt_stream
, "\r");
313 * Download a file specified in 'args', to the adapt.
314 * FIXME: Assumes the file to download is a binary coff file.
317 adapt_load(args
,fromtty
)
326 printf_filtered("Adapt not open. Use 'target' command to open adapt\n");
330 /* OK, now read in the file. Y=read, C=COFF, T=dTe port
333 #ifdef ASCII_COFF /* Ascii coff */
334 fprintf (adapt_stream
, "YA T,0\r");
335 fflush(adapt_stream
); /* Just in case */
336 /* FIXME: should check args for only 1 argument */
337 sprintf(buffer
,"cat %s | btoa > /tmp/#adapt-btoa",args
);
339 fp
= fopen("/tmp/#adapt-btoa","r");
340 rawmode(adapt_desc
,OFF
);
341 while (n
=fread(buffer
,1,1024,fp
)) {
342 do { n
-= write(adapt_desc
,buffer
,n
); } while (n
>0);
343 if (n
<0) { perror("writing ascii coff"); break; }
346 rawmode(adapt_desc
,ON
);
347 system("rm /tmp/#adapt-btoa");
348 #else /* Binary coff - can't get it to work .*/
349 fprintf (adapt_stream
, "YC T,0\r");
350 fflush(adapt_stream
); /* Just in case */
351 if (!(fp
= fopen(args
,"r"))) {
352 printf_filtered("Can't open %s\n",args
);
355 while (n
=fread(buffer
,1,512,fp
)) {
356 do { n
-= write(adapt_desc
,buffer
,n
); } while (n
>0);
357 if (n
<0) { perror("writing ascii coff"); break; }
361 expect_prompt (); /* Skip garbage that comes out */
362 fprintf (adapt_stream
, "\r");
366 /* This is called not only when we first attach, but also when the
367 user types "run" after having attached. */
369 adapt_create_inferior (execfile
, args
, env
)
377 error ("Can't pass arguments to remote adapt process.");
379 if (execfile
== 0 || exec_bfd
== 0)
380 error ("No exec file specified");
382 entry_pt
= (int) bfd_get_start_address (exec_bfd
);
385 adapt_kill(NULL
,NULL
);
386 adapt_clear_breakpoints();
387 init_wait_for_inferior ();
388 /* Clear the input because what the adapt sends back is different
389 * depending on whether it was running or not.
391 slurp_input(); /* After this there should be a prompt */
392 fprintf(adapt_stream
,"\r");
394 printf_filtered("Do you want to download '%s' (y/n)? [y] : ",prog_name
);
398 if (*buffer
!= 'n') {
399 adapt_load(prog_name
,0);
404 /* Set the PC and wait for a go/cont */
405 fprintf (adapt_stream
, "G %x,N\r",entry_pt
);
406 printf_filtered("Now use the 'continue' command to start.\n");
409 insert_breakpoints (); /* Needed to get correct instruction in cache */
410 proceed(entry_pt
, TARGET_SIGNAL_DEFAULT
, 0);
414 printf_filtered("Adapt not open yet.\n");
418 /* Translate baud rates from integers to damn B_codes. Unix should
419 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
428 static struct {int rate
, damn_b
;} baudtab
[] = {
448 static int damn_b (rate
)
453 for (i
= 0; baudtab
[i
].rate
!= -1; i
++)
454 if (rate
== baudtab
[i
].rate
) return baudtab
[i
].damn_b
;
455 return B38400
; /* Random */
459 /* Open a connection to a remote debugger.
460 NAME is the filename used for communication, then a space,
464 static int baudrate
= 9600;
466 adapt_open (name
, from_tty
)
474 /* Find the first whitespace character, it separates dev_name from
480 *p
!= '\0' && !isspace (*p
); p
++)
485 Please include the name of the device for the serial port,\n\
486 the baud rate, and the name of the program to run on the remote system.");
487 dev_name
= (char*)malloc(p
- name
+ 1);
488 strncpy (dev_name
, name
, p
- name
);
489 dev_name
[p
- name
] = '\0';
491 /* Skip over the whitespace after dev_name */
492 for (; isspace (*p
); p
++)
495 if (1 != sscanf (p
, "%d ", &baudrate
))
498 /* Skip the number and then the spaces */
499 for (; isdigit (*p
); p
++)
501 for (; isspace (*p
); p
++)
504 if (prog_name
!= NULL
)
506 prog_name
= savestring (p
, strlen (p
));
510 adapt_desc
= open (dev_name
, O_RDWR
);
512 perror_with_name (dev_name
);
513 ioctl (adapt_desc
, TIOCGETP
, &sg
);
515 sg
.c_cc
[VMIN
] = 0; /* read with timeout. */
516 sg
.c_cc
[VTIME
] = timeout
* 10;
517 sg
.c_lflag
&= ~(ICANON
| ECHO
);
518 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | damn_b (baudrate
);
520 sg
.sg_ispeed
= damn_b (baudrate
);
521 sg
.sg_ospeed
= damn_b (baudrate
);
522 sg
.sg_flags
|= RAW
| ANYP
;
523 sg
.sg_flags
&= ~ECHO
;
526 ioctl (adapt_desc
, TIOCSETP
, &sg
);
527 adapt_stream
= fdopen (adapt_desc
, "r+");
529 push_target (&adapt_ops
);
532 #ifndef NO_SIGINTERRUPT
533 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
535 if (siginterrupt (SIGALRM
, 1) != 0)
536 perror ("adapt_open: error in siginterrupt");
539 /* Set up read timeout timer. */
540 if ((void (*)) signal (SIGALRM
, adapt_timer
) == (void (*)) -1)
541 perror ("adapt_open: error in signal");
544 #if defined (LOG_FILE)
545 log_file
= fopen (LOG_FILE
, "w");
546 if (log_file
== NULL
)
547 perror_with_name (LOG_FILE
);
550 /* Put this port into NORMAL mode, send the 'normal' character */
551 write(adapt_desc
, "\ 1", 1); /* Control A */
552 write(adapt_desc
, "\r", 1);
555 /* Hello? Are you there? */
556 write (adapt_desc
, "\r", 1);
560 /* Clear any break points */
561 adapt_clear_breakpoints();
563 /* Print out some stuff, letting the user now what's going on */
564 printf_filtered("Connected to an Adapt via %s.\n", dev_name
);
565 /* FIXME: can this restriction be removed? */
566 printf_filtered("Remote debugging using virtual addresses works only\n");
567 printf_filtered("\twhen virtual addresses map 1:1 to physical addresses.\n");
568 if (processor_type
!= a29k_freeze_mode
) {
569 fprintf_filtered(stderr
,
570 "Freeze-mode debugging not available, and can only be done on an A29050.\n");
574 /* Close out all files and local state before this target loses control. */
577 adapt_close (quitting
)
581 /* Clear any break points */
582 adapt_clear_breakpoints();
584 /* Put this port back into REMOTE mode */
586 fflush(adapt_stream
);
587 sleep(1); /* Let any output make it all the way back */
588 write(adapt_desc
, "R\r", 2);
591 /* Due to a bug in Unix, fclose closes not only the stdio stream,
592 but also the file descriptor. So we don't actually close
595 fclose (adapt_stream
); /* This also closes adapt_desc */
597 /* close (adapt_desc); */
599 /* Do not try to close adapt_desc again, later in the program. */
603 #if defined (LOG_FILE)
605 if (ferror (log_file
))
606 printf_filtered ("Error writing log file.\n");
607 if (fclose (log_file
) != 0)
608 printf_filtered ("Error closing log file.\n");
614 /* Attach to the target that is already loaded and possibly running */
616 adapt_attach (args
, from_tty
)
622 printf_filtered ("Attaching to remote program %s.\n", prog_name
);
624 /* Send the adapt a kill. It is ok if it is not already running */
625 fprintf(adapt_stream
, "K\r"); fflush(adapt_stream
);
626 expect_prompt(); /* Slurp the echo */
630 /* Terminate the open connection to the remote debugger.
631 Use this when you want to detach and do something else
634 adapt_detach (args
,from_tty
)
639 if (adapt_stream
) { /* Send it on its way (tell it to continue) */
640 adapt_clear_breakpoints();
641 fprintf(adapt_stream
,"G\r");
644 pop_target(); /* calls adapt_close to do the real work */
646 printf_filtered ("Ending remote %s debugging\n", target_shortname
);
649 /* Tell the remote machine to resume. */
652 adapt_resume (pid
, step
, sig
)
654 enum target_signal sig
;
658 write (adapt_desc
, "t 1,s\r", 6);
659 /* Wait for the echo. */
660 expect ("t 1,s\r\n");
661 /* Then comes a line containing the instruction we stepped to. */
663 /* Then we get the prompt. */
666 /* Force the next adapt_wait to return a trap. Not doing anything
667 about I/O from the target means that the user has to type
668 "continue" to see any. FIXME, this should be fixed. */
669 need_artificial_trap
= 1;
673 write (adapt_desc
, "G\r", 2);
674 /* Swallow the echo. */
679 /* Wait until the remote machine stops, then return,
680 storing status in STATUS just as `wait' would. */
684 struct target_waitstatus
*status
;
686 /* Strings to look for. '?' means match any single character.
687 Note that with the algorithm we use, the initial character
688 of the string cannot recur in the string, or we will not
689 find some cases of the string in the input. */
691 static char bpt
[] = "@";
692 /* It would be tempting to look for "\n[__exit + 0x8]\n"
693 but that requires loading symbols with "yc i" and even if
694 we did do that we don't know that the file has symbols. */
695 static char exitmsg
[] = "@????????I JMPTI GR121,LR0";
699 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
701 /* Current position in swallowed. */
702 char *swallowed_p
= swallowed
;
706 int old_timeout
= timeout
;
707 int old_immediate_quit
= immediate_quit
;
709 status
->kind
= TARGET_WAITKIND_EXITED
;
710 status
->value
.integer
= 0;
712 if (need_artificial_trap
!= 0)
714 status
->kind
= TARGET_WAITKIND_STOPPED
;
715 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
716 need_artificial_trap
--;
720 timeout
= 0; /* Don't time out -- user program is running. */
721 immediate_quit
= 1; /* Helps ability to QUIT */
723 QUIT
; /* Let user quit and leave process running */
735 if (ch
== *ep
|| *ep
== '?') {
747 /* Print out any characters which have been swallowed. */
748 for (p
= swallowed
; p
< swallowed_p
; ++p
)
750 swallowed_p
= swallowed
;
757 status
->kind
= TARGET_WAITKIND_STOPPED
;
758 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
762 status
->kind
= TARGET_WAITKIND_EXITED
;
763 status
->value
.integer
= 0;
765 timeout
= old_timeout
;
766 immediate_quit
= old_immediate_quit
;
770 /* Return the name of register number REGNO
771 in the form input and output by adapt.
773 Returns a pointer to a static buffer containing the answer. */
779 if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32 )
780 sprintf (buf
, "GR%03d", regno
- GR96_REGNUM
+ 96);
781 #if defined(GR64_REGNUM)
782 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
783 sprintf (buf
, "GR%03d", regno
- GR64_REGNUM
+ 64);
785 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
786 sprintf (buf
, "LR%03d", regno
- LR0_REGNUM
);
787 else if (regno
== Q_REGNUM
)
788 strcpy (buf
, "SR131");
789 else if (regno
>= BP_REGNUM
&& regno
<= CR_REGNUM
)
790 sprintf (buf
, "SR%03d", regno
- BP_REGNUM
+ 133);
791 else if (regno
== ALU_REGNUM
)
792 strcpy (buf
, "SR132");
793 else if (regno
>= IPC_REGNUM
&& regno
<= IPB_REGNUM
)
794 sprintf (buf
, "SR%03d", regno
- IPC_REGNUM
+ 128);
795 else if (regno
>= VAB_REGNUM
&& regno
<= LRU_REGNUM
) {
796 /* When a 29050 is in freeze-mode, read shadow pcs instead */
797 if ((regno
>= NPC_REGNUM
&& regno
<= PC2_REGNUM
) && USE_SHADOW_PC
)
798 sprintf (buf
, "SR%03d", regno
- NPC_REGNUM
+ 20);
800 sprintf (buf
, "SR%03d", regno
- VAB_REGNUM
);
802 else if (regno
== GR1_REGNUM
)
803 strcpy (buf
, "GR001");
807 /* Read the remote registers. */
810 adapt_fetch_registers ()
821 #if defined(GR64_REGNUM)
822 write (adapt_desc
, "dw gr64,gr95\r", 13);
823 for (reg_index
= 64, regnum_index
= GR64_REGNUM
;
825 reg_index
+= 4, regnum_index
+= 4)
827 sprintf (tempbuf
, "GR%03d ", reg_index
);
829 get_hex_regs (4, regnum_index
);
833 write (adapt_desc
, "dw gr96,gr127\r", 14);
834 for (reg_index
= 96, regnum_index
= GR96_REGNUM
;
836 reg_index
+= 4, regnum_index
+= 4)
838 sprintf (tempbuf
, "GR%03d ", reg_index
);
840 get_hex_regs (4, regnum_index
);
847 for (i
= 0; i
< 128; i
+= 32)
849 /* The PC has a tendency to hang if we get these
850 all in one fell swoop ("dw lr0,lr127"). */
851 sprintf (tempbuf
, "dw lr%d\r", i
);
852 write (adapt_desc
, tempbuf
, strlen (tempbuf
));
853 for (reg_index
= i
, regnum_index
= LR0_REGNUM
+ i
;
855 reg_index
+= 4, regnum_index
+= 4)
857 sprintf (tempbuf
, "LR%03d ", reg_index
);
859 get_hex_regs (4, regnum_index
);
867 sprintf (tempbuf
, "dw sr0\r");
868 write (adapt_desc
, tempbuf
, strlen (tempbuf
));
869 for (i
=0 ; i
<4 ; i
++) { /* SR0 - SR14 */
870 sprintf (tempbuf
, "SR%3d",i
*4);
872 for (j
=0 ; j
< (i
==3 ? 3 : 4) ; j
++)
873 sreg_buf
[i
*4 + j
] = get_hex_word();
877 * Read the pcs individually if we are in freeze mode.
878 * See get_reg_name(), it translates the register names for the pcs to
879 * the names of the shadow pcs.
882 sreg_buf
[10] = read_register(NPC_REGNUM
); /* pc0 */
883 sreg_buf
[11] = read_register(PC_REGNUM
); /* pc1 */
884 sreg_buf
[12] = read_register(PC2_REGNUM
); /* pc2 */
886 for (i
=0 ; i
<14 ; i
++) /* Supply vab -> lru */
887 supply_register(VAB_REGNUM
+i
, (char *) &sreg_buf
[i
]);
888 sprintf (tempbuf
, "dw sr128\r");
889 write (adapt_desc
, tempbuf
, strlen (tempbuf
));
890 for (i
=0 ; i
<2 ; i
++) { /* SR128 - SR135 */
891 sprintf (tempbuf
, "SR%3d",128 + i
*4);
893 for (j
=0 ; j
<4 ; j
++)
894 sreg_buf
[i
*4 + j
] = get_hex_word();
897 supply_register(IPC_REGNUM
,(char *) &sreg_buf
[0]);
898 supply_register(IPA_REGNUM
,(char *) &sreg_buf
[1]);
899 supply_register(IPB_REGNUM
,(char *) &sreg_buf
[2]);
900 supply_register(Q_REGNUM
, (char *) &sreg_buf
[3]);
902 supply_register(BP_REGNUM
, (char *) &sreg_buf
[5]);
903 supply_register(FC_REGNUM
, (char *) &sreg_buf
[6]);
904 supply_register(CR_REGNUM
, (char *) &sreg_buf
[7]);
906 /* There doesn't seem to be any way to get these. */
909 supply_register (FPE_REGNUM
, (char *) &val
);
910 supply_register (INTE_REGNUM
, (char *) &val
);
911 supply_register (FPS_REGNUM
, (char *) &val
);
912 supply_register (EXO_REGNUM
, (char *) &val
);
915 write (adapt_desc
, "dw gr1,gr1\r", 11);
917 get_hex_regs (1, GR1_REGNUM
);
921 /* Fetch register REGNO, or all registers if REGNO is -1.
924 adapt_fetch_register (regno
)
928 adapt_fetch_registers ();
931 char *name
= get_reg_name (regno
);
932 fprintf (adapt_stream
, "dw %s,%s\r", name
, name
);
935 get_hex_regs (1, regno
);
940 /* Store the remote registers from the contents of the block REGS. */
943 adapt_store_registers ()
947 fprintf (adapt_stream
, "s gr1,%x\r", read_register (GR1_REGNUM
));
950 #if defined(GR64_REGNUM)
951 for (j
= 0; j
< 32; j
+= 16)
953 fprintf (adapt_stream
, "s gr%d,", j
+ 64);
954 for (i
= 0; i
< 15; ++i
)
955 fprintf (adapt_stream
, "%x,", read_register (GR64_REGNUM
+ j
+ i
));
956 fprintf (adapt_stream
, "%x\r", read_register (GR64_REGNUM
+ j
+ 15));
960 for (j
= 0; j
< 32; j
+= 16)
962 fprintf (adapt_stream
, "s gr%d,", j
+ 96);
963 for (i
= 0; i
< 15; ++i
)
964 fprintf (adapt_stream
, "%x,", read_register (GR96_REGNUM
+ j
+ i
));
965 fprintf (adapt_stream
, "%x\r", read_register (GR96_REGNUM
+ j
+ 15));
969 for (j
= 0; j
< 128; j
+= 16)
971 fprintf (adapt_stream
, "s lr%d,", j
);
972 for (i
= 0; i
< 15; ++i
)
973 fprintf (adapt_stream
, "%x,", read_register (LR0_REGNUM
+ j
+ i
));
974 fprintf (adapt_stream
, "%x\r", read_register (LR0_REGNUM
+ j
+ 15));
978 fprintf (adapt_stream
, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM
),
979 read_register (IPA_REGNUM
), read_register (IPB_REGNUM
));
981 fprintf (adapt_stream
, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM
),
982 read_register (FC_REGNUM
), read_register (CR_REGNUM
));
984 fprintf (adapt_stream
, "s sr131,%x\r", read_register (Q_REGNUM
));
986 fprintf (adapt_stream
, "s sr0,");
987 for (i
=0 ; i
<7 ; ++i
)
988 fprintf (adapt_stream
, "%x,", read_register (VAB_REGNUM
+ i
));
990 fprintf (adapt_stream
, "s sr7,");
991 for (i
=7; i
<14 ; ++i
)
992 fprintf (adapt_stream
, "%x,", read_register (VAB_REGNUM
+ i
));
996 /* Store register REGNO, or all if REGNO == -1.
997 Return errno value. */
999 adapt_store_register (regno
)
1002 /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1004 adapt_store_registers ();
1007 char *name
= get_reg_name (regno
);
1008 fprintf (adapt_stream
, "s %s,%x\r", name
, read_register (regno
));
1009 /* Setting GR1 changes the numbers of all the locals, so
1010 invalidate the register cache. Do this *after* calling
1011 read_register, because we want read_register to return the
1012 value that write_register has just stuffed into the registers
1013 array, not the value of the register fetched from the
1015 if (regno
== GR1_REGNUM
)
1016 registers_changed ();
1021 /* Get ready to modify the registers array. On machines which store
1022 individual registers, this doesn't need to do anything. On machines
1023 which store all the registers in one fell swoop, this makes sure
1024 that registers contains all the registers from the program being
1028 adapt_prepare_to_store ()
1030 /* Do nothing, since we can store individual regs */
1034 translate_addr(addr
)
1037 #if defined(KERNEL_DEBUGGING)
1038 /* Check for a virtual address in the kernel */
1039 /* Assume physical address of ublock is in paddr_u register */
1040 if (addr
>= UVADDR
) {
1041 /* PADDR_U register holds the physical address of the ublock */
1042 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
1043 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
1053 /* FIXME! Merge these two. */
1055 adapt_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
1062 memaddr
= translate_addr(memaddr
);
1065 return adapt_write_inferior_memory (memaddr
, myaddr
, len
);
1067 return adapt_read_inferior_memory (memaddr
, myaddr
, len
);
1073 printf_filtered("\tAttached to %s at %d baud and running program %s\n",
1074 dev_name
, baudrate
, prog_name
);
1075 printf_filtered("\ton an %s processor.\n", processor_name
[processor_type
]);
1078 /* Copy LEN bytes of data from debugger memory at MYADDR
1079 to inferior's memory at MEMADDR. Returns errno value.
1080 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1083 adapt_write_inferior_memory (memaddr
, myaddr
, len
)
1091 /* Turn TU bit off so we can do 'sb' commands */
1092 cps
= read_register(CPS_REGNUM
);
1093 if (cps
& 0x00000800)
1094 write_register(CPS_REGNUM
,cps
&~(0x00000800));
1096 for (i
= 0; i
< len
; i
++)
1099 fprintf (adapt_stream
, "sb %x,", memaddr
+ i
);
1100 if ((i
% 16) == 15 || i
== len
- 1)
1102 fprintf (adapt_stream
, "%x\r", ((unsigned char *)myaddr
)[i
]);
1106 fprintf (adapt_stream
, "%x,", ((unsigned char *)myaddr
)[i
]);
1108 /* Restore the old value of cps if the TU bit was on */
1109 if (cps
& 0x00000800)
1110 write_register(CPS_REGNUM
,cps
);
1114 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1115 at debugger address MYADDR. Returns errno value. */
1117 adapt_read_inferior_memory(memaddr
, myaddr
, len
)
1124 /* Number of bytes read so far. */
1127 /* Starting address of this pass. */
1128 unsigned long startaddr
;
1130 /* Number of bytes to read in this pass. */
1133 /* Note that this code works correctly if startaddr is just less
1134 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1135 thing). That is, something like
1136 adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1137 works--it never adds len to memaddr and gets 0. */
1138 /* However, something like
1139 adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1140 doesn't need to work. Detect it and give up if there's an attempt
1143 if (((memaddr
- 1) + len
) < memaddr
)
1146 startaddr
= memaddr
;
1151 if ((startaddr
% 16) != 0)
1152 len_this_pass
-= startaddr
% 16;
1153 if (len_this_pass
> (len
- count
))
1154 len_this_pass
= (len
- count
);
1156 fprintf (adapt_stream
, "db %x,%x\r", startaddr
,
1157 (startaddr
- 1) + len_this_pass
);
1159 #ifdef NOTDEF /* Why do this */
1161 /* Look for 8 hex digits. */
1165 if (isxdigit (readchar ()))
1170 error ("Hex digit expected from remote system.");
1179 for (i
= 0; i
< len_this_pass
; i
++)
1180 get_hex_byte (&myaddr
[count
++]);
1184 startaddr
+= len_this_pass
;
1189 #define MAX_BREAKS 8
1190 static int num_brkpts
=0;
1192 adapt_insert_breakpoint(addr
, save
)
1194 char *save
; /* Throw away, let adapt save instructions */
1196 if (num_brkpts
< MAX_BREAKS
) {
1198 fprintf (adapt_stream
, "B %x", addr
);
1199 fprintf (adapt_stream
, "\r");
1201 return(0); /* Success */
1203 fprintf_filtered(stderr
,
1204 "Too many break points, break point not installed\n");
1205 return(1); /* Failure */
1210 adapt_remove_breakpoint(addr
, save
)
1212 char *save
; /* Throw away, let adapt save instructions */
1214 if (num_brkpts
> 0) {
1216 fprintf (adapt_stream
, "BR %x", addr
);
1217 fprintf (adapt_stream
, "\r");
1218 fflush (adapt_stream
);
1224 /* Clear the adapts notion of what the break points are */
1226 adapt_clear_breakpoints()
1229 fprintf (adapt_stream
, "BR"); /* Clear all break points */
1230 fprintf (adapt_stream
, "\r");
1231 fflush(adapt_stream
);
1239 adapt_clear_breakpoints();
1240 pop_target (); /* Pop back to no-child state */
1241 generic_mourn_inferior ();
1244 /* Display everthing we read in from the adapt until we match/see the
1253 while (c
=readchar()) {
1256 if (i
== strlen(str
)) return;
1259 for (j
=0 ; j
<i
; j
++) /* Put everthing we matched */
1270 /* Put a command string, in args, out to the adapt. The adapt is assumed to
1271 be in raw mode, all writing/reading done through adapt_desc.
1272 Ouput from the adapt is placed on the users terminal until the
1273 prompt from the adapt is seen.
1274 FIXME: Can't handle commands that take input. */
1277 adapt_com (args
, fromtty
)
1281 if (!adapt_stream
) {
1282 printf_filtered("Adapt not open. Use the 'target' command to open.\n");
1286 /* Clear all input so only command relative output is displayed */
1289 switch(islower(args
[0]) ? toupper(args
[0]) : args
[0]) {
1291 printf_filtered("Unknown/Unimplemented adapt command '%s'\n",args
);
1293 case 'G': /* Go, begin execution */
1294 write(adapt_desc
,args
,strlen(args
));
1295 write(adapt_desc
,"\r",1);
1298 case 'B': /* Break points, B or BR */
1299 case 'C': /* Check current 29k status (running/halted) */
1300 case 'D': /* Display data/registers */
1301 case 'I': /* Input from i/o space */
1302 case 'J': /* Jam an instruction */
1303 case 'K': /* Kill, stop execution */
1304 case 'L': /* Disassemble */
1305 case 'O': /* Output to i/o space */
1306 case 'T': /* Trace */
1307 case 'P': /* Pulse an input line */
1308 case 'X': /* Examine special purpose registers */
1309 case 'Z': /* Display trace buffer */
1310 write(adapt_desc
,args
,strlen(args
));
1311 write(adapt_desc
,"\r",1);
1312 expect(args
); /* Don't display the command */
1313 display_until("# ");
1315 /* Begin commands that take input in the form 'c x,y[,z...]' */
1316 case 'S': /* Set memory or register */
1317 if (strchr(args
,',')) { /* Assume it is properly formatted */
1318 write(adapt_desc
,args
,strlen(args
));
1319 write(adapt_desc
,"\r",1);
1326 /* Define the target subroutine names */
1328 struct target_ops adapt_ops
= {
1329 "adapt", "Remote AMD `Adapt' target",
1330 "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232",
1331 adapt_open
, adapt_close
,
1332 adapt_attach
, adapt_detach
, adapt_resume
, adapt_wait
,
1333 adapt_fetch_register
, adapt_store_register
,
1334 adapt_prepare_to_store
,
1335 adapt_xfer_inferior_memory
,
1337 adapt_insert_breakpoint
, adapt_remove_breakpoint
, /* Breakpoints */
1338 0, 0, 0, 0, 0, /* Terminal handling */
1339 adapt_kill
, /* FIXME, kill */
1341 0, /* lookup_symbol */
1342 adapt_create_inferior
, /* create_inferior */
1343 adapt_mourn
, /* mourn_inferior FIXME */
1345 0, /* notice_signals */
1346 process_stratum
, 0, /* next */
1347 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1348 0,0, /* Section pointers */
1349 OPS_MAGIC
, /* Always the last thing */
1353 _initialize_remote_adapt ()
1355 add_target (&adapt_ops
);
1356 add_com ("adapt <command>", class_obscure
, adapt_com
,
1357 "Send a command to the AMD Adapt remote monitor.");