* remote-{monitor,bug}.c: Make bug_ops not static (forward declaration
[deliverable/binutils-gdb.git] / gdb / remote-monitor.c
CommitLineData
054240ec 1/* Remote debugging interface for MONITOR boot monitor, for GDB.
5905161c 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
054240ec
RS
3 Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, 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--
d7d35f00 26 having an a29k board in a PC hooked up to a unix machine with
054240ec
RS
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
59struct monitor_ops *current_monitor;
60extern struct target_ops rom68k_ops; /* Forward declaration */
61extern struct target_ops mon68_ops; /* Forward declaration */
ae87844d 62extern struct target_ops monitor_bug_ops; /* Forward declaration */
054240ec
RS
63extern struct monitor_ops rom68k_cmds; /* Forward declaration */
64extern struct monitor_ops mon68_cmds; /* Forward declaration */
65extern struct monitor_ops bug_cmds; /* Forward declaration */
66extern struct cmd_list_element *setlist;
67extern struct cmd_list_element *unsetlist;
68struct cmd_list_element *showlist;
69
70static void monitor_close();
71static void monitor_fetch_register();
72static void monitor_store_register();
73static int kiodebug; /* flag set by "set remotedebug" */
74static int hashmark; /* flag set by "set hash" */
75
76#define LOG_FILE "monitor.log"
77#if defined (LOG_FILE)
78FILE *log_file;
79#endif
80
81static int timeout = 24;
82
5905161c
RP
83/* Descriptor for I/O to remote machine. Initialize it to NULL so that
84 monitor_open knows that we don't have a file open when the program starts.
85 */
86static serial_t monitor_desc = NULL;
054240ec
RS
87
88/* Send data to monitor. Works just like printf. */
89
90static void
91printf_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
1724c671
SG
105 if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
106 fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
054240ec
RS
107}
108
109/* Read a character from the remote system, doing all the fancy
110 timeout stuff. */
111static int
112readchar(timeout)
113 int timeout;
114{
115 int c;
116
1724c671 117 c = SERIAL_READCHAR(monitor_desc, timeout);
054240ec
RS
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
1724c671 130 if (c == SERIAL_TIMEOUT)
054240ec
RS
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. */
144static void
145expect(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. */
198static void
199expect_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). */
212static int
213get_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. */
238static void
239get_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. */
251static void
252get_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. */
272static void
273monitor_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
317static int baudrate = 9600;
318static char dev_name[100];
319
320static void
1724c671 321general_open(args, name, from_tty)
054240ec 322 char *args;
1724c671 323 char *name;
054240ec
RS
324 int from_tty;
325{
60a60032
JK
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);
054240ec
RS
329
330 target_preopen(from_tty);
054240ec
RS
331
332 monitor_close(0);
333
1724c671 334 monitor_desc = SERIAL_OPEN(dev_name);
054240ec 335
5905161c 336 if (monitor_desc == NULL)
1724c671 337 perror_with_name(dev_name);
054240ec 338
60a60032
JK
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 }
054240ec 351
1724c671 352 SERIAL_RAW(monitor_desc);
054240ec
RS
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? */
1724c671 361 printf_monitor("\r"); /* CR wakes up monitor */
054240ec
RS
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
370static void
1724c671 371rom68k_open(args, from_tty)
054240ec
RS
372 char *args;
373 int from_tty;
374{
1724c671
SG
375 push_target(&rom68k_ops);
376 push_monitor (&rom68k_cmds);
054240ec 377
1724c671
SG
378 general_open (args, "rom68k", from_tty);
379}
054240ec 380
1724c671
SG
381static void
382mon68_open(args, from_tty)
383 char *args;
384 int from_tty;
385{
054240ec
RS
386 push_target(&mon68_ops);
387 push_monitor (&mon68_cmds);
388
1724c671 389 general_open (args, "mon68", from_tty);
054240ec
RS
390}
391
392static void
393bug_open(args, from_tty)
394 char *args;
395 int from_tty;
396{
ae87844d 397 push_target(&monitor_bug_ops);
054240ec
RS
398 push_monitor (&bug_cmds);
399
1724c671 400 general_open (args, "bug", from_tty);
054240ec
RS
401}
402
403/*
404 * _close -- Close out all files and local state before this target loses control.
405 */
1724c671 406
054240ec
RS
407static void
408monitor_close (quitting)
409 int quitting;
410{
1724c671 411 SERIAL_CLOSE(monitor_desc);
5905161c 412 monitor_desc = NULL;
054240ec
RS
413
414#if defined (LOG_FILE)
415 if (log_file) {
416 if (ferror(log_file))
417 fprintf(stderr, "Error writing log file.\n");
418 if (fclose(log_file) != 0)
419 fprintf(stderr, "Error closing log file.\n");
420 }
421#endif
422}
423
424/* Terminate the open connection to the remote debugger.
425 Use this when you want to detach and do something else
426 with your gdb. */
427static void
428monitor_detach (from_tty)
429 int from_tty;
430{
431 pop_target(); /* calls monitor_close to do the real work */
432 if (from_tty)
433 printf ("Ending remote %s debugging\n", target_shortname);
434}
435
436/*
437 * _resume -- Tell the remote machine to resume.
438 */
439static void
25286543
SG
440monitor_resume (pid, step, sig)
441 int pid, step, sig;
054240ec
RS
442{
443#ifdef LOG_FILE
444 fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
445#endif
446
447 if (step)
448 {
449 printf_monitor (STEP_CMD);
450 /* wait for the echo. */
451 expect (STEP_CMD, 1);
452 }
453 else
454 {
455 printf_monitor (GO_CMD);
456 /* swallow the echo. */
457 expect (GO_CMD, 1);
458 }
459}
460
461/*
462 * _wait -- Wait until the remote machine stops, then return,
463 * storing status in status just as `wait' would.
464 */
465
466static int
467monitor_wait (status)
468 WAITTYPE *status;
469{
470 int old_timeout = timeout;
471#ifdef LOG_FILE
472 fputs ("\nIn wait ()", log_file);
473#endif
474
475 WSETEXIT ((*status), 0);
476
477 timeout = 0; /* Don't time out -- user program is running. */
478
479 expect_prompt(0); /* Wait for prompt, outputting extraneous text */
480
481 WSETSTOP ((*status), SIGTRAP);
482
483 timeout = old_timeout;
484
485 return 0;
486}
487
488/* Return the name of register number regno in the form input and output by
489 monitor. Currently, register_names just happens to contain exactly what
490 monitor wants. Lets take advantage of that just as long as possible! */
491
492static char *
493get_reg_name (regno)
494 int regno;
495{
496 static char buf[50];
497 const char *p;
498 char *b;
499
500 b = buf;
501
502 if (regno < 0)
503 return ("");
504 for (p = reg_names[regno]; *p; p++)
505 *b++ = toupper(*p);
506 *b = '\000';
507
508 return buf;
509}
510
511/* read the remote registers into the block regs. */
512
513static void
514monitor_fetch_registers ()
515{
516 int regno;
517
518 /* yeah yeah, i know this is horribly inefficient. but it isn't done
519 very often... i'll clean it up later. */
520
521 for (regno = 0; regno <= PC_REGNUM; regno++)
522 monitor_fetch_register(regno);
523}
524
525/* Fetch register REGNO, or all registers if REGNO is -1.
526 Returns errno value. */
527static void
528monitor_fetch_register (regno)
529 int regno;
530{
531 int val, j;
532
533#ifdef LOG_FILE
534 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
535 fflush (log_file);
536#endif
537
538 if (regno < 0)
539 {
540 monitor_fetch_registers ();
541 }
542 else
543 {
544 char *name = get_reg_name (regno);
545 printf_monitor (GET_REG, name);
546 expect (name, 1);
547 expect (REG_DELIM, 1);
548 if (strcasecmp (name, "SR") == 0)
549 {
550 val = 0;
551 for (j = 0; j < 4; j++)
552 val = (val << 4) + get_hex_digit (j == 0);
553 supply_register (regno, (char *) &val);
554 }
555 else
556 {
557 get_hex_regs (1, regno);
558 }
559 if (CMD_END)
560 {
561 expect (CMD_DELIM);
562 printf_monitor (CMD_END);
563 }
564 expect_prompt (1);
565 }
566 return;
567}
568
569/* Store the remote registers from the contents of the block REGS. */
570
571static void
572monitor_store_registers ()
573{
574 int regno;
575
576 for (regno = 0; regno <= PC_REGNUM; regno++)
577 monitor_store_register(regno);
578
579 registers_changed ();
580}
581
582/* Store register REGNO, or all if REGNO == 0.
583 return errno value. */
584static void
585monitor_store_register (regno)
586 int regno;
587{
588#ifdef LOG_FILE
589 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
590#endif
591 if (regno == -1)
592 monitor_store_registers ();
593 else
594 {
595 if (kiodebug)
596 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
597
598 printf_monitor (SET_REG, get_reg_name (regno),
599 read_register (regno));
600
601 expect_prompt (1);
602 }
603}
604
605/* Get ready to modify the registers array. On machines which store
606 individual registers, this doesn't need to do anything. On machines
607 which store all the registers in one fell swoop, this makes sure
608 that registers contains all the registers from the program being
609 debugged. */
610
611static void
612monitor_prepare_to_store ()
613{
614 /* Do nothing, since we can store individual regs */
615}
616
617static void
618monitor_files_info ()
619{
620 printf ("\tAttached to %s at %d baud.\n",
621 dev_name, baudrate);
622}
623
624/* Copy LEN bytes of data from debugger memory at MYADDR
625 to inferior's memory at MEMADDR. Returns length moved. */
626static int
627monitor_write_inferior_memory (memaddr, myaddr, len)
628 CORE_ADDR memaddr;
629 unsigned char *myaddr;
630 int len;
631{
632 int i;
633 char buf[10];
634
635#ifdef LOG_FILE
636 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
637#endif
638 for (i = 0; i < len; i++)
639 {
640 printf_monitor (MEM_SET_CMD, memaddr + i);
641 expect (sprintf (buf, MEM_PROMPT, memaddr + i), 1);
642 expect (CMD_DELIM);
643 printf_monitor ("%x", myaddr[i]);
644 if (kiodebug)
645 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
646 if (CMD_END)
647 {
648/*** expect (sprintf (buf, MEM_PROMPT, memaddr + i +1), 1);
649 expect (CMD_DELIM); ***/
650 printf_monitor (CMD_END);
651 }
652 expect_prompt (1);
653 }
654 return len;
655}
656
657/* Read LEN bytes from inferior memory at MEMADDR. Put the result
658 at debugger address MYADDR. Returns length moved. */
659static int
660monitor_read_inferior_memory(memaddr, myaddr, len)
661 CORE_ADDR memaddr;
662 char *myaddr;
663 int len;
664{
665 int i, j;
666 char buf[20];
667
668 /* Number of bytes read so far. */
669 int count;
670
671 /* Starting address of this pass. */
672 unsigned long startaddr;
673
674 /* Number of bytes to read in this pass. */
675 int len_this_pass;
676
677#ifdef LOG_FILE
678 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
679#endif
680
681 /* Note that this code works correctly if startaddr is just less
682 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
683 thing). That is, something like
684 monitor_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
685 works--it never adds len To memaddr and gets 0. */
686 /* However, something like
687 monitor_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
688 doesn't need to work. Detect it and give up if there's an attempt
689 to do that. */
690 if (((memaddr - 1) + len) < memaddr) {
691 errno = EIO;
692 return 0;
693 }
694
695 startaddr = memaddr;
696 count = 0;
697 while (count < len)
698 {
699 len_this_pass = 16;
700 if ((startaddr % 16) != 0)
701 len_this_pass -= startaddr % 16;
702 if (len_this_pass > (len - count))
703 len_this_pass = (len - count);
704 if (kiodebug)
705 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
706
707 for (i = 0; i < len_this_pass; i++)
708 {
709 printf_monitor (MEM_DIS_CMD, startaddr);
710 expect (sprintf(buf, MEM_PROMPT, startaddr), 1);
711 get_hex_byte (&myaddr[count++]);
712 if (kiodebug)
713 printf ("\nRead a 0x%x from 0x%x\n", myaddr[count-1], startaddr);
714 if (CMD_END)
715 {
716 expect (CMD_DELIM);
717 printf_monitor (CMD_END);
718 }
719 expect_prompt (1);
720 startaddr += 1;
721 }
722 }
723 return len;
724}
725
726/* FIXME-someday! merge these two. */
727static int
728monitor_xfer_inferior_memory (memaddr, myaddr, len, write, target)
729 CORE_ADDR memaddr;
730 char *myaddr;
731 int len;
732 int write;
733 struct target_ops *target; /* ignored */
734{
735 if (write)
736 return monitor_write_inferior_memory (memaddr, myaddr, len);
737 else
738 return monitor_read_inferior_memory (memaddr, myaddr, len);
739}
740
741static void
742monitor_kill (args, from_tty)
743 char *args;
744 int from_tty;
745{
746 return; /* ignore attempts to kill target system */
747}
748
749/* Clean up when a program exits.
750 The program actually lives on in the remote processor's RAM, and may be
751 run again without a download. Don't leave it full of breakpoint
752 instructions. */
753
754static void
755monitor_mourn_inferior ()
756{
757 remove_breakpoints ();
758 generic_mourn_inferior (); /* Do all the proper things now */
759}
760
761#define MAX_MONITOR_BREAKPOINTS 16
762
763extern int memory_breakpoint_size;
764static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
765
766static int
767monitor_insert_breakpoint (addr, shadow)
768 CORE_ADDR addr;
769 char *shadow;
770{
771 int i;
772
773#ifdef LOG_FILE
774 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
775#endif
776 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
777 if (breakaddr[i] == 0)
778 {
779 breakaddr[i] = addr;
780 if (kiodebug)
781 printf ("Breakpoint at %x\n", addr);
782 monitor_read_inferior_memory(addr, shadow, memory_breakpoint_size);
783 printf_monitor(SET_BREAK_CMD, addr);
784 expect_prompt(1);
785 return 0;
786 }
787
788 fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
789 return 1;
790}
791
792/*
793 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
794 */
795static int
796monitor_remove_breakpoint (addr, shadow)
797 CORE_ADDR addr;
798 char *shadow;
799{
800 int i;
801
802#ifdef LOG_FILE
803 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
804#endif
805 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
806 if (breakaddr[i] == addr)
807 {
808 breakaddr[i] = 0;
809 /* some monitors remove breakpoints based on the address */
810 if (strcasecmp (target_shortname, "bug") == 0)
811 printf_monitor(CLR_BREAK_CMD, addr);
812 else
813 printf_monitor(CLR_BREAK_CMD, i);
814 expect_prompt(1);
815 return 0;
816 }
817
818 fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
819 return 1;
820}
821
822/* Load a file. This is usually an srecord, which is ascii. No
823 protocol, just sent line by line. */
824
825#define DOWNLOAD_LINE_SIZE 100
826static void
827monitor_load (arg)
828 char *arg;
829{
830 FILE *download;
831 char buf[DOWNLOAD_LINE_SIZE];
832 int i, bytes_read;
833
834 if (kiodebug)
835 printf ("Loading %s to monitor\n", arg);
836
837 download = fopen (arg, "r");
838 if (download == NULL)
839 {
840 error (sprintf (buf, "%s Does not exist", arg));
841 return;
842 }
843
844 printf_monitor (LOAD_CMD);
845/* expect ("Waiting for S-records from host... ", 1); */
846
847 while (!feof (download))
848 {
849 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
850 if (hashmark)
851 {
852 putchar ('.');
853 fflush (stdout);
854 }
855
1724c671
SG
856 if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
857 fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
054240ec
RS
858 break;
859 }
860 i = 0;
861 while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
862 if (bytes_read < DOWNLOAD_LINE_SIZE)
863 {
864 if (!feof (download))
865 error ("Only read %d bytes\n", bytes_read);
866 break;
867 }
868 }
869
870 if (hashmark)
871 {
872 putchar ('\n');
873 }
874 if (!feof (download))
875 error ("Never got EOF while downloading");
876 fclose (download);
877}
878
879/* Put a command string, in args, out to MONITOR. Output from MONITOR is placed
880 on the users terminal until the prompt is seen. */
881
882static void
883monitor_command (args, fromtty)
884 char *args;
885 int fromtty;
886{
887#ifdef LOG_FILE
888 fprintf (log_file, "\nIn command (args=%s)\n", args);
889#endif
5905161c 890 if (monitor_desc == NULL)
054240ec
RS
891 error("monitor target not open.");
892
893 if (!args)
894 error("Missing command.");
895
896 printf_monitor("%s\r", args);
897 expect_prompt(0);
898}
899
1724c671
SG
900#if 0
901
054240ec
RS
902/* Connect the user directly to MONITOR. This command acts just like the
903 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
904
905static struct ttystate ttystate;
906
907static void
908cleanup_tty()
909{ printf("\r\n[Exiting connect mode]\r\n");
1724c671 910 /*SERIAL_RESTORE(0, &ttystate);*/
054240ec
RS
911}
912
913static void
914connect_command (args, fromtty)
915 char *args;
916 int fromtty;
917{
918 fd_set readfds;
919 int numfds;
920 int c;
921 char cur_esc = 0;
922
923 dont_repeat();
924
5905161c 925 if (monitor_desc == NULL)
054240ec
RS
926 error("monitor target not open.");
927
928 if (args)
929 fprintf("This command takes no args. They have been ignored.\n");
930
931 printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
932
933 serial_raw(0, &ttystate);
934
935 make_cleanup(cleanup_tty, 0);
936
937 FD_ZERO(&readfds);
938
939 while (1)
940 {
941 do
942 {
943 FD_SET(0, &readfds);
944 FD_SET(monitor_desc, &readfds);
945 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
946 }
947 while (numfds == 0);
948
949 if (numfds < 0)
950 perror_with_name("select");
951
952 if (FD_ISSET(0, &readfds))
953 { /* tty input, send to monitor */
954 c = getchar();
955 if (c < 0)
956 perror_with_name("connect");
957
958 printf_monitor("%c", c);
959 switch (cur_esc)
960 {
961 case 0:
962 if (c == '\r')
963 cur_esc = c;
964 break;
965 case '\r':
966 if (c == '~')
967 cur_esc = c;
968 else
969 cur_esc = 0;
970 break;
971 case '~':
972 if (c == '.' || c == '\004')
973 return;
974 else
975 cur_esc = 0;
976 }
977 }
978
979 if (FD_ISSET(monitor_desc, &readfds))
980 {
981 while (1)
982 {
983 c = readchar(0);
984 if (c < 0)
985 break;
986 putchar(c);
987 }
988 fflush(stdout);
989 }
990 }
991}
1724c671 992#endif
054240ec
RS
993
994/*
995 * Define the monitor command strings. Since these are passed directly
996 * through to a printf style function, we need can include formatting
997 * strings. We also need a CR or LF on the end.
998 */
999struct monitor_ops rom68k_cmds = {
1000 "go \r", /* execute or usually GO command */
1001 "go \r", /* continue command */
1002 "st \r", /* single step */
1003 "db %x\r", /* set a breakpoint */
1004 "cb %x\r", /* clear a breakpoint */
1005 "pm %x\r", /* set memory to a value */
1006 "pm %x\r", /* display memory */
1007 "-%08X ", /* prompt memory commands use */
1008 "pr %s %x\r", /* set a register */
1009 ": ", /* delimiter between registers */
1010 "pr %s\r", /* read a register */
1011 "dc \r", /* download command */
1012 "ROM68K :->", /* monitor command prompt */
1013 "=", /* end-of-command delimitor */
1014 ".\r" /* optional command terminator */
1015};
1016
1017struct monitor_ops bug_cmds = {
1018 "go \r", /* execute or usually GO command */
1019 "go \r", /* continue command */
1020 "gn \r", /* single step */
1021 "br %x\r", /* set a breakpoint */
1022 "nobr %x\r", /* clear a breakpoint */
1023 "mm %x\r", /* set memory to a value */
1024 "mm %x\r", /* display memory */
1025 "%08X", /* prompt memory commands use */
1026 "rs %s %x\r", /* set a register */
1027 "=", /* delimiter between registers */
1028 "rm %s\r", /* read a register */
1029 "lo 0\r", /* download command */
1030 "Bug>", /* monitor command prompt */
1031 "? ", /* end-of-command delimitor */
1032 ".\r" /* optional command terminator */
1033};
1034
1035/* Define the target subroutine names */
1036struct monitor_ops mon68_cmds = {
1037 "", /* execute or usually GO command */
1038 "", /* continue command */
1039 "", /* single step */
1040 "", /* set a breakpoint */
1041 "", /* clear a breakpoint */
1042 "", /* set memory to a value */
1043 "", /* display memory */
1044 "", /* set a register */
1045 "", /* delimiter between registers */
1046 "", /* read a register */
1047 "", /* download command */
1048 ">", /* monitor command prompt */
1049 "", /* end-of-command delimitor */
1050 "" /* optional command terminator */
1051};
1052
1053struct target_ops rom68k_ops = {
1054 "rom68k",
1055 "Integrated System's ROM68K remote debug monitor",
60a60032
JK
1056 "Use a remote computer running the ROM68K debug monitor.\n\
1057Specify the serial device it is connected to (e.g. /dev/ttya).",
054240ec
RS
1058 rom68k_open,
1059 monitor_close,
1060 0,
1061 monitor_detach,
1062 monitor_resume,
1063 monitor_wait,
1064 monitor_fetch_register,
1065 monitor_store_register,
1066 monitor_prepare_to_store,
1067 monitor_xfer_inferior_memory,
1068 monitor_files_info,
1069 monitor_insert_breakpoint,
1070 monitor_remove_breakpoint, /* Breakpoints */
1071 0,
1072 0,
1073 0,
1074 0,
1075 0, /* Terminal handling */
1076 monitor_kill,
1077 monitor_load, /* load */
1078 0, /* lookup_symbol */
1079 monitor_create_inferior,
1080 monitor_mourn_inferior,
1081 0, /* can_run */
1082 0, /* notice_signals */
1083 process_stratum,
1084 0, /* next */
1085 1,
1086 1,
1087 1,
1088 1,
1089 1, /* all mem, mem, stack, regs, exec */
1090 0,
1091 0, /* Section pointers */
1092 OPS_MAGIC, /* Always the last thing */
1093};
1094
ae87844d 1095struct target_ops monitor_bug_ops = {
054240ec
RS
1096 "bug",
1097 "Motorola's BUG remote serial debug monitor",
60a60032
JK
1098 "Use a remote computer running Motorola's BUG debug monitor.\n\
1099Specify the serial device it is connected to (e.g. /dev/ttya).",
054240ec
RS
1100 bug_open,
1101 monitor_close,
1102 0,
1103 monitor_detach,
1104 monitor_resume,
1105 monitor_wait,
1106 monitor_fetch_register,
1107 monitor_store_register,
1108 monitor_prepare_to_store,
1109 monitor_xfer_inferior_memory,
1110 monitor_files_info,
1111 monitor_insert_breakpoint,
1112 monitor_remove_breakpoint, /* Breakpoints */
1113 0,
1114 0,
1115 0,
1116 0,
1117 0, /* Terminal handling */
1118 monitor_kill,
1119 monitor_load, /* load */
1120 0, /* lookup_symbol */
1121 monitor_create_inferior,
1122 monitor_mourn_inferior,
1123 0, /* can_run */
1124 0, /* notice_signals */
1125 process_stratum,
1126 0, /* next */
1127 1,
1128 1,
1129 1,
1130 1,
1131 1, /* all mem, mem, stack, regs, exec */
1132 0,
1133 0, /* Section pointers */
1134 OPS_MAGIC, /* Always the last thing */
1135};
1136
1137struct target_ops mon68_ops = {
1138 "mon68",
1139 "Intermetric's MON68 remote serial debug monitor",
60a60032
JK
1140 "Use a remote computer running the MON68 debug monitor.\n\
1141Specify the serial device it is connected to (e.g. /dev/ttya).",
054240ec
RS
1142 mon68_open,
1143 monitor_close,
1144 0,
1145 monitor_detach,
1146 monitor_resume,
1147 monitor_wait,
1148 monitor_fetch_register,
1149 monitor_store_register,
1150 monitor_prepare_to_store,
1151 monitor_xfer_inferior_memory,
1152 monitor_files_info,
1153 monitor_insert_breakpoint,
1154 monitor_remove_breakpoint, /* Breakpoints */
1155 0,
1156 0,
1157 0,
1158 0,
1159 0, /* Terminal handling */
1160 monitor_kill,
1161 monitor_load, /* load */
1162 0, /* lookup_symbol */
1163 monitor_create_inferior,
1164 monitor_mourn_inferior,
1165 0, /* can_run */
1166 0, /* notice_signals */
1167 process_stratum,
1168 0, /* next */
1169 1,
1170 1,
1171 1,
1172 1,
1173 1, /* all mem, mem, stack, regs, exec */
1174 0,
1175 0, /* Section pointers */
1176 OPS_MAGIC, /* Always the last thing */
1177};
1178
1179void
1180_initialize_remote_monitors ()
1181{
1182 add_show_from_set (
1183 add_set_cmd ("remotedebug", no_class, var_boolean,
1184 (char *)&kiodebug,
1185 "Set debugging of I/O to a serial based Monitor.\n\
1186When enabled, debugging info is displayed.",
1187 &setlist),
1188 &showlist);
1189 add_show_from_set (
1190 add_set_cmd ("hash", no_class, var_boolean,
1191 (char *)&hashmark,
1192 "Set display of activity while downloading a file.\n\
1193When 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.");
60a60032 1200#if 0
054240ec
RS
1201 add_com ("connect", class_obscure, connect_command,
1202 "Connect the terminal directly up to a serial based command monitor.\n\
1203Use <CR>~. or <CR>~^D to break out.");
60a60032 1204#endif
054240ec
RS
1205
1206 add_target (&rom68k_ops);
1207/* add_target (&mon68_ops); */
ae87844d 1208 add_target (&monitor_bug_ops);
054240ec 1209}
This page took 0.100504 seconds and 4 git commands to generate.