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