/[gxemul]/trunk/src/devices/dev_le.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_le.c

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

revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_le.c,v 1.46 2005/11/13 00:14:09 debug Exp $   *  $Id: dev_le.c,v 1.56 2007/06/15 19:11:15 debug Exp $
29   *     *  
30   *  LANCE ethernet, as used in DECstations.   *  COMMENT: LANCE ethernet, as used in DECstations
31   *   *
32   *  This is based on "PMAD-AA TURBOchannel Ethernet Module Functional   *  This is based on "PMAD-AA TURBOchannel Ethernet Module Functional
33   *  Specification". I've tried to keep symbol names in this file to what   *  Specification". I've tried to keep symbol names in this file to what
# Line 47  Line 47 
47   *   *
48   *  TODO:  Error conditions (such as when there are not enough receive   *  TODO:  Error conditions (such as when there are not enough receive
49   *         buffers) are not emulated yet.   *         buffers) are not emulated yet.
50     *
51     *         (Old bug, but probably still valid:  "UDP packets that are too
52     *         large are not handled well by the Lance device.")
53   */   */
54    
55  #include <stdio.h>  #include <stdio.h>
# Line 82  extern int quiet_mode; Line 85  extern int quiet_mode;
85    
86    
87  struct le_data {  struct le_data {
88          int             irq_nr;          struct interrupt irq;
89            int             irq_asserted;
90    
91          uint64_t        buf_start;          uint64_t        buf_start;
92          uint64_t        buf_end;          uint64_t        buf_end;
# Line 230  static void le_tx(struct net *net, struc Line 234  static void le_tx(struct net *net, struc
234  {  {
235          int start_txp = d->txp;          int start_txp = d->txp;
236          uint16_t tx_descr[4];          uint16_t tx_descr[4];
237          int stp, enp, i, cur_packet_offset;          int stp, enp, cur_packet_offset;
238            size_t i;
239          uint32_t bufaddr, buflen;          uint32_t bufaddr, buflen;
240    
241          /*  TODO: This is just a guess:  */          /*  TODO: This is just a guess:  */
# Line 285  static void le_tx(struct net *net, struc Line 290  static void le_tx(struct net *net, struc
290                  /*  Start of a new packet:  */                  /*  Start of a new packet:  */
291                  if (stp) {                  if (stp) {
292                          d->tx_packet_len = buflen;                          d->tx_packet_len = buflen;
293                          d->tx_packet = malloc(buflen);                          CHECK_ALLOCATION(d->tx_packet = malloc(buflen));
                         if (d->tx_packet == NULL) {  
                                 fprintf(stderr, "out of memory (1) in "  
                                     "le_tx()\n");  
                                 exit(1);  
                         }  
294                  } else {                  } else {
295                          d->tx_packet_len += buflen;                          d->tx_packet_len += buflen;
296                          d->tx_packet = realloc(d->tx_packet, d->tx_packet_len);                          CHECK_ALLOCATION(d->tx_packet =
297                          if (d->tx_packet == NULL) {                              realloc(d->tx_packet, d->tx_packet_len));
                                 fprintf(stderr, "out of memory (2) in"  
                                     " le_tx()\n");  
                                 exit(1);  
                         }  
298                  }                  }
299    
300                  /*  Copy data from SRAM into the tx packet:  */                  /*  Copy data from SRAM into the tx packet:  */
# Line 349  static void le_tx(struct net *net, struc Line 345  static void le_tx(struct net *net, struc
345   */   */
346  static void le_rx(struct net *net, struct le_data *d)  static void le_rx(struct net *net, struct le_data *d)
347  {  {
348          int i, start_rxp = d->rxp;          int start_rxp = d->rxp;
349            size_t i;
350          uint16_t rx_descr[4];          uint16_t rx_descr[4];
351          uint32_t bufaddr, buflen;          uint32_t bufaddr, buflen;
352    
# Line 387  static void le_rx(struct net *net, struc Line 384  static void le_rx(struct net *net, struc
384    
385                  /*  Copy data from the packet into SRAM:  */                  /*  Copy data from the packet into SRAM:  */
386                  for (i=0; i<buflen; i++) {                  for (i=0; i<buflen; i++) {
387                          if (d->rx_packet_offset + i >= d->rx_packet_len)                          if (d->rx_packet_offset+(ssize_t)i >= d->rx_packet_len)
388                                  break;                                  break;
389                          d->sram[(bufaddr + i) & (SRAM_SIZE-1)] =                          d->sram[(bufaddr + i) & (SRAM_SIZE-1)] =
390                              d->rx_packet[d->rx_packet_offset + i];                              d->rx_packet[d->rx_packet_offset + i];
# Line 526  static void le_register_fix(struct net * Line 523  static void le_register_fix(struct net *
523  }  }
524    
525    
526  /*  DEVICE_TICK(le)
  *  dev_le_tick():  
  */  
 void dev_le_tick(struct cpu *cpu, void *extra)  
527  {  {
528          struct le_data *d = (struct le_data *) extra;          struct le_data *d = extra;
529            int new_assert;
530    
531          le_register_fix(cpu->machine->emul->net, d);          le_register_fix(cpu->machine->emul->net, d);
532    
533          if (d->reg[0] & LE_INTR && d->reg[0] & LE_INEA)          new_assert = (d->reg[0] & LE_INTR) && (d->reg[0] & LE_INEA);
534                  cpu_interrupt(cpu, d->irq_nr);  
535          else          if (new_assert && !d->irq_asserted)
536                  cpu_interrupt_ack(cpu, d->irq_nr);                  INTERRUPT_ASSERT(d->irq);
537            if (d->irq_asserted && !new_assert)
538                    INTERRUPT_DEASSERT(d->irq);
539    
540            d->irq_asserted = new_assert;
541  }  }
542    
543    
# Line 599  void le_register_write(struct le_data *d Line 598  void le_register_write(struct le_data *d
598  }  }
599    
600    
601  /*  DEVICE_ACCESS(le_sram)
  *  dev_le_sram_access():  
  */  
 int dev_le_sram_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
602  {  {
         int i, retval;  
603          struct le_data *d = extra;          struct le_data *d = extra;
604            size_t i;
605            int retval;
606    
607  #ifdef LE_DEBUG  #ifdef LE_DEBUG
608          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
# Line 648  int dev_le_sram_access(struct cpu *cpu, Line 643  int dev_le_sram_access(struct cpu *cpu,
643  }  }
644    
645    
646  /*  DEVICE_ACCESS(le)
  *  dev_le_access():  
  */  
 int dev_le_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr,  
         unsigned char *data, size_t len, int writeflag, void *extra)  
647  {  {
         uint64_t idata = 0, odata = 0;  
         int i, retval = 1;  
648          struct le_data *d = extra;          struct le_data *d = extra;
649            uint64_t idata = 0, odata = 0;
650            int retval = 1;
651            size_t i;
652    
653          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
654                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
# Line 672  int dev_le_access(struct cpu *cpu, struc Line 664  int dev_le_access(struct cpu *cpu, struc
664    
665          /*  Read from station's ROM (ethernet address):  */          /*  Read from station's ROM (ethernet address):  */
666          if (relative_addr >= 0xc0000 && relative_addr <= 0xfffff) {          if (relative_addr >= 0xc0000 && relative_addr <= 0xfffff) {
667                  i = (relative_addr & 0xff) / 4;                  uint32_t a;
668                  i = d->rom[i & (ROM_SIZE-1)];                  int j = (relative_addr & 0xff) / 4;
669                    a = d->rom[j & (ROM_SIZE-1)];
670    
671                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
672                          odata = (i << 24) + (i << 16) + (i << 8) + i;                          odata = (a << 24) + (a << 16) + (a << 8) + a;
673                  } else {                  } else {
674                          fatal("[ le: WRITE to ethernet addr (%08lx):",                          fatal("[ le: WRITE to ethernet addr (%08lx):",
675                              (long)relative_addr);                              (long)relative_addr);
# Line 766  do_return: Line 759  do_return:
759   *  dev_le_init():   *  dev_le_init():
760   */   */
761  void dev_le_init(struct machine *machine, struct memory *mem, uint64_t baseaddr,  void dev_le_init(struct machine *machine, struct memory *mem, uint64_t baseaddr,
762          uint64_t buf_start, uint64_t buf_end, int irq_nr, int len)          uint64_t buf_start, uint64_t buf_end, char *irq_path, int len)
763  {  {
764          char *name2;          char *name2;
765          size_t nlen = 55;          size_t nlen = 55;
766          struct le_data *d = malloc(sizeof(struct le_data));          struct le_data *d;
   
         if (d == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
767    
768            CHECK_ALLOCATION(d = malloc(sizeof(struct le_data)));
769          memset(d, 0, sizeof(struct le_data));          memset(d, 0, sizeof(struct le_data));
         d->irq_nr    = irq_nr;  
770    
771          d->sram = malloc(SRAM_SIZE);          INTERRUPT_CONNECT(irq_path, d->irq);
772          if (d->sram == NULL) {  
773                  fprintf(stderr, "out of memory\n");          CHECK_ALLOCATION(d->sram = malloc(SRAM_SIZE));
                 exit(1);  
         }  
774          memset(d->sram, 0, SRAM_SIZE);          memset(d->sram, 0, SRAM_SIZE);
775    
776          /*  TODO:  Are these actually used yet?  */          /*  TODO:  Are these actually used yet?  */
# Line 820  void dev_le_init(struct machine *machine Line 806  void dev_le_init(struct machine *machine
806              DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK              DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK
807              | DM_READS_HAVE_NO_SIDE_EFFECTS, d->sram);              | DM_READS_HAVE_NO_SIDE_EFFECTS, d->sram);
808    
809          name2 = malloc(nlen);          CHECK_ALLOCATION(name2 = malloc(nlen));
         if (name2 == NULL) {  
                 fprintf(stderr, "out of memory in dev_le_init()\n");  
                 exit(1);  
         }  
810          snprintf(name2, nlen, "le [%02x:%02x:%02x:%02x:%02x:%02x]",          snprintf(name2, nlen, "le [%02x:%02x:%02x:%02x:%02x:%02x]",
811              d->rom[0], d->rom[1], d->rom[2], d->rom[3], d->rom[4], d->rom[5]);              d->rom[0], d->rom[1], d->rom[2], d->rom[3], d->rom[4], d->rom[5]);
812    

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

  ViewVC Help
Powered by ViewVC 1.1.26