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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [cris/] [rvdummy.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* Test-driver for the remote-virtual-component simulator framework
2
   for GDB, the GNU Debugger.
3
 
4
   Copyright 2006, 2007, 2008 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 3 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, see <http://www.gnu.org/licenses/>.  */
20
 
21
/* Avoid any problems whatsoever building this program if we're not
22
   also building hardware support.  */
23
 
24
#if !WITH_HW
25
int
26
main (int argc, char *argv[])
27
{
28
  return 2;
29
}
30
#else
31
 
32
#ifdef HAVE_CONFIG_H
33
#include "cconfig.h"
34
#include "tconfig.h"
35
#endif
36
 
37
#include "getopt.h"
38
#include "libiberty.h"
39
 
40
#define _GNU_SOURCE
41
#include <stdio.h>
42
 
43
#ifdef HAVE_UNISTD_H
44
#include <unistd.h>
45
#endif
46
#ifdef HAVE_STDLIB_H
47
#include <stdlib.h>
48
#endif
49
#ifdef HAVE_STRING_H
50
#include <string.h>
51
#endif
52
 
53
#ifdef HAVE_SYS_TYPES_H
54
#include <sys/types.h>
55
#endif
56
 
57
#ifdef HAVE_SYS_TIME_H
58
#include <sys/time.h>
59
#endif
60
 
61
#ifdef HAVE_SYS_SELECT_H
62
#include <sys/select.h>
63
#endif
64
 
65
#ifdef HAVE_ERRNO_H
66
#include <errno.h>
67
#endif
68
 
69
/* Not guarded in dv-sockser.c, so why here.  */
70
#include <netinet/in.h>
71
#include <arpa/inet.h>
72
#include <netdb.h>
73
#include <sys/socket.h>
74
 
75
enum rv_command {
76
  RV_READ_CMD = 0,
77
  RV_WRITE_CMD = 1,
78
  RV_IRQ_CMD = 2,
79
  RV_MEM_RD_CMD = 3,
80
  RV_MEM_WR_CMD = 4,
81
  RV_MBOX_HANDLE_CMD = 5,
82
  RV_MBOX_PUT_CMD = 6,
83
  RV_WATCHDOG_CMD = 7
84
};
85
 
86
enum opts { OPT_PORT = 1, OPT_TIMEOUT, OPT_VERBOSE };
87
 
88
struct option longopts[] =
89
  {
90
    {"port", required_argument, NULL, OPT_PORT},
91
    {"timeout", required_argument, NULL, OPT_TIMEOUT},
92
    {"verbose", no_argument, NULL, OPT_VERBOSE},
93
    {NULL, 0, NULL, 0}
94
  };
95
 
96
int port = 10000;
97
time_t timeout = 30000;
98
char *progname = "(unknown)";
99
int verbose = 0;
100
 
101
/* Required forward-declarations.  */
102
static void handle_input_file (int, char *);
103
 
104
/* Set up a "server" listening to the port in PORT for a raw TCP
105
   connection.  Return a file descriptor for the connection or -1 on
106
   error.  */
107
 
108
int setupsocket (void)
109
{
110
  int s;
111
  socklen_t len;
112
  int reuse = 1;
113
  struct sockaddr_in sa_in;
114
  struct sockaddr_in from;
115
 
116
  len = sizeof (from);
117
  memset (&from, 0, len);
118
  memset (&sa_in, 0, sizeof (sa_in));
119
 
120
  s = socket (AF_INET, SOCK_STREAM, 0);
121
  if (s < 0)
122
    return -1;
123
 
124
  if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse) != 0)
125
    return -1;
126
 
127
  sa_in.sin_port = htons (port);
128
  sa_in.sin_family = AF_INET;
129
 
130
  if (bind (s, (struct sockaddr *) & sa_in, sizeof sa_in) < 0)
131
    return -1;
132
 
133
  if (listen (s, 1) < 0)
134
    return -1;
135
 
136
  return accept (s, (struct sockaddr *) &from, &len);
137
}
138
 
139
/* Basic host-to-little-endian 32-bit value.  Could use the BFD
140
   machinery, but let's avoid it for this only dependency.  */
141
 
142
static void
143
h2le32 (unsigned char *dest, unsigned int val)
144
{
145
  dest[0] = val & 255;
146
  dest[1] = (val >> 8) & 255;
147
  dest[2] = (val >> 16) & 255;
148
  dest[3] = (val >> 24) & 255;
149
}
150
 
151
/* Send a blob of data.  */
152
 
153
static void
154
send_output (int fd, unsigned char *buf, int nbytes)
155
{
156
  while (nbytes > 0)
157
    {
158
      ssize_t written = write (fd, buf, nbytes);
159
      if (written < 0)
160
        {
161
          fprintf (stderr, "%s: write to socket failed: %s\n",
162
                  progname, strerror (errno));
163
          exit (2);
164
        }
165
      nbytes -= written;
166
    }
167
}
168
 
169
/* Receive a blob of data, NBYTES large.  Compare to the first NCOMP
170
   bytes of BUF; if not a match, write error message to stderr and
171
   exit (2).  Else put it in buf.  */
172
 
173
static void
174
expect_input (int fd, unsigned char *buf, int nbytes, int ncomp)
175
{
176
  unsigned char byt;
177
  int i;
178
 
179
  for (i = 0; i < nbytes; i++)
180
    {
181
      int r;
182
 
183
      do
184
        {
185
          errno = 0;
186
          r = read (fd, &byt, 1);
187
        }
188
      while (r <= 0 && (r == 0 || errno == EAGAIN));
189
 
190
      if (r != 1)
191
        {
192
          fprintf (stderr, "%s: read from socket failed: %s",
193
                  progname, strerror (errno));
194
          exit (2);
195
        }
196
 
197
      if (i < ncomp && byt != buf[i])
198
        {
199
          int j;
200
          fprintf (stderr, "%s: unexpected input,\n ", progname);
201
          if (i == 0)
202
            fprintf (stderr, "nothing,");
203
          else
204
            for (j = 0; j < i; j++)
205
              fprintf (stderr, "%02x", buf[j]);
206
          fprintf (stderr, "\nthen %02x instead of %02x\n", byt, buf[i]);
207
          exit (2);
208
        }
209
      else
210
        buf[i] = byt;
211
    }
212
}
213
 
214
/* Handle everything about a nil-terminated line of input.
215
   Call exit (2) on error with error text on stderr.  */
216
 
217
static void
218
handle_input (int fd, char *buf, char *fname, int lineno)
219
{
220
  int nbytes = 0;
221
  int n = -1;
222
  char *s = buf + 2;
223
  unsigned int data;
224
  static unsigned char bytes[1024];
225
  int i;
226
 
227
  memset (bytes, 0, sizeof bytes);
228
  lineno++;
229
 
230
  if (buf[1] != ',')
231
    goto syntax_error;
232
 
233
  switch (buf[0])
234
    {
235
      /* Comment characters and empty lines.  */
236
    case 0: case '!': case '#':
237
      break;
238
 
239
      /* Include another file.  */
240
    case '@':
241
      handle_input_file (fd, s);
242
      break;
243
 
244
      /* Raw input (to be expected).  */
245
    case 'i':
246
      do
247
        {
248
          n = -1;
249
          sscanf (s, "%02x%n", &data, &n);
250
          s += n;
251
          if (n > 0)
252
            bytes[nbytes++] = data;
253
        }
254
      while (n > 0);
255
      expect_input (fd, bytes, nbytes, nbytes);
256
      if (verbose)
257
        {
258
          printf ("i,");
259
          for (i = 0; i < nbytes; i++)
260
            printf ("%02x", bytes[i]);
261
          printf ("\n");
262
        }
263
      break;
264
 
265
      /* Raw output (to be written).  */
266
    case 'o':
267
      do
268
        {
269
          n = -1;
270
          sscanf (s, "%02x%n", &data, &n);
271
          if (n > 0)
272
            {
273
              s += n;
274
              bytes[nbytes++] = data;
275
            }
276
        }
277
      while (n > 0);
278
      if (*s != 0)
279
        goto syntax_error;
280
      send_output (fd, bytes, nbytes);
281
      if (verbose)
282
        {
283
          printf ("o,");
284
          for (i = 0; i < nbytes; i++)
285
            printf ("%02x", bytes[i]);
286
          printf ("\n");
287
        }
288
      break;
289
 
290
      /* Read a register.  */
291
    case 'r':
292
      {
293
        unsigned int addr;
294
        sscanf (s, "%x,%x%n", &addr, &data, &n);
295
        if (n < 0 || s[n] != 0)
296
          goto syntax_error;
297
        bytes[0] = 11;
298
        bytes[1] = 0;
299
        bytes[2] = RV_READ_CMD;
300
        h2le32 (bytes + 3, addr);
301
        expect_input (fd, bytes, 11, 7);
302
        h2le32 (bytes + 7, data);
303
        send_output (fd, bytes, 11);
304
        if (verbose)
305
          printf ("r,%x,%x\n", addr, data);
306
      }
307
      break;
308
 
309
      /* Write a register.  */
310
    case 'w':
311
      {
312
        unsigned int addr;
313
        sscanf (s, "%x,%x%n", &addr, &data, &n);
314
        if (n < 0 || s[n] != 0)
315
          goto syntax_error;
316
        bytes[0] = 11;
317
        bytes[1] = 0;
318
        bytes[2] = RV_WRITE_CMD;
319
        h2le32 (bytes + 3, addr);
320
        h2le32 (bytes + 7, data);
321
        expect_input (fd, bytes, 11, 11);
322
        send_output (fd, bytes, 11);
323
        if (verbose)
324
          printf ("w,%x,%x\n", addr, data);
325
      }
326
      break;
327
 
328
      /* Wait for some milliseconds.  */
329
    case 't':
330
      {
331
        int del = 0;
332
        struct timeval to;
333
        sscanf (s, "%d%n", &del, &n);
334
        if (n < 0 || s[n] != 0 || del == 0)
335
          goto syntax_error;
336
 
337
        to.tv_sec = del / 1000;
338
        to.tv_usec = (del % 1000) * 1000;
339
 
340
        if (select (0, NULL, NULL, NULL, &to) != 0)
341
          {
342
            fprintf (stderr, "%s: problem waiting for %d ms:\n %s\n",
343
                     progname, del, strerror (errno));
344
            exit (2);
345
          }
346
        if (verbose)
347
          printf ("t,%d\n", del);
348
      }
349
      break;
350
 
351
      /* Expect a watchdog command.  */
352
    case 'W':
353
      if (*s != 0)
354
        goto syntax_error;
355
      bytes[0] = 3;
356
      bytes[1] = 0;
357
      bytes[2] = RV_WATCHDOG_CMD;
358
      expect_input (fd, bytes, 3, 3);
359
      if (verbose)
360
        printf ("W\n");
361
      break;
362
 
363
      /* Send an IRQ notification.  */
364
    case 'I':
365
      sscanf (s, "%x%n", &data, &n);
366
      if (n < 0 || s[n] != 0)
367
        goto syntax_error;
368
      bytes[0] = 7;
369
      bytes[1] = 0;
370
      bytes[2] = RV_IRQ_CMD;
371
      h2le32 (bytes + 3, data);
372
      send_output (fd, bytes, 7);
373
      if (verbose)
374
        printf ("I,%x\n", data);
375
      break;
376
 
377
      /* DMA store (to CPU).  */
378
    case 's':
379
      {
380
        unsigned int addr;
381
        sscanf (s, "%x,%n", &addr, &n);
382
 
383
        if (n < 0 || s[n] == 0)
384
          goto syntax_error;
385
        s += n;
386
        do
387
          {
388
            n = -1;
389
            sscanf (s, "%02x%n", &data, &n);
390
            if (n > 0)
391
              {
392
                s += n;
393
                bytes[11 + nbytes++] = data;
394
              }
395
          }
396
        while (n > 0);
397
 
398
        if (*s != 0)
399
          goto syntax_error;
400
        h2le32 (bytes, nbytes + 11);
401
        bytes[2] = RV_MEM_WR_CMD;
402
        h2le32 (bytes + 3, addr);
403
        h2le32 (bytes + 7, nbytes);
404
        send_output (fd, bytes, nbytes + 11);
405
        if (verbose)
406
          {
407
            printf ("s,%x,", addr);
408
            for (i = 0; i < nbytes; i++)
409
              printf ("%02x", bytes[i]);
410
            printf ("\n");
411
          }
412
      }
413
      break;
414
 
415
      /* DMA load (from CPU).  */
416
    case 'l':
417
      {
418
        unsigned int addr;
419
        sscanf (s, "%x,%n", &addr, &n);
420
 
421
        if (n < 0 || s[n] == 0)
422
          goto syntax_error;
423
        s += n;
424
        do
425
          {
426
            n = -1;
427
            sscanf (s, "%02x%n", &data, &n);
428
            if (n > 0)
429
              {
430
                s += n;
431
                bytes[11 + nbytes++] = data;
432
              }
433
          }
434
        while (n > 0);
435
 
436
        if (*s != 0)
437
          goto syntax_error;
438
        h2le32 (bytes, nbytes + 11);
439
        bytes[0] = 11;
440
        bytes[1] = 0;
441
        bytes[2] = RV_MEM_RD_CMD;
442
        h2le32 (bytes + 3, addr);
443
        h2le32 (bytes + 7, nbytes);
444
        send_output (fd, bytes, 11);
445
        bytes[0] = (nbytes + 11) & 255;
446
        bytes[1] = ((nbytes + 11) >> 8) & 255;
447
        expect_input (fd, bytes, nbytes + 11, nbytes + 11);
448
        if (verbose)
449
          {
450
            printf ("l,%x,", addr);
451
            for (i = 0; i < nbytes; i++)
452
              printf ("%02x", bytes[i]);
453
            printf ("\n");
454
          }
455
      }
456
      break;
457
 
458
    syntax_error:
459
    default:
460
      fprintf (stderr, "%s: invalid command line in %s:%d:\n %s",
461
               progname, fname, lineno, strerror (errno));
462
      exit (2);
463
    }
464
}
465
 
466
/* Loop over the contents of FNAME, using handle_input to parse each line.
467
   Errors to stderr, exit (2).  */
468
 
469
static void
470
handle_input_file (int fd, char *fname)
471
{
472
  static char buf[2048] = {0};
473
  int lineno = 0;
474
  FILE *f = fopen (fname, "r");
475
 
476
  if (f == NULL)
477
    {
478
      fprintf (stderr, "%s: problem opening %s: %s\n",
479
               progname, fname, strerror (errno));
480
      exit (2);
481
    }
482
 
483
  /* Let's cut the buffer short, so we always get a newline.  */
484
  while (fgets (buf, sizeof (buf) - 1, f) != NULL)
485
    {
486
      buf[strlen (buf) - 1] = 0;
487
      lineno++;
488
      handle_input (fd, buf, fname, lineno);
489
    }
490
 
491
  fclose (f);
492
}
493
 
494
int
495
main (int argc, char *argv[])
496
{
497
  int optc;
498
  int fd;
499
  FILE *f;
500
  int i;
501
 
502
  progname = argv[0];
503
  while ((optc = getopt_long (argc, argv, "", longopts, NULL)) != -1)
504
    switch (optc)
505
      {
506
      case OPT_PORT:
507
        port = atoi (optarg);
508
        break;
509
 
510
      case OPT_TIMEOUT:
511
        timeout = (time_t) atoi (optarg);
512
        break;
513
 
514
      case OPT_VERBOSE:
515
        verbose = 1;
516
        break;
517
      }
518
 
519
  fd = setupsocket ();
520
  if (fd < 0)
521
    {
522
      fprintf (stderr, "%s: problem setting up the connection: %s\n",
523
               progname, strerror (errno));
524
      exit (2);
525
    }
526
 
527
  for (i = optind; i < argc; i++)
528
    handle_input_file (fd, argv[i]);
529
 
530
  /* FIXME: option-controlled test for remaining input?  */
531
  close (fd);
532
  return 1;
533
}
534
#endif

powered by: WebSVN 2.1.0

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