1 /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18.
2 Copyright 1990, 1991, 1992, 2001 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"
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)
102 FILE *log_file = NULL;
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 (int desc, int turnon)
128 ioctl (desc, TIOCGETP, &sg);
133 sg.c_lflag &= ~(ICANON);
141 sg.c_lflag |= ICANON;
143 sg.sg_flags &= ~(RAW);
146 ioctl (desc, TIOCSETP, &sg);
149 /* Suck up all the input from the adapt */
155 /* termio does the timeout for us. */
156 while (read (adapt_desc, buf, 8) > 0);
159 while (read (adapt_desc, buf, 8) > 0);
164 /* Read a character from the remote system, doing all the fancy
173 /* termio does the timeout for us. */
174 read (adapt_desc, &buf, 1);
177 if (read (adapt_desc, &buf, 1) < 0)
180 error ("Timeout reading from remote system.");
182 perror_with_name ("remote");
188 error ("Timeout reading from remote system.");
189 #if defined (LOG_FILE)
190 putc (buf & 0x7f, log_file);
195 /* Keep discarding input from the remote system, until STRING is found.
196 Let the user break out immediately. */
198 expect (char *string)
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 (int ignore_space)
255 if (ch >= '0' && ch <= '9')
257 else if (ch >= 'A' && ch <= 'F')
258 return ch - 'A' + 10;
259 else if (ch >= 'a' && ch <= 'f')
260 return ch - 'a' + 10;
261 else if (ch == ' ' && ignore_space)
266 error ("Invalid hex digit from remote system.");
271 /* Get a byte from adapt_desc and put it in *BYT. Accept any number
274 get_hex_byte (char *byt)
278 val = get_hex_digit (1) << 4;
279 val |= get_hex_digit (0);
283 /* Read a 32-bit hex word from the adapt, preceded by a space */
291 for (j = 0; j < 8; j++)
292 val = (val << 4) + get_hex_digit (j == 0);
295 /* Get N 32-bit hex words from remote, each preceded by a space
296 and put them in registers starting at REGNO. */
298 get_hex_regs (int n, int regno)
303 val = get_hex_word ();
304 supply_register (regno++, (char *) &val);
307 /* Called when SIGALRM signal sent due to alarm() timeout. */
316 volatile int n_alarms;
323 printf ("adapt_timer called\n");
329 /* malloc'd name of the program on the remote system. */
330 static char *prog_name = NULL;
332 /* Number of SIGTRAPs we need to simulate. That is, the next
333 NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
334 SIGTRAP without actually waiting for anything. */
336 static int need_artificial_trap = 0;
339 adapt_kill (char *arg, int from_tty)
341 fprintf (adapt_stream, "K");
342 fprintf (adapt_stream, "\r");
346 * Download a file specified in 'args', to the adapt.
347 * FIXME: Assumes the file to download is a binary coff file.
350 adapt_load (char *args, int fromtty)
358 printf_filtered ("Adapt not open. Use 'target' command to open adapt\n");
362 /* OK, now read in the file. Y=read, C=COFF, T=dTe port
365 #ifdef ASCII_COFF /* Ascii coff */
366 fprintf (adapt_stream, "YA T,0\r");
367 fflush (adapt_stream); /* Just in case */
368 /* FIXME: should check args for only 1 argument */
369 sprintf (buffer, "cat %s | btoa > /tmp/#adapt-btoa", args);
371 fp = fopen ("/tmp/#adapt-btoa", "r");
372 rawmode (adapt_desc, OFF);
373 while (n = fread (buffer, 1, 1024, fp))
377 n -= write (adapt_desc, buffer, n);
382 perror ("writing ascii coff");
387 rawmode (adapt_desc, ON);
388 system ("rm /tmp/#adapt-btoa");
389 #else /* Binary coff - can't get it to work . */
390 fprintf (adapt_stream, "YC T,0\r");
391 fflush (adapt_stream); /* Just in case */
392 if (!(fp = fopen (args, "r")))
394 printf_filtered ("Can't open %s\n", args);
397 while (n = fread (buffer, 1, 512, fp))
401 n -= write (adapt_desc, buffer, n);
406 perror ("writing ascii coff");
412 expect_prompt (); /* Skip garbage that comes out */
413 fprintf (adapt_stream, "\r");
417 /* This is called not only when we first attach, but also when the
418 user types "run" after having attached. */
420 adapt_create_inferior (char *execfile, char *args, char **env)
425 error ("Can't pass arguments to remote adapt process.");
427 if (execfile == 0 || exec_bfd == 0)
428 error ("No executable file specified");
430 entry_pt = (int) bfd_get_start_address (exec_bfd);
434 adapt_kill (NULL, NULL);
435 adapt_clear_breakpoints ();
436 init_wait_for_inferior ();
437 /* Clear the input because what the adapt sends back is different
438 * depending on whether it was running or not.
440 slurp_input (); /* After this there should be a prompt */
441 fprintf (adapt_stream, "\r");
443 printf_filtered ("Do you want to download '%s' (y/n)? [y] : ", prog_name);
449 adapt_load (prog_name, 0);
454 /* Set the PC and wait for a go/cont */
455 fprintf (adapt_stream, "G %x,N\r", entry_pt);
456 printf_filtered ("Now use the 'continue' command to start.\n");
459 insert_breakpoints (); /* Needed to get correct instruction in cache */
460 proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
466 printf_filtered ("Adapt not open yet.\n");
470 /* Translate baud rates from integers to damn B_codes. Unix should
471 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
561 for (i = 0; baudtab[i].rate != -1; i++)
562 if (rate == baudtab[i].rate)
563 return baudtab[i].damn_b;
564 return B38400; /* Random */
568 /* Open a connection to a remote debugger.
569 NAME is the filename used for communication, then a space,
573 static int baudrate = 9600;
575 adapt_open (char *name, int from_tty)
581 /* Find the first whitespace character, it separates dev_name from
587 *p != '\0' && !isspace (*p); p++)
592 Please include the name of the device for the serial port,\n\
593 the baud rate, and the name of the program to run on the remote system.");
594 dev_name = (char *) xmalloc (p - name + 1);
595 strncpy (dev_name, name, p - name);
596 dev_name[p - name] = '\0';
598 /* Skip over the whitespace after dev_name */
599 for (; isspace (*p); p++)
602 if (1 != sscanf (p, "%d ", &baudrate))
605 /* Skip the number and then the spaces */
606 for (; isdigit (*p); p++)
608 for (; isspace (*p); p++)
611 if (prog_name != NULL)
613 prog_name = savestring (p, strlen (p));
617 adapt_desc = open (dev_name, O_RDWR);
619 perror_with_name (dev_name);
620 ioctl (adapt_desc, TIOCGETP, &sg);
621 #if ! defined(COMPILE_CHECK)
623 sg.c_cc[VMIN] = 0; /* read with timeout. */
624 sg.c_cc[VTIME] = timeout * 10;
625 sg.c_lflag &= ~(ICANON | ECHO);
626 sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
628 sg.sg_ispeed = damn_b (baudrate);
629 sg.sg_ospeed = damn_b (baudrate);
630 sg.sg_flags |= RAW | ANYP;
631 sg.sg_flags &= ~ECHO;
634 ioctl (adapt_desc, TIOCSETP, &sg);
635 adapt_stream = fdopen (adapt_desc, "r+");
636 #endif /* compile_check */
637 push_target (&adapt_ops);
640 #ifndef NO_SIGINTERRUPT
641 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
643 if (siginterrupt (SIGALRM, 1) != 0)
644 perror ("adapt_open: error in siginterrupt");
647 /* Set up read timeout timer. */
648 if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1)
649 perror ("adapt_open: error in signal");
652 #if defined (LOG_FILE)
653 log_file = fopen (LOG_FILE, "w");
654 if (log_file == NULL)
655 perror_with_name (LOG_FILE);
658 /* Put this port into NORMAL mode, send the 'normal' character */
659 write (adapt_desc, "
\ 1", 1); /* Control A */
660 write (adapt_desc, "\r", 1);
663 /* Hello? Are you there? */
664 write (adapt_desc, "\r", 1);
668 /* Clear any break points */
669 adapt_clear_breakpoints ();
671 /* Print out some stuff, letting the user now what's going on */
672 printf_filtered ("Connected to an Adapt via %s.\n", dev_name);
673 /* FIXME: can this restriction be removed? */
674 printf_filtered ("Remote debugging using virtual addresses works only\n");
675 printf_filtered ("\twhen virtual addresses map 1:1 to physical addresses.\n");
676 if (processor_type != a29k_freeze_mode)
678 fprintf_filtered (gdb_stderr,
679 "Freeze-mode debugging not available, and can only be done on an A29050.\n");
683 /* Close out all files and local state before this target loses control. */
686 adapt_close (int quitting)
689 /* Clear any break points */
690 adapt_clear_breakpoints ();
692 /* Put this port back into REMOTE mode */
695 fflush (adapt_stream);
696 sleep (1); /* Let any output make it all the way back */
697 write (adapt_desc, "R\r", 2);
700 /* Due to a bug in Unix, fclose closes not only the stdio stream,
701 but also the file descriptor. So we don't actually close
704 fclose (adapt_stream); /* This also closes adapt_desc */
706 /* close (adapt_desc); */
708 /* Do not try to close adapt_desc again, later in the program. */
712 #if defined (LOG_FILE)
715 if (ferror (log_file))
716 printf_filtered ("Error writing log file.\n");
717 if (fclose (log_file) != 0)
718 printf_filtered ("Error closing log file.\n");
724 /* Attach to the target that is already loaded and possibly running */
726 adapt_attach (char *args, int from_tty)
730 printf_filtered ("Attaching to remote program %s.\n", prog_name);
732 /* Send the adapt a kill. It is ok if it is not already running */
733 fprintf (adapt_stream, "K\r");
734 fflush (adapt_stream);
735 expect_prompt (); /* Slurp the echo */
739 /* Terminate the open connection to the remote debugger.
740 Use this when you want to detach and do something else
743 adapt_detach (char *args, int from_tty)
747 { /* Send it on its way (tell it to continue) */
748 adapt_clear_breakpoints ();
749 fprintf (adapt_stream, "G\r");
752 pop_target (); /* calls adapt_close to do the real work */
754 printf_filtered ("Ending remote %s debugging\n", target_shortname);
757 /* Tell the remote machine to resume. */
760 adapt_resume (int pid, int step, enum target_signal sig)
764 write (adapt_desc, "t 1,s\r", 6);
765 /* Wait for the echo. */
766 expect ("t 1,s\r\n");
767 /* Then comes a line containing the instruction we stepped to. */
769 /* Then we get the prompt. */
772 /* Force the next adapt_wait to return a trap. Not doing anything
773 about I/O from the target means that the user has to type
774 "continue" to see any. FIXME, this should be fixed. */
775 need_artificial_trap = 1;
779 write (adapt_desc, "G\r", 2);
780 /* Swallow the echo. */
785 /* Wait until the remote machine stops, then return,
786 storing status in STATUS just as `wait' would. */
789 adapt_wait (struct target_waitstatus *status)
791 /* Strings to look for. '?' means match any single character.
792 Note that with the algorithm we use, the initial character
793 of the string cannot recur in the string, or we will not
794 find some cases of the string in the input. */
796 static char bpt[] = "@";
797 /* It would be tempting to look for "\n[__exit + 0x8]\n"
798 but that requires loading symbols with "yc i" and even if
799 we did do that we don't know that the file has symbols. */
800 static char exitmsg[] = "@????????I JMPTI GR121,LR0";
804 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
806 /* Current position in swallowed. */
807 char *swallowed_p = swallowed;
811 int old_timeout = timeout;
812 int old_immediate_quit = immediate_quit;
814 status->kind = TARGET_WAITKIND_EXITED;
815 status->value.integer = 0;
817 if (need_artificial_trap != 0)
819 status->kind = TARGET_WAITKIND_STOPPED;
820 status->value.sig = TARGET_SIGNAL_TRAP;
821 need_artificial_trap--;
825 timeout = 0; /* Don't time out -- user program is running. */
826 immediate_quit = 1; /* Helps ability to QUIT */
829 QUIT; /* Let user quit and leave process running */
843 if (ch == *ep || *ep == '?')
858 /* Print out any characters which have been swallowed. */
859 for (p = swallowed; p < swallowed_p; ++p)
861 swallowed_p = swallowed;
868 status->kind = TARGET_WAITKIND_STOPPED;
869 status->value.sig = TARGET_SIGNAL_TRAP;
873 status->kind = TARGET_WAITKIND_EXITED;
874 status->value.integer = 0;
876 timeout = old_timeout;
877 immediate_quit = old_immediate_quit;
881 /* Return the name of register number REGNO
882 in the form input and output by adapt.
884 Returns a pointer to a static buffer containing the answer. */
886 get_reg_name (int regno)
889 if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
890 sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
891 #if defined(GR64_REGNUM)
892 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
893 sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64);
895 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
896 sprintf (buf, "LR%03d", regno - LR0_REGNUM);
897 else if (regno == Q_REGNUM)
898 strcpy (buf, "SR131");
899 else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
900 sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
901 else if (regno == ALU_REGNUM)
902 strcpy (buf, "SR132");
903 else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
904 sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
905 else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM)
907 /* When a 29050 is in freeze-mode, read shadow pcs instead */
908 if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC)
909 sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20);
911 sprintf (buf, "SR%03d", regno - VAB_REGNUM);
913 else if (regno == GR1_REGNUM)
914 strcpy (buf, "GR001");
918 /* Read the remote registers. */
921 adapt_fetch_registers (void)
932 #if defined(GR64_REGNUM)
933 write (adapt_desc, "dw gr64,gr95\r", 13);
934 for (reg_index = 64, regnum_index = GR64_REGNUM;
936 reg_index += 4, regnum_index += 4)
938 sprintf (tempbuf, "GR%03d ", reg_index);
940 get_hex_regs (4, regnum_index);
944 write (adapt_desc, "dw gr96,gr127\r", 14);
945 for (reg_index = 96, regnum_index = GR96_REGNUM;
947 reg_index += 4, regnum_index += 4)
949 sprintf (tempbuf, "GR%03d ", reg_index);
951 get_hex_regs (4, regnum_index);
958 for (i = 0; i < 128; i += 32)
960 /* The PC has a tendency to hang if we get these
961 all in one fell swoop ("dw lr0,lr127"). */
962 sprintf (tempbuf, "dw lr%d\r", i);
963 write (adapt_desc, tempbuf, strlen (tempbuf));
964 for (reg_index = i, regnum_index = LR0_REGNUM + i;
966 reg_index += 4, regnum_index += 4)
968 sprintf (tempbuf, "LR%03d ", reg_index);
970 get_hex_regs (4, regnum_index);
978 sprintf (tempbuf, "dw sr0\r");
979 write (adapt_desc, tempbuf, strlen (tempbuf));
980 for (i = 0; i < 4; i++)
982 sprintf (tempbuf, "SR%3d", i * 4);
984 for (j = 0; j < (i == 3 ? 3 : 4); j++)
985 sreg_buf[i * 4 + j] = get_hex_word ();
989 * Read the pcs individually if we are in freeze mode.
990 * See get_reg_name(), it translates the register names for the pcs to
991 * the names of the shadow pcs.
995 sreg_buf[10] = read_register (NPC_REGNUM); /* pc0 */
996 sreg_buf[11] = read_register (PC_REGNUM); /* pc1 */
997 sreg_buf[12] = read_register (PC2_REGNUM); /* pc2 */
999 for (i = 0; i < 14; i++) /* Supply vab -> lru */
1000 supply_register (VAB_REGNUM + i, (char *) &sreg_buf[i]);
1001 sprintf (tempbuf, "dw sr128\r");
1002 write (adapt_desc, tempbuf, strlen (tempbuf));
1003 for (i = 0; i < 2; i++)
1004 { /* SR128 - SR135 */
1005 sprintf (tempbuf, "SR%3d", 128 + i * 4);
1007 for (j = 0; j < 4; j++)
1008 sreg_buf[i * 4 + j] = get_hex_word ();
1011 supply_register (IPC_REGNUM, (char *) &sreg_buf[0]);
1012 supply_register (IPA_REGNUM, (char *) &sreg_buf[1]);
1013 supply_register (IPB_REGNUM, (char *) &sreg_buf[2]);
1014 supply_register (Q_REGNUM, (char *) &sreg_buf[3]);
1016 supply_register (BP_REGNUM, (char *) &sreg_buf[5]);
1017 supply_register (FC_REGNUM, (char *) &sreg_buf[6]);
1018 supply_register (CR_REGNUM, (char *) &sreg_buf[7]);
1020 /* There doesn't seem to be any way to get these. */
1023 supply_register (FPE_REGNUM, (char *) &val);
1024 supply_register (INTE_REGNUM, (char *) &val);
1025 supply_register (FPS_REGNUM, (char *) &val);
1026 supply_register (EXO_REGNUM, (char *) &val);
1029 write (adapt_desc, "dw gr1,gr1\r", 11);
1031 get_hex_regs (1, GR1_REGNUM);
1035 /* Fetch register REGNO, or all registers if REGNO is -1.
1038 adapt_fetch_register (int regno)
1041 adapt_fetch_registers ();
1044 char *name = get_reg_name (regno);
1045 fprintf (adapt_stream, "dw %s,%s\r", name, name);
1048 get_hex_regs (1, regno);
1053 /* Store the remote registers from the contents of the block REGS. */
1056 adapt_store_registers (void)
1060 fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM));
1063 #if defined(GR64_REGNUM)
1064 for (j = 0; j < 32; j += 16)
1066 fprintf (adapt_stream, "s gr%d,", j + 64);
1067 for (i = 0; i < 15; ++i)
1068 fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i));
1069 fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15));
1073 for (j = 0; j < 32; j += 16)
1075 fprintf (adapt_stream, "s gr%d,", j + 96);
1076 for (i = 0; i < 15; ++i)
1077 fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i));
1078 fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15));
1082 for (j = 0; j < 128; j += 16)
1084 fprintf (adapt_stream, "s lr%d,", j);
1085 for (i = 0; i < 15; ++i)
1086 fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i));
1087 fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15));
1091 fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM),
1092 read_register (IPA_REGNUM), read_register (IPB_REGNUM));
1094 fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM),
1095 read_register (FC_REGNUM), read_register (CR_REGNUM));
1097 fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM));
1099 fprintf (adapt_stream, "s sr0,");
1100 for (i = 0; i < 7; ++i)
1101 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1103 fprintf (adapt_stream, "s sr7,");
1104 for (i = 7; i < 14; ++i)
1105 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1109 /* Store register REGNO, or all if REGNO == -1.
1110 Return errno value. */
1112 adapt_store_register (int regno)
1114 /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1116 adapt_store_registers ();
1119 char *name = get_reg_name (regno);
1120 fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno));
1121 /* Setting GR1 changes the numbers of all the locals, so
1122 invalidate the register cache. Do this *after* calling
1123 read_register, because we want read_register to return the
1124 value that write_register has just stuffed into the registers
1125 array, not the value of the register fetched from the
1127 if (regno == GR1_REGNUM)
1128 registers_changed ();
1133 /* Get ready to modify the registers array. On machines which store
1134 individual registers, this doesn't need to do anything. On machines
1135 which store all the registers in one fell swoop, this makes sure
1136 that registers contains all the registers from the program being
1140 adapt_prepare_to_store (void)
1142 /* Do nothing, since we can store individual regs */
1146 translate_addr (CORE_ADDR addr)
1148 #if defined(KERNEL_DEBUGGING)
1149 /* Check for a virtual address in the kernel */
1150 /* Assume physical address of ublock is in paddr_u register */
1153 /* PADDR_U register holds the physical address of the ublock */
1154 CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
1155 return (i + addr - (CORE_ADDR) UVADDR);
1167 /* FIXME! Merge these two. */
1169 adapt_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
1170 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
1171 struct target_ops *target ATTRIBUTE_UNUSED)
1174 memaddr = translate_addr (memaddr);
1177 return adapt_write_inferior_memory (memaddr, myaddr, len);
1179 return adapt_read_inferior_memory (memaddr, myaddr, len);
1183 adapt_files_info (void)
1185 printf_filtered ("\tAttached to %s at %d baud and running program %s\n",
1186 dev_name, baudrate, prog_name);
1187 printf_filtered ("\ton an %s processor.\n", processor_name[processor_type]);
1190 /* Copy LEN bytes of data from debugger memory at MYADDR
1191 to inferior's memory at MEMADDR. Returns errno value.
1192 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1195 adapt_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1200 /* Turn TU bit off so we can do 'sb' commands */
1201 cps = read_register (CPS_REGNUM);
1202 if (cps & 0x00000800)
1203 write_register (CPS_REGNUM, cps & ~(0x00000800));
1205 for (i = 0; i < len; i++)
1208 fprintf (adapt_stream, "sb %x,", memaddr + i);
1209 if ((i % 16) == 15 || i == len - 1)
1211 fprintf (adapt_stream, "%x\r", ((unsigned char *) myaddr)[i]);
1215 fprintf (adapt_stream, "%x,", ((unsigned char *) myaddr)[i]);
1217 /* Restore the old value of cps if the TU bit was on */
1218 if (cps & 0x00000800)
1219 write_register (CPS_REGNUM, cps);
1223 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1224 at debugger address MYADDR. Returns errno value. */
1226 adapt_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1230 /* Number of bytes read so far. */
1233 /* Starting address of this pass. */
1234 unsigned long startaddr;
1236 /* Number of bytes to read in this pass. */
1239 /* Note that this code works correctly if startaddr is just less
1240 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1241 thing). That is, something like
1242 adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1243 works--it never adds len to memaddr and gets 0. */
1244 /* However, something like
1245 adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1246 doesn't need to work. Detect it and give up if there's an attempt
1249 if (((memaddr - 1) + len) < memaddr)
1252 startaddr = memaddr;
1257 if ((startaddr % 16) != 0)
1258 len_this_pass -= startaddr % 16;
1259 if (len_this_pass > (len - count))
1260 len_this_pass = (len - count);
1262 fprintf (adapt_stream, "db %x,%x\r", startaddr,
1263 (startaddr - 1) + len_this_pass);
1265 #ifdef NOTDEF /* Why do this */
1267 /* Look for 8 hex digits. */
1271 if (isxdigit (readchar ()))
1276 error ("Hex digit expected from remote system.");
1285 for (i = 0; i < len_this_pass; i++)
1286 get_hex_byte (&myaddr[count++]);
1290 startaddr += len_this_pass;
1295 #define MAX_BREAKS 8
1296 static int num_brkpts = 0;
1298 /* Insert a breakpoint at ADDR. SAVE is normally the address of the
1299 pattern buffer where the instruction that the breakpoint overwrites
1300 is saved. It is unused here since the Adapt Monitor is responsible
1301 for saving/restoring the original instruction. */
1304 adapt_insert_breakpoint (CORE_ADDR addr, char *save)
1306 if (num_brkpts < MAX_BREAKS)
1309 fprintf (adapt_stream, "B %x", addr);
1310 fprintf (adapt_stream, "\r");
1312 return (0); /* Success */
1316 fprintf_filtered (gdb_stderr,
1317 "Too many break points, break point not installed\n");
1318 return (1); /* Failure */
1323 /* Remove a breakpoint at ADDR. SAVE is normally the previously
1324 saved pattern, but is unused here as the Adapt Monitor is
1325 responsible for saving/restoring instructions. */
1328 adapt_remove_breakpoint (CORE_ADDR addr, char *save)
1333 fprintf (adapt_stream, "BR %x", addr);
1334 fprintf (adapt_stream, "\r");
1335 fflush (adapt_stream);
1341 /* Clear the adapts notion of what the break points are */
1343 adapt_clear_breakpoints (void)
1347 fprintf (adapt_stream, "BR"); /* Clear all break points */
1348 fprintf (adapt_stream, "\r");
1349 fflush (adapt_stream);
1357 adapt_clear_breakpoints ();
1358 pop_target (); /* Pop back to no-child state */
1359 generic_mourn_inferior ();
1362 /* Display everthing we read in from the adapt until we match/see the
1366 display_until (char *str)
1370 while (c = readchar ())
1375 if (i == strlen (str))
1382 for (j = 0; j < i; j++) /* Put everthing we matched */
1393 /* Put a command string, in args, out to the adapt. The adapt is assumed to
1394 be in raw mode, all writing/reading done through adapt_desc.
1395 Ouput from the adapt is placed on the users terminal until the
1396 prompt from the adapt is seen.
1397 FIXME: Can't handle commands that take input. */
1400 adapt_com (char *args, int fromtty)
1404 printf_filtered ("Adapt not open. Use the 'target' command to open.\n");
1408 /* Clear all input so only command relative output is displayed */
1411 switch (islower (args[0]) ? toupper (args[0]) : args[0])
1414 printf_filtered ("Unknown/Unimplemented adapt command '%s'\n", args);
1416 case 'G': /* Go, begin execution */
1417 write (adapt_desc, args, strlen (args));
1418 write (adapt_desc, "\r", 1);
1421 case 'B': /* Break points, B or BR */
1422 case 'C': /* Check current 29k status (running/halted) */
1423 case 'D': /* Display data/registers */
1424 case 'I': /* Input from i/o space */
1425 case 'J': /* Jam an instruction */
1426 case 'K': /* Kill, stop execution */
1427 case 'L': /* Disassemble */
1428 case 'O': /* Output to i/o space */
1429 case 'T': /* Trace */
1430 case 'P': /* Pulse an input line */
1431 case 'X': /* Examine special purpose registers */
1432 case 'Z': /* Display trace buffer */
1433 write (adapt_desc, args, strlen (args));
1434 write (adapt_desc, "\r", 1);
1435 expect (args); /* Don't display the command */
1436 display_until ("# ");
1438 /* Begin commands that take input in the form 'c x,y[,z...]' */
1439 case 'S': /* Set memory or register */
1440 if (strchr (args, ','))
1441 { /* Assume it is properly formatted */
1442 write (adapt_desc, args, strlen (args));
1443 write (adapt_desc, "\r", 1);
1450 /* Define the target subroutine names */
1452 struct target_ops adapt_ops;
1455 init_adapt_ops (void)
1457 adapt_ops.to_shortname = "adapt";
1458 adapt_ops.to_longname = "Remote AMD `Adapt' target";
1459 adapt_ops.to_doc = "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232";
1460 adapt_ops.to_open = adapt_open;
1461 adapt_ops.to_close = adapt_close;
1462 adapt_ops.to_attach = adapt_attach;
1463 adapt_ops.to_post_attach = NULL;
1464 adapt_ops.to_require_attach = NULL;
1465 adapt_ops.to_detach = adapt_detach;
1466 adapt_ops.to_require_detach = NULL;
1467 adapt_ops.to_resume = adapt_resume;
1468 adapt_ops.to_wait = adapt_wait;
1469 adapt_ops.to_post_wait = NULL;
1470 adapt_ops.to_fetch_registers = adapt_fetch_register;
1471 adapt_ops.to_store_registers = adapt_store_register;
1472 adapt_ops.to_prepare_to_store = adapt_prepare_to_store;
1473 adapt_ops.to_xfer_memory = adapt_xfer_inferior_memory;
1474 adapt_ops.to_files_info = adapt_files_info;
1475 adapt_ops.to_insert_breakpoint = adapt_insert_breakpoint;
1476 adapt_ops.to_remove_breakpoint = adapt_remove_breakpoint;
1477 adapt_ops.to_terminal_init = 0;
1478 adapt_ops.to_terminal_inferior = 0;
1479 adapt_ops.to_terminal_ours_for_output = 0;
1480 adapt_ops.to_terminal_ours = 0;
1481 adapt_ops.to_terminal_info = 0;
1482 adapt_ops.to_kill = adapt_kill;
1483 adapt_ops.to_load = adapt_load;
1484 adapt_ops.to_lookup_symbol = 0;
1485 adapt_ops.to_create_inferior = adapt_create_inferior;
1486 adapt_ops.to_post_startup_inferior = NULL;
1487 adapt_ops.to_acknowledge_created_inferior = NULL;
1488 adapt_ops.to_clone_and_follow_inferior = NULL;
1489 adapt_ops.to_post_follow_inferior_by_clone = NULL;
1490 adapt_ops.to_insert_fork_catchpoint = NULL;
1491 adapt_ops.to_remove_fork_catchpoint = NULL;
1492 adapt_ops.to_insert_vfork_catchpoint = NULL;
1493 adapt_ops.to_remove_vfork_catchpoint = NULL;
1494 adapt_ops.to_has_forked = NULL;
1495 adapt_ops.to_has_vforked = NULL;
1496 adapt_ops.to_can_follow_vfork_prior_to_exec = NULL;
1497 adapt_ops.to_post_follow_vfork = NULL;
1498 adapt_ops.to_insert_exec_catchpoint = NULL;
1499 adapt_ops.to_remove_exec_catchpoint = NULL;
1500 adapt_ops.to_has_execd = NULL;
1501 adapt_ops.to_reported_exec_events_per_exec_call = NULL;
1502 adapt_ops.to_has_exited = NULL;
1503 adapt_ops.to_mourn_inferior = adapt_mourn;
1504 adapt_ops.to_can_run = 0;
1505 adapt_ops.to_notice_signals = 0;
1506 adapt_ops.to_thread_alive = 0;
1507 adapt_ops.to_stop = 0; /* process_stratum; */
1508 adapt_ops.to_pid_to_exec_file = NULL;
1509 adapt_ops.to_core_file_to_sym_file = NULL;
1510 adapt_ops.to_stratum = 0;
1511 adapt_ops.DONT_USE = 0;
1512 adapt_ops.to_has_all_memory = 1;
1513 adapt_ops.to_has_memory = 1;
1514 adapt_ops.to_has_stack = 1;
1515 adapt_ops.to_has_registers = 1;
1516 adapt_ops.to_has_execution = 0;
1517 adapt_ops.to_sections = 0;
1518 adapt_ops.to_sections_end = 0;
1519 adapt_ops.to_magic = OPS_MAGIC;
1520 } /* init_adapt_ops */
1523 _initialize_remote_adapt (void)
1526 add_target (&adapt_ops);
1527 add_com ("adapt <command>", class_obscure, adapt_com,
1528 "Send a command to the AMD Adapt remote monitor.");