OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [cris/] [dv-rv.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* The remote-virtual-component simulator framework
2
   for GDB, the GNU Debugger.
3
 
4
   Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
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 3 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, see <http://www.gnu.org/licenses/>.  */
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
 
297
enum 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
 
309
typedef 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.  */
383
enum
384
  {
385
    INT_PORT
386
  };
387
 
388
/* Our ports.  */
389
static 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
 
397
static void
398
hw_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.  */
407
  if (rv->fd < 0)
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
 
427
static void
428
hw_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
 
458
static void
459
hw_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
 
492
static void
493
hw_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
 
546
static void
547
hw_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
 
597
static void
598
hw_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
 
625
static void
626
hw_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
 
640
      if (rv->fd < 0)
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
 
700
static void
701
hw_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
 
716
static void
717
hw_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
 
726
  if (rv->fd < 0)
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
 
753
static void
754
hw_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
 
780
static void
781
do_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
 
801
static void
802
hw_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.  */
825
struct sim_hw { struct hw *tree; };
826
 
827
static SIM_RC
828
hw_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
 
845
static void
846
hw_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
 
853
static void
854
hw_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
 
890
  if (sock < 0)
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
 
911
static unsigned int
912
hw_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
 
953
static void
954
hw_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
 
1012
static unsigned int
1013
hw_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
 
1065
static void
1066
hw_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
 
1216
const struct hw_descriptor dv_rv_descriptor[] = {
1217
  { RV_FAMILY_NAME, hw_rv_finish },
1218
  { NULL }
1219
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.