Automatic date update in version.in
[binutils-gdb.git] / sim / cris / rvdummy.c
blob957f0f4405874611d915d5f90b04376766573012
1 /* Test-driver for the remote-virtual-component simulator framework
2 for GDB, the GNU Debugger.
4 Copyright 2006-2024 Free Software Foundation, Inc.
6 This file is part of GDB.
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.
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.
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/>. */
21 /* Avoid any problems whatsoever building this program if we're not
22 also building hardware support. */
24 #if !WITH_HW
25 int
26 main (int argc, char *argv[])
28 return 2;
30 #else
32 /* This must come before any other includes. */
33 #include "defs.h"
35 #include "getopt.h"
36 #include "libiberty.h"
38 #include <stdio.h>
39 #include <unistd.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #ifdef HAVE_SYS_TYPES_H
43 #include <sys/types.h>
44 #endif
46 #include <sys/time.h>
48 #include <errno.h>
50 /* Not guarded in dv-sockser.c, so why here. */
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
53 #include <netdb.h>
54 #include <sys/select.h>
55 #include <sys/socket.h>
57 enum rv_command {
58 RV_READ_CMD = 0,
59 RV_WRITE_CMD = 1,
60 RV_IRQ_CMD = 2,
61 RV_MEM_RD_CMD = 3,
62 RV_MEM_WR_CMD = 4,
63 RV_MBOX_HANDLE_CMD = 5,
64 RV_MBOX_PUT_CMD = 6,
65 RV_WATCHDOG_CMD = 7
68 enum opts { OPT_PORT = 1, OPT_TIMEOUT, OPT_VERBOSE };
70 struct option longopts[] =
72 {"port", required_argument, NULL, OPT_PORT},
73 {"timeout", required_argument, NULL, OPT_TIMEOUT},
74 {"verbose", no_argument, NULL, OPT_VERBOSE},
75 {NULL, 0, NULL, 0}
78 int port = 10000;
79 time_t timeout = 30000;
80 char *progname = "(unknown)";
81 int verbose = 0;
83 /* Required forward-declarations. */
84 static void handle_input_file (int, char *);
86 /* Set up a "server" listening to the port in PORT for a raw TCP
87 connection. Return a file descriptor for the connection or -1 on
88 error. */
90 static int setupsocket (void)
92 int s;
93 socklen_t len;
94 int reuse = 1;
95 struct sockaddr_in sa_in;
96 struct sockaddr_in from;
98 len = sizeof (from);
99 memset (&from, 0, len);
100 memset (&sa_in, 0, sizeof (sa_in));
102 s = socket (AF_INET, SOCK_STREAM, 0);
103 if (s == -1)
104 return -1;
106 if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse) != 0)
107 return -1;
109 sa_in.sin_port = htons (port);
110 sa_in.sin_family = AF_INET;
112 if (bind (s, (struct sockaddr *) & sa_in, sizeof sa_in) < 0)
113 return -1;
115 if (listen (s, 1) < 0)
116 return -1;
118 return accept (s, (struct sockaddr *) &from, &len);
121 /* Basic host-to-little-endian 32-bit value. Could use the BFD
122 machinery, but let's avoid it for this only dependency. */
124 static void
125 h2le32 (unsigned char *dest, unsigned int val)
127 dest[0] = val & 255;
128 dest[1] = (val >> 8) & 255;
129 dest[2] = (val >> 16) & 255;
130 dest[3] = (val >> 24) & 255;
133 /* Send a blob of data. */
135 static void
136 send_output (int fd, unsigned char *buf, int nbytes)
138 while (nbytes > 0)
140 ssize_t written = write (fd, buf, nbytes);
141 if (written < 0)
143 fprintf (stderr, "%s: write to socket failed: %s\n",
144 progname, strerror (errno));
145 exit (2);
147 nbytes -= written;
151 /* Receive a blob of data, NBYTES large. Compare to the first NCOMP
152 bytes of BUF; if not a match, write error message to stderr and
153 exit (2). Else put it in buf. */
155 static void
156 expect_input (int fd, unsigned char *buf, int nbytes, int ncomp)
158 unsigned char byt;
159 int i;
161 for (i = 0; i < nbytes; i++)
163 int r;
167 errno = 0;
168 r = read (fd, &byt, 1);
170 while (r <= 0 && (r == 0 || errno == EAGAIN));
172 if (r != 1)
174 fprintf (stderr, "%s: read from socket failed: %s",
175 progname, strerror (errno));
176 exit (2);
179 if (i < ncomp && byt != buf[i])
181 int j;
182 fprintf (stderr, "%s: unexpected input,\n ", progname);
183 if (i == 0)
184 fprintf (stderr, "nothing,");
185 else
186 for (j = 0; j < i; j++)
187 fprintf (stderr, "%02x", buf[j]);
188 fprintf (stderr, "\nthen %02x instead of %02x\n", byt, buf[i]);
189 exit (2);
191 else
192 buf[i] = byt;
196 /* Handle everything about a nil-terminated line of input.
197 Call exit (2) on error with error text on stderr. */
199 static void
200 handle_input (int fd, char *buf, char *fname, int lineno)
202 int nbytes = 0;
203 int n = -1;
204 char *s = buf + 2;
205 unsigned int data;
206 static unsigned char bytes[1024];
207 int i;
209 memset (bytes, 0, sizeof bytes);
210 lineno++;
212 if (buf[1] != ',')
213 goto syntax_error;
215 switch (buf[0])
217 /* Comment characters and empty lines. */
218 case 0: case '!': case '#':
219 break;
221 /* Include another file. */
222 case '@':
223 handle_input_file (fd, s);
224 break;
226 /* Raw input (to be expected). */
227 case 'i':
230 n = -1;
231 sscanf (s, "%02x%n", &data, &n);
232 s += n;
233 if (n > 0)
234 bytes[nbytes++] = data;
236 while (n > 0);
237 expect_input (fd, bytes, nbytes, nbytes);
238 if (verbose)
240 printf ("i,");
241 for (i = 0; i < nbytes; i++)
242 printf ("%02x", bytes[i]);
243 printf ("\n");
245 break;
247 /* Raw output (to be written). */
248 case 'o':
251 n = -1;
252 sscanf (s, "%02x%n", &data, &n);
253 if (n > 0)
255 s += n;
256 bytes[nbytes++] = data;
259 while (n > 0);
260 if (*s != 0)
261 goto syntax_error;
262 send_output (fd, bytes, nbytes);
263 if (verbose)
265 printf ("o,");
266 for (i = 0; i < nbytes; i++)
267 printf ("%02x", bytes[i]);
268 printf ("\n");
270 break;
272 /* Read a register. */
273 case 'r':
275 unsigned int addr;
276 sscanf (s, "%x,%x%n", &addr, &data, &n);
277 if (n < 0 || s[n] != 0)
278 goto syntax_error;
279 bytes[0] = 11;
280 bytes[1] = 0;
281 bytes[2] = RV_READ_CMD;
282 h2le32 (bytes + 3, addr);
283 expect_input (fd, bytes, 11, 7);
284 h2le32 (bytes + 7, data);
285 send_output (fd, bytes, 11);
286 if (verbose)
287 printf ("r,%x,%x\n", addr, data);
289 break;
291 /* Write a register. */
292 case 'w':
294 unsigned int addr;
295 sscanf (s, "%x,%x%n", &addr, &data, &n);
296 if (n < 0 || s[n] != 0)
297 goto syntax_error;
298 bytes[0] = 11;
299 bytes[1] = 0;
300 bytes[2] = RV_WRITE_CMD;
301 h2le32 (bytes + 3, addr);
302 h2le32 (bytes + 7, data);
303 expect_input (fd, bytes, 11, 11);
304 send_output (fd, bytes, 11);
305 if (verbose)
306 printf ("w,%x,%x\n", addr, data);
308 break;
310 /* Wait for some milliseconds. */
311 case 't':
313 int del = 0;
314 struct timeval to;
315 sscanf (s, "%d%n", &del, &n);
316 if (n < 0 || s[n] != 0 || del == 0)
317 goto syntax_error;
319 to.tv_sec = del / 1000;
320 to.tv_usec = (del % 1000) * 1000;
322 if (select (0, NULL, NULL, NULL, &to) != 0)
324 fprintf (stderr, "%s: problem waiting for %d ms:\n %s\n",
325 progname, del, strerror (errno));
326 exit (2);
328 if (verbose)
329 printf ("t,%d\n", del);
331 break;
333 /* Expect a watchdog command. */
334 case 'W':
335 if (*s != 0)
336 goto syntax_error;
337 bytes[0] = 3;
338 bytes[1] = 0;
339 bytes[2] = RV_WATCHDOG_CMD;
340 expect_input (fd, bytes, 3, 3);
341 if (verbose)
342 printf ("W\n");
343 break;
345 /* Send an IRQ notification. */
346 case 'I':
347 sscanf (s, "%x%n", &data, &n);
348 if (n < 0 || s[n] != 0)
349 goto syntax_error;
350 bytes[0] = 7;
351 bytes[1] = 0;
352 bytes[2] = RV_IRQ_CMD;
353 h2le32 (bytes + 3, data);
354 send_output (fd, bytes, 7);
355 if (verbose)
356 printf ("I,%x\n", data);
357 break;
359 /* DMA store (to CPU). */
360 case 's':
362 unsigned int addr;
363 sscanf (s, "%x,%n", &addr, &n);
365 if (n < 0 || s[n] == 0)
366 goto syntax_error;
367 s += n;
370 n = -1;
371 sscanf (s, "%02x%n", &data, &n);
372 if (n > 0)
374 s += n;
375 bytes[11 + nbytes++] = data;
378 while (n > 0);
380 if (*s != 0)
381 goto syntax_error;
382 h2le32 (bytes, nbytes + 11);
383 bytes[2] = RV_MEM_WR_CMD;
384 h2le32 (bytes + 3, addr);
385 h2le32 (bytes + 7, nbytes);
386 send_output (fd, bytes, nbytes + 11);
387 if (verbose)
389 printf ("s,%x,", addr);
390 for (i = 0; i < nbytes; i++)
391 printf ("%02x", bytes[i]);
392 printf ("\n");
395 break;
397 /* DMA load (from CPU). */
398 case 'l':
400 unsigned int addr;
401 sscanf (s, "%x,%n", &addr, &n);
403 if (n < 0 || s[n] == 0)
404 goto syntax_error;
405 s += n;
408 n = -1;
409 sscanf (s, "%02x%n", &data, &n);
410 if (n > 0)
412 s += n;
413 bytes[11 + nbytes++] = data;
416 while (n > 0);
418 if (*s != 0)
419 goto syntax_error;
420 h2le32 (bytes, nbytes + 11);
421 bytes[0] = 11;
422 bytes[1] = 0;
423 bytes[2] = RV_MEM_RD_CMD;
424 h2le32 (bytes + 3, addr);
425 h2le32 (bytes + 7, nbytes);
426 send_output (fd, bytes, 11);
427 bytes[0] = (nbytes + 11) & 255;
428 bytes[1] = ((nbytes + 11) >> 8) & 255;
429 expect_input (fd, bytes, nbytes + 11, nbytes + 11);
430 if (verbose)
432 printf ("l,%x,", addr);
433 for (i = 0; i < nbytes; i++)
434 printf ("%02x", bytes[i]);
435 printf ("\n");
438 break;
440 syntax_error:
441 default:
442 fprintf (stderr, "%s: invalid command line in %s:%d:\n %s",
443 progname, fname, lineno, strerror (errno));
444 exit (2);
448 /* Loop over the contents of FNAME, using handle_input to parse each line.
449 Errors to stderr, exit (2). */
451 static void
452 handle_input_file (int fd, char *fname)
454 static char buf[2048] = {0};
455 int lineno = 0;
456 FILE *f = fopen (fname, "r");
458 if (f == NULL)
460 fprintf (stderr, "%s: problem opening %s: %s\n",
461 progname, fname, strerror (errno));
462 exit (2);
465 /* Let's cut the buffer short, so we always get a newline. */
466 while (fgets (buf, sizeof (buf) - 1, f) != NULL)
468 buf[strlen (buf) - 1] = 0;
469 lineno++;
470 handle_input (fd, buf, fname, lineno);
473 fclose (f);
477 main (int argc, char *argv[])
479 int optc;
480 int fd;
481 int i;
483 progname = argv[0];
484 while ((optc = getopt_long (argc, argv, "", longopts, NULL)) != -1)
485 switch (optc)
487 case OPT_PORT:
488 port = atoi (optarg);
489 break;
491 case OPT_TIMEOUT:
492 timeout = (time_t) atoi (optarg);
493 break;
495 case OPT_VERBOSE:
496 verbose = 1;
497 break;
500 fd = setupsocket ();
501 if (fd == -1)
503 fprintf (stderr, "%s: problem setting up the connection: %s\n",
504 progname, strerror (errno));
505 exit (2);
508 for (i = optind; i < argc; i++)
509 handle_input_file (fd, argv[i]);
511 /* FIXME: option-controlled test for remaining input? */
512 close (fd);
513 return 1;
515 #endif