* serial.h, ser-{unix,go32,tcp}.c: Add flush_input and send_break.
authorJim Kingdon <jkingdon@engr.sgi.com>
Wed, 28 Jul 1993 06:45:35 +0000 (06:45 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Wed, 28 Jul 1993 06:45:35 +0000 (06:45 +0000)
* nindy-share/*, remote-nindy.c: Extensive hacking to make it
conform to GDB conventions like using memcpy not bcopy, serial.h,
etc.  This is to make it host on Solaris, AIX, etc.
* Makefile.in: Reflect removed nindy-share files.

gdb/ChangeLog
gdb/remote-nindy.c
gdb/ser-go32.c
gdb/ser-tcp.c
gdb/ser-unix.c
gdb/serial.h

index 43e156c2eec61ff9477acc4251513576fd353399..fa4cf8ddaac1406ffd4fe298f7310c8fe69666c1 100644 (file)
@@ -2,7 +2,11 @@ Tue Jul 27 12:07:38 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
        * remote-udi.c: Remove old comment about download not implemented.
 
-       * serial.h, ser-{unix,go32,tcp}.c: Add flush_input.
+       * serial.h, ser-{unix,go32,tcp}.c: Add flush_input and send_break.
+       * nindy-share/*, remote-nindy.c: Extensive hacking to make it
+       conform to GDB conventions like using memcpy not bcopy, serial.h,
+       etc.  This is to make it host on Solaris, AIX, etc.
+       * Makefile.in: Reflect removed nindy-share files.
 
        * stack.c (print_frame_info): Revise comment about `pathological'
        case (there was a wrong FIXME about text labels; also asm() can
index 55efac778dacd76f295b15290bd7604916163f8c..dd027bfd72c06f5838d6cff500f17d99307d4067 100644 (file)
@@ -113,8 +113,11 @@ NINDY ROM monitor at the other end of the line.
 #include <sys/ioctl.h>
 #include <sys/file.h>
 #include <ctype.h>
+#include "serial.h"
+#if 0
 #include "nindy-share/ttycntl.h"
 #include "nindy-share/demux.h"
+#endif
 #include "nindy-share/env.h"
 #include "nindy-share/stop.h"
 
@@ -139,7 +142,9 @@ char *nindy_ttyname;        /* name of tty to talk to nindy on, or null */
 #define TRUE   1
 #define FALSE  0
 
-int nindy_fd = 0;      /* Descriptor for I/O to NINDY  */
+/* From nindy-share/nindy.c.  */
+extern serial_t nindy_serial;
+
 static int have_regs = 0;      /* 1 iff regs read since i960 last halted */
 static int regs_changed = 0;   /* 1 iff regs were modified since last read */
 
@@ -157,55 +162,15 @@ nindy_fetch_registers PARAMS ((int));
 static void
 nindy_store_registers PARAMS ((int));
 \f
-/* FIXME, we can probably use the normal terminal_inferior stuff here.
-   We have to do terminal_inferior and then set up the passthrough
-   settings initially.  Thereafter, terminal_ours and terminal_inferior
-   will automatically swap the settings around for us.  */
-
-/* Restore TTY to normal operation */
-
-static TTY_STRUCT orig_tty;    /* TTY attributes before entering passthrough */
-
-static void
-restore_tty()
-{
-       ioctl( 0, TIOCSETN, &orig_tty );
-}
-
-
-/* Recover from ^Z or ^C while remote process is running */
-
-static void (*old_ctrlc)();    /* Signal handlers before entering passthrough */
-
-#ifdef SIGTSTP
-static void (*old_ctrlz)();
-#endif
-
-static
-#ifdef USG
-void
-#endif
-cleanup()
-{
-       restore_tty();
-       signal(SIGINT, old_ctrlc);
-#ifdef SIGTSTP
-       signal(SIGTSTP, old_ctrlz);
-#endif
-       error("\n\nYou may need to reset the 80960 and/or reload your program.\n");
-}
-\f
-/* Clean up anything that needs cleaning when losing control.  */
-
 static char *savename;
 
 static void
 nindy_close (quitting)
      int quitting;
 {
-  if (nindy_fd)
-    close (nindy_fd);
-  nindy_fd = 0;
+  if (nindy_serial != NULL)
+    SERIAL_CLOSE (nindy_serial);
+  nindy_serial = NULL;
 
   if (savename)
     free (savename);
@@ -229,25 +194,24 @@ nindy_open (name, from_tty)
   
   nindy_close (0);
 
-       have_regs = regs_changed = 0;
-       dcache_init();
+  have_regs = regs_changed = 0;
+  dcache_init();
 
-       /* Allow user to interrupt the following -- we could hang if
-        * there's no NINDY at the other end of the remote tty.
-        */
-       immediate_quit++;
-       nindy_fd = ninConnect( name, baud_rate? baud_rate: "9600",
-                       nindy_initial_brk, !from_tty, nindy_old_protocol );
-       immediate_quit--;
+  /* Allow user to interrupt the following -- we could hang if there's
+     no NINDY at the other end of the remote tty.  */
+  immediate_quit++;
+  ninConnect(name, baud_rate ? baud_rate : "9600",
+            nindy_initial_brk, !from_tty, nindy_old_protocol);
+  immediate_quit--;
 
-       if ( nindy_fd < 0 ){
-               nindy_fd = 0;
-               error( "Can't open tty '%s'", name );
-       }
+  if (nindy_serial == NULL)
+    {
+      perror_with_name (name);
+    }
 
-        savename = savestring (name, strlen (name));
-       push_target (&nindy_ops);
-       target_fetch_registers(-1);
+  savename = savestring (name, strlen (name));
+  push_target (&nindy_ops);
+  target_fetch_registers(-1);
 }
 
 /* User-initiated quit of nindy operations.  */
@@ -307,6 +271,27 @@ nindy_resume (step, siggnal)
        have_regs = 0;
        ninGo( step );
 }
+\f
+/* FIXME, we can probably use the normal terminal_inferior stuff here.
+   We have to do terminal_inferior and then set up the passthrough
+   settings initially.  Thereafter, terminal_ours and terminal_inferior
+   will automatically swap the settings around for us.  */
+
+struct clean_up_tty_args {
+  serial_ttystate state;
+  serial_t serial;
+};
+
+static void
+clean_up_tty (ptrarg)
+     PTR ptrarg;
+{
+  struct clean_up_tty_args *args = (struct clean_up_tty_args *) ptrarg;
+  SERIAL_SET_TTY_STATE (args->serial, args->state);
+  free (args->state);
+  warning ("\n\n\
+You may need to reset the 80960 and/or reload your program.\n");
+}
 
 /* Wait until the remote machine stops. While waiting, operate in passthrough
  * mode; i.e., pass everything NINDY sends to stdout, and everything from
@@ -319,107 +304,120 @@ static int
 nindy_wait( status )
     WAITTYPE *status;
 {
-       DEMUX_DECL;     /* OS-dependent data needed by DEMUX... macros */
-       char buf[500];  /* FIXME, what is "500" here? */
-       int i, n;
-       unsigned char stop_exit;
-       unsigned char stop_code;
-       TTY_STRUCT tty;
-       long ip_value, fp_value, sp_value;      /* Reg values from stop */
-
-
-       WSETEXIT( (*status), 0 );
-
-       /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
-
-       /* Save current tty attributes, set up signals to restore them.
-        */
-       ioctl( 0, TIOCGETP, &orig_tty );
-       old_ctrlc = signal( SIGINT, cleanup );
-#ifdef SIGTSTP
-       old_ctrlz = signal( SIGTSTP, cleanup );
-#endif
-
-       /* Pass input from keyboard to NINDY as it arrives.
-        * NINDY will interpret <CR> and perform echo.
-        */
-       tty = orig_tty;
-       TTY_NINDYTERM( tty );
-       ioctl( 0, TIOCSETN, &tty );
-
-       while ( 1 ){
-               /* Go to sleep until there's something for us on either
-                * the remote port or stdin.
-                */
-
-               DEMUX_WAIT( nindy_fd );
-
-               /* Pass input through to correct place */
+  fd_set fds;
+  char buf[500];       /* FIXME, what is "500" here? */
+  int i, n;
+  unsigned char stop_exit;
+  unsigned char stop_code;
+  struct clean_up_tty_args tty_args;
+  struct cleanup *old_cleanups;
+  long ip_value, fp_value, sp_value;   /* Reg values from stop */
+
+  WSETEXIT( (*status), 0 );
+
+  /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
+
+  /* Save current tty attributes, and restore them when done.  */
+  tty_args.serial = SERIAL_FDOPEN (0);
+  tty_args.state = SERIAL_GET_TTY_STATE (tty_args.serial);
+  old_cleanups = make_cleanup (clean_up_tty, &tty_args);
+
+  /* Pass input from keyboard to NINDY as it arrives.  NINDY will interpret
+     <CR> and perform echo.  */
+  /* This used to set CBREAK and clear ECHO and CRMOD.  I hope this is close
+     enough.  */
+  SERIAL_RAW (tty_args.serial);
+
+  while (1)
+    {
+      /* Wait for input on either the remote port or stdin.  */
+      FD_ZERO (&fds);
+      FD_SET (0, &fds);
+      FD_SET (nindy_serial->fd, &fds);
+      if (select (nindy_serial->fd + 1, &fds, 0, 0, 0) <= 0)
+       continue;
+
+      /* Pass input through to correct place */
+      if (FD_ISSET (0, &fds))
+       {
+         /* Input on stdin */
+         n = read (0, buf, sizeof (buf));
+         if (n)
+           {
+             SERIAL_WRITE (nindy_serial, buf, n );
+           }
+       }
 
-               n = DEMUX_READ( 0, buf, sizeof(buf) );
-               if ( n ){                               /* Input on stdin */
-                       write( nindy_fd, buf, n );
+      if (FD_ISSET (nindy_serial->fd, &fds))
+       {
+         /* Input on remote */
+         n = read (nindy_serial->fd, buf, sizeof (buf));
+         if (n)
+           {
+             /* Write out any characters in buffer preceding DLE */
+             i = non_dle( buf, n );
+             if ( i > 0 )
+               {
+                 write (1, buf, i);
                }
 
-               n = DEMUX_READ( nindy_fd, buf, sizeof(buf) );
-               if ( n ){                               /* Input on remote */
-                       /* Write out any characters in buffer preceding DLE */
-                       i = non_dle( buf, n );
-                       if ( i > 0 ){
-                               write( 1, buf, i );
-                       }
-
-                       if ( i != n ){
-                               /* There *was* a DLE in the buffer */
-                               stop_exit = ninStopWhy( &stop_code,
-                                       &ip_value, &fp_value, &sp_value);
-                               if ( !stop_exit && (stop_code==STOP_SRQ) ){
-                                       immediate_quit++;
-                                       ninSrq();
-                                       immediate_quit--;
-                               } else {
-                                       /* Get out of loop */
-                                       supply_register (IP_REGNUM, 
-                                                        (char *)&ip_value);
-                                       supply_register (FP_REGNUM, 
-                                                        (char *)&fp_value);
-                                       supply_register (SP_REGNUM, 
-                                                        (char *)&sp_value);
-                                       break;
-                               }
-                       }
+             if (i != n)
+               {
+                 /* There *was* a DLE in the buffer */
+                 stop_exit = ninStopWhy(&stop_code,
+                                        &ip_value, &fp_value, &sp_value);
+                 if (!stop_exit && (stop_code == STOP_SRQ))
+                   {
+                     immediate_quit++;
+                     ninSrq();
+                     immediate_quit--;
+                   }
+                 else
+                   {
+                     /* Get out of loop */
+                     supply_register (IP_REGNUM, 
+                                      (char *)&ip_value);
+                     supply_register (FP_REGNUM, 
+                                      (char *)&fp_value);
+                     supply_register (SP_REGNUM, 
+                                      (char *)&sp_value);
+                     break;
+                   }
                }
+           }
        }
+    }
 
-       signal( SIGINT, old_ctrlc );
-#ifdef SIGTSTP
-       signal( SIGTSTP, old_ctrlz );
-#endif
-       restore_tty();
-
-       if ( stop_exit ){                       /* User program exited */
-               WSETEXIT( (*status), stop_code );
-       } else {                                /* Fault or trace */
-               switch (stop_code){
-               case STOP_GDB_BPT:
-               case TRACE_STEP:
-                       /* Make it look like a VAX trace trap */
-                       stop_code = SIGTRAP;
-                       break;
-               default:
-                       /* The target is not running Unix, and its
-                          faults/traces do not map nicely into Unix signals.
-                          Make sure they do not get confused with Unix signals
-                          by numbering them with values higher than the highest
-                          legal Unix signal.  code in i960_print_fault(),
-                          called via PRINT_RANDOM_SIGNAL, will interpret the
-                          value.  */
-                       stop_code += NSIG;
-                       break;
-               }
-               WSETSTOP( (*status), stop_code );
+  do_cleanups (old_cleanups);
+
+  if (stop_exit)
+    {
+      /* User program exited */
+      WSETEXIT ((*status), stop_code);
+    }
+  else
+    {
+      /* Fault or trace */
+      switch (stop_code)
+       {
+       case STOP_GDB_BPT:
+       case TRACE_STEP:
+         /* Breakpoint or single stepping.  */
+         stop_code = SIGTRAP;
+         break;
+       default:
+         /* The target is not running Unix, and its faults/traces do
+            not map nicely into Unix signals.  Make sure they do not
+            get confused with Unix signals by numbering them with
+            values higher than the highest legal Unix signal.  code
+            in i960_print_fault(), called via PRINT_RANDOM_SIGNAL,
+            will interpret the value.  */
+         stop_code += NSIG;
+         break;
        }
-       return inferior_pid;
+      WSETSTOP ((*status), stop_code);
+    }
+  return inferior_pid;
 }
 
 /* Read the remote registers into the block REGS.  */
@@ -446,11 +444,11 @@ nindy_fetch_registers(regno)
   ninRegsGet( (char *) &nindy_regs );
   immediate_quit--;
 
-  bcopy (nindy_regs.local_regs, &registers[REGISTER_BYTE (R0_REGNUM)], 16*4);
-  bcopy (nindy_regs.global_regs, &registers[REGISTER_BYTE (G0_REGNUM)], 16*4);
-  bcopy (nindy_regs.pcw_acw, &registers[REGISTER_BYTE (PCW_REGNUM)], 2*4);
-  bcopy (nindy_regs.ip, &registers[REGISTER_BYTE (IP_REGNUM)], 1*4);
-  bcopy (nindy_regs.tcw, &registers[REGISTER_BYTE (TCW_REGNUM)], 1*4);
+  memcpy (&registers[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs, 16*4);
+  memcpy (&registers[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16*4);
+  memcpy (&registers[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw, 2*4);
+  memcpy (&registers[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip, 1*4);
+  memcpy (&registers[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw, 1*4);
   for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
     dub = unpack_double (builtin_type_double,
                         &nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
@@ -478,11 +476,11 @@ nindy_store_registers(regno)
   int regnum, inv;
   double dub;
 
-  bcopy (&registers[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs,  16*4);
-  bcopy (&registers[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16*4);
-  bcopy (&registers[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw,     2*4);
-  bcopy (&registers[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip,           1*4);
-  bcopy (&registers[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw,         1*4);
+  memcpy (nindy_regs.local_regs, &registers[REGISTER_BYTE (R0_REGNUM)], 16*4);
+  memcpy (nindy_regs.global_regs, &registers[REGISTER_BYTE (G0_REGNUM)], 16*4);
+  memcpy (nindy_regs.pcw_acw, &registers[REGISTER_BYTE (PCW_REGNUM)], 2*4);
+  memcpy (nindy_regs.ip, &registers[REGISTER_BYTE (IP_REGNUM)], 1*4);
+  memcpy (nindy_regs.tcw, &registers[REGISTER_BYTE (TCW_REGNUM)], 1*4);
   /* Float regs.  Only works on IEEE_FLOAT hosts.  FIXME!  */
   for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
     ieee_extended_to_double (&ext_format_i960,
@@ -493,8 +491,7 @@ nindy_store_registers(regno)
        This mostly works but not quite.  */
     dub = unpack_double (builtin_type_double, (char *)&dub, &inv);
     /* dub now in target byte order */
-    bcopy ((char *)&dub, &nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
-       8);
+    memcpy (&nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)], &dub, 8);
   }
 
   immediate_quit++;
@@ -565,7 +562,7 @@ nindy_xfer_inferior_memory(memaddr, myaddr, len, write, target)
 
       /* Copy data to be written over corresponding part of buffer */
 
-      bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+      memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
 
       /* Write the entire buffer.  */
 
@@ -590,7 +587,7 @@ nindy_xfer_inferior_memory(memaddr, myaddr, len, write, target)
        }
 
       /* Copy appropriate bytes out of the buffer.  */
-      bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+      memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
     }
   return len;
 }
@@ -808,13 +805,15 @@ reset_command(args, from_tty)
      char *args;
      int from_tty;
 {
-       if ( !nindy_fd ){
-           error( "No target system to reset -- use 'target nindy' command.");
-       }
-       if ( query("Really reset the target system?",0,0) ){
-               send_break( nindy_fd );
-               tty_flush( nindy_fd );
-       }
+  if (nindy_serial == NULL)
+    {
+      error( "No target system to reset -- use 'target nindy' command.");
+    }
+  if ( query("Really reset the target system?",0,0) )
+    {
+      SERIAL_SEND_BREAK (nindy_serial);
+      tty_flush (nindy_serial);
+    }
 }
 
 void
index ff1bdf119307aeaffa7082b81786a87b18ac7a7c..905526ddc183cad6f24ab4ef636f03d3ca4cefed 100644 (file)
@@ -267,10 +267,9 @@ go32_open (scb, name)
 }
 
 static int
-go32_flush_output (scb)
+go32_noop (scb)
      serial_t scb;
 {
-  /* No need to flush, because there is no buffering.  */
   return 0;
 }
 
@@ -378,7 +377,9 @@ static struct serial_ops go32_ops =
   go32_close,
   go32_readchar,
   go32_write,
-  go32_flush_output,
+  go32_noop, /* flush output */
+  go32_noop, /* flush input */
+  go32_noop, /* send break -- currently used only for nindy */
   go32_raw,
   go32_get_tty_state,
   go32_set_tty_state,
index 6ff79aa3d4a670dc67b539e3be046ea3bad646c4..f492bc13ccd7987181ddc2ddb199659ddff11c6a 100644 (file)
@@ -141,11 +141,9 @@ tcp_set_tty_state(scb, ttystate)
 }
 
 static int
-tcp_flush_output (scb)
+tcp_return_0 (scb)
      serial_t scb;
 {
-  /* This is only used by utils.c on stdout, so it doesn't need to work
-     for tcp.  */
   return 0;
 }
 
@@ -309,7 +307,9 @@ static struct serial_ops tcp_ops =
   tcp_close,
   tcp_readchar,
   tcp_write,
-  tcp_flush_output,
+  tcp_return_0, /* flush output */
+  tcp_return_0, /* flush input */
+  tcp_return_0, /* send break */
   tcp_raw,
   tcp_get_tty_state,
   tcp_set_tty_state,
index 5f07adec0c5992ee14feb5b2b7158aa1c3ced99e..1f8d738f70ab425f6ce3283ad67489b1fdfd721c 100644 (file)
@@ -326,6 +326,46 @@ hardwire_flush_output (scb)
 #endif  
 }
 
+static int
+hardwire_flush_input (scb)
+     serial_t scb;
+{
+#ifdef HAVE_TERMIOS
+  return tcflush (scb->fd, TCIFLUSH);
+#endif
+
+#ifdef HAVE_TERMIO
+  return ioctl (scb->fd, TCFLSH, 0);
+#endif
+
+#ifdef HAVE_SGTTY
+  /* This flushes both input and output, but we can't do better.  */
+  return ioctl (scb->fd, TIOCFLUSH, 0);
+#endif  
+}
+
+static int
+hardwire_send_break (scb)
+     serial_t scb;
+{
+  int status;
+
+#ifdef HAVE_TERMIOS
+  return tcsendbreak (scb->fd, 0);
+#endif
+
+#ifdef HAVE_TERMIO
+  return ioctl (scb->fd, TCSBRK, 0);
+#endif
+
+#ifdef HAVE_SGTTY
+  status = ioctl (scb->fd, TIOCSBRK, 0);
+  usleep (250000);
+  status = ioctl (scb->fd, TIOCCBRK, 0);
+  return status;
+#endif  
+}
+
 static void
 hardwire_raw(scb)
      serial_t scb;
@@ -607,6 +647,8 @@ static struct serial_ops hardwire_ops =
   hardwire_readchar,
   hardwire_write,
   hardwire_flush_output,
+  hardwire_flush_input,
+  hardwire_send_break,
   hardwire_raw,
   hardwire_get_tty_state,
   hardwire_set_tty_state,
index 630ed43b1f9712cc10983fa99f1b2057a8d470b9..a9dba27212529328d2453e1cd80a822e74e2f392 100644 (file)
@@ -42,6 +42,8 @@ struct serial_ops {
   int (*readchar) PARAMS ((serial_t, int timeout));
   int (*write) PARAMS ((serial_t, const char *str, int len));
   int (*flush_output) PARAMS ((serial_t));
+  int (*flush_input) PARAMS ((serial_t));
+  int (*send_break) PARAMS ((serial_t));
   void (*go_raw) PARAMS ((serial_t));
   serial_ttystate (*get_tty_state) PARAMS ((serial_t));
   int (*set_tty_state) PARAMS ((serial_t, serial_ttystate));
@@ -72,11 +74,23 @@ serial_t serial_fdopen PARAMS ((int fd));
 
 #define SERIAL_FDOPEN(FD) serial_fdopen(FD)
 
-/* Flush pending output.  */
+/* Flush pending output.  Might also flush input (if this system can't flush
+   only output).  */
 
 #define SERIAL_FLUSH_OUTPUT(SERIAL_T) \
   ((SERIAL_T)->ops->flush_output((SERIAL_T)))
 
+/* Flush pending input.  Might also flush output (if this system can't flush
+   only input).  */
+
+#define SERIAL_FLUSH_INPUT(SERIAL_T)\
+  ((*(SERIAL_T)->ops->flush_input) ((SERIAL_T)))
+
+/* Send a break between 0.25 and 0.5 seconds long.  */
+
+#define SERIAL_SEND_BREAK(SERIAL_T) \
+  ((*(SERIAL_T)->ops->send_break) (SERIAL_T))
+
 /* Turn the port into raw mode. */
 
 #define SERIAL_RAW(SERIAL_T) (SERIAL_T)->ops->go_raw((SERIAL_T))