Allow PPC users to select which PPC/RS6000 variant they're debugging
[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"
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
a23dbfcb
SS
48extern void _initialize_remote_sds PARAMS ((void));
49
2d46177c
SS
50/* Declarations of local functions. */
51
52static int sds_write_bytes PARAMS ((CORE_ADDR, char *, int));
53
54static int sds_read_bytes PARAMS ((CORE_ADDR, char *, int));
55
56static void sds_files_info PARAMS ((struct target_ops *ignore));
57
58static int sds_xfer_memory PARAMS ((CORE_ADDR, char *,
59 int, int, struct target_ops *));
60
61static void sds_prepare_to_store PARAMS ((void));
62
63static void sds_fetch_registers PARAMS ((int));
64
65static void sds_resume PARAMS ((int, int, enum target_signal));
66
bc8bd256 67static int sds_start_remote PARAMS ((PTR));
2d46177c
SS
68
69static void sds_open PARAMS ((char *, int));
70
71static void sds_close PARAMS ((int));
72
73static void sds_store_registers PARAMS ((int));
74
75static void sds_mourn PARAMS ((void));
76
2d46177c
SS
77static void sds_create_inferior PARAMS ((char *, char *, char **));
78
9d59cbb1 79static void sds_load PARAMS ((char *, int));
665ff287 80
2d46177c
SS
81static int getmessage PARAMS ((unsigned char *, int));
82
83static int putmessage PARAMS ((unsigned char *, int));
84
85static int sds_send PARAMS ((unsigned char *, int));
86
87static int readchar PARAMS ((int));
88
89static int sds_wait PARAMS ((int, struct target_waitstatus *));
90
91static void sds_kill PARAMS ((void));
92
93static int tohex PARAMS ((int));
94
95static int fromhex PARAMS ((int));
96
97static void sds_detach PARAMS ((char *, int));
98
99static void sds_interrupt PARAMS ((int));
100
101static void sds_interrupt_twice PARAMS ((int));
102
103static void interrupt_query PARAMS ((void));
104
105static int read_frame PARAMS ((char *));
106
107static int sds_insert_breakpoint PARAMS ((CORE_ADDR, char *));
108
109static int sds_remove_breakpoint PARAMS ((CORE_ADDR, char *));
110
a23dbfcb
SS
111static void init_sds_ops PARAMS ((void));
112
113static void sds_command PARAMS ((char *args, int from_tty));
114
115/* Define the target operations vector. */
2d46177c 116
a23dbfcb 117static struct target_ops sds_ops;
2d46177c
SS
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
2d46177c
SS
124static int sds_timeout = 2;
125
2d46177c
SS
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
3d7cd517
SS
132/* This limit comes from the monitor. */
133
134#define PBUFSIZ 250
2d46177c
SS
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
2d46177c
SS
140static int next_msg_id;
141
142static int just_started;
143
144static int message_pending;
145
2d46177c
SS
146\f
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)
bc8bd256 163 PTR dummy;
2d46177c
SS
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)
959941e7 175 printf_unfiltered ("%c", c);
2d46177c
SS
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
2d46177c
SS
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). */
bc8bd256 245 if (!catch_errors (sds_start_remote, NULL,
2d46177c
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;
287 else
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)
298 return '0'+nib;
299 else
300 return 'a'+nib-10;
301}
302
303static int
304tob64 (inbuf, outbuf, len)
305 unsigned char *inbuf;
306 char *outbuf;
307 int len;
308{
309 int i, sum;
3d7cd517 310 char *p;
2d46177c
SS
311
312 if (len % 3 != 0)
313 error ("bad length");
314
3d7cd517 315 p = outbuf;
2d46177c
SS
316 for (i = 0; i < len; i += 3)
317 {
318 /* Collect the next three bytes into a number. */
319 sum = ((long) *inbuf++) << 16;
320 sum |= ((long) *inbuf++) << 8;
321 sum |= ((long) *inbuf++);
322
323 /* Spit out 4 6-bit encodings. */
3d7cd517
SS
324 *p++ = ((sum >> 18) & 0x3f) + '0';
325 *p++ = ((sum >> 12) & 0x3f) + '0';
326 *p++ = ((sum >> 6) & 0x3f) + '0';
327 *p++ = (sum & 0x3f) + '0';
2d46177c 328 }
3d7cd517 329 return (p - outbuf);
2d46177c
SS
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. */
345 sum = (*inbuf++ - '0') << 18;
346 sum |= (*inbuf++ - '0') << 12;
347 sum |= (*inbuf++ - '0') << 6;
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;
353 *outbuf++ = (sum >> 8) & 0xff;
354 *outbuf++ = sum & 0xff;
355 }
356
357 return (len / 4) * 3;
358}
359
360\f
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);
379 buf[1] = 0; /* (should be signal?) */
380
381 sds_send (buf, 2);
382}
383\f
3d7cd517
SS
384/* Send a message to target to halt it. Target will respond, and send
385 us a message pending notice. */
2d46177c
SS
386
387static void
388sds_interrupt (signo)
389 int signo;
390{
3d7cd517
SS
391 unsigned char buf[PBUFSIZ];
392
2d46177c
SS
393 /* If this doesn't work, try more severe steps. */
394 signal (signo, sds_interrupt_twice);
395
396 if (remote_debug)
397 printf_unfiltered ("sds_interrupt called\n");
398
3d7cd517
SS
399 buf[0] = 25;
400 sds_send (buf, 1);
2d46177c
SS
401}
402
403static void (*ofunc)();
404
405/* The user typed ^C twice. */
3d7cd517 406
2d46177c
SS
407static void
408sds_interrupt_twice (signo)
409 int signo;
410{
411 signal (signo, ofunc);
412
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);
3d7cd517
SS
472 if (remote_debug)
473 {
474 fprintf_unfiltered (gdb_stderr, "Signals: %04x %02x %02x\n",
475 ((int) buf[0]) << 8 + buf[1],
476 buf[2], buf[3]);
477 }
2d46177c
SS
478 message_pending = 0;
479 status->kind = TARGET_WAITKIND_STOPPED;
3d7cd517 480 status->value.sig = TARGET_SIGNAL_TRAP;
2d46177c
SS
481 goto got_status;
482 }
483 }
484 got_status:
485 return inferior_pid;
486}
487
3d7cd517 488static unsigned char sprs[16];
2d46177c
SS
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];
3d7cd517 499 int i, retlen;
2d46177c
SS
500 char *p;
501 char regs[REGISTER_BYTES];
502
503 /* Unimplemented registers read as all bits zero. */
504 memset (regs, 0, REGISTER_BYTES);
505
506 buf[0] = 18;
3d7cd517 507 buf[1] = 1;
2d46177c 508 buf[2] = 0;
3d7cd517 509 retlen = sds_send (buf, 3);
2d46177c 510
3d7cd517
SS
511 for (i = 0; i < 4 * 6; ++i)
512 regs[i + 4 * 32 + 8 * 32] = buf[i];
513 for (i = 0; i < 4 * 4; ++i)
514 sprs[i] = buf[i + 4 * 7];
2d46177c
SS
515
516 buf[0] = 18;
3d7cd517 517 buf[1] = 2;
2d46177c 518 buf[2] = 0;
3d7cd517 519 retlen = sds_send (buf, 3);
2d46177c 520
3d7cd517
SS
521 for (i = 0; i < retlen; i++)
522 regs[i] = buf[i];
2d46177c
SS
523
524 /* (should warn about reply too short) */
525
2d46177c
SS
526 for (i = 0; i < NUM_REGS; i++)
527 supply_register (i, &regs[REGISTER_BYTE(i)]);
528}
529
3d7cd517
SS
530/* Prepare to store registers. Since we may send them all, we have to
531 read out the ones we don't want to change first. */
2d46177c
SS
532
533static void
534sds_prepare_to_store ()
535{
536 /* Make sure the entire registers array is valid. */
537 read_register_bytes (0, (char *)NULL, REGISTER_BYTES);
538}
539
540/* Store register REGNO, or all registers if REGNO == -1, from the contents
541 of REGISTERS. FIXME: ignores errors. */
542
543static void
544sds_store_registers (regno)
545 int regno;
546{
3d7cd517 547 unsigned char *p, buf[PBUFSIZ];
2d46177c 548 int i;
2d46177c 549
3d7cd517
SS
550 /* Store all the special-purpose registers. */
551 p = buf;
552 *p++ = 19;
553 *p++ = 1;
554 *p++ = 0;
555 *p++ = 0;
556 for (i = 0; i < 4 * 6; i++)
557 *p++ = registers[i + 4 * 32 + 8 * 32];
558 for (i = 0; i < 4 * 1; i++)
559 *p++ = 0;
560 for (i = 0; i < 4 * 4; i++)
561 *p++ = sprs[i];
562
563 sds_send (buf, p - buf);
564
565 /* Store all the general-purpose registers. */
566 p = buf;
567 *p++ = 19;
568 *p++ = 2;
569 *p++ = 0;
570 *p++ = 0;
2d46177c 571 for (i = 0; i < 4 * 32; i++)
3d7cd517 572 *p++ = registers[i];
2d46177c 573
3d7cd517 574 sds_send (buf, p - buf);
2d46177c 575
2d46177c 576}
2d46177c
SS
577\f
578/* Write memory data directly to the remote machine. This does not
579 inform the data cache; the data cache uses this. MEMADDR is the
580 address in the remote memory space. MYADDR is the address of the
581 buffer in our space. LEN is the number of bytes.
582
583 Returns number of bytes transferred, or 0 for error. */
584
585static int
586sds_write_bytes (memaddr, myaddr, len)
587 CORE_ADDR memaddr;
588 char *myaddr;
589 int len;
590{
591 int max_buf_size; /* Max size of packet output buffer */
592 int origlen;
593 unsigned char buf[PBUFSIZ];
594 int todo;
595 int i;
596
597 /* Chop the transfer down if necessary */
598
599 max_buf_size = 150;
600
601 origlen = len;
602 while (len > 0)
603 {
604 todo = min (len, max_buf_size);
605
606 buf[0] = 13;
607 buf[1] = 0;
608 buf[2] = (int) (memaddr >> 24) & 0xff;
609 buf[3] = (int) (memaddr >> 16) & 0xff;
610 buf[4] = (int) (memaddr >> 8) & 0xff;
611 buf[5] = (int) (memaddr ) & 0xff;
612 buf[6] = 1;
613 buf[7] = 0;
614
615 for (i = 0; i < todo; i++)
616 buf[i + 8] = myaddr[i];
617
618 sds_send (buf, 8 + todo);
619
620 /* (should look at result) */
621
622 myaddr += todo;
623 memaddr += todo;
624 len -= todo;
625 }
626 return origlen;
627}
628
629/* Read memory data directly from the remote machine. This does not
630 use the data cache; the data cache uses this. MEMADDR is the
631 address in the remote memory space. MYADDR is the address of the
632 buffer in our space. LEN is the number of bytes.
633
634 Returns number of bytes transferred, or 0 for error. */
635
636static int
637sds_read_bytes (memaddr, myaddr, len)
638 CORE_ADDR memaddr;
639 char *myaddr;
640 int len;
641{
642 int max_buf_size; /* Max size of packet output buffer */
643 int origlen, retlen;
644 unsigned char buf[PBUFSIZ];
645 int todo;
646 int i;
647
648 /* Chop the transfer down if necessary */
649
650 max_buf_size = 150;
651
652 origlen = len;
653 while (len > 0)
654 {
655 todo = min (len, max_buf_size);
656
657 buf[0] = 12;
658 buf[1] = 0;
659 buf[2] = (int) (memaddr >> 24) & 0xff;
660 buf[3] = (int) (memaddr >> 16) & 0xff;
661 buf[4] = (int) (memaddr >> 8) & 0xff;
662 buf[5] = (int) (memaddr ) & 0xff;
663 buf[6] = (int) (todo >> 8) & 0xff;
664 buf[7] = (int) (todo ) & 0xff;
665 buf[8] = 1;
666
667 retlen = sds_send (buf, 9);
668
669 if (retlen - 2 != todo)
670 {
671 return 0;
672 }
673
674 /* Reply describes memory byte by byte. */
675
676 for (i = 0; i < todo; i++)
677 myaddr[i] = buf[i + 2];
678
679 myaddr += todo;
680 memaddr += todo;
681 len -= todo;
682 }
683
684 return origlen;
685}
686\f
687/* Read or write LEN bytes from inferior memory at MEMADDR,
688 transferring to or from debugger address MYADDR. Write to inferior
689 if SHOULD_WRITE is nonzero. Returns length of data written or
690 read; 0 for error. */
691
692/* ARGSUSED */
693static int
694sds_xfer_memory(memaddr, myaddr, len, should_write, target)
695 CORE_ADDR memaddr;
696 char *myaddr;
697 int len;
698 int should_write;
699 struct target_ops *target; /* ignored */
700{
701 return dcache_xfer_memory (sds_dcache, memaddr, myaddr, len, should_write);
702}
703
704\f
705static void
706sds_files_info (ignore)
707 struct target_ops *ignore;
708{
3d7cd517 709 puts_filtered ("Debugging over a serial connection, using SDS protocol.\n");
2d46177c
SS
710}
711\f
712/* Stuff for dealing with the packets which are part of this protocol.
713 See comment at top of file for details. */
714
715/* Read a single character from the remote end, masking it down to 7 bits. */
716
717static int
718readchar (timeout)
719 int timeout;
720{
721 int ch;
722
723 ch = SERIAL_READCHAR (sds_desc, timeout);
724
725 if (remote_debug > 1 && ch >= 0)
726 printf_unfiltered("%c(%x)", ch, ch);
727
728 switch (ch)
729 {
730 case SERIAL_EOF:
731 error ("Remote connection closed");
732 case SERIAL_ERROR:
733 perror_with_name ("Remote communication error");
734 case SERIAL_TIMEOUT:
735 return ch;
736 default:
737 return ch & 0x7f;
738 }
739}
740
3d7cd517
SS
741/* An SDS-style checksum is a sum of the bytes modulo 253. (Presumably
742 because 253, 254, and 255 are special flags in the protocol.) */
743
2d46177c
SS
744static int
745compute_checksum (csum, buf, len)
746 int csum, len;
747 char *buf;
748{
749 int i;
750
751 for (i = 0; i < len; ++i)
752 csum += (unsigned char) buf[i];
753
754 csum %= 253;
755 return csum;
756}
757
758/* Send the command in BUF to the remote machine, and read the reply
759 into BUF also. */
760
761static int
762sds_send (buf, len)
763 unsigned char *buf;
764 int len;
765{
766 putmessage (buf, len);
767
768 return getmessage (buf, 0);
769}
770
771/* Send a message to the remote machine. */
772
773static int
774putmessage (buf, len)
775 unsigned char *buf;
776 int len;
777{
3d7cd517 778 int i, enclen;
2d46177c
SS
779 unsigned char csum = 0;
780 char buf2[PBUFSIZ], buf3[PBUFSIZ];
781 unsigned char header[3];
782 int ch;
783 int tcount = 0;
784 char *p;
785
786 /* Copy the packet into buffer BUF2, encapsulating it
787 and giving it a checksum. */
788
3d7cd517 789 if (len > 170) /* Prosanity check */
2d46177c
SS
790 abort();
791
792 if (remote_debug)
793 {
794 fprintf_unfiltered (gdb_stderr, "Message to send: \"");
795 for (i = 0; i < len; ++i)
796 fprintf_unfiltered (gdb_stderr, "%02x", buf[i]);
797 fprintf_unfiltered (gdb_stderr, "\"\n");
798 }
799
800 p = buf2;
801 *p++ = '$';
802
2d46177c
SS
803 if (len % 3 != 0)
804 {
805 buf[len] = '\0';
806 buf[len+1] = '\0';
807 }
808
3d7cd517 809 header[1] = next_msg_id;
2d46177c
SS
810
811 header[2] = len;
812
813 csum = compute_checksum (csum, buf, len);
3d7cd517 814 csum = compute_checksum (csum, header + 1, 2);
2d46177c
SS
815
816 header[0] = csum;
817
818 tob64 (header, p, 3);
819 p += 4;
3d7cd517 820 enclen = tob64 (buf, buf3, ((len + 2) / 3) * 3);
2d46177c 821
3d7cd517
SS
822 for (i = 0; i < enclen; ++i)
823 *p++ = buf3[i];
2d46177c
SS
824 *p++ = '\r';
825 *p++ = '\n';
826
827 next_msg_id = (next_msg_id + 3) % 245;
828
829 /* Send it over and over until we get a positive ack. */
830
831 while (1)
832 {
833 int started_error_output = 0;
834
835 if (remote_debug)
836 {
837 *p = '\0';
838 printf_unfiltered ("Sending encoded: \"%s\"", buf2);
839 printf_unfiltered (" (Checksum %d, id %d, length %d)\n",
840 header[0], header[1], header[2]);
841 gdb_flush (gdb_stdout);
842 }
843 if (SERIAL_WRITE (sds_desc, buf2, p - buf2))
844 perror_with_name ("putmessage: write failed");
845
846 return 1;
847
848 }
849
850}
851
852/* Come here after finding the start of the frame. Collect the rest
853 into BUF. Returns 0 on any error, 1 on success. */
854
855static int
856read_frame (buf)
857 char *buf;
858{
859 char *bp;
860 int c;
861
862 bp = buf;
863
864 while (1)
865 {
866 c = readchar (sds_timeout);
867
868 switch (c)
869 {
870 case SERIAL_TIMEOUT:
871 if (remote_debug)
872 puts_filtered ("Timeout in mid-message, retrying\n");
873 return 0;
874 case '$':
875 if (remote_debug)
876 puts_filtered ("Saw new packet start in middle of old one\n");
877 return 0; /* Start a new packet, count retries */
878 case '\r':
879 break;
880
881 case '\n':
882 {
883 *bp = '\000';
884 if (remote_debug)
3d7cd517
SS
885 fprintf_unfiltered (gdb_stderr, "Received encoded: \"%s\"\n",
886 buf);
2d46177c
SS
887 return 1;
888 }
889
890 default:
891 if (bp < buf + PBUFSIZ - 1)
892 {
893 *bp++ = c;
894 continue;
895 }
896
897 *bp = '\0';
898 puts_filtered ("Message too long: ");
899 puts_filtered (buf);
900 puts_filtered ("\n");
901
902 return 0;
903 }
904 }
905}
906
907/* Read a packet from the remote machine, with error checking,
908 and store it in BUF. BUF is expected to be of size PBUFSIZ.
909 If FOREVER, wait forever rather than timing out; this is used
910 while the target is executing user code. */
911
912static int
913getmessage (buf, forever)
914 unsigned char *buf;
915 int forever;
916{
917 int c, c2, c3;
918 int tries;
919 int timeout;
920 int val, i, len, csum;
921 unsigned char header[3];
922 unsigned char inbuf[500];
923
924 strcpy (buf, "timeout");
925
926 if (forever)
927 {
928#ifdef MAINTENANCE_CMDS
929 timeout = watchdog > 0 ? watchdog : -1;
930#else
931 timeout = -1;
932#endif
933 }
934
935 else
936 timeout = sds_timeout;
937
938#define MAX_TRIES 3
939
940 for (tries = 1; tries <= MAX_TRIES; tries++)
941 {
942 /* This can loop forever if the remote side sends us characters
943 continuously, but if it pauses, we'll get a zero from readchar
944 because of timeout. Then we'll count that as a retry. */
945
946 /* Note that we will only wait forever prior to the start of a packet.
947 After that, we expect characters to arrive at a brisk pace. They
948 should show up within sds_timeout intervals. */
949
950 do
951 {
952 c = readchar (timeout);
953
954 if (c == SERIAL_TIMEOUT)
955 {
956#ifdef MAINTENANCE_CMDS
957 if (forever) /* Watchdog went off. Kill the target. */
958 {
959 target_mourn_inferior ();
960 error ("Watchdog has expired. Target detached.\n");
961 }
962#endif
963 if (remote_debug)
964 puts_filtered ("Timed out.\n");
965 goto retry;
966 }
967 }
968 while (c != '$' && c != '{');
969
970 /* We might have seen a "trigraph", a sequence of three characters
971 that indicate various sorts of communication state. */
972
973 if (c == '{')
974 {
975 /* Read the other two chars of the trigraph. */
976 c2 = readchar (timeout);
977 c3 = readchar (timeout);
978 if (remote_debug)
979 fprintf_unfiltered (gdb_stderr, "Trigraph %c%c%c received\n",
980 c, c2, c3);
981 if (c3 == '+')
982 {
983 message_pending = 1;
1c3cd1b0 984 return 0; /*????*/
2d46177c
SS
985 }
986 continue;
987 }
988
989 val = read_frame (inbuf);
990
991 if (val == 1)
992 {
993 fromb64 (inbuf, header, 4);
994 /* (should check out other bits) */
995 fromb64 (inbuf + 4, buf, strlen (inbuf) - 4);
996
997 len = header[2];
998
999 csum = 0;
1000 csum = compute_checksum (csum, buf, len);
1001 csum = compute_checksum (csum, header + 1, 2);
1002
1003 if (csum != header[0])
1004 fprintf_unfiltered (gdb_stderr,
1005 "Checksum mismatch: computed %d, received %d\n",
1006 csum, header[0]);
1007
1008 if (header[2] == 0xff)
1009 fprintf_unfiltered (gdb_stderr, "Requesting resend...\n");
1010
1011 if (remote_debug)
1012 {
1013 fprintf_unfiltered (gdb_stderr,
1014 "... (Got checksum %d, id %d, length %d)\n",
1015 header[0], header[1], header[2]);
1016 fprintf_unfiltered (gdb_stderr, "Message received: \"");
1017 for (i = 0; i < len; ++i)
1018 {
1019 fprintf_unfiltered (gdb_stderr, "%02x", (unsigned char) buf[i]);
1020 }
1021 fprintf_unfiltered (gdb_stderr, "\"\n");
1022 }
1023
1024 /* no ack required? */
1025 return len;
1026 }
1027
1028 /* Try the whole thing again. */
1029 retry:
1030 /* need to do something here */
1031 }
1032
1033 /* We have tried hard enough, and just can't receive the packet. Give up. */
1034
1035 printf_unfiltered ("Ignoring packet error, continuing...\n");
1c3cd1b0 1036 return 0;
2d46177c
SS
1037}
1038\f
1039static void
1040sds_kill ()
1041{
665ff287 1042 /* Don't try to do anything to the target. */
2d46177c
SS
1043}
1044
1045static void
1046sds_mourn ()
1047{
1048 unpush_target (&sds_ops);
1049 generic_mourn_inferior ();
1050}
1051
1052static void
1053sds_create_inferior (exec_file, args, env)
1054 char *exec_file;
1055 char *args;
1056 char **env;
1057{
665ff287 1058 inferior_pid = 42000;
2d46177c
SS
1059
1060 /* Clean up from the last time we were running. */
1061 clear_proceed_status ();
1062
1063 /* Let the remote process run. */
665ff287 1064 proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
2d46177c
SS
1065}
1066
665ff287
SS
1067static void
1068sds_load (filename, from_tty)
1069 char *filename;
1070 int from_tty;
1071{
1072 generic_load (filename, from_tty);
1073
1074 inferior_pid = 0;
1075}
2d46177c
SS
1076\f
1077/* The SDS monitor has commands for breakpoint insertion, although it
1078 it doesn't actually manage the breakpoints, it just returns the
1079 replaced instruction back to the debugger. */
1080
1081static int
1082sds_insert_breakpoint (addr, contents_cache)
1083 CORE_ADDR addr;
1084 char *contents_cache;
1085{
3d7cd517
SS
1086 int i, retlen;
1087 unsigned char *p, buf[PBUFSIZ];
1088
1089 p = buf;
1090 *p++ = 16;
1091 *p++ = 0;
1092 *p++ = (int) (addr >> 24) & 0xff;
1093 *p++ = (int) (addr >> 16) & 0xff;
1094 *p++ = (int) (addr >> 8) & 0xff;
1095 *p++ = (int) (addr ) & 0xff;
1096
1097 retlen = sds_send (buf, p - buf);
2d46177c 1098
3d7cd517
SS
1099 for (i = 0; i < 4; ++i)
1100 contents_cache[i] = buf[i + 2];
2d46177c 1101
3d7cd517 1102 return 0;
2d46177c
SS
1103}
1104
1105static int
1106sds_remove_breakpoint (addr, contents_cache)
1107 CORE_ADDR addr;
1108 char *contents_cache;
1109{
3d7cd517
SS
1110 int i, retlen;
1111 unsigned char *p, buf[PBUFSIZ];
1112
1113 p = buf;
1114 *p++ = 17;
1115 *p++ = 0;
1116 *p++ = (int) (addr >> 24) & 0xff;
1117 *p++ = (int) (addr >> 16) & 0xff;
1118 *p++ = (int) (addr >> 8) & 0xff;
1119 *p++ = (int) (addr ) & 0xff;
1120 for (i = 0; i < 4; ++i)
1121 *p++ = contents_cache[i];
1122
1123 retlen = sds_send (buf, p - buf);
1124
1125 return 0;
2d46177c
SS
1126}
1127\f
ba4d67c2 1128static void
a23dbfcb 1129init_sds_ops ()
2d46177c 1130{
a23dbfcb
SS
1131 sds_ops.to_shortname = "sds";
1132 sds_ops.to_longname = "Remote serial target with SDS protocol";
1133 sds_ops.to_doc = "Use a remote computer via a serial line; using the SDS protocol.\n\
1134Specify the serial device it is connected to (e.g. /dev/ttya).";
1135 sds_ops.to_open = sds_open;
1136 sds_ops.to_close = sds_close;
1137 sds_ops.to_detach = sds_detach;
1138 sds_ops.to_resume = sds_resume;
1139 sds_ops.to_wait = sds_wait;
1140 sds_ops.to_fetch_registers = sds_fetch_registers;
1141 sds_ops.to_store_registers = sds_store_registers;
1142 sds_ops.to_prepare_to_store = sds_prepare_to_store;
1143 sds_ops.to_xfer_memory = sds_xfer_memory;
1144 sds_ops.to_files_info = sds_files_info;
1145 sds_ops.to_insert_breakpoint = sds_insert_breakpoint;
1146 sds_ops.to_remove_breakpoint = sds_remove_breakpoint;
1147 sds_ops.to_kill = sds_kill;
1148 sds_ops.to_load = sds_load;
1149 sds_ops.to_create_inferior = sds_create_inferior;
1150 sds_ops.to_mourn_inferior = sds_mourn;
1151 sds_ops.to_stratum = process_stratum;
1152 sds_ops.to_has_all_memory = 1;
1153 sds_ops.to_has_memory = 1;
1154 sds_ops.to_has_stack = 1;
1155 sds_ops.to_has_registers = 1;
1156 sds_ops.to_has_execution = 1;
1157 sds_ops.to_magic = OPS_MAGIC;
c719b714 1158}
2d46177c
SS
1159
1160/* Put a command string, in args, out to the monitor and display the
1161 reply message. */
1162
1163static void
1164sds_command (args, from_tty)
1165 char *args;
1166 int from_tty;
1167{
1168 char *p;
3d7cd517 1169 int i, len, retlen;
2d46177c
SS
1170 unsigned char buf[1000];
1171
1172 /* Convert hexadecimal chars into a byte buffer. */
1173 p = args;
1174 len = 0;
1175 while (*p != '\0')
1176 {
1177 buf[len++] = fromhex (p[0]) * 16 + fromhex (p[1]);
1178 if (p[1] == '\0')
1179 break;
1180 p += 2;
1181 }
1182
3d7cd517 1183 retlen = sds_send (buf, len);
2d46177c
SS
1184
1185 printf_filtered ("Reply is ");
3d7cd517 1186 for (i = 0; i < retlen; ++i)
2d46177c
SS
1187 {
1188 printf_filtered ("%02x", buf[i]);
1189 }
1190 printf_filtered ("\n");
1191}
1192
1193void
1194_initialize_remote_sds ()
1195{
a23dbfcb 1196 init_sds_ops ();
2d46177c
SS
1197 add_target (&sds_ops);
1198
1199 add_show_from_set (add_set_cmd ("sdstimeout", no_class,
1200 var_integer, (char *)&sds_timeout,
1201 "Set timeout value for sds read.\n", &setlist),
1202 &showlist);
1203
1204 add_com ("sds", class_obscure, sds_command,
1205 "Send a command to the SDS monitor.");
1206}
This page took 0.139548 seconds and 4 git commands to generate.