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