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