1 /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18.
2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
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, Boston, MA 02111-1307, 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. */
35 #include "gdb_string.h"
47 /* This processor is getting rusty but I am trying to keep it
48 up to date at least with data structure changes.
49 Activate this block to compile just this file.
51 #define COMPILE_CHECK 0
76 extern int a29k_freeze_mode ;
77 extern int processor_type ;
78 extern char * processor_name ;
81 /* External data declarations */
82 extern int stop_soon_quietly; /* for wait_for_inferior */
84 /* Forward data declarations */
85 extern struct target_ops adapt_ops; /* Forward declaration */
87 /* Forward function declarations */
88 static void adapt_fetch_registers ();
89 static void adapt_store_registers ();
90 static void adapt_close ();
91 static int adapt_clear_breakpoints();
93 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
94 #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
96 /* Can't seem to get binary coff working */
97 #define ASCII_COFF /* Adapt will be downloaded with ascii coff */
99 /* FIXME: Replace with `set remotedebug'. */
100 #define LOG_FILE "adapt.log"
101 #if defined (LOG_FILE)
105 static int timeout = 5;
106 static char *dev_name;
108 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
109 adapt_open knows that we don't have a file open when the program
113 /* stream which is fdopen'd from adapt_desc. Only valid when
120 rawmode(desc, turnon)
130 ioctl (desc, TIOCGETP, &sg);
134 sg.c_lflag &= ~(ICANON);
140 sg.c_lflag |= ICANON;
142 sg.sg_flags &= ~(RAW);
145 ioctl (desc, TIOCSETP, &sg);
148 /* Suck up all the input from the adapt */
154 /* termio does the timeout for us. */
155 while (read (adapt_desc, buf, 8) > 0);
158 while (read (adapt_desc, buf, 8) > 0);
163 /* Read a character from the remote system, doing all the fancy
172 /* termio does the timeout for us. */
173 read (adapt_desc, &buf, 1);
176 if (read (adapt_desc, &buf, 1) < 0)
179 error ("Timeout reading from remote system.");
181 perror_with_name ("remote");
187 error ("Timeout reading from remote system.");
188 #if defined (LOG_FILE)
189 putc (buf & 0x7f, log_file);
194 /* Keep discarding input from the remote system, until STRING is found.
195 Let the user break out immediately. */
202 fflush(adapt_stream);
206 if (readchar() == *p)
220 /* Keep discarding input until we see the adapt prompt.
222 The convention for dealing with the prompt is that you
224 o *then* wait for the prompt.
226 Thus the last thing that a procedure does with the serial line
227 will be an expect_prompt(). Exception: adapt_resume does not
228 wait for the prompt, because the terminal is being handed over
229 to the inferior. However, the next thing which happens after that
230 is a adapt_wait which does wait for the prompt.
231 Note that this includes abnormal exit, e.g. error(). This is
232 necessary to prevent getting into states from which we can't
237 #if defined (LOG_FILE)
238 /* This is a convenient place to do this. The idea is to do it often
239 enough that we never lose much data if we terminate abnormally. */
242 fflush(adapt_stream);
246 /* Get a hex digit from the remote system & return its value.
247 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
249 get_hex_digit (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
280 val = get_hex_digit (1) << 4;
281 val |= get_hex_digit (0);
285 /* Read a 32-bit hex word from the adapt, preceded by a space */
293 for (j = 0; j < 8; j++)
294 val = (val << 4) + get_hex_digit (j == 0);
297 /* Get N 32-bit hex words from remote, each preceded by a space
298 and put them in registers starting at REGNO. */
300 get_hex_regs (n, regno)
306 val = get_hex_word();
307 supply_register(regno++,(char *) &val);
310 /* Called when SIGALRM signal sent due to alarm() timeout. */
315 # define volatile /**/
318 volatile int n_alarms;
325 printf ("adapt_timer called\n");
331 /* malloc'd name of the program on the remote system. */
332 static char *prog_name = NULL;
334 /* Number of SIGTRAPs we need to simulate. That is, the next
335 NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
336 SIGTRAP without actually waiting for anything. */
338 static int need_artificial_trap = 0;
341 adapt_kill(arg,from_tty)
345 fprintf (adapt_stream, "K");
346 fprintf (adapt_stream, "\r");
350 * Download a file specified in 'args', to the adapt.
351 * FIXME: Assumes the file to download is a binary coff file.
354 adapt_load(args,fromtty)
363 printf_filtered("Adapt not open. Use 'target' command to open adapt\n");
367 /* OK, now read in the file. Y=read, C=COFF, T=dTe port
370 #ifdef ASCII_COFF /* Ascii coff */
371 fprintf (adapt_stream, "YA T,0\r");
372 fflush(adapt_stream); /* Just in case */
373 /* FIXME: should check args for only 1 argument */
374 sprintf(buffer,"cat %s | btoa > /tmp/#adapt-btoa",args);
376 fp = fopen("/tmp/#adapt-btoa","r");
377 rawmode(adapt_desc,OFF);
378 while (n=fread(buffer,1,1024,fp)) {
379 do { n -= write(adapt_desc,buffer,n); } while (n>0);
380 if (n<0) { perror("writing ascii coff"); break; }
383 rawmode(adapt_desc,ON);
384 system("rm /tmp/#adapt-btoa");
385 #else /* Binary coff - can't get it to work .*/
386 fprintf (adapt_stream, "YC T,0\r");
387 fflush(adapt_stream); /* Just in case */
388 if (!(fp = fopen(args,"r"))) {
389 printf_filtered("Can't open %s\n",args);
392 while (n=fread(buffer,1,512,fp)) {
393 do { n -= write(adapt_desc,buffer,n); } while (n>0);
394 if (n<0) { perror("writing ascii coff"); break; }
398 expect_prompt (); /* Skip garbage that comes out */
399 fprintf (adapt_stream, "\r");
403 /* This is called not only when we first attach, but also when the
404 user types "run" after having attached. */
406 adapt_create_inferior (execfile, args, env)
414 error ("Can't pass arguments to remote adapt process.");
416 if (execfile == 0 || exec_bfd == 0)
417 error ("No executable file specified");
419 entry_pt = (int) bfd_get_start_address (exec_bfd);
422 adapt_kill(NULL,NULL);
423 adapt_clear_breakpoints();
424 init_wait_for_inferior ();
425 /* Clear the input because what the adapt sends back is different
426 * depending on whether it was running or not.
428 slurp_input(); /* After this there should be a prompt */
429 fprintf(adapt_stream,"\r");
431 printf_filtered("Do you want to download '%s' (y/n)? [y] : ",prog_name);
435 if (*buffer != 'n') {
436 adapt_load(prog_name,0);
441 /* Set the PC and wait for a go/cont */
442 fprintf (adapt_stream, "G %x,N\r",entry_pt);
443 printf_filtered("Now use the 'continue' command to start.\n");
446 insert_breakpoints (); /* Needed to get correct instruction in cache */
447 proceed(entry_pt, TARGET_SIGNAL_DEFAULT, 0);
451 printf_filtered("Adapt not open yet.\n");
455 /* Translate baud rates from integers to damn B_codes. Unix should
456 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
465 static struct {int rate, damn_b;} baudtab[] = {
485 static int damn_b (rate)
490 for (i = 0; baudtab[i].rate != -1; i++)
491 if (rate == baudtab[i].rate) return baudtab[i].damn_b;
492 return B38400; /* Random */
496 /* Open a connection to a remote debugger.
497 NAME is the filename used for communication, then a space,
501 static int baudrate = 9600;
503 adapt_open (name, from_tty)
511 /* Find the first whitespace character, it separates dev_name from
517 *p != '\0' && !isspace (*p); p++)
522 Please include the name of the device for the serial port,\n\
523 the baud rate, and the name of the program to run on the remote system.");
524 dev_name = (char*)xmalloc(p - name + 1);
525 strncpy (dev_name, name, p - name);
526 dev_name[p - name] = '\0';
528 /* Skip over the whitespace after dev_name */
529 for (; isspace (*p); p++)
532 if (1 != sscanf (p, "%d ", &baudrate))
535 /* Skip the number and then the spaces */
536 for (; isdigit (*p); p++)
538 for (; isspace (*p); p++)
541 if (prog_name != NULL)
543 prog_name = savestring (p, strlen (p));
547 adapt_desc = open (dev_name, O_RDWR);
549 perror_with_name (dev_name);
550 ioctl (adapt_desc, TIOCGETP, &sg);
551 #if ! defined(COMPILE_CHECK)
553 sg.c_cc[VMIN] = 0; /* read with timeout. */
554 sg.c_cc[VTIME] = timeout * 10;
555 sg.c_lflag &= ~(ICANON | ECHO);
556 sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
558 sg.sg_ispeed = damn_b (baudrate);
559 sg.sg_ospeed = damn_b (baudrate);
560 sg.sg_flags |= RAW | ANYP;
561 sg.sg_flags &= ~ECHO;
564 ioctl (adapt_desc, TIOCSETP, &sg);
565 adapt_stream = fdopen (adapt_desc, "r+");
566 #endif /* compile_check */
567 push_target (&adapt_ops);
570 #ifndef NO_SIGINTERRUPT
571 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
573 if (siginterrupt (SIGALRM, 1) != 0)
574 perror ("adapt_open: error in siginterrupt");
577 /* Set up read timeout timer. */
578 if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1)
579 perror ("adapt_open: error in signal");
582 #if defined (LOG_FILE)
583 log_file = fopen (LOG_FILE, "w");
584 if (log_file == NULL)
585 perror_with_name (LOG_FILE);
588 /* Put this port into NORMAL mode, send the 'normal' character */
589 write(adapt_desc, "
\ 1", 1); /* Control A */
590 write(adapt_desc, "\r", 1);
593 /* Hello? Are you there? */
594 write (adapt_desc, "\r", 1);
598 /* Clear any break points */
599 adapt_clear_breakpoints();
601 /* Print out some stuff, letting the user now what's going on */
602 printf_filtered("Connected to an Adapt via %s.\n", dev_name);
603 /* FIXME: can this restriction be removed? */
604 printf_filtered("Remote debugging using virtual addresses works only\n");
605 printf_filtered("\twhen virtual addresses map 1:1 to physical addresses.\n");
606 if (processor_type != a29k_freeze_mode) {
607 fprintf_filtered(gdb_stderr,
608 "Freeze-mode debugging not available, and can only be done on an A29050.\n");
612 /* Close out all files and local state before this target loses control. */
615 adapt_close (quitting)
619 /* Clear any break points */
620 adapt_clear_breakpoints();
622 /* Put this port back into REMOTE mode */
624 fflush(adapt_stream);
625 sleep(1); /* Let any output make it all the way back */
626 write(adapt_desc, "R\r", 2);
629 /* Due to a bug in Unix, fclose closes not only the stdio stream,
630 but also the file descriptor. So we don't actually close
633 fclose (adapt_stream); /* This also closes adapt_desc */
635 /* close (adapt_desc); */
637 /* Do not try to close adapt_desc again, later in the program. */
641 #if defined (LOG_FILE)
643 if (ferror (log_file))
644 printf_filtered ("Error writing log file.\n");
645 if (fclose (log_file) != 0)
646 printf_filtered ("Error closing log file.\n");
652 /* Attach to the target that is already loaded and possibly running */
654 adapt_attach (args, from_tty)
660 printf_filtered ("Attaching to remote program %s.\n", prog_name);
662 /* Send the adapt a kill. It is ok if it is not already running */
663 fprintf(adapt_stream, "K\r"); fflush(adapt_stream);
664 expect_prompt(); /* Slurp the echo */
668 /* Terminate the open connection to the remote debugger.
669 Use this when you want to detach and do something else
672 adapt_detach (args,from_tty)
677 if (adapt_stream) { /* Send it on its way (tell it to continue) */
678 adapt_clear_breakpoints();
679 fprintf(adapt_stream,"G\r");
682 pop_target(); /* calls adapt_close to do the real work */
684 printf_filtered ("Ending remote %s debugging\n", target_shortname);
687 /* Tell the remote machine to resume. */
690 adapt_resume (pid, step, sig)
692 enum target_signal sig;
696 write (adapt_desc, "t 1,s\r", 6);
697 /* Wait for the echo. */
698 expect ("t 1,s\r\n");
699 /* Then comes a line containing the instruction we stepped to. */
701 /* Then we get the prompt. */
704 /* Force the next adapt_wait to return a trap. Not doing anything
705 about I/O from the target means that the user has to type
706 "continue" to see any. FIXME, this should be fixed. */
707 need_artificial_trap = 1;
711 write (adapt_desc, "G\r", 2);
712 /* Swallow the echo. */
717 /* Wait until the remote machine stops, then return,
718 storing status in STATUS just as `wait' would. */
722 struct target_waitstatus *status;
724 /* Strings to look for. '?' means match any single character.
725 Note that with the algorithm we use, the initial character
726 of the string cannot recur in the string, or we will not
727 find some cases of the string in the input. */
729 static char bpt[] = "@";
730 /* It would be tempting to look for "\n[__exit + 0x8]\n"
731 but that requires loading symbols with "yc i" and even if
732 we did do that we don't know that the file has symbols. */
733 static char exitmsg[] = "@????????I JMPTI GR121,LR0";
737 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
739 /* Current position in swallowed. */
740 char *swallowed_p = swallowed;
744 int old_timeout = timeout;
745 int old_immediate_quit = immediate_quit;
747 status->kind = TARGET_WAITKIND_EXITED;
748 status->value.integer = 0;
750 if (need_artificial_trap != 0)
752 status->kind = TARGET_WAITKIND_STOPPED;
753 status->value.sig = TARGET_SIGNAL_TRAP;
754 need_artificial_trap--;
758 timeout = 0; /* Don't time out -- user program is running. */
759 immediate_quit = 1; /* Helps ability to QUIT */
761 QUIT; /* Let user quit and leave process running */
773 if (ch == *ep || *ep == '?') {
785 /* Print out any characters which have been swallowed. */
786 for (p = swallowed; p < swallowed_p; ++p)
788 swallowed_p = swallowed;
795 status->kind = TARGET_WAITKIND_STOPPED;
796 status->value.sig = TARGET_SIGNAL_TRAP;
800 status->kind = TARGET_WAITKIND_EXITED;
801 status->value.integer = 0;
803 timeout = old_timeout;
804 immediate_quit = old_immediate_quit;
808 /* Return the name of register number REGNO
809 in the form input and output by adapt.
811 Returns a pointer to a static buffer containing the answer. */
817 if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32 )
818 sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
819 #if defined(GR64_REGNUM)
820 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
821 sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64);
823 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
824 sprintf (buf, "LR%03d", regno - LR0_REGNUM);
825 else if (regno == Q_REGNUM)
826 strcpy (buf, "SR131");
827 else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
828 sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
829 else if (regno == ALU_REGNUM)
830 strcpy (buf, "SR132");
831 else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
832 sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
833 else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM) {
834 /* When a 29050 is in freeze-mode, read shadow pcs instead */
835 if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC)
836 sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20);
838 sprintf (buf, "SR%03d", regno - VAB_REGNUM);
840 else if (regno == GR1_REGNUM)
841 strcpy (buf, "GR001");
845 /* Read the remote registers. */
848 adapt_fetch_registers ()
859 #if defined(GR64_REGNUM)
860 write (adapt_desc, "dw gr64,gr95\r", 13);
861 for (reg_index = 64, regnum_index = GR64_REGNUM;
863 reg_index += 4, regnum_index += 4)
865 sprintf (tempbuf, "GR%03d ", reg_index);
867 get_hex_regs (4, regnum_index);
871 write (adapt_desc, "dw gr96,gr127\r", 14);
872 for (reg_index = 96, regnum_index = GR96_REGNUM;
874 reg_index += 4, regnum_index += 4)
876 sprintf (tempbuf, "GR%03d ", reg_index);
878 get_hex_regs (4, regnum_index);
885 for (i = 0; i < 128; i += 32)
887 /* The PC has a tendency to hang if we get these
888 all in one fell swoop ("dw lr0,lr127"). */
889 sprintf (tempbuf, "dw lr%d\r", i);
890 write (adapt_desc, tempbuf, strlen (tempbuf));
891 for (reg_index = i, regnum_index = LR0_REGNUM + i;
893 reg_index += 4, regnum_index += 4)
895 sprintf (tempbuf, "LR%03d ", reg_index);
897 get_hex_regs (4, regnum_index);
905 sprintf (tempbuf, "dw sr0\r");
906 write (adapt_desc, tempbuf, strlen (tempbuf));
907 for (i=0 ; i<4 ; i++) { /* SR0 - SR14 */
908 sprintf (tempbuf, "SR%3d",i*4);
910 for (j=0 ; j < (i==3 ? 3 : 4) ; j++)
911 sreg_buf[i*4 + j] = get_hex_word();
915 * Read the pcs individually if we are in freeze mode.
916 * See get_reg_name(), it translates the register names for the pcs to
917 * the names of the shadow pcs.
920 sreg_buf[10] = read_register(NPC_REGNUM); /* pc0 */
921 sreg_buf[11] = read_register(PC_REGNUM); /* pc1 */
922 sreg_buf[12] = read_register(PC2_REGNUM); /* pc2 */
924 for (i=0 ; i<14 ; i++) /* Supply vab -> lru */
925 supply_register(VAB_REGNUM+i, (char *) &sreg_buf[i]);
926 sprintf (tempbuf, "dw sr128\r");
927 write (adapt_desc, tempbuf, strlen (tempbuf));
928 for (i=0 ; i<2 ; i++) { /* SR128 - SR135 */
929 sprintf (tempbuf, "SR%3d",128 + i*4);
931 for (j=0 ; j<4 ; j++)
932 sreg_buf[i*4 + j] = get_hex_word();
935 supply_register(IPC_REGNUM,(char *) &sreg_buf[0]);
936 supply_register(IPA_REGNUM,(char *) &sreg_buf[1]);
937 supply_register(IPB_REGNUM,(char *) &sreg_buf[2]);
938 supply_register(Q_REGNUM, (char *) &sreg_buf[3]);
940 supply_register(BP_REGNUM, (char *) &sreg_buf[5]);
941 supply_register(FC_REGNUM, (char *) &sreg_buf[6]);
942 supply_register(CR_REGNUM, (char *) &sreg_buf[7]);
944 /* There doesn't seem to be any way to get these. */
947 supply_register (FPE_REGNUM, (char *) &val);
948 supply_register (INTE_REGNUM, (char *) &val);
949 supply_register (FPS_REGNUM, (char *) &val);
950 supply_register (EXO_REGNUM, (char *) &val);
953 write (adapt_desc, "dw gr1,gr1\r", 11);
955 get_hex_regs (1, GR1_REGNUM);
959 /* Fetch register REGNO, or all registers if REGNO is -1.
962 adapt_fetch_register (regno)
966 adapt_fetch_registers ();
969 char *name = get_reg_name (regno);
970 fprintf (adapt_stream, "dw %s,%s\r", name, name);
973 get_hex_regs (1, regno);
978 /* Store the remote registers from the contents of the block REGS. */
981 adapt_store_registers ()
985 fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM));
988 #if defined(GR64_REGNUM)
989 for (j = 0; j < 32; j += 16)
991 fprintf (adapt_stream, "s gr%d,", j + 64);
992 for (i = 0; i < 15; ++i)
993 fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i));
994 fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15));
998 for (j = 0; j < 32; j += 16)
1000 fprintf (adapt_stream, "s gr%d,", j + 96);
1001 for (i = 0; i < 15; ++i)
1002 fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i));
1003 fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15));
1007 for (j = 0; j < 128; j += 16)
1009 fprintf (adapt_stream, "s lr%d,", j);
1010 for (i = 0; i < 15; ++i)
1011 fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i));
1012 fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15));
1016 fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM),
1017 read_register (IPA_REGNUM), read_register (IPB_REGNUM));
1019 fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM),
1020 read_register (FC_REGNUM), read_register (CR_REGNUM));
1022 fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM));
1024 fprintf (adapt_stream, "s sr0,");
1025 for (i=0 ; i<7 ; ++i)
1026 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1028 fprintf (adapt_stream, "s sr7,");
1029 for (i=7; i<14 ; ++i)
1030 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1034 /* Store register REGNO, or all if REGNO == -1.
1035 Return errno value. */
1037 adapt_store_register (regno)
1040 /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1042 adapt_store_registers ();
1045 char *name = get_reg_name (regno);
1046 fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno));
1047 /* Setting GR1 changes the numbers of all the locals, so
1048 invalidate the register cache. Do this *after* calling
1049 read_register, because we want read_register to return the
1050 value that write_register has just stuffed into the registers
1051 array, not the value of the register fetched from the
1053 if (regno == GR1_REGNUM)
1054 registers_changed ();
1059 /* Get ready to modify the registers array. On machines which store
1060 individual registers, this doesn't need to do anything. On machines
1061 which store all the registers in one fell swoop, this makes sure
1062 that registers contains all the registers from the program being
1066 adapt_prepare_to_store ()
1068 /* Do nothing, since we can store individual regs */
1072 translate_addr(addr)
1075 #if defined(KERNEL_DEBUGGING)
1076 /* Check for a virtual address in the kernel */
1077 /* Assume physical address of ublock is in paddr_u register */
1078 if (addr >= UVADDR) {
1079 /* PADDR_U register holds the physical address of the ublock */
1080 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
1081 return(i + addr - (CORE_ADDR)UVADDR);
1091 /* FIXME! Merge these two. */
1093 adapt_xfer_inferior_memory (memaddr, myaddr, len, write)
1100 memaddr = translate_addr(memaddr);
1103 return adapt_write_inferior_memory (memaddr, myaddr, len);
1105 return adapt_read_inferior_memory (memaddr, myaddr, len);
1111 printf_filtered("\tAttached to %s at %d baud and running program %s\n",
1112 dev_name, baudrate, prog_name);
1113 printf_filtered("\ton an %s processor.\n", processor_name[processor_type]);
1116 /* Copy LEN bytes of data from debugger memory at MYADDR
1117 to inferior's memory at MEMADDR. Returns errno value.
1118 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1121 adapt_write_inferior_memory (memaddr, myaddr, len)
1129 /* Turn TU bit off so we can do 'sb' commands */
1130 cps = read_register(CPS_REGNUM);
1131 if (cps & 0x00000800)
1132 write_register(CPS_REGNUM,cps&~(0x00000800));
1134 for (i = 0; i < len; i++)
1137 fprintf (adapt_stream, "sb %x,", memaddr + i);
1138 if ((i % 16) == 15 || i == len - 1)
1140 fprintf (adapt_stream, "%x\r", ((unsigned char *)myaddr)[i]);
1144 fprintf (adapt_stream, "%x,", ((unsigned char *)myaddr)[i]);
1146 /* Restore the old value of cps if the TU bit was on */
1147 if (cps & 0x00000800)
1148 write_register(CPS_REGNUM,cps);
1152 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1153 at debugger address MYADDR. Returns errno value. */
1155 adapt_read_inferior_memory(memaddr, myaddr, len)
1162 /* Number of bytes read so far. */
1165 /* Starting address of this pass. */
1166 unsigned long startaddr;
1168 /* Number of bytes to read in this pass. */
1171 /* Note that this code works correctly if startaddr is just less
1172 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1173 thing). That is, something like
1174 adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1175 works--it never adds len to memaddr and gets 0. */
1176 /* However, something like
1177 adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1178 doesn't need to work. Detect it and give up if there's an attempt
1181 if (((memaddr - 1) + len) < memaddr)
1184 startaddr = memaddr;
1189 if ((startaddr % 16) != 0)
1190 len_this_pass -= startaddr % 16;
1191 if (len_this_pass > (len - count))
1192 len_this_pass = (len - count);
1194 fprintf (adapt_stream, "db %x,%x\r", startaddr,
1195 (startaddr - 1) + len_this_pass);
1197 #ifdef NOTDEF /* Why do this */
1199 /* Look for 8 hex digits. */
1203 if (isxdigit (readchar ()))
1208 error ("Hex digit expected from remote system.");
1217 for (i = 0; i < len_this_pass; i++)
1218 get_hex_byte (&myaddr[count++]);
1222 startaddr += len_this_pass;
1227 #define MAX_BREAKS 8
1228 static int num_brkpts=0;
1230 adapt_insert_breakpoint(addr, save)
1232 char *save; /* Throw away, let adapt save instructions */
1234 if (num_brkpts < MAX_BREAKS) {
1236 fprintf (adapt_stream, "B %x", addr);
1237 fprintf (adapt_stream, "\r");
1239 return(0); /* Success */
1241 fprintf_filtered(gdb_stderr,
1242 "Too many break points, break point not installed\n");
1243 return(1); /* Failure */
1248 adapt_remove_breakpoint(addr, save)
1250 char *save; /* Throw away, let adapt save instructions */
1252 if (num_brkpts > 0) {
1254 fprintf (adapt_stream, "BR %x", addr);
1255 fprintf (adapt_stream, "\r");
1256 fflush (adapt_stream);
1262 /* Clear the adapts notion of what the break points are */
1264 adapt_clear_breakpoints()
1267 fprintf (adapt_stream, "BR"); /* Clear all break points */
1268 fprintf (adapt_stream, "\r");
1269 fflush(adapt_stream);
1277 adapt_clear_breakpoints();
1278 pop_target (); /* Pop back to no-child state */
1279 generic_mourn_inferior ();
1282 /* Display everthing we read in from the adapt until we match/see the
1291 while (c=readchar()) {
1294 if (i == strlen(str)) return;
1297 for (j=0 ; j<i ; j++) /* Put everthing we matched */
1308 /* Put a command string, in args, out to the adapt. The adapt is assumed to
1309 be in raw mode, all writing/reading done through adapt_desc.
1310 Ouput from the adapt is placed on the users terminal until the
1311 prompt from the adapt is seen.
1312 FIXME: Can't handle commands that take input. */
1315 adapt_com (args, fromtty)
1319 if (!adapt_stream) {
1320 printf_filtered("Adapt not open. Use the 'target' command to open.\n");
1324 /* Clear all input so only command relative output is displayed */
1327 switch(islower(args[0]) ? toupper(args[0]) : args[0]) {
1329 printf_filtered("Unknown/Unimplemented adapt command '%s'\n",args);
1331 case 'G': /* Go, begin execution */
1332 write(adapt_desc,args,strlen(args));
1333 write(adapt_desc,"\r",1);
1336 case 'B': /* Break points, B or BR */
1337 case 'C': /* Check current 29k status (running/halted) */
1338 case 'D': /* Display data/registers */
1339 case 'I': /* Input from i/o space */
1340 case 'J': /* Jam an instruction */
1341 case 'K': /* Kill, stop execution */
1342 case 'L': /* Disassemble */
1343 case 'O': /* Output to i/o space */
1344 case 'T': /* Trace */
1345 case 'P': /* Pulse an input line */
1346 case 'X': /* Examine special purpose registers */
1347 case 'Z': /* Display trace buffer */
1348 write(adapt_desc,args,strlen(args));
1349 write(adapt_desc,"\r",1);
1350 expect(args); /* Don't display the command */
1351 display_until("# ");
1353 /* Begin commands that take input in the form 'c x,y[,z...]' */
1354 case 'S': /* Set memory or register */
1355 if (strchr(args,',')) { /* Assume it is properly formatted */
1356 write(adapt_desc,args,strlen(args));
1357 write(adapt_desc,"\r",1);
1364 /* Define the target subroutine names */
1366 struct target_ops adapt_ops ;
1369 init_adapt_ops(void)
1371 adapt_ops.to_shortname = "adapt";
1372 adapt_ops.to_longname = "Remote AMD `Adapt' target";
1373 adapt_ops.to_doc = "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232";
1374 adapt_ops.to_open = adapt_open;
1375 adapt_ops.to_close = adapt_close;
1376 adapt_ops.to_attach = adapt_attach;
1377 adapt_ops.to_post_attach = NULL;
1378 adapt_ops.to_require_attach = NULL;
1379 adapt_ops.to_detach = adapt_detach;
1380 adapt_ops.to_require_detach = NULL;
1381 adapt_ops.to_resume = adapt_resume;
1382 adapt_ops.to_wait = adapt_wait;
1383 adapt_ops.to_post_wait = NULL;
1384 adapt_ops.to_fetch_registers = adapt_fetch_register;
1385 adapt_ops.to_store_registers = adapt_store_register;
1386 adapt_ops.to_prepare_to_store = adapt_prepare_to_store;
1387 adapt_ops.to_xfer_memory = adapt_xfer_inferior_memory;
1388 adapt_ops.to_files_info = adapt_files_info;
1389 adapt_ops.to_insert_breakpoint = adapt_insert_breakpoint;
1390 adapt_ops.to_remove_breakpoint = adapt_remove_breakpoint;
1391 adapt_ops.to_terminal_init = 0;
1392 adapt_ops.to_terminal_inferior = 0;
1393 adapt_ops.to_terminal_ours_for_output = 0;
1394 adapt_ops.to_terminal_ours = 0;
1395 adapt_ops.to_terminal_info = 0;
1396 adapt_ops.to_kill = adapt_kill;
1397 adapt_ops.to_load = adapt_load;
1398 adapt_ops.to_lookup_symbol = 0;
1399 adapt_ops.to_create_inferior = adapt_create_inferior;
1400 adapt_ops.to_post_startup_inferior = NULL;
1401 adapt_ops.to_acknowledge_created_inferior = NULL;
1402 adapt_ops.to_clone_and_follow_inferior = NULL;
1403 adapt_ops.to_post_follow_inferior_by_clone = NULL;
1404 adapt_ops.to_insert_fork_catchpoint = NULL;
1405 adapt_ops.to_remove_fork_catchpoint = NULL;
1406 adapt_ops.to_insert_vfork_catchpoint = NULL;
1407 adapt_ops.to_remove_vfork_catchpoint = NULL;
1408 adapt_ops.to_has_forked = NULL;
1409 adapt_ops.to_has_vforked = NULL;
1410 adapt_ops.to_can_follow_vfork_prior_to_exec = NULL;
1411 adapt_ops.to_post_follow_vfork = NULL;
1412 adapt_ops.to_insert_exec_catchpoint = NULL;
1413 adapt_ops.to_remove_exec_catchpoint = NULL;
1414 adapt_ops.to_has_execd = NULL;
1415 adapt_ops.to_reported_exec_events_per_exec_call = NULL;
1416 adapt_ops.to_has_exited = NULL;
1417 adapt_ops.to_mourn_inferior = adapt_mourn;
1418 adapt_ops.to_can_run = 0;
1419 adapt_ops.to_notice_signals = 0;
1420 adapt_ops.to_thread_alive = 0;
1421 adapt_ops.to_stop = 0 ; /* process_stratum; */
1422 adapt_ops.to_pid_to_exec_file = NULL;
1423 adapt_ops.to_core_file_to_sym_file = NULL;
1424 adapt_ops.to_stratum = 0;
1425 adapt_ops.DONT_USE = 0 ;
1426 adapt_ops.to_has_all_memory = 1;
1427 adapt_ops.to_has_memory = 1;
1428 adapt_ops.to_has_stack = 1;
1429 adapt_ops.to_has_registers = 1;
1430 adapt_ops.to_has_execution = 0;
1431 adapt_ops.to_sections = 0;
1432 adapt_ops.to_sections_end = 0 ;
1433 adapt_ops.to_magic = OPS_MAGIC;
1434 } /* init_adapt_ops */
1437 _initialize_remote_adapt ()
1440 add_target (&adapt_ops);
1441 add_com ("adapt <command>", class_obscure, adapt_com,
1442 "Send a command to the AMD Adapt remote monitor.");