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