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