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