]> Git Repo - binutils.git/blob - gdb/remote-sa.sparc.c
readline/sysdep.h no longer exists, so main.o does not depend on it.
[binutils.git] / gdb / remote-sa.sparc.c
1 /* THIS FILE HAS NOT HAD ITS COPYRIGHT CHECKED...FSF SHOULD NOT
2    DISTRIBUTE IT UNTIL THIS HAPPENS.  */
3
4 /* Memory-access and commands for inferior process, for GDB.
5 */
6
7 #include <sys/errno.h>
8 #include <setjmp.h>
9 #include <stdio.h>
10 #include "defs.h"
11 #include "frame.h"
12 #include "value.h"
13 #include "inferior.h"
14 #include "symtab.h"
15
16 #undef WSTOPSIG
17 #undef WTERMSIG
18 #include "wait.h"
19
20 #ifdef USG
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #endif
24
25 #include <signal.h>
26 #include <sys/file.h>
27
28 #include <termios.h>
29 #define TERMINAL struct termios
30
31 #define LONGTIMEOUT 5
32 #define SHORTTIMEOUT 1
33
34 #define KD_MINUTAE 1
35 #define KD_LINEDISCIPLINE 2
36 #define KD_RETRY 4
37 #define KD_BLOCKTRANSFER 8
38
39 #ifndef STDIN
40 #define STDIN 0
41 #endif
42
43 #define GL_READING 0 /* get line is reading data */
44 #define GL_OK 1 /* Getline saw the "ok" string */
45 #define GL_SUCCESS 2 /* Get line got data */
46 #define GL_TIMEOUT 3 /* Get line timed out */
47 #define GL_OVERRUN 4 /* Get line filled up the buffer */
48 #define GL_EXCEPTION 5 /* Get line saw "Exception" */
49 #define GL_PROMLINE 6 /* Get line saw prom specific info */
50 #define GL_BLANKLINE 7 /* Get line saw a blank line */
51
52 static int kiodebug /* = KD_RETRY | KD_BLOCKTRANSFER */;
53
54 static CORE_ADDR remote_pc = 0;
55 static CORE_ADDR remote_next_pc = 0;
56 static CORE_ADDR remove_thisbp_next_pc = 0;
57 static CORE_ADDR remove_thisbp_target = 0;
58
59 enum showDrainage {DONTSHOW , SHOW} ;
60
61
62 /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
63    remote_open knows that we don't have a file open when the program
64    starts.  */
65 int remote_desc = -1;
66
67 int dontskipcrs = 0;
68
69 #define PBUFSIZ 400
70
71 unsigned char ignorebuf[PBUFSIZ];
72 #define IGNORE &ignorebuf[0]
73
74 /* Maximum number of bytes to read/write at once.  The value here
75    is chosen to fill up a packet (the headers account for the 32).  */
76 #define MAXBUFBYTES ((PBUFSIZ-32)/2)
77
78 static void remote_send ();
79 static void putpkt ();
80 static int getpkt ();
81
82
83 /* Open a connection to a remote debugger.
84    NAME is the filename used for communication.  */
85 CORE_ADDR breakpoint_regs_addr;
86
87
88 void
89 remote_open (name, from_tty)
90      char *name;
91      int from_tty;
92 {
93   extern int frame_file_full_name;
94   unsigned char buf[PBUFSIZ];
95   TERMINAL sg;
96
97   remote_debugging = 0;
98
99   if (remote_desc >= 0)
100     close (remote_desc);
101
102   breakpoint_regs_addr = parse_and_eval_address("&breakpoint_regs");
103
104   dontskipcrs = !frame_file_full_name; /* if we are running inside of
105                                          emacs, this will be true. 
106                                          then skip carriage returns */
107
108   remote_desc = open (name, O_RDWR);
109   if (remote_desc < 0)
110     perror_with_name (name);
111
112   setup_remote();
113
114   if (from_tty)
115     printf ("Remote debugging using %s\n", name);
116   remote_debugging = 1;
117
118
119 }
120 static char *boot_cmd = 0;
121
122 static print_boot_cmd()
123 {
124     fprintf(stderr, "boot command set to be \"%s\"\n", boot_cmd);
125 }
126
127 remote_start()
128 {
129   WAITTYPE ignoredWaitType;
130
131   if (boot_cmd)
132     {
133     sendbreak();
134     remote_wait (&ignoredWaitType);
135     putpkt ("reset");
136     sleep(10);
137     sendbreak();
138     remote_wait (&ignoredWaitType);
139     sleep(10);
140     print_boot_cmd();
141     putpkt(boot_cmd);
142     fprintf(stderr, "rgdb and nucleus synchronized, booting....\n");
143     }
144   else
145     {
146     error("The boot command is null. Cannot start the remote kernel/nucleus");
147     }
148 }
149
150 /* Close the open connection to the remote debugger.
151    Use this when you want to detach and do something else
152    with your gdb.  */
153 void
154 remote_close (from_tty)
155      int from_tty;
156 {
157   if (!remote_debugging)
158     error ("Can't close remote connection: not debugging remotely.");
159   
160   close (remote_desc);          /* This should never be called if
161                                    there isn't something valid in
162                                    remote_desc.  */
163
164   /* Do not try to close remote_desc again, later in the program.  */
165   remote_desc = -1;
166
167   if (from_tty)
168     printf ("Ending remote debugging\n");
169
170   remote_debugging = 0;
171 }
172  
173 /* Convert hex digit A to a number.  */
174
175 static int
176 fromhex (a)
177      int a;
178 {
179   if (a >= '0' && a <= '9')
180     return a - '0';
181   else if (a >= 'a' && a <= 'f')
182     return a - 'a' + 10;
183   else
184     error ("Reply contains invalid hex digit");
185 }
186
187 /* Convert number NIB to a hex digit.  */
188
189 static int
190 tohex (nib)
191      int nib;
192 {
193   if (nib < 10)
194     return '0'+nib;
195   else
196     return 'a'+nib-10;
197 }
198 \f
199 /* Tell the remote machine to resume.  */
200
201 extern int one_stepped;         /* From machine dependent code */
202 static int remote_set_one_stepped;
203
204 int
205 remote_resume (step, signal)
206      int step, signal;
207 {
208   if (step)
209     {
210       remote_single_step();
211     }
212   remote_set_one_stepped = step;
213   putpkt("go");
214 }
215
216 /* Wait until the remote machine stops, then return,
217    storing status in STATUS just as `wait' would.  */
218
219 int
220 remote_wait (status)
221      WAITTYPE *status;
222 {
223   char last, this;
224   int pend, saveTheOh = 0;
225
226   user_terminal_raw();
227
228   WSETEXIT ((*status), 0177);
229   last = this = 0;
230
231   while (1)
232       {
233         char buf[PBUFSIZ];
234         int readUser, readProm, state;
235
236         doselect(&readUser, &readProm);
237         if (readProm)
238           {
239             switch (state = getline(buf, PBUFSIZ, SHORTTIMEOUT))
240               {
241               case GL_BLANKLINE:
242                 if (remote_set_one_stepped)
243                   break;
244                 
245                 /* fall through */
246
247               default:
248               case GL_READING:
249               case GL_SUCCESS:
250               case GL_OVERRUN:
251               case GL_TIMEOUT:
252                 if (kiodebug & KD_LINEDISCIPLINE)
253                   fprintf(stderr, "%d<%s>\n", state, buf);
254                 else
255                   {
256                     fprintf(stderr, "%s", buf);
257                     fflush(stderr);
258                   }
259                 break;
260               case GL_OK:
261                 remote_cleanup_after_stop();
262                 WSETSTOP ((*status), SIGTRAP);
263                 return;
264               case GL_PROMLINE:
265                 break;
266               }
267           }
268         if (readUser)
269           shuffleFromUserToProm();
270       }
271 }
272 static TERMINAL userterminal;
273         
274 user_terminal_restore()
275 {
276 #if 0
277   int in_desc = fileno (stdin);
278   ioctl (in_desc, TCSETS, &userterminal);
279 #endif
280 }
281 static void set_term_raw();
282
283 user_terminal_raw()
284 {
285 #if 0
286   TERMINAL tempterminal;
287   int in_desc = fileno (stdin);
288   ioctl (in_desc, TCGETS, &userterminal);
289   tempterminal = userterminal;
290
291   tempterminal.c_lflag &= ~(ICANON|ISIG|IEXTEN);
292   tempterminal.c_cc[VMIN] = 1;
293   tempterminal.c_cc[VTIME] = 0;
294   tempterminal.c_iflag &= ~(INPCK|IXON|IXOFF);
295   tempterminal.c_oflag = 0;
296
297   ioctl (in_desc, TCSETS, &tempterminal);
298 #endif
299 }
300
301 doselect(pReadUser, pReadProm)
302      int *pReadUser, *pReadProm;
303 {
304   extern FILE *instream;
305   int in_desc = fileno (stdin);
306   int instreammask = 1 << in_desc;
307   int remotemask = 1 << remote_desc;
308   int rfds = instreammask | remotemask;
309
310   select (32, &rfds, 0, 0, (struct timeval *) 0); /* 0 = Block indefinitely */
311   *pReadUser = (rfds & instreammask) == instreammask;
312   *pReadProm = (rfds & remotemask) == remotemask;
313 }
314
315
316
317 /* Read the remote registers into the block pRegisters.
318 implementation copied largely from fetch_inferior_registers () 
319 in sparc-dep.c */
320
321 void
322 remote_fetch_registers(ignored)
323 int *ignored;
324 {
325   struct regs inferior_registers;
326   extern char registers[];
327   CORE_ADDR breakpoint_regs_target;
328
329   if (breakpoint_regs_addr == 0)
330     {
331       error("no address for breakpoint_regs\n");
332       return;
333     }
334   remote_read_inferior_memory(breakpoint_regs_addr, &breakpoint_regs_target,
335                               sizeof(breakpoint_regs_target));
336
337   bzero(registers, REGISTER_BYTES);
338   registers[REGISTER_BYTE (0)] = 0;
339
340   if (breakpoint_regs_target)
341     {
342       remote_read_inferior_memory(breakpoint_regs_target, &inferior_registers,
343                                   sizeof(inferior_registers));
344       registers[REGISTER_BYTE (0)] = 0;
345       bcopy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (1)], 15 * 4);
346       *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; 
347       *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
348       *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
349       *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
350       remote_pc =  inferior_registers.r_pc; 
351       remote_next_pc =  inferior_registers.r_npc; 
352       remote_read_inferior_memory (inferior_registers.r_sp,
353                                    &registers[REGISTER_BYTE (16)],
354                                    16*4);
355     }
356   else
357     {
358       error("breakpoint_regs == 0\n");
359     }
360 }
361
362
363
364 \f
365 /* Write memory data directly to the remote machine.
366    This does not inform the data cache; the data cache uses this.
367    MEMADDR is the address in the remote memory space.
368    MYADDR is the address of the buffer in our space.
369    LEN is the number of bytes.  */
370
371 int
372 remote_write_bytes (memaddr, myaddr, len)
373      CORE_ADDR memaddr;
374      unsigned char *myaddr;
375      int len;
376 {
377   char buf[PBUFSIZ];
378   int i;
379
380   /* Command describes registers byte by byte,
381      each byte encoded as two hex characters.  */
382
383   for (i = 0; i < len; i++)
384     {
385     sprintf(buf, "%x %x c!", myaddr[i], memaddr + i); 
386     remote_send (buf, buf);
387     if (strstr(buf, "Exception"))
388       {
389         return EFAULT;    
390       }
391     }
392   return 0;       
393 }
394
395 /* Copy LEN bytes of data from debugger memory at MYADDR
396    to inferior's memory at MEMADDR.  Returns errno value.  */
397 int
398 remote_write_inferior_memory (memaddr, myaddr, len)
399      CORE_ADDR memaddr;
400      char *myaddr;
401      int len;
402 {
403   int xfersize;
404   int retval;
405
406   while (len > 0)
407     {
408       if (len > MAXBUFBYTES)
409         xfersize = MAXBUFBYTES;
410       else
411         xfersize = len;
412       
413       retval = remote_write_bytes(memaddr, myaddr, xfersize);
414       if (retval)
415         return retval; /* error */
416       
417       memaddr += xfersize;
418       myaddr  += xfersize;
419       len     -= xfersize;
420     }
421   return 0; /* no error */
422 }
423 \f
424
425 /* read a single character */
426
427 static int
428 readCharFromProm ()
429 {
430   char buf;
431
432   buf = '\0';
433   /* termio does the timeout for us.  */
434   read (remote_desc, &buf, 1);
435   return buf & 0x7f;
436 }
437
438 /* Send the command in BUF to the remote machine,
439    and read the reply into BUF.
440    Report an error if we get an error reply.  */
441
442 static void
443 remote_send (buf, buf2)
444      char *buf, *buf2;
445 {
446   putpkt (buf);
447   getpkt (buf2);
448 }
449
450 /* Send a single character out over the wire */
451
452 static void
453 putcharacter (ch)
454      char ch;
455 {
456
457   while (1)
458     {
459       int i;
460
461       write(remote_desc, &ch, 1);
462       for (i = 0; i < 100; i++)
463         {
464           char nch = 0;
465
466           if (read (remote_desc, &nch, 1) == 0)
467             i++;
468           if ((ch == nch)
469               || (ch == '\n' && nch == '\r')
470               || (ch == '\r' && nch == '\n'))
471             return;
472           if (kiodebug & KD_MINUTAE)
473             fprintf (stderr, "Sent %c(%d) Received %c(%d)\n", ch, ch, nch, nch);
474         }
475     }
476 }
477
478 /* Send a packet to the remote machine, with error checking.
479    The data of the packet is in BUF.  */
480
481 static void
482 putpkt (buf)
483      char *buf;
484 {
485   int i;
486   int cnt = strlen (buf);
487   char ch;
488
489   if (kiodebug & KD_LINEDISCIPLINE)
490     fprintf(stderr, "putpkt(%s)\n", buf);
491
492   for (i = 0; i < cnt; i++)
493       putcharacter (buf[i]);
494   putcharacter ('\n');
495 }
496
497 jmp_buf getline_jmpbuf;
498
499 /* Read a line from the remote machine, and store it in BUF.  */
500 getline_timer()
501 {
502   alarm(0);
503   
504   if (kiodebug & KD_RETRY)
505     fprintf(stderr, "getline timed out\n");
506   longjmp(getline_jmpbuf, 1);
507 }
508
509 static int
510 getline (buf, size, timeout)
511      char *buf;
512      int size, timeout;
513 {
514   int cnt = 0;
515   int state;
516   int isspace_state = 1;
517
518   if ((void (*)) signal (SIGALRM, getline_timer) == (void (*)) -1)
519     perror ("remote_open: error in signal");
520
521   --size; /* back it up one so that we can read */
522
523   state = GL_READING;
524
525   if (setjmp(getline_jmpbuf))
526     state = GL_TIMEOUT;
527   else
528     {
529       alarm (timeout);
530       do
531         {
532           char ch = readCharFromProm();
533           isspace_state = isspace_state && isspace(ch);
534           if (ch && (dontskipcrs || ch != '\r'))
535             {
536               buf[cnt++] = ch;
537               buf[cnt] = '\0';
538             }
539           if (kiodebug & KD_MINUTAE)
540             fprintf (stderr,"letter received :%c\n", buf[cnt - 1]);
541           if (cnt >= 2 && buf[cnt - 2] == 'o' && buf[cnt - 1] == 'k')
542               state = GL_OK;
543           else if (buf[cnt - 1] == '\n' )
544             state = isspace_state ?  GL_BLANKLINE : GL_SUCCESS;
545           else if (cnt == size)
546             state = GL_OVERRUN;
547           else if (strstr(buf, "Type  'go' to resume"))
548             state = GL_PROMLINE;
549           else if (strstr(buf, "Type  help  for more information"))
550             state = GL_PROMLINE;
551           else if (strstr(buf, "Exception"))
552             state = GL_EXCEPTION;
553         }
554       while (state == GL_READING);
555     }
556   alarm (0);
557   
558   if (kiodebug & KD_LINEDISCIPLINE)
559     fprintf (stderr,"Line received :%s\n", buf);
560   return state;
561 }
562
563
564 /* Read a packet from the remote machine, and store it in BUF.  */
565
566 static int
567 getpkt (buf)
568      char *buf;
569 {
570   int cnt = 0;
571
572     do
573       {
574       char ch = readCharFromProm();
575       if (ch)
576         buf[cnt++] = ch;
577       if (kiodebug & KD_MINUTAE)
578         fprintf (stderr,"letter received :%c\n", buf[cnt - 1]);
579       }
580     while (cnt < 2 ||
581       buf[cnt - 2] != 'o' &&
582       buf[cnt - 1] != 'k');
583
584     buf[cnt] = '\0';
585     if (kiodebug& KD_LINEDISCIPLINE)
586       fprintf (stderr,"Packet received :%s\n", buf);
587     return cnt;
588 }
589
590 void remote_fetch_word (addr)
591      CORE_ADDR addr;
592 {
593   error ("Internal error: remote_fetch_word is obsolete.\n");
594 }
595 void remote_store_word (addr)
596      CORE_ADDR addr;
597 {
598   error ("Internal error: remote_store_word is obsolete.\n");
599 }
600 #include <termio.h>
601
602 draininput(showit)
603 enum showDrainage showit;
604 {
605   unsigned char buf[PBUFSIZ];
606   int cnt;
607
608   while ((cnt = read(remote_desc, buf, PBUFSIZ)) > 0)
609     {
610       buf[cnt] = 0;
611       if (kiodebug& KD_LINEDISCIPLINE)
612         fprintf (stderr,"Draining :%s\n", buf);
613       else
614         if (showit == SHOW)
615           fprintf (stderr,"%s", buf);
616     }
617   if (kiodebug& KD_LINEDISCIPLINE)
618     fprintf (stderr,"Drained\n");
619 }
620 sendbreak()
621 {
622   if (kiodebug & KD_RETRY)
623     fprintf (stderr,"rgdb sending break to target...\n");
624   else
625     {
626       fprintf (stderr,"=");
627       fflush(stderr);
628     }
629     
630   ioctl (remote_desc, TCSBRK, 0);
631   sleep(5);
632 }
633
634
635 /* shuffle a character from the user to remote debugger */
636
637 int 
638 shuffleFromUserToProm()
639 {
640   char ch;
641   static int escape = 0;
642     
643   extern FILE *instream;
644   
645   ch = 0;
646   if (read(STDIN, &ch , 1) != 1 || ch == 0)
647     return;
648
649   if (escape) {
650     if (ch == '#')
651       sendbreak();
652     else if (ch == '.')
653         {
654           while (ch != '\n')    
655             read(STDIN, &ch , 1);
656           return 1;
657         }
658     else {
659       static char tilde = '~';
660
661       putcharacter(tilde);
662       putcharacter(ch);
663     }
664     escape = 0;
665   } else /* not escape */ {
666     if (ch == '~')
667       escape = 1;
668     else
669       putcharacter(ch);
670   }
671   return 0;
672 }
673   
674   
675
676 /* Tell  the Prom put a breakpoint at memaddr */
677 remote_insert_breakpoint(memaddr)
678      CORE_ADDR memaddr;
679 {
680   char buf[PBUFSIZ];
681
682   /* Command describes registers byte by byte,
683      each byte encoded as two hex characters.  */
684
685   sprintf(buf, "%x +bp", memaddr);
686   remote_send(buf, buf);
687   if (strstr(buf, "Exception"))
688     {
689       return EFAULT;      
690     }
691   else
692     {
693       return 0;   
694     }
695 }
696
697 /* Tell  the Prom remove the the breakpoint at memaddr */
698 remote_remove_breakpoint(memaddr)
699      CORE_ADDR memaddr;
700 {
701   char buf[PBUFSIZ];
702
703   /* Command describes registers byte by byte,
704      each byte encoded as two hex characters.  */
705
706   sprintf(buf, "%x -bp", memaddr);
707   remote_send(buf, buf);
708   if (strstr(buf, "Exception"))
709     {
710       return EFAULT;      
711     }
712   else
713     {
714       return 0;   
715     }
716 }
717
718
719
720
721
722 /* Read memory data directly from the remote machine.
723    This does not use the data cache; the data cache uses this.
724    MEMADDR is the address in the remote memory space.
725    MYADDR is the address of the buffer in our space.
726    LEN is the number of words.  */
727
728 long
729 remote_read(memaddr, myaddr, len, increment, promcommand)
730      CORE_ADDR memaddr;
731      unsigned char *myaddr;
732      int len, increment;
733      char *promcommand;
734 {
735   char buf[PBUFSIZ];
736   char buf2[PBUFSIZ];
737   int i;
738   unsigned long num;
739
740   /* Command describes registers byte by byte,
741      each byte encoded as two hex characters.  */
742
743   for (i = 0; i < len; i += increment)
744     {
745       sprintf(buf, promcommand, memaddr + i) ;
746       remote_send(buf, buf2);
747       remote_send(".", buf);
748       if (strstr(buf2, "Exception"))
749         {
750           bzero(&myaddr[i], len - i);
751           return -i;      
752         }
753       else
754         {
755           char *pBuf;
756           for (pBuf = &buf[0]; *pBuf == '\r' || *pBuf == '\n'; pBuf++)
757             ;
758           sscanf(pBuf, "%x\n", &num);
759           switch (increment)
760             {
761             case 1: myaddr[i] = num;
762               if (num > 255)
763                 fprintf(stderr, "number out of bounds %x truncating to %x\n",
764                         num, myaddr[i]);
765               break;
766             case 4: {unsigned long *p;
767                      p = (unsigned long *) &myaddr[i];
768                      *p = num;
769                      }
770               break;
771             default: fprintf(stderr, "unknown increment\n"); break;
772             }
773         }
774     }
775   return i;
776 }
777 \f
778
779
780 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
781    at debugger address MYADDR.  Returns errno value.  */
782 int
783 remote_read_inferior_memory(memaddr, myaddr, len)
784      CORE_ADDR memaddr;
785      char *myaddr;
786      int len;
787 {
788   int xfersize;
789   while (len > 0)
790     {
791       int mod;
792
793       if (len > MAXBUFBYTES)
794         xfersize = MAXBUFBYTES;
795       else
796         xfersize = len;
797
798       mod = memaddr % 4;
799       if  (mod == 0 && xfersize >= 4)
800         if  (mod == 0 && xfersize >= 16)
801           {
802             xfersize = remote_read_many(memaddr, myaddr, (len & ~3));
803             getpkt(IGNORE);
804           }
805         else
806           xfersize = remote_read(memaddr, myaddr, 4, 4, "%x @");
807       else
808         xfersize = remote_read(memaddr, myaddr, max(mod, 1), 1, "%x c@");
809       if (xfersize <= 0)
810         return EFAULT; /* error */
811       memaddr += xfersize;
812       myaddr  += xfersize;
813       len     -= xfersize;
814     }
815   return 0; /* no error */
816 }
817 static int baud_rate=B38400;
818
819 static void set_term_raw(pTermio)
820      TERMINAL *pTermio;
821 {
822   pTermio->c_cflag &= (CREAD|HUPCL|CLOCAL);
823   pTermio->c_cflag |= baud_rate | CS8;
824   pTermio->c_iflag = ISTRIP /* | IXON | IXOFF */;
825   pTermio->c_oflag = 0;
826   pTermio->c_lflag = 0;
827   pTermio->c_cc[VMIN] = 0;
828   pTermio->c_cc[VTIME] = 1;
829 }
830
831 /* setup the remote termio stream */
832 setup_remote()
833 {
834   TERMINAL temptempio;
835
836   ioctl(remote_desc, TCGETS, &temptempio);
837   set_term_raw(&temptempio);
838   ioctl(remote_desc, TCSETS, &temptempio);
839 }
840
841 /* step one machine instruction */
842 remote_single_step ()
843 {
844   CORE_ADDR next_pc, npc4, target, pc;
845   typedef enum
846     {
847       Error, not_branch, bicc, bicca, ba, baa, ticc, ta,
848     } branch_type;
849   branch_type br, isannulled();
850
851   npc4 = remote_next_pc + 4; /* branch not taken */
852
853   /* Always set breakpoint for NPC.  */
854
855   remote_insert_breakpoint(remote_next_pc);
856   remove_thisbp_next_pc = remote_next_pc;
857
858   /* printf ("set break at %x\n",remote_next_pc); */
859   
860   br = isannulled (remote_pc, &target);
861   
862   if (br == bicca)
863     {
864       /* Conditional annulled branch will either end up at
865          npc (if taken) or at npc+4 (if not taken).
866          Trap npc+4.  */
867       remote_insert_breakpoint(npc4);
868       remove_thisbp_target = npc4;
869     }
870   else if (br == baa && target != remote_next_pc)
871     {
872       /* Unconditional annulled branch will always end up at
873          the target.  */
874       remote_insert_breakpoint(target);
875       remove_thisbp_target = target;
876     }
877 }
878
879
880
881
882 /* read many words of memory */
883 long
884 remote_read_many(memaddr, myaddr, len)
885      CORE_ADDR memaddr;
886      unsigned char *myaddr;
887      int len;
888 {
889 #define BLOCKSIZE 1024
890   static int max_number_of_blocks = 24;
891
892   char buf[PBUFSIZ];
893   char buf2[PBUFSIZ];
894   int i;
895   unsigned long *p;
896 /* Command describes registers byte by byte,
897      each byte encoded as two hex characters.  */
898
899   len = min(len, max_number_of_blocks * BLOCKSIZE);
900
901   sprintf(buf, "%x %x do i @ . cr 4 +loop", memaddr + len, memaddr);
902   putpkt(buf);
903   getline(buf2, PBUFSIZ, LONGTIMEOUT); /* I don't care */
904
905   p = (unsigned long *) myaddr;
906   for (i = 0; i < len; i += 4, p++)
907     {
908       extern int InspectIt;
909
910       if (!InspectIt && ((i % BLOCKSIZE) == 0))
911           fprintf(stderr, "+"); /* let 'em know that we are working */
912       switch (getline(buf2, PBUFSIZ, LONGTIMEOUT))
913         {
914         default:
915         case GL_PROMLINE:
916         case GL_READING:
917         case GL_OK:
918         case GL_OVERRUN:
919         case GL_TIMEOUT:
920         case GL_BLANKLINE:
921           /* resync and retry */
922           max_number_of_blocks = max(1, i / BLOCKSIZE);
923           fprintf(stderr, "-"); /* let 'em know that we are working */
924           
925           if (kiodebug & KD_BLOCKTRANSFER)
926             fprintf(stderr, "failed read_many %d %d/%d (%s)\n",
927                     max_number_of_blocks, i, len, buf2);
928           sendbreak();
929           return remote_read_many(memaddr, myaddr, len);
930         case GL_EXCEPTION:
931           return -i;      
932         case GL_SUCCESS:
933           sscanf(buf2, "%x\n", p);
934           break;
935         }
936     }
937   if (kiodebug & KD_BLOCKTRANSFER)
938     fprintf(stderr, "success read_many %d %d/%d (%s)\n", max_number_of_blocks,
939             i, len, buf2);
940   return i;
941 }
942 /*
943  * allow the user to type directly to the prom ! 
944  */
945 prom_command()
946 {
947   int readUser, readProm;
948
949   user_terminal_raw();
950   fprintf(stderr, "entering prom mode...\n");
951   while (1)
952     {
953       doselect(&readUser, &readProm);
954       if (readUser)
955         if (shuffleFromUserToProm())
956           {
957           fprintf(stderr, "exiting prom mode\n");
958           user_terminal_restore();
959           return;
960         }
961       if (readProm)
962         fprintf(stderr, "%c", readCharFromProm ());
963     }
964 }
965 static char *boot_set_msg = "boot needs a string in quotes of the form \"boot vmunix\"  ";
966 static char *baud_set_msg = "baud rate should be of the form \"set baud=9600\"";
967
968 static void
969 set_boot (arg, from_tty)
970      char *arg;
971      int from_tty;
972 {
973   int h, i;
974
975   if (!arg)
976     {
977     print_boot_cmd();
978     error_no_arg (boot_set_msg);
979     }
980   
981   arg = tilde_expand (arg);
982   make_cleanup (free, arg);
983
984   i = strlen (arg) - 1;
985   
986   free (boot_cmd);
987   
988   h = 0;
989   while (*arg && h < i && (arg[h] == ' ' || arg[h] == '\t'))
990     {
991     h++;
992     arg++;
993     }
994   while (i > 0 && (arg[i] == ' ' || arg[i] == '\t'))
995     i--;
996
997   if (h >= i || !*arg || arg[h] != '"' || arg[i] != '"')
998     error (boot_set_msg);
999   else
1000     {
1001     boot_cmd = savestring (++arg, i);
1002     boot_cmd[i - 1] = '\0';
1003     }
1004  if (from_tty)
1005     print_boot_cmd();
1006 }
1007
1008 static int bauds[] = {
1009         0, 50, 75, 110, 134, 150, 200, 300, 600,
1010         1200, 1800, 2400, 4800, 9600, 19200, 38400, -1
1011 };
1012
1013
1014 static int convert_to_baud_B(n)
1015         int n;
1016 {
1017         register int *p;
1018
1019         for (p = bauds; *p != -1;  p++)
1020                 if (*p != 0 && *p == n)
1021                         return (p - bauds);
1022         return (NULL);
1023 }
1024
1025 static void print_acceptable_bauds()
1026 {
1027         register int *p;
1028
1029         for (p = bauds; *p != -1;  p++)
1030                 if (*p != 0 )
1031                         fprintf(stderr, "%d\n", *p);
1032 }
1033
1034 static void print_baud()
1035 {
1036 fprintf(stderr, "the baud rate is now %d\n", bauds[baud_rate]);
1037 }
1038
1039 static void
1040 set_baud (arg, from_tty)
1041      char *arg;
1042      int from_tty;
1043 {
1044   int temp_baud_rate;
1045
1046   if (!arg)
1047     {
1048     print_baud();
1049     print_acceptable_bauds();
1050     error_no_arg (baud_set_msg);
1051     return;
1052     }
1053
1054   while (*arg && !isdigit(*arg))
1055     arg++;
1056   
1057   if (*arg  && (temp_baud_rate = convert_to_baud_B(atoi(arg))) != NULL)
1058     {
1059         baud_rate = temp_baud_rate;
1060         if (remote_debugging)
1061           setup_remote();
1062     }
1063   else
1064     {
1065       fprintf(stderr, "bad baud rate %s, acceptable values are\n", arg);
1066       print_acceptable_bauds();
1067     }
1068
1069   print_baud();
1070 }
1071
1072
1073
1074
1075 void
1076 _initialize_remote()
1077 {
1078 /* Chain containing all defined set subcommands */
1079
1080 extern struct cmd_list_element *setlist;
1081
1082
1083   add_com ("prom", class_obscure, prom_command,
1084            "Conduct a dialogue directly with the prom. \
1085 only useful after an attach\n\
1086 Terminate by typing ~.");
1087
1088   add_cmd ("boot_cmd", class_support, set_boot, boot_set_msg, &setlist);
1089
1090   add_cmd ("baud", class_support, set_baud, baud_set_msg, &setlist);
1091
1092   set_boot ("\"boot nucleus -d\"", 0);
1093   }
1094
1095
1096 /* Store the remote registers from the contents of the block REGS.  */
1097
1098 void
1099 remote_store_registers (registers)
1100      char *registers;
1101 {
1102   CORE_ADDR core;
1103   struct regs inferior_registers;
1104
1105   core = parse_and_eval_address("breakpoint_regs");
1106
1107   bcopy (&registers[REGISTER_BYTE (1)],
1108          &inferior_registers.r_g1, 15 * 4);
1109
1110   inferior_registers.r_ps =
1111     *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
1112   inferior_registers.r_pc =
1113     *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
1114   inferior_registers.r_npc =
1115     *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
1116   inferior_registers.r_y =
1117     *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
1118
1119   remote_write_inferior_memory (*(int *)&registers[REGISTER_BYTE (SP_REGNUM)],
1120                                 &registers[REGISTER_BYTE (16)],
1121                                 16*4);
1122   remote_write_inferior_memory (core,
1123                                 &inferior_registers, 
1124                                 sizeof(inferior_registers));
1125 }
1126
1127
1128
1129 /* we have stopped. do some cleanup */
1130 remote_cleanup_after_stop()
1131 {
1132   if (remove_thisbp_next_pc)
1133     {
1134       remote_remove_breakpoint (remove_thisbp_next_pc);
1135       remove_thisbp_next_pc = 0;
1136     }
1137   if (remove_thisbp_target)
1138     {
1139       remote_remove_breakpoint (remove_thisbp_target);
1140       remove_thisbp_target = 0;
1141     }
1142   user_terminal_restore();
1143   
1144   one_stepped = remote_set_one_stepped;
1145 }
This page took 0.089884 seconds and 4 git commands to generate.