1 /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18.
2 Copyright 1990, 1991 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., 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. */
36 #include "param-no-tm.h"
48 /* External data declarations */
49 extern int stop_soon_quietly; /* for wait_for_inferior */
51 /* External function declarations */
52 extern struct value *call_function_by_hand();
54 /* Forward data declarations */
55 extern struct target_ops adapt_ops; /* Forward declaration */
57 /* Forward function declarations */
58 static void adapt_fetch_registers ();
59 static int adapt_store_registers ();
60 static void adapt_close ();
61 static int adapt_clear_breakpoints();
64 * Processor types. It is assumed that the adapt has the correct
65 * ROM for the given processor.
67 #define TYPE_UNKNOWN 0
71 static char *processor_name[] = { "Unknown", "A29000", "A29030", "A29050" };
72 static int processor_type=TYPE_UNKNOWN;
74 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
75 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
78 /* #define DEBUG /* */
80 # define DENTER(NAME) (printf_filtered("Entering %s\n",NAME), fflush(stdout))
81 # define DEXIT(NAME) (printf_filtered("Exiting %s\n",NAME), fflush(stdout))
87 /* Can't seem to get binary coff working */
88 #define ASCII_COFF /* Adapt will be downloaded with ascii coff */
90 #define LOG_FILE "adapt.log"
91 #if defined (LOG_FILE)
95 static int timeout = 5;
96 static char *dev_name;
98 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
99 adapt_open knows that we don't have a file open when the program
103 /* stream which is fdopen'd from adapt_desc. Only valid when
110 rawmode(desc, turnon)
119 ioctl (desc, TIOCGETP, &sg);
123 sg.c_lflag &= ~(ICANON);
129 sg.c_lflag |= ICANON;
131 sg.sg_flags &= ~(RAW);
134 ioctl (desc, TIOCSETP, &sg);
137 /* Suck up all the input from the adapt */
143 /* termio does the timeout for us. */
144 while (read (adapt_desc, buf, 8) > 0);
147 while (read (adapt_desc, buf, 8) > 0);
152 /* Read a character from the remote system, doing all the fancy
161 /* termio does the timeout for us. */
162 read (adapt_desc, &buf, 1);
165 if (read (adapt_desc, &buf, 1) < 0)
168 error ("Timeout reading from remote system.");
170 perror_with_name ("remote");
176 error ("Timeout reading from remote system.");
177 #if defined (LOG_FILE)
178 putc (buf & 0x7f, log_file);
183 /* Keep discarding input from the remote system, until STRING is found.
184 Let the user break out immediately. */
191 fflush(adapt_stream);
195 if (readchar() == *p)
209 /* Keep discarding input until we see the adapt prompt.
211 The convention for dealing with the prompt is that you
213 o *then* wait for the prompt.
215 Thus the last thing that a procedure does with the serial line
216 will be an expect_prompt(). Exception: adapt_resume does not
217 wait for the prompt, because the terminal is being handed over
218 to the inferior. However, the next thing which happens after that
219 is a adapt_wait which does wait for the prompt.
220 Note that this includes abnormal exit, e.g. error(). This is
221 necessary to prevent getting into states from which we can't
226 #if defined (LOG_FILE)
227 /* This is a convenient place to do this. The idea is to do it often
228 enough that we never lose much data if we terminate abnormally. */
231 fflush(adapt_stream);
235 /* Get a hex digit from the remote system & return its value.
236 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
238 get_hex_digit (ignore_space)
245 if (ch >= '0' && ch <= '9')
247 else if (ch >= 'A' && ch <= 'F')
248 return ch - 'A' + 10;
249 else if (ch >= 'a' && ch <= 'f')
250 return ch - 'a' + 10;
251 else if (ch == ' ' && ignore_space)
256 error ("Invalid hex digit from remote system.");
261 /* Get a byte from adapt_desc and put it in *BYT. Accept any number
269 val = get_hex_digit (1) << 4;
270 val |= get_hex_digit (0);
274 /* Read a 32-bit hex word from the adapt, preceded by a space */
282 for (j = 0; j < 8; j++)
283 val = (val << 4) + get_hex_digit (j == 0);
286 /* Get N 32-bit hex words from remote, each preceded by a space
287 and put them in registers starting at REGNO. */
289 get_hex_regs (n, regno)
295 val = get_hex_word();
296 supply_register(regno++,&val);
299 /* Called when SIGALRM signal sent due to alarm() timeout. */
304 # define volatile /**/
307 volatile int n_alarms;
314 printf ("adapt_timer called\n");
320 /* malloc'd name of the program on the remote system. */
321 static char *prog_name = NULL;
323 /* Number of SIGTRAPs we need to simulate. That is, the next
324 NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
325 SIGTRAP without actually waiting for anything. */
327 static int need_artificial_trap = 0;
330 adapt_kill(arg,from_tty)
334 DENTER("adapt_kill()");
335 fprintf (adapt_stream, "K");
336 fprintf (adapt_stream, "\r");
338 DEXIT("adapt_kill()");
341 * Download a file specified in 'args', to the adapt.
342 * FIXME: Assumes the file to download is a binary coff file.
345 adapt_load(args,fromtty)
353 DENTER("adapt_load()");
355 printf_filtered("Adapt not open. Use 'target' command to open adapt\n");
359 /* OK, now read in the file. Y=read, C=COFF, T=dTe port
362 #ifdef ASCII_COFF /* Ascii coff */
363 fprintf (adapt_stream, "YA T,0\r");
364 fflush(adapt_stream); /* Just in case */
365 /* FIXME: should check args for only 1 argument */
366 sprintf(buffer,"cat %s | btoa > /tmp/#adapt-btoa",args);
368 fp = fopen("/tmp/#adapt-btoa","r");
369 rawmode(adapt_desc,OFF);
370 while (n=fread(buffer,1,1024,fp)) {
371 do { n -= write(adapt_desc,buffer,n); } while (n>0);
372 if (n<0) { perror("writing ascii coff"); break; }
375 rawmode(adapt_desc,ON);
376 system("rm /tmp/#adapt-btoa");
377 #else /* Binary coff - can't get it to work .*/
378 fprintf (adapt_stream, "YC T,0\r");
379 fflush(adapt_stream); /* Just in case */
380 if (!(fp = fopen(args,"r"))) {
381 printf_filtered("Can't open %s\n",args);
384 while (n=fread(buffer,1,512,fp)) {
385 do { n -= write(adapt_desc,buffer,n); } while (n>0);
386 if (n<0) { perror("writing ascii coff"); break; }
390 expect_prompt (); /* Skip garbage that comes out */
391 fprintf (adapt_stream, "\r");
393 DEXIT("adapt_load()");
396 /* This is called not only when we first attach, but also when the
397 user types "run" after having attached. */
399 adapt_create_inferior (execfile, args, env)
406 DENTER("adapt_create_inferior()");
409 error ("Can't pass arguments to remote adapt process.");
411 if (execfile == 0 || exec_bfd == 0)
412 error ("No exec file specified");
414 entry_pt = (int) bfd_get_start_address (exec_bfd);
417 adapt_kill(NULL,NULL);
418 adapt_clear_breakpoints();
419 init_wait_for_inferior ();
420 /* Clear the input because what the adapt sends back is different
421 * depending on whether it was running or not.
423 slurp_input(); /* After this there should be a prompt */
424 fprintf(adapt_stream,"\r");
426 printf_filtered("Do you want to download '%s' (y/n)? [y] : ",prog_name);
430 if (*buffer != 'n') {
431 adapt_load(prog_name,0);
436 /* Set the PC and wait for a go/cont */
437 fprintf (adapt_stream, "G %x,N\r",entry_pt);
438 printf_filtered("Now use the 'continue' command to start.\n");
441 insert_breakpoints (); /* Needed to get correct instruction in cache */
442 proceed(entry_pt, -1, 0);
446 printf_filtered("Adapt not open yet.\n");
448 DEXIT("adapt_create_inferior()");
451 /* Translate baud rates from integers to damn B_codes. Unix should
452 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
461 static struct {int rate, damn_b;} baudtab[] = {
481 static int damn_b (rate)
486 for (i = 0; baudtab[i].rate != -1; i++)
487 if (rate == baudtab[i].rate) return baudtab[i].damn_b;
488 return B38400; /* Random */
492 /* Open a connection to a remote debugger.
493 NAME is the filename used for communication, then a space,
497 static int baudrate = 9600;
499 adapt_open (name, from_tty)
507 DENTER("adapt_open()");
508 /* Find the first whitespace character, it separates dev_name from
514 *p != '\0' && !isspace (*p); p++)
519 Please include the name of the device for the serial port,\n\
520 the baud rate, and the name of the program to run on the remote system.");
521 dev_name = (char*)malloc(p - name + 1);
522 strncpy (dev_name, name, p - name);
523 dev_name[p - name] = '\0';
525 /* Skip over the whitespace after dev_name */
526 for (; isspace (*p); p++)
529 if (1 != sscanf (p, "%d ", &baudrate))
532 /* Skip the number and then the spaces */
533 for (; isdigit (*p); p++)
535 for (; isspace (*p); p++)
538 if (prog_name != NULL)
540 prog_name = savestring (p, strlen (p));
544 adapt_desc = open (dev_name, O_RDWR);
546 perror_with_name (dev_name);
547 ioctl (adapt_desc, TIOCGETP, &sg);
549 sg.c_cc[VMIN] = 0; /* read with timeout. */
550 sg.c_cc[VTIME] = timeout * 10;
551 sg.c_lflag &= ~(ICANON | ECHO);
552 sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
554 sg.sg_ispeed = damn_b (baudrate);
555 sg.sg_ospeed = damn_b (baudrate);
556 sg.sg_flags |= RAW | ANYP;
557 sg.sg_flags &= ~ECHO;
560 ioctl (adapt_desc, TIOCSETP, &sg);
561 adapt_stream = fdopen (adapt_desc, "r+");
563 push_target (&adapt_ops);
564 /* start_remote (); /* Initialize gdb process mechanisms */
568 #ifndef NO_SIGINTERRUPT
569 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
571 if (siginterrupt (SIGALRM, 1) != 0)
572 perror ("adapt_open: error in siginterrupt");
575 /* Set up read timeout timer. */
576 if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1)
577 perror ("adapt_open: error in signal");
580 #if defined (LOG_FILE)
581 log_file = fopen (LOG_FILE, "w");
582 if (log_file == NULL)
583 perror_with_name (LOG_FILE);
586 /* Put this port into NORMAL mode, send the 'normal' character */
587 write(adapt_desc, "
\ 1", 1); /* Control A */
588 write(adapt_desc, "\r", 1);
591 /* Hello? Are you there? */
592 write (adapt_desc, "\r", 1);
596 /* Clear any break points */
597 adapt_clear_breakpoints();
599 /* Determine the processor revision level */
600 prl = (unsigned int)read_register(CFG_REGNUM) >> 24;
602 processor_type = TYPE_A29000;
603 } else if ((prl&0xf0) == 0x40) { /* 29030 = 0x4* */
604 processor_type = TYPE_A29030;
605 fprintf_filtered(stderr,"WARNING: debugging of A29030 not tested.\n");
606 } else if ((prl&0xf0) == 0x20) { /* 29050 = 0x2* */
607 processor_type = TYPE_A29050;
608 fprintf_filtered(stderr,"WARNING: debugging of A29050 not tested.\n");
610 processor_type = TYPE_UNKNOWN;
611 fprintf_filtered(stderr,"WARNING: processor type unknown.\n");
614 /* Print out some stuff, letting the user now what's going on */
615 printf_filtered("Remote debugging on an %s connect to an Adapt via %s.\n",
616 processor_name[processor_type],dev_name);
617 /* FIXME: can this restriction be removed? */
618 printf_filtered("Remote debugging using virtual addresses works only\n");
619 printf_filtered("\twhen virtual addresses map 1:1 to physical addresses.\n");
620 if (processor_type != TYPE_A29050) {
621 fprintf_filtered(stderr,
622 "Freeze-mode debugging not available, and can only be done on an A29050.\n");
624 DEXIT("adapt_open()");
627 /* Close out all files and local state before this target loses control. */
630 adapt_close (quitting)
634 DENTER("adapt_close()");
636 /* Clear any break points */
637 adapt_clear_breakpoints();
639 /* Put this port back into REMOTE mode */
641 fflush(adapt_stream);
642 sleep(1); /* Let any output make it all the way back */
643 write(adapt_desc, "R\r", 2);
646 /* Due to a bug in Unix, fclose closes not only the stdio stream,
647 but also the file descriptor. So we don't actually close
650 fclose (adapt_stream); /* This also closes adapt_desc */
652 /* close (adapt_desc); */
654 /* Do not try to close adapt_desc again, later in the program. */
658 #if defined (LOG_FILE)
660 if (ferror (log_file))
661 printf_filtered ("Error writing log file.\n");
662 if (fclose (log_file) != 0)
663 printf_filtered ("Error closing log file.\n");
667 DEXIT("adapt_close()");
670 /* Attach to the target that is already loaded and possibly running */
672 adapt_attach (args, from_tty)
677 DENTER("adapt_attach()");
679 printf_filtered ("Attaching to remote program %s.\n", prog_name);
681 /* push_target(&adapt_ops); /* This done in adapt_open() */
683 mark_breakpoints_out ();
685 /* Send the adapt a kill. It is ok if it is not already running */
686 fprintf(adapt_stream, "K\r"); fflush(adapt_stream);
687 expect_prompt(); /* Slurp the echo */
689 /* We will get a task spawn event immediately. */
690 init_wait_for_inferior ();
691 clear_proceed_status ();
692 stop_soon_quietly = 1;
693 wait_for_inferior ();
694 stop_soon_quietly = 0;
696 DEXIT("adapt_attach()");
700 /* Terminate the open connection to the remote debugger.
701 Use this when you want to detach and do something else
704 adapt_detach (args,from_tty)
708 DENTER("adapt_detach()");
709 if (adapt_stream) { /* Send it on its way (tell it to continue) */
710 adapt_clear_breakpoints();
711 fprintf(adapt_stream,"G\r");
714 pop_target(); /* calls adapt_close to do the real work */
716 printf_filtered ("Ending remote %s debugging\n", target_shortname);
717 DEXIT("adapt_detach()");
720 /* Tell the remote machine to resume. */
723 adapt_resume (step, sig)
726 DENTER("adapt_resume()");
729 write (adapt_desc, "t 1,s\r", 6);
730 /* Wait for the echo. */
731 expect ("t 1,s\r\n");
732 /* Then comes a line containing the instruction we stepped to. */
734 /* Then we get the prompt. */
737 /* Force the next adapt_wait to return a trap. Not doing anything
738 about I/O from the target means that the user has to type
739 "continue" to see any. FIXME, this should be fixed. */
740 need_artificial_trap = 1;
744 write (adapt_desc, "G\r", 2);
745 /* Swallow the echo. */
748 DEXIT("adapt_resume()");
751 /* Wait until the remote machine stops, then return,
752 storing status in STATUS just as `wait' would. */
758 /* Strings to look for. '?' means match any single character.
759 Note that with the algorithm we use, the initial character
760 of the string cannot recur in the string, or we will not
761 find some cases of the string in the input. */
763 static char bpt[] = "@";
764 /* It would be tempting to look for "\n[__exit + 0x8]\n"
765 but that requires loading symbols with "yc i" and even if
766 we did do that we don't know that the file has symbols. */
767 static char exitmsg[] = "@????????I JMPTI GR121,LR0";
771 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
773 /* Current position in swallowed. */
774 char *swallowed_p = swallowed;
778 int old_timeout = timeout;
779 int old_immediate_quit = immediate_quit;
781 DENTER("adapt_wait()");
783 WSETEXIT ((*status), 0);
785 if (need_artificial_trap != 0)
787 WSETSTOP ((*status), SIGTRAP);
788 need_artificial_trap--;
792 timeout = 0; /* Don't time out -- user program is running. */
793 immediate_quit = 1; /* Helps ability to QUIT */
795 QUIT; /* Let user quit and leave process running */
807 if (ch == *ep || *ep == '?') {
819 /* Print out any characters which have been swallowed. */
820 for (p = swallowed; p < swallowed_p; ++p)
822 swallowed_p = swallowed;
828 WSETSTOP ((*status), SIGTRAP);
830 WSETEXIT ((*status), 0);
831 timeout = old_timeout;
832 immediate_quit = old_immediate_quit;
833 DEXIT("adapt_wait()");
837 /* Return the name of register number REGNO
838 in the form input and output by adapt.
840 Returns a pointer to a static buffer containing the answer. */
846 if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32 )
847 sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
848 #if defined(GR64_REGNUM)
849 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
850 sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64);
852 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
853 sprintf (buf, "LR%03d", regno - LR0_REGNUM);
854 else if (regno == Q_REGNUM)
855 strcpy (buf, "SR131");
856 else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
857 sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
858 else if (regno == ALU_REGNUM)
859 strcpy (buf, "SR132");
860 else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
861 sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
862 else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM) {
863 /* When a 29050 is in freeze-mode, read shadow pcs instead */
864 if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC)
865 sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20);
867 sprintf (buf, "SR%03d", regno - VAB_REGNUM);
869 else if (regno == GR1_REGNUM)
870 strcpy (buf, "GR001");
874 /* Read the remote registers. */
877 adapt_fetch_registers ()
885 DENTER("adapt_fetch_registers()");
890 #if defined(GR64_REGNUM)
891 write (adapt_desc, "dw gr64,gr95\r", 13);
892 for (reg_index = 64, regnum_index = GR64_REGNUM;
894 reg_index += 4, regnum_index += 4)
896 sprintf (tempbuf, "GR%03d ", reg_index);
898 get_hex_regs (4, regnum_index);
902 write (adapt_desc, "dw gr96,gr127\r", 14);
903 for (reg_index = 96, regnum_index = GR96_REGNUM;
905 reg_index += 4, regnum_index += 4)
907 sprintf (tempbuf, "GR%03d ", reg_index);
909 get_hex_regs (4, regnum_index);
916 for (i = 0; i < 128; i += 32)
918 /* The PC has a tendency to hang if we get these
919 all in one fell swoop ("dw lr0,lr127"). */
920 sprintf (tempbuf, "dw lr%d\r", i);
921 write (adapt_desc, tempbuf, strlen (tempbuf));
922 for (reg_index = i, regnum_index = LR0_REGNUM + i;
924 reg_index += 4, regnum_index += 4)
926 sprintf (tempbuf, "LR%03d ", reg_index);
928 get_hex_regs (4, regnum_index);
936 sprintf (tempbuf, "dw sr0\r");
937 write (adapt_desc, tempbuf, strlen (tempbuf));
938 for (i=0 ; i<4 ; i++) { /* SR0 - SR14 */
939 sprintf (tempbuf, "SR%3d",i*4);
941 for (j=0 ; j < (i==3 ? 3 : 4) ; j++)
942 sreg_buf[i*4 + j] = get_hex_word();
946 * Read the pcs individually if we are in freeze mode.
947 * See get_reg_name(), it translates the register names for the pcs to
948 * the names of the shadow pcs.
951 sreg_buf[10] = read_register(NPC_REGNUM); /* pc0 */
952 sreg_buf[11] = read_register(PC_REGNUM); /* pc1 */
953 sreg_buf[12] = read_register(PC2_REGNUM); /* pc2 */
955 for (i=0 ; i<14 ; i++) /* Supply vab -> lru */
956 supply_register(VAB_REGNUM+i,&sreg_buf[i]);
957 sprintf (tempbuf, "dw sr128\r");
958 write (adapt_desc, tempbuf, strlen (tempbuf));
959 for (i=0 ; i<2 ; i++) { /* SR128 - SR135 */
960 sprintf (tempbuf, "SR%3d",128 + i*4);
962 for (j=0 ; j<4 ; j++)
963 sreg_buf[i*4 + j] = get_hex_word();
966 supply_register(IPC_REGNUM,&sreg_buf[0]);
967 supply_register(IPA_REGNUM,&sreg_buf[1]);
968 supply_register(IPB_REGNUM,&sreg_buf[2]);
969 supply_register(Q_REGNUM, &sreg_buf[3]);
971 supply_register(BP_REGNUM, &sreg_buf[5]);
972 supply_register(FC_REGNUM, &sreg_buf[6]);
973 supply_register(CR_REGNUM, &sreg_buf[7]);
975 /* There doesn't seem to be any way to get these. */
978 supply_register (FPE_REGNUM, &val);
979 supply_register (INT_REGNUM, &val);
980 supply_register (FPS_REGNUM, &val);
981 supply_register (EXO_REGNUM, &val);
984 write (adapt_desc, "dw gr1,gr1\r", 11);
986 get_hex_regs (1, GR1_REGNUM);
989 DEXIT("adapt_fetch_registers()");
992 /* Fetch register REGNO, or all registers if REGNO is -1.
995 adapt_fetch_register (regno)
998 DENTER("adapt_fetch_register()");
1000 adapt_fetch_registers ();
1003 char *name = get_reg_name (regno);
1004 fprintf (adapt_stream, "dw %s,%s\r", name, name);
1007 get_hex_regs (1, regno);
1010 DEXIT("adapt_fetch_register()");
1013 /* Store the remote registers from the contents of the block REGS. */
1016 adapt_store_registers ()
1020 DENTER("adapt_store_registers()");
1021 fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM));
1024 #if defined(GR64_REGNUM)
1025 for (j = 0; j < 32; j += 16)
1027 fprintf (adapt_stream, "s gr%d,", j + 64);
1028 for (i = 0; i < 15; ++i)
1029 fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i));
1030 fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15));
1034 for (j = 0; j < 32; j += 16)
1036 fprintf (adapt_stream, "s gr%d,", j + 96);
1037 for (i = 0; i < 15; ++i)
1038 fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i));
1039 fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15));
1043 for (j = 0; j < 128; j += 16)
1045 fprintf (adapt_stream, "s lr%d,", j);
1046 for (i = 0; i < 15; ++i)
1047 fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i));
1048 fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15));
1052 fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM),
1053 read_register (IPA_REGNUM), read_register (IPB_REGNUM));
1055 fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM),
1056 read_register (FC_REGNUM), read_register (CR_REGNUM));
1058 fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM));
1060 fprintf (adapt_stream, "s sr0,");
1061 for (i=0 ; i<7 ; ++i)
1062 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1064 fprintf (adapt_stream, "s sr7,");
1065 for (i=7; i<14 ; ++i)
1066 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1070 /* Store register REGNO, or all if REGNO == -1.
1071 Return errno value. */
1073 adapt_store_register (regno)
1076 /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1078 adapt_store_registers ();
1081 char *name = get_reg_name (regno);
1082 fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno));
1083 /* Setting GR1 changes the numbers of all the locals, so
1084 invalidate the register cache. Do this *after* calling
1085 read_register, because we want read_register to return the
1086 value that write_register has just stuffed into the registers
1087 array, not the value of the register fetched from the
1089 if (regno == GR1_REGNUM)
1090 registers_changed ();
1093 DEXIT("adapt_store_registers()");
1097 /* Get ready to modify the registers array. On machines which store
1098 individual registers, this doesn't need to do anything. On machines
1099 which store all the registers in one fell swoop, this makes sure
1100 that registers contains all the registers from the program being
1104 adapt_prepare_to_store ()
1106 /* Do nothing, since we can store individual regs */
1110 translate_addr(addr)
1113 #if defined(KERNEL_DEBUGGING)
1114 /* Check for a virtual address in the kernel */
1115 /* Assume physical address of ublock is in paddr_u register */
1116 if (addr >= UVADDR) {
1117 /* PADDR_U register holds the physical address of the ublock */
1118 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
1119 return(i + addr - (CORE_ADDR)UVADDR);
1129 /* FIXME! Merge these two. */
1131 adapt_xfer_inferior_memory (memaddr, myaddr, len, write)
1138 memaddr = translate_addr(memaddr);
1141 return adapt_write_inferior_memory (memaddr, myaddr, len);
1143 return adapt_read_inferior_memory (memaddr, myaddr, len);
1149 printf_filtered("\tAttached to %s at %d baud and running program %s\n",
1150 dev_name, baudrate, prog_name);
1151 printf_filtered("\ton an %s processor.\n", processor_name[processor_type]);
1154 /* Copy LEN bytes of data from debugger memory at MYADDR
1155 to inferior's memory at MEMADDR. Returns errno value.
1156 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1159 adapt_write_inferior_memory (memaddr, myaddr, len)
1167 /* DENTER("adapt_write_inferior_memory()"); */
1169 /* Turn TU bit off so we can do 'sb' commands */
1170 cps = read_register(CPS_REGNUM);
1171 if (cps & 0x00000800)
1172 write_register(CPS_REGNUM,cps&~(0x00000800));
1174 for (i = 0; i < len; i++)
1177 fprintf (adapt_stream, "sb %x,", memaddr + i);
1178 if ((i % 16) == 15 || i == len - 1)
1180 fprintf (adapt_stream, "%x\r", ((unsigned char *)myaddr)[i]);
1184 fprintf (adapt_stream, "%x,", ((unsigned char *)myaddr)[i]);
1186 /* Restore the old value of cps if the TU bit was on */
1187 if (cps & 0x00000800)
1188 write_register(CPS_REGNUM,cps);
1189 /* DEXIT("adapt_write_inferior_memory()"); */
1193 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1194 at debugger address MYADDR. Returns errno value. */
1196 adapt_read_inferior_memory(memaddr, myaddr, len)
1203 /* Number of bytes read so far. */
1206 /* Starting address of this pass. */
1207 unsigned long startaddr;
1209 /* Number of bytes to read in this pass. */
1212 /* Note that this code works correctly if startaddr is just less
1213 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1214 thing). That is, something like
1215 adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1216 works--it never adds len to memaddr and gets 0. */
1217 /* However, something like
1218 adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1219 doesn't need to work. Detect it and give up if there's an attempt
1221 /* DENTER("adapt_read_inferior_memory()"); */
1223 if (((memaddr - 1) + len) < memaddr)
1226 startaddr = memaddr;
1231 if ((startaddr % 16) != 0)
1232 len_this_pass -= startaddr % 16;
1233 if (len_this_pass > (len - count))
1234 len_this_pass = (len - count);
1236 fprintf (adapt_stream, "db %x,%x\r", startaddr,
1237 (startaddr - 1) + len_this_pass);
1239 #ifdef NOTDEF /* Why do this */
1241 /* Look for 8 hex digits. */
1245 if (isxdigit (readchar ()))
1250 error ("Hex digit expected from remote system.");
1259 for (i = 0; i < len_this_pass; i++)
1260 get_hex_byte (&myaddr[count++]);
1264 startaddr += len_this_pass;
1267 /* DEXIT("adapt_read_inferior_memory()"); */
1271 #define MAX_BREAKS 8
1272 static int num_brkpts=0;
1274 adapt_insert_breakpoint(addr, save)
1276 char *save; /* Throw away, let adapt save instructions */
1278 DENTER("adapt_insert_breakpoint()");
1279 if (num_brkpts < MAX_BREAKS) {
1281 fprintf (adapt_stream, "B %x", addr);
1282 fprintf (adapt_stream, "\r");
1284 DEXIT("adapt_insert_breakpoint() success");
1285 return(0); /* Success */
1287 fprintf_filtered(stderr,
1288 "Too many break points, break point not installed\n");
1289 DEXIT("adapt_insert_breakpoint() failure");
1290 return(1); /* Failure */
1295 adapt_remove_breakpoint(addr, save)
1297 char *save; /* Throw away, let adapt save instructions */
1299 DENTER("adapt_remove_breakpoint()");
1300 if (num_brkpts > 0) {
1302 fprintf (adapt_stream, "BR %x", addr);
1303 fprintf (adapt_stream, "\r");
1304 fflush (adapt_stream);
1307 DEXIT("adapt_remove_breakpoint()");
1311 /* Clear the adapts notion of what the break points are */
1313 adapt_clear_breakpoints()
1315 DENTER("adapt_clear_breakpoint()");
1317 fprintf (adapt_stream, "BR"); /* Clear all break points */
1318 fprintf (adapt_stream, "\r");
1319 fflush(adapt_stream);
1323 DEXIT("adapt_clear_breakpoint()");
1328 DENTER("adapt_mourn()");
1329 adapt_clear_breakpoints();
1330 pop_target (); /* Pop back to no-child state */
1331 generic_mourn_inferior ();
1332 DEXIT("adapt_mourn()");
1335 /* Display everthing we read in from the adapt until we match/see the
1344 while (c=readchar()) {
1347 if (i == strlen(str)) return;
1350 for (j=0 ; j<i ; j++) /* Put everthing we matched */
1361 /* Put a command string, in args, out to the adapt. The adapt is assumed to
1362 be in raw mode, all writing/reading done through adapt_desc.
1363 Ouput from the adapt is placed on the users terminal until the
1364 prompt from the adapt is seen.
1365 FIXME: Can't handle commands that take input. */
1368 adapt_com (args, fromtty)
1372 if (!adapt_stream) {
1373 printf_filtered("Adapt not open. Use the 'target' command to open.\n");
1377 /* Clear all input so only command relative output is displayed */
1380 switch(islower(args[0]) ? toupper(args[0]) : args[0]) {
1382 printf_filtered("Unknown/Unimplemented adapt command '%s'\n",args);
1384 case 'G': /* Go, begin execution */
1385 write(adapt_desc,args,strlen(args));
1386 write(adapt_desc,"\r",1);
1389 case 'B': /* Break points, B or BR */
1390 case 'C': /* Check current 29k status (running/halted) */
1391 case 'D': /* Display data/registers */
1392 case 'I': /* Input from i/o space */
1393 case 'J': /* Jam an instruction */
1394 case 'K': /* Kill, stop execution */
1395 case 'L': /* Disassemble */
1396 case 'O': /* Output to i/o space */
1397 case 'T': /* Trace */
1398 case 'P': /* Pulse an input line */
1399 case 'X': /* Examine special purpose registers */
1400 case 'Z': /* Display trace buffer */
1401 write(adapt_desc,args,strlen(args));
1402 write(adapt_desc,"\r",1);
1403 expect(args); /* Don't display the command */
1404 display_until("# ");
1406 /* Begin commands that take input in the form 'c x,y[,z...]' */
1407 case 'S': /* Set memory or register */
1408 if (index(args,',')) { /* Assume it is properly formatted */
1409 write(adapt_desc,args,strlen(args));
1410 write(adapt_desc,"\r",1);
1417 /* Define the target subroutine names */
1419 struct target_ops adapt_ops = {
1420 "adapt", "Remote AMD `Adapt' target",
1421 "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232",
1422 adapt_open, adapt_close,
1423 adapt_attach, adapt_detach, adapt_resume, adapt_wait,
1424 adapt_fetch_register, adapt_store_register,
1425 adapt_prepare_to_store, 0, 0, /* conv_to, conv_from */
1426 adapt_xfer_inferior_memory,
1428 adapt_insert_breakpoint, adapt_remove_breakpoint, /* Breakpoints */
1429 0, 0, 0, 0, 0, /* Terminal handling */
1430 adapt_kill, /* FIXME, kill */
1432 call_function_by_hand,
1433 0, /* lookup_symbol */
1434 adapt_create_inferior, /* create_inferior */
1435 adapt_mourn, /* mourn_inferior FIXME */
1436 process_stratum, 0, /* next */
1437 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1438 0,0, /* Section pointers */
1439 OPS_MAGIC, /* Always the last thing */
1443 _initialize_remote_adapt ()
1445 add_target (&adapt_ops);
1446 add_com ("adapt <command>", class_obscure, adapt_com,
1447 "Send a command to the AMD Adapt remote monitor.");