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