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