dev_le.cc Source File

Back to the index.

dev_le.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2009 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: LANCE ethernet, as used in DECstations
29  *
30  * This is based on "PMAD-AA TURBOchannel Ethernet Module Functional
31  * Specification". I've tried to keep symbol names in this file to what
32  * the specs use.
33  *
34  * This is what the memory layout looks like on a DECstation 5000/200:
35  *
36  * 0x000000 - 0x0fffff Ethernet SRAM buffer (should be 128KB)
37  * 0x100000 - 0x17ffff LANCE registers
38  * 0x1c0000 - 0x1fffff Ethernet Diagnostic ROM and Station
39  * Address ROM
40  *
41  * The length of the device is set to 0x1c0200, however, because Sprite
42  * tries to read TURBOchannel rom data from 0x1c03f0, and that is provided
43  * by the turbochannel device, not this device.
44  *
45  *
46  * TODO: Error conditions (such as when there are not enough receive
47  * buffers) are not emulated yet.
48  *
49  * (Old bug, but probably still valid: "UDP packets that are too
50  * large are not handled well by the Lance device.")
51  */
52 
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 
57 #include "cpu.h"
58 #include "devices.h"
59 #include "emul.h"
60 #include "machine.h"
61 #include "memory.h"
62 #include "misc.h"
63 #include "net.h"
64 
65 #include "thirdparty/if_lereg.h"
66 
67 
68 #define LE_TICK_SHIFT 14
69 
70 /* #define LE_DEBUG */
71 /* #define debug fatal */
72 
73 extern int quiet_mode;
74 
75 #define LE_MODE_LOOP 4
76 #define LE_MODE_DTX 2
77 #define LE_MODE_DRX 1
78 
79 
80 #define N_REGISTERS 4
81 #define SRAM_SIZE (128*1024)
82 #define ROM_SIZE 32
83 
84 
85 struct le_data {
86  struct interrupt irq;
88 
89  uint64_t buf_start;
90  uint64_t buf_end;
91  int len;
92 
93  uint8_t rom[ROM_SIZE];
94 
96  uint16_t reg[N_REGISTERS];
97 
98  unsigned char *sram;
99 
100  /* Initialization block: */
101  uint32_t init_block_addr;
102 
103  uint16_t mode;
104  uint64_t padr; /* MAC address */
105  uint64_t ladrf;
106  uint32_t rdra; /* receive descriptor ring address */
107  int rlen; /* nr of rx descriptors */
108  uint32_t tdra; /* transmit descriptor ring address */
109  int tlen; /* nr ot tx descriptors */
110 
111  /* Current rx and tx descriptor indices: */
112  int rxp;
113  int txp;
114 
115  unsigned char *tx_packet;
117 
118  unsigned char *rx_packet;
122 };
123 
124 
125 /*
126  * le_read_16bit():
127  *
128  * Read a 16-bit word from the SRAM.
129  */
130 static uint64_t le_read_16bit(struct le_data *d, int addr)
131 {
132  /* TODO: This is for little endian only */
133  int x = d->sram[addr & (SRAM_SIZE-1)] +
134  (d->sram[(addr+1) & (SRAM_SIZE-1)] << 8);
135  return x;
136 }
137 
138 
139 /*
140  * le_write_16bit():
141  *
142  * Write a 16-bit word to the SRAM.
143  */
144 static void le_write_16bit(struct le_data *d, int addr, uint16_t x)
145 {
146  /* TODO: This is for little endian only */
147  d->sram[addr & (SRAM_SIZE-1)] = x & 0xff;
148  d->sram[(addr+1) & (SRAM_SIZE-1)] = (x >> 8) & 0xff;
149 }
150 
151 
152 /*
153  * le_chip_init():
154  *
155  * Initialize data structures by reading an 'initialization block' from the
156  * SRAM.
157  */
158 static void le_chip_init(struct le_data *d)
159 {
160  d->init_block_addr = (d->reg[1] & 0xffff) + ((d->reg[2] & 0xff) << 16);
161  if (d->init_block_addr & 1)
162  fatal("[ le: WARNING! initialization block address "
163  "not word aligned? ]\n");
164 
165  debug("[ le: d->init_block_addr = 0x%06x ]\n", d->init_block_addr);
166 
167  d->mode = le_read_16bit(d, d->init_block_addr + 0);
168  d->padr = le_read_16bit(d, d->init_block_addr + 2);
169  d->padr += (le_read_16bit(d, d->init_block_addr + 4) << 16);
170  d->padr += (le_read_16bit(d, d->init_block_addr + 6) << 32);
171  d->ladrf = le_read_16bit(d, d->init_block_addr + 8);
172  d->ladrf += (le_read_16bit(d, d->init_block_addr + 10) << 16);
173  d->ladrf += (le_read_16bit(d, d->init_block_addr + 12) << 32);
174  d->ladrf += (le_read_16bit(d, d->init_block_addr + 14) << 48);
175  d->rdra = le_read_16bit(d, d->init_block_addr + 16);
176  d->rdra += ((le_read_16bit(d, d->init_block_addr + 18) & 0xff) << 16);
177  d->rlen = 1 << ((le_read_16bit(d, d->init_block_addr + 18) >> 13) & 7);
178  d->tdra = le_read_16bit(d, d->init_block_addr + 20);
179  d->tdra += ((le_read_16bit(d, d->init_block_addr + 22) & 0xff) << 16);
180  d->tlen = 1 << ((le_read_16bit(d, d->init_block_addr + 22) >> 13) & 7);
181 
182  debug("[ le: DEBUG: mode %04x ]\n", d->mode);
183  debug("[ le: DEBUG: padr %016llx ]\n", (long long)d->padr);
184  debug("[ le: DEBUG: ladrf %016llx ]\n", (long long)d->ladrf);
185  debug("[ le: DEBUG: rdra %06llx ]\n", d->rdra);
186  debug("[ le: DEBUG: rlen %3i ]\n", d->rlen);
187  debug("[ le: DEBUG: tdra %06llx ]\n", d->tdra);
188  debug("[ le: DEBUG: tlen %3i ]\n", d->tlen);
189 
190  /* Set TXON and RXON, unless they are disabled by 'mode': */
191  if (d->mode & LE_MODE_DTX)
192  d->reg[0] &= ~LE_TXON;
193  else
194  d->reg[0] |= LE_TXON;
195 
196  if (d->mode & LE_MODE_DRX)
197  d->reg[0] &= ~LE_RXON;
198  else
199  d->reg[0] |= LE_RXON;
200 
201  /* Go to the start of the descriptor rings: */
202  d->rxp = d->txp = 0;
203 
204  /* Set IDON and reset the INIT bit when we are done. */
205  d->reg[0] |= LE_IDON;
206  d->reg[0] &= ~LE_INIT;
207 
208  /* Free any old packets: */
209  if (d->tx_packet != NULL)
210  free(d->tx_packet);
211  d->tx_packet = NULL;
212  d->tx_packet_len = 0;
213 
214  if (d->rx_packet != NULL)
215  free(d->rx_packet);
216  d->rx_packet = NULL;
217  d->rx_packet_len = 0;
218  d->rx_packet_offset = 0;
219  d->rx_middle_bit = 0;
220 }
221 
222 
223 /*
224  * le_tx():
225  *
226  * Check the transmitter descriptor ring for buffers that are owned by the
227  * Lance chip (that is, buffers that are to be transmitted).
228  *
229  * This routine should only be called if TXON is enabled.
230  */
231 static void le_tx(struct net *net, struct le_data *d)
232 {
233  int start_txp = d->txp;
234  uint16_t tx_descr[4];
235  int stp, enp, cur_packet_offset;
236  size_t i;
237  uint32_t bufaddr, buflen;
238 
239  /* TODO: This is just a guess: */
240  d->reg[0] &= ~LE_TDMD;
241 
242  do {
243  /* Load the 8 descriptor bytes: */
244  tx_descr[0] = le_read_16bit(d, d->tdra + d->txp*8 + 0);
245  tx_descr[1] = le_read_16bit(d, d->tdra + d->txp*8 + 2);
246  tx_descr[2] = le_read_16bit(d, d->tdra + d->txp*8 + 4);
247  tx_descr[3] = le_read_16bit(d, d->tdra + d->txp*8 + 6);
248 
249  bufaddr = tx_descr[0] + ((tx_descr[1] & 0xff) << 16);
250  stp = tx_descr[1] & LE_STP? 1 : 0;
251  enp = tx_descr[1] & LE_ENP? 1 : 0;
252  buflen = 4096 - (tx_descr[2] & 0xfff);
253 
254  /*
255  * Check the OWN bit. If it is zero, then this buffer is
256  * not ready to be transmitted yet. Also check the '1111'
257  * mark, and make sure that byte-count is reasonable.
258  */
259  if (!(tx_descr[1] & LE_OWN))
260  return;
261  if ((tx_descr[2] & 0xf000) != 0xf000)
262  return;
263  if (buflen < 12 || buflen > 1900) {
264  fatal("[ le_tx(): buflen = %i ]\n", buflen);
265  return;
266  }
267 
268  debug("[ le_tx(): descr %3i DUMP: 0x%04x 0x%04x 0x%04x 0x%04x "
269  "=> addr=0x%06x, len=%i bytes, STP=%i ENP=%i ]\n", d->txp,
270  tx_descr[0], tx_descr[1], tx_descr[2], tx_descr[3],
271  bufaddr, buflen, stp, enp);
272 
273  if (d->tx_packet == NULL && !stp) {
274  fatal("[ le_tx(): !stp but tx_packet == NULL ]\n");
275  return;
276  }
277 
278  if (d->tx_packet != NULL && stp) {
279  fatal("[ le_tx(): stp but tx_packet != NULL ]\n");
280  free(d->tx_packet);
281  d->tx_packet = NULL;
282  d->tx_packet_len = 0;
283  }
284 
285  /* Where to write to in the tx_packet: */
286  cur_packet_offset = d->tx_packet_len;
287 
288  /* Start of a new packet: */
289  if (stp) {
290  d->tx_packet_len = buflen;
291  CHECK_ALLOCATION(d->tx_packet = (unsigned char *) malloc(buflen));
292  } else {
293  d->tx_packet_len += buflen;
294  CHECK_ALLOCATION(d->tx_packet = (unsigned char *)
295  realloc(d->tx_packet, d->tx_packet_len));
296  }
297 
298  /* Copy data from SRAM into the tx packet: */
299  for (i=0; i<buflen; i++) {
300  unsigned char ch;
301  ch = d->sram[(bufaddr + i) & (SRAM_SIZE-1)];
302  d->tx_packet[cur_packet_offset + i] = ch;
303  }
304 
305  /*
306  * Is this the last buffer in a packet? Then transmit
307  * it, cause an interrupt, and free the memory used by
308  * the packet.
309  */
310  if (enp) {
311  net_ethernet_tx(net, d, d->tx_packet, d->tx_packet_len);
312 
313  free(d->tx_packet);
314  d->tx_packet = NULL;
315  d->tx_packet_len = 0;
316 
317  d->reg[0] |= LE_TINT;
318  }
319 
320  /* Clear the OWN bit: */
321  tx_descr[1] &= ~LE_OWN;
322 
323  /* Write back the descriptor to SRAM: */
324  le_write_16bit(d, d->tdra + d->txp*8 + 2, tx_descr[1]);
325  le_write_16bit(d, d->tdra + d->txp*8 + 4, tx_descr[2]);
326  le_write_16bit(d, d->tdra + d->txp*8 + 6, tx_descr[3]);
327 
328  /* Go to the next descriptor: */
329  d->txp ++;
330  if (d->txp >= d->tlen)
331  d->txp = 0;
332  } while (d->txp != start_txp);
333 
334  /* We are here if all descriptors were taken care of. */
335  fatal("[ le_tx(): all TX descriptors used up? ]\n");
336 }
337 
338 
339 /*
340  * le_rx():
341  *
342  * This routine should only be called if RXON is enabled.
343  */
344 static void le_rx(struct net *net, struct le_data *d)
345 {
346  int start_rxp = d->rxp;
347  size_t i;
348  uint16_t rx_descr[4];
349  uint32_t bufaddr, buflen;
350 
351  do {
352  if (d->rx_packet == NULL)
353  return;
354 
355  /* Load the 8 descriptor bytes: */
356  rx_descr[0] = le_read_16bit(d, d->rdra + d->rxp*8 + 0);
357  rx_descr[1] = le_read_16bit(d, d->rdra + d->rxp*8 + 2);
358  rx_descr[2] = le_read_16bit(d, d->rdra + d->rxp*8 + 4);
359  rx_descr[3] = le_read_16bit(d, d->rdra + d->rxp*8 + 6);
360 
361  bufaddr = rx_descr[0] + ((rx_descr[1] & 0xff) << 16);
362  buflen = 4096 - (rx_descr[2] & 0xfff);
363 
364  /*
365  * Check the OWN bit. If it is zero, then this buffer is
366  * not ready to receive data yet. Also check the '1111'
367  * mark, and make sure that byte-count is reasonable.
368  */
369  if (!(rx_descr[1] & LE_OWN))
370  return;
371  if ((rx_descr[2] & 0xf000) != 0xf000)
372  return;
373  if (buflen < 12 || buflen > 1900) {
374  fatal("[ le_rx(): buflen = %i ]\n", buflen);
375  return;
376  }
377 
378  debug("[ le_rx(): descr %3i DUMP: 0x%04x 0x%04x 0x%04x 0x%04x "
379  "=> addr=0x%06x, len=%i bytes ]\n", d->rxp,
380  rx_descr[0], rx_descr[1], rx_descr[2], rx_descr[3],
381  bufaddr, buflen);
382 
383  /* Copy data from the packet into SRAM: */
384  for (i=0; i<buflen; i++) {
385  if (d->rx_packet_offset+(ssize_t)i >= d->rx_packet_len)
386  break;
387  d->sram[(bufaddr + i) & (SRAM_SIZE-1)] =
388  d->rx_packet[d->rx_packet_offset + i];
389  }
390 
391  /* Here, i is the number of bytes copied. */
392  d->rx_packet_offset += i;
393 
394  /* Set the ENP bit if this was the end of a packet: */
395  if (d->rx_packet_offset >= d->rx_packet_len) {
396  rx_descr[1] |= LE_ENP;
397 
398  /*
399  * NOTE: The Lance documentation that I have read
400  * says _NOTHING_ about the length being 4 more than
401  * the length of the data. You can guess how
402  * surprised I was when I saw the following in
403  * NetBSD (dev/ic/am7990.c):
404  *
405  * lance_read(sc, LE_RBUFADDR(sc, bix),
406  * (int)rmd.rmd3 - 4);
407  */
408  rx_descr[3] &= ~0xfff;
409  rx_descr[3] |= d->rx_packet_len + 4;
410 
411  free(d->rx_packet);
412  d->rx_packet = NULL;
413  d->rx_packet_len = 0;
414  d->rx_packet_offset = 0;
415  d->rx_middle_bit = 0;
416 
417  d->reg[0] |= LE_RINT;
418  }
419 
420  /* Set the STP bit if this was the start of a packet: */
421  if (!d->rx_middle_bit) {
422  rx_descr[1] |= LE_STP;
423 
424  /* Are we continuing on this packet? */
425  if (d->rx_packet != NULL)
426  d->rx_middle_bit = 1;
427  }
428 
429  /* Clear the OWN bit: */
430  rx_descr[1] &= ~LE_OWN;
431 
432  /* Write back the descriptor to SRAM: */
433  le_write_16bit(d, d->rdra + d->rxp*8 + 2, rx_descr[1]);
434  le_write_16bit(d, d->rdra + d->rxp*8 + 4, rx_descr[2]);
435  le_write_16bit(d, d->rdra + d->rxp*8 + 6, rx_descr[3]);
436 
437  /* Go to the next descriptor: */
438  d->rxp ++;
439  if (d->rxp >= d->rlen)
440  d->rxp = 0;
441  } while (d->rxp != start_rxp);
442 
443  /* We are here if all descriptors were taken care of. */
444  fatal("[ le_rx(): all RX descriptors used up? ]\n");
445 }
446 
447 
448 /*
449  * le_register_fix():
450  */
451 static void le_register_fix(struct net *net, struct le_data *d)
452 {
453  /* Init with new Initialization block, if needed. */
454  if (d->reg[0] & LE_INIT)
455  le_chip_init(d);
456 
457 #ifdef LE_DEBUG
458  {
459  static int x = 1234;
460  if (x != d->reg[0]) {
461  debug("[ le reg[0] = 0x%04x ]\n", d->reg[0]);
462  x = d->reg[0];
463  }
464  }
465 #endif
466 
467  /*
468  * If the receiver is on:
469  * If there is a current rx_packet, try to receive it into the
470  * Lance buffers. Then try to receive any additional packets.
471  */
472  if (d->reg[0] & LE_RXON) {
473  do {
474  if (d->rx_packet != NULL)
475  /* Try to receive the packet: */
476  le_rx(net, d);
477 
478  if (d->rx_packet != NULL)
479  /* If the packet wasn't fully received,
480  then abort for now. */
481  break;
482 
483  if (d->rx_packet == NULL &&
484  net_ethernet_rx_avail(net, d))
485  net_ethernet_rx(net, d,
486  &d->rx_packet, &d->rx_packet_len);
487  } while (d->rx_packet != NULL);
488  }
489 
490  /* If the transmitter is on, check for outgoing buffers: */
491  if (d->reg[0] & LE_TXON)
492  le_tx(net, d);
493 
494  /* SERR should be the OR of BABL, CERR, MISS, and MERR: */
495  d->reg[0] &= ~LE_SERR;
496  if (d->reg[0] & (LE_BABL | LE_CERR | LE_MISS | LE_MERR))
497  d->reg[0] |= LE_SERR;
498 
499  /* INTR should be the OR of BABL, MISS, MERR, RINT, TINT, IDON: */
500  d->reg[0] &= ~LE_INTR;
501  if (d->reg[0] & (LE_BABL | LE_MISS | LE_MERR | LE_RINT |
502  LE_TINT | LE_IDON))
503  d->reg[0] |= LE_INTR;
504 
505  /* The MERR bit clears some bits: */
506  if (d->reg[0] & LE_MERR)
507  d->reg[0] &= ~(LE_RXON | LE_TXON);
508 
509  /* The STOP bit clears a lot of stuff: */
510 #if 0
511  /* According to the LANCE manual: (doesn't work with Ultrix) */
512  if (d->reg[0] & LE_STOP)
513  d->reg[0] &= ~(LE_SERR | LE_BABL | LE_CERR | LE_MISS | LE_MERR
515  | LE_RXON | LE_TXON | LE_TDMD);
516 #else
517  /* Works with Ultrix: */
518  if (d->reg[0] & LE_STOP)
519  d->reg[0] &= ~(LE_IDON);
520 #endif
521 }
522 
523 
525 {
526  struct le_data *d = (struct le_data *) extra;
527  int new_assert;
528 
529  le_register_fix(cpu->machine->emul->net, d);
530 
531  new_assert = (d->reg[0] & LE_INTR) && (d->reg[0] & LE_INEA);
532 
533  if (new_assert && !d->irq_asserted)
534  INTERRUPT_ASSERT(d->irq);
535  if (d->irq_asserted && !new_assert)
537 
538  d->irq_asserted = new_assert;
539 }
540 
541 
542 /*
543  * le_register_write():
544  *
545  * This function is called when the value 'x' is written to register 'r'.
546  */
547 void le_register_write(struct le_data *d, int r, uint32_t x)
548 {
549  switch (r) {
550  case 0: /* CSR0: */
551  /* Some bits are write-one-to-clear: */
552  if (x & LE_BABL)
553  d->reg[r] &= ~LE_BABL;
554  if (x & LE_CERR)
555  d->reg[r] &= ~LE_CERR;
556  if (x & LE_MISS)
557  d->reg[r] &= ~LE_MISS;
558  if (x & LE_MERR)
559  d->reg[r] &= ~LE_MERR;
560  if (x & LE_RINT)
561  d->reg[r] &= ~LE_RINT;
562  if (x & LE_TINT)
563  d->reg[r] &= ~LE_TINT;
564  if (x & LE_IDON)
565  d->reg[r] &= ~LE_IDON;
566 
567  /* Some bits are write-only settable, not clearable: */
568  if (x & LE_TDMD)
569  d->reg[r] |= LE_TDMD;
570  if (x & LE_STRT) {
571  d->reg[r] |= LE_STRT;
572  d->reg[r] &= ~LE_STOP;
573  }
574  if (x & LE_INIT) {
575  if (!(d->reg[r] & LE_STOP))
576  fatal("[ le: attempt to INIT before"
577  " STOPped! ]\n");
578  d->reg[r] |= LE_INIT;
579  d->reg[r] &= ~LE_STOP;
580  }
581  if (x & LE_STOP) {
582  d->reg[r] |= LE_STOP;
583  /* STOP takes precedence over STRT and INIT: */
584  d->reg[r] &= ~(LE_STRT | LE_INIT);
585  }
586 
587  /* Some bits get through, both settable and clearable: */
588  d->reg[r] &= ~LE_INEA;
589  d->reg[r] |= (x & LE_INEA);
590  break;
591 
592  default:
593  /* CSR1, CSR2, and CSR3: */
594  d->reg[r] = x;
595  }
596 }
597 
598 
600 {
601  struct le_data *d = (struct le_data *) extra;
602  size_t i;
603  int retval;
604 
605 #ifdef LE_DEBUG
606  if (writeflag == MEM_WRITE) {
607  fatal("[ le_sram: write to addr 0x%06x: ", (int)relative_addr);
608  for (i=0; i<len; i++)
609  fatal("%02x ", data[i]);
610  fatal("]\n");
611  }
612 #endif
613 
614  /* Read/write of the SRAM: */
615  if (relative_addr < SRAM_SIZE && relative_addr + len <= SRAM_SIZE) {
616  if (writeflag == MEM_READ) {
617  memcpy(data, d->sram + relative_addr, len);
618  if (!quiet_mode) {
619  debug("[ le: read from SRAM offset 0x%05x:",
620  relative_addr);
621  for (i=0; i<len; i++)
622  debug(" %02x", data[i]);
623  debug(" ]\n");
624  }
625  retval = 9; /* 9 cycles */
626  } else {
627  memcpy(d->sram + relative_addr, data, len);
628  if (!quiet_mode) {
629  debug("[ le: write to SRAM offset 0x%05x:",
630  relative_addr);
631  for (i=0; i<len; i++)
632  debug(" %02x", data[i]);
633  debug(" ]\n");
634  }
635  retval = 6; /* 6 cycles */
636  }
637  return retval;
638  }
639 
640  return 0;
641 }
642 
643 
645 {
646  struct le_data *d = (struct le_data *) extra;
647  uint64_t idata = 0, odata = 0;
648  int retval = 1;
649  size_t i;
650 
651  if (writeflag == MEM_WRITE)
652  idata = memory_readmax64(cpu, data, len);
653 
654 #ifdef LE_DEBUG
655  if (writeflag == MEM_WRITE) {
656  fatal("[ le: write to addr 0x%06x: ", (int)relative_addr);
657  for (i=0; i<len; i++)
658  fatal("%02x ", data[i]);
659  fatal("]\n");
660  }
661 #endif
662 
663  /* Read from station's ROM (ethernet address): */
664  if (relative_addr >= 0xc0000 && relative_addr <= 0xfffff) {
665  uint32_t a;
666  int j = (relative_addr & 0xff) / 4;
667  a = d->rom[j & (ROM_SIZE-1)];
668 
669  if (writeflag == MEM_READ) {
670  odata = (a << 24) + (a << 16) + (a << 8) + a;
671  } else {
672  fatal("[ le: WRITE to ethernet addr (%08lx):",
673  (long)relative_addr);
674  for (i=0; i<len; i++)
675  fatal(" %02x", data[i]);
676  fatal(" ]\n");
677  }
678 
679  retval = 13; /* 13 cycles */
680  goto do_return;
681  }
682 
683 
684  switch (relative_addr) {
685 
686  /* Register read/write: */
687  case 0:
688  if (writeflag==MEM_READ) {
689  odata = d->reg[d->reg_select];
690  if (!quiet_mode)
691  debug("[ le: read from register 0x%02x: 0x"
692  "%02x ]\n", d->reg_select, (int)odata);
693  /*
694  * A read from csr1..3 should return "undefined"
695  * result if the stop bit is set. However, Ultrix
696  * seems to do just that, so let's _not_ print
697  * a warning here.
698  */
699  } else {
700  if (!quiet_mode)
701  debug("[ le: write to register 0x%02x: 0x"
702  "%02x ]\n", d->reg_select, (int)idata);
703  /*
704  * A write to from csr1..3 when the stop bit is
705  * set should be ignored. However, Ultrix writes
706  * even if the stop bit is set, so let's _not_
707  * print a warning about it.
708  */
709  le_register_write(d, d->reg_select, idata);
710  }
711  break;
712 
713  /* Register select: */
714  case 4:
715  if (writeflag==MEM_READ) {
716  odata = d->reg_select;
717  if (!quiet_mode)
718  debug("[ le: read from register select: "
719  "0x%02x ]\n", (int)odata);
720  } else {
721  if (!quiet_mode)
722  debug("[ le: write to register select: "
723  "0x%02x ]\n", (int)idata);
724  d->reg_select = idata & (N_REGISTERS - 1);
725  if (idata >= N_REGISTERS)
726  fatal("[ le: WARNING! register select %i "
727  "(max is %i) ]\n", idata, N_REGISTERS - 1);
728  }
729  break;
730 
731  default:
732  if (writeflag==MEM_READ) {
733  fatal("[ le: read from UNIMPLEMENTED addr 0x%06x ]\n",
734  (int)relative_addr);
735  } else {
736  fatal("[ le: write to UNIMPLEMENTED addr 0x%06x: "
737  "0x%08x ]\n", (int)relative_addr, (int)idata);
738  }
739  }
740 
741 do_return:
742  if (writeflag == MEM_READ) {
743  memory_writemax64(cpu, data, len, odata);
744 #ifdef LE_DEBUG
745  fatal("[ le: read from addr 0x%06x: 0x%08x ]\n",
746  relative_addr, odata);
747 #endif
748  }
749 
750  dev_le_tick(cpu, extra);
751 
752  return retval;
753 }
754 
755 
756 /*
757  * dev_le_init():
758  */
759 void dev_le_init(struct machine *machine, struct memory *mem, uint64_t baseaddr,
760  uint64_t buf_start, uint64_t buf_end, const char *irq_path, int len)
761 {
762  char *name2;
763  size_t nlen = 55;
764  struct le_data *d;
765 
766  CHECK_ALLOCATION(d = (struct le_data *) malloc(sizeof(struct le_data)));
767  memset(d, 0, sizeof(struct le_data));
768 
769  INTERRUPT_CONNECT(irq_path, d->irq);
770 
771  CHECK_ALLOCATION(d->sram = (unsigned char *) malloc(SRAM_SIZE));
772  memset(d->sram, 0, SRAM_SIZE);
773 
774  /* TODO: Are these actually used yet? */
775  d->len = len;
776  d->buf_start = buf_start;
777  d->buf_end = buf_end;
778 
779  /* Initial register contents: */
780  d->reg[0] = LE_STOP;
781 
782  d->tx_packet = NULL;
783  d->rx_packet = NULL;
784 
785  /* ROM (including the MAC address): */
786  net_generate_unique_mac(machine, &d->rom[0]);
787 
788  /* Copies of the MAC address and a test pattern: */
789  d->rom[10] = d->rom[21] = d->rom[5];
790  d->rom[11] = d->rom[20] = d->rom[4];
791  d->rom[12] = d->rom[19] = d->rom[3];
792  d->rom[7] = d->rom[8] = d->rom[23] =
793  d->rom[13] = d->rom[18] = d->rom[2];
794  d->rom[6] = d->rom[9] = d->rom[22] =
795  d->rom[14] = d->rom[17] = d->rom[1];
796  d->rom[15] = d->rom[16] = d->rom[0];
797  d->rom[24] = d->rom[28] = 0xff;
798  d->rom[25] = d->rom[29] = 0x00;
799  d->rom[26] = d->rom[30] = 0x55;
800  d->rom[27] = d->rom[31] = 0xaa;
801 
802  memory_device_register(mem, "le_sram", baseaddr,
803  SRAM_SIZE, dev_le_sram_access, (void *)d,
805  | DM_READS_HAVE_NO_SIDE_EFFECTS, d->sram);
806 
807  CHECK_ALLOCATION(name2 = (char *) malloc(nlen));
808  snprintf(name2, nlen, "le [%02x:%02x:%02x:%02x:%02x:%02x]",
809  d->rom[0], d->rom[1], d->rom[2], d->rom[3], d->rom[4], d->rom[5]);
810 
811  memory_device_register(mem, name2, baseaddr + 0x100000,
812  len - 0x100000, dev_le_access, (void *)d, DM_DEFAULT, NULL);
813 
814  machine_add_tickfunction(machine, dev_le_tick, d, LE_TICK_SHIFT);
815 
816  net_add_nic(machine->emul->net, d, &d->rom[0]);
817 }
818 
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition: memory.cc:55
void net_ethernet_tx(struct net *net, void *extra, unsigned char *packet, int len)
Definition: net.cc:371
void fatal(const char *fmt,...)
Definition: main.cc:152
int txp
Definition: dev_le.cc:113
#define LE_INEA
Definition: if_lereg.h:359
#define DM_DEFAULT
Definition: memory.h:130
#define LE_SERR
Definition: if_lereg.h:350
int rx_middle_bit
Definition: dev_le.cc:121
#define LE_OWN
Definition: if_lereg.h:374
#define LE_RXON
Definition: if_lereg.h:360
int tx_packet_len
Definition: dev_le.cc:116
uint32_t init_block_addr
Definition: dev_le.cc:101
int quiet_mode
Definition: main.cc:78
int dev_le_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
struct machine * machine
Definition: cpu.h:328
#define MEM_READ
Definition: memory.h:116
#define LE_IDON
Definition: if_lereg.h:357
void le_register_write(struct le_data *d, int r, uint32_t x)
Definition: dev_le.cc:547
#define LE_STOP
Definition: if_lereg.h:363
int len
Definition: dev_le.cc:91
unsigned char * sram
Definition: dev_le.cc:98
void dev_le_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, uint64_t buf_start, uint64_t buf_end, const char *irq_path, int len)
Definition: dev_le.cc:759
#define LE_ENP
Definition: if_lereg.h:377
int tlen
Definition: dev_le.cc:109
#define LE_STRT
Definition: if_lereg.h:364
uint16_t mode
Definition: dev_le.cc:103
int net_ethernet_rx(struct net *net, void *extra, unsigned char **packetp, int *lenp)
Definition: net.cc:316
struct emul * emul
Definition: machine.h:99
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239
struct interrupt irq
Definition: dev_le.cc:86
#define LE_MISS
Definition: if_lereg.h:353
#define N_REGISTERS
Definition: dev_le.cc:80
#define LE_TICK_SHIFT
Definition: dev_le.cc:68
void net_add_nic(struct net *net, void *extra, unsigned char *macaddr)
Definition: net.cc:598
DEVICE_TICK(le)
Definition: dev_le.cc:524
int irq_asserted
Definition: dev_le.cc:87
int rlen
Definition: dev_le.cc:107
#define DM_READS_HAVE_NO_SIDE_EFFECTS
Definition: memory.h:133
u_short data
Definition: siireg.h:79
#define ROM_SIZE
Definition: dev_le.cc:82
uint64_t buf_end
Definition: dev_le.cc:90
uint64_t ladrf
Definition: dev_le.cc:105
Definition: net.h:119
#define INTERRUPT_ASSERT(istruct)
Definition: interrupt.h:74
#define DM_DYNTRANS_WRITE_OK
Definition: memory.h:132
void net_generate_unique_mac(struct machine *, unsigned char *macbuf)
Definition: net_misc.cc:88
uint8_t rom[ROM_SIZE]
Definition: dev_le.cc:93
#define MEM_WRITE
Definition: memory.h:117
#define LE_MERR
Definition: if_lereg.h:354
#define LE_TDMD
Definition: if_lereg.h:362
unsigned char * tx_packet
Definition: dev_le.cc:115
uint32_t rdra
Definition: dev_le.cc:106
int net_ethernet_rx_avail(struct net *net, void *extra)
Definition: net.cc:253
uint32_t addr
int reg_select
Definition: dev_le.cc:95
#define debug
Definition: dev_adb.cc:57
#define INTERRUPT_CONNECT(name, istruct)
Definition: interrupt.h:77
Definition: cpu.h:326
int rx_packet_offset
Definition: dev_le.cc:120
unsigned char * rx_packet
Definition: dev_le.cc:118
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition: memory.cc:89
#define SRAM_SIZE
Definition: dev_le.cc:81
#define LE_INIT
Definition: if_lereg.h:365
#define LE_MODE_DTX
Definition: dev_le.cc:76
#define LE_CERR
Definition: if_lereg.h:352
#define LE_TXON
Definition: if_lereg.h:361
DEVICE_ACCESS(le_sram)
Definition: dev_le.cc:599
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition: memory.cc:339
struct net * net
Definition: emul.h:43
#define LE_MODE_DRX
Definition: dev_le.cc:77
#define DM_DYNTRANS_OK
Definition: memory.h:131
uint32_t tdra
Definition: dev_le.cc:108
uint64_t padr
Definition: dev_le.cc:104
int rxp
Definition: dev_le.cc:112
uint64_t buf_start
Definition: dev_le.cc:89
#define LE_TINT
Definition: if_lereg.h:356
Definition: memory.h:75
void machine_add_tickfunction(struct machine *machine, void(*func)(struct cpu *, void *), void *extra, int clockshift)
Definition: machine.cc:280
#define LE_RINT
Definition: if_lereg.h:355
#define LE_INTR
Definition: if_lereg.h:358
#define LE_STP
Definition: if_lereg.h:376
#define LE_BABL
Definition: if_lereg.h:351
#define INTERRUPT_DEASSERT(istruct)
Definition: interrupt.h:75
int rx_packet_len
Definition: dev_le.cc:119
uint16_t reg[N_REGISTERS]
Definition: dev_le.cc:96

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13