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