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

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

revision 23 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_ether.c,v 1.11 2006/02/09 20:02:59 debug Exp $   *  $Id: dev_ether.c,v 1.14 2006/06/15 17:29:38 debug Exp $
29   *   *
30   *  Basic "ethernet" network device. This is a simple test device which can   *  Basic "ethernet" network device. This is a simple test device which can
31   *  be used to send and receive packets to/from a simulated ethernet network.   *  be used to send and receive packets to/from a simulated ethernet network.
# Line 37  Line 37 
37    
38  #include "cpu.h"  #include "cpu.h"
39  #include "device.h"  #include "device.h"
 #include "devices.h"  
40  #include "emul.h"  #include "emul.h"
41  #include "machine.h"  #include "machine.h"
42  #include "memory.h"  #include "memory.h"
43  #include "misc.h"  #include "misc.h"
44  #include "net.h"  #include "net.h"
45    
46    #include "testmachine/dev_ether.h"
47    
 #define DEV_ETHER_MAXBUFLEN     16384  
 #define DEV_ETHER_TICK_SHIFT    14  
48    
49  #define STATUS_RECEIVED         0x01  #define DEV_ETHER_TICK_SHIFT    14
 #define STATUS_MORE_AVAIL       0x02  
50    
51  struct ether_data {  struct ether_data {
52          unsigned char   buf[DEV_ETHER_MAXBUFLEN];          unsigned char   buf[DEV_ETHER_BUFFER_SIZE];
53          unsigned char   mac[6];          unsigned char   mac[6];
54    
55          int             status;          int             status;
# Line 70  void dev_ether_tick(struct cpu *cpu, voi Line 67  void dev_ether_tick(struct cpu *cpu, voi
67          struct ether_data *d = (struct ether_data *) extra;          struct ether_data *d = (struct ether_data *) extra;
68          int r = 0;          int r = 0;
69    
70          d->status &= ~STATUS_MORE_AVAIL;          d->status &= ~DEV_ETHER_STATUS_MORE_PACKETS_AVAILABLE;
71          if (cpu->machine->emul->net != NULL)          if (cpu->machine->emul->net != NULL)
72                  r = net_ethernet_rx_avail(cpu->machine->emul->net, d);                  r = net_ethernet_rx_avail(cpu->machine->emul->net, d);
73          if (r)          if (r)
74                  d->status |= STATUS_MORE_AVAIL;                  d->status |= DEV_ETHER_STATUS_MORE_PACKETS_AVAILABLE;
75    
76          if (d->status)          if (d->status)
77                  cpu_interrupt(cpu, d->irq_nr);                  cpu_interrupt(cpu, d->irq_nr);
# Line 98  DEVICE_ACCESS(ether_buf) Line 95  DEVICE_ACCESS(ether_buf)
95  }  }
96    
97    
 /*  
  *  dev_ether_access():  
  */  
98  DEVICE_ACCESS(ether)  DEVICE_ACCESS(ether)
99  {  {
100          struct ether_data *d = (struct ether_data *) extra;          struct ether_data *d = (struct ether_data *) extra;
# Line 111  DEVICE_ACCESS(ether) Line 105  DEVICE_ACCESS(ether)
105          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
106                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
107    
108          switch (relative_addr) {          /*  Note: relative_addr + DEV_ETHER_BUFFER_SIZE to get the same
109          case 0x0000:              offsets as in the header file:  */
110    
111            switch (relative_addr + DEV_ETHER_BUFFER_SIZE) {
112    
113            case DEV_ETHER_STATUS:
114                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
115                          odata = d->status;                          odata = d->status;
116                          d->status = 0;                          d->status = 0;
# Line 120  DEVICE_ACCESS(ether) Line 118  DEVICE_ACCESS(ether)
118                  } else                  } else
119                          fatal("[ ether: WARNING: write to status ]\n");                          fatal("[ ether: WARNING: write to status ]\n");
120                  break;                  break;
121          case 0x0010:  
122            case DEV_ETHER_PACKETLENGTH:
123                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
124                          odata = d->packet_len;                          odata = d->packet_len;
125                  else {                  else {
# Line 129  DEVICE_ACCESS(ether) Line 128  DEVICE_ACCESS(ether)
128                                      " short (%i bytes) ]\n", (int)idata);                                      " short (%i bytes) ]\n", (int)idata);
129                                  idata = -1;                                  idata = -1;
130                          }                          }
131                          if (idata > DEV_ETHER_MAXBUFLEN) {                          if (idata > DEV_ETHER_BUFFER_SIZE) {
132                                  fatal("[ ether: ERROR: packet len too"                                  fatal("[ ether: ERROR: packet len too"
133                                      " large (%i bytes) ]\n", (int)idata);                                      " large (%i bytes) ]\n", (int)idata);
134                                  idata = DEV_ETHER_MAXBUFLEN;                                  idata = DEV_ETHER_BUFFER_SIZE;
135                          }                          }
136                          d->packet_len = idata;                          d->packet_len = idata;
137                  }                  }
138                  break;                  break;
139          case 0x0020:  
140                  if (writeflag == MEM_READ)          case DEV_ETHER_COMMAND:
141                    if (writeflag == MEM_READ) {
142                          fatal("[ ether: WARNING: read from command ]\n");                          fatal("[ ether: WARNING: read from command ]\n");
143                  else {                          break;
144                          switch (idata) {                  }
145                          case 0x00:              /*  Receive:  */  
146                                  if (cpu->machine->emul->net == NULL)                  /*  Write:  */
147                                          fatal("[ ether: RECEIVE but no "                  switch (idata) {
148                                              "net? ]\n");  
149                                  else {                  case DEV_ETHER_COMMAND_RX:      /*  Receive:  */
150                                          d->status &= ~STATUS_RECEIVED;                          if (cpu->machine->emul->net == NULL)
151                                          net_ethernet_rx(cpu->machine->emul->net,                                  fatal("[ ether: RECEIVE but no net? ]\n");
152                                              d, &incoming_ptr, &incoming_len);                          else {
153                                          if (incoming_ptr != NULL) {                                  d->status &= ~DEV_ETHER_STATUS_PACKET_RECEIVED;
154                                                  d->status |= STATUS_RECEIVED;                                  net_ethernet_rx(cpu->machine->emul->net,
155                                                  if (incoming_len >                                      d, &incoming_ptr, &incoming_len);
156                                                      DEV_ETHER_MAXBUFLEN)                                  if (incoming_ptr != NULL) {
157                                                          incoming_len =                                          d->status |=
158                                                              DEV_ETHER_MAXBUFLEN;                                              DEV_ETHER_STATUS_PACKET_RECEIVED;
159                                                  memcpy(d->buf, incoming_ptr,                                          if (incoming_len>DEV_ETHER_BUFFER_SIZE)
160                                                      incoming_len);                                                  incoming_len =
161                                                  free(incoming_ptr);                                                      DEV_ETHER_BUFFER_SIZE;
162                                                  d->packet_len = incoming_len;                                          memcpy(d->buf, incoming_ptr,
163                                          }                                              incoming_len);
164                                            free(incoming_ptr);
165                                            d->packet_len = incoming_len;
166                                  }                                  }
                                 dev_ether_tick(cpu, d);  
                                 break;  
                         case 0x01:              /*  Send  */  
                                 if (cpu->machine->emul->net == NULL)  
                                         fatal("[ ether: SEND but no net? ]\n");  
                                 else  
                                         net_ethernet_tx(cpu->machine->emul->net,  
                                             d, d->buf, d->packet_len);  
                                 d->status &= ~STATUS_RECEIVED;  
                                 dev_ether_tick(cpu, d);  
                                 break;  
                         default:fatal("[ ether: UNIMPLEMENTED command 0x"  
                                     "%02x ]\n", idata);  
                                 cpu->running = 0;  
167                          }                          }
168                            dev_ether_tick(cpu, d);
169                            break;
170    
171                    case DEV_ETHER_COMMAND_TX:      /*  Send  */
172                            if (cpu->machine->emul->net == NULL)
173                                    fatal("[ ether: SEND but no net? ]\n");
174                            else
175                                    net_ethernet_tx(cpu->machine->emul->net,
176                                        d, d->buf, d->packet_len);
177                            d->status &= ~DEV_ETHER_STATUS_PACKET_RECEIVED;
178                            dev_ether_tick(cpu, d);
179                            break;
180    
181                    default:fatal("[ ether: UNIMPLEMENTED command 0x"
182                                "%02x ]\n", idata);
183                            cpu->running = 0;
184                  }                  }
185                  break;                  break;
186    
187          default:if (writeflag == MEM_WRITE) {          default:if (writeflag == MEM_WRITE) {
188                          fatal("[ ether: unimplemented write to "                          fatal("[ ether: unimplemented write to "
189                              "offset 0x%x: data=0x%x ]\n", (int)                              "offset 0x%x: data=0x%x ]\n", (int)
# Line 221  DEVINIT(ether) Line 226  DEVINIT(ether)
226          snprintf(n1, nlen, "%s [%s]", devinit->name, tmp);          snprintf(n1, nlen, "%s [%s]", devinit->name, tmp);
227          snprintf(n2, nlen, "%s [%s, control]", devinit->name, tmp);          snprintf(n2, nlen, "%s [%s, control]", devinit->name, tmp);
228    
229          memory_device_register(devinit->machine->memory, n1,          memory_device_register(devinit->machine->memory, n1, devinit->addr,
230              devinit->addr, DEV_ETHER_MAXBUFLEN, dev_ether_buf_access, (void *)d,              DEV_ETHER_BUFFER_SIZE, dev_ether_buf_access, (void *)d,
231              DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK |              DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK |
232              DM_READS_HAVE_NO_SIDE_EFFECTS, d->buf);              DM_READS_HAVE_NO_SIDE_EFFECTS, d->buf);
233          memory_device_register(devinit->machine->memory, n2,          memory_device_register(devinit->machine->memory, n2,
234              devinit->addr + DEV_ETHER_MAXBUFLEN,              devinit->addr + DEV_ETHER_BUFFER_SIZE,
235              DEV_ETHER_LENGTH-DEV_ETHER_MAXBUFLEN, dev_ether_access, (void *)d,              DEV_ETHER_LENGTH-DEV_ETHER_BUFFER_SIZE, dev_ether_access, (void *)d,
236              DM_DEFAULT, NULL);              DM_DEFAULT, NULL);
237    
238          net_add_nic(devinit->machine->emul->net, d, d->mac);          net_add_nic(devinit->machine->emul->net, d, d->mac);
239    
240          machine_add_tickfunction(devinit->machine,          machine_add_tickfunction(devinit->machine,
241              dev_ether_tick, d, DEV_ETHER_TICK_SHIFT);              dev_ether_tick, d, DEV_ETHER_TICK_SHIFT, 0.0);
242    
243          return 1;          return 1;
244  }  }

Legend:
Removed from v.23  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26