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