Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / sim / cris / dv-rv.c
CommitLineData
aad3b3cb
HPN
1/* The remote-virtual-component simulator framework
2 for GDB, the GNU Debugger.
3
88b9d363 4 Copyright 2006-2022 Free Software Foundation, Inc.
aad3b3cb
HPN
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
4744ac1b 10 the Free Software Foundation; either version 3 of the License, or
aad3b3cb
HPN
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
4744ac1b 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
aad3b3cb 20
6df01ab8
MF
21/* This must come before any other includes. */
22#include "defs.h"
aad3b3cb
HPN
23
24#include "sim-main.h"
25#include "hw-main.h"
26
27#include "hw-tree.h"
28
29#include <ctype.h>
aad3b3cb 30#include <errno.h>
aad3b3cb 31#include <string.h>
aad3b3cb
HPN
32#ifdef HAVE_UNISTD_H
33#include <unistd.h>
34#endif
aad3b3cb 35#include <stdlib.h>
aad3b3cb
HPN
36#ifdef HAVE_SYS_TYPES_H
37#include <sys/types.h>
38#endif
39
aad3b3cb 40#include <sys/time.h>
aad3b3cb 41
aad3b3cb 42#include <sys/select.h>
aad3b3cb
HPN
43
44/* Not guarded in dv-sockser.c, so why here. */
45#include <netinet/in.h>
46#include <arpa/inet.h>
47#include <netdb.h>
48#include <sys/socket.h>
49
50
51/* DEVICE
52
53
54 rv - Remote Virtual component
55
56
57 DESCRIPTION
58
59
60 Socket connection to a remote simulator component, for example one
61 for testing a verilog construction. Protocol defined below.
62
63 There is a set of 32-bit I/O ports, with a mapping from local to
64 remote addresses. There is a set of interrupts expressed as a
65 bit-mask, with a mapping from remote to local. There is a set of
66 memory ranges (actual memory defined elsewhere), also with a
67 mapping from remote to local addresses, that is expected to be
68 accessible to the remote simulator in 32-byte chunks (simulating
69 DMA). There is a mapping from remote cycles (or an appropriate
70 elsewhere defined time-slice) to local cycles.
71
72 PROPERTIES
73
74 reg = <address> <size>
75 The address (within the parent bus) that this device is to
76 be located.
77
78 remote-reg = <remote-address>
79 The address of reg on the remote side. Defaults to 0.
80
81 mem = <address> <size>
82 Specify an address-range (within the parent bus) that the remote
83 device can access. The memory is assumed to be already defined.
84 If there's no memory defined but the remote side asks for a memory
85 access, the simulation is aborted.
86
87 remote-mem = <remote-address>
88 The address of mem on the remote side. Defaults to 0.
89
90 mbox = <address>
91 Address of the mailbox interface. Writes to this address with the
92 local address of a mailbox command, a complete packet with length
93 and command; (4 or 6)) invokes the mailbox interface. Reads are
94 invalid. Replies are written to the same address. Address space
95 from <address> up-to-and-including <address>+3 is allocated.
96
97 max-poll-ticks = <local-count>
98 Sets the maximum interval between polling the external component,
99 expressed in internal cycles. Defaults to 10000.
100
101 watchdog-interval = <seconds>
102 Sets the wallclock seconds between watchdog packets sent to the
103 remote side (may be larger if there's no rv activity in that time).
104 Defaults to 30. If set to 0, no watchdog packets are sent.
105
106 intnum = <local-int-0> <local-int-1> ... <local-int-31>
107 Defines a map from remote bit numbers to local values to be emitted
108 on the "int" port, with the external bit number as the ordinal - 1
109 of the local translation. E.g. 43 121 would mean map external
110 (1<<0) to internal 43 and external (1<<1) to internal 121. The
111 default is unity; no translation. If more than one bit is set in
112 the remote interrupt word, the intmultiple property can be used to
113 control the translation.
114
115 intmultiple = <intvalue>
116 When more than one bit is set in the remote interrupt word, you may
117 want to map this situation to a separate interrupt value. If this
118 property is non-zero, it is used as that value. If it is zero, the
119 local value for the "int" port is the bitwise-or of the translated
120 local values.
121
122 host = <hostid>
123 The hostname or address where the simulator to be used listens.
124 Defaults to "127.0.0.1"
125
126 port = <portnumber>
127 The hostname or address where the simulator to be used listens.
128 Defaults to 10000.
129
130 dummy = <value>
131 or
132 dummy = <filename>
133 Don't connect to a remote side; use initial dummy contents from
134 <filename> (which has to be at least as big as the <size> argument
135 of reg above) or filled with byte-value <value>. Mailboxes are not
136 supported (can be defined but can not be used) and remote-memory
137 accesses don't apply. The main purpose for this property is to
138 simplify use of configuration and simulated hardware that is
139 e.g. only trivially initialized but not actually used.
140
141
142 PORTS
143
144 int (output)
145 Driven as a result of a remote interrupt request. The value is a
146 32-bit bitset of active interrupts.
147
148
149 BUGS
150
151 All and none.
152
153
154 PROTOCOL
155
156 This is version 1.0 of this protocol, defining packet format and
157 actions in a supposedly upward-compatible manner where client and
158 servers of different versions are expected to interoperate; the
159 format and the definitions below are hopefully generic enough to
160 allow this.
161
162 Each connection has a server and a client (this code); the roles
163 are known beforehand. The client usually corresponds to a CPU and
164 memory system and the server corresponds to a memory-mapped
165 register hardware interface and/or a DMA controller. They
166 communicate using packets with specific commands, of which some
167 require replies from the other side; most are intiated by the
168 client with one exception. A reply uses the same format as the
169 command.
170
171 Packets are at least three bytes long, where the first two bytes
172 form a header, a 16-bit little-endian number that is the total
173 length of the packet including the header. There is also a
174 one-byte command. The payload is optional, depending on the
175 command.
176
177 [[16-bit-low-byte-of-length] [16-bit-high-byte-of-length]
178 [command/reply] [payload byte 0] [payload byte 1]
179 ... [payload byte (length-of-packet - 3)]]
180
181 Commands:
182
183 A client or server that reads an undocumented command may exit with
184 a hard error. Payload not defined or disallowed below is ignored.
185
186 It is expected that future client versions find out the version of
187 the server side by polling with base commands, assuming earlier
188 versions if a certain reply isn't seen, with newly defined payload
189 parts where earlier versions left it undefined. New commands and
190 formats are sent only to the other side after the client and server
191 has found out each others version. Not all servers support all
192 commands; the type of server and supported set of commands is
193 expected to be known beforehand.
194
195 RV_READ_CMD = 0
196 Initiated by the client, requires a reply from the server. The
197 payload from the client is at least 4 bytes, forming a 4-byte
198 little-endian address, the rest being undefined. The reply from
199 the server is at least 8 bytes, forming the same address data as in
200 the request and the second 4-byte data being the little-endian
201 contents.
202
203 RV_WRITE_CMD = 1
204 Initiated by the client, requires a reply from the server. Payload
205 from the client is at least 8 bytes, forming a 4-byte little-endian
206 word being the address, the rest being the little-endian contents
207 to write. The reply from the server is 8 bytes unless elsewhere
208 agreed otherwise, forming the same address and data as in the
209 request. The data sent back may have been altered to correspond to
210 defined parts but can safely be discarded.
211
212 RV_IRQ_CMD = 2
213 Initiated by the server, no reply. The payload is 4 bytes, forming
214 a little-endian word with bits numbers corresponding to currently
215 active interrupt sources; value (1<<N) indicating interrupt source
216 N being active.
217
218 RV_MEM_RD_CMD = 3
219 Initiated by the server, requires a reply. A client must know
220 beforehand when (in command sequence or constant) the server can
221 send this command and if so must then not send any commands of its
222 own (including watchdog commands); the server is allowed to assume
223 that incoming data is only replies to this command. The format is
224 8 bytes of data; 4 bytes of little-endian address followed by a
225 32-bit little endian word with the number of bytes to read. The
226 reply is the same address and number of bytes, followed by the data
227 that had been read.
228
229 RV_MEM_WR_CMD = 4
230 Initiated by the server, no reply. The format is the same as a
231 reply to RV_MEM_RD_CMD; a 32-bit little-endian address, followed by
232 the 32-bit little-endian number of bytes to write (redundant
233 information but must be consistent with the packet header).
234
235 RV_MBOX_HANDLE_CMD = 5
236 Initiated by the client, requires a reply. The payload is 4
237 undefined bytes followed by an binary blob, the size of the
238 blob given by the packet header. The reply is a 32-bit little
239 endian number at the same index as the undefined bytes. Actual
240 semantics are application-specific.
241
242 RV_MBOX_PUT_CMD = 6
243 Initiated by the client, requires a reply, with the reply using the
244 RV_MBOX_HANDLE_CMD reply format (i.e. *both* that command and
245 32-bit little-endian number). The payload is a 32-bit little
246 endian number followed by an undefined payload, at most 20 bytes
247 long. The reply is a 32-bit little endian number. Actual
248 semantics are application-specific.
249
250 RV_WATCHDOG_CMD = 7
251 Initiated by the client, no reply. A version 1.0 client sends no
252 payload; a version 1.0 server should ignore any such payload. A
253 version 1.0 server must not send a reply.
254
255
256 Possible future enhancements:
257
258 Synchronization; server and client reports the number of elapsed
259 cycles (unit to-be-defined) at each request or notification.
260 Pretty much the top-of-the-todo-list item.
261
262 Large addresses; 1.0 being restricted to 32-bit addresses.
263
264 Variable-size data; currently restricted to 32-bit register
265 accesses.
266
267 Specified data endianness (not the packet header) perhaps as part
268 of an initial format request; currently little-endian only.
269
270
271 Usage notes:
272 When used with servers sending RV_MEM_RD_CMD but being
273 narrow-minded about indata, set watchdog-interval to 0. Use
274 multiple rv instances when there are e.g. separate register and
275 memory servers. Alway log, setting "/rv/trace? true", at the
276 development phase. Borrow from the test-suite.
277 */
278
279#define RV_FAMILY_NAME "rv"
280
281enum rv_command {
282 RV_READ_CMD = 0,
283 RV_WRITE_CMD = 1,
284 RV_IRQ_CMD = 2,
285 RV_MEM_RD_CMD = 3,
286 RV_MEM_WR_CMD = 4,
287 RV_MBOX_HANDLE_CMD = 5,
288 RV_MBOX_PUT_CMD = 6,
289 RV_WATCHDOG_CMD = 7
290};
291
292
293typedef struct _hw_rv_device
294{
295 /* Mapping of remote interrupt bit-numbers to local ones. */
296 unsigned32 remote_to_local_int[32];
297
298 /* When multiple bits are set, a non-zero value here indicates that
299 this value should be used instead. */
300 unsigned32 intmultiple;
301
302 /* Local address of registers. */
303 unsigned32 reg_address;
304
305 /* Size of register bank in bytes. */
306 unsigned32 reg_size;
307
308 /* Remote address of registers. */
309 unsigned32 remote_reg_address;
310
311 /* Local address of DMA:able memory. */
312 unsigned32 mem_address;
313
314 /* Size of DMA:able memory in bytes. */
315 unsigned32 mem_size;
316
317 /* Bitmask for valid DMA request size. */
318 unsigned32 mem_burst_mask;
319
320 /* Remote address of DMA:able memory. */
321 unsigned32 remote_mem_address;
322
323 /* (Local) address of mbox; where to put a pointer to the mbox to be
324 sent. */
325 unsigned32 mbox_address;
326
327 /* Probably not 127.0.0.1:10000. */
328 const char *host;
329 int port;
330
331 /* If non-NULL, points to memory to use instead of connection. */
332 unsigned8 *dummy;
333
334 /* File descriptor for the socket. Set to -1 when error. Only one
335 of dummy and this is active. */
336 int fd;
337
338 /* Stashed errno, as we don't emit an error right away. */
339 int saved_errno;
340
341 /* This, plus latency because the CPU might not be checking until a
342 CTI insn (usually a branch or a jump) is the interval in cycles
343 between the rv is polled for e.g. DMA requests. */
344 unsigned32 max_tick_poll_interval;
345
346 /* Running counter for exponential backoff up to
347 max_tick_poll_interval to avoid polling the connection
348 unnecessarily often. Set to 1 when rv activity (read/write
349 register, DMA request) is detected. */
350 unsigned32 next_period;
351
352 /* This is the interval in wall-clock seconds between watchdog
353 packets are sent to the remote side. Zero means no watchdog
354 packets. */
355 unsigned32 watchdog_interval;
356
357 /* Last time we sent a watchdog packet. */
358 struct timeval last_wdog_time;
359
360 /* Mostly used as a kludge for knowing which rv:s have poll events
361 active. */
362 struct hw_event *poll_callback;
363} hw_rv_device;
364
365
366/* We might add ports in the future, so keep this an enumeration. */
367enum
368 {
369 INT_PORT
370 };
371
372/* Our ports. */
373static const struct hw_port_descriptor hw_rv_ports[] = {
374 { "int", INT_PORT, 0, output_port },
375 { NULL }
376};
377
378/* Send LEN bytes of data from BUF to the socket. Abort on
379 errors. */
380
381static void
382hw_rv_write (struct hw *me,
383 void *buf,
384 unsigned int len)
385{
386 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
387 unsigned8 *bufp = buf;
388
389 /* If we don't have a valid fd here, it's because we got an error
390 initially, and we suppressed that error. */
363a6e9f 391 if (rv->fd == -1)
aad3b3cb
HPN
392 hw_abort (me, "couldn't open a connection to %s:%d because: %s",
393 rv->host, rv->port, strerror (rv->saved_errno));
394
395 while (len > 0)
396 {
397 ssize_t ret = write (rv->fd, bufp, len);
398 if (ret < 0)
399 /* FIXME: More graceful exit. */
400 hw_abort (me, "write to %s:%d failed: %s\n", rv->host, rv->port,
401 strerror (errno));
402
403 len -= ret;
404 bufp += ret;
405 }
406}
407
408/* Read LEN bytes of data into BUF from the socket. Set the file
409 descriptor to -1 if there's an error. */
410
411static void
412hw_rv_read (struct hw *me,
413 void *buf,
414 unsigned int len)
415{
416 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
417 unsigned8 *bufp = buf;
418
419 while (len > 0)
420 {
421 ssize_t ret = read (rv->fd, bufp, len);
422
423 /* We get all zero if the remote end quits, but no error
424 indication; even select says there's data active. */
425 if (ret <= 0)
426 {
427 if (close (rv->fd) != 0)
428 /* FIXME: More graceful exit. */
429 hw_abort (me, "read from %s:%d failed: %d\n", rv->host, rv->port, errno);
430 rv->fd = -1;
431 return;
432 }
433
434 len -= ret;
435 bufp += ret;
436 }
437}
438
439/* Construct and send a packet of data of type CMD and len
440 LEN_NOHEADER (not counting the header...). */
441
442static void
443hw_rv_send (struct hw *me,
444 unsigned int cmd,
445 void *msg,
446 unsigned int len_noheader)
447{
448 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
449 unsigned8 buf[32+3];
450 unsigned8 *bufp;
451 unsigned int len = len_noheader + 3;
452 int ret;
453
454 buf[0] = len & 255;
455 buf[1] = (len >> 8) & 255;
456 buf[2] = cmd;
457
458 if (len > sizeof (buf))
459 {
460 hw_rv_write (me, buf, 3);
461 len = len_noheader;
462 bufp = msg;
463 }
464 else
465 {
466 memcpy (buf + 3, msg, len_noheader);
467 bufp = buf;
468 }
469
470 hw_rv_write (me, bufp, len);
471}
472
473/* Handle incoming DMA requests as per the RV_MEM_RD_CMD packet.
474 Abort on errors. */
475
476static void
477hw_rv_read_mem (struct hw *me, unsigned int len)
478{
479 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
480 /* If you change this size, please adjust the mem2 testcase. */
481 unsigned8 buf[32+8];
482 unsigned8 *bufp = buf;
483 unsigned32 leaddr;
484 unsigned32 addr;
485 unsigned32 lelen;
486 unsigned32 i;
487
488 if (len != 8)
489 hw_abort (me, "expected DMA read request len 8+3, got %d+3", len);
490
491 hw_rv_read (me, &leaddr, 4);
492 hw_rv_read (me, &lelen, 4);
493 len = LE2H_4 (lelen);
494 addr = LE2H_4 (leaddr);
495
496 if (addr < rv->remote_mem_address
497 || addr >= rv->remote_mem_address + rv->mem_size)
498 hw_abort (me, "DMA read at remote 0x%x; outside [0x%x..0x%x-1]",
499 (unsigned) addr, (unsigned) rv->remote_mem_address,
500 (unsigned) (rv->remote_mem_address + rv->mem_size));
501 addr = addr - rv->remote_mem_address + rv->mem_address;
502
503 if (len == 0)
504 hw_abort (me, "DMA read request for 0 bytes isn't supported");
505
506 if (len & ~rv->mem_burst_mask)
507 hw_abort (me, "DMA trying to read %d bytes; not matching mask of 0x%x",
508 len, rv->mem_burst_mask);
509 if (len + 8 > sizeof (buf))
510 bufp = hw_malloc (me, len + 8);
511
512 HW_TRACE ((me, "DMA R 0x%x..0x%x", addr, addr + len -1));
513 hw_dma_read_buffer (me, bufp + 8, 0, addr, len);
514 if (hw_trace_p (me))
515 for (i = 0; i < len; i += 4)
516 HW_TRACE ((me, "0x%x: %02x %02x %02x %02x",
517 addr + i,
518 bufp[i+8], bufp[i+9], bufp[i+10], bufp[i+11]));
519
520 memcpy (bufp, &leaddr, 4);
521 memcpy (bufp + 4, &lelen, 4);
522 hw_rv_send (me, RV_MEM_RD_CMD, bufp, len + 8);
523 if (bufp != buf)
524 hw_free (me, bufp);
525}
526
527/* Handle incoming DMA requests as per the RV_MEM_WR_CMD packet.
528 Abort on errors. */
529
530static void
531hw_rv_write_mem (struct hw *me, unsigned int plen)
532{
533 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
534 /* If you change this size, please adjust the mem2 testcase. */
535 unsigned8 buf[32+8];
536 unsigned8 *bufp = buf;
537 unsigned32 leaddr;
538 unsigned32 addr;
539 unsigned32 lelen;
540 unsigned32 len;
541 unsigned32 i;
542
543 hw_rv_read (me, &leaddr, 4);
544 hw_rv_read (me, &lelen, 4);
545 len = LE2H_4 (lelen);
546 addr = LE2H_4 (leaddr);
547
548 if (len != plen - 8)
549 hw_abort (me,
550 "inconsistency in DMA write request packet: "
551 "envelope %d+3, inner %d bytes", plen, len);
552
553 if (addr < rv->remote_mem_address
554 || addr >= rv->remote_mem_address + rv->mem_size)
555 hw_abort (me, "DMA write at remote 0x%x; outside [0x%x..0x%x-1]",
556 (unsigned) addr, (unsigned) rv->remote_mem_address,
557 (unsigned) (rv->remote_mem_address + rv->mem_size));
558
559 addr = addr - rv->remote_mem_address + rv->mem_address;
560 if (len == 0)
561 hw_abort (me, "DMA write request for 0 bytes isn't supported");
562
563 if (len & ~rv->mem_burst_mask)
564 hw_abort (me, "DMA trying to write %d bytes; not matching mask of 0x%x",
565 len, rv->mem_burst_mask);
566 if (len + 8 > sizeof (buf))
567 bufp = hw_malloc (me, len + 8);
568
569 hw_rv_read (me, bufp + 8, len);
570 HW_TRACE ((me, "DMA W 0x%x..0x%x", addr, addr + len - 1));
571 hw_dma_write_buffer (me, bufp + 8, 0, addr, len, 0);
572 if (hw_trace_p (me))
573 for (i = 0; i < len; i += 4)
574 HW_TRACE ((me, "0x%x: %02x %02x %02x %02x",
575 addr + i,
576 bufp[i+8], bufp[i+9], bufp[i+10], bufp[i+11]));
577 if (bufp != buf)
578 hw_free (me, bufp);
579}
580
581static void
582hw_rv_irq (struct hw *me, unsigned int len)
583{
584 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
585 unsigned32 intbitsle;
586 unsigned32 intbits_ext;
587 unsigned32 intval = 0;
588 int i;
589
590 if (len != 4)
591 hw_abort (me, "IRQ with %d data not supported", len);
592
593 hw_rv_read (me, &intbitsle, 4);
594 intbits_ext = LE2H_4 (intbitsle);
595 for (i = 0; i < 32; i++)
596 if ((intbits_ext & (1 << i)) != 0)
597 intval |= rv->remote_to_local_int[i];
598 if ((intbits_ext & ~(intbits_ext - 1)) != intbits_ext
599 && rv->intmultiple != 0)
600 intval = rv->intmultiple;
601
602 HW_TRACE ((me, "IRQ 0x%x", intval));
603 hw_port_event (me, INT_PORT, intval);
604}
605
606/* Handle incoming interrupt notifications as per the RV_IRQ_CMD
607 packet. Abort on errors. */
608
609static void
610hw_rv_handle_incoming (struct hw *me,
611 int expected_type,
612 unsigned8 *buf,
613 unsigned int *return_len)
614{
615 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
616 unsigned8 cbuf[32];
617 unsigned int len;
618 unsigned int cmd;
619
620 while (1)
621 {
622 hw_rv_read (me, cbuf, 3);
623
363a6e9f 624 if (rv->fd == -1)
aad3b3cb
HPN
625 return;
626
627 len = cbuf[0] + cbuf[1] * 256 - 3;
628 cmd = cbuf[2];
629
630 /* These come in "asynchronously"; not as a reply. */
631 switch (cmd)
632 {
633 case RV_IRQ_CMD:
634 hw_rv_irq (me, len);
635 break;
636
637 case RV_MEM_RD_CMD:
638 hw_rv_read_mem (me, len);
639 break;
640
641 case RV_MEM_WR_CMD:
642 hw_rv_write_mem (me, len);
643 break;
644 }
645
646 /* Something is incoming from the other side, so tighten up all
647 slack at the next wait. */
648 rv->next_period = 1;
649
650 switch (cmd)
651 {
652 case RV_MEM_RD_CMD:
653 case RV_MEM_WR_CMD:
654 case RV_IRQ_CMD:
655 /* Don't try to handle more than one of these if we were'nt
656 expecting a reply. */
657 if (expected_type == -1)
658 return;
659 continue;
660 }
661
662 /* Require a match between this supposed-reply and the command
663 for the rest. */
664 if (cmd != expected_type)
665 hw_abort (me, "unexpected reply, expected command %d, got %d",
666 expected_type, cmd);
667
668 switch (cmd)
669 {
670 case RV_MBOX_PUT_CMD:
671 case RV_MBOX_HANDLE_CMD:
672 case RV_WRITE_CMD:
673 case RV_READ_CMD:
674 hw_rv_read (me, buf, len <= *return_len ? len : *return_len);
675 *return_len = len;
676 break;
677 }
678 break;
679 }
680}
681
682/* Send a watchdog packet. Make a note of wallclock time. */
683
684static void
685hw_rv_send_wdog (struct hw *me)
686{
687 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
688 HW_TRACE ((me, "WD"));
689 gettimeofday (&rv->last_wdog_time, NULL);
690 hw_rv_send (me, RV_WATCHDOG_CMD, "", 0);
691}
692
693/* Poll the remote side: see if there's any incoming traffic; handle a
694 packet if so. Send a watchdog packet if it's time to do so.
695 Beware that the Linux select call indicates traffic for a socket
696 that the remote side has closed (which may be because it was
697 finished; don't hork until we need to write something just because
698 we're polling). */
699
700static void
701hw_rv_poll_once (struct hw *me)
702{
703 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
704 fd_set rfds;
705 fd_set efds;
706 struct timeval now;
707 int ret;
708 struct timeval tv;
709
363a6e9f 710 if (rv->fd == -1)
aad3b3cb
HPN
711 /* Connection has died or was never initiated. */
712 return;
713
714 FD_ZERO (&rfds);
715 FD_SET (rv->fd, &rfds);
716 FD_ZERO (&efds);
717 FD_SET (rv->fd, &efds);
718 tv.tv_sec = 0;
719 tv.tv_usec = 0;
720
721 ret = select (rv->fd + 1, &rfds, NULL, &efds, &tv);
722 gettimeofday (&now, NULL);
723
724 if (ret < 0)
725 hw_abort (me, "select failed: %d\n", errno);
726
727 if (rv->watchdog_interval != 0
728 && now.tv_sec - rv->last_wdog_time.tv_sec >= rv->watchdog_interval)
729 hw_rv_send_wdog (me);
730
731 if (FD_ISSET (rv->fd, &rfds))
732 hw_rv_handle_incoming (me, -1, NULL, NULL);
733}
734
735/* Initialize mapping of remote-to-local interrupt data. */
736
737static void
738hw_rv_map_ints (struct hw *me)
739{
740 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
741 int i;
742
743 for (i = 0; i < 32; i++)
744 rv->remote_to_local_int[i] = 1 << i;
745
746 if (hw_find_property (me, "intnum") != NULL)
747 for (i = 0; i < 32; i++)
748 {
749 signed_cell val = -1;
750 if (hw_find_integer_array_property (me, "intnum", i, &val) > 0)
751 {
752 if (val > 0)
753 rv->remote_to_local_int[i] = val;
754 else
755 hw_abort (me, "property \"intnum@%d\" must be > 0; is %d",
756 i, (int) val);
757 }
758 }
759}
760
761/* Handle the after-N-ticks "poll event", calling the poll-the-fd
762 method. Update the period. */
763
764static void
765do_poll_event (struct hw *me, void *data)
766{
767 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
768 unsigned32 new_period;
769
770 if (rv->dummy != NULL)
771 return;
772
773 hw_rv_poll_once (me);
774 if (rv->fd >= 0)
775 rv->poll_callback
776 = hw_event_queue_schedule (me, rv->next_period, do_poll_event, NULL);
777
778 new_period = rv->next_period * 2;
779 if (new_period <= rv->max_tick_poll_interval)
780 rv->next_period = new_period;
781}
782
783/* HW tree traverse function for hw_rv_add_init. */
784
785static void
786hw_rv_add_poller (struct hw *me, void *data)
787{
788 hw_rv_device *rv;
789
790 if (hw_family (me) == NULL
791 || strcmp (hw_family (me), RV_FAMILY_NAME) != 0)
792 return;
793
794 rv = (hw_rv_device *) hw_data (me);
795 if (rv->poll_callback != NULL)
796 return;
797
798 rv->poll_callback
799 = hw_event_queue_schedule (me, 1, do_poll_event, NULL);
800}
801
802/* Simulator module init function for hw_rv_add_init. */
803
804/* FIXME: For the call so hw_tree_traverse, we need to know that the
805 first member of struct sim_hw is the struct hw *root, but there's
806 no accessor method and struct sim_hw is defined in sim-hw.c only.
807 Hence this hack, until an accessor is added, or there's a traverse
808 function that takes a SIM_DESC argument. */
809struct sim_hw { struct hw *tree; };
810
811static SIM_RC
812hw_rv_add_rv_pollers (SIM_DESC sd)
813{
814 hw_tree_traverse (STATE_HW (sd)->tree, hw_rv_add_poller, NULL, NULL);
815 return SIM_RC_OK;
816}
817
818/* We need to add events for polling, but we can't add one from the
819 finish-function, and there are no other call points, at least for
820 instances without "reg" (when there are just DMA requests from the
821 remote end; no locally initiated activity). Therefore we add a
822 simulator module init function, but those don't have private
823 payload arguments; just a SD argument. We cope by parsing the HW
824 root and making sure *all* "rv":s have poll callbacks installed.
825 Luckily, this is just an initialization step, and not many
826 simultaneous instances of rv are expected: we get a N**2 complexity
827 for visits to each rv node by this method. */
828
829static void
830hw_rv_add_init (struct hw *me)
831{
832 sim_module_add_init_fn (hw_system (me), hw_rv_add_rv_pollers);
833}
834
835/* Open up a connection to the other side. Abort on errors. */
836
837static void
838hw_rv_init_socket (struct hw *me)
839{
840 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
841 int sock;
842 struct sockaddr_in server;
843
844 rv->fd = -1;
845
846 if (rv->dummy != NULL)
847 return;
848
849 memset (&server, 0, sizeof (server));
850 server.sin_family = AF_INET;
851 server.sin_addr.s_addr = inet_addr (rv->host);
852
853 /* Solaris 2.7 lacks this macro. */
854#ifndef INADDR_NONE
855#define INADDR_NONE -1
856#endif
857
858 if (server.sin_addr.s_addr == INADDR_NONE)
859 {
860 struct hostent *h;
861 h = gethostbyname (rv->host);
862 if (h != NULL)
863 {
864 memcpy (&server.sin_addr, h->h_addr, h->h_length);
865 server.sin_family = h->h_addrtype;
866 }
867 else
868 hw_abort (me, "can't resolve host %s", rv->host);
869 }
870
871 server.sin_port = htons (rv->port);
872 sock = socket (AF_INET, SOCK_STREAM, 0);
873
363a6e9f 874 if (sock == -1)
aad3b3cb
HPN
875 hw_abort (me, "can't get a socket for %s:%d connection",
876 rv->host, rv->port);
877
878 if (connect (sock, (struct sockaddr *) &server, sizeof server) >= 0)
879 {
880 rv->fd = sock;
881
882 /* FIXME: init packet here. Maybe start packet too. */
883 if (rv->watchdog_interval != 0)
884 hw_rv_send_wdog (me);
885 }
886 else
887 /* Stash the errno for later display, if some connection activity
888 is requested. Don't emit an error here; we might have been
889 called just for test purposes. */
890 rv->saved_errno = errno;
891}
892
893/* Local rv register reads end up here. */
894
895static unsigned int
896hw_rv_reg_read (struct hw *me,
897 void *dest,
898 int space,
899 unsigned_word addr,
900 unsigned int nr_bytes)
901{
902 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
903 unsigned8 addr_data[8] = "";
904 unsigned32 a_l = H2LE_4 (addr - rv->reg_address + rv->remote_reg_address);
905 unsigned int len = 8;
906
907 if (nr_bytes != 4)
908 hw_abort (me, "must be four byte read");
909
910 if (addr == rv->mbox_address)
911 hw_abort (me, "invalid read of mbox address 0x%x",
912 (unsigned) rv->mbox_address);
913
914 memcpy (addr_data, &a_l, 4);
915 HW_TRACE ((me, "REG R 0x%x", addr));
916 if (rv->dummy != NULL)
917 {
918 len = 8;
919 memcpy (addr_data + 4, rv->dummy + addr - rv->reg_address, 4);
920 }
921 else
922 {
923 hw_rv_send (me, RV_READ_CMD, addr_data, len);
924 hw_rv_handle_incoming (me, RV_READ_CMD, addr_data, &len);
925 }
926
927 if (len != 8)
928 hw_abort (me, "read %d != 8 bytes returned", len);
929 HW_TRACE ((me, ":= 0x%02x%02x%02x%02x",
930 addr_data[7], addr_data[6], addr_data[5], addr_data[4]));
931 memcpy (dest, addr_data + 4, 4);
932 return nr_bytes;
933}
934
935/* Local rv mbox requests (handle or put) end up here. */
936
937static void
938hw_rv_mbox (struct hw *me, unsigned_word address)
939{
940 unsigned8 buf[256+3];
941 unsigned int cmd;
942 unsigned int rlen;
943 unsigned32 i;
944 unsigned int len
945 = hw_dma_read_buffer (me, buf, 0, address, 3);
946
947 if (len != 3)
948 hw_abort (me, "mbox read %d != 3 bytes returned", len);
949
950 cmd = buf[2];
951 if (cmd != RV_MBOX_HANDLE_CMD && cmd != RV_MBOX_PUT_CMD)
952 hw_abort (me, "unsupported mbox command %d", cmd);
953
954 len = buf[0] + buf[1]*256;
955
956 if (len > sizeof (buf))
957 hw_abort (me, "mbox cmd %d send size %d unsupported", cmd, len);
958
959 rlen = hw_dma_read_buffer (me, buf + 3, 0, address + 3, len - 3);
960 if (rlen != len - 3)
961 hw_abort (me, "mbox read %d != %d bytes returned", rlen, len - 3);
962
963 HW_TRACE ((me, "MBOX %s 0x%x..0x%x",
964 cmd == RV_MBOX_HANDLE_CMD ? "H" : "P",
965 address, address + len - 1));
966 for (i = 0; i < rlen; i += 8)
967 HW_TRACE ((me, "0x%x: %02x %02x %02x %02x %02x %02x %02x %02x",
968 address + 3 + i,
969 buf[3+i], buf[4+i], buf[5+i], buf[6+i], buf[7+i], buf[8+i],
970 buf[9+i], buf[10+i]));
971
972 len -= 3;
973 hw_rv_send (me, cmd, buf + 3, len);
974
975 /* Note: both ..._PUT and ..._HANDLE get the ..._HANDLE reply. */
976 hw_rv_handle_incoming (me, RV_MBOX_HANDLE_CMD, buf + 3, &len);
977 if (len > sizeof (buf))
978 hw_abort (me, "mbox cmd %d receive size %d unsupported", cmd, len);
979 HW_TRACE ((me, "-> 0x%x..0x%x", address, address + len + 3 - 1));
980 for (i = 0; i < len; i += 8)
981 HW_TRACE ((me, "0x%x: %02x %02x %02x %02x %02x %02x %02x %02x",
982 address + 3 + i,
983 buf[3+i], buf[4+i], buf[5+i], buf[6+i], buf[7+i], buf[8+i],
984 buf[9+i], buf[10+i]));
985
986 len += 3;
987 buf[0] = len & 255;
988 buf[1] = len / 256;
989 rlen = hw_dma_write_buffer (me, buf, 0, address, len, 0);
990 if (rlen != len)
991 hw_abort (me, "mbox write %d != %d bytes", rlen, len);
992}
993
994/* Local rv register writes end up here. */
995
996static unsigned int
997hw_rv_reg_write (struct hw *me,
998 const void *source,
999 int space,
1000 unsigned_word addr,
1001 unsigned int nr_bytes)
1002{
1003 hw_rv_device *rv = (hw_rv_device *) hw_data (me);
1004
1005 unsigned8 addr_data[8] = "";
1006 unsigned32 a_l = H2LE_4 (addr - rv->reg_address + rv->remote_reg_address);
1007 unsigned int len = 8;
1008
1009 if (nr_bytes != 4)
1010 hw_abort (me, "must be four byte write");
1011
1012 memcpy (addr_data, &a_l, 4);
1013 memcpy (addr_data + 4, source, 4);
1014
1015 if (addr == rv->mbox_address)
1016 {
1017 unsigned32 mbox_addr_le;
1018 if (rv->dummy != NULL)
1019 hw_abort (me, "mbox not supported for a dummy instance");
1020 memcpy (&mbox_addr_le, source, 4);
1021 hw_rv_mbox (me, LE2H_4 (mbox_addr_le));
1022 return nr_bytes;
1023 }
1024
1025 HW_TRACE ((me, "REG W 0x%x := 0x%02x%02x%02x%02x", addr,
1026 addr_data[7], addr_data[6], addr_data[5], addr_data[4]));
1027 if (rv->dummy != NULL)
1028 {
1029 len = 8;
1030 memcpy (rv->dummy + addr - rv->reg_address, addr_data + 4, 4);
1031 }
1032 else
1033 {
1034 hw_rv_send (me, RV_WRITE_CMD, addr_data, len);
1035 hw_rv_handle_incoming (me, RV_WRITE_CMD, addr_data, &len);
1036 }
1037
1038 if (len != 8)
1039 hw_abort (me, "read %d != 8 bytes returned", len);
1040
1041 /* We had an access: tighten up all slack. */
1042 rv->next_period = 1;
1043
1044 return nr_bytes;
1045}
1046
1047/* Instance initializer function. */
1048
1049static void
1050hw_rv_finish (struct hw *me)
1051{
1052 hw_rv_device *rv = HW_ZALLOC (me, hw_rv_device);
1053 int i;
1054 const struct hw_property *mem_prop;
1055 const struct hw_property *dummy_prop;
1056 const struct hw_property *mbox_prop;
1057
1058 set_hw_data (me, rv);
1059
1060#undef RV_GET_IPROP
1061#undef RV_GET_PROP
1062#define RV_GET_PROP(T, N, M, D) \
1063 do \
1064 { \
1065 if (hw_find_property (me, N) != NULL) \
1066 rv->M = hw_find_ ## T ## _property (me, N); \
1067 else \
1068 rv->M = (D); \
1069 } \
1070 while (0)
1071#define RV_GET_IPROP(N, M, D) RV_GET_PROP (integer, N, M, D)
1072
1073 RV_GET_PROP (string, "host", host, "127.0.0.1");
1074 RV_GET_IPROP ("port", port, 10000);
1075 RV_GET_IPROP ("remote-reg", remote_reg_address, 0);
1076 RV_GET_IPROP ("max-poll-ticks", max_tick_poll_interval, 10000);
1077 RV_GET_IPROP ("watchdog-interval", watchdog_interval, 30);
1078 RV_GET_IPROP ("remote-mem", remote_mem_address, 0);
1079 RV_GET_IPROP ("mem-burst-mask", mem_burst_mask, 0xffff);
1080 RV_GET_IPROP ("intmultiple", intmultiple, 0);
1081
1082 set_hw_io_read_buffer (me, hw_rv_reg_read);
1083 set_hw_io_write_buffer (me, hw_rv_reg_write);
1084 set_hw_ports (me, hw_rv_ports);
1085 rv->next_period = 1;
1086
1087 /* FIXME: We only support zero or one reg and zero or one mem area. */
1088 if (hw_find_property (me, "reg") != NULL)
1089 {
1090 reg_property_spec reg;
1091 if (hw_find_reg_array_property (me, "reg", 0, &reg))
1092 {
1093 unsigned_word attach_address;
1094 int attach_space;
1095 unsigned int attach_size;
1096
1097 hw_unit_address_to_attach_address (hw_parent (me),
1098 &reg.address,
1099 &attach_space,
1100 &attach_address,
1101 me);
1102 rv->reg_address = attach_address;
1103 hw_unit_size_to_attach_size (hw_parent (me),
1104 &reg.size,
1105 &attach_size, me);
1106 rv->reg_size = attach_size;
1107 if ((attach_address & 3) != 0)
1108 hw_abort (me, "register block must be 4 byte aligned");
1109 hw_attach_address (hw_parent (me),
1110 0,
1111 attach_space, attach_address, attach_size,
1112 me);
1113 }
1114 else
1115 hw_abort (me, "property \"reg\" has the wrong type");
1116 }
1117
1118 dummy_prop = hw_find_property (me, "dummy");
1119 if (dummy_prop != NULL)
1120 {
1121 if (rv->reg_size == 0)
1122 hw_abort (me, "dummy argument requires a \"reg\" property");
1123
1124 if (hw_property_type (dummy_prop) == integer_property)
1125 {
1126 unsigned32 dummyfill = hw_find_integer_property (me, "dummy");
1127 unsigned8 *dummymem = hw_malloc (me, rv->reg_size);
1128 memset (dummymem, dummyfill, rv->reg_size);
1129 rv->dummy = dummymem;
1130 }
1131 else
1132 {
1133 const char *dummyarg = hw_find_string_property (me, "dummy");
1134 unsigned8 *dummymem = hw_malloc (me, rv->reg_size);
1135 FILE *f = fopen (dummyarg, "rb");
1136
1137 if (f == NULL)
1138 hw_abort (me, "opening dummy-file \"%s\": %s",
1139 dummyarg, strerror (errno));
1140 if (fread (dummymem, 1, rv->reg_size, f) != rv->reg_size)
1141 hw_abort (me, "reading dummy-file \"%s\": %s",
1142 dummyarg, strerror (errno));
1143 fclose (f);
1144 rv->dummy = dummymem;
1145 }
1146 }
1147
1148 mbox_prop = hw_find_property (me, "mbox");
1149 if (mbox_prop != NULL)
1150 {
1151 if (hw_property_type (mbox_prop) == integer_property)
1152 {
1153 signed_cell attach_address_sc
1154 = hw_find_integer_property (me, "mbox");
1155
1156 rv->mbox_address = (unsigned32) attach_address_sc;
1157 hw_attach_address (hw_parent (me),
1158 0,
1159 0, (unsigned32) attach_address_sc, 4, me);
1160 }
1161 else
1162 hw_abort (me, "property \"mbox\" has the wrong type");
1163 }
1164
1165 mem_prop = hw_find_property (me, "mem");
1166 if (mem_prop != NULL)
1167 {
1168 signed_cell attach_address_sc;
1169 signed_cell attach_size_sc;
1170
1171 /* Only specific names are reg_array_properties, the rest are
1172 array_properties. */
1173 if (hw_property_type (mem_prop) == array_property
1174 && hw_property_sizeof_array (mem_prop) == 2 * sizeof (attach_address_sc)
1175 && hw_find_integer_array_property (me, "mem", 0, &attach_address_sc)
1176 && hw_find_integer_array_property (me, "mem", 1, &attach_size_sc))
1177 {
1178 /* Unfortunate choice of types forces us to dance around a bit. */
1179 rv->mem_address = (unsigned32) attach_address_sc;
1180 rv->mem_size = (unsigned32) attach_size_sc;
1181 if ((attach_address_sc & 3) != 0)
1182 hw_abort (me, "memory block must be 4 byte aligned");
1183 }
1184 else
1185 hw_abort (me, "property \"mem\" has the wrong type");
1186 }
1187
1188 hw_rv_map_ints (me);
1189
1190 hw_rv_init_socket (me);
1191
1192 /* We need an extra initialization pass, after all others currently
1193 scheduled (mostly, after the simulation events machinery has been
1194 initialized so the events we want don't get thrown out). */
1195 hw_rv_add_init (me);
1196}
1197
1198/* Our root structure; see dv-* build machinery for usage. */
1199
1200const struct hw_descriptor dv_rv_descriptor[] = {
1201 { RV_FAMILY_NAME, hw_rv_finish },
1202 { NULL }
1203};
This page took 0.841256 seconds and 4 git commands to generate.