]> Git Repo - binutils.git/blob - gdb/remote-adapt.c
Break the thread of control that implies that a unix child
[binutils.git] / gdb / remote-adapt.c
1 /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18. 
2    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
3    Contributed by David Wood at New York University ([email protected]).
4    Adapted from work done at Cygnus Support in remote-eb.c.
5
6 This file is part of GDB.
7
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.
12
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.
17
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.  */
21
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 
25    running gdb. 
26
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.  */
31
32 #include "defs.h"
33 #include <string.h>
34 #include "inferior.h"
35 #include "wait.h"
36 #include "value.h"
37 #include <ctype.h>
38 #include <fcntl.h>
39 #include <signal.h>
40 #include <errno.h>
41 #include "terminal.h"
42 #include "target.h"
43 #include "gdbcore.h"
44
45 /* External data declarations */
46 extern int stop_soon_quietly;           /* for wait_for_inferior */
47
48 /* Forward data declarations */
49 extern struct target_ops adapt_ops;             /* Forward declaration */
50
51 /* Forward function declarations */
52 static void adapt_fetch_registers ();
53 static void adapt_store_registers ();
54 static void adapt_close ();
55 static int  adapt_clear_breakpoints();
56
57 /* 
58  * Processor types. It is assumed that the adapt has the correct 
59  * ROM for the given processor. 
60  */
61 #define TYPE_UNKNOWN    0
62 #define TYPE_A29000     1
63 #define TYPE_A29030     2
64 #define TYPE_A29050     3
65 static char *processor_name[] = { "Unknown", "A29000", "A29030", "A29050" };
66 static int processor_type=TYPE_UNKNOWN;
67
68 #define FREEZE_MODE     (read_register(CPS_REGNUM) && 0x400) 
69 #define USE_SHADOW_PC   ((processor_type == TYPE_A29050) && FREEZE_MODE)
70
71
72 /* #define DEBUG        /* */
73 #ifdef DEBUG
74 # define DENTER(NAME)   (printf_filtered("Entering %s\n",NAME), fflush(stdout))
75 # define DEXIT(NAME)    (printf_filtered("Exiting  %s\n",NAME), fflush(stdout))
76 #else
77 # define DENTER(NAME)
78 # define DEXIT(NAME)
79 #endif
80
81 /* Can't seem to get binary coff working */
82 #define ASCII_COFF              /* Adapt will be downloaded with ascii coff */
83
84 #define LOG_FILE "adapt.log"
85 #if defined (LOG_FILE)
86 FILE *log_file=NULL;
87 #endif
88
89 static int timeout = 5;
90 static char *dev_name;
91
92 /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
93    adapt_open knows that we don't have a file open when the program
94    starts.  */
95 int adapt_desc = -1;
96
97 /* stream which is fdopen'd from adapt_desc.  Only valid when
98    adapt_desc != -1.  */
99 FILE *adapt_stream;
100
101 #define ON      1
102 #define OFF     0
103 static void
104 rawmode(desc, turnon)
105 int     desc;
106 int     turnon;
107 {
108   TERMINAL sg;
109
110   if (desc < 0)
111     return;
112
113   ioctl (desc, TIOCGETP, &sg);
114
115   if (turnon) {
116 #ifdef HAVE_TERMIO
117         sg.c_lflag &= ~(ICANON);
118 #else
119         sg.sg_flags |= RAW;
120 #endif
121   } else {
122 #ifdef HAVE_TERMIO
123         sg.c_lflag |= ICANON;
124 #else
125         sg.sg_flags &= ~(RAW);
126 #endif
127   }
128   ioctl (desc, TIOCSETP, &sg);
129 }
130
131 /* Suck up all the input from the adapt */
132 slurp_input()
133 {
134   char buf[8];
135
136 #ifdef HAVE_TERMIO
137   /* termio does the timeout for us.  */
138   while (read (adapt_desc, buf, 8) > 0);
139 #else
140   alarm (timeout);
141   while (read (adapt_desc, buf, 8) > 0);
142   alarm (0);
143 #endif
144 }
145
146 /* Read a character from the remote system, doing all the fancy
147    timeout stuff.  */
148 static int
149 readchar ()
150 {
151   char buf;
152
153   buf = '\0';
154 #ifdef HAVE_TERMIO
155   /* termio does the timeout for us.  */
156   read (adapt_desc, &buf, 1);
157 #else
158   alarm (timeout);
159   if (read (adapt_desc, &buf, 1) < 0)
160     {
161       if (errno == EINTR)
162         error ("Timeout reading from remote system.");
163       else
164         perror_with_name ("remote");
165     }
166   alarm (0);
167 #endif
168
169   if (buf == '\0')
170     error ("Timeout reading from remote system.");
171 #if defined (LOG_FILE)
172   putc (buf & 0x7f, log_file);
173 #endif
174   return buf & 0x7f;
175 }
176
177 /* Keep discarding input from the remote system, until STRING is found. 
178    Let the user break out immediately.  */
179 static void
180 expect (string)
181      char *string;
182 {
183   char *p = string;
184
185   fflush(adapt_stream);
186   immediate_quit = 1;
187   while (1)
188     {
189       if (readchar() == *p)
190         {
191           p++;
192           if (*p == '\0')
193             {
194               immediate_quit = 0;
195               return;
196             }
197         }
198       else
199         p = string;
200     }
201 }
202
203 /* Keep discarding input until we see the adapt prompt.
204
205    The convention for dealing with the prompt is that you
206    o give your command
207    o *then* wait for the prompt.
208
209    Thus the last thing that a procedure does with the serial line
210    will be an expect_prompt().  Exception:  adapt_resume does not
211    wait for the prompt, because the terminal is being handed over
212    to the inferior.  However, the next thing which happens after that
213    is a adapt_wait which does wait for the prompt.
214    Note that this includes abnormal exit, e.g. error().  This is
215    necessary to prevent getting into states from which we can't
216    recover.  */
217 static void
218 expect_prompt ()
219 {
220 #if defined (LOG_FILE)
221   /* This is a convenient place to do this.  The idea is to do it often
222      enough that we never lose much data if we terminate abnormally.  */
223   fflush (log_file);
224 #endif
225   fflush(adapt_stream);
226   expect ("\n# ");
227 }
228
229 /* Get a hex digit from the remote system & return its value.
230    If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
231 static int
232 get_hex_digit (ignore_space)
233      int ignore_space;
234 {
235   int ch;
236   while (1)
237     {
238       ch = readchar ();
239       if (ch >= '0' && ch <= '9')
240         return ch - '0';
241       else if (ch >= 'A' && ch <= 'F')
242         return ch - 'A' + 10;
243       else if (ch >= 'a' && ch <= 'f')
244         return ch - 'a' + 10;
245       else if (ch == ' ' && ignore_space)
246         ;
247       else
248         {
249           expect_prompt ();
250           error ("Invalid hex digit from remote system.");
251         }
252     }
253 }
254
255 /* Get a byte from adapt_desc and put it in *BYT.  Accept any number
256    leading spaces.  */
257 static void
258 get_hex_byte (byt)
259      char *byt;
260 {
261   int val;
262
263   val = get_hex_digit (1) << 4;
264   val |= get_hex_digit (0);
265   *byt = val;
266 }
267
268 /* Read a 32-bit hex word from the adapt, preceded by a space  */
269 static long 
270 get_hex_word()
271 {
272   long val;
273   int j;
274       
275   val = 0;
276   for (j = 0; j < 8; j++)
277         val = (val << 4) + get_hex_digit (j == 0);
278   return val;
279 }
280 /* Get N 32-bit hex words from remote, each preceded by a space 
281    and put them in registers starting at REGNO.  */
282 static void
283 get_hex_regs (n, regno)
284      int n;
285      int regno;
286 {
287         long val;
288         while (n--) {
289                 val = get_hex_word();
290                 supply_register(regno++,&val);
291         }
292 }
293 /* Called when SIGALRM signal sent due to alarm() timeout.  */
294 #ifndef HAVE_TERMIO
295
296 #ifndef __STDC__
297 # ifndef volatile
298 #  define volatile /**/
299 # endif
300 #endif
301 volatile int n_alarms;
302
303 void
304 adapt_timer ()
305 {
306 #if 0
307   if (kiodebug)
308     printf ("adapt_timer called\n");
309 #endif
310   n_alarms++;
311 }
312 #endif
313
314 /* malloc'd name of the program on the remote system.  */
315 static char *prog_name = NULL;
316
317 /* Number of SIGTRAPs we need to simulate.  That is, the next
318    NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
319    SIGTRAP without actually waiting for anything.  */
320
321 static int need_artificial_trap = 0;
322
323 void
324 adapt_kill(arg,from_tty)
325 char    *arg;
326 int     from_tty;
327 {
328         DENTER("adapt_kill()");
329         fprintf (adapt_stream, "K");
330         fprintf (adapt_stream, "\r");
331         expect_prompt ();
332         DEXIT("adapt_kill()");
333 }
334 /*
335  * Download a file specified in 'args', to the adapt. 
336  * FIXME: Assumes the file to download is a binary coff file.
337  */
338 static void
339 adapt_load(args,fromtty)
340 char    *args;
341 int     fromtty;
342 {
343         FILE *fp;
344         int     n;
345         char    buffer[1024];
346         
347         DENTER("adapt_load()");
348         if (!adapt_stream) {
349                 printf_filtered("Adapt not open. Use 'target' command to open adapt\n");
350                 return;
351         }
352
353         /* OK, now read in the file.  Y=read, C=COFF, T=dTe port
354                 0=start address.  */
355
356 #ifdef ASCII_COFF       /* Ascii coff */
357         fprintf (adapt_stream, "YA T,0\r");
358         fflush(adapt_stream);   /* Just in case */
359         /* FIXME: should check args for only 1 argument */
360         sprintf(buffer,"cat %s | btoa > /tmp/#adapt-btoa",args);
361         system(buffer);
362         fp = fopen("/tmp/#adapt-btoa","r");
363         rawmode(adapt_desc,OFF);        
364         while (n=fread(buffer,1,1024,fp)) {
365                 do { n -= write(adapt_desc,buffer,n); } while (n>0);
366                 if (n<0) { perror("writing ascii coff"); break; }
367         }
368         fclose(fp);
369         rawmode(adapt_desc,ON); 
370         system("rm /tmp/#adapt-btoa");
371 #else   /* Binary coff - can't get it to work .*/
372         fprintf (adapt_stream, "YC T,0\r");
373         fflush(adapt_stream);   /* Just in case */
374         if (!(fp = fopen(args,"r"))) {
375                 printf_filtered("Can't open %s\n",args);
376                 return;
377         }
378         while (n=fread(buffer,1,512,fp)) {
379                 do { n -= write(adapt_desc,buffer,n); } while (n>0);
380                 if (n<0) { perror("writing ascii coff"); break; }
381         }
382         fclose(fp);
383 #endif
384         expect_prompt ();       /* Skip garbage that comes out */
385         fprintf (adapt_stream, "\r");
386         expect_prompt ();
387         DEXIT("adapt_load()");
388 }
389
390 /* This is called not only when we first attach, but also when the
391    user types "run" after having attached.  */
392 void
393 adapt_create_inferior (execfile, args, env)
394      char *execfile;
395      char *args;
396      char **env;
397 {
398   int entry_pt;
399
400   DENTER("adapt_create_inferior()");
401
402   if (args && *args)
403     error ("Can't pass arguments to remote adapt process.");
404
405   if (execfile == 0 || exec_bfd == 0)
406     error ("No exec file specified");
407
408   entry_pt = (int) bfd_get_start_address (exec_bfd);
409
410   if (adapt_stream) {
411         adapt_kill(NULL,NULL);   
412         adapt_clear_breakpoints();
413         init_wait_for_inferior ();
414         /* Clear the input because what the adapt sends back is different
415          * depending on whether it was running or not.
416          */
417         slurp_input();  /* After this there should be a prompt */
418         fprintf(adapt_stream,"\r"); 
419         expect_prompt();
420         printf_filtered("Do you want to download '%s' (y/n)? [y] : ",prog_name);
421         {       
422                 char buffer[10];
423                 gets(buffer);
424                 if (*buffer != 'n') {
425                         adapt_load(prog_name,0);
426                 }
427         }
428
429 #ifdef NOTDEF
430         /* Set the PC and wait for a go/cont */
431           fprintf (adapt_stream, "G %x,N\r",entry_pt);
432           printf_filtered("Now use the 'continue' command to start.\n"); 
433           expect_prompt ();
434 #else
435         insert_breakpoints ();  /* Needed to get correct instruction in cache */
436         proceed(entry_pt, -1, 0);
437 #endif
438
439   } else {
440         printf_filtered("Adapt not open yet.\n");
441   }
442   DEXIT("adapt_create_inferior()");
443 }
444
445 /* Translate baud rates from integers to damn B_codes.  Unix should
446    have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
447
448 #ifndef B19200
449 #define B19200 EXTA
450 #endif
451 #ifndef B38400
452 #define B38400 EXTB
453 #endif
454
455 static struct {int rate, damn_b;} baudtab[] = {
456         {0, B0},
457         {50, B50},
458         {75, B75},
459         {110, B110},
460         {134, B134},
461         {150, B150},
462         {200, B200},
463         {300, B300},
464         {600, B600},
465         {1200, B1200},
466         {1800, B1800},
467         {2400, B2400},
468         {4800, B4800},
469         {9600, B9600},
470         {19200, B19200},
471         {38400, B38400},
472         {-1, -1},
473 };
474
475 static int damn_b (rate)
476      int rate;
477 {
478   int i;
479
480   for (i = 0; baudtab[i].rate != -1; i++)
481     if (rate == baudtab[i].rate) return baudtab[i].damn_b;
482   return B38400;        /* Random */
483 }
484
485
486 /* Open a connection to a remote debugger.
487    NAME is the filename used for communication, then a space,
488    then the baud rate.
489  */
490
491 static int baudrate = 9600;
492 static void
493 adapt_open (name, from_tty)
494      char *name;
495      int from_tty;
496 {
497   TERMINAL sg;
498   unsigned int prl;
499   char *p;
500
501   DENTER("adapt_open()");
502   /* Find the first whitespace character, it separates dev_name from
503      prog_name.  */
504   if (name == 0)
505     goto erroid;
506
507   for (p = name;
508        *p != '\0' && !isspace (*p); p++)
509     ;
510   if (*p == '\0')
511 erroid:
512     error ("\
513 Please include the name of the device for the serial port,\n\
514 the baud rate, and the name of the program to run on the remote system.");
515   dev_name = (char*)malloc(p - name + 1);
516   strncpy (dev_name, name, p - name);
517   dev_name[p - name] = '\0';
518
519   /* Skip over the whitespace after dev_name */
520   for (; isspace (*p); p++)
521     /*EMPTY*/;
522   
523   if (1 != sscanf (p, "%d ", &baudrate))
524     goto erroid;
525
526   /* Skip the number and then the spaces */
527   for (; isdigit (*p); p++)
528     /*EMPTY*/;
529   for (; isspace (*p); p++)
530     /*EMPTY*/;
531   
532   if (prog_name != NULL)
533     free (prog_name);
534   prog_name = savestring (p, strlen (p));
535
536   adapt_close (0);
537
538   adapt_desc = open (dev_name, O_RDWR);
539   if (adapt_desc < 0)
540     perror_with_name (dev_name);
541   ioctl (adapt_desc, TIOCGETP, &sg);
542 #ifdef HAVE_TERMIO
543   sg.c_cc[VMIN] = 0;            /* read with timeout.  */
544   sg.c_cc[VTIME] = timeout * 10;
545   sg.c_lflag &= ~(ICANON | ECHO);
546   sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
547 #else
548   sg.sg_ispeed = damn_b (baudrate);
549   sg.sg_ospeed = damn_b (baudrate);
550   sg.sg_flags |= RAW | ANYP;
551   sg.sg_flags &= ~ECHO;
552 #endif
553
554   ioctl (adapt_desc, TIOCSETP, &sg);
555   adapt_stream = fdopen (adapt_desc, "r+");
556
557   push_target (&adapt_ops);
558   /* start_remote ();              /* Initialize gdb process mechanisms */
559
560
561 #ifndef HAVE_TERMIO
562 #ifndef NO_SIGINTERRUPT
563   /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
564      the read.  */
565   if (siginterrupt (SIGALRM, 1) != 0)
566     perror ("adapt_open: error in siginterrupt");
567 #endif
568
569   /* Set up read timeout timer.  */
570   if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1)
571     perror ("adapt_open: error in signal");
572 #endif
573
574 #if defined (LOG_FILE)
575   log_file = fopen (LOG_FILE, "w");
576   if (log_file == NULL)
577     perror_with_name (LOG_FILE);
578 #endif
579
580   /* Put this port into NORMAL mode, send the 'normal' character */
581   write(adapt_desc, "\ 1", 1);    /* Control A */
582   write(adapt_desc, "\r", 1);   
583   expect_prompt ();
584   
585   /* Hello?  Are you there?  */
586   write (adapt_desc, "\r", 1);
587  
588   expect_prompt ();
589
590   /* Clear any break points */
591   adapt_clear_breakpoints();
592
593   /* Determine the processor revision level */
594   prl = (unsigned int)read_register(CFG_REGNUM) >> 24;
595   if (prl == 0x03) { 
596         processor_type = TYPE_A29000;  
597   } else if ((prl&0xf0) == 0x40) {      /* 29030 = 0x4* */
598         processor_type = TYPE_A29030;  
599         fprintf_filtered(stderr,"WARNING: debugging of A29030 not tested.\n");
600   } else if ((prl&0xf0) == 0x20) {      /* 29050 = 0x2* */
601         processor_type = TYPE_A29050;  
602         fprintf_filtered(stderr,"WARNING: debugging of A29050 not tested.\n");
603   } else {
604         processor_type = TYPE_UNKNOWN;  
605         fprintf_filtered(stderr,"WARNING: processor type unknown.\n");
606   }
607
608   /* Print out some stuff, letting the user now what's going on */
609   printf_filtered("Remote debugging on an %s connect to an Adapt via %s.\n",
610                 processor_name[processor_type],dev_name);
611     /* FIXME: can this restriction be removed? */
612   printf_filtered("Remote debugging using virtual addresses works only\n");
613   printf_filtered("\twhen virtual addresses map 1:1 to physical addresses.\n"); 
614   if (processor_type != TYPE_A29050) {
615         fprintf_filtered(stderr,
616         "Freeze-mode debugging not available, and can only be done on an A29050.\n");
617   }
618   DEXIT("adapt_open()");
619 }
620
621 /* Close out all files and local state before this target loses control. */
622
623 static void
624 adapt_close (quitting)
625      int quitting;
626 {
627
628   DENTER("adapt_close()");
629
630   /* Clear any break points */
631   adapt_clear_breakpoints();
632
633   /* Put this port back into REMOTE mode */ 
634   if (adapt_stream) {
635      fflush(adapt_stream);
636      sleep(1);          /* Let any output make it all the way back */
637      write(adapt_desc, "R\r", 2);
638   }
639
640   /* Due to a bug in Unix, fclose closes not only the stdio stream,
641      but also the file descriptor.  So we don't actually close
642      adapt_desc.  */
643   if (adapt_stream)
644     fclose (adapt_stream);      /* This also closes adapt_desc */
645   if (adapt_desc >= 0)
646     /* close (adapt_desc); */
647
648   /* Do not try to close adapt_desc again, later in the program.  */
649   adapt_stream = NULL;
650   adapt_desc = -1;
651
652 #if defined (LOG_FILE)
653   if (log_file) {
654     if (ferror (log_file))
655       printf_filtered ("Error writing log file.\n");
656     if (fclose (log_file) != 0)
657       printf_filtered ("Error closing log file.\n");
658     log_file = NULL;
659   }
660 #endif
661   DEXIT("adapt_close()");
662 }
663
664 /* Attach to the target that is already loaded and possibly running */
665 static void
666 adapt_attach (args, from_tty)
667      char *args;
668      int from_tty;
669 {
670
671   DENTER("adapt_attach()");
672   if (from_tty)
673       printf_filtered ("Attaching to remote program %s.\n", prog_name);
674
675   /* push_target(&adapt_ops);   /* This done in adapt_open() */
676
677   mark_breakpoints_out ();
678
679   /* Send the adapt a kill. It is ok if it is not already running */
680   fprintf(adapt_stream, "K\r"); fflush(adapt_stream);
681   expect_prompt();              /* Slurp the echo */
682
683   /* We will get a task spawn event immediately.  */
684   init_wait_for_inferior ();
685   clear_proceed_status ();
686   stop_soon_quietly = 1;
687   wait_for_inferior ();
688   stop_soon_quietly = 0;
689   normal_stop ();
690   DEXIT("adapt_attach()");
691 }
692
693
694 /* Terminate the open connection to the remote debugger.
695    Use this when you want to detach and do something else
696    with your gdb.  */
697 void
698 adapt_detach (args,from_tty)
699      char *args;
700      int from_tty;
701 {
702   DENTER("adapt_detach()");
703   if (adapt_stream) { /* Send it on its way (tell it to continue)  */
704         adapt_clear_breakpoints();
705         fprintf(adapt_stream,"G\r");
706   }
707  
708   pop_target();         /* calls adapt_close to do the real work */
709   if (from_tty)
710     printf_filtered ("Ending remote %s debugging\n", target_shortname);
711   DEXIT("adapt_detach()");
712 }
713  
714 /* Tell the remote machine to resume.  */
715
716 void
717 adapt_resume (step, sig)
718      int step, sig;
719 {
720   DENTER("adapt_resume()");
721   if (step)     
722     {
723       write (adapt_desc, "t 1,s\r", 6);
724       /* Wait for the echo.  */
725       expect ("t 1,s\r\n");
726       /* Then comes a line containing the instruction we stepped to.  */
727       expect ("@");
728       /* Then we get the prompt.  */
729       expect_prompt ();
730
731       /* Force the next adapt_wait to return a trap.  Not doing anything
732          about I/O from the target means that the user has to type
733          "continue" to see any.  FIXME, this should be fixed.  */
734       need_artificial_trap = 1;
735     }
736   else
737     {
738       write (adapt_desc, "G\r", 2);
739       /* Swallow the echo.  */
740       expect_prompt(); 
741     }
742   DEXIT("adapt_resume()");
743 }
744
745 /* Wait until the remote machine stops, then return,
746    storing status in STATUS just as `wait' would.  */
747
748 int
749 adapt_wait (status)
750      WAITTYPE *status;
751 {
752   /* Strings to look for.  '?' means match any single character.  
753      Note that with the algorithm we use, the initial character
754      of the string cannot recur in the string, or we will not
755      find some cases of the string in the input.  */
756   
757   static char bpt[] = "@";
758   /* It would be tempting to look for "\n[__exit + 0x8]\n"
759      but that requires loading symbols with "yc i" and even if
760      we did do that we don't know that the file has symbols.  */
761   static char exitmsg[] = "@????????I    JMPTI     GR121,LR0";
762   char *bp = bpt;
763   char *ep = exitmsg;
764
765   /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars.  */
766   char swallowed[50];
767   /* Current position in swallowed.  */
768   char *swallowed_p = swallowed;
769
770   int ch;
771   int ch_handled;
772   int old_timeout = timeout;
773   int old_immediate_quit = immediate_quit;
774
775   DENTER("adapt_wait()");
776
777   WSETEXIT ((*status), 0);
778
779   if (need_artificial_trap != 0)
780     {
781       WSETSTOP ((*status), SIGTRAP);
782       need_artificial_trap--;
783       return 0;
784     }
785
786   timeout = 0;          /* Don't time out -- user program is running. */
787   immediate_quit = 1;   /* Helps ability to QUIT */
788   while (1) {
789       QUIT;             /* Let user quit and leave process running */
790       ch_handled = 0;
791       ch = readchar ();
792       if (ch == *bp) {
793           bp++;
794           if (*bp == '\0')
795             break;
796           ch_handled = 1;
797
798           *swallowed_p++ = ch;
799       } else
800         bp = bpt;
801       if (ch == *ep || *ep == '?') {
802           ep++;
803           if (*ep == '\0')
804             break;
805
806           if (!ch_handled)
807             *swallowed_p++ = ch;
808           ch_handled = 1;
809       } else
810         ep = exitmsg;
811       if (!ch_handled) {
812           char *p;
813           /* Print out any characters which have been swallowed.  */
814           for (p = swallowed; p < swallowed_p; ++p)
815             putc (*p, stdout);
816           swallowed_p = swallowed;
817           putc (ch, stdout);
818       }
819   }
820   expect_prompt ();
821   if (*bp== '\0')
822     WSETSTOP ((*status), SIGTRAP);
823   else
824     WSETEXIT ((*status), 0);
825   timeout = old_timeout;
826   immediate_quit = old_immediate_quit;
827   DEXIT("adapt_wait()");
828   return 0;
829 }
830
831 /* Return the name of register number REGNO
832    in the form input and output by adapt.
833
834    Returns a pointer to a static buffer containing the answer.  */
835 static char *
836 get_reg_name (regno)
837      int regno;
838 {
839   static char buf[80];
840   if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32 )
841     sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
842 #if defined(GR64_REGNUM)
843   else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
844     sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64);
845 #endif
846   else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
847     sprintf (buf, "LR%03d", regno - LR0_REGNUM);
848   else if (regno == Q_REGNUM) 
849     strcpy (buf, "SR131");
850   else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
851     sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
852   else if (regno == ALU_REGNUM)
853     strcpy (buf, "SR132");
854   else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
855     sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
856   else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM) {
857     /* When a 29050 is in freeze-mode, read shadow pcs instead */
858     if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC)
859         sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20);
860     else
861         sprintf (buf, "SR%03d", regno - VAB_REGNUM);
862   }
863   else if (regno == GR1_REGNUM)
864     strcpy (buf, "GR001");
865   return buf;
866 }
867
868 /* Read the remote registers.  */
869
870 static void
871 adapt_fetch_registers ()
872 {
873   int reg_index;
874   int regnum_index;
875   char tempbuf[10];
876   int   sreg_buf[16];
877   int i,j;
878
879   DENTER("adapt_fetch_registers()");
880
881 /* 
882  * Global registers
883  */
884 #if defined(GR64_REGNUM)
885   write (adapt_desc, "dw gr64,gr95\r", 13);
886   for (reg_index = 64, regnum_index = GR64_REGNUM;
887        reg_index < 96;
888        reg_index += 4, regnum_index += 4)
889     {
890       sprintf (tempbuf, "GR%03d ", reg_index);
891       expect (tempbuf);
892       get_hex_regs (4, regnum_index);
893       expect ("\n");
894     }
895 #endif
896   write (adapt_desc, "dw gr96,gr127\r", 14);
897   for (reg_index = 96, regnum_index = GR96_REGNUM;
898        reg_index < 128;
899        reg_index += 4, regnum_index += 4)
900     {
901       sprintf (tempbuf, "GR%03d ", reg_index);
902       expect (tempbuf);
903       get_hex_regs (4, regnum_index);
904       expect ("\n");
905     }
906
907 /* 
908  * Local registers
909  */
910   for (i = 0; i < 128; i += 32)
911     {
912       /* The PC has a tendency to hang if we get these
913          all in one fell swoop ("dw lr0,lr127").  */
914       sprintf (tempbuf, "dw lr%d\r", i);
915       write (adapt_desc, tempbuf, strlen (tempbuf));
916       for (reg_index = i, regnum_index = LR0_REGNUM + i;
917            reg_index < i + 32;
918            reg_index += 4, regnum_index += 4)
919         {
920           sprintf (tempbuf, "LR%03d ", reg_index);
921           expect (tempbuf);
922           get_hex_regs (4, regnum_index);
923           expect ("\n");
924         }
925     }
926
927 /* 
928  * Special registers
929  */
930   sprintf (tempbuf, "dw sr0\r");
931   write (adapt_desc, tempbuf, strlen (tempbuf));
932   for (i=0 ; i<4 ; i++) {                       /* SR0 - SR14 */
933         sprintf (tempbuf, "SR%3d",i*4);
934         expect(tempbuf);
935         for (j=0 ; j < (i==3 ? 3 : 4) ; j++)
936                 sreg_buf[i*4 + j] = get_hex_word();
937   }             
938   expect_prompt();
939   /* 
940    * Read the pcs individually if we are in freeze mode.
941    * See get_reg_name(), it translates the register names for the pcs to
942    * the names of the shadow pcs.
943    */ 
944   if (USE_SHADOW_PC)  {
945           sreg_buf[10] = read_register(NPC_REGNUM);     /* pc0 */
946           sreg_buf[11] = read_register(PC_REGNUM);      /* pc1 */
947           sreg_buf[12] = read_register(PC2_REGNUM);     /* pc2 */
948   }
949   for (i=0 ; i<14 ; i++)                /* Supply vab -> lru */
950         supply_register(VAB_REGNUM+i,&sreg_buf[i]);
951   sprintf (tempbuf, "dw sr128\r");
952   write (adapt_desc, tempbuf, strlen (tempbuf));
953   for (i=0 ; i<2 ; i++) {                       /* SR128 - SR135 */
954         sprintf (tempbuf, "SR%3d",128 + i*4);
955         expect(tempbuf);
956         for (j=0 ; j<4 ; j++)
957                 sreg_buf[i*4 + j] = get_hex_word();
958   }             
959   expect_prompt();
960   supply_register(IPC_REGNUM,&sreg_buf[0]);
961   supply_register(IPA_REGNUM,&sreg_buf[1]);
962   supply_register(IPB_REGNUM,&sreg_buf[2]);
963   supply_register(Q_REGNUM,  &sreg_buf[3]);
964                 /* Skip ALU */
965   supply_register(BP_REGNUM, &sreg_buf[5]);
966   supply_register(FC_REGNUM, &sreg_buf[6]);
967   supply_register(CR_REGNUM, &sreg_buf[7]);
968
969   /* There doesn't seem to be any way to get these.  */
970   {
971     int val = -1;
972     supply_register (FPE_REGNUM, &val);
973     supply_register (INTE_REGNUM, &val);
974     supply_register (FPS_REGNUM, &val);
975     supply_register (EXO_REGNUM, &val);
976   }
977
978   write (adapt_desc, "dw gr1,gr1\r", 11);
979   expect ("GR001 ");
980   get_hex_regs (1, GR1_REGNUM);
981   expect_prompt ();
982
983   DEXIT("adapt_fetch_registers()");
984 }
985
986 /* Fetch register REGNO, or all registers if REGNO is -1.
987  */
988 static void
989 adapt_fetch_register (regno)
990      int regno;
991 {
992   DENTER("adapt_fetch_register()");
993   if (regno == -1)
994     adapt_fetch_registers ();
995   else
996     {
997       char *name = get_reg_name (regno);
998       fprintf (adapt_stream, "dw %s,%s\r", name, name);
999       expect (name);
1000       expect (" ");
1001       get_hex_regs (1, regno);
1002       expect_prompt ();
1003     }
1004   DEXIT("adapt_fetch_register()");
1005 }
1006
1007 /* Store the remote registers from the contents of the block REGS.  */
1008
1009 static void
1010 adapt_store_registers ()
1011 {
1012   int i, j;
1013
1014   DENTER("adapt_store_registers()");
1015   fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM));
1016   expect_prompt ();
1017
1018 #if defined(GR64_REGNUM)
1019   for (j = 0; j < 32; j += 16)
1020     {
1021       fprintf (adapt_stream, "s gr%d,", j + 64);
1022       for (i = 0; i < 15; ++i) 
1023         fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i));
1024       fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15));
1025       expect_prompt ();
1026     }
1027 #endif
1028   for (j = 0; j < 32; j += 16)
1029     {
1030       fprintf (adapt_stream, "s gr%d,", j + 96);
1031       for (i = 0; i < 15; ++i) 
1032         fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i));
1033       fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15));
1034       expect_prompt ();
1035     }
1036
1037   for (j = 0; j < 128; j += 16)
1038     {
1039       fprintf (adapt_stream, "s lr%d,", j);
1040       for (i = 0; i < 15; ++i) 
1041         fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i));
1042       fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15));
1043       expect_prompt ();
1044     }
1045
1046   fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM),
1047            read_register (IPA_REGNUM), read_register (IPB_REGNUM));
1048   expect_prompt ();
1049   fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM),
1050            read_register (FC_REGNUM), read_register (CR_REGNUM));
1051   expect_prompt ();
1052   fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM));
1053   expect_prompt ();
1054   fprintf (adapt_stream, "s sr0,");
1055   for (i=0 ; i<7 ; ++i)
1056     fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1057   expect_prompt ();
1058   fprintf (adapt_stream, "s sr7,");
1059   for (i=7; i<14 ; ++i)
1060     fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1061   expect_prompt ();
1062 }
1063
1064 /* Store register REGNO, or all if REGNO == -1.
1065    Return errno value.  */
1066 void
1067 adapt_store_register (regno)
1068      int regno;
1069 {
1070   /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1071   if (regno == -1)
1072     adapt_store_registers ();
1073   else
1074     {
1075       char *name = get_reg_name (regno);
1076       fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno));
1077       /* Setting GR1 changes the numbers of all the locals, so
1078          invalidate the register cache.  Do this *after* calling
1079          read_register, because we want read_register to return the
1080          value that write_register has just stuffed into the registers
1081          array, not the value of the register fetched from the
1082          inferior.  */
1083       if (regno == GR1_REGNUM)
1084         registers_changed ();
1085       expect_prompt ();
1086     }
1087   DEXIT("adapt_store_registers()");
1088 }
1089
1090 /* Get ready to modify the registers array.  On machines which store
1091    individual registers, this doesn't need to do anything.  On machines
1092    which store all the registers in one fell swoop, this makes sure
1093    that registers contains all the registers from the program being
1094    debugged.  */
1095
1096 void
1097 adapt_prepare_to_store ()
1098 {
1099   /* Do nothing, since we can store individual regs */
1100 }
1101
1102 static CORE_ADDR 
1103 translate_addr(addr)
1104 CORE_ADDR addr;
1105 {
1106 #if defined(KERNEL_DEBUGGING)
1107         /* Check for a virtual address in the kernel */
1108         /* Assume physical address of ublock is in  paddr_u register */
1109         if (addr >= UVADDR) {
1110                 /* PADDR_U register holds the physical address of the ublock */
1111                 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM); 
1112                 return(i + addr - (CORE_ADDR)UVADDR);
1113         } else {
1114                 return(addr);
1115         }
1116 #else
1117         return(addr);
1118 #endif
1119 }
1120
1121
1122 /* FIXME!  Merge these two.  */
1123 int
1124 adapt_xfer_inferior_memory (memaddr, myaddr, len, write)
1125      CORE_ADDR memaddr;
1126      char *myaddr;
1127      int len;
1128      int write;
1129 {
1130
1131   memaddr = translate_addr(memaddr);
1132
1133   if (write)
1134     return adapt_write_inferior_memory (memaddr, myaddr, len);
1135   else
1136     return adapt_read_inferior_memory (memaddr, myaddr, len);
1137 }
1138
1139 void
1140 adapt_files_info ()
1141 {
1142   printf_filtered("\tAttached to %s at %d baud and running program %s\n",
1143           dev_name, baudrate, prog_name);
1144   printf_filtered("\ton an %s processor.\n", processor_name[processor_type]);
1145 }
1146
1147 /* Copy LEN bytes of data from debugger memory at MYADDR
1148    to inferior's memory at MEMADDR.  Returns errno value.  
1149  * sb/sh instructions don't work on unaligned addresses, when TU=1. 
1150  */
1151 int
1152 adapt_write_inferior_memory (memaddr, myaddr, len)
1153      CORE_ADDR memaddr;
1154      char *myaddr;
1155      int len;
1156 {
1157   int i;
1158   unsigned int cps;
1159
1160   /* DENTER("adapt_write_inferior_memory()"); */
1161
1162 /* Turn TU bit off so we can do 'sb' commands */
1163   cps = read_register(CPS_REGNUM);
1164   if (cps & 0x00000800)
1165         write_register(CPS_REGNUM,cps&~(0x00000800));
1166
1167   for (i = 0; i < len; i++)
1168     {
1169       if ((i % 16) == 0)
1170         fprintf (adapt_stream, "sb %x,", memaddr + i);
1171       if ((i % 16) == 15 || i == len - 1)
1172         {
1173           fprintf (adapt_stream, "%x\r", ((unsigned char *)myaddr)[i]);
1174           expect_prompt ();
1175         }
1176       else
1177         fprintf (adapt_stream, "%x,", ((unsigned char *)myaddr)[i]);
1178     }
1179   /* Restore the old value of cps if the TU bit was on */
1180   if (cps & 0x00000800)
1181         write_register(CPS_REGNUM,cps);
1182   /* DEXIT("adapt_write_inferior_memory()"); */
1183   return len;
1184 }
1185
1186 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
1187    at debugger address MYADDR.  Returns errno value.  */
1188 int
1189 adapt_read_inferior_memory(memaddr, myaddr, len)
1190      CORE_ADDR memaddr;
1191      char *myaddr;
1192      int len;
1193 {
1194   int i;
1195
1196   /* Number of bytes read so far.  */
1197   int count;
1198
1199   /* Starting address of this pass.  */
1200   unsigned long startaddr;
1201
1202   /* Number of bytes to read in this pass.  */
1203   int len_this_pass;
1204
1205   /* Note that this code works correctly if startaddr is just less
1206      than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1207      thing).  That is, something like
1208      adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1209      works--it never adds len to memaddr and gets 0.  */
1210   /* However, something like
1211      adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1212      doesn't need to work.  Detect it and give up if there's an attempt
1213      to do that.  */
1214   /* DENTER("adapt_read_inferior_memory()"); */
1215
1216   if (((memaddr - 1) + len) < memaddr)
1217     return EIO;
1218   
1219   startaddr = memaddr;
1220   count = 0;
1221   while (count < len)
1222     {
1223       len_this_pass = 16;
1224       if ((startaddr % 16) != 0)
1225         len_this_pass -= startaddr % 16;
1226       if (len_this_pass > (len - count))
1227         len_this_pass = (len - count);
1228
1229       fprintf (adapt_stream, "db %x,%x\r", startaddr,
1230                (startaddr - 1) + len_this_pass);
1231
1232 #ifdef NOTDEF   /* Why do this */
1233       expect ("\n");
1234       /* Look for 8 hex digits.  */
1235       i = 0;
1236       while (1)
1237         {
1238           if (isxdigit (readchar ()))
1239             ++i;
1240           else
1241             {
1242               expect_prompt ();
1243               error ("Hex digit expected from remote system.");
1244             }
1245           if (i >= 8)
1246             break;
1247         }
1248 #endif /* NOTDEF */
1249
1250       expect ("  ");
1251
1252       for (i = 0; i < len_this_pass; i++)
1253         get_hex_byte (&myaddr[count++]);
1254
1255       expect_prompt ();
1256
1257       startaddr += len_this_pass;
1258     }
1259
1260   /* DEXIT("adapt_read_inferior_memory()"); */
1261   return count;
1262 }
1263
1264 #define MAX_BREAKS      8
1265 static int num_brkpts=0;
1266 static int
1267 adapt_insert_breakpoint(addr, save)
1268 CORE_ADDR       addr;
1269 char            *save;  /* Throw away, let adapt save instructions */
1270 {
1271   DENTER("adapt_insert_breakpoint()"); 
1272   if (num_brkpts < MAX_BREAKS) {
1273         num_brkpts++;
1274         fprintf (adapt_stream, "B %x", addr);
1275         fprintf (adapt_stream, "\r");
1276         expect_prompt ();
1277         DEXIT("adapt_insert_breakpoint() success"); 
1278         return(0);      /* Success */
1279   } else {
1280         fprintf_filtered(stderr,
1281                 "Too many break points, break point not installed\n");
1282         DEXIT("adapt_insert_breakpoint() failure"); 
1283         return(1);      /* Failure */
1284   }
1285
1286 }
1287 static int
1288 adapt_remove_breakpoint(addr, save)
1289 CORE_ADDR       addr;
1290 char            *save;  /* Throw away, let adapt save instructions */
1291 {
1292   DENTER("adapt_remove_breakpoint()");
1293   if (num_brkpts > 0) {
1294           num_brkpts--;
1295           fprintf (adapt_stream, "BR %x", addr);
1296           fprintf (adapt_stream, "\r");
1297           fflush (adapt_stream);
1298           expect_prompt ();
1299   }
1300   DEXIT("adapt_remove_breakpoint()");
1301   return(0);
1302 }
1303
1304 /* Clear the adapts notion of what the break points are */
1305 static int
1306 adapt_clear_breakpoints() 
1307
1308   DENTER("adapt_clear_breakpoint()");
1309   if (adapt_stream) {
1310         fprintf (adapt_stream, "BR");   /* Clear all break points */
1311         fprintf (adapt_stream, "\r");
1312         fflush(adapt_stream);
1313         expect_prompt ();
1314   }
1315   num_brkpts = 0;
1316   DEXIT("adapt_clear_breakpoint()");
1317 }
1318 static void
1319 adapt_mourn() 
1320
1321   DENTER("adapt_mourn()");
1322   adapt_clear_breakpoints();
1323   pop_target ();                /* Pop back to no-child state */
1324   generic_mourn_inferior ();
1325   DEXIT("adapt_mourn()");
1326 }
1327
1328 /* Display everthing we read in from the adapt until we match/see the
1329  * specified string
1330  */
1331 static int
1332 display_until(str)
1333 char    *str;
1334 {
1335         int     i=0,j,c;
1336
1337         while (c=readchar()) {
1338                 if (c==str[i]) {
1339                         i++;
1340                         if (i == strlen(str)) return;
1341                 } else {
1342                         if (i) {
1343                             for (j=0 ; j<i ; j++) /* Put everthing we matched */
1344                                 putchar(str[j]);
1345                             i=0;
1346                         }
1347                         putchar(c);
1348                 }       
1349         }
1350
1351 }
1352
1353
1354 /* Put a command string, in args, out to the adapt.  The adapt is assumed to
1355    be in raw mode, all writing/reading done through adapt_desc.
1356    Ouput from the adapt is placed on the users terminal until the
1357    prompt from the adapt is seen.
1358    FIXME: Can't handle commands that take input.  */
1359
1360 void
1361 adapt_com (args, fromtty)
1362      char       *args;
1363      int        fromtty;
1364 {
1365         if (!adapt_stream) {
1366                 printf_filtered("Adapt not open.  Use the 'target' command to open.\n");
1367                 return;
1368         }
1369
1370         /* Clear all input so only command relative output is displayed */
1371         slurp_input();  
1372
1373         switch(islower(args[0]) ? toupper(args[0]) : args[0]) {
1374         default:
1375                 printf_filtered("Unknown/Unimplemented adapt command '%s'\n",args);
1376                 break;
1377         case 'G':       /* Go, begin execution */
1378                 write(adapt_desc,args,strlen(args));
1379                 write(adapt_desc,"\r",1);
1380                 expect_prompt();
1381                 break;
1382         case 'B':       /* Break points, B or BR */
1383         case 'C':       /* Check current 29k status (running/halted) */
1384         case 'D':       /* Display data/registers */ 
1385         case 'I':       /* Input from i/o space */
1386         case 'J':       /* Jam an instruction */
1387         case 'K':       /* Kill, stop execution */
1388         case 'L':       /* Disassemble */
1389         case 'O':       /* Output to i/o space */
1390         case 'T':       /* Trace */ 
1391         case 'P':       /* Pulse an input line */ 
1392         case 'X':       /* Examine special purpose registers */ 
1393         case 'Z':       /* Display trace buffer */ 
1394                 write(adapt_desc,args,strlen(args));
1395                 write(adapt_desc,"\r",1);
1396                 expect(args);           /* Don't display the command */
1397                 display_until("# ");
1398                 break;
1399         /* Begin commands that take input in the form 'c x,y[,z...]' */
1400         case 'S':       /* Set memory or register */
1401                 if (index(args,',')) {  /* Assume it is properly formatted */
1402                         write(adapt_desc,args,strlen(args));
1403                         write(adapt_desc,"\r",1);
1404                         expect_prompt();
1405                 }
1406                 break;
1407         }
1408 }
1409
1410 /* Define the target subroutine names */
1411
1412 struct target_ops adapt_ops = {
1413         "adapt", "Remote AMD `Adapt' target",
1414         "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232",
1415         adapt_open, adapt_close, 
1416         adapt_attach, adapt_detach, adapt_resume, adapt_wait,
1417         adapt_fetch_register, adapt_store_register,
1418         adapt_prepare_to_store,
1419         adapt_xfer_inferior_memory, 
1420         adapt_files_info,
1421         adapt_insert_breakpoint, adapt_remove_breakpoint, /* Breakpoints */
1422         0, 0, 0, 0, 0,          /* Terminal handling */
1423         adapt_kill,             /* FIXME, kill */
1424         adapt_load, 
1425         0,                      /* lookup_symbol */
1426         adapt_create_inferior,  /* create_inferior */ 
1427         adapt_mourn,            /* mourn_inferior FIXME */
1428         0, /* can_run */
1429         process_stratum, 0, /* next */
1430         1, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
1431         0,0,            /* Section pointers */
1432         OPS_MAGIC,              /* Always the last thing */
1433 };
1434
1435 void
1436 _initialize_remote_adapt ()
1437 {
1438   add_target (&adapt_ops);
1439   add_com ("adapt <command>", class_obscure, adapt_com,
1440         "Send a command to the AMD Adapt remote monitor.");
1441 }
This page took 0.104144 seconds and 4 git commands to generate.