New commands ``set architecture'', ``show architecture'' and ``info
[deliverable/binutils-gdb.git] / gdb / remote-sds.c
CommitLineData
2d46177c
SS
1/* Remote target communications for serial-line targets using SDS' protocol.
2 Copyright 1997 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20/* This interface was written by studying the behavior of the SDS
21 monitor on an ADS 821/860 board, and by consulting the
22 documentation of the monitor that is available on Motorola's web
23 site. -sts 8/13/97 */
24
25#include "defs.h"
26#include "gdb_string.h"
27#include <fcntl.h>
28#include "frame.h"
29#include "inferior.h"
30#include "bfd.h"
31#include "symfile.h"
32#include "target.h"
33#include "wait.h"
34#include "gdbcmd.h"
35#include "objfiles.h"
36#include "gdb-stabs.h"
37#include "gdbthread.h"
38
39#include "dcache.h"
40
41#ifdef USG
42#include <sys/types.h>
43#endif
44
45#include <signal.h>
46#include "serial.h"
47
48/* Declarations of local functions. */
49
50static int sds_write_bytes PARAMS ((CORE_ADDR, char *, int));
51
52static int sds_read_bytes PARAMS ((CORE_ADDR, char *, int));
53
54static void sds_files_info PARAMS ((struct target_ops *ignore));
55
56static int sds_xfer_memory PARAMS ((CORE_ADDR, char *,
57 int, int, struct target_ops *));
58
59static void sds_prepare_to_store PARAMS ((void));
60
61static void sds_fetch_registers PARAMS ((int));
62
63static void sds_resume PARAMS ((int, int, enum target_signal));
64
65static int sds_start_remote PARAMS ((char *));
66
67static void sds_open PARAMS ((char *, int));
68
69static void sds_close PARAMS ((int));
70
71static void sds_store_registers PARAMS ((int));
72
73static void sds_mourn PARAMS ((void));
74
75static void sds_restart PARAMS ((void));
76
77static void sds_create_inferior PARAMS ((char *, char *, char **));
78
79static int getmessage PARAMS ((unsigned char *, int));
80
81static int putmessage PARAMS ((unsigned char *, int));
82
83static int sds_send PARAMS ((unsigned char *, int));
84
85static int readchar PARAMS ((int));
86
87static int sds_wait PARAMS ((int, struct target_waitstatus *));
88
89static void sds_kill PARAMS ((void));
90
91static int tohex PARAMS ((int));
92
93static int fromhex PARAMS ((int));
94
95static void sds_detach PARAMS ((char *, int));
96
97static void sds_interrupt PARAMS ((int));
98
99static void sds_interrupt_twice PARAMS ((int));
100
101static void interrupt_query PARAMS ((void));
102
103static int read_frame PARAMS ((char *));
104
105static int sds_insert_breakpoint PARAMS ((CORE_ADDR, char *));
106
107static int sds_remove_breakpoint PARAMS ((CORE_ADDR, char *));
108
109
110static struct target_ops sds_ops; /* Forward decl */
111
112/* This was 5 seconds, which is a long time to sit and wait.
113 Unless this is going though some terminal server or multiplexer or
114 other form of hairy serial connection, I would think 2 seconds would
115 be plenty. */
116
117/* Changed to allow option to set timeout value.
118 was static int sds_timeout = 2; */
119static int sds_timeout = 2;
120
2d46177c
SS
121/* Descriptor for I/O to remote machine. Initialize it to NULL so
122 that sds_open knows that we don't have a file open when the program
123 starts. */
124
125static serial_t sds_desc = NULL;
126
3d7cd517
SS
127/* This limit comes from the monitor. */
128
129#define PBUFSIZ 250
2d46177c
SS
130
131/* Maximum number of bytes to read/write at once. The value here
132 is chosen to fill up a packet (the headers account for the 32). */
133#define MAXBUFBYTES ((PBUFSIZ-32)/2)
134
2d46177c
SS
135static int next_msg_id;
136
137static int just_started;
138
139static int message_pending;
140
141\f
142/* Restart the remote side; this is an extended protocol operation. */
143
144static void
145sds_restart ()
146{
147}
148\f
149/* Clean up connection to a remote debugger. */
150
151/* ARGSUSED */
152static void
153sds_close (quitting)
154 int quitting;
155{
156 if (sds_desc)
157 SERIAL_CLOSE (sds_desc);
158 sds_desc = NULL;
159}
160
161/* Stub for catch_errors. */
162
163static int
164sds_start_remote (dummy)
165 char *dummy;
166{
167 char c;
168 unsigned char buf[200];
169
170 immediate_quit = 1; /* Allow user to interrupt it */
171
172 /* Ack any packet which the remote side has already sent. */
173 SERIAL_WRITE (sds_desc, "{#*\r\n", 5);
174 SERIAL_WRITE (sds_desc, "{#}\r\n", 5);
175
176 while ((c = readchar (1)) >= 0)
177 printf_unfiltered ("%c");
178 printf_unfiltered ("\n");
179
180 next_msg_id = 251;
181
182 buf[0] = 26;
183 sds_send (buf, 1);
184
185 buf[0] = 0;
186 sds_send (buf, 1);
187
188 immediate_quit = 0;
189
190 start_remote (); /* Initialize gdb process mechanisms */
191 return 1;
192}
193
194/* Open a connection to a remote debugger.
195 NAME is the filename used for communication. */
196
197static DCACHE *sds_dcache;
198
199static void
200sds_open (name, from_tty)
201 char *name;
202 int from_tty;
203{
204 if (name == 0)
205 error ("To open a remote debug connection, you need to specify what serial\n\
206device is attached to the remote system (e.g. /dev/ttya).");
207
208 target_preopen (from_tty);
209
210 unpush_target (&sds_ops);
211
212 sds_dcache = dcache_init (sds_read_bytes, sds_write_bytes);
213
214 sds_desc = SERIAL_OPEN (name);
215 if (!sds_desc)
216 perror_with_name (name);
217
218 if (baud_rate != -1)
219 {
220 if (SERIAL_SETBAUDRATE (sds_desc, baud_rate))
221 {
222 SERIAL_CLOSE (sds_desc);
223 perror_with_name (name);
224 }
225 }
226
227
228 SERIAL_RAW (sds_desc);
229
230 /* If there is something sitting in the buffer we might take it as a
231 response to a command, which would be bad. */
232 SERIAL_FLUSH_INPUT (sds_desc);
233
234 if (from_tty)
235 {
236 puts_filtered ("Remote debugging using ");
237 puts_filtered (name);
238 puts_filtered ("\n");
239 }
240 push_target (&sds_ops); /* Switch to using remote target now */
241
242 /* Without this, some commands which require an active target (such
243 as kill) won't work. This variable serves (at least) double duty
244 as both the pid of the target process (if it has such), and as a
245 flag indicating that a target is active. These functions should
246 be split out into seperate variables, especially since GDB will
247 someday have a notion of debugging several processes. */
248
249 inferior_pid = 42000;
250
251 just_started = 1;
252
253 /* Start the remote connection; if error (0), discard this target.
254 In particular, if the user quits, be sure to discard it (we'd be
255 in an inconsistent state otherwise). */
256 if (!catch_errors (sds_start_remote, (char *)0,
257 "Couldn't establish connection to remote target\n",
258 RETURN_MASK_ALL))
259 pop_target ();
260}
261
262/* This takes a program previously attached to and detaches it. After
263 this is done, GDB can be used to debug some other program. We
264 better not have left any breakpoints in the target program or it'll
265 die when it hits one. */
266
267static void
268sds_detach (args, from_tty)
269 char *args;
270 int from_tty;
271{
272 char buf[PBUFSIZ];
273
274 if (args)
275 error ("Argument given to \"detach\" when remotely debugging.");
276
277#if 0
278 /* Tell the remote target to detach. */
279 strcpy (buf, "D");
280 sds_send (buf, 1);
281#endif
282
283 pop_target ();
284 if (from_tty)
285 puts_filtered ("Ending remote debugging.\n");
286}
287
288/* Convert hex digit A to a number. */
289
290static int
291fromhex (a)
292 int a;
293{
294 if (a >= '0' && a <= '9')
295 return a - '0';
296 else if (a >= 'a' && a <= 'f')
297 return a - 'a' + 10;
298 else
299 error ("Reply contains invalid hex digit %d", a);
300}
301
302/* Convert number NIB to a hex digit. */
303
304static int
305tohex (nib)
306 int nib;
307{
308 if (nib < 10)
309 return '0'+nib;
310 else
311 return 'a'+nib-10;
312}
313
314static int
315tob64 (inbuf, outbuf, len)
316 unsigned char *inbuf;
317 char *outbuf;
318 int len;
319{
320 int i, sum;
3d7cd517 321 char *p;
2d46177c
SS
322
323 if (len % 3 != 0)
324 error ("bad length");
325
3d7cd517 326 p = outbuf;
2d46177c
SS
327 for (i = 0; i < len; i += 3)
328 {
329 /* Collect the next three bytes into a number. */
330 sum = ((long) *inbuf++) << 16;
331 sum |= ((long) *inbuf++) << 8;
332 sum |= ((long) *inbuf++);
333
334 /* Spit out 4 6-bit encodings. */
3d7cd517
SS
335 *p++ = ((sum >> 18) & 0x3f) + '0';
336 *p++ = ((sum >> 12) & 0x3f) + '0';
337 *p++ = ((sum >> 6) & 0x3f) + '0';
338 *p++ = (sum & 0x3f) + '0';
2d46177c 339 }
3d7cd517 340 return (p - outbuf);
2d46177c
SS
341}
342
343static int
344fromb64 (inbuf, outbuf, len)
345 char *inbuf, *outbuf;
346 int len;
347{
348 int i, sum;
349
350 if (len % 4 != 0)
351 error ("bad length");
352
353 for (i = 0; i < len; i += 4)
354 {
355 /* Collect 4 6-bit digits. */
356 sum = (*inbuf++ - '0') << 18;
357 sum |= (*inbuf++ - '0') << 12;
358 sum |= (*inbuf++ - '0') << 6;
359 sum |= (*inbuf++ - '0');
360
361 /* Now take the resulting 24-bit number and get three bytes out
362 of it. */
363 *outbuf++ = (sum >> 16) & 0xff;
364 *outbuf++ = (sum >> 8) & 0xff;
365 *outbuf++ = sum & 0xff;
366 }
367
368 return (len / 4) * 3;
369}
370
371\f
372/* Tell the remote machine to resume. */
373
374static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
375int last_sent_step;
376
377static void
378sds_resume (pid, step, siggnal)
379 int pid, step;
380 enum target_signal siggnal;
381{
382 unsigned char buf[PBUFSIZ];
383
384 dcache_flush (sds_dcache);
385
386 last_sent_signal = siggnal;
387 last_sent_step = step;
388
389 buf[0] = (step ? 21 : 20);
390 buf[1] = 0; /* (should be signal?) */
391
392 sds_send (buf, 2);
393}
394\f
3d7cd517
SS
395/* Send a message to target to halt it. Target will respond, and send
396 us a message pending notice. */
2d46177c
SS
397
398static void
399sds_interrupt (signo)
400 int signo;
401{
3d7cd517
SS
402 unsigned char buf[PBUFSIZ];
403
2d46177c
SS
404 /* If this doesn't work, try more severe steps. */
405 signal (signo, sds_interrupt_twice);
406
407 if (remote_debug)
408 printf_unfiltered ("sds_interrupt called\n");
409
3d7cd517
SS
410 buf[0] = 25;
411 sds_send (buf, 1);
2d46177c
SS
412}
413
414static void (*ofunc)();
415
416/* The user typed ^C twice. */
3d7cd517 417
2d46177c
SS
418static void
419sds_interrupt_twice (signo)
420 int signo;
421{
422 signal (signo, ofunc);
423
424 interrupt_query ();
425
426 signal (signo, sds_interrupt);
427}
428
429/* Ask the user what to do when an interrupt is received. */
430
431static void
432interrupt_query ()
433{
434 target_terminal_ours ();
435
436 if (query ("Interrupted while waiting for the program.\n\
437Give up (and stop debugging it)? "))
438 {
439 target_mourn_inferior ();
440 return_to_top_level (RETURN_QUIT);
441 }
442
443 target_terminal_inferior ();
444}
445
446/* If nonzero, ignore the next kill. */
447int kill_kludge;
448
449/* Wait until the remote machine stops, then return, storing status in
450 STATUS just as `wait' would. Returns "pid" (though it's not clear
451 what, if anything, that means in the case of this target). */
452
453static int
454sds_wait (pid, status)
455 int pid;
456 struct target_waitstatus *status;
457{
458 unsigned char buf[PBUFSIZ];
459 int retlen;
460
461 status->kind = TARGET_WAITKIND_EXITED;
462 status->value.integer = 0;
463
464 ofunc = (void (*)()) signal (SIGINT, sds_interrupt);
465
466 signal (SIGINT, ofunc);
467
468 if (just_started)
469 {
470 just_started = 0;
471 status->kind = TARGET_WAITKIND_STOPPED;
472 return inferior_pid;
473 }
474
475 while (1)
476 {
477 getmessage (buf, 1);
478
479 if (message_pending)
480 {
481 buf[0] = 26;
482 retlen = sds_send (buf, 1);
3d7cd517
SS
483 if (remote_debug)
484 {
485 fprintf_unfiltered (gdb_stderr, "Signals: %04x %02x %02x\n",
486 ((int) buf[0]) << 8 + buf[1],
487 buf[2], buf[3]);
488 }
2d46177c
SS
489 message_pending = 0;
490 status->kind = TARGET_WAITKIND_STOPPED;
3d7cd517 491 status->value.sig = TARGET_SIGNAL_TRAP;
2d46177c
SS
492 goto got_status;
493 }
494 }
495 got_status:
496 return inferior_pid;
497}
498
3d7cd517 499static unsigned char sprs[16];
2d46177c
SS
500
501/* Read the remote registers into the block REGS. */
502/* Currently we just read all the registers, so we don't use regno. */
503
504/* ARGSUSED */
505static void
506sds_fetch_registers (regno)
507 int regno;
508{
509 unsigned char buf[PBUFSIZ];
3d7cd517 510 int i, retlen;
2d46177c
SS
511 char *p;
512 char regs[REGISTER_BYTES];
513
514 /* Unimplemented registers read as all bits zero. */
515 memset (regs, 0, REGISTER_BYTES);
516
517 buf[0] = 18;
3d7cd517 518 buf[1] = 1;
2d46177c 519 buf[2] = 0;
3d7cd517 520 retlen = sds_send (buf, 3);
2d46177c 521
3d7cd517
SS
522 for (i = 0; i < 4 * 6; ++i)
523 regs[i + 4 * 32 + 8 * 32] = buf[i];
524 for (i = 0; i < 4 * 4; ++i)
525 sprs[i] = buf[i + 4 * 7];
2d46177c
SS
526
527 buf[0] = 18;
3d7cd517 528 buf[1] = 2;
2d46177c 529 buf[2] = 0;
3d7cd517 530 retlen = sds_send (buf, 3);
2d46177c 531
3d7cd517
SS
532 for (i = 0; i < retlen; i++)
533 regs[i] = buf[i];
2d46177c
SS
534
535 /* (should warn about reply too short) */
536
2d46177c
SS
537 for (i = 0; i < NUM_REGS; i++)
538 supply_register (i, &regs[REGISTER_BYTE(i)]);
539}
540
3d7cd517
SS
541/* Prepare to store registers. Since we may send them all, we have to
542 read out the ones we don't want to change first. */
2d46177c
SS
543
544static void
545sds_prepare_to_store ()
546{
547 /* Make sure the entire registers array is valid. */
548 read_register_bytes (0, (char *)NULL, REGISTER_BYTES);
549}
550
551/* Store register REGNO, or all registers if REGNO == -1, from the contents
552 of REGISTERS. FIXME: ignores errors. */
553
554static void
555sds_store_registers (regno)
556 int regno;
557{
3d7cd517 558 unsigned char *p, buf[PBUFSIZ];
2d46177c 559 int i;
2d46177c 560
3d7cd517
SS
561 /* Store all the special-purpose registers. */
562 p = buf;
563 *p++ = 19;
564 *p++ = 1;
565 *p++ = 0;
566 *p++ = 0;
567 for (i = 0; i < 4 * 6; i++)
568 *p++ = registers[i + 4 * 32 + 8 * 32];
569 for (i = 0; i < 4 * 1; i++)
570 *p++ = 0;
571 for (i = 0; i < 4 * 4; i++)
572 *p++ = sprs[i];
573
574 sds_send (buf, p - buf);
575
576 /* Store all the general-purpose registers. */
577 p = buf;
578 *p++ = 19;
579 *p++ = 2;
580 *p++ = 0;
581 *p++ = 0;
2d46177c 582 for (i = 0; i < 4 * 32; i++)
3d7cd517 583 *p++ = registers[i];
2d46177c 584
3d7cd517 585 sds_send (buf, p - buf);
2d46177c 586
2d46177c 587}
2d46177c
SS
588\f
589/* Write memory data directly to the remote machine. This does not
590 inform the data cache; the data cache uses this. MEMADDR is the
591 address in the remote memory space. MYADDR is the address of the
592 buffer in our space. LEN is the number of bytes.
593
594 Returns number of bytes transferred, or 0 for error. */
595
596static int
597sds_write_bytes (memaddr, myaddr, len)
598 CORE_ADDR memaddr;
599 char *myaddr;
600 int len;
601{
602 int max_buf_size; /* Max size of packet output buffer */
603 int origlen;
604 unsigned char buf[PBUFSIZ];
605 int todo;
606 int i;
607
608 /* Chop the transfer down if necessary */
609
610 max_buf_size = 150;
611
612 origlen = len;
613 while (len > 0)
614 {
615 todo = min (len, max_buf_size);
616
617 buf[0] = 13;
618 buf[1] = 0;
619 buf[2] = (int) (memaddr >> 24) & 0xff;
620 buf[3] = (int) (memaddr >> 16) & 0xff;
621 buf[4] = (int) (memaddr >> 8) & 0xff;
622 buf[5] = (int) (memaddr ) & 0xff;
623 buf[6] = 1;
624 buf[7] = 0;
625
626 for (i = 0; i < todo; i++)
627 buf[i + 8] = myaddr[i];
628
629 sds_send (buf, 8 + todo);
630
631 /* (should look at result) */
632
633 myaddr += todo;
634 memaddr += todo;
635 len -= todo;
636 }
637 return origlen;
638}
639
640/* Read memory data directly from the remote machine. This does not
641 use the data cache; the data cache uses this. MEMADDR is the
642 address in the remote memory space. MYADDR is the address of the
643 buffer in our space. LEN is the number of bytes.
644
645 Returns number of bytes transferred, or 0 for error. */
646
647static int
648sds_read_bytes (memaddr, myaddr, len)
649 CORE_ADDR memaddr;
650 char *myaddr;
651 int len;
652{
653 int max_buf_size; /* Max size of packet output buffer */
654 int origlen, retlen;
655 unsigned char buf[PBUFSIZ];
656 int todo;
657 int i;
658
659 /* Chop the transfer down if necessary */
660
661 max_buf_size = 150;
662
663 origlen = len;
664 while (len > 0)
665 {
666 todo = min (len, max_buf_size);
667
668 buf[0] = 12;
669 buf[1] = 0;
670 buf[2] = (int) (memaddr >> 24) & 0xff;
671 buf[3] = (int) (memaddr >> 16) & 0xff;
672 buf[4] = (int) (memaddr >> 8) & 0xff;
673 buf[5] = (int) (memaddr ) & 0xff;
674 buf[6] = (int) (todo >> 8) & 0xff;
675 buf[7] = (int) (todo ) & 0xff;
676 buf[8] = 1;
677
678 retlen = sds_send (buf, 9);
679
680 if (retlen - 2 != todo)
681 {
682 return 0;
683 }
684
685 /* Reply describes memory byte by byte. */
686
687 for (i = 0; i < todo; i++)
688 myaddr[i] = buf[i + 2];
689
690 myaddr += todo;
691 memaddr += todo;
692 len -= todo;
693 }
694
695 return origlen;
696}
697\f
698/* Read or write LEN bytes from inferior memory at MEMADDR,
699 transferring to or from debugger address MYADDR. Write to inferior
700 if SHOULD_WRITE is nonzero. Returns length of data written or
701 read; 0 for error. */
702
703/* ARGSUSED */
704static int
705sds_xfer_memory(memaddr, myaddr, len, should_write, target)
706 CORE_ADDR memaddr;
707 char *myaddr;
708 int len;
709 int should_write;
710 struct target_ops *target; /* ignored */
711{
712 return dcache_xfer_memory (sds_dcache, memaddr, myaddr, len, should_write);
713}
714
715\f
716static void
717sds_files_info (ignore)
718 struct target_ops *ignore;
719{
3d7cd517 720 puts_filtered ("Debugging over a serial connection, using SDS protocol.\n");
2d46177c
SS
721}
722\f
723/* Stuff for dealing with the packets which are part of this protocol.
724 See comment at top of file for details. */
725
726/* Read a single character from the remote end, masking it down to 7 bits. */
727
728static int
729readchar (timeout)
730 int timeout;
731{
732 int ch;
733
734 ch = SERIAL_READCHAR (sds_desc, timeout);
735
736 if (remote_debug > 1 && ch >= 0)
737 printf_unfiltered("%c(%x)", ch, ch);
738
739 switch (ch)
740 {
741 case SERIAL_EOF:
742 error ("Remote connection closed");
743 case SERIAL_ERROR:
744 perror_with_name ("Remote communication error");
745 case SERIAL_TIMEOUT:
746 return ch;
747 default:
748 return ch & 0x7f;
749 }
750}
751
3d7cd517
SS
752/* An SDS-style checksum is a sum of the bytes modulo 253. (Presumably
753 because 253, 254, and 255 are special flags in the protocol.) */
754
2d46177c
SS
755static int
756compute_checksum (csum, buf, len)
757 int csum, len;
758 char *buf;
759{
760 int i;
761
762 for (i = 0; i < len; ++i)
763 csum += (unsigned char) buf[i];
764
765 csum %= 253;
766 return csum;
767}
768
769/* Send the command in BUF to the remote machine, and read the reply
770 into BUF also. */
771
772static int
773sds_send (buf, len)
774 unsigned char *buf;
775 int len;
776{
777 putmessage (buf, len);
778
779 return getmessage (buf, 0);
780}
781
782/* Send a message to the remote machine. */
783
784static int
785putmessage (buf, len)
786 unsigned char *buf;
787 int len;
788{
3d7cd517 789 int i, enclen;
2d46177c
SS
790 unsigned char csum = 0;
791 char buf2[PBUFSIZ], buf3[PBUFSIZ];
792 unsigned char header[3];
793 int ch;
794 int tcount = 0;
795 char *p;
796
797 /* Copy the packet into buffer BUF2, encapsulating it
798 and giving it a checksum. */
799
3d7cd517 800 if (len > 170) /* Prosanity check */
2d46177c
SS
801 abort();
802
803 if (remote_debug)
804 {
805 fprintf_unfiltered (gdb_stderr, "Message to send: \"");
806 for (i = 0; i < len; ++i)
807 fprintf_unfiltered (gdb_stderr, "%02x", buf[i]);
808 fprintf_unfiltered (gdb_stderr, "\"\n");
809 }
810
811 p = buf2;
812 *p++ = '$';
813
2d46177c
SS
814 if (len % 3 != 0)
815 {
816 buf[len] = '\0';
817 buf[len+1] = '\0';
818 }
819
3d7cd517 820 header[1] = next_msg_id;
2d46177c
SS
821
822 header[2] = len;
823
824 csum = compute_checksum (csum, buf, len);
3d7cd517 825 csum = compute_checksum (csum, header + 1, 2);
2d46177c
SS
826
827 header[0] = csum;
828
829 tob64 (header, p, 3);
830 p += 4;
3d7cd517 831 enclen = tob64 (buf, buf3, ((len + 2) / 3) * 3);
2d46177c 832
3d7cd517
SS
833 for (i = 0; i < enclen; ++i)
834 *p++ = buf3[i];
2d46177c
SS
835 *p++ = '\r';
836 *p++ = '\n';
837
838 next_msg_id = (next_msg_id + 3) % 245;
839
840 /* Send it over and over until we get a positive ack. */
841
842 while (1)
843 {
844 int started_error_output = 0;
845
846 if (remote_debug)
847 {
848 *p = '\0';
849 printf_unfiltered ("Sending encoded: \"%s\"", buf2);
850 printf_unfiltered (" (Checksum %d, id %d, length %d)\n",
851 header[0], header[1], header[2]);
852 gdb_flush (gdb_stdout);
853 }
854 if (SERIAL_WRITE (sds_desc, buf2, p - buf2))
855 perror_with_name ("putmessage: write failed");
856
857 return 1;
858
859 }
860
861}
862
863/* Come here after finding the start of the frame. Collect the rest
864 into BUF. Returns 0 on any error, 1 on success. */
865
866static int
867read_frame (buf)
868 char *buf;
869{
870 char *bp;
871 int c;
872
873 bp = buf;
874
875 while (1)
876 {
877 c = readchar (sds_timeout);
878
879 switch (c)
880 {
881 case SERIAL_TIMEOUT:
882 if (remote_debug)
883 puts_filtered ("Timeout in mid-message, retrying\n");
884 return 0;
885 case '$':
886 if (remote_debug)
887 puts_filtered ("Saw new packet start in middle of old one\n");
888 return 0; /* Start a new packet, count retries */
889 case '\r':
890 break;
891
892 case '\n':
893 {
894 *bp = '\000';
895 if (remote_debug)
3d7cd517
SS
896 fprintf_unfiltered (gdb_stderr, "Received encoded: \"%s\"\n",
897 buf);
2d46177c
SS
898 return 1;
899 }
900
901 default:
902 if (bp < buf + PBUFSIZ - 1)
903 {
904 *bp++ = c;
905 continue;
906 }
907
908 *bp = '\0';
909 puts_filtered ("Message too long: ");
910 puts_filtered (buf);
911 puts_filtered ("\n");
912
913 return 0;
914 }
915 }
916}
917
918/* Read a packet from the remote machine, with error checking,
919 and store it in BUF. BUF is expected to be of size PBUFSIZ.
920 If FOREVER, wait forever rather than timing out; this is used
921 while the target is executing user code. */
922
923static int
924getmessage (buf, forever)
925 unsigned char *buf;
926 int forever;
927{
928 int c, c2, c3;
929 int tries;
930 int timeout;
931 int val, i, len, csum;
932 unsigned char header[3];
933 unsigned char inbuf[500];
934
935 strcpy (buf, "timeout");
936
937 if (forever)
938 {
939#ifdef MAINTENANCE_CMDS
940 timeout = watchdog > 0 ? watchdog : -1;
941#else
942 timeout = -1;
943#endif
944 }
945
946 else
947 timeout = sds_timeout;
948
949#define MAX_TRIES 3
950
951 for (tries = 1; tries <= MAX_TRIES; tries++)
952 {
953 /* This can loop forever if the remote side sends us characters
954 continuously, but if it pauses, we'll get a zero from readchar
955 because of timeout. Then we'll count that as a retry. */
956
957 /* Note that we will only wait forever prior to the start of a packet.
958 After that, we expect characters to arrive at a brisk pace. They
959 should show up within sds_timeout intervals. */
960
961 do
962 {
963 c = readchar (timeout);
964
965 if (c == SERIAL_TIMEOUT)
966 {
967#ifdef MAINTENANCE_CMDS
968 if (forever) /* Watchdog went off. Kill the target. */
969 {
970 target_mourn_inferior ();
971 error ("Watchdog has expired. Target detached.\n");
972 }
973#endif
974 if (remote_debug)
975 puts_filtered ("Timed out.\n");
976 goto retry;
977 }
978 }
979 while (c != '$' && c != '{');
980
981 /* We might have seen a "trigraph", a sequence of three characters
982 that indicate various sorts of communication state. */
983
984 if (c == '{')
985 {
986 /* Read the other two chars of the trigraph. */
987 c2 = readchar (timeout);
988 c3 = readchar (timeout);
989 if (remote_debug)
990 fprintf_unfiltered (gdb_stderr, "Trigraph %c%c%c received\n",
991 c, c2, c3);
992 if (c3 == '+')
993 {
994 message_pending = 1;
995 return;
996 }
997 continue;
998 }
999
1000 val = read_frame (inbuf);
1001
1002 if (val == 1)
1003 {
1004 fromb64 (inbuf, header, 4);
1005 /* (should check out other bits) */
1006 fromb64 (inbuf + 4, buf, strlen (inbuf) - 4);
1007
1008 len = header[2];
1009
1010 csum = 0;
1011 csum = compute_checksum (csum, buf, len);
1012 csum = compute_checksum (csum, header + 1, 2);
1013
1014 if (csum != header[0])
1015 fprintf_unfiltered (gdb_stderr,
1016 "Checksum mismatch: computed %d, received %d\n",
1017 csum, header[0]);
1018
1019 if (header[2] == 0xff)
1020 fprintf_unfiltered (gdb_stderr, "Requesting resend...\n");
1021
1022 if (remote_debug)
1023 {
1024 fprintf_unfiltered (gdb_stderr,
1025 "... (Got checksum %d, id %d, length %d)\n",
1026 header[0], header[1], header[2]);
1027 fprintf_unfiltered (gdb_stderr, "Message received: \"");
1028 for (i = 0; i < len; ++i)
1029 {
1030 fprintf_unfiltered (gdb_stderr, "%02x", (unsigned char) buf[i]);
1031 }
1032 fprintf_unfiltered (gdb_stderr, "\"\n");
1033 }
1034
1035 /* no ack required? */
1036 return len;
1037 }
1038
1039 /* Try the whole thing again. */
1040 retry:
1041 /* need to do something here */
1042 }
1043
1044 /* We have tried hard enough, and just can't receive the packet. Give up. */
1045
1046 printf_unfiltered ("Ignoring packet error, continuing...\n");
1047}
1048\f
1049static void
1050sds_kill ()
1051{
1052 /* For some mysterious reason, wait_for_inferior calls kill instead of
1053 mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
1054 if (kill_kludge)
1055 {
1056 kill_kludge = 0;
1057 target_mourn_inferior ();
1058 return;
1059 }
1060
1061#if 0 /* fix to use 1-arg fn */
1062 /* Use catch_errors so the user can quit from gdb even when we aren't on
1063 speaking terms with the remote system. */
1064 catch_errors (putmessage, "k", "", RETURN_MASK_ERROR);
1065#endif
1066
1067 /* Don't wait for it to die. I'm not really sure it matters whether
1068 we do or not. For the existing stubs, kill is a noop. */
1069 target_mourn_inferior ();
1070}
1071
1072static void
1073sds_mourn ()
1074{
1075 unpush_target (&sds_ops);
1076 generic_mourn_inferior ();
1077}
1078
1079static void
1080sds_create_inferior (exec_file, args, env)
1081 char *exec_file;
1082 char *args;
1083 char **env;
1084{
1085 /* Rip out the breakpoints; we'll reinsert them after restarting
1086 the remote server. */
1087 remove_breakpoints ();
1088
1089 /* Now restart the remote server. */
1090 sds_restart ();
1091
1092 /* Now put the breakpoints back in. This way we're safe if the
1093 restart function works via a unix fork on the remote side. */
1094 insert_breakpoints ();
1095
1096 /* Clean up from the last time we were running. */
1097 clear_proceed_status ();
1098
1099 /* Let the remote process run. */
1100 proceed (-1, TARGET_SIGNAL_0, 0);
1101}
1102
1103\f
1104/* The SDS monitor has commands for breakpoint insertion, although it
1105 it doesn't actually manage the breakpoints, it just returns the
1106 replaced instruction back to the debugger. */
1107
1108static int
1109sds_insert_breakpoint (addr, contents_cache)
1110 CORE_ADDR addr;
1111 char *contents_cache;
1112{
3d7cd517
SS
1113 int i, retlen;
1114 unsigned char *p, buf[PBUFSIZ];
1115
1116 p = buf;
1117 *p++ = 16;
1118 *p++ = 0;
1119 *p++ = (int) (addr >> 24) & 0xff;
1120 *p++ = (int) (addr >> 16) & 0xff;
1121 *p++ = (int) (addr >> 8) & 0xff;
1122 *p++ = (int) (addr ) & 0xff;
1123
1124 retlen = sds_send (buf, p - buf);
2d46177c 1125
3d7cd517
SS
1126 for (i = 0; i < 4; ++i)
1127 contents_cache[i] = buf[i + 2];
2d46177c 1128
3d7cd517 1129 return 0;
2d46177c
SS
1130}
1131
1132static int
1133sds_remove_breakpoint (addr, contents_cache)
1134 CORE_ADDR addr;
1135 char *contents_cache;
1136{
3d7cd517
SS
1137 int i, retlen;
1138 unsigned char *p, buf[PBUFSIZ];
1139
1140 p = buf;
1141 *p++ = 17;
1142 *p++ = 0;
1143 *p++ = (int) (addr >> 24) & 0xff;
1144 *p++ = (int) (addr >> 16) & 0xff;
1145 *p++ = (int) (addr >> 8) & 0xff;
1146 *p++ = (int) (addr ) & 0xff;
1147 for (i = 0; i < 4; ++i)
1148 *p++ = contents_cache[i];
1149
1150 retlen = sds_send (buf, p - buf);
1151
1152 return 0;
2d46177c
SS
1153}
1154\f
1155/* Define the target operations vector. */
1156
1157static struct target_ops sds_ops =
1158{
1159 "sds", /* to_shortname */
1160 "Remote serial target with SDS protocol", /* to_longname */
1161 "Use a remote computer via a serial line, using the SDS protocol.\n\
1162Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
1163 sds_open, /* to_open */
1164 sds_close, /* to_close */
1165 NULL, /* to_attach */
1166 sds_detach, /* to_detach */
1167 sds_resume, /* to_resume */
1168 sds_wait, /* to_wait */
1169 sds_fetch_registers, /* to_fetch_registers */
1170 sds_store_registers, /* to_store_registers */
1171 sds_prepare_to_store, /* to_prepare_to_store */
1172 sds_xfer_memory, /* to_xfer_memory */
1173 sds_files_info, /* to_files_info */
1174 sds_insert_breakpoint, /* to_insert_breakpoint */
1175 sds_remove_breakpoint, /* to_remove_breakpoint */
1176 NULL, /* to_terminal_init */
1177 NULL, /* to_terminal_inferior */
1178 NULL, /* to_terminal_ours_for_output */
1179 NULL, /* to_terminal_ours */
1180 NULL, /* to_terminal_info */
1181 sds_kill, /* to_kill */
1182 generic_load, /* to_load */
1183 NULL, /* to_lookup_symbol */
1184 sds_create_inferior, /* to_create_inferior */
1185 sds_mourn, /* to_mourn_inferior */
1186 0, /* to_can_run */
1187 0, /* to_notice_signals */
1188 0, /* to_thread_alive */
1189 0, /* to_stop */
1190 process_stratum, /* to_stratum */
1191 NULL, /* to_next */
1192 1, /* to_has_all_memory */
1193 1, /* to_has_memory */
1194 1, /* to_has_stack */
1195 1, /* to_has_registers */
1196 1, /* to_has_execution */
1197 NULL, /* sections */
1198 NULL, /* sections_end */
1199 OPS_MAGIC /* to_magic */
1200};
1201
1202/* Put a command string, in args, out to the monitor and display the
1203 reply message. */
1204
1205static void
1206sds_command (args, from_tty)
1207 char *args;
1208 int from_tty;
1209{
1210 char *p;
3d7cd517 1211 int i, len, retlen;
2d46177c
SS
1212 unsigned char buf[1000];
1213
1214 /* Convert hexadecimal chars into a byte buffer. */
1215 p = args;
1216 len = 0;
1217 while (*p != '\0')
1218 {
1219 buf[len++] = fromhex (p[0]) * 16 + fromhex (p[1]);
1220 if (p[1] == '\0')
1221 break;
1222 p += 2;
1223 }
1224
3d7cd517 1225 retlen = sds_send (buf, len);
2d46177c
SS
1226
1227 printf_filtered ("Reply is ");
3d7cd517 1228 for (i = 0; i < retlen; ++i)
2d46177c
SS
1229 {
1230 printf_filtered ("%02x", buf[i]);
1231 }
1232 printf_filtered ("\n");
1233}
1234
1235void
1236_initialize_remote_sds ()
1237{
1238 add_target (&sds_ops);
1239
1240 add_show_from_set (add_set_cmd ("sdstimeout", no_class,
1241 var_integer, (char *)&sds_timeout,
1242 "Set timeout value for sds read.\n", &setlist),
1243 &showlist);
1244
1245 add_com ("sds", class_obscure, sds_command,
1246 "Send a command to the SDS monitor.");
1247}
This page took 0.068698 seconds and 4 git commands to generate.