* symfile.{c,h} (generic_load): New function.
[platform/upstream/binutils.git] / gdb / remote-nindy.c
1 /* Memory-access and commands for remote NINDY process, for GDB.
2    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3    Contributed by Intel Corporation.  Modified from remote.c by Chris Benenati.
4
5 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
6 WARRANTY.  No author or distributor accepts responsibility to anyone
7 for the consequences of using it or for whether it serves any
8 particular purpose or works at all, unless he says so in writing.
9 Refer to the GDB General Public License for full details.
10
11 Everyone is granted permission to copy, modify and redistribute GDB,
12 but only under the conditions described in the GDB General Public
13 License.  A copy of this license is supposed to have been given to you
14 along with GDB so you can know your rights and responsibilities.  It
15 should be in a file named COPYING.  Among other things, the copyright
16 notice and this notice must be preserved on all copies.
17
18 In other words, go ahead and share GDB, but don't try to stop
19 anyone else from sharing it farther.  Help stamp out software hoarding!
20 */
21
22 /*
23 Except for the data cache routines, this file bears little resemblence
24 to remote.c.  A new (although similar) protocol has been specified, and
25 portions of the code are entirely dependent on having an i80960 with a
26 NINDY ROM monitor at the other end of the line.
27 */
28
29 /*****************************************************************************
30  *
31  * REMOTE COMMUNICATION PROTOCOL BETWEEN GDB960 AND THE NINDY ROM MONITOR.
32  *
33  *
34  * MODES OF OPERATION
35  * ----- -- ---------
36  *      
37  * As far as NINDY is concerned, GDB is always in one of two modes: command
38  * mode or passthrough mode.
39  *
40  * In command mode (the default) pre-defined packets containing requests
41  * are sent by GDB to NINDY.  NINDY never talks except in reponse to a request.
42  *
43  * Once the the user program is started, GDB enters passthrough mode, to give
44  * the user program access to the terminal.  GDB remains in this mode until
45  * NINDY indicates that the program has stopped.
46  *
47  *
48  * PASSTHROUGH MODE
49  * ----------- ----
50  *
51  * GDB writes all input received from the keyboard directly to NINDY, and writes
52  * all characters received from NINDY directly to the monitor.
53  *
54  * Keyboard input is neither buffered nor echoed to the monitor.
55  *
56  * GDB remains in passthrough mode until NINDY sends a single ^P character,
57  * to indicate that the user process has stopped.
58  *
59  * Note:
60  *      GDB assumes NINDY performs a 'flushreg' when the user program stops.
61  *
62  *
63  * COMMAND MODE
64  * ------- ----
65  *
66  * All info (except for message ack and nak) is transferred between gdb
67  * and the remote processor in messages of the following format:
68  *
69  *              <info>#<checksum>
70  *
71  * where 
72  *      #       is a literal character
73  *
74  *      <info>  ASCII information;  all numeric information is in the
75  *              form of hex digits ('0'-'9' and lowercase 'a'-'f').
76  *
77  *      <checksum>
78  *              is a pair of ASCII hex digits representing an 8-bit
79  *              checksum formed by adding together each of the
80  *              characters in <info>.
81  *
82  * The receiver of a message always sends a single character to the sender
83  * to indicate that the checksum was good ('+') or bad ('-');  the sender
84  * re-transmits the entire message over until a '+' is received.
85  *
86  * In response to a command NINDY always sends back either data or
87  * a result code of the form "Xnn", where "nn" are hex digits and "X00"
88  * means no errors.  (Exceptions: the "s" and "c" commands don't respond.)
89  *
90  * SEE THE HEADER OF THE FILE "gdb.c" IN THE NINDY MONITOR SOURCE CODE FOR A
91  * FULL DESCRIPTION OF LEGAL COMMANDS.
92  *
93  * SEE THE FILE "stop.h" IN THE NINDY MONITOR SOURCE CODE FOR A LIST
94  * OF STOP CODES.
95  *
96  ******************************************************************************/
97
98 #include "defs.h"
99 #include <signal.h>
100 #include <sys/types.h>
101 #include <setjmp.h>
102
103 #include "frame.h"
104 #include "inferior.h"
105 #include "symfile.h"
106 #include "target.h"
107 #include "gdbcore.h"
108 #include "command.h"
109 #include "bfd.h"
110 #include "ieee-float.h"
111
112 #include "wait.h"
113 #include <sys/ioctl.h>
114 #include <sys/file.h>
115 #include <ctype.h>
116 #include "nindy-share/ttycntl.h"
117 #include "nindy-share/demux.h"
118 #include "nindy-share/env.h"
119 #include "nindy-share/stop.h"
120
121 extern int unlink();
122 extern char *getenv();
123 extern char *mktemp();
124
125 extern void generic_mourn_inferior ();
126
127 extern struct target_ops nindy_ops;
128 extern jmp_buf to_top_level;
129 extern FILE *instream;
130 extern struct ext_format ext_format_i960;       /* i960-tdep.c */
131
132 extern char ninStopWhy ();
133
134 int nindy_initial_brk;  /* nonzero if want to send an initial BREAK to nindy */
135 int nindy_old_protocol; /* nonzero if want to use old protocol */
136 char *nindy_ttyname;    /* name of tty to talk to nindy on, or null */
137
138 #define DLE     '\020'  /* Character NINDY sends to indicate user program has
139                          * halted.  */
140 #define TRUE    1
141 #define FALSE   0
142
143 int nindy_fd = 0;       /* Descriptor for I/O to NINDY  */
144 static int have_regs = 0;       /* 1 iff regs read since i960 last halted */
145 static int regs_changed = 0;    /* 1 iff regs were modified since last read */
146
147 extern char *exists();
148
149 static void
150 dcache_flush (), dcache_poke (), dcache_init();
151
152 static int
153 dcache_fetch ();
154
155 static void
156 nindy_fetch_registers PARAMS ((int));
157
158 static void
159 nindy_store_registers PARAMS ((int));
160 \f
161 /* FIXME, we can probably use the normal terminal_inferior stuff here.
162    We have to do terminal_inferior and then set up the passthrough
163    settings initially.  Thereafter, terminal_ours and terminal_inferior
164    will automatically swap the settings around for us.  */
165
166 /* Restore TTY to normal operation */
167
168 static TTY_STRUCT orig_tty;     /* TTY attributes before entering passthrough */
169
170 static void
171 restore_tty()
172 {
173         ioctl( 0, TIOCSETN, &orig_tty );
174 }
175
176
177 /* Recover from ^Z or ^C while remote process is running */
178
179 static void (*old_ctrlc)();    /* Signal handlers before entering passthrough */
180
181 #ifdef SIGTSTP
182 static void (*old_ctrlz)();
183 #endif
184
185 static
186 #ifdef USG
187 void
188 #endif
189 cleanup()
190 {
191         restore_tty();
192         signal(SIGINT, old_ctrlc);
193 #ifdef SIGTSTP
194         signal(SIGTSTP, old_ctrlz);
195 #endif
196         error("\n\nYou may need to reset the 80960 and/or reload your program.\n");
197 }
198 \f
199 /* Clean up anything that needs cleaning when losing control.  */
200
201 static char *savename;
202
203 static void
204 nindy_close (quitting)
205      int quitting;
206 {
207   if (nindy_fd)
208     close (nindy_fd);
209   nindy_fd = 0;
210
211   if (savename)
212     free (savename);
213   savename = 0;
214 }
215
216 /* Open a connection to a remote debugger.   
217    FIXME, there should be a way to specify the various options that are
218    now specified with gdb command-line options.  (baud_rate, old_protocol,
219    and initial_brk)  */
220 void
221 nindy_open (name, from_tty)
222     char *name;         /* "/dev/ttyXX", "ttyXX", or "XX": tty to be opened */
223     int from_tty;
224 {
225
226   if (!name)
227     error_no_arg ("serial port device name");
228
229   target_preopen (from_tty);
230   
231   nindy_close (0);
232
233         have_regs = regs_changed = 0;
234         dcache_init();
235
236         /* Allow user to interrupt the following -- we could hang if
237          * there's no NINDY at the other end of the remote tty.
238          */
239         immediate_quit++;
240         nindy_fd = ninConnect( name, baud_rate? baud_rate: "9600",
241                         nindy_initial_brk, !from_tty, nindy_old_protocol );
242         immediate_quit--;
243
244         if ( nindy_fd < 0 ){
245                 nindy_fd = 0;
246                 error( "Can't open tty '%s'", name );
247         }
248
249         savename = savestring (name, strlen (name));
250         push_target (&nindy_ops);
251         target_fetch_registers(-1);
252 }
253
254 /* User-initiated quit of nindy operations.  */
255
256 static void
257 nindy_detach (name, from_tty)
258      char *name;
259      int from_tty;
260 {
261   if (name)
262     error ("Too many arguments");
263   pop_target ();
264 }
265
266 static void
267 nindy_files_info ()
268 {
269   printf("\tAttached to %s at %s bps%s%s.\n", savename,
270          baud_rate? baud_rate: "9600",
271          nindy_old_protocol? " in old protocol": "",
272          nindy_initial_brk? " with initial break": "");
273 }
274 \f
275 /* Return the number of characters in the buffer before
276    the first DLE character.  */
277
278 static
279 int
280 non_dle( buf, n )
281     char *buf;          /* Character buffer; NOT '\0'-terminated */
282     int n;              /* Number of characters in buffer */
283 {
284         int i;
285
286         for ( i = 0; i < n; i++ ){
287                 if ( buf[i] == DLE ){
288                         break;
289                 }
290         }
291         return i;
292 }
293 \f
294 /* Tell the remote machine to resume.  */
295
296 void
297 nindy_resume (step, siggnal)
298      int step, siggnal;
299 {
300         if (siggnal != 0 && siggnal != stop_signal)
301           error ("Can't send signals to remote NINDY targets.");
302
303         dcache_flush();
304         if ( regs_changed ){
305                 nindy_store_registers (-1);
306                 regs_changed = 0;
307         }
308         have_regs = 0;
309         ninGo( step );
310 }
311
312 /* Wait until the remote machine stops. While waiting, operate in passthrough
313  * mode; i.e., pass everything NINDY sends to stdout, and everything from
314  * stdin to NINDY.
315  *
316  * Return to caller, storing status in 'status' just as `wait' would.
317  */
318
319 static int
320 nindy_wait( status )
321     WAITTYPE *status;
322 {
323         DEMUX_DECL;     /* OS-dependent data needed by DEMUX... macros */
324         char buf[500];  /* FIXME, what is "500" here? */
325         int i, n;
326         unsigned char stop_exit;
327         unsigned char stop_code;
328         TTY_STRUCT tty;
329         long ip_value, fp_value, sp_value;      /* Reg values from stop */
330
331
332         WSETEXIT( (*status), 0 );
333
334         /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
335
336         /* Save current tty attributes, set up signals to restore them.
337          */
338         ioctl( 0, TIOCGETP, &orig_tty );
339         old_ctrlc = signal( SIGINT, cleanup );
340 #ifdef SIGTSTP
341         old_ctrlz = signal( SIGTSTP, cleanup );
342 #endif
343
344         /* Pass input from keyboard to NINDY as it arrives.
345          * NINDY will interpret <CR> and perform echo.
346          */
347         tty = orig_tty;
348         TTY_NINDYTERM( tty );
349         ioctl( 0, TIOCSETN, &tty );
350
351         while ( 1 ){
352                 /* Go to sleep until there's something for us on either
353                  * the remote port or stdin.
354                  */
355
356                 DEMUX_WAIT( nindy_fd );
357
358                 /* Pass input through to correct place */
359
360                 n = DEMUX_READ( 0, buf, sizeof(buf) );
361                 if ( n ){                               /* Input on stdin */
362                         write( nindy_fd, buf, n );
363                 }
364
365                 n = DEMUX_READ( nindy_fd, buf, sizeof(buf) );
366                 if ( n ){                               /* Input on remote */
367                         /* Write out any characters in buffer preceding DLE */
368                         i = non_dle( buf, n );
369                         if ( i > 0 ){
370                                 write( 1, buf, i );
371                         }
372
373                         if ( i != n ){
374                                 /* There *was* a DLE in the buffer */
375                                 stop_exit = ninStopWhy( &stop_code,
376                                         &ip_value, &fp_value, &sp_value);
377                                 if ( !stop_exit && (stop_code==STOP_SRQ) ){
378                                         immediate_quit++;
379                                         ninSrq();
380                                         immediate_quit--;
381                                 } else {
382                                         /* Get out of loop */
383                                         supply_register (IP_REGNUM, 
384                                                          (char *)&ip_value);
385                                         supply_register (FP_REGNUM, 
386                                                          (char *)&fp_value);
387                                         supply_register (SP_REGNUM, 
388                                                          (char *)&sp_value);
389                                         break;
390                                 }
391                         }
392                 }
393         }
394
395         signal( SIGINT, old_ctrlc );
396 #ifdef SIGTSTP
397         signal( SIGTSTP, old_ctrlz );
398 #endif
399         restore_tty();
400
401         if ( stop_exit ){                       /* User program exited */
402                 WSETEXIT( (*status), stop_code );
403         } else {                                /* Fault or trace */
404                 switch (stop_code){
405                 case STOP_GDB_BPT:
406                 case TRACE_STEP:
407                         /* Make it look like a VAX trace trap */
408                         stop_code = SIGTRAP;
409                         break;
410                 default:
411                         /* The target is not running Unix, and its
412                            faults/traces do not map nicely into Unix signals.
413                            Make sure they do not get confused with Unix signals
414                            by numbering them with values higher than the highest
415                            legal Unix signal.  code in i960_print_fault(),
416                            called via PRINT_RANDOM_SIGNAL, will interpret the
417                            value.  */
418                         stop_code += NSIG;
419                         break;
420                 }
421                 WSETSTOP( (*status), stop_code );
422         }
423         return inferior_pid;
424 }
425
426 /* Read the remote registers into the block REGS.  */
427
428 /* This is the block that ninRegsGet and ninRegsPut handles.  */
429 struct nindy_regs {
430   char  local_regs[16 * 4];
431   char  global_regs[16 * 4];
432   char  pcw_acw[2 * 4];
433   char  ip[4];
434   char  tcw[4];
435   char  fp_as_double[4 * 8];
436 };
437
438 static void
439 nindy_fetch_registers(regno)
440      int regno;
441 {
442   struct nindy_regs nindy_regs;
443   int regnum, inv;
444   double dub;
445
446   immediate_quit++;
447   ninRegsGet( (char *) &nindy_regs );
448   immediate_quit--;
449
450   bcopy (nindy_regs.local_regs, &registers[REGISTER_BYTE (R0_REGNUM)], 16*4);
451   bcopy (nindy_regs.global_regs, &registers[REGISTER_BYTE (G0_REGNUM)], 16*4);
452   bcopy (nindy_regs.pcw_acw, &registers[REGISTER_BYTE (PCW_REGNUM)], 2*4);
453   bcopy (nindy_regs.ip, &registers[REGISTER_BYTE (IP_REGNUM)], 1*4);
454   bcopy (nindy_regs.tcw, &registers[REGISTER_BYTE (TCW_REGNUM)], 1*4);
455   for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
456     dub = unpack_double (builtin_type_double,
457                          &nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
458                          &inv);
459     /* dub now in host byte order */
460     double_to_ieee_extended (&ext_format_i960, &dub,
461                              &registers[REGISTER_BYTE (regnum)]);
462   }
463
464   registers_fetched ();
465 }
466
467 static void
468 nindy_prepare_to_store()
469 {
470   /* Fetch all regs if they aren't already here.  */
471   read_register_bytes (0, NULL, REGISTER_BYTES);
472 }
473
474 static void
475 nindy_store_registers(regno)
476      int regno;
477 {
478   struct nindy_regs nindy_regs;
479   int regnum, inv;
480   double dub;
481
482   bcopy (&registers[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs,  16*4);
483   bcopy (&registers[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16*4);
484   bcopy (&registers[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw,     2*4);
485   bcopy (&registers[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip,           1*4);
486   bcopy (&registers[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw,         1*4);
487   /* Float regs.  Only works on IEEE_FLOAT hosts.  FIXME!  */
488   for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
489     ieee_extended_to_double (&ext_format_i960,
490                              &registers[REGISTER_BYTE (regnum)], &dub);
491     /* dub now in host byte order */
492     /* FIXME-someday, the arguments to unpack_double are backward.
493        It expects a target double and returns a host; we pass the opposite.
494        This mostly works but not quite.  */
495     dub = unpack_double (builtin_type_double, (char *)&dub, &inv);
496     /* dub now in target byte order */
497     bcopy ((char *)&dub, &nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
498         8);
499   }
500
501   immediate_quit++;
502   ninRegsPut( (char *) &nindy_regs );
503   immediate_quit--;
504 }
505
506 /* Read a word from remote address ADDR and return it.
507  * This goes through the data cache.
508  */
509 int
510 nindy_fetch_word (addr)
511      CORE_ADDR addr;
512 {
513         return dcache_fetch (addr);
514 }
515
516 /* Write a word WORD into remote address ADDR.
517    This goes through the data cache.  */
518
519 void
520 nindy_store_word (addr, word)
521      CORE_ADDR addr;
522      int word;
523 {
524         dcache_poke (addr, word);
525 }
526
527 /* Copy LEN bytes to or from inferior's memory starting at MEMADDR
528    to debugger memory starting at MYADDR.   Copy to inferior if
529    WRITE is nonzero.  Returns the length copied.
530
531    This is stolen almost directly from infptrace.c's child_xfer_memory,
532    which also deals with a word-oriented memory interface.  Sometime,
533    FIXME, rewrite this to not use the word-oriented routines.  */
534
535 int
536 nindy_xfer_inferior_memory(memaddr, myaddr, len, write, target)
537      CORE_ADDR memaddr;
538      char *myaddr;
539      int len;
540      int write;
541      struct target_ops *target;                 /* ignored */
542 {
543   register int i;
544   /* Round starting address down to longword boundary.  */
545   register CORE_ADDR addr = memaddr & - sizeof (int);
546   /* Round ending address up; get number of longwords that makes.  */
547   register int count
548     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
549   /* Allocate buffer of that many longwords.  */
550   register int *buffer = (int *) alloca (count * sizeof (int));
551
552   if (write)
553     {
554       /* Fill start and end extra bytes of buffer with existing memory data.  */
555
556       if (addr != memaddr || len < (int)sizeof (int)) {
557         /* Need part of initial word -- fetch it.  */
558         buffer[0] = nindy_fetch_word (addr);
559       }
560
561       if (count > 1)            /* FIXME, avoid if even boundary */
562         {
563           buffer[count - 1]
564             = nindy_fetch_word (addr + (count - 1) * sizeof (int));
565         }
566
567       /* Copy data to be written over corresponding part of buffer */
568
569       bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
570
571       /* Write the entire buffer.  */
572
573       for (i = 0; i < count; i++, addr += sizeof (int))
574         {
575           errno = 0;
576           nindy_store_word (addr, buffer[i]);
577           if (errno)
578             return 0;
579         }
580     }
581   else
582     {
583       /* Read all the longwords */
584       for (i = 0; i < count; i++, addr += sizeof (int))
585         {
586           errno = 0;
587           buffer[i] = nindy_fetch_word (addr);
588           if (errno)
589             return 0;
590           QUIT;
591         }
592
593       /* Copy appropriate bytes out of the buffer.  */
594       bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
595     }
596   return len;
597 }
598 \f
599 /* The data cache records all the data read from the remote machine
600    since the last time it stopped.
601
602    Each cache block holds 16 bytes of data
603    starting at a multiple-of-16 address.  */
604
605 #define DCACHE_SIZE 64          /* Number of cache blocks */
606
607 struct dcache_block {
608         struct dcache_block *next, *last;
609         unsigned int addr;      /* Address for which data is recorded.  */
610         int data[4];
611 };
612
613 struct dcache_block dcache_free, dcache_valid;
614
615 /* Free all the data cache blocks, thus discarding all cached data.  */ 
616 static
617 void
618 dcache_flush ()
619 {
620   register struct dcache_block *db;
621
622   while ((db = dcache_valid.next) != &dcache_valid)
623     {
624       remque (db);
625       insque (db, &dcache_free);
626     }
627 }
628
629 /*
630  * If addr is present in the dcache, return the address of the block
631  * containing it.
632  */
633 static
634 struct dcache_block *
635 dcache_hit (addr)
636      unsigned int addr;
637 {
638   register struct dcache_block *db;
639
640   if (addr & 3)
641     abort ();
642
643   /* Search all cache blocks for one that is at this address.  */
644   db = dcache_valid.next;
645   while (db != &dcache_valid)
646     {
647       if ((addr & 0xfffffff0) == db->addr)
648         return db;
649       db = db->next;
650     }
651   return NULL;
652 }
653
654 /*  Return the int data at address ADDR in dcache block DC.  */
655 static
656 int
657 dcache_value (db, addr)
658      struct dcache_block *db;
659      unsigned int addr;
660 {
661   if (addr & 3)
662     abort ();
663   return (db->data[(addr>>2)&3]);
664 }
665
666 /* Get a free cache block, put or keep it on the valid list,
667    and return its address.  The caller should store into the block
668    the address and data that it describes, then remque it from the
669    free list and insert it into the valid list.  This procedure
670    prevents errors from creeping in if a ninMemGet is interrupted
671    (which used to put garbage blocks in the valid list...).  */
672 static
673 struct dcache_block *
674 dcache_alloc ()
675 {
676   register struct dcache_block *db;
677
678   if ((db = dcache_free.next) == &dcache_free)
679     {
680       /* If we can't get one from the free list, take last valid and put
681          it on the free list.  */
682       db = dcache_valid.last;
683       remque (db);
684       insque (db, &dcache_free);
685     }
686
687   remque (db);
688   insque (db, &dcache_valid);
689   return (db);
690 }
691
692 /* Return the contents of the word at address ADDR in the remote machine,
693    using the data cache.  */
694 static
695 int
696 dcache_fetch (addr)
697      CORE_ADDR addr;
698 {
699   register struct dcache_block *db;
700
701   db = dcache_hit (addr);
702   if (db == 0)
703     {
704       db = dcache_alloc ();
705       immediate_quit++;
706       ninMemGet(addr & ~0xf, (unsigned char *)db->data, 16);
707       immediate_quit--;
708       db->addr = addr & ~0xf;
709       remque (db);                      /* Off the free list */
710       insque (db, &dcache_valid);       /* On the valid list */
711     }
712   return (dcache_value (db, addr));
713 }
714
715 /* Write the word at ADDR both in the data cache and in the remote machine.  */
716 static void
717 dcache_poke (addr, data)
718      CORE_ADDR addr;
719      int data;
720 {
721   register struct dcache_block *db;
722
723   /* First make sure the word is IN the cache.  DB is its cache block.  */
724   db = dcache_hit (addr);
725   if (db == 0)
726     {
727       db = dcache_alloc ();
728       immediate_quit++;
729       ninMemGet(addr & ~0xf, (unsigned char *)db->data, 16);
730       immediate_quit--;
731       db->addr = addr & ~0xf;
732       remque (db);                      /* Off the free list */
733       insque (db, &dcache_valid);       /* On the valid list */
734     }
735
736   /* Modify the word in the cache.  */
737   db->data[(addr>>2)&3] = data;
738
739   /* Send the changed word.  */
740   immediate_quit++;
741   ninMemPut(addr, (unsigned char *)&data, 4);
742   immediate_quit--;
743 }
744
745 /* The cache itself. */
746 struct dcache_block the_cache[DCACHE_SIZE];
747
748 /* Initialize the data cache.  */
749 static void
750 dcache_init ()
751 {
752   register i;
753   register struct dcache_block *db;
754
755   db = the_cache;
756   dcache_free.next = dcache_free.last = &dcache_free;
757   dcache_valid.next = dcache_valid.last = &dcache_valid;
758   for (i=0;i<DCACHE_SIZE;i++,db++)
759     insque (db, &dcache_free);
760 }
761
762
763 static void
764 nindy_create_inferior (execfile, args, env)
765      char *execfile;
766      char *args;
767      char **env;
768 {
769   int entry_pt;
770   int pid;
771
772   if (args && *args)
773     error ("Can't pass arguments to remote NINDY process");
774
775   if (execfile == 0 || exec_bfd == 0)
776     error ("No exec file specified");
777
778   entry_pt = (int) bfd_get_start_address (exec_bfd);
779
780   pid = 42;
781
782 #ifdef CREATE_INFERIOR_HOOK
783   CREATE_INFERIOR_HOOK (pid);
784 #endif  
785
786 /* The "process" (board) is already stopped awaiting our commands, and
787    the program is already downloaded.  We just set its PC and go.  */
788
789   inferior_pid = pid;           /* Needed for wait_for_inferior below */
790
791   clear_proceed_status ();
792
793   /* Tell wait_for_inferior that we've started a new process.  */
794   init_wait_for_inferior ();
795
796   /* Set up the "saved terminal modes" of the inferior
797      based on what modes we are starting it with.  */
798   target_terminal_init ();
799
800   /* Install inferior's terminal modes.  */
801   target_terminal_inferior ();
802
803   /* insert_step_breakpoint ();  FIXME, do we need this?  */
804   proceed ((CORE_ADDR)entry_pt, -1, 0);         /* Let 'er rip... */
805 }
806
807 static void
808 reset_command(args, from_tty)
809      char *args;
810      int from_tty;
811 {
812         if ( !nindy_fd ){
813             error( "No target system to reset -- use 'target nindy' command.");
814         }
815         if ( query("Really reset the target system?",0,0) ){
816                 send_break( nindy_fd );
817                 tty_flush( nindy_fd );
818         }
819 }
820
821 void
822 nindy_kill (args, from_tty)
823      char *args;
824      int from_tty;
825 {
826   return;               /* Ignore attempts to kill target system */
827 }
828
829 /* Clean up when a program exits.
830
831    The program actually lives on in the remote processor's RAM, and may be
832    run again without a download.  Don't leave it full of breakpoint
833    instructions.  */
834
835 void
836 nindy_mourn_inferior ()
837 {
838   remove_breakpoints ();
839   unpush_target (&nindy_ops);
840   generic_mourn_inferior ();    /* Do all the proper things now */
841 }
842 \f
843 /* This routine is run as a hook, just before the main command loop is
844    entered.  If gdb is configured for the i960, but has not had its
845    nindy target specified yet, this will loop prompting the user to do so.
846
847    Unlike the loop provided by Intel, we actually let the user get out
848    of this with a RETURN.  This is useful when e.g. simply examining
849    an i960 object file on the host system.  */
850
851 void
852 nindy_before_main_loop ()
853 {
854   char ttyname[100];
855   char *p, *p2;
856
857   setjmp(to_top_level);
858   while (current_target != &nindy_ops) { /* remote tty not specified yet */
859         if ( instream == stdin ){
860                 printf("\nAttach /dev/ttyNN -- specify NN, or \"quit\" to quit:  ");
861                 fflush( stdout );
862         }
863         fgets( ttyname, sizeof(ttyname)-1, stdin );
864
865         /* Strip leading and trailing whitespace */
866         for ( p = ttyname; isspace(*p); p++ ){
867                 ;
868         }
869         if ( *p == '\0' ){
870                 return;         /* User just hit spaces or return, wants out */
871         }
872         for ( p2= p; !isspace(*p2) && (*p2 != '\0'); p2++ ){
873                 ;
874         }
875         *p2= '\0';
876         if ( STREQ("quit",p) ){
877                 exit(1);
878         }
879
880         nindy_open( p, 1 );
881
882         /* Now that we have a tty open for talking to the remote machine,
883            download the executable file if one was specified.  */
884         if ( !setjmp(to_top_level) && exec_bfd ) {
885               target_load (bfd_get_filename (exec_bfd), 1);
886         }
887   }
888 }
889 \f
890 /* Define the target subroutine names */
891
892 struct target_ops nindy_ops = {
893         "nindy", "Remote serial target in i960 NINDY-specific protocol",
894         "Use a remote i960 system running NINDY connected by a serial line.\n\
895 Specify the name of the device the serial line is connected to.\n\
896 The speed (baud rate), whether to use the old NINDY protocol,\n\
897 and whether to send a break on startup, are controlled by options\n\
898 specified when you started GDB.",
899         nindy_open, nindy_close,
900         0,
901         nindy_detach,
902         nindy_resume,
903         nindy_wait,
904         nindy_fetch_registers, nindy_store_registers,
905         nindy_prepare_to_store,
906         nindy_xfer_inferior_memory, nindy_files_info,
907         0, 0, /* insert_breakpoint, remove_breakpoint, */
908         0, 0, 0, 0, 0,  /* Terminal crud */
909         nindy_kill,
910         generic_load,
911         0, /* lookup_symbol */
912         nindy_create_inferior,
913         nindy_mourn_inferior,
914         0,              /* can_run */
915         0, /* notice_signals */
916         process_stratum, 0, /* next */
917         1, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
918         0, 0,                   /* Section pointers */
919         OPS_MAGIC,              /* Always the last thing */
920 };
921
922 void
923 _initialize_nindy ()
924 {
925   add_target (&nindy_ops);
926   add_com ("reset", class_obscure, reset_command,
927            "Send a 'break' to the remote target system.\n\
928 Only useful if the target has been equipped with a circuit\n\
929 to perform a hard reset when a break is detected.");
930 }