41f87c135824a3f61f8eb5684c3f457c2271dcf2
[deliverable/binutils-gdb.git] / gdb / remote-monitor.c
1 /* Remote debugging interface for MONITOR boot monitor, for GDB.
2 Copyright 1990, 1991, 1992 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 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 -1 so that
84 monitor_open knows that we don't have a file open when the program
85 starts. */
86 static serial_t monitor_desc;
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)
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(&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
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 (step, sig)
440 int 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 (kiodebug)
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 (kiodebug)
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 (kiodebug)
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 (kiodebug)
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 (kiodebug)
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 (kiodebug)
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 < 0)
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 < 0)
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 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 add_show_from_set (
1189 add_set_cmd ("hash", no_class, var_boolean,
1190 (char *)&hashmark,
1191 "Set display of activity while downloading a file.\n\
1192 When enabled, a period \'.\' is displayed.",
1193 &setlist),
1194 &showlist);
1195
1196 /* generic monitor command */
1197 add_com ("monitor <command>", class_obscure, monitor_command,
1198 "Send a command to the debug monitor.");
1199 #if 0
1200 add_com ("connect", class_obscure, connect_command,
1201 "Connect the terminal directly up to a serial based command monitor.\n\
1202 Use <CR>~. or <CR>~^D to break out.");
1203 #endif
1204
1205 add_target (&rom68k_ops);
1206 /* add_target (&mon68_ops); */
1207 add_target (&bug_ops);
1208 }
This page took 0.065233 seconds and 3 git commands to generate.