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. */
46 /* External data declarations */
47 extern int stop_soon_quietly; /* for wait_for_inferior */
49 /* External function declarations */
50 extern struct value *call_function_by_hand();
52 /* Forward data declarations */
53 extern struct target_ops adapt_ops; /* Forward declaration */
55 /* Forward function declarations */
56 static void adapt_fetch_registers ();
57 static int adapt_store_registers ();
58 static void adapt_close ();
59 static int adapt_clear_breakpoints();
62 * Processor types. It is assumed that the adapt has the correct
63 * ROM for the given processor.
65 #define TYPE_UNKNOWN 0
69 static char *processor_name[] = { "Unknown", "A29000", "A29030", "A29050" };
70 static int processor_type=TYPE_UNKNOWN;
72 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
73 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
76 /* #define DEBUG /* */
78 # define DENTER(NAME) (printf_filtered("Entering %s\n",NAME), fflush(stdout))
79 # define DEXIT(NAME) (printf_filtered("Exiting %s\n",NAME), fflush(stdout))
85 /* Can't seem to get binary coff working */
86 #define ASCII_COFF /* Adapt will be downloaded with ascii coff */
88 #define LOG_FILE "adapt.log"
89 #if defined (LOG_FILE)
93 static int timeout = 5;
94 static char *dev_name;
96 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
97 adapt_open knows that we don't have a file open when the program
101 /* stream which is fdopen'd from adapt_desc. Only valid when
108 rawmode(desc, turnon)
117 ioctl (desc, TIOCGETP, &sg);
121 sg.c_lflag &= ~(ICANON);
127 sg.c_lflag |= ICANON;
129 sg.sg_flags &= ~(RAW);
132 ioctl (desc, TIOCSETP, &sg);
135 /* Suck up all the input from the adapt */
141 /* termio does the timeout for us. */
142 while (read (adapt_desc, buf, 8) > 0);
145 while (read (adapt_desc, buf, 8) > 0);
150 /* Read a character from the remote system, doing all the fancy
159 /* termio does the timeout for us. */
160 read (adapt_desc, &buf, 1);
163 if (read (adapt_desc, &buf, 1) < 0)
166 error ("Timeout reading from remote system.");
168 perror_with_name ("remote");
174 error ("Timeout reading from remote system.");
175 #if defined (LOG_FILE)
176 putc (buf & 0x7f, log_file);
181 /* Keep discarding input from the remote system, until STRING is found.
182 Let the user break out immediately. */
189 fflush(adapt_stream);
193 if (readchar() == *p)
207 /* Keep discarding input until we see the adapt prompt.
209 The convention for dealing with the prompt is that you
211 o *then* wait for the prompt.
213 Thus the last thing that a procedure does with the serial line
214 will be an expect_prompt(). Exception: adapt_resume does not
215 wait for the prompt, because the terminal is being handed over
216 to the inferior. However, the next thing which happens after that
217 is a adapt_wait which does wait for the prompt.
218 Note that this includes abnormal exit, e.g. error(). This is
219 necessary to prevent getting into states from which we can't
224 #if defined (LOG_FILE)
225 /* This is a convenient place to do this. The idea is to do it often
226 enough that we never lose much data if we terminate abnormally. */
229 fflush(adapt_stream);
233 /* Get a hex digit from the remote system & return its value.
234 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
236 get_hex_digit (ignore_space)
243 if (ch >= '0' && ch <= '9')
245 else if (ch >= 'A' && ch <= 'F')
246 return ch - 'A' + 10;
247 else if (ch >= 'a' && ch <= 'f')
248 return ch - 'a' + 10;
249 else if (ch == ' ' && ignore_space)
254 error ("Invalid hex digit from remote system.");
259 /* Get a byte from adapt_desc and put it in *BYT. Accept any number
267 val = get_hex_digit (1) << 4;
268 val |= get_hex_digit (0);
272 /* Read a 32-bit hex word from the adapt, preceded by a space */
280 for (j = 0; j < 8; j++)
281 val = (val << 4) + get_hex_digit (j == 0);
284 /* Get N 32-bit hex words from remote, each preceded by a space
285 and put them in registers starting at REGNO. */
287 get_hex_regs (n, regno)
293 val = get_hex_word();
294 supply_register(regno++,&val);
297 /* Called when SIGALRM signal sent due to alarm() timeout. */
302 # define volatile /**/
305 volatile int n_alarms;
312 printf ("adapt_timer called\n");
318 /* malloc'd name of the program on the remote system. */
319 static char *prog_name = NULL;
321 /* Number of SIGTRAPs we need to simulate. That is, the next
322 NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
323 SIGTRAP without actually waiting for anything. */
325 static int need_artificial_trap = 0;
328 adapt_kill(arg,from_tty)
332 DENTER("adapt_kill()");
333 fprintf (adapt_stream, "K");
334 fprintf (adapt_stream, "\r");
336 DEXIT("adapt_kill()");
339 * Download a file specified in 'args', to the adapt.
340 * FIXME: Assumes the file to download is a binary coff file.
343 adapt_load(args,fromtty)
351 DENTER("adapt_load()");
353 printf_filtered("Adapt not open. Use 'target' command to open adapt\n");
357 /* OK, now read in the file. Y=read, C=COFF, T=dTe port
360 #ifdef ASCII_COFF /* Ascii coff */
361 fprintf (adapt_stream, "YA T,0\r");
362 fflush(adapt_stream); /* Just in case */
363 /* FIXME: should check args for only 1 argument */
364 sprintf(buffer,"cat %s | btoa > /tmp/#adapt-btoa",args);
366 fp = fopen("/tmp/#adapt-btoa","r");
367 rawmode(adapt_desc,OFF);
368 while (n=fread(buffer,1,1024,fp)) {
369 do { n -= write(adapt_desc,buffer,n); } while (n>0);
370 if (n<0) { perror("writing ascii coff"); break; }
373 rawmode(adapt_desc,ON);
374 system("rm /tmp/#adapt-btoa");
375 #else /* Binary coff - can't get it to work .*/
376 fprintf (adapt_stream, "YC T,0\r");
377 fflush(adapt_stream); /* Just in case */
378 if (!(fp = fopen(args,"r"))) {
379 printf_filtered("Can't open %s\n",args);
382 while (n=fread(buffer,1,512,fp)) {
383 do { n -= write(adapt_desc,buffer,n); } while (n>0);
384 if (n<0) { perror("writing ascii coff"); break; }
388 expect_prompt (); /* Skip garbage that comes out */
389 fprintf (adapt_stream, "\r");
391 DEXIT("adapt_load()");
394 /* This is called not only when we first attach, but also when the
395 user types "run" after having attached. */
397 adapt_create_inferior (execfile, args, env)
404 DENTER("adapt_create_inferior()");
407 error ("Can't pass arguments to remote adapt process.");
409 if (execfile == 0 || exec_bfd == 0)
410 error ("No exec file specified");
412 entry_pt = (int) bfd_get_start_address (exec_bfd);
415 adapt_kill(NULL,NULL);
416 adapt_clear_breakpoints();
417 init_wait_for_inferior ();
418 /* Clear the input because what the adapt sends back is different
419 * depending on whether it was running or not.
421 slurp_input(); /* After this there should be a prompt */
422 fprintf(adapt_stream,"\r");
424 printf_filtered("Do you want to download '%s' (y/n)? [y] : ",prog_name);
428 if (*buffer != 'n') {
429 adapt_load(prog_name,0);
434 /* Set the PC and wait for a go/cont */
435 fprintf (adapt_stream, "G %x,N\r",entry_pt);
436 printf_filtered("Now use the 'continue' command to start.\n");
439 insert_breakpoints (); /* Needed to get correct instruction in cache */
440 proceed(entry_pt, -1, 0);
444 printf_filtered("Adapt not open yet.\n");
446 DEXIT("adapt_create_inferior()");
449 /* Translate baud rates from integers to damn B_codes. Unix should
450 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
459 static struct {int rate, damn_b;} baudtab[] = {
479 static int damn_b (rate)
484 for (i = 0; baudtab[i].rate != -1; i++)
485 if (rate == baudtab[i].rate) return baudtab[i].damn_b;
486 return B38400; /* Random */
490 /* Open a connection to a remote debugger.
491 NAME is the filename used for communication, then a space,
495 static int baudrate = 9600;
497 adapt_open (name, from_tty)
505 DENTER("adapt_open()");
506 /* Find the first whitespace character, it separates dev_name from
512 *p != '\0' && !isspace (*p); p++)
517 Please include the name of the device for the serial port,\n\
518 the baud rate, and the name of the program to run on the remote system.");
519 dev_name = (char*)malloc(p - name + 1);
520 strncpy (dev_name, name, p - name);
521 dev_name[p - name] = '\0';
523 /* Skip over the whitespace after dev_name */
524 for (; isspace (*p); p++)
527 if (1 != sscanf (p, "%d ", &baudrate))
530 /* Skip the number and then the spaces */
531 for (; isdigit (*p); p++)
533 for (; isspace (*p); p++)
536 if (prog_name != NULL)
538 prog_name = savestring (p, strlen (p));
542 adapt_desc = open (dev_name, O_RDWR);
544 perror_with_name (dev_name);
545 ioctl (adapt_desc, TIOCGETP, &sg);
547 sg.c_cc[VMIN] = 0; /* read with timeout. */
548 sg.c_cc[VTIME] = timeout * 10;
549 sg.c_lflag &= ~(ICANON | ECHO);
550 sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
552 sg.sg_ispeed = damn_b (baudrate);
553 sg.sg_ospeed = damn_b (baudrate);
554 sg.sg_flags |= RAW | ANYP;
555 sg.sg_flags &= ~ECHO;
558 ioctl (adapt_desc, TIOCSETP, &sg);
559 adapt_stream = fdopen (adapt_desc, "r+");
561 push_target (&adapt_ops);
562 /* start_remote (); /* Initialize gdb process mechanisms */
566 #ifndef NO_SIGINTERRUPT
567 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
569 if (siginterrupt (SIGALRM, 1) != 0)
570 perror ("adapt_open: error in siginterrupt");
573 /* Set up read timeout timer. */
574 if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1)
575 perror ("adapt_open: error in signal");
578 #if defined (LOG_FILE)
579 log_file = fopen (LOG_FILE, "w");
580 if (log_file == NULL)
581 perror_with_name (LOG_FILE);
584 /* Put this port into NORMAL mode, send the 'normal' character */
585 write(adapt_desc, "
\ 1", 1); /* Control A */
586 write(adapt_desc, "\r", 1);
589 /* Hello? Are you there? */
590 write (adapt_desc, "\r", 1);
594 /* Clear any break points */
595 adapt_clear_breakpoints();
597 /* Determine the processor revision level */
598 prl = (unsigned int)read_register(CFG_REGNUM) >> 24;
600 processor_type = TYPE_A29000;
601 } else if ((prl&0xf0) == 0x40) { /* 29030 = 0x4* */
602 processor_type = TYPE_A29030;
603 fprintf_filtered(stderr,"WARNING: debugging of A29030 not tested.\n");
604 } else if ((prl&0xf0) == 0x20) { /* 29050 = 0x2* */
605 processor_type = TYPE_A29050;
606 fprintf_filtered(stderr,"WARNING: debugging of A29050 not tested.\n");
608 processor_type = TYPE_UNKNOWN;
609 fprintf_filtered(stderr,"WARNING: processor type unknown.\n");
612 /* Print out some stuff, letting the user now what's going on */
613 printf_filtered("Remote debugging on an %s connect to an Adapt via %s.\n",
614 processor_name[processor_type],dev_name);
615 /* FIXME: can this restriction be removed? */
616 printf_filtered("Remote debugging using virtual addresses works only\n");
617 printf_filtered("\twhen virtual addresses map 1:1 to physical addresses.\n");
618 if (processor_type != TYPE_A29050) {
619 fprintf_filtered(stderr,
620 "Freeze-mode debugging not available, and can only be done on an A29050.\n");
622 DEXIT("adapt_open()");
625 /* Close out all files and local state before this target loses control. */
628 adapt_close (quitting)
632 DENTER("adapt_close()");
634 /* Clear any break points */
635 adapt_clear_breakpoints();
637 /* Put this port back into REMOTE mode */
639 fflush(adapt_stream);
640 sleep(1); /* Let any output make it all the way back */
641 write(adapt_desc, "R\r", 2);
644 /* Due to a bug in Unix, fclose closes not only the stdio stream,
645 but also the file descriptor. So we don't actually close
648 fclose (adapt_stream); /* This also closes adapt_desc */
650 /* close (adapt_desc); */
652 /* Do not try to close adapt_desc again, later in the program. */
656 #if defined (LOG_FILE)
658 if (ferror (log_file))
659 printf_filtered ("Error writing log file.\n");
660 if (fclose (log_file) != 0)
661 printf_filtered ("Error closing log file.\n");
665 DEXIT("adapt_close()");
668 /* Attach to the target that is already loaded and possibly running */
670 adapt_attach (args, from_tty)
675 DENTER("adapt_attach()");
677 printf_filtered ("Attaching to remote program %s.\n", prog_name);
679 /* push_target(&adapt_ops); /* This done in adapt_open() */
681 mark_breakpoints_out ();
683 /* Send the adapt a kill. It is ok if it is not already running */
684 fprintf(adapt_stream, "K\r"); fflush(adapt_stream);
685 expect_prompt(); /* Slurp the echo */
687 /* We will get a task spawn event immediately. */
688 init_wait_for_inferior ();
689 clear_proceed_status ();
690 stop_soon_quietly = 1;
691 wait_for_inferior ();
692 stop_soon_quietly = 0;
694 DEXIT("adapt_attach()");
698 /* Terminate the open connection to the remote debugger.
699 Use this when you want to detach and do something else
702 adapt_detach (args,from_tty)
706 DENTER("adapt_detach()");
707 if (adapt_stream) { /* Send it on its way (tell it to continue) */
708 adapt_clear_breakpoints();
709 fprintf(adapt_stream,"G\r");
712 pop_target(); /* calls adapt_close to do the real work */
714 printf_filtered ("Ending remote %s debugging\n", target_shortname);
715 DEXIT("adapt_detach()");
718 /* Tell the remote machine to resume. */
721 adapt_resume (step, sig)
724 DENTER("adapt_resume()");
727 write (adapt_desc, "t 1,s\r", 6);
728 /* Wait for the echo. */
729 expect ("t 1,s\r\n");
730 /* Then comes a line containing the instruction we stepped to. */
732 /* Then we get the prompt. */
735 /* Force the next adapt_wait to return a trap. Not doing anything
736 about I/O from the target means that the user has to type
737 "continue" to see any. FIXME, this should be fixed. */
738 need_artificial_trap = 1;
742 write (adapt_desc, "G\r", 2);
743 /* Swallow the echo. */
746 DEXIT("adapt_resume()");
749 /* Wait until the remote machine stops, then return,
750 storing status in STATUS just as `wait' would. */
756 /* Strings to look for. '?' means match any single character.
757 Note that with the algorithm we use, the initial character
758 of the string cannot recur in the string, or we will not
759 find some cases of the string in the input. */
761 static char bpt[] = "@";
762 /* It would be tempting to look for "\n[__exit + 0x8]\n"
763 but that requires loading symbols with "yc i" and even if
764 we did do that we don't know that the file has symbols. */
765 static char exitmsg[] = "@????????I JMPTI GR121,LR0";
769 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
771 /* Current position in swallowed. */
772 char *swallowed_p = swallowed;
776 int old_timeout = timeout;
777 int old_immediate_quit = immediate_quit;
779 DENTER("adapt_wait()");
781 WSETEXIT ((*status), 0);
783 if (need_artificial_trap != 0)
785 WSETSTOP ((*status), SIGTRAP);
786 need_artificial_trap--;
790 timeout = 0; /* Don't time out -- user program is running. */
791 immediate_quit = 1; /* Helps ability to QUIT */
793 QUIT; /* Let user quit and leave process running */
805 if (ch == *ep || *ep == '?') {
817 /* Print out any characters which have been swallowed. */
818 for (p = swallowed; p < swallowed_p; ++p)
820 swallowed_p = swallowed;
826 WSETSTOP ((*status), SIGTRAP);
828 WSETEXIT ((*status), 0);
829 timeout = old_timeout;
830 immediate_quit = old_immediate_quit;
831 DEXIT("adapt_wait()");
835 /* Return the name of register number REGNO
836 in the form input and output by adapt.
838 Returns a pointer to a static buffer containing the answer. */
844 if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32 )
845 sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
846 #if defined(GR64_REGNUM)
847 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
848 sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64);
850 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
851 sprintf (buf, "LR%03d", regno - LR0_REGNUM);
852 else if (regno == Q_REGNUM)
853 strcpy (buf, "SR131");
854 else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
855 sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
856 else if (regno == ALU_REGNUM)
857 strcpy (buf, "SR132");
858 else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
859 sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
860 else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM) {
861 /* When a 29050 is in freeze-mode, read shadow pcs instead */
862 if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC)
863 sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20);
865 sprintf (buf, "SR%03d", regno - VAB_REGNUM);
867 else if (regno == GR1_REGNUM)
868 strcpy (buf, "GR001");
872 /* Read the remote registers. */
875 adapt_fetch_registers ()
883 DENTER("adapt_fetch_registers()");
888 #if defined(GR64_REGNUM)
889 write (adapt_desc, "dw gr64,gr95\r", 13);
890 for (reg_index = 64, regnum_index = GR64_REGNUM;
892 reg_index += 4, regnum_index += 4)
894 sprintf (tempbuf, "GR%03d ", reg_index);
896 get_hex_regs (4, regnum_index);
900 write (adapt_desc, "dw gr96,gr127\r", 14);
901 for (reg_index = 96, regnum_index = GR96_REGNUM;
903 reg_index += 4, regnum_index += 4)
905 sprintf (tempbuf, "GR%03d ", reg_index);
907 get_hex_regs (4, regnum_index);
914 for (i = 0; i < 128; i += 32)
916 /* The PC has a tendency to hang if we get these
917 all in one fell swoop ("dw lr0,lr127"). */
918 sprintf (tempbuf, "dw lr%d\r", i);
919 write (adapt_desc, tempbuf, strlen (tempbuf));
920 for (reg_index = i, regnum_index = LR0_REGNUM + i;
922 reg_index += 4, regnum_index += 4)
924 sprintf (tempbuf, "LR%03d ", reg_index);
926 get_hex_regs (4, regnum_index);
934 sprintf (tempbuf, "dw sr0\r");
935 write (adapt_desc, tempbuf, strlen (tempbuf));
936 for (i=0 ; i<4 ; i++) { /* SR0 - SR14 */
937 sprintf (tempbuf, "SR%3d",i*4);
939 for (j=0 ; j < (i==3 ? 3 : 4) ; j++)
940 sreg_buf[i*4 + j] = get_hex_word();
944 * Read the pcs individually if we are in freeze mode.
945 * See get_reg_name(), it translates the register names for the pcs to
946 * the names of the shadow pcs.
949 sreg_buf[10] = read_register(NPC_REGNUM); /* pc0 */
950 sreg_buf[11] = read_register(PC_REGNUM); /* pc1 */
951 sreg_buf[12] = read_register(PC2_REGNUM); /* pc2 */
953 for (i=0 ; i<14 ; i++) /* Supply vab -> lru */
954 supply_register(VAB_REGNUM+i,&sreg_buf[i]);
955 sprintf (tempbuf, "dw sr128\r");
956 write (adapt_desc, tempbuf, strlen (tempbuf));
957 for (i=0 ; i<2 ; i++) { /* SR128 - SR135 */
958 sprintf (tempbuf, "SR%3d",128 + i*4);
960 for (j=0 ; j<4 ; j++)
961 sreg_buf[i*4 + j] = get_hex_word();
964 supply_register(IPC_REGNUM,&sreg_buf[0]);
965 supply_register(IPA_REGNUM,&sreg_buf[1]);
966 supply_register(IPB_REGNUM,&sreg_buf[2]);
967 supply_register(Q_REGNUM, &sreg_buf[3]);
969 supply_register(BP_REGNUM, &sreg_buf[5]);
970 supply_register(FC_REGNUM, &sreg_buf[6]);
971 supply_register(CR_REGNUM, &sreg_buf[7]);
973 /* There doesn't seem to be any way to get these. */
976 supply_register (FPE_REGNUM, &val);
977 supply_register (INT_REGNUM, &val);
978 supply_register (FPS_REGNUM, &val);
979 supply_register (EXO_REGNUM, &val);
982 write (adapt_desc, "dw gr1,gr1\r", 11);
984 get_hex_regs (1, GR1_REGNUM);
987 DEXIT("adapt_fetch_registers()");
990 /* Fetch register REGNO, or all registers if REGNO is -1.
993 adapt_fetch_register (regno)
996 DENTER("adapt_fetch_register()");
998 adapt_fetch_registers ();
1001 char *name = get_reg_name (regno);
1002 fprintf (adapt_stream, "dw %s,%s\r", name, name);
1005 get_hex_regs (1, regno);
1008 DEXIT("adapt_fetch_register()");
1011 /* Store the remote registers from the contents of the block REGS. */
1014 adapt_store_registers ()
1018 DENTER("adapt_store_registers()");
1019 fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM));
1022 #if defined(GR64_REGNUM)
1023 for (j = 0; j < 32; j += 16)
1025 fprintf (adapt_stream, "s gr%d,", j + 64);
1026 for (i = 0; i < 15; ++i)
1027 fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i));
1028 fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15));
1032 for (j = 0; j < 32; j += 16)
1034 fprintf (adapt_stream, "s gr%d,", j + 96);
1035 for (i = 0; i < 15; ++i)
1036 fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i));
1037 fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15));
1041 for (j = 0; j < 128; j += 16)
1043 fprintf (adapt_stream, "s lr%d,", j);
1044 for (i = 0; i < 15; ++i)
1045 fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i));
1046 fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15));
1050 fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM),
1051 read_register (IPA_REGNUM), read_register (IPB_REGNUM));
1053 fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM),
1054 read_register (FC_REGNUM), read_register (CR_REGNUM));
1056 fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM));
1058 fprintf (adapt_stream, "s sr0,");
1059 for (i=0 ; i<7 ; ++i)
1060 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1062 fprintf (adapt_stream, "s sr7,");
1063 for (i=7; i<14 ; ++i)
1064 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1068 /* Store register REGNO, or all if REGNO == -1.
1069 Return errno value. */
1071 adapt_store_register (regno)
1074 /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1076 adapt_store_registers ();
1079 char *name = get_reg_name (regno);
1080 fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno));
1081 /* Setting GR1 changes the numbers of all the locals, so
1082 invalidate the register cache. Do this *after* calling
1083 read_register, because we want read_register to return the
1084 value that write_register has just stuffed into the registers
1085 array, not the value of the register fetched from the
1087 if (regno == GR1_REGNUM)
1088 registers_changed ();
1091 DEXIT("adapt_store_registers()");
1095 /* Get ready to modify the registers array. On machines which store
1096 individual registers, this doesn't need to do anything. On machines
1097 which store all the registers in one fell swoop, this makes sure
1098 that registers contains all the registers from the program being
1102 adapt_prepare_to_store ()
1104 /* Do nothing, since we can store individual regs */
1108 translate_addr(addr)
1111 #if defined(KERNEL_DEBUGGING)
1112 /* Check for a virtual address in the kernel */
1113 /* Assume physical address of ublock is in paddr_u register */
1114 if (addr >= UVADDR) {
1115 /* PADDR_U register holds the physical address of the ublock */
1116 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
1117 return(i + addr - (CORE_ADDR)UVADDR);
1127 /* FIXME! Merge these two. */
1129 adapt_xfer_inferior_memory (memaddr, myaddr, len, write)
1136 memaddr = translate_addr(memaddr);
1139 return adapt_write_inferior_memory (memaddr, myaddr, len);
1141 return adapt_read_inferior_memory (memaddr, myaddr, len);
1147 printf_filtered("\tAttached to %s at %d baud and running program %s\n",
1148 dev_name, baudrate, prog_name);
1149 printf_filtered("\ton an %s processor.\n", processor_name[processor_type]);
1152 /* Copy LEN bytes of data from debugger memory at MYADDR
1153 to inferior's memory at MEMADDR. Returns errno value.
1154 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1157 adapt_write_inferior_memory (memaddr, myaddr, len)
1165 /* DENTER("adapt_write_inferior_memory()"); */
1167 /* Turn TU bit off so we can do 'sb' commands */
1168 cps = read_register(CPS_REGNUM);
1169 if (cps & 0x00000800)
1170 write_register(CPS_REGNUM,cps&~(0x00000800));
1172 for (i = 0; i < len; i++)
1175 fprintf (adapt_stream, "sb %x,", memaddr + i);
1176 if ((i % 16) == 15 || i == len - 1)
1178 fprintf (adapt_stream, "%x\r", ((unsigned char *)myaddr)[i]);
1182 fprintf (adapt_stream, "%x,", ((unsigned char *)myaddr)[i]);
1184 /* Restore the old value of cps if the TU bit was on */
1185 if (cps & 0x00000800)
1186 write_register(CPS_REGNUM,cps);
1187 /* DEXIT("adapt_write_inferior_memory()"); */
1191 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1192 at debugger address MYADDR. Returns errno value. */
1194 adapt_read_inferior_memory(memaddr, myaddr, len)
1201 /* Number of bytes read so far. */
1204 /* Starting address of this pass. */
1205 unsigned long startaddr;
1207 /* Number of bytes to read in this pass. */
1210 /* Note that this code works correctly if startaddr is just less
1211 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1212 thing). That is, something like
1213 adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1214 works--it never adds len to memaddr and gets 0. */
1215 /* However, something like
1216 adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1217 doesn't need to work. Detect it and give up if there's an attempt
1219 /* DENTER("adapt_read_inferior_memory()"); */
1221 if (((memaddr - 1) + len) < memaddr)
1224 startaddr = memaddr;
1229 if ((startaddr % 16) != 0)
1230 len_this_pass -= startaddr % 16;
1231 if (len_this_pass > (len - count))
1232 len_this_pass = (len - count);
1234 fprintf (adapt_stream, "db %x,%x\r", startaddr,
1235 (startaddr - 1) + len_this_pass);
1237 #ifdef NOTDEF /* Why do this */
1239 /* Look for 8 hex digits. */
1243 if (isxdigit (readchar ()))
1248 error ("Hex digit expected from remote system.");
1257 for (i = 0; i < len_this_pass; i++)
1258 get_hex_byte (&myaddr[count++]);
1262 startaddr += len_this_pass;
1265 /* DEXIT("adapt_read_inferior_memory()"); */
1269 #define MAX_BREAKS 8
1270 static int num_brkpts=0;
1272 adapt_insert_breakpoint(addr, save)
1274 char *save; /* Throw away, let adapt save instructions */
1276 DENTER("adapt_insert_breakpoint()");
1277 if (num_brkpts < MAX_BREAKS) {
1279 fprintf (adapt_stream, "B %x", addr);
1280 fprintf (adapt_stream, "\r");
1282 DEXIT("adapt_insert_breakpoint() success");
1283 return(0); /* Success */
1285 fprintf_filtered(stderr,
1286 "Too many break points, break point not installed\n");
1287 DEXIT("adapt_insert_breakpoint() failure");
1288 return(1); /* Failure */
1293 adapt_remove_breakpoint(addr, save)
1295 char *save; /* Throw away, let adapt save instructions */
1297 DENTER("adapt_remove_breakpoint()");
1298 if (num_brkpts > 0) {
1300 fprintf (adapt_stream, "BR %x", addr);
1301 fprintf (adapt_stream, "\r");
1302 fflush (adapt_stream);
1305 DEXIT("adapt_remove_breakpoint()");
1309 /* Clear the adapts notion of what the break points are */
1311 adapt_clear_breakpoints()
1313 DENTER("adapt_clear_breakpoint()");
1315 fprintf (adapt_stream, "BR"); /* Clear all break points */
1316 fprintf (adapt_stream, "\r");
1317 fflush(adapt_stream);
1321 DEXIT("adapt_clear_breakpoint()");
1326 DENTER("adapt_mourn()");
1327 adapt_clear_breakpoints();
1328 pop_target (); /* Pop back to no-child state */
1329 generic_mourn_inferior ();
1330 DEXIT("adapt_mourn()");
1333 /* Display everthing we read in from the adapt until we match/see the
1342 while (c=readchar()) {
1345 if (i == strlen(str)) return;
1348 for (j=0 ; j<i ; j++) /* Put everthing we matched */
1359 /* Put a command string, in args, out to the adapt. The adapt is assumed to
1360 be in raw mode, all writing/reading done through adapt_desc.
1361 Ouput from the adapt is placed on the users terminal until the
1362 prompt from the adapt is seen.
1363 FIXME: Can't handle commands that take input. */
1366 adapt_com (args, fromtty)
1370 if (!adapt_stream) {
1371 printf_filtered("Adapt not open. Use the 'target' command to open.\n");
1375 /* Clear all input so only command relative output is displayed */
1378 switch(islower(args[0]) ? toupper(args[0]) : args[0]) {
1380 printf_filtered("Unknown/Unimplemented adapt command '%s'\n",args);
1382 case 'G': /* Go, begin execution */
1383 write(adapt_desc,args,strlen(args));
1384 write(adapt_desc,"\r",1);
1387 case 'B': /* Break points, B or BR */
1388 case 'C': /* Check current 29k status (running/halted) */
1389 case 'D': /* Display data/registers */
1390 case 'I': /* Input from i/o space */
1391 case 'J': /* Jam an instruction */
1392 case 'K': /* Kill, stop execution */
1393 case 'L': /* Disassemble */
1394 case 'O': /* Output to i/o space */
1395 case 'T': /* Trace */
1396 case 'P': /* Pulse an input line */
1397 case 'X': /* Examine special purpose registers */
1398 case 'Z': /* Display trace buffer */
1399 write(adapt_desc,args,strlen(args));
1400 write(adapt_desc,"\r",1);
1401 expect(args); /* Don't display the command */
1402 display_until("# ");
1404 /* Begin commands that take input in the form 'c x,y[,z...]' */
1405 case 'S': /* Set memory or register */
1406 if (index(args,',')) { /* Assume it is properly formatted */
1407 write(adapt_desc,args,strlen(args));
1408 write(adapt_desc,"\r",1);
1415 /* Define the target subroutine names */
1417 struct target_ops adapt_ops = {
1418 "adapt", "Remote AMD `Adapt' target",
1419 "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232",
1420 adapt_open, adapt_close,
1421 adapt_attach, adapt_detach, adapt_resume, adapt_wait,
1422 adapt_fetch_register, adapt_store_register,
1423 adapt_prepare_to_store, 0, 0, /* conv_to, conv_from */
1424 adapt_xfer_inferior_memory,
1426 adapt_insert_breakpoint, adapt_remove_breakpoint, /* Breakpoints */
1427 0, 0, 0, 0, 0, /* Terminal handling */
1428 adapt_kill, /* FIXME, kill */
1430 call_function_by_hand,
1431 0, /* lookup_symbol */
1432 adapt_create_inferior, /* create_inferior */
1433 adapt_mourn, /* mourn_inferior FIXME */
1434 process_stratum, 0, /* next */
1435 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1436 0,0, /* Section pointers */
1437 OPS_MAGIC, /* Always the last thing */
1441 _initialize_remote_adapt ()
1443 add_target (&adapt_ops);
1444 add_com ("adapt <command>", class_obscure, adapt_com,
1445 "Send a command to the AMD Adapt remote monitor.");