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