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