]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/remote-os9k.c
Initial creation of sourceware repository
[thirdparty/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 executable 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 = REGISTER_NAME (regno); *p; p++)
551 *b++ = toupper(*p);
552 *b = '\000';
553 */
554 p = (char *)REGISTER_NAME (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 static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
890
891 static int
892 rombug_insert_breakpoint (addr, shadow)
893 CORE_ADDR addr;
894 char *shadow;
895 {
896 int i;
897 CORE_ADDR bp_addr = addr;
898 int bp_size = 0;
899
900 if (monitor_log)
901 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
902 BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
903
904 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
905 if (breakaddr[i] == 0)
906 {
907 breakaddr[i] = addr;
908 if (sr_get_debug())
909 printf ("Breakpoint at %x\n", addr);
910 rombug_read_inferior_memory (bp_addr, shadow, bp_size);
911 printf_monitor(SET_BREAK_CMD, addr);
912 is_trace_mode = 0;
913 expect_prompt(1);
914 return 0;
915 }
916
917 fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
918 return 1;
919 }
920
921 /*
922 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
923 */
924 static int
925 rombug_remove_breakpoint (addr, shadow)
926 CORE_ADDR addr;
927 char *shadow;
928 {
929 int i;
930
931 if (monitor_log)
932 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
933
934 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
935 if (breakaddr[i] == addr)
936 {
937 breakaddr[i] = 0;
938 printf_monitor(CLR_BREAK_CMD, addr);
939 is_trace_mode = 0;
940 expect_prompt(1);
941 return 0;
942 }
943
944 fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
945 return 1;
946 }
947
948 /* Load a file. This is usually an srecord, which is ascii. No
949 protocol, just sent line by line. */
950
951 #define DOWNLOAD_LINE_SIZE 100
952 static void
953 rombug_load (arg)
954 char *arg;
955 {
956 /* this part comment out for os9* */
957 #if 0
958 FILE *download;
959 char buf[DOWNLOAD_LINE_SIZE];
960 int i, bytes_read;
961
962 if (sr_get_debug())
963 printf ("Loading %s to monitor\n", arg);
964
965 download = fopen (arg, "r");
966 if (download == NULL)
967 {
968 error (sprintf (buf, "%s Does not exist", arg));
969 return;
970 }
971
972 printf_monitor (LOAD_CMD);
973 /* expect ("Waiting for S-records from host... ", 1); */
974
975 while (!feof (download))
976 {
977 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
978 if (hashmark)
979 {
980 putchar ('.');
981 fflush (stdout);
982 }
983
984 if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
985 fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
986 break;
987 }
988 i = 0;
989 while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
990 if (bytes_read < DOWNLOAD_LINE_SIZE)
991 {
992 if (!feof (download))
993 error ("Only read %d bytes\n", bytes_read);
994 break;
995 }
996 }
997
998 if (hashmark)
999 {
1000 putchar ('\n');
1001 }
1002 if (!feof (download))
1003 error ("Never got EOF while downloading");
1004 fclose (download);
1005 #endif 0
1006 }
1007
1008 /* Put a command string, in args, out to MONITOR.
1009 Output from MONITOR is placed on the users terminal until the prompt
1010 is seen. */
1011
1012 static void
1013 rombug_command (args, fromtty)
1014 char *args;
1015 int fromtty;
1016 {
1017 if (monitor_desc == NULL)
1018 error("monitor target not open.");
1019
1020 if (monitor_log)
1021 fprintf (log_file, "\nIn command (args=%s)\n", args);
1022
1023 if (!args)
1024 error("Missing command.");
1025
1026 printf_monitor("%s\r", args);
1027 expect_prompt(0);
1028 }
1029
1030 #if 0
1031 /* Connect the user directly to MONITOR. This command acts just like the
1032 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
1033
1034 static struct ttystate ttystate;
1035
1036 static void
1037 cleanup_tty()
1038 { printf("\r\n[Exiting connect mode]\r\n");
1039 /*SERIAL_RESTORE(0, &ttystate);*/
1040 }
1041
1042 static void
1043 connect_command (args, fromtty)
1044 char *args;
1045 int fromtty;
1046 {
1047 fd_set readfds;
1048 int numfds;
1049 int c;
1050 char cur_esc = 0;
1051
1052 dont_repeat();
1053
1054 if (monitor_desc == NULL)
1055 error("monitor target not open.");
1056
1057 if (args)
1058 fprintf("This command takes no args. They have been ignored.\n");
1059
1060 printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
1061
1062 serial_raw(0, &ttystate);
1063
1064 make_cleanup(cleanup_tty, 0);
1065
1066 FD_ZERO(&readfds);
1067
1068 while (1)
1069 {
1070 do
1071 {
1072 FD_SET(0, &readfds);
1073 FD_SET(monitor_desc, &readfds);
1074 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1075 }
1076 while (numfds == 0);
1077
1078 if (numfds < 0)
1079 perror_with_name("select");
1080
1081 if (FD_ISSET(0, &readfds))
1082 { /* tty input, send to monitor */
1083 c = getchar();
1084 if (c < 0)
1085 perror_with_name("connect");
1086
1087 printf_monitor("%c", c);
1088 switch (cur_esc)
1089 {
1090 case 0:
1091 if (c == '\r')
1092 cur_esc = c;
1093 break;
1094 case '\r':
1095 if (c == '~')
1096 cur_esc = c;
1097 else
1098 cur_esc = 0;
1099 break;
1100 case '~':
1101 if (c == '.' || c == '\004')
1102 return;
1103 else
1104 cur_esc = 0;
1105 }
1106 }
1107
1108 if (FD_ISSET(monitor_desc, &readfds))
1109 {
1110 while (1)
1111 {
1112 c = readchar(0);
1113 if (c < 0)
1114 break;
1115 putchar(c);
1116 }
1117 fflush(stdout);
1118 }
1119 }
1120 }
1121 #endif
1122
1123 /*
1124 * Define the monitor command strings. Since these are passed directly
1125 * through to a printf style function, we need can include formatting
1126 * strings. We also need a CR or LF on the end.
1127 */
1128 #warning FIXME: monitor interface pattern strings, stale struct decl
1129 struct monitor_ops rombug_cmds = {
1130 "g \r", /* execute or usually GO command */
1131 "g \r", /* continue command */
1132 "t \r", /* single step */
1133 "b %x\r", /* set a breakpoint */
1134 "k %x\r", /* clear a breakpoint */
1135 "c %x\r", /* set memory to a value */
1136 "d %x %d\r", /* display memory */
1137 "$%08X", /* prompt memory commands use */
1138 ".%s %x\r", /* set a register */
1139 ":", /* delimiter between registers */
1140 ". \r", /* read a register */
1141 "mf \r", /* download command */
1142 "RomBug: ", /* monitor command prompt */
1143 ": ", /* end-of-command delimitor */
1144 ".\r" /* optional command terminator */
1145 };
1146
1147 struct target_ops rombug_ops ;
1148
1149 static void
1150 init_rombug_ops(void)
1151 {
1152 rombug_ops.to_shortname = "rombug";
1153 rombug_ops.to_longname = "Microware's ROMBUG debug monitor";
1154 rombug_ops.to_doc = "Use a remote computer running the ROMBUG debug monitor.\n\
1155 Specify the serial device it is connected to (e.g. /dev/ttya).",
1156 rombug_ops.to_open = rombug_open;
1157 rombug_ops.to_close = rombug_close;
1158 rombug_ops.to_attach = 0;
1159 rombug_ops.to_post_attach = NULL;
1160 rombug_ops.to_require_attach = NULL;
1161 rombug_ops.to_detach = rombug_detach;
1162 rombug_ops.to_require_detach = NULL;
1163 rombug_ops.to_resume = rombug_resume;
1164 rombug_ops.to_wait = rombug_wait;
1165 rombug_ops.to_post_wait = NULL;
1166 rombug_ops.to_fetch_registers = rombug_fetch_register;
1167 rombug_ops.to_store_registers = rombug_store_register;
1168 rombug_ops.to_prepare_to_store = rombug_prepare_to_store;
1169 rombug_ops.to_xfer_memory = rombug_xfer_inferior_memory;
1170 rombug_ops.to_files_info = rombug_files_info;
1171 rombug_ops.to_insert_breakpoint = rombug_insert_breakpoint;
1172 rombug_ops.to_remove_breakpoint = rombug_remove_breakpoint; /* Breakpoints */
1173 rombug_ops.to_terminal_init = 0;
1174 rombug_ops.to_terminal_inferior = 0;
1175 rombug_ops.to_terminal_ours_for_output = 0;
1176 rombug_ops.to_terminal_ours = 0;
1177 rombug_ops.to_terminal_info = 0; /* Terminal handling */
1178 rombug_ops.to_kill = rombug_kill;
1179 rombug_ops.to_load = rombug_load; /* load */
1180 rombug_ops.to_lookup_symbol = rombug_link; /* lookup_symbol */
1181 rombug_ops.to_create_inferior = rombug_create_inferior;
1182 rombug_ops.to_post_startup_inferior = NULL;
1183 rombug_ops.to_acknowledge_created_inferior = NULL;
1184 rombug_ops.to_clone_and_follow_inferior = NULL;
1185 rombug_ops.to_post_follow_inferior_by_clone = NULL;
1186 rombug_ops.to_insert_fork_catchpoint = NULL;
1187 rombug_ops.to_remove_fork_catchpoint = NULL;
1188 rombug_ops.to_insert_vfork_catchpoint = NULL;
1189 rombug_ops.to_remove_vfork_catchpoint = NULL;
1190 rombug_ops.to_has_forked = NULL;
1191 rombug_ops.to_has_vforked = NULL;
1192 rombug_ops.to_can_follow_vfork_prior_to_exec = NULL;
1193 rombug_ops.to_post_follow_vfork = NULL;
1194 rombug_ops.to_insert_exec_catchpoint = NULL;
1195 rombug_ops.to_remove_exec_catchpoint = NULL;
1196 rombug_ops.to_has_execd = NULL;
1197 rombug_ops.to_reported_exec_events_per_exec_call = NULL;
1198 rombug_ops.to_has_exited = NULL;
1199 rombug_ops.to_mourn_inferior = rombug_mourn_inferior;
1200 rombug_ops.to_can_run = 0; /* can_run */
1201 rombug_ops.to_notice_signals = 0; /* notice_signals */
1202 rombug_ops.to_thread_alive = 0;
1203 rombug_ops.to_stop = 0; /* to_stop */
1204 rombug_ops.to_pid_to_exec_file = NULL;
1205 rombug_ops.to_core_file_to_sym_file = NULL;
1206 rombug_ops.to_stratum = process_stratum;
1207 rombug_ops.DONT_USE = 0; /* next */
1208 rombug_ops.to_has_all_memory = 1;
1209 rombug_ops.to_has_memory = 1;
1210 rombug_ops.to_has_stack = 1;
1211 rombug_ops.to_has_registers = 1;
1212 rombug_ops.to_has_execution = 1; /* has execution */
1213 rombug_ops.to_sections = 0;
1214 rombug_ops.to_sections_end = 0; /* Section pointers */
1215 rombug_ops.to_magic = OPS_MAGIC; /* Always the last thing */
1216 }
1217
1218 void
1219 _initialize_remote_os9k ()
1220 {
1221 init_rombug_ops() ;
1222 add_target (&rombug_ops);
1223
1224 add_show_from_set (
1225 add_set_cmd ("hash", no_class, var_boolean, (char *)&hashmark,
1226 "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
1227 &setlist),
1228 &showlist);
1229
1230 add_show_from_set (
1231 add_set_cmd ("timeout", no_class, var_zinteger,
1232 (char *) &timeout,
1233 "Set timeout in seconds for remote MIPS serial I/O.",
1234 &setlist),
1235 &showlist);
1236
1237 add_show_from_set (
1238 add_set_cmd ("remotelog", no_class, var_zinteger,
1239 (char *) &monitor_log,
1240 "Set monitor activity log on(=1) or off(=0).",
1241 &setlist),
1242 &showlist);
1243
1244 add_show_from_set (
1245 add_set_cmd ("remotexon", no_class, var_zinteger,
1246 (char *) &tty_xon,
1247 "Set remote tty line XON control",
1248 &setlist),
1249 &showlist);
1250
1251 add_show_from_set (
1252 add_set_cmd ("remotexoff", no_class, var_zinteger,
1253 (char *) &tty_xoff,
1254 "Set remote tty line XOFF control",
1255 &setlist),
1256 &showlist);
1257
1258 add_com ("rombug <command>", class_obscure, rombug_command,
1259 "Send a command to the debug monitor.");
1260 #if 0
1261 add_com ("connect", class_obscure, connect_command,
1262 "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");
1263 #endif
1264 }