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