Add Adobe a.out support.
[deliverable/binutils-gdb.git] / gdb / remote-adapt.c
CommitLineData
7c18a68f 1/* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18.
e17960fb 2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
7c18a68f
JG
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
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, 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
7c18a68f 32#include "defs.h"
d747e0af 33#include <string.h>
7c18a68f
JG
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 */
46extern int stop_soon_quietly; /* for wait_for_inferior */
47
7c18a68f
JG
48/* Forward data declarations */
49extern struct target_ops adapt_ops; /* Forward declaration */
50
51/* Forward function declarations */
52static void adapt_fetch_registers ();
e95bfbf1 53static void adapt_store_registers ();
15f27b29 54static void adapt_close ();
e36ca74a 55static int adapt_clear_breakpoints();
7c18a68f
JG
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
65static char *processor_name[] = { "Unknown", "A29000", "A29030", "A29050" };
66static 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)
86FILE *log_file=NULL;
87#endif
88
89static int timeout = 5;
90static 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. */
95int adapt_desc = -1;
96
97/* stream which is fdopen'd from adapt_desc. Only valid when
98 adapt_desc != -1. */
99FILE *adapt_stream;
100
101#define ON 1
102#define OFF 0
103static void
104rawmode(desc, turnon)
105int desc;
106int 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 */
132slurp_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. */
148static int
149readchar ()
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. */
179static void
180expect (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. */
217static void
218expect_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). */
231static int
232get_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. */
257static void
258get_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 */
269static long
270get_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. */
282static void
283get_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
301volatile int n_alarms;
302
303void
304adapt_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. */
315static 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
321static int need_artificial_trap = 0;
322
323void
324adapt_kill(arg,from_tty)
325char *arg;
326int 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 */
338static void
339adapt_load(args,fromtty)
340char *args;
341int 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. */
392void
393adapt_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
455static 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
475static 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
491static int baudrate = 9600;
492static void
493adapt_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')
511erroid:
512 error ("\
513Please include the name of the device for the serial port,\n\
514the 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
623static void
624adapt_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 */
665static void
666adapt_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. */
697void
698adapt_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
716void
717adapt_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
748int
749adapt_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. */
835static char *
836get_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
870static void
871adapt_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);
e95bfbf1 973 supply_register (INTE_REGNUM, &val);
7c18a68f
JG
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 */
988static void
989adapt_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
e95bfbf1 1009static void
7c18a68f
JG
1010adapt_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. */
e95bfbf1 1066void
7c18a68f
JG
1067adapt_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()");
7c18a68f
JG
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
1096void
1097adapt_prepare_to_store ()
1098{
1099 /* Do nothing, since we can store individual regs */
1100}
1101
1102static CORE_ADDR
1103translate_addr(addr)
1104CORE_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. */
1123int
1124adapt_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
1139void
1140adapt_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 */
1151int
1152adapt_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. */
1188int
1189adapt_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
1265static int num_brkpts=0;
1266static int
1267adapt_insert_breakpoint(addr, save)
1268CORE_ADDR addr;
1269char *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}
1287static int
1288adapt_remove_breakpoint(addr, save)
1289CORE_ADDR addr;
1290char *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 */
1305static int
1306adapt_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}
1318static void
1319adapt_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 */
1331static int
1332display_until(str)
1333char *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
1360void
1361adapt_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
1412struct 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,
a03d4f8e 1418 adapt_prepare_to_store,
7c18a68f
JG
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,
7c18a68f
JG
1425 0, /* lookup_symbol */
1426 adapt_create_inferior, /* create_inferior */
1427 adapt_mourn, /* mourn_inferior FIXME */
5ee4e16c 1428 0, /* can_run */
7c18a68f
JG
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
1435void
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.118061 seconds and 4 git commands to generate.