]> Git Repo - binutils.git/blob - gdb/remote-monitor.c
* remote-{monitor,bug}.c: Make bug_ops not static (forward declaration
[binutils.git] / gdb / remote-monitor.c
1 /* Remote debugging interface for MONITOR boot monitor, for GDB.
2    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3    Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /* This file was derived from remote-eb.c, which did a similar job, but for
22    an AMD-29K running EBMON.  That file was in turn derived from remote.c
23    as mentioned in the following comment (left in for comic relief):
24
25   "This is like remote.c but is for an esoteric situation--
26    having an a29k board in a PC hooked up to a unix machine with
27    a serial line, and running ctty com1 on the PC, through which
28    the unix machine can run ebmon.  Not to mention that the PC
29    has PC/NFS, so it can access the same executables that gdb can,
30    over the net in real time."
31
32    In reality, this module talks to a debug monitor called 'MONITOR', which
33    We communicate with MONITOR via either a direct serial line, or a TCP
34    (or possibly TELNET) stream to a terminal multiplexor,
35    which in turn talks to the target board.
36
37    This is based on remote-st2000.c. I left in the above note here for histerical
38    reasons.
39 */
40
41 #include "defs.h"
42 #include "gdbcore.h"
43 #include "target.h"
44 #include "wait.h"
45 #include <varargs.h>
46 #include <signal.h>
47 #include <string.h>
48 #include <sys/types.h>
49 #include "command.h"
50 #include "serial.h"
51 #include "monitor.h"
52
53 #ifdef HAVE_TERMIO
54 #  define TERMINAL struct termios
55 #else
56 #  define TERMINAL struct sgttyb
57 #endif
58
59 struct monitor_ops *current_monitor;
60 extern struct target_ops rom68k_ops;            /* Forward declaration */
61 extern struct target_ops mon68_ops;             /* Forward declaration */
62 extern struct target_ops monitor_bug_ops;       /* Forward declaration */
63 extern struct monitor_ops rom68k_cmds;          /* Forward declaration */
64 extern struct monitor_ops mon68_cmds;           /* Forward declaration */
65 extern struct monitor_ops bug_cmds;             /* Forward declaration */
66 extern struct cmd_list_element *setlist;
67 extern struct cmd_list_element *unsetlist;
68 struct cmd_list_element *showlist;
69
70 static void monitor_close();
71 static void monitor_fetch_register();
72 static void monitor_store_register();
73 static int kiodebug;                            /* flag set by "set remotedebug" */
74 static int hashmark;                            /* flag set by "set hash" */
75
76 #define LOG_FILE "monitor.log"
77 #if defined (LOG_FILE)
78 FILE *log_file;
79 #endif
80
81 static int timeout = 24;
82
83 /* Descriptor for I/O to remote machine.  Initialize it to NULL so that
84    monitor_open knows that we don't have a file open when the program starts.
85    */
86 static serial_t monitor_desc = NULL;
87
88 /* Send data to monitor.  Works just like printf. */
89
90 static void
91 printf_monitor(va_alist)
92      va_dcl
93 {
94   va_list args;
95   char *pattern;
96   char buf[200];
97   int i;
98
99   va_start(args);
100
101   pattern = va_arg(args, char *);
102
103   vsprintf(buf, pattern, args);
104
105   if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
106     fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
107 }
108
109 /* Read a character from the remote system, doing all the fancy
110    timeout stuff.  */
111 static int
112 readchar(timeout)
113      int timeout;
114 {
115   int c;
116
117   c = SERIAL_READCHAR(monitor_desc, timeout);
118
119   if (kiodebug)
120     putchar(c & 0x7f);
121
122 #ifdef LOG_FILE
123   if (isascii (c))
124     putc(c & 0x7f, log_file);
125 #endif
126
127   if (c >= 0)
128     return c & 0x7f;
129
130   if (c == SERIAL_TIMEOUT)
131     {
132       if (timeout == 0)
133         return c;               /* Polls shouldn't generate timeout errors */
134
135       error("Timeout reading from remote system.");
136     }
137
138   perror_with_name("remote-monitor");
139 }
140
141 /* Scan input from the remote system, until STRING is found.  If DISCARD is
142    non-zero, then discard non-matching input, else print it out.
143    Let the user break out immediately.  */
144 static void
145 expect(string, discard)
146      char *string;
147      int discard;
148 {
149   char *p = string;
150   int c;
151
152   if (kiodebug)
153     printf ("Expecting \"%s\"\n", string);
154
155   immediate_quit = 1;
156   while (1)
157     {
158       c = readchar(timeout);
159       if (!isascii (c))
160         continue;
161       if (c == *p++)
162         {
163           if (*p == '\0')
164             {
165               immediate_quit = 0;
166               if (kiodebug)
167                 printf ("\nMatched\n");
168               return;
169             }
170         }
171       else
172         {
173           if (!discard)
174             {
175               fwrite(string, 1, (p - 1) - string, stdout);
176               putchar((char)c);
177               fflush(stdout);
178             }
179           p = string;
180         }
181     }
182 }
183
184 /* Keep discarding input until we see the MONITOR prompt.
185
186    The convention for dealing with the prompt is that you
187    o give your command
188    o *then* wait for the prompt.
189
190    Thus the last thing that a procedure does with the serial line
191    will be an expect_prompt().  Exception:  monitor_resume does not
192    wait for the prompt, because the terminal is being handed over
193    to the inferior.  However, the next thing which happens after that
194    is a monitor_wait which does wait for the prompt.
195    Note that this includes abnormal exit, e.g. error().  This is
196    necessary to prevent getting into states from which we can't
197    recover.  */
198 static void
199 expect_prompt(discard)
200      int discard;
201 {
202 #if defined (LOG_FILE)
203   /* This is a convenient place to do this.  The idea is to do it often
204      enough that we never lose much data if we terminate abnormally.  */
205   fflush(log_file);
206 #endif
207   expect (PROMPT, discard);
208 }
209
210 /* Get a hex digit from the remote system & return its value.
211    If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
212 static int
213 get_hex_digit(ignore_space)
214      int ignore_space;
215 {
216   int ch;
217   while (1)
218     {
219       ch = readchar(timeout);
220       if (ch >= '0' && ch <= '9')
221         return ch - '0';
222       else if (ch >= 'A' && ch <= 'F')
223         return ch - 'A' + 10;
224       else if (ch >= 'a' && ch <= 'f')
225         return ch - 'a' + 10;
226       else if (ch == ' ' && ignore_space)
227         ;
228       else
229         {
230           expect_prompt(1);
231           error("Invalid hex digit from remote system.");
232         }
233     }
234 }
235
236 /* Get a byte from monitor and put it in *BYT.  Accept any number
237    leading spaces.  */
238 static void
239 get_hex_byte (byt)
240      char *byt;
241 {
242   int val;
243
244   val = get_hex_digit (1) << 4;
245   val |= get_hex_digit (0);
246   *byt = val;
247 }
248
249 /* Get N 32-bit words from remote, each preceded by a space,
250    and put them in registers starting at REGNO.  */
251 static void
252 get_hex_regs (n, regno)
253      int n;
254      int regno;
255 {
256   long val;
257   int i;
258
259   for (i = 0; i < n; i++)
260     {
261       int j;
262       
263       val = 0;
264       for (j = 0; j < 8; j++)
265         val = (val << 4) + get_hex_digit (j == 0);
266       supply_register (regno++, (char *) &val);
267     }
268 }
269
270 /* This is called not only when we first attach, but also when the
271    user types "run" after having attached.  */
272 static void
273 monitor_create_inferior (execfile, args, env)
274      char *execfile;
275      char *args;
276      char **env;
277 {
278   int entry_pt;
279
280   if (args && *args)
281     error("Can't pass arguments to remote MONITOR process");
282
283   if (execfile == 0 || exec_bfd == 0)
284     error("No exec file specified");
285
286   entry_pt = (int) bfd_get_start_address (exec_bfd);
287
288 #ifdef CREATE_INFERIOR_HOOK
289   CREATE_INFERIOR_HOOK (0);             /* No process-ID */
290 #endif  
291 #ifdef LOG_FILE
292   fputs ("\nIn Create_inferior()", log_file);
293 #endif
294
295 /* The "process" (board) is already stopped awaiting our commands, and
296    the program is already downloaded.  We just set its PC and go.  */
297
298   clear_proceed_status ();
299
300   /* Tell wait_for_inferior that we've started a new process.  */
301   init_wait_for_inferior ();
302
303   /* Set up the "saved terminal modes" of the inferior
304      based on what modes we are starting it with.  */
305   target_terminal_init ();
306
307   /* Install inferior's terminal modes.  */
308   target_terminal_inferior ();
309
310   /* insert_step_breakpoint ();  FIXME, do we need this?  */
311   proceed ((CORE_ADDR)entry_pt, -1, 0);         /* Let 'er rip... */
312 }
313
314 /* Open a connection to a remote debugger.
315    NAME is the filename used for communication.  */
316
317 static int baudrate = 9600;
318 static char dev_name[100];
319
320 static void
321 general_open(args, name, from_tty)
322      char *args;
323      char *name;
324      int from_tty;
325 {
326   if (args == NULL)
327     error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\
328 `target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name);
329
330   target_preopen(from_tty);
331
332   monitor_close(0);
333
334   monitor_desc = SERIAL_OPEN(dev_name);
335
336   if (monitor_desc == NULL)
337     perror_with_name(dev_name);
338
339   /* The baud rate was specified when GDB was started.  */
340   if (baud_rate)
341     {
342       int rate;
343
344       if (sscanf (baud_rate, "%d", &rate) == 1)
345         if (SERIAL_SETBAUDRATE (monitor_desc, rate))
346           {
347             SERIAL_CLOSE (monitor_desc);
348             perror_with_name (name);
349           }
350     }
351
352   SERIAL_RAW(monitor_desc);
353
354 #if defined (LOG_FILE)
355   log_file = fopen (LOG_FILE, "w");
356   if (log_file == NULL)
357     perror_with_name (LOG_FILE);
358 #endif
359
360   /* Hello?  Are you there?  */
361   printf_monitor("\r"); /* CR wakes up monitor */
362   
363   expect_prompt(1);
364
365   if (from_tty)
366     printf("Remote %s connected to %s\n", target_shortname,
367            dev_name);
368 }
369
370 static void
371 rom68k_open(args, from_tty)
372      char *args;
373      int from_tty;
374 {
375   push_target(&rom68k_ops);
376   push_monitor (&rom68k_cmds);
377
378   general_open (args, "rom68k", from_tty);
379 }
380
381 static void
382 mon68_open(args, from_tty)
383      char *args;
384      int from_tty;
385 {
386   push_target(&mon68_ops);
387   push_monitor (&mon68_cmds);
388
389   general_open (args, "mon68", from_tty);
390 }
391
392 static void
393 bug_open(args, from_tty)
394      char *args;
395      int from_tty;
396 {
397   push_target(&monitor_bug_ops);
398   push_monitor (&bug_cmds);
399
400   general_open (args, "bug", from_tty);
401 }
402
403 /*
404  * _close -- Close out all files and local state before this target loses control.
405  */
406
407 static void
408 monitor_close (quitting)
409      int quitting;
410 {
411   SERIAL_CLOSE(monitor_desc);
412   monitor_desc = NULL;
413
414 #if defined (LOG_FILE)
415   if (log_file) {
416     if (ferror(log_file))
417       fprintf(stderr, "Error writing log file.\n");
418     if (fclose(log_file) != 0)
419       fprintf(stderr, "Error closing log file.\n");
420   }
421 #endif
422 }
423
424 /* Terminate the open connection to the remote debugger.
425    Use this when you want to detach and do something else
426    with your gdb.  */
427 static void
428 monitor_detach (from_tty)
429      int from_tty;
430 {
431   pop_target();         /* calls monitor_close to do the real work */
432   if (from_tty)
433     printf ("Ending remote %s debugging\n", target_shortname);
434 }
435  
436 /*
437  * _resume -- Tell the remote machine to resume.
438  */
439 static void
440 monitor_resume (pid, step, sig)
441      int pid, step, sig;
442 {
443 #ifdef LOG_FILE
444   fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
445 #endif
446
447   if (step)
448     {
449       printf_monitor (STEP_CMD);
450       /* wait for the echo.  */
451       expect (STEP_CMD, 1);
452     }
453   else
454     {
455       printf_monitor (GO_CMD);
456       /* swallow the echo.  */
457       expect (GO_CMD, 1);
458     }
459 }
460
461 /*
462  * _wait -- Wait until the remote machine stops, then return,
463  *          storing status in status just as `wait' would.
464  */
465
466 static int
467 monitor_wait (status)
468      WAITTYPE *status;
469 {
470   int old_timeout = timeout;
471 #ifdef LOG_FILE
472   fputs ("\nIn wait ()", log_file);
473 #endif
474
475   WSETEXIT ((*status), 0);
476
477   timeout = 0;          /* Don't time out -- user program is running. */
478
479   expect_prompt(0);    /* Wait for prompt, outputting extraneous text */
480
481   WSETSTOP ((*status), SIGTRAP);
482
483   timeout = old_timeout;
484
485   return 0;
486 }
487
488 /* Return the name of register number regno in the form input and output by
489    monitor.  Currently, register_names just happens to contain exactly what
490    monitor wants.  Lets take advantage of that just as long as possible! */
491
492 static char *
493 get_reg_name (regno)
494      int regno;
495 {
496   static char buf[50];
497   const char *p;
498   char *b;
499
500   b = buf;
501
502   if (regno < 0)
503     return ("");
504   for (p = reg_names[regno]; *p; p++)
505     *b++ = toupper(*p);
506   *b = '\000';
507
508   return buf;
509 }
510
511 /* read the remote registers into the block regs.  */
512
513 static void
514 monitor_fetch_registers ()
515 {
516   int regno;
517
518   /* yeah yeah, i know this is horribly inefficient.  but it isn't done
519      very often...  i'll clean it up later.  */
520
521   for (regno = 0; regno <= PC_REGNUM; regno++)
522     monitor_fetch_register(regno);
523 }
524
525 /* Fetch register REGNO, or all registers if REGNO is -1.
526    Returns errno value.  */
527 static void
528 monitor_fetch_register (regno)
529      int regno;
530 {
531   int val, j;
532
533 #ifdef LOG_FILE
534   fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
535   fflush (log_file);
536 #endif
537
538   if (regno < 0)
539     {
540       monitor_fetch_registers ();
541     }
542   else
543     {
544       char *name = get_reg_name (regno);
545       printf_monitor (GET_REG, name);
546       expect (name, 1);
547       expect (REG_DELIM, 1);
548       if (strcasecmp (name, "SR") == 0)
549         {
550           val = 0;
551           for (j = 0; j < 4; j++)
552             val = (val << 4) + get_hex_digit (j == 0);
553           supply_register (regno, (char *) &val);
554         }
555       else
556         {
557           get_hex_regs (1, regno);
558         }
559       if (CMD_END) 
560         {
561           expect (CMD_DELIM);
562           printf_monitor (CMD_END);
563         }
564       expect_prompt (1);
565     }
566   return;
567 }
568
569 /* Store the remote registers from the contents of the block REGS.  */
570
571 static void
572 monitor_store_registers ()
573 {
574   int regno;
575
576   for (regno = 0; regno <= PC_REGNUM; regno++)
577     monitor_store_register(regno);
578
579   registers_changed ();
580 }
581
582 /* Store register REGNO, or all if REGNO == 0.
583    return errno value.  */
584 static void
585 monitor_store_register (regno)
586      int regno;
587 {
588 #ifdef LOG_FILE
589   fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
590 #endif
591   if (regno == -1)
592     monitor_store_registers ();
593   else
594     {
595       if (kiodebug)
596         printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
597
598       printf_monitor (SET_REG, get_reg_name (regno),
599                       read_register (regno));
600
601       expect_prompt (1);
602     }
603 }
604
605 /* Get ready to modify the registers array.  On machines which store
606    individual registers, this doesn't need to do anything.  On machines
607    which store all the registers in one fell swoop, this makes sure
608    that registers contains all the registers from the program being
609    debugged.  */
610
611 static void
612 monitor_prepare_to_store ()
613 {
614   /* Do nothing, since we can store individual regs */
615 }
616
617 static void
618 monitor_files_info ()
619 {
620   printf ("\tAttached to %s at %d baud.\n",
621           dev_name, baudrate);
622 }
623
624 /* Copy LEN bytes of data from debugger memory at MYADDR
625    to inferior's memory at MEMADDR.  Returns length moved.  */
626 static int
627 monitor_write_inferior_memory (memaddr, myaddr, len)
628      CORE_ADDR memaddr;
629      unsigned char *myaddr;
630      int len;
631 {
632   int i;
633   char buf[10];
634
635 #ifdef LOG_FILE
636   fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
637 #endif
638   for (i = 0; i < len; i++)
639     {
640       printf_monitor (MEM_SET_CMD, memaddr + i);
641       expect (sprintf (buf, MEM_PROMPT, memaddr + i), 1); 
642       expect (CMD_DELIM);
643       printf_monitor ("%x", myaddr[i]);
644       if (kiodebug)
645         printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
646       if (CMD_END)
647         {
648 /***      expect (sprintf (buf, MEM_PROMPT, memaddr + i +1), 1);          
649           expect (CMD_DELIM); ***/
650           printf_monitor (CMD_END);
651         }
652       expect_prompt (1);
653     }
654   return len;
655 }
656
657 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
658    at debugger address MYADDR.  Returns length moved.  */
659 static int
660 monitor_read_inferior_memory(memaddr, myaddr, len)
661      CORE_ADDR memaddr;
662      char *myaddr;
663      int len;
664 {
665   int i, j;
666   char buf[20];
667
668   /* Number of bytes read so far.  */
669   int count;
670
671   /* Starting address of this pass.  */
672   unsigned long startaddr;
673
674   /* Number of bytes to read in this pass.  */
675   int len_this_pass;
676
677 #ifdef LOG_FILE
678   fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
679 #endif
680
681   /* Note that this code works correctly if startaddr is just less
682      than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
683      thing).  That is, something like
684      monitor_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
685      works--it never adds len To memaddr and gets 0.  */
686   /* However, something like
687      monitor_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
688      doesn't need to work.  Detect it and give up if there's an attempt
689      to do that.  */
690   if (((memaddr - 1) + len) < memaddr) {
691     errno = EIO;
692     return 0;
693   }
694   
695   startaddr = memaddr;
696   count = 0;
697   while (count < len)
698     {
699       len_this_pass = 16;
700       if ((startaddr % 16) != 0)
701         len_this_pass -= startaddr % 16;
702       if (len_this_pass > (len - count))
703         len_this_pass = (len - count);
704       if (kiodebug)
705         printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
706
707       for (i = 0; i < len_this_pass; i++)
708         {
709           printf_monitor (MEM_DIS_CMD, startaddr);
710           expect (sprintf(buf, MEM_PROMPT, startaddr), 1);
711           get_hex_byte (&myaddr[count++]);
712           if (kiodebug)
713             printf ("\nRead a 0x%x from 0x%x\n", myaddr[count-1], startaddr);
714           if (CMD_END) 
715             {
716               expect (CMD_DELIM);
717               printf_monitor (CMD_END);
718             }
719           expect_prompt (1);
720           startaddr += 1;
721         }
722     }
723   return len;
724 }
725
726 /* FIXME-someday!  merge these two.  */
727 static int
728 monitor_xfer_inferior_memory (memaddr, myaddr, len, write, target)
729      CORE_ADDR memaddr;
730      char *myaddr;
731      int len;
732      int write;
733      struct target_ops *target;         /* ignored */
734 {
735   if (write)
736     return monitor_write_inferior_memory (memaddr, myaddr, len);
737   else
738     return monitor_read_inferior_memory (memaddr, myaddr, len);
739 }
740
741 static void
742 monitor_kill (args, from_tty)
743      char *args;
744      int from_tty;
745 {
746   return;               /* ignore attempts to kill target system */
747 }
748
749 /* Clean up when a program exits.
750    The program actually lives on in the remote processor's RAM, and may be
751    run again without a download.  Don't leave it full of breakpoint
752    instructions.  */
753
754 static void
755 monitor_mourn_inferior ()
756 {
757   remove_breakpoints ();
758   generic_mourn_inferior ();    /* Do all the proper things now */
759 }
760
761 #define MAX_MONITOR_BREAKPOINTS 16
762
763 extern int memory_breakpoint_size;
764 static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
765
766 static int
767 monitor_insert_breakpoint (addr, shadow)
768      CORE_ADDR addr;
769      char *shadow;
770 {
771   int i;
772
773 #ifdef LOG_FILE
774   fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
775 #endif
776   for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
777     if (breakaddr[i] == 0)
778       {
779         breakaddr[i] = addr;
780         if (kiodebug)
781           printf ("Breakpoint at %x\n", addr);
782         monitor_read_inferior_memory(addr, shadow, memory_breakpoint_size);
783         printf_monitor(SET_BREAK_CMD, addr);
784         expect_prompt(1);
785         return 0;
786       }
787
788   fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
789   return 1;
790 }
791
792 /*
793  * _remove_breakpoint -- Tell the monitor to remove a breakpoint
794  */
795 static int
796 monitor_remove_breakpoint (addr, shadow)
797      CORE_ADDR addr;
798      char *shadow;
799 {
800   int i;
801
802 #ifdef LOG_FILE
803   fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
804 #endif
805   for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
806     if (breakaddr[i] == addr)
807       {
808         breakaddr[i] = 0;
809         /* some monitors remove breakpoints based on the address */
810         if (strcasecmp (target_shortname, "bug") == 0)   
811             printf_monitor(CLR_BREAK_CMD, addr);
812           else
813             printf_monitor(CLR_BREAK_CMD, i);
814         expect_prompt(1);
815         return 0;
816       }
817
818   fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
819   return 1;
820 }
821
822 /* Load a file. This is usually an srecord, which is ascii. No 
823    protocol, just sent line by line. */
824
825 #define DOWNLOAD_LINE_SIZE 100
826 static void
827 monitor_load (arg)
828     char        *arg;
829 {
830   FILE *download;
831   char buf[DOWNLOAD_LINE_SIZE];
832   int i, bytes_read;
833
834   if (kiodebug)
835     printf ("Loading %s to monitor\n", arg);
836
837   download = fopen (arg, "r");
838   if (download == NULL)
839     {
840     error (sprintf (buf, "%s Does not exist", arg));
841     return;
842   }
843
844   printf_monitor (LOAD_CMD);
845 /*  expect ("Waiting for S-records from host... ", 1); */
846
847   while (!feof (download))
848     {
849       bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
850       if (hashmark)
851         {
852           putchar ('.');
853           fflush (stdout);
854         }
855
856       if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
857         fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
858         break;
859       }
860       i = 0;
861       while (i++ <=200000) {} ;                         /* Ugly HACK, probably needs flow control */
862       if (bytes_read < DOWNLOAD_LINE_SIZE)
863         {
864           if (!feof (download))
865             error ("Only read %d bytes\n", bytes_read);
866           break;
867         }
868     }
869
870   if (hashmark)
871     {
872       putchar ('\n');
873     }
874   if (!feof (download))
875     error ("Never got EOF while downloading");
876   fclose (download);
877 }
878
879 /* Put a command string, in args, out to MONITOR.  Output from MONITOR is placed
880    on the users terminal until the prompt is seen. */
881
882 static void
883 monitor_command (args, fromtty)
884      char       *args;
885      int        fromtty;
886 {
887 #ifdef LOG_FILE
888   fprintf (log_file, "\nIn command (args=%s)\n", args);
889 #endif
890   if (monitor_desc == NULL)
891     error("monitor target not open.");
892   
893   if (!args)
894     error("Missing command.");
895         
896   printf_monitor("%s\r", args);
897   expect_prompt(0);
898 }
899
900 #if 0
901
902 /* Connect the user directly to MONITOR.  This command acts just like the
903    'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
904
905 static struct ttystate ttystate;
906
907 static void
908 cleanup_tty()
909 {  printf("\r\n[Exiting connect mode]\r\n");
910   /*SERIAL_RESTORE(0, &ttystate);*/
911 }
912
913 static void
914 connect_command (args, fromtty)
915      char       *args;
916      int        fromtty;
917 {
918   fd_set readfds;
919   int numfds;
920   int c;
921   char cur_esc = 0;
922
923   dont_repeat();
924
925   if (monitor_desc == NULL)
926     error("monitor target not open.");
927   
928   if (args)
929     fprintf("This command takes no args.  They have been ignored.\n");
930         
931   printf("[Entering connect mode.  Use ~. or ~^D to escape]\n");
932
933   serial_raw(0, &ttystate);
934
935   make_cleanup(cleanup_tty, 0);
936
937   FD_ZERO(&readfds);
938
939   while (1)
940     {
941       do
942         {
943           FD_SET(0, &readfds);
944           FD_SET(monitor_desc, &readfds);
945           numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
946         }
947       while (numfds == 0);
948
949       if (numfds < 0)
950         perror_with_name("select");
951
952       if (FD_ISSET(0, &readfds))
953         {                       /* tty input, send to monitor */
954           c = getchar();
955           if (c < 0)
956             perror_with_name("connect");
957
958           printf_monitor("%c", c);
959           switch (cur_esc)
960             {
961             case 0:
962               if (c == '\r')
963                 cur_esc = c;
964               break;
965             case '\r':
966               if (c == '~')
967                 cur_esc = c;
968               else
969                 cur_esc = 0;
970               break;
971             case '~':
972               if (c == '.' || c == '\004')
973                 return;
974               else
975                 cur_esc = 0;
976             }
977         }
978
979       if (FD_ISSET(monitor_desc, &readfds))
980         {
981           while (1)
982             {
983               c = readchar(0);
984               if (c < 0)
985                 break;
986               putchar(c);
987             }
988           fflush(stdout);
989         }
990     }
991 }
992 #endif
993
994 /*
995  * Define the monitor command strings. Since these are passed directly
996  * through to a printf style function, we need can include formatting
997  * strings. We also need a CR or LF on the end.
998  */
999 struct monitor_ops rom68k_cmds = {
1000   "go \r",                              /* execute or usually GO command */
1001   "go \r",                              /* continue command */
1002   "st \r",                              /* single step */
1003   "db %x\r",                            /* set a breakpoint */
1004   "cb %x\r",                            /* clear a breakpoint */
1005   "pm %x\r",                            /* set memory to a value */
1006   "pm %x\r",                            /* display memory */
1007   "-%08X  ",                            /* prompt memory commands use */
1008   "pr %s %x\r",                         /* set a register */
1009   ":  ",                                /* delimiter between registers */
1010   "pr %s\r",                            /* read a register */
1011   "dc \r",                              /* download command */
1012   "ROM68K :->",                         /* monitor command prompt */
1013   "=",                                  /* end-of-command delimitor */
1014   ".\r"                                 /* optional command terminator */
1015 };
1016
1017 struct monitor_ops bug_cmds = {
1018   "go \r",                              /* execute or usually GO command */
1019   "go \r",                              /* continue command */
1020   "gn \r",                              /* single step */
1021   "br %x\r",                            /* set a breakpoint */
1022   "nobr %x\r",                          /* clear a breakpoint */
1023   "mm %x\r",                            /* set memory to a value */
1024   "mm %x\r",                            /* display memory */
1025   "%08X",                               /* prompt memory commands use */
1026   "rs %s %x\r",                         /* set a register */
1027   "=",                                  /* delimiter between registers */
1028   "rm %s\r",                            /* read a register */
1029   "lo 0\r",                             /* download command */
1030   "Bug>",                               /* monitor command prompt */
1031   "? ",                                 /* end-of-command delimitor */
1032   ".\r"                                 /* optional command terminator */
1033 };
1034
1035 /* Define the target subroutine names */
1036 struct monitor_ops mon68_cmds = {
1037   "",                           /* execute or usually GO command */
1038   "",                           /* continue command */
1039   "",                           /* single step */
1040   "",                           /* set a breakpoint */
1041   "",                           /* clear a breakpoint */
1042   "",                           /* set memory to a value */
1043   "",                           /* display memory */
1044   "",                           /* set a register */
1045   "",                           /* delimiter between registers */       
1046   "",                           /* read a register */
1047   "",                           /* download command */
1048   ">",                          /* monitor command prompt */
1049   "",                                   /* end-of-command delimitor */
1050   ""                                    /* optional command terminator */
1051 };
1052
1053 struct target_ops rom68k_ops = {
1054   "rom68k",
1055   "Integrated System's ROM68K remote debug monitor",
1056   "Use a remote computer running the ROM68K debug monitor.\n\
1057 Specify the serial device it is connected to (e.g. /dev/ttya).",
1058   rom68k_open,
1059   monitor_close, 
1060   0,
1061   monitor_detach,
1062   monitor_resume,
1063   monitor_wait,
1064   monitor_fetch_register,
1065   monitor_store_register,
1066   monitor_prepare_to_store,
1067   monitor_xfer_inferior_memory,
1068   monitor_files_info,
1069   monitor_insert_breakpoint,
1070   monitor_remove_breakpoint,    /* Breakpoints */
1071   0,
1072   0,
1073   0,
1074   0,
1075   0,                            /* Terminal handling */
1076   monitor_kill,
1077   monitor_load,                 /* load */
1078   0,                            /* lookup_symbol */
1079   monitor_create_inferior,
1080   monitor_mourn_inferior,
1081   0,                            /* can_run */
1082   0,                            /* notice_signals */
1083   process_stratum,
1084   0,                            /* next */
1085   1,
1086   1,
1087   1,
1088   1,
1089   1,                            /* all mem, mem, stack, regs, exec */
1090   0,
1091   0,                            /* Section pointers */
1092   OPS_MAGIC,                    /* Always the last thing */
1093 };
1094
1095 struct target_ops monitor_bug_ops = {
1096   "bug",
1097   "Motorola's BUG remote serial debug monitor",
1098   "Use a remote computer running Motorola's BUG debug monitor.\n\
1099 Specify the serial device it is connected to (e.g. /dev/ttya).",
1100   bug_open,
1101   monitor_close, 
1102   0,
1103   monitor_detach,
1104   monitor_resume,
1105   monitor_wait,
1106   monitor_fetch_register,
1107   monitor_store_register,
1108   monitor_prepare_to_store,
1109   monitor_xfer_inferior_memory,
1110   monitor_files_info,
1111   monitor_insert_breakpoint,
1112   monitor_remove_breakpoint,    /* Breakpoints */
1113   0,
1114   0,
1115   0,
1116   0,
1117   0,                            /* Terminal handling */
1118   monitor_kill,
1119   monitor_load,                 /* load */
1120   0,                            /* lookup_symbol */
1121   monitor_create_inferior,
1122   monitor_mourn_inferior,
1123   0,                            /* can_run */
1124   0,                            /* notice_signals */
1125   process_stratum,
1126   0,                            /* next */
1127   1,
1128   1,
1129   1,
1130   1,
1131   1,                            /* all mem, mem, stack, regs, exec */
1132   0,
1133   0,                            /* Section pointers */
1134   OPS_MAGIC,                    /* Always the last thing */
1135 };
1136
1137 struct target_ops mon68_ops = {
1138   "mon68",
1139   "Intermetric's MON68 remote serial debug monitor",
1140   "Use a remote computer running the MON68 debug monitor.\n\
1141 Specify the serial device it is connected to (e.g. /dev/ttya).",
1142   mon68_open,
1143   monitor_close, 
1144   0,
1145   monitor_detach,
1146   monitor_resume,
1147   monitor_wait,
1148   monitor_fetch_register,
1149   monitor_store_register,
1150   monitor_prepare_to_store,
1151   monitor_xfer_inferior_memory,
1152   monitor_files_info,
1153   monitor_insert_breakpoint,
1154   monitor_remove_breakpoint,    /* Breakpoints */
1155   0,
1156   0,
1157   0,
1158   0,
1159   0,                            /* Terminal handling */
1160   monitor_kill,
1161   monitor_load,                 /* load */
1162   0,                            /* lookup_symbol */
1163   monitor_create_inferior,
1164   monitor_mourn_inferior,
1165   0,                            /* can_run */
1166   0,                            /* notice_signals */
1167   process_stratum,
1168   0,                            /* next */
1169   1,
1170   1,
1171   1,
1172   1,
1173   1,                            /* all mem, mem, stack, regs, exec */
1174   0,
1175   0,                            /* Section pointers */
1176   OPS_MAGIC,                    /* Always the last thing */
1177 };
1178
1179 void
1180 _initialize_remote_monitors ()
1181 {
1182   add_show_from_set (
1183                      add_set_cmd ("remotedebug", no_class, var_boolean,
1184                                   (char *)&kiodebug,
1185                                   "Set debugging of I/O to a serial based Monitor.\n\
1186 When enabled, debugging info is displayed.",
1187                                   &setlist),
1188                      &showlist);
1189   add_show_from_set (
1190                      add_set_cmd ("hash", no_class, var_boolean,
1191                                   (char *)&hashmark,
1192                                   "Set display of activity while downloading a file.\n\
1193 When enabled, a period \'.\' is displayed.",
1194                                   &setlist),
1195                      &showlist);
1196
1197   /* generic monitor command */
1198   add_com ("monitor <command>", class_obscure, monitor_command,
1199            "Send a command to the debug monitor."); 
1200 #if 0
1201   add_com ("connect", class_obscure, connect_command,
1202            "Connect the terminal directly up to a serial based command monitor.\n\
1203 Use <CR>~. or <CR>~^D to break out.");
1204 #endif
1205
1206   add_target (&rom68k_ops);
1207 /*  add_target (&mon68_ops); */
1208   add_target (&monitor_bug_ops);
1209 }
This page took 0.091128 seconds and 4 git commands to generate.