OSDN Git Service

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