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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [serial.c] - Blame information for rev 1773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Generic serial interface routines
2
 
3
   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4
   2001, 2002 Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
#include "defs.h"
24
#include <ctype.h>
25
#include "serial.h"
26
#include "gdb_string.h"
27
#include "gdbcmd.h"
28
 
29
extern void _initialize_serial (void);
30
 
31
/* Is serial being debugged? */
32
 
33
static int global_serial_debug_p;
34
 
35
/* Linked list of serial I/O handlers */
36
 
37
static struct serial_ops *serial_ops_list = NULL;
38
 
39
/* This is the last serial stream opened.  Used by connect command. */
40
 
41
static struct serial *last_serial_opened = NULL;
42
 
43
/* Pointer to list of scb's. */
44
 
45
static struct serial *scb_base;
46
 
47
/* Non-NULL gives filename which contains a recording of the remote session,
48
   suitable for playback by gdbserver. */
49
 
50
static char *serial_logfile = NULL;
51
static struct ui_file *serial_logfp = NULL;
52
 
53
static struct serial_ops *serial_interface_lookup (char *);
54
static void serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout);
55
static const char logbase_hex[] = "hex";
56
static const char logbase_octal[] = "octal";
57
static const char logbase_ascii[] = "ascii";
58
static const char *logbase_enums[] =
59
{logbase_hex, logbase_octal, logbase_ascii, NULL};
60
static const char *serial_logbase = logbase_ascii;
61
 
62
 
63
static int serial_current_type = 0;
64
 
65
/* Log char CH of type CHTYPE, with TIMEOUT */
66
 
67
/* Define bogus char to represent a BREAK.  Should be careful to choose a value
68
   that can't be confused with a normal char, or an error code.  */
69
#define SERIAL_BREAK 1235
70
 
71
static void
72
serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
73
{
74
  if (ch_type != serial_current_type)
75
    {
76
      fprintf_unfiltered (stream, "\n%c ", ch_type);
77
      serial_current_type = ch_type;
78
    }
79
 
80
  if (serial_logbase != logbase_ascii)
81
    fputc_unfiltered (' ', stream);
82
 
83
  switch (ch)
84
    {
85
    case SERIAL_TIMEOUT:
86
      fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
87
      return;
88
    case SERIAL_ERROR:
89
      fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
90
      return;
91
    case SERIAL_EOF:
92
      fputs_unfiltered ("<Eof>", stream);
93
      return;
94
    case SERIAL_BREAK:
95
      fputs_unfiltered ("<Break>", stream);
96
      return;
97
    default:
98
      if (serial_logbase == logbase_hex)
99
        fprintf_unfiltered (stream, "%02x", ch & 0xff);
100
      else if (serial_logbase == logbase_octal)
101
        fprintf_unfiltered (stream, "%03o", ch & 0xff);
102
      else
103
        switch (ch)
104
          {
105
          case '\\':
106
            fputs_unfiltered ("\\\\", stream);
107
            break;
108
          case '\b':
109
            fputs_unfiltered ("\\b", stream);
110
            break;
111
          case '\f':
112
            fputs_unfiltered ("\\f", stream);
113
            break;
114
          case '\n':
115
            fputs_unfiltered ("\\n", stream);
116
            break;
117
          case '\r':
118
            fputs_unfiltered ("\\r", stream);
119
            break;
120
          case '\t':
121
            fputs_unfiltered ("\\t", stream);
122
            break;
123
          case '\v':
124
            fputs_unfiltered ("\\v", stream);
125
            break;
126
          default:
127
            fprintf_unfiltered (stream, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
128
            break;
129
          }
130
    }
131
}
132
 
133
void
134
serial_log_command (const char *cmd)
135
{
136
  if (!serial_logfp)
137
    return;
138
 
139
  serial_current_type = 'c';
140
 
141
  fputs_unfiltered ("\nc ", serial_logfp);
142
  fputs_unfiltered (cmd, serial_logfp);
143
 
144
  /* Make sure that the log file is as up-to-date as possible,
145
     in case we are getting ready to dump core or something. */
146
  gdb_flush (serial_logfp);
147
}
148
 
149
 
150
static struct serial_ops *
151
serial_interface_lookup (char *name)
152
{
153
  struct serial_ops *ops;
154
 
155
  for (ops = serial_ops_list; ops; ops = ops->next)
156
    if (strcmp (name, ops->name) == 0)
157
      return ops;
158
 
159
  return NULL;
160
}
161
 
162
void
163
serial_add_interface (struct serial_ops *optable)
164
{
165
  optable->next = serial_ops_list;
166
  serial_ops_list = optable;
167
}
168
 
169
/* Open up a device or a network socket, depending upon the syntax of NAME. */
170
 
171
struct serial *
172
serial_open (const char *name)
173
{
174
  struct serial *scb;
175
  struct serial_ops *ops;
176
  const char *open_name = name;
177
 
178
  for (scb = scb_base; scb; scb = scb->next)
179
    if (scb->name && strcmp (scb->name, name) == 0)
180
      {
181
        scb->refcnt++;
182
        return scb;
183
      }
184
 
185
  if (strcmp (name, "pc") == 0)
186
    ops = serial_interface_lookup ("pc");
187
  else if (strchr (name, ':'))
188
    ops = serial_interface_lookup ("tcp");
189
  else if (strncmp (name, "lpt", 3) == 0)
190
    ops = serial_interface_lookup ("parallel");
191
  else if (strncmp (name, "|", 1) == 0)
192
    {
193
      ops = serial_interface_lookup ("pipe");
194
      open_name = name + 1; /* discard ``|'' */
195
    }
196
  else
197
    ops = serial_interface_lookup ("hardwire");
198
 
199
  if (!ops)
200
    return NULL;
201
 
202
  scb = XMALLOC (struct serial);
203
 
204
  scb->ops = ops;
205
 
206
  scb->bufcnt = 0;
207
  scb->bufp = scb->buf;
208
 
209
  if (scb->ops->open (scb, open_name))
210
    {
211
      xfree (scb);
212
      return NULL;
213
    }
214
 
215
  scb->name = xstrdup (name);
216
  scb->next = scb_base;
217
  scb->refcnt = 1;
218
  scb->debug_p = 0;
219
  scb->async_state = 0;
220
  scb->async_handler = NULL;
221
  scb->async_context = NULL;
222
  scb_base = scb;
223
 
224
  last_serial_opened = scb;
225
 
226
  if (serial_logfile != NULL)
227
    {
228
      serial_logfp = gdb_fopen (serial_logfile, "w");
229
      if (serial_logfp == NULL)
230
        perror_with_name (serial_logfile);
231
    }
232
 
233
  return scb;
234
}
235
 
236
struct serial *
237
serial_fdopen (const int fd)
238
{
239
  struct serial *scb;
240
  struct serial_ops *ops;
241
 
242
  for (scb = scb_base; scb; scb = scb->next)
243
    if (scb->fd == fd)
244
      {
245
        scb->refcnt++;
246
        return scb;
247
      }
248
 
249
  ops = serial_interface_lookup ("hardwire");
250
 
251
  if (!ops)
252
    return NULL;
253
 
254
  scb = XMALLOC (struct serial);
255
 
256
  scb->ops = ops;
257
 
258
  scb->bufcnt = 0;
259
  scb->bufp = scb->buf;
260
 
261
  scb->fd = fd;
262
 
263
  scb->name = NULL;
264
  scb->next = scb_base;
265
  scb->refcnt = 1;
266
  scb->debug_p = 0;
267
  scb->async_state = 0;
268
  scb->async_handler = NULL;
269
  scb->async_context = NULL;
270
  scb_base = scb;
271
 
272
  last_serial_opened = scb;
273
 
274
  return scb;
275
}
276
 
277
static void
278
do_serial_close (struct serial *scb, int really_close)
279
{
280
  struct serial *tmp_scb;
281
 
282
  last_serial_opened = NULL;
283
 
284
  if (serial_logfp)
285
    {
286
      fputs_unfiltered ("\nEnd of log\n", serial_logfp);
287
      serial_current_type = 0;
288
 
289
      /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
290
      ui_file_delete (serial_logfp);
291
      serial_logfp = NULL;
292
    }
293
 
294
/* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
295
   should fix your code instead.  */
296
 
297
  if (!scb)
298
    return;
299
 
300
  scb->refcnt--;
301
  if (scb->refcnt > 0)
302
    return;
303
 
304
  /* ensure that the FD has been taken out of async mode */
305
  if (scb->async_handler != NULL)
306
    serial_async (scb, NULL, NULL);
307
 
308
  if (really_close)
309
    scb->ops->close (scb);
310
 
311
  if (scb->name)
312
    xfree (scb->name);
313
 
314
  if (scb_base == scb)
315
    scb_base = scb_base->next;
316
  else
317
    for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
318
      {
319
        if (tmp_scb->next != scb)
320
          continue;
321
 
322
        tmp_scb->next = tmp_scb->next->next;
323
        break;
324
      }
325
 
326
  xfree (scb);
327
}
328
 
329
void
330
serial_close (struct serial *scb)
331
{
332
  do_serial_close (scb, 1);
333
}
334
 
335
void
336
serial_un_fdopen (struct serial *scb)
337
{
338
  do_serial_close (scb, 0);
339
}
340
 
341
int
342
serial_readchar (struct serial *scb, int timeout)
343
{
344
  int ch;
345
 
346
  /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
347
     code is finished. */
348
  if (0 && serial_is_async_p (scb) && timeout < 0)
349
    internal_error (__FILE__, __LINE__,
350
                    "serial_readchar: blocking read in async mode");
351
 
352
  ch = scb->ops->readchar (scb, timeout);
353
  if (serial_logfp != NULL)
354
    {
355
      serial_logchar (serial_logfp, 'r', ch, timeout);
356
 
357
      /* Make sure that the log file is as up-to-date as possible,
358
         in case we are getting ready to dump core or something. */
359
      gdb_flush (serial_logfp);
360
    }
361
  if (serial_debug_p (scb))
362
    {
363
      fprintf_unfiltered (gdb_stdlog, "[");
364
      serial_logchar (gdb_stdlog, 'r', ch, timeout);
365
      fprintf_unfiltered (gdb_stdlog, "]");
366
      gdb_flush (gdb_stdlog);
367
    }
368
 
369
  return (ch);
370
}
371
 
372
int
373
serial_write (struct serial *scb, const char *str, int len)
374
{
375
  if (serial_logfp != NULL)
376
    {
377
      int count;
378
 
379
      for (count = 0; count < len; count++)
380
        serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
381
 
382
      /* Make sure that the log file is as up-to-date as possible,
383
         in case we are getting ready to dump core or something. */
384
      gdb_flush (serial_logfp);
385
    }
386
 
387
  return (scb->ops->write (scb, str, len));
388
}
389
 
390
void
391
serial_printf (struct serial *desc, const char *format,...)
392
{
393
  va_list args;
394
  char *buf;
395
  va_start (args, format);
396
 
397
  xvasprintf (&buf, format, args);
398
  serial_write (desc, buf, strlen (buf));
399
 
400
  xfree (buf);
401
  va_end (args);
402
}
403
 
404
int
405
serial_drain_output (struct serial *scb)
406
{
407
  return scb->ops->drain_output (scb);
408
}
409
 
410
int
411
serial_flush_output (struct serial *scb)
412
{
413
  return scb->ops->flush_output (scb);
414
}
415
 
416
int
417
serial_flush_input (struct serial *scb)
418
{
419
  return scb->ops->flush_input (scb);
420
}
421
 
422
int
423
serial_send_break (struct serial *scb)
424
{
425
  if (serial_logfp != NULL)
426
    serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
427
 
428
  return (scb->ops->send_break (scb));
429
}
430
 
431
void
432
serial_raw (struct serial *scb)
433
{
434
  scb->ops->go_raw (scb);
435
}
436
 
437
serial_ttystate
438
serial_get_tty_state (struct serial *scb)
439
{
440
  return scb->ops->get_tty_state (scb);
441
}
442
 
443
int
444
serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
445
{
446
  return scb->ops->set_tty_state (scb, ttystate);
447
}
448
 
449
void
450
serial_print_tty_state (struct serial *scb,
451
                        serial_ttystate ttystate,
452
                        struct ui_file *stream)
453
{
454
  scb->ops->print_tty_state (scb, ttystate, stream);
455
}
456
 
457
int
458
serial_noflush_set_tty_state (struct serial *scb,
459
                              serial_ttystate new_ttystate,
460
                              serial_ttystate old_ttystate)
461
{
462
  return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
463
}
464
 
465
int
466
serial_setbaudrate (struct serial *scb, int rate)
467
{
468
  return scb->ops->setbaudrate (scb, rate);
469
}
470
 
471
int
472
serial_setstopbits (struct serial *scb, int num)
473
{
474
  return scb->ops->setstopbits (scb, num);
475
}
476
 
477
int
478
serial_can_async_p (struct serial *scb)
479
{
480
  return (scb->ops->async != NULL);
481
}
482
 
483
int
484
serial_is_async_p (struct serial *scb)
485
{
486
  return (scb->ops->async != NULL) && (scb->async_handler != NULL);
487
}
488
 
489
void
490
serial_async (struct serial *scb,
491
              serial_event_ftype *handler,
492
              void *context)
493
{
494
  /* Only change mode if there is a need. */
495
  if ((scb->async_handler == NULL)
496
      != (handler == NULL))
497
    scb->ops->async (scb, handler != NULL);
498
  scb->async_handler = handler;
499
  scb->async_context = context;
500
}
501
 
502
int
503
deprecated_serial_fd (struct serial *scb)
504
{
505
  /* FIXME: should this output a warning that deprecated code is being
506
     called? */
507
  if (scb->fd < 0)
508
    {
509
      internal_error (__FILE__, __LINE__,
510
                      "serial: FD not valid");
511
    }
512
  return scb->fd; /* sigh */
513
}
514
 
515
void
516
serial_debug (struct serial *scb, int debug_p)
517
{
518
  scb->debug_p = debug_p;
519
}
520
 
521
int
522
serial_debug_p (struct serial *scb)
523
{
524
  return scb->debug_p || global_serial_debug_p;
525
}
526
 
527
 
528
#if 0
529
/* The connect command is #if 0 because I hadn't thought of an elegant
530
   way to wait for I/O on two `struct serial *'s simultaneously.  Two
531
   solutions came to mind:
532
 
533
   1) Fork, and have have one fork handle the to user direction,
534
   and have the other hand the to target direction.  This
535
   obviously won't cut it for MSDOS.
536
 
537
   2) Use something like select.  This assumes that stdin and
538
   the target side can both be waited on via the same
539
   mechanism.  This may not be true for DOS, if GDB is
540
   talking to the target via a TCP socket.
541
   -grossman, 8 Jun 93 */
542
 
543
/* Connect the user directly to the remote system.  This command acts just like
544
   the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
545
 
546
static struct serial *tty_desc; /* Controlling terminal */
547
 
548
static void
549
cleanup_tty (serial_ttystate ttystate)
550
{
551
  printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
552
  serial_set_tty_state (tty_desc, ttystate);
553
  xfree (ttystate);
554
  serial_close (tty_desc);
555
}
556
 
557
static void
558
connect_command (char *args, int fromtty)
559
{
560
  int c;
561
  char cur_esc = 0;
562
  serial_ttystate ttystate;
563
  struct serial *port_desc;             /* TTY port */
564
 
565
  dont_repeat ();
566
 
567
  if (args)
568
    fprintf_unfiltered (gdb_stderr, "This command takes no args.  They have been ignored.\n");
569
 
570
  printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");
571
 
572
  tty_desc = serial_fdopen (0);
573
  port_desc = last_serial_opened;
574
 
575
  ttystate = serial_get_tty_state (tty_desc);
576
 
577
  serial_raw (tty_desc);
578
  serial_raw (port_desc);
579
 
580
  make_cleanup (cleanup_tty, ttystate);
581
 
582
  while (1)
583
    {
584
      int mask;
585
 
586
      mask = serial_wait_2 (tty_desc, port_desc, -1);
587
 
588
      if (mask & 2)
589
        {                       /* tty input */
590
          char cx;
591
 
592
          while (1)
593
            {
594
              c = serial_readchar (tty_desc, 0);
595
 
596
              if (c == SERIAL_TIMEOUT)
597
                break;
598
 
599
              if (c < 0)
600
                perror_with_name ("connect");
601
 
602
              cx = c;
603
              serial_write (port_desc, &cx, 1);
604
 
605
              switch (cur_esc)
606
                {
607
                case 0:
608
                  if (c == '\r')
609
                    cur_esc = c;
610
                  break;
611
                case '\r':
612
                  if (c == '~')
613
                    cur_esc = c;
614
                  else
615
                    cur_esc = 0;
616
                  break;
617
                case '~':
618
                  if (c == '.' || c == '\004')
619
                    return;
620
                  else
621
                    cur_esc = 0;
622
                }
623
            }
624
        }
625
 
626
      if (mask & 1)
627
        {                       /* Port input */
628
          char cx;
629
 
630
          while (1)
631
            {
632
              c = serial_readchar (port_desc, 0);
633
 
634
              if (c == SERIAL_TIMEOUT)
635
                break;
636
 
637
              if (c < 0)
638
                perror_with_name ("connect");
639
 
640
              cx = c;
641
 
642
              serial_write (tty_desc, &cx, 1);
643
            }
644
        }
645
    }
646
}
647
#endif /* 0 */
648
 
649
/* Serial set/show framework.  */
650
 
651
static struct cmd_list_element *serial_set_cmdlist;
652
static struct cmd_list_element *serial_show_cmdlist;
653
 
654
static void
655
serial_set_cmd (char *args, int from_tty)
656
{
657
  printf_unfiltered ("\"set serial\" must be followed by the name of a command.\n");
658
  help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
659
}
660
 
661
static void
662
serial_show_cmd (char *args, int from_tty)
663
{
664
  cmd_show_list (serial_show_cmdlist, from_tty, "");
665
}
666
 
667
 
668
void
669
_initialize_serial (void)
670
{
671
#if 0
672
  add_com ("connect", class_obscure, connect_command,
673
           "Connect the terminal directly up to the command monitor.\n\
674
Use <CR>~. or <CR>~^D to break out.");
675
#endif /* 0 */
676
 
677
  add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, "\
678
Set default serial/parallel port configuration.",
679
                  &serial_set_cmdlist, "set serial ",
680
                  0/*allow-unknown*/,
681
                  &setlist);
682
 
683
  add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, "\
684
Show default serial/parallel port configuration.",
685
                  &serial_show_cmdlist, "show serial ",
686
                  0/*allow-unknown*/,
687
                  &showlist);
688
 
689
  add_show_from_set
690
    (add_set_cmd ("remotelogfile", no_class,
691
                  var_filename, (char *) &serial_logfile,
692
                  "Set filename for remote session recording.\n\
693
This file is used to record the remote session for future playback\n\
694
by gdbserver.",
695
                  &setlist),
696
     &showlist);
697
 
698
  add_show_from_set
699
    (add_set_enum_cmd ("remotelogbase", no_class,
700
                       logbase_enums, &serial_logbase,
701
                       "Set numerical base for remote session logging",
702
                       &setlist),
703
     &showlist);
704
 
705
  add_show_from_set (add_set_cmd ("serial",
706
                                  class_maintenance,
707
                                  var_zinteger,
708
                                  (char *)&global_serial_debug_p,
709
                                  "Set serial debugging.\n\
710
When non-zero, serial port debugging is enabled.", &setdebuglist),
711
                     &showdebuglist);
712
}

powered by: WebSVN 2.1.0

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