OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [remote-sds.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.