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