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