1 /* The remote-virtual-component simulator framework
2 for GDB, the GNU Debugger.
4 Copyright 2006-2023 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 /* This must come before any other includes. */
34 #ifdef HAVE_SYS_TYPES_H
35 #include <sys/types.h>
40 #include <sys/select.h>
42 /* Not guarded in dv-sockser.c, so why here. */
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
46 #include <sys/socket.h>
52 rv - Remote Virtual component
58 Socket connection to a remote simulator component, for example one
59 for testing a verilog construction. Protocol defined below.
61 There is a set of 32-bit I/O ports, with a mapping from local to
62 remote addresses. There is a set of interrupts expressed as a
63 bit-mask, with a mapping from remote to local. There is a set of
64 memory ranges (actual memory defined elsewhere), also with a
65 mapping from remote to local addresses, that is expected to be
66 accessible to the remote simulator in 32-byte chunks (simulating
67 DMA). There is a mapping from remote cycles (or an appropriate
68 elsewhere defined time-slice) to local cycles.
72 reg = <address> <size>
73 The address (within the parent bus) that this device is to
76 remote-reg = <remote-address>
77 The address of reg on the remote side. Defaults to 0.
79 mem = <address> <size>
80 Specify an address-range (within the parent bus) that the remote
81 device can access. The memory is assumed to be already defined.
82 If there's no memory defined but the remote side asks for a memory
83 access, the simulation is aborted.
85 remote-mem = <remote-address>
86 The address of mem on the remote side. Defaults to 0.
89 Address of the mailbox interface. Writes to this address with the
90 local address of a mailbox command, a complete packet with length
91 and command; (4 or 6)) invokes the mailbox interface. Reads are
92 invalid. Replies are written to the same address. Address space
93 from <address> up-to-and-including <address>+3 is allocated.
95 max-poll-ticks = <local-count>
96 Sets the maximum interval between polling the external component,
97 expressed in internal cycles. Defaults to 10000.
99 watchdog-interval = <seconds>
100 Sets the wallclock seconds between watchdog packets sent to the
101 remote side (may be larger if there's no rv activity in that time).
102 Defaults to 30. If set to 0, no watchdog packets are sent.
104 intnum = <local-int-0> <local-int-1> ... <local-int-31>
105 Defines a map from remote bit numbers to local values to be emitted
106 on the "int" port, with the external bit number as the ordinal - 1
107 of the local translation. E.g. 43 121 would mean map external
108 (1<<0) to internal 43 and external (1<<1) to internal 121. The
109 default is unity; no translation. If more than one bit is set in
110 the remote interrupt word, the intmultiple property can be used to
111 control the translation.
113 intmultiple = <intvalue>
114 When more than one bit is set in the remote interrupt word, you may
115 want to map this situation to a separate interrupt value. If this
116 property is non-zero, it is used as that value. If it is zero, the
117 local value for the "int" port is the bitwise-or of the translated
121 The hostname or address where the simulator to be used listens.
122 Defaults to "127.0.0.1"
125 The hostname or address where the simulator to be used listens.
131 Don't connect to a remote side; use initial dummy contents from
132 <filename> (which has to be at least as big as the <size> argument
133 of reg above) or filled with byte-value <value>. Mailboxes are not
134 supported (can be defined but can not be used) and remote-memory
135 accesses don't apply. The main purpose for this property is to
136 simplify use of configuration and simulated hardware that is
137 e.g. only trivially initialized but not actually used.
143 Driven as a result of a remote interrupt request. The value is a
144 32-bit bitset of active interrupts.
154 This is version 1.0 of this protocol, defining packet format and
155 actions in a supposedly upward-compatible manner where client and
156 servers of different versions are expected to interoperate; the
157 format and the definitions below are hopefully generic enough to
160 Each connection has a server and a client (this code); the roles
161 are known beforehand. The client usually corresponds to a CPU and
162 memory system and the server corresponds to a memory-mapped
163 register hardware interface and/or a DMA controller. They
164 communicate using packets with specific commands, of which some
165 require replies from the other side; most are intiated by the
166 client with one exception. A reply uses the same format as the
169 Packets are at least three bytes long, where the first two bytes
170 form a header, a 16-bit little-endian number that is the total
171 length of the packet including the header. There is also a
172 one-byte command. The payload is optional, depending on the
175 [[16-bit-low-byte-of-length] [16-bit-high-byte-of-length]
176 [command/reply] [payload byte 0] [payload byte 1]
177 ... [payload byte (length-of-packet - 3)]]
181 A client or server that reads an undocumented command may exit with
182 a hard error. Payload not defined or disallowed below is ignored.
184 It is expected that future client versions find out the version of
185 the server side by polling with base commands, assuming earlier
186 versions if a certain reply isn't seen, with newly defined payload
187 parts where earlier versions left it undefined. New commands and
188 formats are sent only to the other side after the client and server
189 has found out each others version. Not all servers support all
190 commands; the type of server and supported set of commands is
191 expected to be known beforehand.
194 Initiated by the client, requires a reply from the server. The
195 payload from the client is at least 4 bytes, forming a 4-byte
196 little-endian address, the rest being undefined. The reply from
197 the server is at least 8 bytes, forming the same address data as in
198 the request and the second 4-byte data being the little-endian
202 Initiated by the client, requires a reply from the server. Payload
203 from the client is at least 8 bytes, forming a 4-byte little-endian
204 word being the address, the rest being the little-endian contents
205 to write. The reply from the server is 8 bytes unless elsewhere
206 agreed otherwise, forming the same address and data as in the
207 request. The data sent back may have been altered to correspond to
208 defined parts but can safely be discarded.
211 Initiated by the server, no reply. The payload is 4 bytes, forming
212 a little-endian word with bits numbers corresponding to currently
213 active interrupt sources; value (1<<N) indicating interrupt source
217 Initiated by the server, requires a reply. A client must know
218 beforehand when (in command sequence or constant) the server can
219 send this command and if so must then not send any commands of its
220 own (including watchdog commands); the server is allowed to assume
221 that incoming data is only replies to this command. The format is
222 8 bytes of data; 4 bytes of little-endian address followed by a
223 32-bit little endian word with the number of bytes to read. The
224 reply is the same address and number of bytes, followed by the data
228 Initiated by the server, no reply. The format is the same as a
229 reply to RV_MEM_RD_CMD; a 32-bit little-endian address, followed by
230 the 32-bit little-endian number of bytes to write (redundant
231 information but must be consistent with the packet header).
233 RV_MBOX_HANDLE_CMD = 5
234 Initiated by the client, requires a reply. The payload is 4
235 undefined bytes followed by an binary blob, the size of the
236 blob given by the packet header. The reply is a 32-bit little
237 endian number at the same index as the undefined bytes. Actual
238 semantics are application-specific.
241 Initiated by the client, requires a reply, with the reply using the
242 RV_MBOX_HANDLE_CMD reply format (i.e. *both* that command and
243 32-bit little-endian number). The payload is a 32-bit little
244 endian number followed by an undefined payload, at most 20 bytes
245 long. The reply is a 32-bit little endian number. Actual
246 semantics are application-specific.
249 Initiated by the client, no reply. A version 1.0 client sends no
250 payload; a version 1.0 server should ignore any such payload. A
251 version 1.0 server must not send a reply.
254 Possible future enhancements:
256 Synchronization; server and client reports the number of elapsed
257 cycles (unit to-be-defined) at each request or notification.
258 Pretty much the top-of-the-todo-list item.
260 Large addresses; 1.0 being restricted to 32-bit addresses.
262 Variable-size data; currently restricted to 32-bit register
265 Specified data endianness (not the packet header) perhaps as part
266 of an initial format request; currently little-endian only.
270 When used with servers sending RV_MEM_RD_CMD but being
271 narrow-minded about indata, set watchdog-interval to 0. Use
272 multiple rv instances when there are e.g. separate register and
273 memory servers. Alway log, setting "/rv/trace? true", at the
274 development phase. Borrow from the test-suite.
277 #define RV_FAMILY_NAME "rv"
285 RV_MBOX_HANDLE_CMD
= 5,
291 typedef struct _hw_rv_device
293 /* Mapping of remote interrupt bit-numbers to local ones. */
294 uint32_t remote_to_local_int
[32];
296 /* When multiple bits are set, a non-zero value here indicates that
297 this value should be used instead. */
298 uint32_t intmultiple
;
300 /* Local address of registers. */
301 uint32_t reg_address
;
303 /* Size of register bank in bytes. */
306 /* Remote address of registers. */
307 uint32_t remote_reg_address
;
309 /* Local address of DMA:able memory. */
310 uint32_t mem_address
;
312 /* Size of DMA:able memory in bytes. */
315 /* Bitmask for valid DMA request size. */
316 uint32_t mem_burst_mask
;
318 /* Remote address of DMA:able memory. */
319 uint32_t remote_mem_address
;
321 /* (Local) address of mbox; where to put a pointer to the mbox to be
323 uint32_t mbox_address
;
325 /* Probably not 127.0.0.1:10000. */
329 /* If non-NULL, points to memory to use instead of connection. */
332 /* File descriptor for the socket. Set to -1 when error. Only one
333 of dummy and this is active. */
336 /* Stashed errno, as we don't emit an error right away. */
339 /* This, plus latency because the CPU might not be checking until a
340 CTI insn (usually a branch or a jump) is the interval in cycles
341 between the rv is polled for e.g. DMA requests. */
342 uint32_t max_tick_poll_interval
;
344 /* Running counter for exponential backoff up to
345 max_tick_poll_interval to avoid polling the connection
346 unnecessarily often. Set to 1 when rv activity (read/write
347 register, DMA request) is detected. */
348 uint32_t next_period
;
350 /* This is the interval in wall-clock seconds between watchdog
351 packets are sent to the remote side. Zero means no watchdog
353 uint32_t watchdog_interval
;
355 /* Last time we sent a watchdog packet. */
356 struct timeval last_wdog_time
;
358 /* Mostly used as a kludge for knowing which rv:s have poll events
360 struct hw_event
*poll_callback
;
364 /* We might add ports in the future, so keep this an enumeration. */
371 static const struct hw_port_descriptor hw_rv_ports
[] = {
372 { "int", INT_PORT
, 0, output_port
},
376 /* Send LEN bytes of data from BUF to the socket. Abort on
380 hw_rv_write (struct hw
*me
,
384 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
387 /* If we don't have a valid fd here, it's because we got an error
388 initially, and we suppressed that error. */
390 hw_abort (me
, "couldn't open a connection to %s:%d because: %s",
391 rv
->host
, rv
->port
, strerror (rv
->saved_errno
));
395 ssize_t ret
= write (rv
->fd
, bufp
, len
);
397 /* FIXME: More graceful exit. */
398 hw_abort (me
, "write to %s:%d failed: %s\n", rv
->host
, rv
->port
,
406 /* Read LEN bytes of data into BUF from the socket. Set the file
407 descriptor to -1 if there's an error. */
410 hw_rv_read (struct hw
*me
,
414 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
419 ssize_t ret
= read (rv
->fd
, bufp
, len
);
421 /* We get all zero if the remote end quits, but no error
422 indication; even select says there's data active. */
425 if (close (rv
->fd
) != 0)
426 /* FIXME: More graceful exit. */
427 hw_abort (me
, "read from %s:%d failed: %d\n", rv
->host
, rv
->port
, errno
);
437 /* Construct and send a packet of data of type CMD and len
438 LEN_NOHEADER (not counting the header...). */
441 hw_rv_send (struct hw
*me
,
444 unsigned int len_noheader
)
446 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
449 unsigned int len
= len_noheader
+ 3;
453 buf
[1] = (len
>> 8) & 255;
456 if (len
> sizeof (buf
))
458 hw_rv_write (me
, buf
, 3);
464 memcpy (buf
+ 3, msg
, len_noheader
);
468 hw_rv_write (me
, bufp
, len
);
471 /* Handle incoming DMA requests as per the RV_MEM_RD_CMD packet.
475 hw_rv_read_mem (struct hw
*me
, unsigned int len
)
477 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
478 /* If you change this size, please adjust the mem2 testcase. */
487 hw_abort (me
, "expected DMA read request len 8+3, got %d+3", len
);
489 hw_rv_read (me
, &leaddr
, 4);
490 hw_rv_read (me
, &lelen
, 4);
491 len
= LE2H_4 (lelen
);
492 addr
= LE2H_4 (leaddr
);
494 if (addr
< rv
->remote_mem_address
495 || addr
>= rv
->remote_mem_address
+ rv
->mem_size
)
496 hw_abort (me
, "DMA read at remote 0x%x; outside [0x%x..0x%x-1]",
497 (unsigned) addr
, (unsigned) rv
->remote_mem_address
,
498 (unsigned) (rv
->remote_mem_address
+ rv
->mem_size
));
499 addr
= addr
- rv
->remote_mem_address
+ rv
->mem_address
;
502 hw_abort (me
, "DMA read request for 0 bytes isn't supported");
504 if (len
& ~rv
->mem_burst_mask
)
505 hw_abort (me
, "DMA trying to read %d bytes; not matching mask of 0x%x",
506 len
, rv
->mem_burst_mask
);
507 if (len
+ 8 > sizeof (buf
))
508 bufp
= hw_malloc (me
, len
+ 8);
510 HW_TRACE ((me
, "DMA R 0x%x..0x%x", addr
, addr
+ len
-1));
511 hw_dma_read_buffer (me
, bufp
+ 8, 0, addr
, len
);
513 for (i
= 0; i
< len
; i
+= 4)
514 HW_TRACE ((me
, "0x%x: %02x %02x %02x %02x",
516 bufp
[i
+8], bufp
[i
+9], bufp
[i
+10], bufp
[i
+11]));
518 memcpy (bufp
, &leaddr
, 4);
519 memcpy (bufp
+ 4, &lelen
, 4);
520 hw_rv_send (me
, RV_MEM_RD_CMD
, bufp
, len
+ 8);
525 /* Handle incoming DMA requests as per the RV_MEM_WR_CMD packet.
529 hw_rv_write_mem (struct hw
*me
, unsigned int plen
)
531 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
532 /* If you change this size, please adjust the mem2 testcase. */
541 hw_rv_read (me
, &leaddr
, 4);
542 hw_rv_read (me
, &lelen
, 4);
543 len
= LE2H_4 (lelen
);
544 addr
= LE2H_4 (leaddr
);
548 "inconsistency in DMA write request packet: "
549 "envelope %d+3, inner %d bytes", plen
, len
);
551 if (addr
< rv
->remote_mem_address
552 || addr
>= rv
->remote_mem_address
+ rv
->mem_size
)
553 hw_abort (me
, "DMA write at remote 0x%x; outside [0x%x..0x%x-1]",
554 (unsigned) addr
, (unsigned) rv
->remote_mem_address
,
555 (unsigned) (rv
->remote_mem_address
+ rv
->mem_size
));
557 addr
= addr
- rv
->remote_mem_address
+ rv
->mem_address
;
559 hw_abort (me
, "DMA write request for 0 bytes isn't supported");
561 if (len
& ~rv
->mem_burst_mask
)
562 hw_abort (me
, "DMA trying to write %d bytes; not matching mask of 0x%x",
563 len
, rv
->mem_burst_mask
);
564 if (len
+ 8 > sizeof (buf
))
565 bufp
= hw_malloc (me
, len
+ 8);
567 hw_rv_read (me
, bufp
+ 8, len
);
568 HW_TRACE ((me
, "DMA W 0x%x..0x%x", addr
, addr
+ len
- 1));
569 hw_dma_write_buffer (me
, bufp
+ 8, 0, addr
, len
, 0);
571 for (i
= 0; i
< len
; i
+= 4)
572 HW_TRACE ((me
, "0x%x: %02x %02x %02x %02x",
574 bufp
[i
+8], bufp
[i
+9], bufp
[i
+10], bufp
[i
+11]));
580 hw_rv_irq (struct hw
*me
, unsigned int len
)
582 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
584 uint32_t intbits_ext
;
589 hw_abort (me
, "IRQ with %d data not supported", len
);
591 hw_rv_read (me
, &intbitsle
, 4);
592 intbits_ext
= LE2H_4 (intbitsle
);
593 for (i
= 0; i
< 32; i
++)
594 if ((intbits_ext
& (1 << i
)) != 0)
595 intval
|= rv
->remote_to_local_int
[i
];
596 if ((intbits_ext
& ~(intbits_ext
- 1)) != intbits_ext
597 && rv
->intmultiple
!= 0)
598 intval
= rv
->intmultiple
;
600 HW_TRACE ((me
, "IRQ 0x%x", intval
));
601 hw_port_event (me
, INT_PORT
, intval
);
604 /* Handle incoming interrupt notifications as per the RV_IRQ_CMD
605 packet. Abort on errors. */
608 hw_rv_handle_incoming (struct hw
*me
,
611 unsigned int *return_len
)
613 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
620 hw_rv_read (me
, cbuf
, 3);
625 len
= cbuf
[0] + cbuf
[1] * 256 - 3;
628 /* These come in "asynchronously"; not as a reply. */
636 hw_rv_read_mem (me
, len
);
640 hw_rv_write_mem (me
, len
);
644 /* Something is incoming from the other side, so tighten up all
645 slack at the next wait. */
653 /* Don't try to handle more than one of these if we were'nt
654 expecting a reply. */
655 if (expected_type
== -1)
660 /* Require a match between this supposed-reply and the command
662 if (cmd
!= expected_type
)
663 hw_abort (me
, "unexpected reply, expected command %d, got %d",
668 case RV_MBOX_PUT_CMD
:
669 case RV_MBOX_HANDLE_CMD
:
672 hw_rv_read (me
, buf
, len
<= *return_len
? len
: *return_len
);
680 /* Send a watchdog packet. Make a note of wallclock time. */
683 hw_rv_send_wdog (struct hw
*me
)
685 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
686 HW_TRACE ((me
, "WD"));
687 gettimeofday (&rv
->last_wdog_time
, NULL
);
688 hw_rv_send (me
, RV_WATCHDOG_CMD
, "", 0);
691 /* Poll the remote side: see if there's any incoming traffic; handle a
692 packet if so. Send a watchdog packet if it's time to do so.
693 Beware that the Linux select call indicates traffic for a socket
694 that the remote side has closed (which may be because it was
695 finished; don't hork until we need to write something just because
699 hw_rv_poll_once (struct hw
*me
)
701 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
709 /* Connection has died or was never initiated. */
713 FD_SET (rv
->fd
, &rfds
);
715 FD_SET (rv
->fd
, &efds
);
719 ret
= select (rv
->fd
+ 1, &rfds
, NULL
, &efds
, &tv
);
720 gettimeofday (&now
, NULL
);
723 hw_abort (me
, "select failed: %d\n", errno
);
725 if (rv
->watchdog_interval
!= 0
726 && now
.tv_sec
- rv
->last_wdog_time
.tv_sec
>= rv
->watchdog_interval
)
727 hw_rv_send_wdog (me
);
729 if (FD_ISSET (rv
->fd
, &rfds
))
730 hw_rv_handle_incoming (me
, -1, NULL
, NULL
);
733 /* Initialize mapping of remote-to-local interrupt data. */
736 hw_rv_map_ints (struct hw
*me
)
738 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
741 for (i
= 0; i
< 32; i
++)
742 rv
->remote_to_local_int
[i
] = 1 << i
;
744 if (hw_find_property (me
, "intnum") != NULL
)
745 for (i
= 0; i
< 32; i
++)
747 signed_cell val
= -1;
748 if (hw_find_integer_array_property (me
, "intnum", i
, &val
) > 0)
751 rv
->remote_to_local_int
[i
] = val
;
753 hw_abort (me
, "property \"intnum@%d\" must be > 0; is %d",
759 /* Handle the after-N-ticks "poll event", calling the poll-the-fd
760 method. Update the period. */
763 do_poll_event (struct hw
*me
, void *data
)
765 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
768 if (rv
->dummy
!= NULL
)
771 hw_rv_poll_once (me
);
774 = hw_event_queue_schedule (me
, rv
->next_period
, do_poll_event
, NULL
);
776 new_period
= rv
->next_period
* 2;
777 if (new_period
<= rv
->max_tick_poll_interval
)
778 rv
->next_period
= new_period
;
781 /* HW tree traverse function for hw_rv_add_init. */
784 hw_rv_add_poller (struct hw
*me
, void *data
)
788 if (hw_family (me
) == NULL
789 || strcmp (hw_family (me
), RV_FAMILY_NAME
) != 0)
792 rv
= (hw_rv_device
*) hw_data (me
);
793 if (rv
->poll_callback
!= NULL
)
797 = hw_event_queue_schedule (me
, 1, do_poll_event
, NULL
);
800 /* Simulator module init function for hw_rv_add_init. */
802 /* FIXME: For the call so hw_tree_traverse, we need to know that the
803 first member of struct sim_hw is the struct hw *root, but there's
804 no accessor method and struct sim_hw is defined in sim-hw.c only.
805 Hence this hack, until an accessor is added, or there's a traverse
806 function that takes a SIM_DESC argument. */
807 struct sim_hw
{ struct hw
*tree
; };
810 hw_rv_add_rv_pollers (SIM_DESC sd
)
812 hw_tree_traverse (STATE_HW (sd
)->tree
, hw_rv_add_poller
, NULL
, NULL
);
816 /* We need to add events for polling, but we can't add one from the
817 finish-function, and there are no other call points, at least for
818 instances without "reg" (when there are just DMA requests from the
819 remote end; no locally initiated activity). Therefore we add a
820 simulator module init function, but those don't have private
821 payload arguments; just a SD argument. We cope by parsing the HW
822 root and making sure *all* "rv":s have poll callbacks installed.
823 Luckily, this is just an initialization step, and not many
824 simultaneous instances of rv are expected: we get a N**2 complexity
825 for visits to each rv node by this method. */
828 hw_rv_add_init (struct hw
*me
)
830 sim_module_add_init_fn (hw_system (me
), hw_rv_add_rv_pollers
);
833 /* Open up a connection to the other side. Abort on errors. */
836 hw_rv_init_socket (struct hw
*me
)
838 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
840 struct sockaddr_in server
;
844 if (rv
->dummy
!= NULL
)
847 memset (&server
, 0, sizeof (server
));
848 server
.sin_family
= AF_INET
;
849 server
.sin_addr
.s_addr
= inet_addr (rv
->host
);
851 /* Solaris 2.7 lacks this macro. */
853 #define INADDR_NONE -1
856 if (server
.sin_addr
.s_addr
== INADDR_NONE
)
859 h
= gethostbyname (rv
->host
);
862 memcpy (&server
.sin_addr
, h
->h_addr
, h
->h_length
);
863 server
.sin_family
= h
->h_addrtype
;
866 hw_abort (me
, "can't resolve host %s", rv
->host
);
869 server
.sin_port
= htons (rv
->port
);
870 sock
= socket (AF_INET
, SOCK_STREAM
, 0);
873 hw_abort (me
, "can't get a socket for %s:%d connection",
876 if (connect (sock
, (struct sockaddr
*) &server
, sizeof server
) >= 0)
880 /* FIXME: init packet here. Maybe start packet too. */
881 if (rv
->watchdog_interval
!= 0)
882 hw_rv_send_wdog (me
);
885 /* Stash the errno for later display, if some connection activity
886 is requested. Don't emit an error here; we might have been
887 called just for test purposes. */
888 rv
->saved_errno
= errno
;
891 /* Local rv register reads end up here. */
894 hw_rv_reg_read (struct hw
*me
,
898 unsigned int nr_bytes
)
900 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
901 uint8_t addr_data
[8] = "";
902 uint32_t a_l
= H2LE_4 (addr
- rv
->reg_address
+ rv
->remote_reg_address
);
903 unsigned int len
= 8;
906 hw_abort (me
, "must be four byte read");
908 if (addr
== rv
->mbox_address
)
909 hw_abort (me
, "invalid read of mbox address 0x%x",
910 (unsigned) rv
->mbox_address
);
912 memcpy (addr_data
, &a_l
, 4);
913 HW_TRACE ((me
, "REG R 0x%x", addr
));
914 if (rv
->dummy
!= NULL
)
917 memcpy (addr_data
+ 4, rv
->dummy
+ addr
- rv
->reg_address
, 4);
921 hw_rv_send (me
, RV_READ_CMD
, addr_data
, len
);
922 hw_rv_handle_incoming (me
, RV_READ_CMD
, addr_data
, &len
);
926 hw_abort (me
, "read %d != 8 bytes returned", len
);
927 HW_TRACE ((me
, ":= 0x%02x%02x%02x%02x",
928 addr_data
[7], addr_data
[6], addr_data
[5], addr_data
[4]));
929 memcpy (dest
, addr_data
+ 4, 4);
933 /* Local rv mbox requests (handle or put) end up here. */
936 hw_rv_mbox (struct hw
*me
, unsigned_word address
)
943 = hw_dma_read_buffer (me
, buf
, 0, address
, 3);
946 hw_abort (me
, "mbox read %d != 3 bytes returned", len
);
949 if (cmd
!= RV_MBOX_HANDLE_CMD
&& cmd
!= RV_MBOX_PUT_CMD
)
950 hw_abort (me
, "unsupported mbox command %d", cmd
);
952 len
= buf
[0] + buf
[1]*256;
954 if (len
> sizeof (buf
))
955 hw_abort (me
, "mbox cmd %d send size %d unsupported", cmd
, len
);
957 rlen
= hw_dma_read_buffer (me
, buf
+ 3, 0, address
+ 3, len
- 3);
959 hw_abort (me
, "mbox read %d != %d bytes returned", rlen
, len
- 3);
961 HW_TRACE ((me
, "MBOX %s 0x%x..0x%x",
962 cmd
== RV_MBOX_HANDLE_CMD
? "H" : "P",
963 address
, address
+ len
- 1));
964 for (i
= 0; i
< rlen
; i
+= 8)
965 HW_TRACE ((me
, "0x%x: %02x %02x %02x %02x %02x %02x %02x %02x",
967 buf
[3+i
], buf
[4+i
], buf
[5+i
], buf
[6+i
], buf
[7+i
], buf
[8+i
],
968 buf
[9+i
], buf
[10+i
]));
971 hw_rv_send (me
, cmd
, buf
+ 3, len
);
973 /* Note: both ..._PUT and ..._HANDLE get the ..._HANDLE reply. */
974 hw_rv_handle_incoming (me
, RV_MBOX_HANDLE_CMD
, buf
+ 3, &len
);
975 if (len
> sizeof (buf
))
976 hw_abort (me
, "mbox cmd %d receive size %d unsupported", cmd
, len
);
977 HW_TRACE ((me
, "-> 0x%x..0x%x", address
, address
+ len
+ 3 - 1));
978 for (i
= 0; i
< len
; i
+= 8)
979 HW_TRACE ((me
, "0x%x: %02x %02x %02x %02x %02x %02x %02x %02x",
981 buf
[3+i
], buf
[4+i
], buf
[5+i
], buf
[6+i
], buf
[7+i
], buf
[8+i
],
982 buf
[9+i
], buf
[10+i
]));
987 rlen
= hw_dma_write_buffer (me
, buf
, 0, address
, len
, 0);
989 hw_abort (me
, "mbox write %d != %d bytes", rlen
, len
);
992 /* Local rv register writes end up here. */
995 hw_rv_reg_write (struct hw
*me
,
999 unsigned int nr_bytes
)
1001 hw_rv_device
*rv
= (hw_rv_device
*) hw_data (me
);
1003 uint8_t addr_data
[8] = "";
1004 uint32_t a_l
= H2LE_4 (addr
- rv
->reg_address
+ rv
->remote_reg_address
);
1005 unsigned int len
= 8;
1008 hw_abort (me
, "must be four byte write");
1010 memcpy (addr_data
, &a_l
, 4);
1011 memcpy (addr_data
+ 4, source
, 4);
1013 if (addr
== rv
->mbox_address
)
1015 uint32_t mbox_addr_le
;
1016 if (rv
->dummy
!= NULL
)
1017 hw_abort (me
, "mbox not supported for a dummy instance");
1018 memcpy (&mbox_addr_le
, source
, 4);
1019 hw_rv_mbox (me
, LE2H_4 (mbox_addr_le
));
1023 HW_TRACE ((me
, "REG W 0x%x := 0x%02x%02x%02x%02x", addr
,
1024 addr_data
[7], addr_data
[6], addr_data
[5], addr_data
[4]));
1025 if (rv
->dummy
!= NULL
)
1028 memcpy (rv
->dummy
+ addr
- rv
->reg_address
, addr_data
+ 4, 4);
1032 hw_rv_send (me
, RV_WRITE_CMD
, addr_data
, len
);
1033 hw_rv_handle_incoming (me
, RV_WRITE_CMD
, addr_data
, &len
);
1037 hw_abort (me
, "read %d != 8 bytes returned", len
);
1039 /* We had an access: tighten up all slack. */
1040 rv
->next_period
= 1;
1045 /* Instance initializer function. */
1048 hw_rv_finish (struct hw
*me
)
1050 hw_rv_device
*rv
= HW_ZALLOC (me
, hw_rv_device
);
1052 const struct hw_property
*mem_prop
;
1053 const struct hw_property
*dummy_prop
;
1054 const struct hw_property
*mbox_prop
;
1056 set_hw_data (me
, rv
);
1060 #define RV_GET_PROP(T, N, M, D) \
1063 if (hw_find_property (me, N) != NULL) \
1064 rv->M = hw_find_ ## T ## _property (me, N); \
1069 #define RV_GET_IPROP(N, M, D) RV_GET_PROP (integer, N, M, D)
1071 RV_GET_PROP (string
, "host", host
, "127.0.0.1");
1072 RV_GET_IPROP ("port", port
, 10000);
1073 RV_GET_IPROP ("remote-reg", remote_reg_address
, 0);
1074 RV_GET_IPROP ("max-poll-ticks", max_tick_poll_interval
, 10000);
1075 RV_GET_IPROP ("watchdog-interval", watchdog_interval
, 30);
1076 RV_GET_IPROP ("remote-mem", remote_mem_address
, 0);
1077 RV_GET_IPROP ("mem-burst-mask", mem_burst_mask
, 0xffff);
1078 RV_GET_IPROP ("intmultiple", intmultiple
, 0);
1080 set_hw_io_read_buffer (me
, hw_rv_reg_read
);
1081 set_hw_io_write_buffer (me
, hw_rv_reg_write
);
1082 set_hw_ports (me
, hw_rv_ports
);
1083 rv
->next_period
= 1;
1085 /* FIXME: We only support zero or one reg and zero or one mem area. */
1086 if (hw_find_property (me
, "reg") != NULL
)
1088 reg_property_spec reg
;
1089 if (hw_find_reg_array_property (me
, "reg", 0, ®
))
1091 unsigned_word attach_address
;
1093 unsigned int attach_size
;
1095 hw_unit_address_to_attach_address (hw_parent (me
),
1100 rv
->reg_address
= attach_address
;
1101 hw_unit_size_to_attach_size (hw_parent (me
),
1104 rv
->reg_size
= attach_size
;
1105 if ((attach_address
& 3) != 0)
1106 hw_abort (me
, "register block must be 4 byte aligned");
1107 hw_attach_address (hw_parent (me
),
1109 attach_space
, attach_address
, attach_size
,
1113 hw_abort (me
, "property \"reg\" has the wrong type");
1116 dummy_prop
= hw_find_property (me
, "dummy");
1117 if (dummy_prop
!= NULL
)
1119 if (rv
->reg_size
== 0)
1120 hw_abort (me
, "dummy argument requires a \"reg\" property");
1122 if (hw_property_type (dummy_prop
) == integer_property
)
1124 uint32_t dummyfill
= hw_find_integer_property (me
, "dummy");
1125 uint8_t *dummymem
= hw_malloc (me
, rv
->reg_size
);
1126 memset (dummymem
, dummyfill
, rv
->reg_size
);
1127 rv
->dummy
= dummymem
;
1131 const char *dummyarg
= hw_find_string_property (me
, "dummy");
1132 uint8_t *dummymem
= hw_malloc (me
, rv
->reg_size
);
1133 FILE *f
= fopen (dummyarg
, "rb");
1136 hw_abort (me
, "opening dummy-file \"%s\": %s",
1137 dummyarg
, strerror (errno
));
1138 if (fread (dummymem
, 1, rv
->reg_size
, f
) != rv
->reg_size
)
1139 hw_abort (me
, "reading dummy-file \"%s\": %s",
1140 dummyarg
, strerror (errno
));
1142 rv
->dummy
= dummymem
;
1146 mbox_prop
= hw_find_property (me
, "mbox");
1147 if (mbox_prop
!= NULL
)
1149 if (hw_property_type (mbox_prop
) == integer_property
)
1151 signed_cell attach_address_sc
1152 = hw_find_integer_property (me
, "mbox");
1154 rv
->mbox_address
= (uint32_t) attach_address_sc
;
1155 hw_attach_address (hw_parent (me
),
1157 0, (uint32_t) attach_address_sc
, 4, me
);
1160 hw_abort (me
, "property \"mbox\" has the wrong type");
1163 mem_prop
= hw_find_property (me
, "mem");
1164 if (mem_prop
!= NULL
)
1166 signed_cell attach_address_sc
;
1167 signed_cell attach_size_sc
;
1169 /* Only specific names are reg_array_properties, the rest are
1170 array_properties. */
1171 if (hw_property_type (mem_prop
) == array_property
1172 && hw_property_sizeof_array (mem_prop
) == 2 * sizeof (attach_address_sc
)
1173 && hw_find_integer_array_property (me
, "mem", 0, &attach_address_sc
)
1174 && hw_find_integer_array_property (me
, "mem", 1, &attach_size_sc
))
1176 /* Unfortunate choice of types forces us to dance around a bit. */
1177 rv
->mem_address
= (uint32_t) attach_address_sc
;
1178 rv
->mem_size
= (uint32_t) attach_size_sc
;
1179 if ((attach_address_sc
& 3) != 0)
1180 hw_abort (me
, "memory block must be 4 byte aligned");
1183 hw_abort (me
, "property \"mem\" has the wrong type");
1186 hw_rv_map_ints (me
);
1188 hw_rv_init_socket (me
);
1190 /* We need an extra initialization pass, after all others currently
1191 scheduled (mostly, after the simulation events machinery has been
1192 initialized so the events we want don't get thrown out). */
1193 hw_rv_add_init (me
);
1196 /* Our root structure; see dv-* build machinery for usage. */
1198 const struct hw_descriptor dv_rv_descriptor
[] = {
1199 { RV_FAMILY_NAME
, hw_rv_finish
},