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