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