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