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