personal checkpoint
[deliverable/binutils-gdb.git] / gdb / remote-sa.sparc.c
CommitLineData
07d021a6
JG
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"
07d021a6
JG
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
52static int kiodebug /* = KD_RETRY | KD_BLOCKTRANSFER */;
53
54static CORE_ADDR remote_pc = 0;
55static CORE_ADDR remote_next_pc = 0;
56static CORE_ADDR remove_thisbp_next_pc = 0;
57static CORE_ADDR remove_thisbp_target = 0;
58
59enum 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. */
65int remote_desc = -1;
66
67int dontskipcrs = 0;
68
69#define PBUFSIZ 400
70
71unsigned 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
78static void remote_send ();
79static void putpkt ();
80static int getpkt ();
81
82
83/* Open a connection to a remote debugger.
84 NAME is the filename used for communication. */
85CORE_ADDR breakpoint_regs_addr;
86
87
88void
89remote_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}
120static char *boot_cmd = 0;
121
122static print_boot_cmd()
123{
124 fprintf(stderr, "boot command set to be \"%s\"\n", boot_cmd);
125}
126
127remote_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. */
153void
154remote_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
175static int
176fromhex (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
189static int
190tohex (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
201extern int one_stepped; /* From machine dependent code */
202static int remote_set_one_stepped;
203
204int
205remote_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
219int
220remote_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}
272static TERMINAL userterminal;
273
274user_terminal_restore()
275{
276#if 0
277 int in_desc = fileno (stdin);
278 ioctl (in_desc, TCSETS, &userterminal);
279#endif
280}
281static void set_term_raw();
282
283user_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
301doselect(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.
318implementation copied largely from fetch_inferior_registers ()
319in sparc-dep.c */
320
321void
322remote_fetch_registers(ignored)
323int *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
371int
372remote_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. */
397int
398remote_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
427static int
428readCharFromProm ()
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
442static void
443remote_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
452static void
453putcharacter (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
481static void
482putpkt (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
497jmp_buf getline_jmpbuf;
498
499/* Read a line from the remote machine, and store it in BUF. */
500getline_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
509static int
510getline (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
566static int
567getpkt (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
590void remote_fetch_word (addr)
591 CORE_ADDR addr;
592{
593 error ("Internal error: remote_fetch_word is obsolete.\n");
594}
595void 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
602draininput(showit)
603enum 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}
620sendbreak()
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
637int
638shuffleFromUserToProm()
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 */
677remote_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 */
698remote_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
728long
729remote_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. */
782int
783remote_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}
817static int baud_rate=B38400;
818
819static 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 */
832setup_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 */
842remote_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 */
883long
884remote_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 */
945prom_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}
965static char *boot_set_msg = "boot needs a string in quotes of the form \"boot vmunix\" ";
966static char *baud_set_msg = "baud rate should be of the form \"set baud=9600\"";
967
968static void
969set_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
1008static int bauds[] = {
1009 0, 50, 75, 110, 134, 150, 200, 300, 600,
1010 1200, 1800, 2400, 4800, 9600, 19200, 38400, -1
1011};
1012
1013
1014static 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
1025static 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
1034static void print_baud()
1035{
1036fprintf(stderr, "the baud rate is now %d\n", bauds[baud_rate]);
1037}
1038
1039static void
1040set_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
1075void
1076_initialize_remote()
1077{
1078/* Chain containing all defined set subcommands */
1079
1080extern struct cmd_list_element *setlist;
1081
1082
1083 add_com ("prom", class_obscure, prom_command,
1084 "Conduct a dialogue directly with the prom. \
1085only useful after an attach\n\
1086Terminate 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
1098void
1099remote_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 */
1130remote_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.113287 seconds and 4 git commands to generate.