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