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