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