/[gxemul]/trunk/src/devices/dev_dec21143.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_dec21143.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 41 by dpavlin, Mon Oct 8 16:21:17 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_dec21143.c,v 1.28 2007/01/05 15:20:06 debug Exp $   *  $Id: dev_dec21143.c,v 1.31 2007/06/15 18:44:19 debug Exp $
29   *   *
30   *  DEC 21143 ("Tulip") ethernet controller. Implemented from Intel document   *  COMMENT: DEC 21143 "Tulip" ethernet controller
31   *  278074-001 ("21143 PC/CardBus 10/100Mb/s Ethernet LAN Controller") and by   *
32   *  reverse-engineering OpenBSD and NetBSD sources.   *  Implemented from Intel document 278074-001 ("21143 PC/CardBus 10/100Mb/s
33     *  Ethernet LAN Controller") and by reverse-engineering OpenBSD and NetBSD
34     *  sources.
35   *   *
36   *  This device emulates several sub-components:   *  This device emulates several sub-components:
37   *   *
# Line 155  int dec21143_rx(struct cpu *cpu, struct Line 157  int dec21143_rx(struct cpu *cpu, struct
157    
158                  /*  Append a 4 byte CRC:  */                  /*  Append a 4 byte CRC:  */
159                  d->cur_rx_buf_len += 4;                  d->cur_rx_buf_len += 4;
160                  d->cur_rx_buf = realloc(d->cur_rx_buf, d->cur_rx_buf_len);                  CHECK_ALLOCATION(d->cur_rx_buf = realloc(d->cur_rx_buf,
161                  if (d->cur_rx_buf == NULL) {                      d->cur_rx_buf_len));
162                          fatal("dec21143_rx(): out of memory\n");  
                         exit(1);  
                 }  
163                  /*  Well... the CRC is just zeros, for now.  */                  /*  Well... the CRC is just zeros, for now.  */
164                  memset(d->cur_rx_buf + d->cur_rx_buf_len - 4, 0, 4);                  memset(d->cur_rx_buf + d->cur_rx_buf_len - 4, 0, 4);
165    
# Line 287  int dec21143_tx(struct cpu *cpu, struct Line 287  int dec21143_tx(struct cpu *cpu, struct
287          uint64_t addr = d->cur_tx_addr, bufaddr;          uint64_t addr = d->cur_tx_addr, bufaddr;
288          unsigned char descr[16];          unsigned char descr[16];
289          uint32_t tdes0, tdes1, tdes2, tdes3;          uint32_t tdes0, tdes1, tdes2, tdes3;
290          int bufsize, buf1_size, buf2_size, i, writeback_len = 4;          int bufsize, buf1_size, buf2_size, i;
291    
292          addr &= 0x7fffffff;          addr &= 0x7fffffff;
293    
# Line 341  int dec21143_tx(struct cpu *cpu, struct Line 341  int dec21143_tx(struct cpu *cpu, struct
341    
342          /*          /*
343          fatal("{ TX (%llx): 0x%08x 0x%08x 0x%x 0x%x: buf %i bytes at 0x%x }\n",          fatal("{ TX (%llx): 0x%08x 0x%08x 0x%x 0x%x: buf %i bytes at 0x%x }\n",
344              (long long)addr, tdes0, tdes1, tdes2, tdes3, bufsize, (int)bufaddr);            (long long)addr, tdes0, tdes1, tdes2, tdes3, bufsize, (int)bufaddr);
345          */          */
346          bufaddr &= 0x7fffffff;          bufaddr &= 0x7fffffff;
347    
# Line 372  int dec21143_tx(struct cpu *cpu, struct Line 372  int dec21143_tx(struct cpu *cpu, struct
372                  if (tdes1 & TDCTL_Tx_FS) {                  if (tdes1 & TDCTL_Tx_FS) {
373                          /*  First segment. Let's allocate a new buffer:  */                          /*  First segment. Let's allocate a new buffer:  */
374                          /*  fatal("new frame }\n");  */                          /*  fatal("new frame }\n");  */
375                          d->cur_tx_buf = malloc(bufsize);  
376                            CHECK_ALLOCATION(d->cur_tx_buf = malloc(bufsize));
377                          d->cur_tx_buf_len = 0;                          d->cur_tx_buf_len = 0;
378                  } else {                  } else {
379                          /*  Not first segment. Increase the length of                          /*  Not first segment. Increase the length of
380                              the current buffer:  */                              the current buffer:  */
381                          /*  fatal("continuing last frame }\n");  */                          /*  fatal("continuing last frame }\n");  */
                         d->cur_tx_buf = realloc(d->cur_tx_buf,  
                             d->cur_tx_buf_len + bufsize);  
                 }  
382    
383                  if (d->cur_tx_buf == NULL) {                          if (d->cur_tx_buf == NULL)
384                          fatal("dec21143_tx(): out of memory\n");                                  fatal("[ dec21143: WARNING! tx: middle "
385                          exit(1);                                      "segment, but no first segment?! ]\n");
386    
387                            CHECK_ALLOCATION(d->cur_tx_buf = realloc(d->cur_tx_buf,
388                                d->cur_tx_buf_len + bufsize));
389                  }                  }
390    
391                  /*  "DMA" data from emulated physical memory into the buf:  */                  /*  "DMA" data from emulated physical memory into the buf:  */
# Line 416  int dec21143_tx(struct cpu *cpu, struct Line 417  int dec21143_tx(struct cpu *cpu, struct
417                          d->cur_tx_buf = NULL;                          d->cur_tx_buf = NULL;
418                          d->cur_tx_buf_len = 0;                          d->cur_tx_buf_len = 0;
419    
                         /*  TODO: Shouldn't the OWN bit be cleared on all  
                             kinds of segments, not just the Last?  */  
   
                         /*  We are done.  */  
                         tdes0 &= ~TDSTAT_OWN;  
                         writeback_len = 1;  
   
420                          /*  Interrupt, if Tx_IC is set:  */                          /*  Interrupt, if Tx_IC is set:  */
421                          if (tdes1 & TDCTL_Tx_IC)                          if (tdes1 & TDCTL_Tx_IC)
422                                  d->reg[CSR_STATUS/8] |= STATUS_TI;                                  d->reg[CSR_STATUS/8] |= STATUS_TI;
423                  }                  }
424    
425                    /*  We are done with this segment.  */
426                    tdes0 &= ~TDSTAT_OWN;
427          }          }
428    
429          /*  Error summary:  */          /*  Error summary:  */
# Line 437  int dec21143_tx(struct cpu *cpu, struct Line 434  int dec21143_tx(struct cpu *cpu, struct
434          /*  Descriptor writeback:  */          /*  Descriptor writeback:  */
435          descr[ 0] = tdes0;       descr[ 1] = tdes0 >> 8;          descr[ 0] = tdes0;       descr[ 1] = tdes0 >> 8;
436          descr[ 2] = tdes0 >> 16; descr[ 3] = tdes0 >> 24;          descr[ 2] = tdes0 >> 16; descr[ 3] = tdes0 >> 24;
437          if (writeback_len > 1) {          descr[ 4] = tdes1;       descr[ 5] = tdes1 >> 8;
438                  descr[ 4] = tdes1;       descr[ 5] = tdes1 >> 8;          descr[ 6] = tdes1 >> 16; descr[ 7] = tdes1 >> 24;
439                  descr[ 6] = tdes1 >> 16; descr[ 7] = tdes1 >> 24;          descr[ 8] = tdes2;       descr[ 9] = tdes2 >> 8;
440                  descr[ 8] = tdes2;       descr[ 9] = tdes2 >> 8;          descr[10] = tdes2 >> 16; descr[11] = tdes2 >> 24;
441                  descr[10] = tdes2 >> 16; descr[11] = tdes2 >> 24;          descr[12] = tdes3;       descr[13] = tdes3 >> 8;
442                  descr[12] = tdes3;       descr[13] = tdes3 >> 8;          descr[14] = tdes3 >> 16; descr[15] = tdes3 >> 24;
                 descr[14] = tdes3 >> 16; descr[15] = tdes3 >> 24;  
         }  
443    
444          if (!cpu->memory_rw(cpu, cpu->mem, addr, descr, sizeof(uint32_t)          if (!cpu->memory_rw(cpu, cpu->mem, addr, descr, sizeof(uint32_t)
445              * writeback_len, MEM_WRITE, PHYSICAL | NO_EXCEPTIONS)) {              * 4, MEM_WRITE, PHYSICAL | NO_EXCEPTIONS)) {
446                  fatal("[ dec21143_tx: memory_rw failed! ]\n");                  fatal("[ dec21143_tx: memory_rw failed! ]\n");
447                  return 0;                  return 0;
448          }          }
# Line 456  int dec21143_tx(struct cpu *cpu, struct Line 451  int dec21143_tx(struct cpu *cpu, struct
451  }  }
452    
453    
454  /*  DEVICE_TICK(dec21143)
  *  dev_dec21143_tick():  
  */  
 void dev_dec21143_tick(struct cpu *cpu, void *extra)  
455  {  {
456          struct dec21143_data *d = extra;          struct dec21143_data *d = extra;
457          int asserted;          int asserted;
# Line 987  DEVINIT(dec21143) Line 979  DEVINIT(dec21143)
979          struct dec21143_data *d;          struct dec21143_data *d;
980          char name2[100];          char name2[100];
981    
982          d = malloc(sizeof(struct dec21143_data));          CHECK_ALLOCATION(d = malloc(sizeof(struct dec21143_data)));
         if (d == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
983          memset(d, 0, sizeof(struct dec21143_data));          memset(d, 0, sizeof(struct dec21143_data));
984    
985          INTERRUPT_CONNECT(devinit->interrupt_path, d->irq);          INTERRUPT_CONNECT(devinit->interrupt_path, d->irq);
# Line 1011  DEVINIT(dec21143) Line 999  DEVINIT(dec21143)
999              devinit->addr, 0x100, dev_dec21143_access, d, DM_DEFAULT, NULL);              devinit->addr, 0x100, dev_dec21143_access, d, DM_DEFAULT, NULL);
1000    
1001          machine_add_tickfunction(devinit->machine,          machine_add_tickfunction(devinit->machine,
1002              dev_dec21143_tick, d, DEC21143_TICK_SHIFT, 0.0);              dev_dec21143_tick, d, DEC21143_TICK_SHIFT);
1003    
1004          /*          /*
1005           *  NetBSD/cats uses memory accesses, OpenBSD/cats uses I/O registers.           *  NetBSD/cats uses memory accesses, OpenBSD/cats uses I/O registers.

Legend:
Removed from v.41  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26